From 157fbeccb585bf874c32ca9734caacd8319fecb3 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Sun, 12 Mar 2017 10:33:06 -0400 Subject: [PATCH 001/698] Add Font Text Color settings --- config.def.h | 3 + configuration.c | 70 +++++++++++++----------- configuration.h | 3 + intl/msg_hash_chs.h | 8 ++- intl/msg_hash_de.h | 6 ++ intl/msg_hash_eo.h | 6 ++ intl/msg_hash_es.c | 6 ++ intl/msg_hash_fr.h | 6 ++ intl/msg_hash_it.h | 6 ++ intl/msg_hash_ja.h | 8 ++- intl/msg_hash_ko.h | 8 ++- intl/msg_hash_lbl.h | 6 ++ intl/msg_hash_nl.h | 6 ++ intl/msg_hash_pt.h | 6 ++ intl/msg_hash_ru.h | 8 ++- intl/msg_hash_us.h | 6 ++ intl/msg_hash_vn.c | 8 ++- menu/drivers/xmb.c | 2 +- menu/menu_displaylist.c | 21 +++++-- menu/menu_setting.c | 118 +++++++++++++++++++++++++++------------- msg_hash.h | 3 + 21 files changed, 232 insertions(+), 82 deletions(-) diff --git a/config.def.h b/config.def.h index 26bf0dc0fa..0e22bf0832 100644 --- a/config.def.h +++ b/config.def.h @@ -608,6 +608,9 @@ static bool default_block_config_read = true; #ifdef HAVE_XMB static unsigned xmb_scale_factor = 100; static unsigned xmb_alpha_factor = 75; +static unsigned xmb_font_color_red = 0; +static unsigned xmb_font_color_green = 0; +static unsigned xmb_font_color_blue = 0; static unsigned xmb_icon_theme = XMB_ICON_THEME_MONOCHROME; static unsigned xmb_theme = XMB_THEME_ELECTRIC_BLUE; #ifdef HAVE_LAKKA diff --git a/configuration.c b/configuration.c index ade27f3b7a..1da32a7833 100644 --- a/configuration.c +++ b/configuration.c @@ -52,7 +52,7 @@ /* All config related settings go here. */ struct config_bool_setting -{ +{ const char *ident; bool *ptr; bool def_enable; @@ -61,7 +61,7 @@ struct config_bool_setting }; struct config_int_setting -{ +{ const char *ident; unsigned *ptr; bool def_enable; @@ -70,7 +70,7 @@ struct config_int_setting }; struct config_float_setting -{ +{ const char *ident; float *ptr; bool def_enable; @@ -79,7 +79,7 @@ struct config_float_setting }; struct config_array_setting -{ +{ const char *ident; char *ptr; bool def_enable; @@ -88,7 +88,7 @@ struct config_array_setting }; struct config_path_setting -{ +{ const char *ident; char *ptr; bool def_enable; @@ -109,7 +109,7 @@ struct config_path_setting tmp[count].def = default_setting; \ tmp[count].handle = handle_setting; \ count++; \ -} +} #define SETTING_BOOL(key, configval, default_enable, default_setting, handle_setting) \ GENERAL_SETTING(key, configval, default_enable, default_setting, struct config_bool_setting, handle_setting) @@ -631,7 +631,7 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, SETTING_PATH("cheat_database_path", settings->path.cheat_database, false, NULL, true); #ifdef HAVE_MENU - SETTING_PATH("menu_wallpaper", + SETTING_PATH("menu_wallpaper", settings->path.menu_wallpaper, false, NULL, true); #endif SETTING_PATH("content_history_path", @@ -650,7 +650,7 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, settings->path.font, false, NULL, true); SETTING_PATH("cursor_directory", settings->directory.cursor, false, NULL, true); - SETTING_PATH("content_history_dir", + SETTING_PATH("content_history_dir", settings->directory.content_history, false, NULL, true); SETTING_PATH("screenshot_directory", settings->directory.screenshot, true, NULL, true); @@ -680,7 +680,7 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, settings->directory.autoconfig, false, NULL, true); SETTING_PATH("audio_filter_dir", settings->directory.audio_filter, true, NULL, true); - SETTING_PATH("savefile_directory", + SETTING_PATH("savefile_directory", dir_get_ptr(RARCH_DIR_SAVEFILE), true, NULL, false); SETTING_PATH("savestate_directory", dir_get_ptr(RARCH_DIR_SAVESTATE), true, NULL, false); @@ -695,11 +695,11 @@ static struct config_path_setting *populate_settings_path(settings_t *settings, settings->directory.overlay, true, NULL, true); #endif #ifndef HAVE_DYNAMIC - SETTING_PATH("libretro_path", + SETTING_PATH("libretro_path", path_get_ptr(RARCH_PATH_CORE), false, NULL, false); #endif SETTING_PATH( - "screenshot_directory", + "screenshot_directory", settings->directory.screenshot, true, NULL, false); if (global) @@ -818,13 +818,13 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("xmb_show_netplay", &settings->menu.xmb.show_netplay, true, xmb_show_netplay, false); #endif SETTING_BOOL("xmb_show_history", &settings->menu.xmb.show_history, true, xmb_show_history, false); -#ifdef HAVE_LIBRETRODB +#ifdef HAVE_LIBRETRODB SETTING_BOOL("xmb_show_add", &settings->menu.xmb.show_add, true, xmb_show_add, false); #endif #endif SETTING_BOOL("rgui_show_start_screen", &settings->menu_show_start_screen, false, false /* TODO */, false); SETTING_BOOL("menu_navigation_wraparound_enable", &settings->menu.navigation.wraparound.enable, true, true, false); - SETTING_BOOL("menu_navigation_browser_filter_supported_extensions_enable", + SETTING_BOOL("menu_navigation_browser_filter_supported_extensions_enable", &settings->menu.navigation.browser.filter.supported_extensions_enable, true, true, false); SETTING_BOOL("menu_show_advanced_settings", &settings->menu.show_advanced_settings, true, show_advanced_settings, false); #endif @@ -948,6 +948,9 @@ static struct config_int_setting *populate_settings_int(settings_t *settings, in #ifdef HAVE_XMB SETTING_INT("xmb_alpha_factor", &settings->menu.xmb.alpha_factor, true, xmb_alpha_factor, false); SETTING_INT("xmb_scale_factor", &settings->menu.xmb.scale_factor, true, xmb_scale_factor, false); + SETTING_INT("xmb_font_color_red", &settings->menu.xmb.font_color_red, true, xmb_font_color_red, false); + SETTING_INT("xmb_font_color_green", &settings->menu.xmb.font_color_green, true, xmb_font_color_green, false); + SETTING_INT("xmb_font_color_blue", &settings->menu.xmb.font_color_blue, true, xmb_font_color_blue, false); SETTING_INT("xmb_theme", &settings->menu.xmb.theme, true, xmb_icon_theme, false); SETTING_INT("xmb_menu_color_theme", &settings->menu.xmb.menu_color_theme, true, xmb_theme, false); #endif @@ -1085,7 +1088,10 @@ static void config_set_defaults(void) strlcpy(settings->menu.driver, def_menu, sizeof(settings->menu.driver)); #ifdef HAVE_XMB - *settings->menu.xmb.font = '\0'; + *settings->menu.xmb.font = '\0'; + settings->menu.xmb.font_color_red = 0; + settings->menu.xmb.font_color_blue = 0; + settings->menu.xmb.font_color_green = 0; #endif #ifdef HAVE_MATERIALUI @@ -1504,7 +1510,7 @@ static config_file_t *open_default_config_file(void) RARCH_WARN("Created new config file in: \"%s\".\n", conf_path); } #elif !defined(RARCH_CONSOLE) - bool has_application_data = + bool has_application_data = fill_pathname_application_data(application_data, sizeof(application_data)); @@ -1685,7 +1691,7 @@ static bool check_shader_compatibility(enum file_path_enum enum_idx) return true; } - if (string_is_equal("gl", settings->video.driver) || + if (string_is_equal("gl", settings->video.driver) || string_is_equal("d3d", settings->video.driver)) { if (enum_idx == FILE_PATH_SLANGP_EXTENSION) @@ -1755,7 +1761,7 @@ static void config_get_hex_base(config_file_t *conf, * Loads a config file and reads all the values into memory. * */ -static bool config_load_file(const char *path, bool set_defaults, +static bool config_load_file(const char *path, bool set_defaults, settings_t *settings) { unsigned i; @@ -2268,10 +2274,10 @@ end: * This function only has an effect if a game-specific or core-specific * configuration file exists at respective locations. * - * core-specific: $CONFIG_DIR/$CORE_NAME/$CORE_NAME.cfg + * core-specific: $CONFIG_DIR/$CORE_NAME/$CORE_NAME.cfg * fallback: $CURRENT_CFG_LOCATION/$CORE_NAME/$CORE_NAME.cfg * - * game-specific: $CONFIG_DIR/$CORE_NAME/$ROM_NAME.cfg + * game-specific: $CONFIG_DIR/$CORE_NAME/$ROM_NAME.cfg * fallback: $CURRENT_CFG_LOCATION/$CORE_NAME/$GAME_NAME.cfg * * Returns: false if there was an error or no action was performed. @@ -2368,7 +2374,7 @@ bool config_load_override(void) /* Re-load the configuration with any overrides that might have been found */ buf[0] = '\0'; - /* Store the libretro_path we're using since it will be + /* Store the libretro_path we're using since it will be * overwritten by the override when reloading. */ strlcpy(buf, path_get(RARCH_PATH_CORE), sizeof(buf)); @@ -2824,7 +2830,7 @@ static void save_keybinds_user(config_file_t *conf, unsigned user) */ void config_load(void) { - /* Flush out some states that could have been + /* Flush out some states that could have been * set by core environment variables */ core_unset_input_descriptors(); @@ -3182,7 +3188,7 @@ bool config_save_overrides(int override_type) fill_pathname_application_special(config_directory, sizeof(config_directory), APPLICATION_SPECIAL_DIRECTORY_CONFIG); - fill_pathname_join(override_directory, config_directory, core_name, + fill_pathname_join(override_directory, config_directory, core_name, sizeof(override_directory)); if(!path_file_exists(override_directory)) @@ -3235,9 +3241,9 @@ bool config_save_overrides(int override_type) { if ((*bool_settings[i].ptr) != (*bool_overrides[i].ptr)) { - RARCH_LOG(" original: %s=%d\n", + RARCH_LOG(" original: %s=%d\n", bool_settings[i].ident, (*bool_settings[i].ptr)); - RARCH_LOG(" override: %s=%d\n", + RARCH_LOG(" override: %s=%d\n", bool_overrides[i].ident, (*bool_overrides[i].ptr)); config_set_bool(conf, bool_overrides[i].ident, (*bool_overrides[i].ptr)); @@ -3247,9 +3253,9 @@ bool config_save_overrides(int override_type) { if ((*int_settings[i].ptr) != (*int_overrides[i].ptr)) { - RARCH_LOG(" original: %s=%d\n", + RARCH_LOG(" original: %s=%d\n", int_settings[i].ident, (*int_settings[i].ptr)); - RARCH_LOG(" override: %s=%d\n", + RARCH_LOG(" override: %s=%d\n", int_overrides[i].ident, (*int_overrides[i].ptr)); config_set_int(conf, int_overrides[i].ident, (*int_overrides[i].ptr)); @@ -3259,9 +3265,9 @@ bool config_save_overrides(int override_type) { if ((*float_settings[i].ptr) != (*float_overrides[i].ptr)) { - RARCH_LOG(" original: %s=%f\n", + RARCH_LOG(" original: %s=%f\n", float_settings[i].ident, *float_settings[i].ptr); - RARCH_LOG(" override: %s=%f\n", + RARCH_LOG(" override: %s=%f\n", float_overrides[i].ident, *float_overrides[i].ptr); config_set_float(conf, float_overrides[i].ident, *float_overrides[i].ptr); @@ -3272,9 +3278,9 @@ bool config_save_overrides(int override_type) { if (!string_is_equal(array_settings[i].ptr, array_overrides[i].ptr)) { - RARCH_LOG(" original: %s=%s\n", + RARCH_LOG(" original: %s=%s\n", array_settings[i].ident, array_settings[i].ptr); - RARCH_LOG(" override: %s=%s\n", + RARCH_LOG(" override: %s=%s\n", array_overrides[i].ident, array_overrides[i].ptr); config_set_string(conf, array_overrides[i].ident, array_overrides[i].ptr); @@ -3285,9 +3291,9 @@ bool config_save_overrides(int override_type) { if (!string_is_equal(path_settings[i].ptr, path_overrides[i].ptr)) { - RARCH_LOG(" original: %s=%s\n", + RARCH_LOG(" original: %s=%s\n", path_settings[i].ident, path_settings[i].ptr); - RARCH_LOG(" override: %s=%s\n", + RARCH_LOG(" override: %s=%s\n", path_overrides[i].ident, path_overrides[i].ptr); config_set_path(conf, path_overrides[i].ident, path_overrides[i].ptr); diff --git a/configuration.h b/configuration.h index 9b1c827b33..47b72414e5 100644 --- a/configuration.h +++ b/configuration.h @@ -189,6 +189,9 @@ typedef struct settings { unsigned shader_pipeline; char font[PATH_MAX_LENGTH]; + int font_color_red; + int font_color_green; + int font_color_blue; unsigned scale_factor; unsigned alpha_factor; unsigned theme; diff --git a/intl/msg_hash_chs.h b/intl/msg_hash_chs.h index 2247b51f46..4034850c68 100644 --- a/intl/msg_hash_chs.h +++ b/intl/msg_hash_chs.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "编译器" ) @@ -1656,6 +1656,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "菜单透明度因子") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "菜单字体") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_de.h b/intl/msg_hash_de.h index 3a0614e528..2e181e483e 100644 --- a/intl/msg_hash_de.h +++ b/intl/msg_hash_de.h @@ -1649,6 +1649,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "WLAN") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Menü-Transparenz") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Menü-Schriftart") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_eo.h b/intl/msg_hash_eo.h index aede2dfc0d..5eeb225a48 100644 --- a/intl/msg_hash_eo.h +++ b/intl/msg_hash_eo.h @@ -1550,6 +1550,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Menu Alpha Factor") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Menu Font") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_es.c b/intl/msg_hash_es.c index 5f2c0ed82e..6e2fbdaf7e 100644 --- a/intl/msg_hash_es.c +++ b/intl/msg_hash_es.c @@ -2310,6 +2310,12 @@ const char *msg_hash_to_str_es(enum msg_hash_enums msg) return "Pantalla completa en ventana"; case MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR: return "Transparencia del XMB"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED: + return "Fuente del XMB Red"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN: + return "Fuente del XMB Green"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE: + return "Fuente del XMB Blue"; case MENU_ENUM_LABEL_VALUE_XMB_FONT: return "Fuente del XMB"; case MENU_ENUM_LABEL_VALUE_XMB_SCALE_FACTOR: diff --git a/intl/msg_hash_fr.h b/intl/msg_hash_fr.h index 25c2bb4686..86bbee4106 100644 --- a/intl/msg_hash_fr.h +++ b/intl/msg_hash_fr.h @@ -1518,6 +1518,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "XMB : Transparence") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "XMB : Police") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_it.h b/intl/msg_hash_it.h index 76a68124e8..ea4188108e 100644 --- a/intl/msg_hash_it.h +++ b/intl/msg_hash_it.h @@ -1530,6 +1530,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Fattore alpha del menù") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Carattere del menù") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index 672d162bef..24a9a0ba5f 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif @@ -1661,6 +1661,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "メニューの透明性") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "メニューのフォント") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_ko.h b/intl/msg_hash_ko.h index 79c19ce9d1..b48776df5e 100644 --- a/intl/msg_hash_ko.h +++ b/intl/msg_hash_ko.h @@ -1,4 +1,4 @@ -MSG_HASH( +MSG_HASH( MSG_COMPILER, "컴파일러" ) @@ -1653,6 +1653,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "메뉴 알파 요소") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "메뉴 폰트") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 663db375f5..0e469f1049 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1095,6 +1095,12 @@ MSG_HASH(MENU_ENUM_LABEL_WIFI_SETTINGS, "wifi_settings") MSG_HASH(MENU_ENUM_LABEL_XMB_ALPHA_FACTOR, "xmb_alpha_factor") +MSG_HASH(MENU_ENUM_LABEL_XMB_FONT_COLOR_RED, + "xmb_font_color_red") +MSG_HASH(MENU_ENUM_LABEL_XMB_FONT_COLOR_GREEN, + "xmb_font_color_green") +MSG_HASH(MENU_ENUM_LABEL_XMB_FONT_COLOR_BLUE, + "xmb_font_color_blue") MSG_HASH(MENU_ENUM_LABEL_XMB_FONT, "xmb_font") MSG_HASH(MENU_ENUM_LABEL_XMB_MENU_COLOR_THEME, diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index 6ce92a9aa5..6eaee8ea7e 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -1550,6 +1550,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Menu Alpha Factor") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Menu Font") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_pt.h b/intl/msg_hash_pt.h index 816c2a19d6..0c98626c8f 100644 --- a/intl/msg_hash_pt.h +++ b/intl/msg_hash_pt.h @@ -1647,6 +1647,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Fator Alfa do Menu") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Fonte do Menu") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_ru.h b/intl/msg_hash_ru.h index 480252759d..7e73e64fce 100644 --- a/intl/msg_hash_ru.h +++ b/intl/msg_hash_ru.h @@ -1,4 +1,4 @@ -#if defined(_MSC_VER) && !defined(_XBOX) +#if defined(_MSC_VER) && !defined(_XBOX) /* https://support.microsoft.com/en-us/kb/980263 */ #pragma execution_character_set("utf-8") #endif @@ -1551,6 +1551,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Menu Alpha Factor") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Menu Font") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index a44a6d0b70..747fcb8894 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -1653,6 +1653,12 @@ MSG_HASH(MENU_ENUM_LABEL_VALUE_WIFI_SETTINGS, "Wi-Fi") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR, "Menu Alpha Factor") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + "Menu Font Red Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + "Menu Font Green Color") +MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + "Menu Font Blue Color") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_FONT, "Menu Font") MSG_HASH(MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM, diff --git a/intl/msg_hash_vn.c b/intl/msg_hash_vn.c index 833bc627cb..bbe117548a 100644 --- a/intl/msg_hash_vn.c +++ b/intl/msg_hash_vn.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker * @@ -3188,6 +3188,12 @@ const char *msg_hash_to_str_vn(enum msg_hash_enums msg) return "Wi-Fi"; case MENU_ENUM_LABEL_VALUE_XMB_ALPHA_FACTOR: return "Menu Alpha Factor"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED: + return "Menu Font Red Color"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN: + return "Menu Font Green Color"; + case MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE: + return "Menu Font Blue Color"; case MENU_ENUM_LABEL_VALUE_XMB_FONT: return "Menu Font"; case MENU_ENUM_LABEL_VALUE_XMB_ICON_THEME_CUSTOM: diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 796fb62c48..546bfcdb21 100644 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -843,7 +843,7 @@ static void xmb_render_messagebox_internal( { const char *msg = list->elems[i].data; int len = (int)utf8len(msg); - + if (len > longest) { longest = len; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index ca6f4e258a..660099d25e 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -196,7 +196,7 @@ static void print_buf_lines(file_list_t *list, char *buf, sizeof(core_path)); if ( - path_file_exists(core_path) + path_file_exists(core_path) && core_info_get_display_name( core_path, display_name, sizeof(display_name))) menu_entries_set_alt_at_offset(list, j, display_name); @@ -2813,8 +2813,8 @@ static int menu_displaylist_parse_horizontal_content_actions( msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RUN), msg_hash_to_str(MENU_ENUM_LABEL_RUN), MENU_ENUM_LABEL_RUN, FILE_TYPE_PLAYLIST_ENTRY, 0, idx); - - if (settings->playlist_entry_remove) + + if (settings->playlist_entry_remove) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DELETE_ENTRY), msg_hash_to_str(MENU_ENUM_LABEL_DELETE_ENTRY), @@ -2995,7 +2995,7 @@ static int menu_displaylist_parse_netplay_room_list( msg_hash_to_str(MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS), MENU_ENUM_LABEL_NETPLAY_REFRESH_ROOMS, MENU_SETTING_ACTION, 0, 0); - + if (netplay_room_count > 0) { unsigned i; @@ -3686,7 +3686,7 @@ static bool menu_displaylist_push_list_process(menu_displaylist_info_t *info) MENU_SETTING_ACTION, 0, 0); } #endif - + if (info->push_builtin_cores) { #if defined(HAVE_VIDEO_PROCESSOR) @@ -4378,7 +4378,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) PARSE_ONLY_UINT, false); ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_PLAYLIST_ENTRY_REMOVE, - PARSE_ONLY_BOOL, false); + PARSE_ONLY_BOOL, false); menu_displaylist_parse_playlist_associations(info); info->need_push = true; @@ -4637,6 +4637,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_XMB_SCALE_FACTOR, PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_FONT_COLOR_RED, + PARSE_ONLY_PATH, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_FONT_COLOR_GREEN, + PARSE_ONLY_PATH, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_XMB_FONT_COLOR_BLUE, + PARSE_ONLY_PATH, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_XMB_FONT, PARSE_ONLY_PATH, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index ff1ee8a1cf..d6b6ed7391 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -140,10 +140,10 @@ static void setting_get_string_representation_uint_custom_viewport_width(void *d rarch_setting_t *setting = (rarch_setting_t*)data; if (!setting) return; - + av_info = video_viewport_get_system_av_info(); geom = (struct retro_game_geometry*)&av_info->geometry; - + if (*setting->value.target.unsigned_integer%geom->base_width == 0) snprintf(s, len, "%u (%ux)", *setting->value.target.unsigned_integer, @@ -161,10 +161,10 @@ static void setting_get_string_representation_uint_custom_viewport_height(void * rarch_setting_t *setting = (rarch_setting_t*)data; if (!setting) return; - + av_info = video_viewport_get_system_av_info(); geom = (struct retro_game_geometry*)&av_info->geometry; - + if (*setting->value.target.unsigned_integer%geom->base_height == 0) snprintf(s, len, "%u (%ux)", *setting->value.target.unsigned_integer, @@ -743,7 +743,7 @@ int menu_action_handle_setting(rarch_setting_t *setting, return -1; } -static rarch_setting_t *menu_setting_find_internal(rarch_setting_t *setting, +static rarch_setting_t *menu_setting_find_internal(rarch_setting_t *setting, const char *label) { uint32_t needle = msg_hash_calculate(label); @@ -773,7 +773,7 @@ static rarch_setting_t *menu_setting_find_internal(rarch_setting_t *setting, return NULL; } -static rarch_setting_t *menu_setting_find_internal_enum(rarch_setting_t *setting, +static rarch_setting_t *menu_setting_find_internal_enum(rarch_setting_t *setting, enum msg_hash_enums enum_idx) { rarch_setting_t **list = &setting; @@ -1032,10 +1032,10 @@ static int setting_action_start_libretro_device_type(void *data) devices[types++] = RETRO_DEVICE_NONE; devices[types++] = RETRO_DEVICE_JOYPAD; - if (runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system) + if (runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system) && system) { - /* Only push RETRO_DEVICE_ANALOG as default if we use an + /* Only push RETRO_DEVICE_ANALOG as default if we use an * older core which doesn't use SET_CONTROLLER_INFO. */ if (!system->ports.size) devices[types++] = RETRO_DEVICE_ANALOG; @@ -1139,7 +1139,7 @@ static int setting_action_left_libretro_device_type( if (system) { - /* Only push RETRO_DEVICE_ANALOG as default if we use an + /* Only push RETRO_DEVICE_ANALOG as default if we use an * older core which doesn't use SET_CONTROLLER_INFO. */ if (!system->ports.size) devices[types++] = RETRO_DEVICE_ANALOG; @@ -1203,10 +1203,10 @@ static int setting_action_right_libretro_device_type( devices[types++] = RETRO_DEVICE_NONE; devices[types++] = RETRO_DEVICE_JOYPAD; - if (runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system) + if (runloop_ctl(RUNLOOP_CTL_SYSTEM_INFO_GET, &system) && system) { - /* Only push RETRO_DEVICE_ANALOG as default if we use an + /* Only push RETRO_DEVICE_ANALOG as default if we use an * older core which doesn't use SET_CONTROLLER_INFO. */ if (!system->ports.size) devices[types++] = RETRO_DEVICE_ANALOG; @@ -1348,7 +1348,7 @@ static int setting_action_ok_bind_defaults(void *data, bool wraparound) target = (struct retro_keybind*) &settings->input.binds[setting->index_offset][0]; - def_binds = (setting->index_offset) ? + def_binds = (setting->index_offset) ? retro_keybinds_rest : retro_keybinds_1; if (!target) @@ -1465,7 +1465,7 @@ static void get_string_representation_bind_device(void * data, char *s, * Get associated label of a setting. **/ void menu_setting_get_label(void *data, char *s, - size_t len, unsigned *w, unsigned type, + size_t len, unsigned *w, unsigned type, const char *menu_label, const char *label, unsigned idx) { rarch_setting_t *setting = NULL; @@ -1595,7 +1595,7 @@ void general_write_handler(void *data) file_list_t *menu_stack = menu_entries_get_menu_stack_ptr(0); info.list = menu_stack; - info.type = 0; + info.type = 0; info.directory_ptr = 0; strlcpy(info.label, msg_hash_to_str(MENU_ENUM_LABEL_HELP), sizeof(info.label)); @@ -1650,14 +1650,14 @@ void general_write_handler(void *data) break; case MENU_ENUM_LABEL_LOG_VERBOSITY: { - if (setting - && setting->value.target.boolean + if (setting + && setting->value.target.boolean && *setting->value.target.boolean) verbosity_enable(); else verbosity_disable(); - if (setting + if (setting && setting->value.target.boolean && *setting->value.target.boolean) retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_VERBOSITY, NULL); @@ -1698,7 +1698,7 @@ void general_write_handler(void *data) { #if defined(__CELLOS_LV2__) && (CELL_SDK_VERSION > 0x340000) cellSysutilEnableBgmPlayback(); -#endif +#endif } else { @@ -1974,7 +1974,7 @@ static bool setting_append_list_input_player_options( (*list)[list_info->index - 1].action_right = &setting_action_right_libretro_device_type; (*list)[list_info->index - 1].action_select = &setting_action_right_libretro_device_type; (*list)[list_info->index - 1].action_start = &setting_action_start_libretro_device_type; - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_libretro_device; menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_LIBRETRO_DEVICE + user)); @@ -1995,7 +1995,7 @@ static bool setting_append_list_input_player_options( (*list)[list_info->index - 1].action_right = &setting_action_right_analog_dpad_mode; (*list)[list_info->index - 1].action_select = &setting_action_right_analog_dpad_mode; (*list)[list_info->index - 1].action_start = &setting_action_start_analog_dpad_mode; - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_analog_dpad_mode; menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_PLAYER_ANALOG_DPAD_MODE + user)); @@ -2073,7 +2073,7 @@ static bool setting_append_list_input_player_options( ) { if (system->input_desc_btn[user][i]) - strlcat(label, + strlcat(label, system->input_desc_btn[user][i], sizeof(label)); else @@ -2912,7 +2912,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 3, 1.0, true, true); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_libretro_log_level; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); @@ -3027,7 +3027,7 @@ static bool setting_append_list( menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_AUTOSAVE_INIT); menu_settings_list_current_add_range(list, list_info, 0, 0, 10, true, false); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_autosave_interval; #endif @@ -3152,7 +3152,7 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_REINIT); menu_settings_list_current_add_range(list, list_info, 0, 1, 1, true, false); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_video_monitor_index; if (video_driver_has_windowed()) @@ -3222,7 +3222,7 @@ static bool setting_append_list( (*list)[list_info->index - 1].action_start = &setting_action_start_video_refresh_rate_auto; (*list)[list_info->index - 1].action_ok = &setting_action_ok_video_refresh_rate_auto; (*list)[list_info->index - 1].action_select = &setting_action_ok_video_refresh_rate_auto; - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_st_float_video_refresh_rate_auto; settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); @@ -3272,7 +3272,7 @@ static bool setting_append_list( true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_CMD_APPLY_AUTO); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_aspect_ratio_index; CONFIG_INT( @@ -3482,7 +3482,7 @@ static bool setting_append_list( general_write_handler, general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_video_rotation; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); @@ -3796,7 +3796,7 @@ static bool setting_append_list( &settings->audio.latency, MENU_ENUM_LABEL_AUDIO_LATENCY, MENU_ENUM_LABEL_VALUE_AUDIO_LATENCY, - g_defaults.settings.out_latency ? + g_defaults.settings.out_latency ? g_defaults.settings.out_latency : out_latency, &group_info, &subgroup_info, @@ -4416,7 +4416,7 @@ static bool setting_append_list( &retro_keybinds_1[i], &group_info, &subgroup_info, parent_group); (*list)[list_info->index - 1].bind_type = i + MENU_SETTINGS_BIND_BEGIN; - menu_settings_list_current_add_enum_idx(list, list_info, + menu_settings_list_current_add_enum_idx(list, list_info, (enum msg_hash_enums)(MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN + i)); } @@ -5003,6 +5003,48 @@ static bool setting_append_list( general_read_handler); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_UINT( + list, list_info, + &settings->menu.xmb.font_color_red, + MENU_ENUM_LABEL_XMB_FONT_COLOR_RED, + MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_RED, + xmb_scale_factor, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 255, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + + CONFIG_UINT( + list, list_info, + &settings->menu.xmb.font_color_green, + MENU_ENUM_LABEL_XMB_FONT_COLOR_GREEN, + MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_GREEN, + xmb_scale_factor, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 255, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + + CONFIG_UINT( + list, list_info, + &settings->menu.xmb.font_color_blue, + MENU_ENUM_LABEL_XMB_FONT_COLOR_BLUE, + MENU_ENUM_LABEL_VALUE_XMB_FONT_COLOR_BLUE, + xmb_scale_factor, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 0, 255, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_UINT( list, list_info, &settings->menu.xmb.theme, @@ -5173,7 +5215,7 @@ static bool setting_append_list( general_read_handler, SD_FLAG_NONE); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); -#endif +#endif } #endif @@ -5513,7 +5555,7 @@ static bool setting_append_list( menu_settings_list_current_add_range(list, list_info, 0, 0, 1.0, true, false); END_SUB_GROUP(list, list_info, parent_group); - + START_SUB_GROUP(list, list_info, "Playlist", &group_info, &subgroup_info, parent_group); CONFIG_BOOL( @@ -5530,9 +5572,9 @@ static bool setting_append_list( general_write_handler, general_read_handler, SD_FLAG_NONE); - + END_SUB_GROUP(list, list_info, parent_group); - + END_GROUP(list, list_info, parent_group); break; case SETTINGS_LIST_CHEEVOS: @@ -5609,7 +5651,7 @@ static bool setting_append_list( sizeof(settings->network.buildbot_url), MENU_ENUM_LABEL_CORE_UPDATER_BUILDBOT_URL, MENU_ENUM_LABEL_VALUE_CORE_UPDATER_BUILDBOT_URL, - buildbot_server_url, + buildbot_server_url, &group_info, &subgroup_info, parent_group, @@ -5623,7 +5665,7 @@ static bool setting_append_list( sizeof(settings->network.buildbot_assets_url), MENU_ENUM_LABEL_BUILDBOT_ASSETS_URL, MENU_ENUM_LABEL_VALUE_BUILDBOT_ASSETS_URL, - buildbot_assets_server_url, + buildbot_assets_server_url, &group_info, &subgroup_info, parent_group, @@ -6138,7 +6180,7 @@ static bool setting_append_list( true, true); menu_settings_list_current_add_cmd(list, list_info, CMD_EVENT_MENU_REFRESH); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_uint_user_language; #endif @@ -6203,7 +6245,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - (*list)[list_info->index - 1].get_string_representation = + (*list)[list_info->index - 1].get_string_representation = &setting_get_string_representation_cheevos_password; settings_data_list_current_add_flags(list, list_info, SD_FLAG_ALLOW_INPUT); #endif @@ -6680,7 +6722,7 @@ static rarch_setting_t *menu_setting_new_internal(rarch_setting_info_t *list_inf { unsigned i; rarch_setting_t* resized_list = NULL; - enum settings_list_type list_types[] = + enum settings_list_type list_types[] = { SETTINGS_LIST_MAIN_MENU, SETTINGS_LIST_DRIVERS, diff --git a/msg_hash.h b/msg_hash.h index 6e3c44c3a4..aa899c92cf 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -653,6 +653,9 @@ enum msg_hash_enums MENU_LABEL(ENTRY_HOVER_COLOR), MENU_LABEL(XMB_ALPHA_FACTOR), MENU_LABEL(XMB_SCALE_FACTOR), + MENU_LABEL(XMB_FONT_COLOR_RED), + MENU_LABEL(XMB_FONT_COLOR_GREEN), + MENU_LABEL(XMB_FONT_COLOR_BLUE), MENU_LABEL(XMB_FONT), MENU_LABEL(XMB_THEME), MENU_LABEL(XMB_MENU_COLOR_THEME), From be936e9bcf0d90c1197e11d0b6c5a41b8735bffd Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Tue, 14 Mar 2017 06:09:46 -0400 Subject: [PATCH 002/698] Fix type of font colors --- configuration.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/configuration.h b/configuration.h index 47b72414e5..35166310da 100644 --- a/configuration.h +++ b/configuration.h @@ -189,9 +189,9 @@ typedef struct settings { unsigned shader_pipeline; char font[PATH_MAX_LENGTH]; - int font_color_red; - int font_color_green; - int font_color_blue; + unsigned font_color_red; + unsigned font_color_green; + unsigned font_color_blue; unsigned scale_factor; unsigned alpha_factor; unsigned theme; From 6903602665e97d41e57261a6e8782d3ed51c3453 Mon Sep 17 00:00:00 2001 From: Andre Leiradella Date: Sun, 26 Nov 2017 22:03:59 +0000 Subject: [PATCH 003/698] Set cheevos_loaded to false if the cheevos and leaderboard lists are empty --- cheevos/cheevos.c | 41 +++++------------------------------------ 1 file changed, 5 insertions(+), 36 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index d04aafaf16..d1f392885d 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -213,42 +213,6 @@ typedef struct cheevos_expr_t value; } cheevos_leaderboard_t; -/* -typedef struct -{ - bool is_lookup; - char* prestring; - cheevos_expr_t expression; -} cheevos_rps_element_t; - -typedef struct -{ - char* name; - unsigned type; -} cheevos_rps_format_t; - -typedef struct -{ - unsigned compare; - char* result; -} cheevos_rps_lookup_value; - -typedef struct -{ - char* name; - cheevos_rps_lookup_value* values; -} cheevos_rps_lookup_t; - -typedef struct -{ - cheevos_rps_element_t* elements; - cheevos_rps_format_t* formats; - unsigned format_count; - cheevos_rps_lookup_t* lookups; - unsigned lookup_count; -} cheevos_rps_t; -*/ - typedef struct { int console_id; @@ -2847,6 +2811,11 @@ static int cheevos_iterate(coro_t* coro) runloop_msg_queue_push(msg, 0, 6 * 60, false); } + if ( cheevos_locals.core.count == 0 + && cheevos_locals.unofficial.count == 0 + && cheevos_locals.lboard_count == 0) + cheevos_unload(); + CORO_STOP(); /************************************************************************** From 78bf72e29e10c85ef642ba4921fb6a45a5033ffc Mon Sep 17 00:00:00 2001 From: bparker06 Date: Sat, 2 Dec 2017 13:33:09 -0500 Subject: [PATCH 004/698] blissbox: add atari pad type --- input/include/blissbox.h | 1 + 1 file changed, 1 insertion(+) diff --git a/input/include/blissbox.h b/input/include/blissbox.h index fd515ee218..4ec18e500d 100644 --- a/input/include/blissbox.h +++ b/input/include/blissbox.h @@ -42,6 +42,7 @@ const blissbox_pad_type_t blissbox_pad_types[] = {"A5200_TB", 50}, {"A7800", 4}, {"ATARI_KEYPAD", 43}, + {"ATARI", 0}, {"ATMARK", 10}, {"BALLY", 42}, {"CD32", 24}, From b1911495adb7e0509f96ff75012a722851f95193 Mon Sep 17 00:00:00 2001 From: radius Date: Sat, 2 Dec 2017 13:59:44 -0500 Subject: [PATCH 005/698] reenable network gamepad --- menu/menu_displaylist.c | 2 +- menu/menu_setting.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 2622132870..b42384394d 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -4273,7 +4273,7 @@ bool menu_displaylist_process(menu_displaylist_info_t *info) MENU_SETTING_ACTION, 0, 0); #endif -#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) && defined(HAVE_NETWORKGAMEPAD_CORE) +#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) menu_entries_append_enum(info->list, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_START_NET_RETROPAD), msg_hash_to_str(MENU_ENUM_LABEL_START_NET_RETROPAD), diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 22e36c4b68..86cca1a42a 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -2263,7 +2263,7 @@ static bool setting_append_list( parent_group); #endif -#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) && defined(HAVE_NETWORKGAMEPAD_CORE) +#if defined(HAVE_NETWORKING) && defined(HAVE_NETWORKGAMEPAD) CONFIG_ACTION( list, list_info, MENU_ENUM_LABEL_START_NET_RETROPAD, From 4efc8453c232996f3bfb2a83470fa5e14b54d44a Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 2 Dec 2017 15:59:33 -0500 Subject: [PATCH 006/698] buildfix for certain mingw environments --- tasks/task_autodetect.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 4c2b454e3c..66080478f8 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -35,7 +35,15 @@ #if defined(_WIN32) && !defined(_XBOX) && !defined(_MSC_VER) && _WIN32_WINNT >= 0x0500 /* MinGW Win32 HID API */ +#include +#include #include +#ifdef __NO_INLINE__ +/* Workaround MinGW issue where compiling without -O2 (which sets __NO_INLINE__) causes the strsafe functions + * to never be defined (only declared). + */ +#define __CRT_STRSAFE_IMPL +#endif #include #include #include From e9a3088a795366929c5ff9c2757d64ae3d49ef6b Mon Sep 17 00:00:00 2001 From: Ash Date: Sun, 3 Dec 2017 11:31:30 +1100 Subject: [PATCH 007/698] [WiiU] Toolchain: Actually fix C++ constructors/destructors (oops!) Looks like I temporarily forgot how external symbols work. Fixes https://gbatemp.net/posts/7720955; hopefully we finally have C++ under control. --- frontend/drivers/platform_wiiu.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/frontend/drivers/platform_wiiu.c b/frontend/drivers/platform_wiiu.c index ab8a62f115..925f820652 100644 --- a/frontend/drivers/platform_wiiu.c +++ b/frontend/drivers/platform_wiiu.c @@ -525,24 +525,23 @@ void __eabi() __attribute__((weak)) void __init(void) { - extern void (**const __CTOR_LIST__)(void); - extern void (**const __CTOR_END__)(void); + extern void (*const __CTOR_LIST__)(void); + extern void (*const __CTOR_END__)(void); - void (**ctor)(void) = __CTOR_LIST__; - while (ctor < __CTOR_END__) { + void (*const *ctor)(void) = &__CTOR_LIST__; + while (ctor < &__CTOR_END__) { (*ctor++)(); } } - __attribute__((weak)) void __fini(void) { - extern void (**const __DTOR_LIST__)(void); - extern void (**const __DTOR_END__)(void); + extern void (*const __DTOR_LIST__)(void); + extern void (*const __DTOR_END__)(void); - void (**dtor)(void) = __DTOR_LIST__; - while (dtor < __DTOR_END__) { + void (*const *dtor)(void) = &__DTOR_LIST__; + while (dtor < &__DTOR_END__) { (*dtor++)(); } } @@ -654,7 +653,10 @@ void _start(int argc, char **argv) main(argc, argv); fsdev_exit(); -// __fini(); + +/* TODO: fix elf2rpl so it doesn't error with "Could not find matching symbol + for relocation" then uncomment this */ +// __fini(); memoryRelease(); SYSRelaunchTitle(0, 0); exit(0); From 69c2040e55755a8a093815a34a6c7f495fd12f8d Mon Sep 17 00:00:00 2001 From: radius Date: Sat, 2 Dec 2017 21:29:13 -0500 Subject: [PATCH 008/698] fix slow motion --- configuration.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/configuration.c b/configuration.c index 14b8d82c0a..30f985f4f3 100644 --- a/configuration.c +++ b/configuration.c @@ -2718,7 +2718,9 @@ static bool config_load_file(const char *path, bool set_defaults, *settings->paths.directory_system = '\0'; if (settings->floats.slowmotion_ratio < 1.0f) - configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f); + { + configuration_set_float(settings, settings->floats.slowmotion_ratio, 15.0f); + } /* Sanitize fastforward_ratio value - previously range was -1 * and up (with 0 being skipped) */ @@ -2727,6 +2729,7 @@ static bool config_load_file(const char *path, bool set_defaults, configuration_set_float(settings, settings->floats.fastforward_ratio, 0.0f); } + #ifdef HAVE_LAKKA settings->bools.ssh_enable = path_file_exists(LAKKA_SSH_PATH); settings->bools.samba_enable = path_file_exists(LAKKA_SAMBA_PATH); From 0a3fb3ec40912211bbbafce8eb73fa61eef17c4b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 3 Dec 2017 03:37:06 +0100 Subject: [PATCH 009/698] Change value to 1.0f --- configuration.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configuration.c b/configuration.c index 30f985f4f3..0af3f1e94a 100644 --- a/configuration.c +++ b/configuration.c @@ -2719,7 +2719,7 @@ static bool config_load_file(const char *path, bool set_defaults, if (settings->floats.slowmotion_ratio < 1.0f) { - configuration_set_float(settings, settings->floats.slowmotion_ratio, 15.0f); + configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f); } /* Sanitize fastforward_ratio value - previously range was -1 From 04b26fe111d991eedfd4ee879bd962472dc0d1c4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 3 Dec 2017 03:43:05 +0100 Subject: [PATCH 010/698] Put braces around macros --- configuration.c | 4 ---- configuration.h | 17 ++++++++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/configuration.c b/configuration.c index 0af3f1e94a..8edb392412 100644 --- a/configuration.c +++ b/configuration.c @@ -2718,16 +2718,12 @@ static bool config_load_file(const char *path, bool set_defaults, *settings->paths.directory_system = '\0'; if (settings->floats.slowmotion_ratio < 1.0f) - { configuration_set_float(settings, settings->floats.slowmotion_ratio, 1.0f); - } /* Sanitize fastforward_ratio value - previously range was -1 * and up (with 0 being skipped) */ if (settings->floats.fastforward_ratio < 0.0f) - { configuration_set_float(settings, settings->floats.fastforward_ratio, 0.0f); - } #ifdef HAVE_LAKKA diff --git a/configuration.h b/configuration.h index 31dbeebff3..c81a53f962 100644 --- a/configuration.h +++ b/configuration.h @@ -29,21 +29,28 @@ #include "input/input_defines.h" #define configuration_set_float(settings, var, newvar) \ +{ \ settings->modified = true; \ - var = newvar + var = newvar; \ +} #define configuration_set_bool(settings, var, newvar) \ +{ \ settings->modified = true; \ - var = newvar + var = newvar; \ +} #define configuration_set_uint(settings, var, newvar) \ +{ \ settings->modified = true; \ - var = newvar + var = newvar; \ +} #define configuration_set_int(settings, var, newvar) \ +{ \ settings->modified = true; \ - var = newvar - + var = newvar; \ +} enum override_type { From bada13a2152b2092e7c66e656b06f14bcd8ea07c Mon Sep 17 00:00:00 2001 From: radius Date: Sat, 2 Dec 2017 22:47:16 -0500 Subject: [PATCH 011/698] let it snow --- .../gl_shaders/pipeline_snowflake.glsl.frag.h | 65 +++++++++++++++++++ gfx/drivers_shader/shader_glsl.c | 16 +++++ gfx/video_driver.h | 1 + intl/msg_hash_us.h | 2 + menu/cbs/menu_cbs_get_value.c | 4 ++ menu/drivers/xmb.c | 3 + menu/drivers_display/menu_display_gl.c | 2 + menu/menu_driver.h | 1 + msg_hash.h | 1 + 9 files changed, 95 insertions(+) create mode 100644 gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h diff --git a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h new file mode 100644 index 0000000000..f2bd97f6df --- /dev/null +++ b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h @@ -0,0 +1,65 @@ +/* credits to: TheTimJames + https://www.shadertoy.com/view/Md2GRw +*/ + +#include "shaders_common.h" + +static const char* stock_fragment_xmb_snowflake = GLSL( + uniform float time; + uniform float atime; + uniform vec2 OutputSize; + vec2 uv; + + float rand(vec2 co) + { + return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); + } + + float snow(vec3 pos, vec2 uv, float o) + { + vec2 d = (pos.xy - uv); + float a = atan(d.y,d.x)+sin(atime*1.+o)*10.; + + float dist = d.x*d.x + d.y*d.y; + + if(dist < pos.z/400.){ + float col = 0.0; + if(sin(a*8.) < 0.0){col=1.0;} + if(distprg[VIDEO_SHADER_MENU_5].id, &glsl->uniforms[VIDEO_SHADER_MENU_5]); + +#if defined(HAVE_OPENGLES) + shader_prog_info.vertex = stock_vertex_xmb_snow_modern; +#else + shader_prog_info.vertex = glsl_core ? stock_vertex_xmb_snow_modern : stock_vertex_xmb_snow_legacy; +#endif + shader_prog_info.fragment = stock_fragment_xmb_snowflake; + + gl_glsl_compile_program( + glsl, + VIDEO_SHADER_MENU_6, + &glsl->prg[VIDEO_SHADER_MENU_6], + &shader_prog_info); + gl_glsl_find_uniforms(glsl, 0, glsl->prg[VIDEO_SHADER_MENU_6].id, + &glsl->uniforms[VIDEO_SHADER_MENU_6]); #endif gl_glsl_reset_attrib(glsl); diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 0267c11e6d..6836ede817 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -56,6 +56,7 @@ #define VIDEO_SHADER_MENU_3 (GFX_MAX_SHADERS - 4) #define VIDEO_SHADER_MENU_4 (GFX_MAX_SHADERS - 5) #define VIDEO_SHADER_MENU_5 (GFX_MAX_SHADERS - 6) +#define VIDEO_SHADER_MENU_6 (GFX_MAX_SHADERS - 7) #endif diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 5fb03ee34b..25a36dda4f 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -2542,6 +2542,8 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, "Bokeh") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "Snowflake") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, "Refresh Room List") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 7c42baa346..5b98e95554 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -246,6 +246,10 @@ static void menu_action_setting_disp_set_label_pipeline( strlcpy(s, msg_hash_to_str( MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH), len); + case XMB_SHADER_PIPELINE_SNOWFLAKE: + strlcpy(s, + msg_hash_to_str( + MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE), len); break; } diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 0392da6f34..0185ec76ee 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2759,6 +2759,9 @@ static void xmb_draw_bg( case XMB_SHADER_PIPELINE_BOKEH: draw.pipeline.id = VIDEO_SHADER_MENU_5; break; + case XMB_SHADER_PIPELINE_SNOWFLAKE: + draw.pipeline.id = VIDEO_SHADER_MENU_6; + break; default: break; } diff --git a/menu/drivers_display/menu_display_gl.c b/menu/drivers_display/menu_display_gl.c index 65cf522115..d1d57b7075 100644 --- a/menu/drivers_display/menu_display_gl.c +++ b/menu/drivers_display/menu_display_gl.c @@ -185,6 +185,7 @@ static void menu_display_gl_draw_pipeline(void *data) case VIDEO_SHADER_MENU_3: case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: shader_info.data = NULL; shader_info.idx = draw->pipeline.id; shader_info.set_active = true; @@ -215,6 +216,7 @@ static void menu_display_gl_draw_pipeline(void *data) case VIDEO_SHADER_MENU_3: case VIDEO_SHADER_MENU_4: case VIDEO_SHADER_MENU_5: + case VIDEO_SHADER_MENU_6: #ifndef HAVE_PSGL uniform_param.type = UNIFORM_2F; uniform_param.lookup.ident = "OutputSize"; diff --git a/menu/menu_driver.h b/menu/menu_driver.h index d660ccbb4b..f2d3db313f 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -260,6 +260,7 @@ enum xmb_shader_pipeline XMB_SHADER_PIPELINE_SIMPLE_SNOW, XMB_SHADER_PIPELINE_SNOW, XMB_SHADER_PIPELINE_BOKEH, + XMB_SHADER_PIPELINE_SNOWFLAKE, XMB_SHADER_PIPELINE_LAST }; diff --git a/msg_hash.h b/msg_hash.h index fdd00470e1..f9e92af1d3 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -447,6 +447,7 @@ enum msg_hash_enums MENU_LABEL(SHADER_PIPELINE_SIMPLE_SNOW), MENU_LABEL(SHADER_PIPELINE_SNOW), MENU_LABEL(SHADER_PIPELINE_BOKEH), + MENU_LABEL(SHADER_PIPELINE_SNOWFLAKE), MENU_LABEL(MATERIALUI_MENU_HEADER_OPACITY), MENU_LABEL(MATERIALUI_MENU_FOOTER_OPACITY), From 3cd7026819286e2ced5adcfa267207290a73a9fd Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 3 Dec 2017 12:19:00 -0500 Subject: [PATCH 012/698] fix the shader and the label --- gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h | 8 ++++---- menu/cbs/menu_cbs_get_value.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h index f2bd97f6df..a5426710ba 100644 --- a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h +++ b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h @@ -15,6 +15,8 @@ static const char* stock_fragment_xmb_snowflake = GLSL( return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); } + float rand(float x){ return rand(vec2(x,1.0));} + float snow(vec3 pos, vec2 uv, float o) { vec2 d = (pos.xy - uv); @@ -35,17 +37,15 @@ static const char* stock_fragment_xmb_snowflake = GLSL( float col(vec2 c) { float color = 0.0; - for (int i = 1; i < 15; i++) + for (int i = 1; i < 50; i++) { - float o = rand(float(i) / 3.) * 15 * 2.0; + float o = rand(float(i) / 3.0) * 15 * 2.0; float z = rand(float(i) + 13.0); float x = 1.8 - (3.6) * (rand(floor((time*((z+1.0)/2.0)+o)/2.0)) + sin(time*o/1000.0)/10.0); float y = 1.0-mod((time*((z+1.0)/2.0))+o, 2.0); color += snow(vec3(x,y,z),c,o); } - - return color; } diff --git a/menu/cbs/menu_cbs_get_value.c b/menu/cbs/menu_cbs_get_value.c index 5b98e95554..d58701f8e3 100644 --- a/menu/cbs/menu_cbs_get_value.c +++ b/menu/cbs/menu_cbs_get_value.c @@ -246,6 +246,7 @@ static void menu_action_setting_disp_set_label_pipeline( strlcpy(s, msg_hash_to_str( MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH), len); + break; case XMB_SHADER_PIPELINE_SNOWFLAKE: strlcpy(s, msg_hash_to_str( From 2747067f6188d0e4f845c6ceb5d39a33ab193b87 Mon Sep 17 00:00:00 2001 From: radius Date: Sun, 3 Dec 2017 15:10:24 -0500 Subject: [PATCH 013/698] this probably fixes the shader on noveau and others --- .../gl_shaders/pipeline_snowflake.glsl.frag.h | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h index a5426710ba..1b048d2223 100644 --- a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h +++ b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h @@ -6,29 +6,40 @@ static const char* stock_fragment_xmb_snowflake = GLSL( uniform float time; - uniform float atime; uniform vec2 OutputSize; vec2 uv; + float atime; + float rand(vec2 co) { return fract(sin(dot(co.xy, vec2(12.9898, 78.233))) * 43758.5453); } - float rand(float x){ return rand(vec2(x,1.0));} + float rand_float(float x) + { + return rand(vec2(x, 1.0)); + } float snow(vec3 pos, vec2 uv, float o) { vec2 d = (pos.xy - uv); - float a = atan(d.y,d.x)+sin(atime*1.+o)*10.; + float a = atan(d.y,d.x) + sin(atime*1.0 + o) * 10.0; float dist = d.x*d.x + d.y*d.y; - if(dist < pos.z/400.){ + if(dist < pos.z/400.0) + { float col = 0.0; - if(sin(a*8.) < 0.0){col=1.0;} - if(dist Date: Mon, 4 Dec 2017 02:48:08 +0100 Subject: [PATCH 014/698] OSX PowerPC might not define O_CLOEXEC --- libretro-common/file/nbio/nbio_unixmmap.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/libretro-common/file/nbio/nbio_unixmmap.c b/libretro-common/file/nbio/nbio_unixmmap.c index 40703ae138..80325da393 100644 --- a/libretro-common/file/nbio/nbio_unixmmap.c +++ b/libretro-common/file/nbio/nbio_unixmmap.c @@ -39,6 +39,20 @@ #include #include +#ifdef __APPLE__ + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0x1000000 +#endif + +#else + +#ifndef O_CLOEXEC +#define O_CLOEXEC 0 +#endif + +#endif + struct nbio_mmap_unix_t { int fd; From 43f6a03110a03ec1216e645645fa087fd91ba96c Mon Sep 17 00:00:00 2001 From: neville Date: Mon, 4 Dec 2017 02:59:06 +0100 Subject: [PATCH 015/698] (OSX PPC) Buildfixes --- gfx/common/gl_common.h | 5 +---- input/input_driver.c | 3 +++ 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 5d5c1fa284..04f2d6e3f4 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -33,15 +33,12 @@ #include "../video_coord_array.h" #include "../video_driver.h" #include "../drivers/gl_symlinks.h" +#include RETRO_BEGIN_DECLS #define MAX_FENCES 4 -#ifndef ARB_sync -typedef struct __GLsync *GLsync; -#endif - typedef struct gl { GLenum internal_fmt; diff --git a/input/input_driver.c b/input/input_driver.c index abfba95a91..b2e216c191 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -806,6 +806,9 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) uint8_t port_max = settings->bools.input_all_users_control_menu ? max_users : 1; + + joypad_info.joy_idx = 0; + joypad_info.auto_binds = NULL; RARCH_INPUT_STATE_CLEAR_PTR( p_new_state ); From f53093de4d4e8e5893dd7bd20b30989ea6a2d9dd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 03:12:27 +0100 Subject: [PATCH 016/698] Default to nbio stdio for PowerPC Mac --- libretro-common/file/nbio/nbio_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/file/nbio/nbio_intf.c b/libretro-common/file/nbio/nbio_intf.c index 57d3eb6484..925cd6884e 100644 --- a/libretro-common/file/nbio/nbio_intf.c +++ b/libretro-common/file/nbio/nbio_intf.c @@ -36,7 +36,7 @@ extern nbio_intf_t nbio_stdio; #if defined(_linux__) static nbio_intf_t *internal_nbio = &nbio_linux; -#elif defined(HAVE_MMAP) && defined(BSD) +#elif defined(HAVE_MMAP) && defined(BSD) && !defined(__powerpc__) && !defined(__ppc__) static nbio_intf_t *internal_nbio = &nbio_mmap_unix; #elif defined(_WIN32) && !defined(_XBOX) static nbio_intf_t *internal_nbio = &nbio_mmap_win32; From 0bf461c40ff2a78dc6695f0a56bec8348ba11a93 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 03:27:03 +0100 Subject: [PATCH 017/698] Try to get past OSX PowerPC crash on exit --- gfx/drivers_renderchain/gl2_renderchain.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 0c9733e35f..5f68e6005e 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -420,19 +420,25 @@ static void gl2_renderchain_deinit_fbo(void *data) { gl_t *gl = (gl_t*)data; + if (!gl) + return; + glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - glDeleteFramebuffers(gl->fbo_pass, gl->fbo); + + if (gl->fbo) + glDeleteFramebuffers(gl->fbo_pass, gl->fbo); + memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture)); - memset(gl->fbo, 0, sizeof(gl->fbo)); - gl->fbo_inited = false; - gl->fbo_pass = 0; + memset(gl->fbo, 0, sizeof(gl->fbo)); if (gl->fbo_feedback) glDeleteFramebuffers(1, &gl->fbo_feedback); if (gl->fbo_feedback_texture) glDeleteTextures(1, &gl->fbo_feedback_texture); + gl->fbo_inited = false; gl->fbo_feedback_enable = false; + gl->fbo_pass = 0; gl->fbo_feedback_pass = 0; gl->fbo_feedback_texture = 0; gl->fbo_feedback = 0; From 62215129115cf9e6f5bea6859a52f90cfd7eaad5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:04:07 +0100 Subject: [PATCH 018/698] use EXT version of Framebuffer/Renderbuffer functions for MacOS X PowerPC --- gfx/drivers/gl_symlinks.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/gfx/drivers/gl_symlinks.h b/gfx/drivers/gl_symlinks.h index 8628698f3e..fb84a8b182 100644 --- a/gfx/drivers/gl_symlinks.h +++ b/gfx/drivers/gl_symlinks.h @@ -38,6 +38,17 @@ #define glFramebufferRenderbuffer glFramebufferRenderbufferOES #define glRenderbufferStorage glRenderbufferStorageOES #define glDeleteRenderbuffers glDeleteRenderbuffersOES +#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define glGenFramebuffers glGenFramebuffersEXT +#define glBindFramebuffer glBindFramebufferEXT +#define glFramebufferTexture2D glFramebufferTexture2DEXT +#define glCheckFramebufferStatus glCheckFramebufferStatusEXT +#define glDeleteFramebuffers glDeleteFramebuffersEXT +#define glGenRenderbuffers glGenRenderbuffersEXT +#define glBindRenderbuffer glBindRenderbufferEXT +#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT +#define glRenderbufferStorage glRenderbufferStorageEXT +#define glDeleteRenderbuffers glDeleteRenderbuffersEXT #endif #if defined(HAVE_PSGL) From 52e7a533f096dd71ada1cb3daf691414660fe0a5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:12:46 +0100 Subject: [PATCH 019/698] Improve FBO check --- libretro-common/gfx/gl_capabilities.c | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/libretro-common/gfx/gl_capabilities.c b/libretro-common/gfx/gl_capabilities.c index 221aa2a0b7..695650eee0 100644 --- a/libretro-common/gfx/gl_capabilities.c +++ b/libretro-common/gfx/gl_capabilities.c @@ -179,16 +179,13 @@ bool gl_check_capability(enum gl_capability_enum enum_idx) && !gl_query_extension("EXT_framebuffer_object")) return false; - if (glGenFramebuffers - && glBindFramebuffer - && glFramebufferTexture2D - && glCheckFramebufferStatus - && glDeleteFramebuffers - && glGenRenderbuffers - && glBindRenderbuffer - && glFramebufferRenderbuffer - && glRenderbufferStorage - && glDeleteRenderbuffers) + if (gl_query_extension("ARB_framebuffer_object")) + return true; + + if (gl_query_extension("EXT_framebuffer_object")) + return true; + + if (major >= 3) return true; break; #endif From b2fbb9aeda9bfb270920131ee76fe21464790f89 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:18:28 +0100 Subject: [PATCH 020/698] Prepare to map DeleteFramebuffersEXT like this --- gfx/drivers/gl_symlinks.h | 11 ----------- gfx/drivers_renderchain/gl2_renderchain.c | 4 +--- libretro-common/glsym/glsym_gl.c | 4 ++++ 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/gfx/drivers/gl_symlinks.h b/gfx/drivers/gl_symlinks.h index fb84a8b182..8628698f3e 100644 --- a/gfx/drivers/gl_symlinks.h +++ b/gfx/drivers/gl_symlinks.h @@ -38,17 +38,6 @@ #define glFramebufferRenderbuffer glFramebufferRenderbufferOES #define glRenderbufferStorage glRenderbufferStorageOES #define glDeleteRenderbuffers glDeleteRenderbuffersOES -#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) -#define glGenFramebuffers glGenFramebuffersEXT -#define glBindFramebuffer glBindFramebufferEXT -#define glFramebufferTexture2D glFramebufferTexture2DEXT -#define glCheckFramebufferStatus glCheckFramebufferStatusEXT -#define glDeleteFramebuffers glDeleteFramebuffersEXT -#define glGenRenderbuffers glGenRenderbuffersEXT -#define glBindRenderbuffer glBindRenderbufferEXT -#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT -#define glRenderbufferStorage glRenderbufferStorageEXT -#define glDeleteRenderbuffers glDeleteRenderbuffersEXT #endif #if defined(HAVE_PSGL) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 5f68e6005e..69b70b71fa 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -424,9 +424,7 @@ static void gl2_renderchain_deinit_fbo(void *data) return; glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - - if (gl->fbo) - glDeleteFramebuffers(gl->fbo_pass, gl->fbo); + glDeleteFramebuffers(gl->fbo_pass, gl->fbo); memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture)); memset(gl->fbo, 0, sizeof(gl->fbo)); diff --git a/libretro-common/glsym/glsym_gl.c b/libretro-common/glsym/glsym_gl.c index 5aa92fdca2..41680ffcd1 100644 --- a/libretro-common/glsym/glsym_gl.c +++ b/libretro-common/glsym/glsym_gl.c @@ -308,7 +308,11 @@ const struct rglgen_sym_map rglgen_symbol_map[] = { SYM(GetRenderbufferParameteriv), SYM(IsFramebuffer), SYM(BindFramebuffer), +#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) + SYM(DeleteFramebuffersEXT), +#else SYM(DeleteFramebuffers), +#endif SYM(GenFramebuffers), SYM(CheckFramebufferStatus), SYM(FramebufferTexture1D), From e9af9f1b092a24699fc6023817d8ae21fc582a55 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:20:54 +0100 Subject: [PATCH 021/698] Add EXT version --- libretro-common/glsym/glsym_gl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro-common/glsym/glsym_gl.c b/libretro-common/glsym/glsym_gl.c index 41680ffcd1..585e7c320c 100644 --- a/libretro-common/glsym/glsym_gl.c +++ b/libretro-common/glsym/glsym_gl.c @@ -1341,6 +1341,7 @@ RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC __rglgen_glGetRenderbufferParameteriv; RGLSYMGLISFRAMEBUFFERPROC __rglgen_glIsFramebuffer; RGLSYMGLBINDFRAMEBUFFERPROC __rglgen_glBindFramebuffer; RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffers; +RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffersEXT; RGLSYMGLGENFRAMEBUFFERSPROC __rglgen_glGenFramebuffers; RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC __rglgen_glCheckFramebufferStatus; RGLSYMGLFRAMEBUFFERTEXTURE1DPROC __rglgen_glFramebufferTexture1D; From 19d7afd0c26778fc1e50dab9f31fd72048c75c57 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:30:28 +0100 Subject: [PATCH 022/698] remove --- libretro-common/glsym/glsym_gl.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libretro-common/glsym/glsym_gl.c b/libretro-common/glsym/glsym_gl.c index 585e7c320c..5aa92fdca2 100644 --- a/libretro-common/glsym/glsym_gl.c +++ b/libretro-common/glsym/glsym_gl.c @@ -308,11 +308,7 @@ const struct rglgen_sym_map rglgen_symbol_map[] = { SYM(GetRenderbufferParameteriv), SYM(IsFramebuffer), SYM(BindFramebuffer), -#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) - SYM(DeleteFramebuffersEXT), -#else SYM(DeleteFramebuffers), -#endif SYM(GenFramebuffers), SYM(CheckFramebufferStatus), SYM(FramebufferTexture1D), @@ -1341,7 +1337,6 @@ RGLSYMGLGETRENDERBUFFERPARAMETERIVPROC __rglgen_glGetRenderbufferParameteriv; RGLSYMGLISFRAMEBUFFERPROC __rglgen_glIsFramebuffer; RGLSYMGLBINDFRAMEBUFFERPROC __rglgen_glBindFramebuffer; RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffers; -RGLSYMGLDELETEFRAMEBUFFERSPROC __rglgen_glDeleteFramebuffersEXT; RGLSYMGLGENFRAMEBUFFERSPROC __rglgen_glGenFramebuffers; RGLSYMGLCHECKFRAMEBUFFERSTATUSPROC __rglgen_glCheckFramebufferStatus; RGLSYMGLFRAMEBUFFERTEXTURE1DPROC __rglgen_glFramebufferTexture1D; From 44f3341ffe20323e2ed4b357e5b0dc33cfc3131f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:42:40 +0100 Subject: [PATCH 023/698] Add EXT versions for OSX PPC --- gfx/drivers_renderchain/gl2_renderchain.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 69b70b71fa..22eb9bc558 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -67,7 +67,14 @@ typedef struct gl2_renderchain coords[5] = yamt; \ coords[7] = yamt -#define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id) +#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define gl2_delete_fb(n, fb) glDeleteFramebuffersEXT(n, fb) +#define gl2_bind_fb(id) glBindFramebufferEXT(RARCH_GL_FRAMEBUFFER, id) +#else +#define gl2_delete_fb(n, fb) glDeleteFramebuffers(n, fb) +#define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id) +#endif + #ifndef GL_SYNC_GPU_COMMANDS_COMPLETE #define GL_SYNC_GPU_COMMANDS_COMPLETE 0x9117 @@ -424,13 +431,13 @@ static void gl2_renderchain_deinit_fbo(void *data) return; glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - glDeleteFramebuffers(gl->fbo_pass, gl->fbo); + gl2_delete_fb(gl->fbo_pass, gl->fbo); memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture)); memset(gl->fbo, 0, sizeof(gl->fbo)); if (gl->fbo_feedback) - glDeleteFramebuffers(1, &gl->fbo_feedback); + gl2_delete_fb(1, &gl->fbo_feedback); if (gl->fbo_feedback_texture) glDeleteTextures(1, &gl->fbo_feedback_texture); @@ -451,7 +458,7 @@ static void gl2_renderchain_deinit_hw_render(void *data) context_bind_hw_render(true); if (gl->hw_render_fbo_init) - glDeleteFramebuffers(gl->textures, gl->hw_render_fbo); + gl2_delete_fb(gl->textures, gl->hw_render_fbo); if (gl->hw_render_depth_init) glDeleteRenderbuffers(gl->textures, gl->hw_render_depth); gl->hw_render_fbo_init = false; @@ -510,9 +517,9 @@ static bool gl_create_fbo_targets(gl_t *gl) return true; error: - glDeleteFramebuffers(gl->fbo_pass, gl->fbo); + gl2_delete_fb(gl->fbo_pass, gl->fbo); if (gl->fbo_feedback) - glDeleteFramebuffers(1, &gl->fbo_feedback); + gl2_delete_fb(1, &gl->fbo_feedback); RARCH_ERR("[GL]: Failed to set up frame buffer objects. Multi-pass shading will not work.\n"); return false; } From 5a341acb5fe0dee96920ef2e7e32e1dbd8762985 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 04:57:58 +0100 Subject: [PATCH 024/698] Wrap more GL framebuffer functions --- gfx/drivers_renderchain/gl2_renderchain.c | 28 ++++++++++++++--------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 22eb9bc558..82038df196 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -68,9 +68,15 @@ typedef struct gl2_renderchain coords[7] = yamt #if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2DEXT(a, b, c, d, e) +#define gl2_check_fb_status(target) glCheckFramebufferStatusEXT(target) +#define gl2_gen_fb(n, ids) glGenFramebuffersEXT(n, ids) #define gl2_delete_fb(n, fb) glDeleteFramebuffersEXT(n, fb) #define gl2_bind_fb(id) glBindFramebufferEXT(RARCH_GL_FRAMEBUFFER, id) #else +#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2D(a, b, c, d, e) +#define gl2_check_fb_status(target) glCheckFramebufferStatus(target) +#define gl2_gen_fb(n, ids) glGenFramebuffers(n, ids) #define gl2_delete_fb(n, fb) glDeleteFramebuffers(n, fb) #define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id) #endif @@ -176,11 +182,11 @@ static bool gl_recreate_fbo( 0, RARCH_GL_TEXTURE_TYPE32, RARCH_GL_FORMAT32, NULL); - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0); - if (glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER) + if (gl2_check_fb_status(RARCH_GL_FRAMEBUFFER) == RARCH_GL_FRAMEBUFFER_COMPLETE) return true; @@ -479,17 +485,17 @@ static bool gl_create_fbo_targets(gl_t *gl) int i; glBindTexture(GL_TEXTURE_2D, 0); - glGenFramebuffers(gl->fbo_pass, gl->fbo); + gl2_gen_fb(gl->fbo_pass, gl->fbo); for (i = 0; i < gl->fbo_pass; i++) { GLenum status; gl2_bind_fb(gl->fbo[i]); - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0); - status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); + status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER); if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) goto error; } @@ -498,13 +504,13 @@ static bool gl_create_fbo_targets(gl_t *gl) { GLenum status; - glGenFramebuffers(1, &gl->fbo_feedback); + gl2_gen_fb(1, &gl->fbo_feedback); gl2_bind_fb(gl->fbo_feedback); - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_feedback_texture, 0); - status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); + status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER); if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) goto error; @@ -883,7 +889,7 @@ static bool gl2_renderchain_init_hw_render( RARCH_LOG("[GL]: Supports FBO (render-to-texture).\n"); glBindTexture(GL_TEXTURE_2D, 0); - glGenFramebuffers(gl->textures, gl->hw_render_fbo); + gl2_gen_fb(gl->textures, gl->hw_render_fbo); depth = hwr->depth; stencil = hwr->stencil; @@ -897,7 +903,7 @@ static bool gl2_renderchain_init_hw_render( for (i = 0; i < gl->textures; i++) { gl2_bind_fb(gl->hw_render_fbo[i]); - glFramebufferTexture2D(RARCH_GL_FRAMEBUFFER, + gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->texture[i], 0); if (depth) @@ -934,7 +940,7 @@ static bool gl2_renderchain_init_hw_render( } } - status = glCheckFramebufferStatus(RARCH_GL_FRAMEBUFFER); + status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER); if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) { RARCH_ERR("[GL]: Failed to create HW render FBO #%u, error: 0x%u.\n", From c869cc51025d7ac04ded8825c64720fd5aa74ce4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 05:55:18 +0100 Subject: [PATCH 025/698] Refactor GL code --- gfx/common/gl_common.c | 2 + gfx/drivers/gl.c | 1 + gfx/drivers/gl_symlinks.h | 15 -------- gfx/drivers_renderchain/gl2_renderchain.c | 46 ++++++++++++++++++----- 4 files changed, 39 insertions(+), 25 deletions(-) diff --git a/gfx/common/gl_common.c b/gfx/common/gl_common.c index f349938427..bf8aab5059 100644 --- a/gfx/common/gl_common.c +++ b/gfx/common/gl_common.c @@ -21,6 +21,8 @@ #include "../../config.h" #endif +#include + #include "../drivers/gl_symlinks.h" #include "../video_coord_array.h" diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 8c2d230194..ba037d574d 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -40,6 +40,7 @@ #include #include +#include #include "../../configuration.h" #include "../../dynamic.h" diff --git a/gfx/drivers/gl_symlinks.h b/gfx/drivers/gl_symlinks.h index 8628698f3e..91d618776d 100644 --- a/gfx/drivers/gl_symlinks.h +++ b/gfx/drivers/gl_symlinks.h @@ -21,25 +21,10 @@ #include #include -#include - #ifdef HAVE_CONFIG_H #include "config.h" #endif -#if defined(HAVE_PSGL) -#define glGenFramebuffers glGenFramebuffersOES -#define glBindFramebuffer glBindFramebufferOES -#define glFramebufferTexture2D glFramebufferTexture2DOES -#define glCheckFramebufferStatus glCheckFramebufferStatusOES -#define glDeleteFramebuffers glDeleteFramebuffersOES -#define glGenRenderbuffers glGenRenderbuffersOES -#define glBindRenderbuffer glBindRenderbufferOES -#define glFramebufferRenderbuffer glFramebufferRenderbufferOES -#define glRenderbufferStorage glRenderbufferStorageOES -#define glDeleteRenderbuffers glDeleteRenderbuffersOES -#endif - #if defined(HAVE_PSGL) #define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES #define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 82038df196..a9320732b3 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -41,6 +41,7 @@ #include #include +#include #include "../video_driver.h" #include "../video_shader_parse.h" @@ -67,18 +68,43 @@ typedef struct gl2_renderchain coords[5] = yamt; \ coords[7] = yamt -#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#if defined(HAVE_PSGL) +#define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2DOES(a, b, c, d, e) +#define gl2_check_fb_status(target) glCheckFramebufferStatusOES(target) +#define gl2_gen_fb(n, ids) glGenFramebuffersOES(n, ids) +#define gl2_delete_fb(n, fb) glDeleteFramebuffersOES(n, fb) +#define gl2_bind_fb(id) glBindFramebufferOES(RARCH_GL_FRAMEBUFFER, id) +#define gl2_gen_rb glGenRenderbuffersOES +#define gl2_bind_rb glBindRenderbufferOES +#define gl2_fb_rb glFramebufferRenderbufferOES +#define gl2_rb_storage glRenderbufferStorageOES +#define gl2_delete_rb glDeleteRenderbuffersOES + +#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) #define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2DEXT(a, b, c, d, e) #define gl2_check_fb_status(target) glCheckFramebufferStatusEXT(target) #define gl2_gen_fb(n, ids) glGenFramebuffersEXT(n, ids) #define gl2_delete_fb(n, fb) glDeleteFramebuffersEXT(n, fb) #define gl2_bind_fb(id) glBindFramebufferEXT(RARCH_GL_FRAMEBUFFER, id) +#define gl2_gen_rb glGenRenderbuffersEXT +#define gl2_bind_rb glBindRenderbufferEXT +#define gl2_fb_rb glFramebufferRenderbufferEXT +#define gl2_rb_storage glRenderbufferStorageEXT +#define gl2_delete_rb glDeleteRenderbuffersEXT + #else + #define gl2_fb_texture_2d(a, b, c, d, e) glFramebufferTexture2D(a, b, c, d, e) #define gl2_check_fb_status(target) glCheckFramebufferStatus(target) #define gl2_gen_fb(n, ids) glGenFramebuffers(n, ids) #define gl2_delete_fb(n, fb) glDeleteFramebuffers(n, fb) #define gl2_bind_fb(id) glBindFramebuffer(RARCH_GL_FRAMEBUFFER, id) +#define gl2_gen_rb glGenRenderbuffers +#define gl2_bind_rb glBindRenderbuffer +#define gl2_fb_rb glFramebufferRenderbuffer +#define gl2_rb_storage glRenderbufferStorage +#define gl2_delete_rb glDeleteRenderbuffers + #endif @@ -466,7 +492,7 @@ static void gl2_renderchain_deinit_hw_render(void *data) if (gl->hw_render_fbo_init) gl2_delete_fb(gl->textures, gl->hw_render_fbo); if (gl->hw_render_depth_init) - glDeleteRenderbuffers(gl->textures, gl->hw_render_depth); + gl2_delete_rb(gl->textures, gl->hw_render_depth); gl->hw_render_fbo_init = false; context_bind_hw_render(false); @@ -896,7 +922,7 @@ static bool gl2_renderchain_init_hw_render( if (depth) { - glGenRenderbuffers(gl->textures, gl->hw_render_depth); + gl2_gen_rb(gl->textures, gl->hw_render_depth); gl->hw_render_depth_init = true; } @@ -908,33 +934,33 @@ static bool gl2_renderchain_init_hw_render( if (depth) { - glBindRenderbuffer(RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); - glRenderbufferStorage(RARCH_GL_RENDERBUFFER, + gl2_bind_rb(RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + gl2_rb_storage(RARCH_GL_RENDERBUFFER, stencil ? RARCH_GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16, width, height); - glBindRenderbuffer(RARCH_GL_RENDERBUFFER, 0); + gl2_bind_rb(RARCH_GL_RENDERBUFFER, 0); if (stencil) { #if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES1) || ((defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__)))) /* GLES2 is a bit weird, as always. * There's no GL_DEPTH_STENCIL_ATTACHMENT like in desktop GL. */ - glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER, + gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_DEPTH_ATTACHMENT, RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); - glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER, + gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_STENCIL_ATTACHMENT, RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); #else /* We use ARB FBO extensions, no need to check. */ - glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER, + gl2_fb_rb(RARCH_GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); #endif } else { - glFramebufferRenderbuffer(RARCH_GL_FRAMEBUFFER, + gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_DEPTH_ATTACHMENT, RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); } From 9558e569f10f924321c6c9541144cd505b2573c9 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 05:56:03 +0100 Subject: [PATCH 026/698] We can still make use of this for PowerPC Mac --- libretro-common/file/nbio/nbio_intf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/file/nbio/nbio_intf.c b/libretro-common/file/nbio/nbio_intf.c index 925cd6884e..57d3eb6484 100644 --- a/libretro-common/file/nbio/nbio_intf.c +++ b/libretro-common/file/nbio/nbio_intf.c @@ -36,7 +36,7 @@ extern nbio_intf_t nbio_stdio; #if defined(_linux__) static nbio_intf_t *internal_nbio = &nbio_linux; -#elif defined(HAVE_MMAP) && defined(BSD) && !defined(__powerpc__) && !defined(__ppc__) +#elif defined(HAVE_MMAP) && defined(BSD) static nbio_intf_t *internal_nbio = &nbio_mmap_unix; #elif defined(_WIN32) && !defined(_XBOX) static nbio_intf_t *internal_nbio = &nbio_mmap_win32; From 512a1b4cb65ac1294b84b0b3453ab4f5fc68262d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 06:03:11 +0100 Subject: [PATCH 027/698] Cleanups --- gfx/common/gl_common.c | 7 +- gfx/common/gl_common.h | 119 ++++++++++++++++++++++++++++++- gfx/drivers/gl_symlinks.h | 144 -------------------------------------- 3 files changed, 119 insertions(+), 151 deletions(-) delete mode 100644 gfx/drivers/gl_symlinks.h diff --git a/gfx/common/gl_common.c b/gfx/common/gl_common.c index bf8aab5059..10c139bef0 100644 --- a/gfx/common/gl_common.c +++ b/gfx/common/gl_common.c @@ -14,18 +14,13 @@ * If not, see . */ -#include #include #ifdef HAVE_CONFIG_H #include "../../config.h" #endif -#include - -#include "../drivers/gl_symlinks.h" -#include "../video_coord_array.h" - +#include "gl_common.h" static void gl_size_format(GLint* internalFormat) { diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 04f2d6e3f4..7eb88af66e 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -17,7 +17,9 @@ #ifndef __GL_COMMON_H #define __GL_COMMON_H +#include #include +#include #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -32,13 +34,128 @@ #include "../font_driver.h" #include "../video_coord_array.h" #include "../video_driver.h" -#include "../drivers/gl_symlinks.h" #include RETRO_BEGIN_DECLS #define MAX_FENCES 4 +#if defined(HAVE_PSGL) +#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES +#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES +#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT +#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT +#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT +#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT +#else +#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER +#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE +#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0 +#endif + +#if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1) || defined(HAVE_OPENGLES_3_2) +#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER +#if defined(HAVE_OPENGLES2) +#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES +#else +#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8 +#endif +#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT +#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT +#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_EXT +#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT +#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT +#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT +#elif defined(HAVE_PSGL) +#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_OES +#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_SCE +#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES +#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES +#else +#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER +#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8 +#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT +#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT +#endif + +#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) +#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_EXT +#elif defined(HAVE_PSGL) +#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_OES +#else +#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE +#endif + +#if defined(HAVE_PSGL) +#define glGenerateMipmap glGenerateMipmapOES +#endif + +#if defined(__APPLE__) || defined(HAVE_PSGL) +#define GL_RGBA32F GL_RGBA32F_ARB +#endif + +#if defined(HAVE_PSGL) +#define RARCH_GL_INTERNAL_FORMAT32 GL_ARGB_SCE +#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB5 /* TODO: Verify if this is really 565 or just 555. */ +#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA +#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA +#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV +#define RARCH_GL_FORMAT16 GL_RGB5 +#elif defined(HAVE_OPENGLES) +/* Imgtec/SGX headers have this missing. */ +#ifndef GL_BGRA_EXT +#define GL_BGRA_EXT 0x80E1 +#endif +#ifndef GL_BGRA8_EXT +#define GL_BGRA8_EXT 0x93A1 +#endif +#ifdef IOS +/* Stupid Apple */ +#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA +#else +#define RARCH_GL_INTERNAL_FORMAT32 GL_BGRA_EXT +#endif +#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB +#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA_EXT +#define RARCH_GL_TEXTURE_TYPE16 GL_RGB +#define RARCH_GL_FORMAT32 GL_UNSIGNED_BYTE +#define RARCH_GL_FORMAT16 GL_UNSIGNED_SHORT_5_6_5 +#else +/* On desktop, we always use 32-bit. */ +#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA8 +#define RARCH_GL_INTERNAL_FORMAT16 GL_RGBA8 +#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA +#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA +#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV +#define RARCH_GL_FORMAT16 GL_UNSIGNED_INT_8_8_8_8_REV + +/* GL_RGB565 internal format isn't in desktop GL + * until 4.1 core (ARB_ES2_compatibility). + * Check for this. */ +#ifndef GL_RGB565 +#define GL_RGB565 0x8D62 +#endif +#define RARCH_GL_INTERNAL_FORMAT16_565 GL_RGB565 +#define RARCH_GL_TEXTURE_TYPE16_565 GL_RGB +#define RARCH_GL_FORMAT16_565 GL_UNSIGNED_SHORT_5_6_5 +#endif + +#if defined(HAVE_OPENGLES2) /* TODO: Figure out exactly what. */ +#define NO_GL_CLAMP_TO_BORDER +#endif + +#if defined(HAVE_OPENGLES) +#ifndef GL_UNPACK_ROW_LENGTH +#define GL_UNPACK_ROW_LENGTH 0x0CF2 +#endif + +#ifndef GL_SRGB_ALPHA_EXT +#define GL_SRGB_ALPHA_EXT 0x8C42 +#endif +#endif + typedef struct gl { GLenum internal_fmt; diff --git a/gfx/drivers/gl_symlinks.h b/gfx/drivers/gl_symlinks.h deleted file mode 100644 index 91d618776d..0000000000 --- a/gfx/drivers/gl_symlinks.h +++ /dev/null @@ -1,144 +0,0 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * Copyright (C) 2011-2017 - Daniel De Matteis - * Copyright (C) 2012-2015 - 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- - * 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 _GL_SYMLINKS_H -#define _GL_SYMLINKS_H - -#include -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#if defined(HAVE_PSGL) -#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES -#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES -#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT -#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) -#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT -#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT -#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT -#else -#define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER -#define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE -#define RARCH_GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0 -#endif - -#if defined(HAVE_OPENGLES2) || defined(HAVE_OPENGLES3) || defined(HAVE_OPENGLES_3_1) || defined(HAVE_OPENGLES_3_2) -#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER -#if defined(HAVE_OPENGLES2) -#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_OES -#else -#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8 -#endif -#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT -#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT -#elif (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) -#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_EXT -#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT -#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT -#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT -#elif defined(HAVE_PSGL) -#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER_OES -#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_SCE -#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_OES -#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_OES -#else -#define RARCH_GL_RENDERBUFFER GL_RENDERBUFFER -#define RARCH_GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8 -#define RARCH_GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT -#define RARCH_GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT -#endif - -#if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) -#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_EXT -#elif defined(HAVE_PSGL) -#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE_OES -#else -#define RARCH_GL_MAX_RENDERBUFFER_SIZE GL_MAX_RENDERBUFFER_SIZE -#endif - -#if defined(HAVE_PSGL) -#define glGenerateMipmap glGenerateMipmapOES -#endif - -#if defined(__APPLE__) || defined(HAVE_PSGL) -#define GL_RGBA32F GL_RGBA32F_ARB -#endif - -#if defined(HAVE_PSGL) -#define RARCH_GL_INTERNAL_FORMAT32 GL_ARGB_SCE -#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB5 /* TODO: Verify if this is really 565 or just 555. */ -#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA -#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA -#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV -#define RARCH_GL_FORMAT16 GL_RGB5 -#elif defined(HAVE_OPENGLES) -/* Imgtec/SGX headers have this missing. */ -#ifndef GL_BGRA_EXT -#define GL_BGRA_EXT 0x80E1 -#endif -#ifndef GL_BGRA8_EXT -#define GL_BGRA8_EXT 0x93A1 -#endif -#ifdef IOS -/* Stupid Apple */ -#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA -#else -#define RARCH_GL_INTERNAL_FORMAT32 GL_BGRA_EXT -#endif -#define RARCH_GL_INTERNAL_FORMAT16 GL_RGB -#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA_EXT -#define RARCH_GL_TEXTURE_TYPE16 GL_RGB -#define RARCH_GL_FORMAT32 GL_UNSIGNED_BYTE -#define RARCH_GL_FORMAT16 GL_UNSIGNED_SHORT_5_6_5 -#else -/* On desktop, we always use 32-bit. */ -#define RARCH_GL_INTERNAL_FORMAT32 GL_RGBA8 -#define RARCH_GL_INTERNAL_FORMAT16 GL_RGBA8 -#define RARCH_GL_TEXTURE_TYPE32 GL_BGRA -#define RARCH_GL_TEXTURE_TYPE16 GL_BGRA -#define RARCH_GL_FORMAT32 GL_UNSIGNED_INT_8_8_8_8_REV -#define RARCH_GL_FORMAT16 GL_UNSIGNED_INT_8_8_8_8_REV - -/* GL_RGB565 internal format isn't in desktop GL - * until 4.1 core (ARB_ES2_compatibility). - * Check for this. */ -#ifndef GL_RGB565 -#define GL_RGB565 0x8D62 -#endif -#define RARCH_GL_INTERNAL_FORMAT16_565 GL_RGB565 -#define RARCH_GL_TEXTURE_TYPE16_565 GL_RGB -#define RARCH_GL_FORMAT16_565 GL_UNSIGNED_SHORT_5_6_5 -#endif - -#if defined(HAVE_OPENGLES2) /* TODO: Figure out exactly what. */ -#define NO_GL_CLAMP_TO_BORDER -#endif - -#if defined(HAVE_OPENGLES) -#ifndef GL_UNPACK_ROW_LENGTH -#define GL_UNPACK_ROW_LENGTH 0x0CF2 -#endif - -#ifndef GL_SRGB_ALPHA_EXT -#define GL_SRGB_ALPHA_EXT 0x8C42 -#endif -#endif - -#endif From 4e342956c10e774363666157bfe58a6e97f83374 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 06:13:01 +0100 Subject: [PATCH 028/698] Update comment --- gfx/drivers_renderchain/gl1_renderchain.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index 04e8fa6199..9cc36d8a36 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -108,14 +108,12 @@ static bool gl1_renderchain_read_viewport( /* Use slow synchronous readbacks. Use this with plain screenshots as we don't really care about performance in this case. */ - /* GLES2 only guarantees GL_RGBA/GL_UNSIGNED_BYTE + /* GL1 only guarantees GL_RGBA/GL_UNSIGNED_BYTE * readbacks so do just that. - * GLES2 also doesn't support reading back data + * GL1 also doesn't support reading back data * from front buffer, so render a cached frame * and have gl_frame() do the readback while it's * in the back buffer. - * - * Keep codepath similar for GLES and desktop GL. */ gl->readback_buffer_screenshot = malloc(num_pixels * sizeof(uint32_t)); From 241df59771d5b9d1048162b15c7c53fdd38a48f8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 11:20:18 +0100 Subject: [PATCH 029/698] Get rid of include --- gfx/video_driver.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/gfx/video_driver.c b/gfx/video_driver.c index d06252fb90..c4174e6726 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -46,10 +46,6 @@ #include "../menu/menu_setting.h" #endif -#ifdef HAVE_OPENGL -#include "common/gl_common.h" -#endif - #include "video_thread_wrapper.h" #include "video_driver.h" From 05ab278aca22bdbf47773a53618a1598d93ae30a Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 11:54:30 +0100 Subject: [PATCH 030/698] Pass chain userdata to renderchain driver --- gfx/drivers/gl.c | 80 +++++++++++++---------- gfx/drivers_renderchain/gl1_renderchain.c | 4 +- gfx/drivers_renderchain/gl2_renderchain.c | 77 +++++++++++++++------- gfx/video_driver.h | 56 +++++++++------- 4 files changed, 134 insertions(+), 83 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index ba037d574d..3cc6adf629 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -595,7 +595,7 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video) if (gl->renderchain_driver->init_texture_reference) gl->renderchain_driver->init_texture_reference( - gl, i, internal_fmt, + gl, gl->renderchain_data, i, internal_fmt, texture_fmt, texture_type); } @@ -894,11 +894,11 @@ static void gl_pbo_async_readback(gl_t *gl) gl->pbo_readback_valid[gl->pbo_readback_index] = true; if (gl->renderchain_driver->readback) - gl->renderchain_driver->readback(gl, + gl->renderchain_driver->readback(gl, gl->renderchain_data, video_pixel_get_alignment(gl->vp.width * sizeof(uint32_t)), fmt, type, NULL); if (gl->renderchain_driver->unbind_pbo) - gl->renderchain_driver->unbind_pbo(); + gl->renderchain_driver->unbind_pbo(gl, gl->renderchain_data); } static INLINE void gl_draw_texture(gl_t *gl, video_frame_info_t *video_info) @@ -983,7 +983,7 @@ static bool gl_frame(void *data, const void *frame, context_bind_hw_render(false); if (gl->core_context_in_use && gl->renderchain_driver->bind_vao) - gl->renderchain_driver->bind_vao(gl); + gl->renderchain_driver->bind_vao(gl, gl->renderchain_data); video_info->cb_shader_use(gl, video_info->shader_data, 1, true); @@ -997,11 +997,12 @@ static bool gl_frame(void *data, const void *frame, { if (gl->renderchain_driver->recompute_pass_sizes) gl->renderchain_driver->recompute_pass_sizes( - gl, frame_width, frame_height, + gl, gl->renderchain_data, frame_width, frame_height, gl->vp_out_width, gl->vp_out_height); if (gl->renderchain_driver->start_render) - gl->renderchain_driver->start_render(gl, video_info); + gl->renderchain_driver->start_render(gl, gl->renderchain_data, + video_info); } if (gl->should_resize) @@ -1019,12 +1020,14 @@ static bool gl_frame(void *data, const void *frame, if (gl->fbo_inited) { if (gl->renderchain_driver->check_fbo_dimensions) - gl->renderchain_driver->check_fbo_dimensions(gl); + gl->renderchain_driver->check_fbo_dimensions(gl, + gl->renderchain_data); /* Go back to what we're supposed to do, * render to FBO #0. */ if (gl->renderchain_driver->start_render) - gl->renderchain_driver->start_render(gl, video_info); + gl->renderchain_driver->start_render(gl, gl->renderchain_data, + video_info); } else gl_set_viewport(gl, video_info, width, height, false, true); @@ -1043,7 +1046,7 @@ static bool gl_frame(void *data, const void *frame, gl_update_input_size(gl, frame_width, frame_height, pitch, true); if (gl->renderchain_driver->copy_frame) - gl->renderchain_driver->copy_frame(gl, + gl->renderchain_driver->copy_frame(gl, gl->renderchain_data, video_info, frame, frame_width, frame_height, pitch); } @@ -1061,12 +1064,12 @@ static bool gl_frame(void *data, const void *frame, if (!gl->fbo_inited) { if (gl->renderchain_driver->bind_backbuffer) - gl->renderchain_driver->bind_backbuffer(); + gl->renderchain_driver->bind_backbuffer(gl, gl->renderchain_data); gl_set_viewport(gl, video_info, width, height, false, true); } if (gl->renderchain_driver->restore_default_state) - gl->renderchain_driver->restore_default_state(gl); + gl->renderchain_driver->restore_default_state(gl, gl->renderchain_data); glDisable(GL_STENCIL_TEST); glDisable(GL_BLEND); @@ -1128,12 +1131,14 @@ static bool gl_frame(void *data, const void *frame, glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); if (gl->fbo_inited && gl->renderchain_driver->renderchain_render) - gl->renderchain_driver->renderchain_render(gl, video_info, + gl->renderchain_driver->renderchain_render(gl, gl->renderchain_data, + video_info, frame_count, &gl->tex_info, &feedback_info); /* Set prev textures. */ if (gl->renderchain_driver->bind_prev_texture) - gl->renderchain_driver->bind_prev_texture(gl, &gl->tex_info); + gl->renderchain_driver->bind_prev_texture(gl, gl->renderchain_data, + &gl->tex_info); #if defined(HAVE_MENU) if (gl->menu_texture_enable) @@ -1168,7 +1173,8 @@ static bool gl_frame(void *data, const void *frame, glBindTexture(GL_TEXTURE_2D, 0); if (gl->renderchain_driver->disable_client_arrays) - gl->renderchain_driver->disable_client_arrays(); + gl->renderchain_driver->disable_client_arrays(gl, + gl->renderchain_data); } /* Screenshots. */ @@ -1176,6 +1182,7 @@ static bool gl_frame(void *data, const void *frame, { if (gl->renderchain_driver->readback) gl->renderchain_driver->readback(gl, + gl->renderchain_data, 4, GL_RGBA, GL_UNSIGNED_BYTE, gl->readback_buffer_screenshot); } @@ -1208,12 +1215,14 @@ static bool gl_frame(void *data, const void *frame, if (gl->renderchain_driver->fence_iterate) gl->renderchain_driver->fence_iterate(gl, + gl->renderchain_data, video_info->hard_sync_frames); } if (gl->core_context_in_use && gl->renderchain_driver->unbind_vao) - gl->renderchain_driver->unbind_vao(gl); + gl->renderchain_driver->unbind_vao(gl, + gl->renderchain_data); context_bind_hw_render(true); @@ -1243,7 +1252,7 @@ static void gl_deinit_chain(gl_t *gl) return; if (gl->renderchain_driver->chain_free) - gl->renderchain_driver->chain_free(gl->renderchain_data); + gl->renderchain_driver->chain_free(gl, gl->renderchain_data); gl->renderchain_driver = NULL; gl->renderchain_data = NULL; @@ -1260,14 +1269,14 @@ static void gl_free(void *data) if (gl->have_sync) { if (gl->renderchain_driver->fence_free) - gl->renderchain_driver->fence_free(gl); + gl->renderchain_driver->fence_free(gl, gl->renderchain_data); } font_driver_free_osd(); video_shader_driver_deinit(); if (gl->renderchain_driver->disable_client_arrays) - gl->renderchain_driver->disable_client_arrays(); + gl->renderchain_driver->disable_client_arrays(gl, gl->renderchain_data); glDeleteTextures(gl->textures, gl->texture); @@ -1296,13 +1305,13 @@ static void gl_free(void *data) if (gl->core_context_in_use) { if (gl->renderchain_driver->unbind_vao) - gl->renderchain_driver->unbind_vao(gl); + gl->renderchain_driver->unbind_vao(gl, gl->renderchain_data); if (gl->renderchain_driver->free_vao) - gl->renderchain_driver->free_vao(gl); + gl->renderchain_driver->free_vao(gl, gl->renderchain_data); } if (gl->renderchain_driver->free) - gl->renderchain_driver->free(gl); + gl->renderchain_driver->free(gl, gl->renderchain_data); gl_deinit_chain(gl); video_context_driver_free(); @@ -1464,7 +1473,7 @@ static bool gl_init_pbo_readback(gl_t *gl) gl->vp.height * sizeof(uint32_t), NULL); } if (gl->renderchain_driver->unbind_pbo) - gl->renderchain_driver->unbind_pbo(); + gl->renderchain_driver->unbind_pbo(gl, gl->renderchain_data); #ifndef HAVE_OPENGLES3 { @@ -1776,11 +1785,11 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo } if (gl->renderchain_driver->restore_default_state) - gl->renderchain_driver->restore_default_state(gl); + gl->renderchain_driver->restore_default_state(gl, gl->renderchain_data); if (hwr->context_type == RETRO_HW_CONTEXT_OPENGL_CORE) if (gl->renderchain_driver->new_vao) - gl->renderchain_driver->new_vao(gl); + gl->renderchain_driver->new_vao(gl, gl->renderchain_data); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); @@ -1928,13 +1937,13 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo gl_init_textures_data(gl); if (gl->renderchain_driver->init) - gl->renderchain_driver->init(gl, gl->tex_w, gl->tex_h); + gl->renderchain_driver->init(gl, gl->renderchain_data, gl->tex_w, gl->tex_h); if (gl->has_fbo) { if (gl->hw_render_use && gl->renderchain_driver->init_hw_render && - !gl->renderchain_driver->init_hw_render(gl, gl->tex_w, gl->tex_h)) + !gl->renderchain_driver->init_hw_render(gl, gl->renderchain_data, gl->tex_w, gl->tex_h)) { RARCH_ERR("[GL]: Hardware rendering context initialization failed.\n"); goto error; @@ -2112,7 +2121,7 @@ static bool gl_set_shader(void *data, if (gl->fbo_inited) { if (gl->renderchain_driver->deinit_fbo) - gl->renderchain_driver->deinit_fbo(gl); + gl->renderchain_driver->deinit_fbo(gl, gl->renderchain_data); glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); } @@ -2144,7 +2153,7 @@ static bool gl_set_shader(void *data, { if (gl->hw_render_use && gl->fbo_inited && gl->renderchain_driver->deinit_hw_render) - gl->renderchain_driver->deinit_hw_render(gl); + gl->renderchain_driver->deinit_hw_render(gl, gl->renderchain_data); glDeleteTextures(gl->textures, gl->texture); #if defined(HAVE_PSGL) @@ -2158,11 +2167,13 @@ static bool gl_set_shader(void *data, gl_init_textures_data(gl); if (gl->hw_render_use && gl->renderchain_driver->init_hw_render) - gl->renderchain_driver->init_hw_render(gl, gl->tex_w, gl->tex_h); + gl->renderchain_driver->init_hw_render(gl, gl->renderchain_data, + gl->tex_w, gl->tex_h); } if (gl->renderchain_driver->init) - gl->renderchain_driver->init(gl, gl->tex_w, gl->tex_h); + gl->renderchain_driver->init(gl, gl->renderchain_data, + gl->tex_w, gl->tex_h); /* Apparently need to set viewport for passes when we aren't using FBOs. */ gl_set_shader_viewports(gl); @@ -2186,7 +2197,7 @@ static void gl_viewport_info(void *data, struct video_viewport *vp) gl_t *gl = (gl_t*)data; if (!gl->renderchain_driver || !gl->renderchain_driver->viewport_info) return; - gl->renderchain_driver->viewport_info(data, vp); + gl->renderchain_driver->viewport_info(gl, gl->renderchain_data, vp); } static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle) @@ -2194,7 +2205,8 @@ static bool gl_read_viewport(void *data, uint8_t *buffer, bool is_idle) gl_t *gl = (gl_t*)data; if (!gl->renderchain_driver || !gl->renderchain_driver->read_viewport) return false; - return gl->renderchain_driver->read_viewport(data, buffer, is_idle); + return gl->renderchain_driver->read_viewport(gl, gl->renderchain_data, + buffer, is_idle); } #if 0 @@ -2525,7 +2537,7 @@ static void gl_set_coords(void *handle_data, void *shader_data, { gl_t *gl = (gl_t*)handle_data; if (gl && gl->renderchain_driver->set_coords) - gl->renderchain_driver->set_coords(handle_data, + gl->renderchain_driver->set_coords(gl, gl->renderchain_data, shader_data, coords); } @@ -2534,7 +2546,7 @@ static void gl_set_mvp(void *data, void *shader_data, { gl_t *gl = (gl_t*)data; if (gl && gl->renderchain_driver->set_mvp) - gl->renderchain_driver->set_mvp(data, + gl->renderchain_driver->set_mvp(gl, gl->renderchain_data, shader_data, mat_data); } diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index 9cc36d8a36..04a756db9f 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -57,9 +57,9 @@ typedef struct gl1_renderchain GLenum min_filter_to_mag(GLenum type); -void gl1_renderchain_free(void *data) +void gl1_renderchain_free(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; + (void)chain_data; (void)gl; } diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index a9320732b3..f52f77f5e7 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -117,7 +117,8 @@ typedef struct gl2_renderchain #endif /* Prototypes */ -static void gl2_renderchain_bind_backbuffer(void) +static void gl2_renderchain_bind_backbuffer(void *data, + void *chain_data) { #ifdef IOS /* There is no default frame buffer on iOS. */ @@ -257,7 +258,8 @@ static void gl_check_fbo_dimension(gl_t *gl, unsigned i, /* On resize, we might have to recreate our FBOs * due to "Viewport" scale, and set a new viewport. */ -static void gl2_renderchain_check_fbo_dimensions(void *data) +static void gl2_renderchain_check_fbo_dimensions(void *data, + void *chain_data) { int i; gl_t *gl = (gl_t*)data; @@ -280,6 +282,7 @@ static void gl2_renderchain_check_fbo_dimensions(void *data) static void gl2_renderchain_render( void *data, + void *chain_data, video_frame_info_t *video_info, uint64_t frame_count, const struct video_tex_info *tex_info, @@ -391,7 +394,7 @@ static void gl2_renderchain_render( set_texture_coords(fbo_tex_coords, xamt, yamt); /* Push final FBO to list. */ - fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; + fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; fbo_info->input_size[0] = prev_rect->img_width; @@ -402,7 +405,7 @@ static void gl2_renderchain_render( fbo_tex_info_cnt++; /* Render our FBO texture to back buffer. */ - gl2_renderchain_bind_backbuffer(); + gl2_renderchain_bind_backbuffer(gl, chain_data); shader_info.data = gl; shader_info.idx = gl->fbo_pass + 1; @@ -455,7 +458,8 @@ static void gl2_renderchain_render( gl->coords.tex_coord = gl->tex_info.coord; } -static void gl2_renderchain_deinit_fbo(void *data) +static void gl2_renderchain_deinit_fbo(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; @@ -481,7 +485,9 @@ static void gl2_renderchain_deinit_fbo(void *data) gl->fbo_feedback = 0; } -static void gl2_renderchain_deinit_hw_render(void *data) +static void gl2_renderchain_deinit_hw_render( + void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -498,12 +504,12 @@ static void gl2_renderchain_deinit_hw_render(void *data) context_bind_hw_render(false); } -void gl2_renderchain_free(void *data) +static void gl2_renderchain_free(void *data, void *chain_data) { gl_t *gl = (gl_t*)data; - gl2_renderchain_deinit_fbo(gl); - gl2_renderchain_deinit_hw_render(gl); + gl2_renderchain_deinit_fbo(gl, chain_data); + gl2_renderchain_deinit_hw_render(gl, chain_data); } static bool gl_create_fbo_targets(gl_t *gl) @@ -683,6 +689,7 @@ static void gl_create_fbo_textures(gl_t *gl) static void gl2_renderchain_recompute_pass_sizes( void *data, + void *chain_data, unsigned width, unsigned height, unsigned vp_width, unsigned vp_height) { @@ -745,6 +752,7 @@ static void gl2_renderchain_recompute_pass_sizes( } static void gl2_renderchain_start_render(void *data, + void *chain_data, video_frame_info_t *video_info) { /* Used when rendering to an FBO. @@ -779,7 +787,8 @@ static void gl2_renderchain_start_render(void *data, /* Set up render to texture. */ void gl2_renderchain_init( - void *data, unsigned fbo_width, unsigned fbo_height) + void *data, void *chain_data, + unsigned fbo_width, unsigned fbo_height) { int i; unsigned width, height; @@ -847,6 +856,7 @@ void gl2_renderchain_init( } gl2_renderchain_recompute_pass_sizes(gl, + chain_data, fbo_width, fbo_height, width, height); for (i = 0; i < gl->fbo_pass; i++) @@ -887,6 +897,7 @@ void gl2_renderchain_init( static bool gl2_renderchain_init_hw_render( void *data, + void *chain_data, unsigned width, unsigned height) { GLenum status; @@ -975,7 +986,7 @@ static bool gl2_renderchain_init_hw_render( } } - gl2_renderchain_bind_backbuffer(); + gl2_renderchain_bind_backbuffer(gl, chain_data); gl->hw_render_fbo_init = true; context_bind_hw_render(false); @@ -984,6 +995,7 @@ static bool gl2_renderchain_init_hw_render( static void gl2_renderchain_bind_prev_texture( void *data, + void *chain_data, const struct video_tex_info *tex_info) { gl_t *gl = (gl_t*)data; @@ -1007,7 +1019,8 @@ static void gl2_renderchain_bind_prev_texture( } static void gl2_renderchain_viewport_info( - void *data, struct video_viewport *vp) + void *data, void *chain_data, + struct video_viewport *vp) { unsigned width, height; unsigned top_y, top_dist; @@ -1026,7 +1039,9 @@ static void gl2_renderchain_viewport_info( } static bool gl2_renderchain_read_viewport( - void *data, uint8_t *buffer, bool is_idle) + void *data, + void *chain_data, + uint8_t *buffer, bool is_idle) { unsigned num_pixels = 0; gl_t *gl = (gl_t*)data; @@ -1127,9 +1142,9 @@ error: return false; } -void gl2_renderchain_free_internal(void *data) +void gl2_renderchain_free_internal(void *data, void *chain_data) { - gl2_renderchain_t *cg_data = (gl2_renderchain_t*)data; + gl2_renderchain_t *cg_data = (gl2_renderchain_t*)chain_data; if (!cg_data) return; @@ -1147,7 +1162,8 @@ static void *gl2_renderchain_new(void) } #ifndef HAVE_OPENGLES -static void gl2_renderchain_bind_vao(void *data) +static void gl2_renderchain_bind_vao(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -1155,7 +1171,8 @@ static void gl2_renderchain_bind_vao(void *data) glBindVertexArray(gl->vao); } -static void gl2_renderchain_unbind_vao(void *data) +static void gl2_renderchain_unbind_vao(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -1163,7 +1180,8 @@ static void gl2_renderchain_unbind_vao(void *data) glBindVertexArray(0); } -static void gl2_renderchain_new_vao(void *data) +static void gl2_renderchain_new_vao(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -1171,7 +1189,8 @@ static void gl2_renderchain_new_vao(void *data) glGenVertexArrays(1, &gl->vao); } -static void gl2_renderchain_free_vao(void *data) +static void gl2_renderchain_free_vao(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -1180,7 +1199,9 @@ static void gl2_renderchain_free_vao(void *data) } #endif -static void gl2_renderchain_restore_default_state(void *data) +static void gl2_renderchain_restore_default_state( + void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -1196,6 +1217,7 @@ static void gl2_renderchain_restore_default_state(void *data) static void gl2_renderchain_copy_frame( void *data, + void *chain_data, video_frame_info_t *video_info, const void *frame, unsigned width, unsigned height, unsigned pitch) @@ -1338,7 +1360,8 @@ static void gl2_renderchain_bind_pbo(unsigned idx) glBindBuffer(GL_PIXEL_PACK_BUFFER, (GLuint)idx); } -static void gl2_renderchain_unbind_pbo(void) +static void gl2_renderchain_unbind_pbo(void *data, + void *chain_data) { glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } @@ -1352,6 +1375,7 @@ static void gl2_renderchain_init_pbo(unsigned size, #endif static void gl2_renderchain_readback(void *data, + void *chain_data, unsigned alignment, unsigned fmt, unsigned type, void *src) @@ -1370,8 +1394,10 @@ static void gl2_renderchain_readback(void *data, } #ifndef HAVE_OPENGLES -static void gl2_renderchain_fence_iterate(void *data, unsigned - hard_sync_frames) +static void gl2_renderchain_fence_iterate( + void *data, + void *chain_data, + unsigned hard_sync_frames) { gl_t *gl = (gl_t*)data; @@ -1390,7 +1416,8 @@ static void gl2_renderchain_fence_iterate(void *data, unsigned } } -static void gl2_renderchain_fence_free(void *data) +static void gl2_renderchain_fence_free(void *data, + void *chain_data) { unsigned i; gl_t *gl = (gl_t*)data; @@ -1406,7 +1433,7 @@ static void gl2_renderchain_fence_free(void *data) #endif static void gl2_renderchain_init_textures_reference( - void *data, unsigned i, + void *data, void *chain_data, unsigned i, unsigned internal_fmt, unsigned texture_fmt, unsigned texture_type) { diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 6836ede817..33765da5dd 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -838,56 +838,68 @@ typedef struct d3d_renderchain_driver typedef struct gl_renderchain_driver { void (*set_coords)(void *handle_data, + void *chain_data, void *shader_data, const struct video_coords *coords); - void (*set_mvp)(void *data, void *shader_data, + void (*set_mvp)(void *data, + void *chain_data, + void *shader_data, const void *mat_data); void (*init_texture_reference)( - void *data, unsigned i, + void *data, void *chain_data, unsigned i, unsigned internal_fmt, unsigned texture_fmt, unsigned texture_type); - void (*fence_iterate)(void *data, unsigned hard_sync_frames); - void (*fence_free)(void *data); + void (*fence_iterate)(void *data, void *chain_data, + unsigned hard_sync_frames); + void (*fence_free)(void *data, void *chain_data); void (*readback)(void *data, + void *chain_data, unsigned alignment, unsigned fmt, unsigned type, void *src); void (*init_pbo)(unsigned size, const void *data); void (*bind_pbo)(unsigned idx); - void (*unbind_pbo)(void); + void (*unbind_pbo)(void *data, void *chain_data); void (*copy_frame)( void *data, + void *chain_data, video_frame_info_t *video_info, const void *frame, unsigned width, unsigned height, unsigned pitch); - void (*restore_default_state)(void *data); - void (*new_vao)(void *data); - void (*free_vao)(void *data); - void (*bind_vao)(void *data); - void (*unbind_vao)(void *data); - void (*disable_client_arrays)(void); + void (*restore_default_state)(void *data, void *chain_data); + void (*new_vao)(void *data, void *chain_data); + void (*free_vao)(void *data, void *chain_data); + void (*bind_vao)(void *data, void *chain_data); + void (*unbind_vao)(void *data, void *chain_data); + void (*disable_client_arrays)(void *data, void *chain_data); void (*ff_vertex)(const void *data); void (*ff_matrix)(const void *data); - void (*bind_backbuffer)(void); - void (*deinit_fbo)(void *data); + void (*bind_backbuffer)(void *data, void *chain_data); + void (*deinit_fbo)(void *data, void *chain_data); void (*viewport_info)( - void *data, struct video_viewport *vp); + void *data, void *chain_data, struct video_viewport *vp); bool (*read_viewport)( - void *data, uint8_t *buffer, bool is_idle); + void *data, void *chain_data, uint8_t *buffer, bool is_idle); void (*bind_prev_texture)( void *data, + void *chain_data, const struct video_tex_info *tex_info); - void (*chain_free)(void *data); + void (*chain_free)(void *data, void *chain_data); void *(*chain_new)(void); - void (*init)(void *data, unsigned fbo_width, unsigned fbo_height); - bool (*init_hw_render)(void *data, unsigned width, unsigned height); - void (*free)(void *data); - void (*deinit_hw_render)(void *data); - void (*start_render)(void *data, video_frame_info_t *video_info); - void (*check_fbo_dimensions)(void *data); + void (*init)(void *data, void *chain_data, + unsigned fbo_width, unsigned fbo_height); + bool (*init_hw_render)(void *data, void *chain_data, + unsigned width, unsigned height); + void (*free)(void *data, void *chain_data); + void (*deinit_hw_render)(void *data, void *chain_data); + void (*start_render)(void *data, void *chain_data, + video_frame_info_t *video_info); + void (*check_fbo_dimensions)(void *data, void *chain_data); void (*recompute_pass_sizes)(void *data, + void *chain_data, unsigned width, unsigned height, unsigned vp_width, unsigned vp_height); void (*renderchain_render)(void *data, + void *chain_data, video_frame_info_t *video_info, uint64_t frame_count, const struct video_tex_info *tex_info, From 072570bbf3f90273474c14380b50e77fd2429482 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 11:58:16 +0100 Subject: [PATCH 031/698] (GL) Update GL1 renderchain too --- gfx/drivers_renderchain/gl1_renderchain.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index 04a756db9f..a9762cf0ba 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -60,11 +60,12 @@ GLenum min_filter_to_mag(GLenum type); void gl1_renderchain_free(void *data, void *chain_data) { (void)chain_data; - (void)gl; + (void)data; } static void gl1_renderchain_bind_prev_texture( void *data, + void *chain_data, const struct video_tex_info *tex_info) { gl_t *gl = (gl_t*)data; @@ -76,7 +77,8 @@ static void gl1_renderchain_bind_prev_texture( } static void gl1_renderchain_viewport_info( - void *data, struct video_viewport *vp) + void *data, void *chain_data, + struct video_viewport *vp) { unsigned width, height; unsigned top_y, top_dist; @@ -95,7 +97,8 @@ static void gl1_renderchain_viewport_info( } static bool gl1_renderchain_read_viewport( - void *data, uint8_t *buffer, bool is_idle) + void *data, void *chain_data, + uint8_t *buffer, bool is_idle) { unsigned num_pixels = 0; gl_t *gl = (gl_t*)data; @@ -134,9 +137,9 @@ static bool gl1_renderchain_read_viewport( return true; } -void gl1_renderchain_free_internal(void *data) +void gl1_renderchain_free_internal(void *data, void *chain_data) { - gl1_renderchain_t *cg_data = (gl1_renderchain_t*)data; + gl1_renderchain_t *cg_data = (gl1_renderchain_t*)chain_data; if (!cg_data) return; @@ -183,7 +186,8 @@ static void gl1_renderchain_ff_matrix(const void *data) glLoadMatrixf(ident.data); } -static void gl1_renderchain_disable_client_arrays(void) +static void gl1_renderchain_disable_client_arrays(void *data, + void *chain_data) { if (gl_query_core_context_in_use()) return; @@ -196,7 +200,8 @@ static void gl1_renderchain_disable_client_arrays(void) glDisableClientState(GL_TEXTURE_COORD_ARRAY); } -static void gl1_renderchain_restore_default_state(void *data) +static void gl1_renderchain_restore_default_state(void *data, + void *chain_data) { gl_t *gl = (gl_t*)data; if (!gl) @@ -209,6 +214,7 @@ static void gl1_renderchain_restore_default_state(void *data) static void gl1_renderchain_copy_frame( void *data, + void *chain_data, video_frame_info_t *video_info, const void *frame, unsigned width, unsigned height, unsigned pitch) @@ -244,6 +250,7 @@ static void gl1_renderchain_copy_frame( } static void gl1_renderchain_readback(void *data, + void *chain_data, unsigned alignment, unsigned fmt, unsigned type, void *src) @@ -260,6 +267,7 @@ static void gl1_renderchain_readback(void *data, } static void gl1_renderchain_set_mvp(void *data, + void *chain_data, void *shader_data, const void *mat_data) { math_matrix_4x4 ident; @@ -274,6 +282,7 @@ static void gl1_renderchain_set_mvp(void *data, } static void gl1_renderchain_set_coords(void *handle_data, + void *chain_data, void *shader_data, const struct video_coords *coords) { /* Fall back to fixed function-style if needed and possible. */ From 267e6fe85fb45dd53adb9d7dc4b1b672401224c4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 12:02:53 +0100 Subject: [PATCH 032/698] Move fence variables to renderchain data struct --- gfx/common/gl_common.h | 3 -- gfx/drivers_renderchain/gl2_renderchain.c | 37 ++++++++++++----------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 7eb88af66e..535dd15ada 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -38,8 +38,6 @@ RETRO_BEGIN_DECLS -#define MAX_FENCES 4 - #if defined(HAVE_PSGL) #define RARCH_GL_FRAMEBUFFER GL_FRAMEBUFFER_OES #define RARCH_GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_OES @@ -250,7 +248,6 @@ typedef struct gl struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS]; struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; - GLsync fences[MAX_FENCES]; const gl_renderchain_driver_t *renderchain_driver; void *renderchain_data; } gl_t; diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index f52f77f5e7..07934a6d52 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -51,9 +51,12 @@ #include "../../configuration.h" #include "../../verbosity.h" +#define MAX_FENCES 4 + typedef struct gl2_renderchain { - void *empty; + unsigned fence_count; + GLsync fences[MAX_FENCES]; } gl2_renderchain_t; #if (!defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3)) @@ -1144,12 +1147,12 @@ error: void gl2_renderchain_free_internal(void *data, void *chain_data) { - gl2_renderchain_t *cg_data = (gl2_renderchain_t*)chain_data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - if (!cg_data) + if (!chain) return; - free(cg_data); + free(chain); } static void *gl2_renderchain_new(void) @@ -1399,20 +1402,20 @@ static void gl2_renderchain_fence_iterate( void *chain_data, unsigned hard_sync_frames) { - gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - gl->fences[gl->fence_count++] = + chain->fences[chain->fence_count++] = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - while (gl->fence_count > hard_sync_frames) + while (chain->fence_count > hard_sync_frames) { - glClientWaitSync(gl->fences[0], + glClientWaitSync(chain->fences[0], GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000); - glDeleteSync(gl->fences[0]); + glDeleteSync(chain->fences[0]); - gl->fence_count--; - memmove(gl->fences, gl->fences + 1, - gl->fence_count * sizeof(GLsync)); + chain->fence_count--; + memmove(chain->fences, chain->fences + 1, + chain->fence_count * sizeof(GLsync)); } } @@ -1420,15 +1423,15 @@ static void gl2_renderchain_fence_free(void *data, void *chain_data) { unsigned i; - gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - for (i = 0; i < gl->fence_count; i++) + for (i = 0; i < chain->fence_count; i++) { - glClientWaitSync(gl->fences[i], + glClientWaitSync(chain->fences[i], GL_SYNC_FLUSH_COMMANDS_BIT, 1000000000); - glDeleteSync(gl->fences[i]); + glDeleteSync(chain->fences[i]); } - gl->fence_count = 0; + chain->fence_count = 0; } #endif From 69d3fd5047e4c0898e4082632ee56f3c4f87a9bc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 12:03:29 +0100 Subject: [PATCH 033/698] Get rid of fence_count in gl struct --- gfx/common/gl_common.h | 1 - 1 file changed, 1 deletion(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 535dd15ada..bf0a8b3ac4 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -222,7 +222,6 @@ typedef struct gl unsigned base_size; /* 2 or 4 */ unsigned overlays; unsigned pbo_readback_index; - unsigned fence_count; unsigned last_width[GFX_MAX_TEXTURES]; unsigned last_height[GFX_MAX_TEXTURES]; From 19ad9aa1cb58691c8a0188260b5799e823363094 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 12:43:22 +0100 Subject: [PATCH 034/698] Add resolve extensions callback --- gfx/drivers/gl.c | 3 +++ gfx/drivers_renderchain/gl1_renderchain.c | 7 ++++--- gfx/drivers_renderchain/gl2_renderchain.c | 6 ++++++ gfx/video_driver.h | 4 ++++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 3cc6adf629..b7302756e8 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -1371,6 +1371,9 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) video_driver_unset_rgba(); + if (gl->renderchain_driver->resolve_extensions) + gl->renderchain_driver->resolve_extensions(gl, gl->renderchain_data, context_ident); + #if defined(HAVE_OPENGLES) && !defined(HAVE_PSGL) if (!gl_check_capability(GL_CAPS_BGRA8888)) { diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index a9762cf0ba..56a5d27650 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -327,10 +327,11 @@ gl_renderchain_driver_t gl2_renderchain = { NULL, /* renderchain_init */ NULL, /* init_hw_render */ gl1_renderchain_free, - NULL, /* deinit_hw_render */ - NULL, /* start_render */ + NULL, /* deinit_hw_render */ + NULL, /* start_render */ NULL, /* check_fbo_dimensions */ NULL, /* recompute_pass_sizes */ - NULL, /* renderchain_render */ + NULL, /* renderchain_render */ + NULL, /* resolve_extensions */ "gl1", }; diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 07934a6d52..5e6d5bcad5 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -1461,6 +1461,11 @@ static void gl2_renderchain_init_textures_reference( #endif } +static void gl2_renderchain_resolve_extensions(void *data, + void *chain_data, const char *context_ident) +{ +} + gl_renderchain_driver_t gl2_renderchain = { NULL, /* set_coords */ NULL, /* set_mvp */ @@ -1513,5 +1518,6 @@ gl_renderchain_driver_t gl2_renderchain = { gl2_renderchain_check_fbo_dimensions, gl2_renderchain_recompute_pass_sizes, gl2_renderchain_render, + gl2_renderchain_resolve_extensions, "gl2", }; diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 33765da5dd..1519bdc7a3 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -904,6 +904,10 @@ typedef struct gl_renderchain_driver uint64_t frame_count, const struct video_tex_info *tex_info, const struct video_tex_info *feedback_info); + void (*resolve_extensions)( + void *data, + void *chain_data, + const char *context_ident); const char *ident; } gl_renderchain_driver_t; From f47888aeda777a317f98e5125cf1e0ee7ab523df Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 12:50:22 +0100 Subject: [PATCH 035/698] Move more variables to renderchain data --- gfx/common/gl_common.h | 3 -- gfx/drivers/gl.c | 7 ---- gfx/drivers_renderchain/gl2_renderchain.c | 42 +++++++++++++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index bf0a8b3ac4..8fe344e433 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -168,9 +168,6 @@ typedef struct gl bool hw_render_fbo_init; bool hw_render_depth_init; bool has_fbo; - bool has_srgb_fbo_gles3; - bool has_fp_fbo; - bool has_srgb_fbo; bool hw_render_use; bool core_context_in_use; diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index b7302756e8..262292ca93 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -1352,19 +1352,12 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) * * have_sync - Use ARB_sync to reduce latency. */ - gl->has_srgb_fbo = false; gl->has_fbo = gl_check_capability(GL_CAPS_FBO); gl->have_full_npot_support = gl_check_capability(GL_CAPS_FULL_NPOT_SUPPORT); gl->have_mipmap = gl_check_capability(GL_CAPS_MIPMAP); gl->have_es2_compat = gl_check_capability(GL_CAPS_ES2_COMPAT); - gl->has_fp_fbo = gl_check_capability(GL_CAPS_FP_FBO); gl->support_unpack_row_length = gl_check_capability(GL_CAPS_UNPACK_ROW_LENGTH); gl->have_sync = gl_check_capability(GL_CAPS_SYNC); - /* GLES3 has unpack_subimage and sRGB in core. */ - gl->has_srgb_fbo_gles3 = gl_check_capability(GL_CAPS_SRGB_FBO_ES3); - - if (!settings->bools.video_force_srgb_disable) - gl->has_srgb_fbo = gl_check_capability(GL_CAPS_SRGB_FBO); if (gl->have_sync && settings->bools.video_hard_sync) RARCH_LOG("[GL]: Using ARB_sync to reduce latency.\n"); diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 5e6d5bcad5..97e1a36c45 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -55,6 +55,9 @@ typedef struct gl2_renderchain { + bool has_fp_fbo; + bool has_srgb_fbo_gles3; + bool has_srgb_fbo; unsigned fence_count; GLsync fences[MAX_FENCES]; } gl2_renderchain_t; @@ -296,6 +299,7 @@ static void gl2_renderchain_render( video_shader_ctx_params_t params; video_shader_ctx_info_t shader_info; gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; static GLfloat fbo_tex_coords[8] = {0.0f}; struct video_tex_info fbo_tex_info[GFX_MAX_SHADERS]; struct video_tex_info *fbo_info = NULL; @@ -385,7 +389,7 @@ static void gl2_renderchain_render( } #if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES) - if (gl->has_srgb_fbo) + if (chain->has_srgb_fbo) glDisable(GL_FRAMEBUFFER_SRGB); #endif @@ -565,13 +569,15 @@ error: return false; } -static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) +static void gl_create_fbo_texture(gl_t *gl, + void *chain_data, unsigned i, GLuint texture) { GLenum mag_filter, wrap_enum; video_shader_ctx_filter_t filter_type; video_shader_ctx_wrap_t wrap = {0}; bool fp_fbo = false; bool smooth = false; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; settings_t *settings = config_get_ptr(); GLuint base_filt = settings->bools.video_smooth ? GL_LINEAR : GL_NEAREST; GLuint base_mip_filt = settings->bools.video_smooth ? @@ -603,12 +609,12 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) if (fp_fbo) { - if (!gl->has_fp_fbo) + if (!chain->has_fp_fbo) RARCH_ERR("[GL]: Floating-point FBO was requested, but is not supported. Falling back to UNORM. Result may band/clip/etc.!\n"); } #if !defined(HAVE_OPENGLES2) - if (fp_fbo && gl->has_fp_fbo) + if (fp_fbo && chain->has_fp_fbo) { RARCH_LOG("[GL]: FBO pass #%d is floating-point.\n", i); gl_load_texture_image(GL_TEXTURE_2D, 0, GL_RGBA32F, @@ -623,14 +629,14 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) if (!fp_fbo && srgb_fbo) { - if (!gl->has_srgb_fbo) + if (!chain->has_srgb_fbo) RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n"); } if (settings->bools.video_force_srgb_disable) srgb_fbo = false; - if (srgb_fbo && gl->has_srgb_fbo) + if (srgb_fbo && chain->has_srgb_fbo) { RARCH_LOG("[GL]: FBO pass #%d is sRGB.\n", i); #ifdef HAVE_OPENGLES2 @@ -639,7 +645,7 @@ static void gl_create_fbo_texture(gl_t *gl, unsigned i, GLuint texture) glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, - gl->has_srgb_fbo_gles3 ? GL_RGBA : GL_SRGB_ALPHA_EXT, + chain->has_srgb_fbo_gles3 ? GL_RGBA : GL_SRGB_ALPHA_EXT, GL_UNSIGNED_BYTE, NULL); #else gl_load_texture_image(GL_TEXTURE_2D, @@ -674,12 +680,14 @@ static void gl_create_fbo_textures(gl_t *gl) glGenTextures(gl->fbo_pass, gl->fbo_texture); for (i = 0; i < gl->fbo_pass; i++) - gl_create_fbo_texture(gl, i, gl->fbo_texture[i]); + gl_create_fbo_texture(gl, gl->renderchain_data, + i, gl->fbo_texture[i]); if (gl->fbo_feedback_enable) { glGenTextures(1, &gl->fbo_feedback_texture); gl_create_fbo_texture(gl, + gl->renderchain_data, gl->fbo_feedback_pass, gl->fbo_feedback_texture); } @@ -767,7 +775,8 @@ static void gl2_renderchain_start_render(void *data, 0, 1, 1, 1 }; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); gl2_bind_fb(gl->fbo[0]); @@ -783,7 +792,7 @@ static void gl2_renderchain_start_render(void *data, gl->coords.vertex = fbo_vertexes; #if defined(GL_FRAMEBUFFER_SRGB) && !defined(HAVE_OPENGLES) - if (gl->has_srgb_fbo) + if (chain->has_srgb_fbo) glEnable(GL_FRAMEBUFFER_SRGB); #endif } @@ -1464,6 +1473,19 @@ static void gl2_renderchain_init_textures_reference( static void gl2_renderchain_resolve_extensions(void *data, void *chain_data, const char *context_ident) { + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + settings_t *settings = config_get_ptr(); + + if (!chain) + return; + + chain->has_srgb_fbo = false; + chain->has_fp_fbo = gl_check_capability(GL_CAPS_FP_FBO); + /* GLES3 has unpack_subimage and sRGB in core. */ + chain->has_srgb_fbo_gles3 = gl_check_capability(GL_CAPS_SRGB_FBO_ES3); + + if (!settings->bools.video_force_srgb_disable) + chain->has_srgb_fbo = gl_check_capability(GL_CAPS_SRGB_FBO); } gl_renderchain_driver_t gl2_renderchain = { From 48c3a509320031a91a7de1bec2a358f972b9e33d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 13:03:14 +0100 Subject: [PATCH 036/698] Move more variables --- gfx/common/gl_common.h | 1 - gfx/drivers/gl.c | 18 ++++++------------ gfx/drivers_renderchain/gl2_renderchain.c | 16 ++++++++++++---- gfx/video_driver.h | 3 ++- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 8fe344e433..db94c1a268 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -180,7 +180,6 @@ typedef struct gl bool have_full_npot_support; bool have_mipmap; - bool egl_images; bool overlay_enable; bool overlay_full_screen; bool menu_texture_enable; diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index 262292ca93..c717513f74 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -544,11 +544,9 @@ static void gl_init_textures_data(gl_t *gl) static void gl_init_textures(gl_t *gl, const video_info_t *video) { unsigned i; - GLenum internal_fmt, texture_type = 0, texture_fmt = 0; - - /* Use regular textures if we use HW render. */ - gl->egl_images = !gl->hw_render_use && gl_check_capability(GL_CAPS_EGLIMAGE) && - video_context_driver_init_image_buffer(video); + GLenum internal_fmt = gl->internal_fmt; + GLenum texture_type = gl->texture_type; + GLenum texture_fmt = gl->texture_fmt; #ifdef HAVE_PSGL if (!gl->pbo) @@ -560,10 +558,6 @@ static void gl_init_textures(gl_t *gl, const video_info_t *video) NULL, GL_STREAM_DRAW); #endif - internal_fmt = gl->internal_fmt; - texture_type = gl->texture_type; - texture_fmt = gl->texture_fmt; - #if defined(HAVE_OPENGLES) && !defined(HAVE_PSGL) /* GLES is picky about which format we use here. * Without extensions, we can *only* render to 16-bit FBOs. */ @@ -1339,7 +1333,7 @@ static void gl_set_nonblock_state(void *data, bool state) context_bind_hw_render(true); } -static bool resolve_extensions(gl_t *gl, const char *context_ident) +static bool resolve_extensions(gl_t *gl, const char *context_ident, const video_info_t *video) { settings_t *settings = config_get_ptr(); @@ -1365,7 +1359,7 @@ static bool resolve_extensions(gl_t *gl, const char *context_ident) video_driver_unset_rgba(); if (gl->renderchain_driver->resolve_extensions) - gl->renderchain_driver->resolve_extensions(gl, gl->renderchain_data, context_ident); + gl->renderchain_driver->resolve_extensions(gl, gl->renderchain_data, context_ident, video); #if defined(HAVE_OPENGLES) && !defined(HAVE_PSGL) if (!gl_check_capability(GL_CAPS_BGRA8888)) @@ -1790,7 +1784,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendEquation(GL_FUNC_ADD); - if (!resolve_extensions(gl, ctx_driver->ident)) + if (!resolve_extensions(gl, ctx_driver->ident, video)) goto error; #ifdef GL_DEBUG diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 97e1a36c45..3ed9b0eb1e 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -55,6 +55,7 @@ typedef struct gl2_renderchain { + bool egl_images; bool has_fp_fbo; bool has_srgb_fbo_gles3; bool has_srgb_fbo; @@ -1253,7 +1254,7 @@ static void gl2_renderchain_copy_frame( } #elif defined(HAVE_OPENGLES) #if defined(HAVE_EGL) - if (gl->egl_images) + if (chain->egl_images) { gfx_ctx_image_t img_info; bool new_egl = false; @@ -1449,7 +1450,8 @@ static void gl2_renderchain_init_textures_reference( unsigned internal_fmt, unsigned texture_fmt, unsigned texture_type) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; #ifdef HAVE_PSGL glTextureReferenceSCE(GL_TEXTURE_2D, 1, gl->tex_w, gl->tex_h, 0, @@ -1457,7 +1459,7 @@ static void gl2_renderchain_init_textures_reference( gl->tex_w * gl->base_size, gl->tex_w * gl->tex_h * i * gl->base_size); #else - if (gl->egl_images) + if (chain->egl_images) return; gl_load_texture_image(GL_TEXTURE_2D, @@ -1471,8 +1473,10 @@ static void gl2_renderchain_init_textures_reference( } static void gl2_renderchain_resolve_extensions(void *data, - void *chain_data, const char *context_ident) + void *chain_data, const char *context_ident, + const video_info_t *video) { + gl_t *gl = (gl_t*)data; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; settings_t *settings = config_get_ptr(); @@ -1486,6 +1490,10 @@ static void gl2_renderchain_resolve_extensions(void *data, if (!settings->bools.video_force_srgb_disable) chain->has_srgb_fbo = gl_check_capability(GL_CAPS_SRGB_FBO); + + /* Use regular textures if we use HW render. */ + chain->egl_images = !gl->hw_render_use && gl_check_capability(GL_CAPS_EGLIMAGE) && + video_context_driver_init_image_buffer(video); } gl_renderchain_driver_t gl2_renderchain = { diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 1519bdc7a3..43bbef97ca 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -907,7 +907,8 @@ typedef struct gl_renderchain_driver void (*resolve_extensions)( void *data, void *chain_data, - const char *context_ident); + const char *context_ident, + const video_info_t *video); const char *ident; } gl_renderchain_driver_t; From 9a8f73fb6cd472a7e5204464347344ba815d4df0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 13:18:34 +0100 Subject: [PATCH 037/698] Move variables --- gfx/common/gl_common.h | 5 - gfx/drivers_renderchain/gl2_renderchain.c | 152 +++++++++++++--------- 2 files changed, 88 insertions(+), 69 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index db94c1a268..c413d653c0 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -166,7 +166,6 @@ typedef struct gl bool fbo_inited; bool fbo_feedback_enable; bool hw_render_fbo_init; - bool hw_render_depth_init; bool has_fbo; bool hw_render_use; bool core_context_in_use; @@ -190,7 +189,6 @@ typedef struct gl int version_major; int version_minor; - int fbo_pass; GLuint tex_mag_filter; GLuint tex_min_filter; @@ -199,13 +197,10 @@ typedef struct gl GLuint pbo; GLuint *overlay_tex; GLuint menu_texture; - GLuint vao; GLuint pbo_readback[4]; GLuint texture[GFX_MAX_TEXTURES]; GLuint fbo[GFX_MAX_SHADERS]; - GLuint fbo_texture[GFX_MAX_SHADERS]; GLuint hw_render_fbo[GFX_MAX_TEXTURES]; - GLuint hw_render_depth[GFX_MAX_TEXTURES]; unsigned tex_index; /* For use with PREV. */ unsigned textures; diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 3ed9b0eb1e..0b0eff8ff3 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -59,7 +59,16 @@ typedef struct gl2_renderchain bool has_fp_fbo; bool has_srgb_fbo_gles3; bool has_srgb_fbo; + bool hw_render_depth_init; + + int fbo_pass; + + GLuint vao; + GLuint fbo_texture[GFX_MAX_SHADERS]; + GLuint hw_render_depth[GFX_MAX_TEXTURES]; + unsigned fence_count; + GLsync fences[MAX_FENCES]; } gl2_renderchain_t; @@ -228,12 +237,15 @@ static bool gl_recreate_fbo( return false; } -static void gl_check_fbo_dimension(gl_t *gl, unsigned i, +static void gl_check_fbo_dimension(gl_t *gl, + void *chain_data, + unsigned i, bool update_feedback) { struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; /* Check proactively since we might suddently * get sizes of tex_w width or tex_h height. */ + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; unsigned img_width = fbo_rect->max_img_width; unsigned img_height = fbo_rect->max_img_height; unsigned max = img_width > img_height ? img_width : img_height; @@ -242,7 +254,7 @@ static void gl_check_fbo_dimension(gl_t *gl, unsigned i, fbo_rect->width = pow2_size; fbo_rect->height = pow2_size; - gl_recreate_fbo(fbo_rect, gl->fbo[i], &gl->fbo_texture[i]); + gl_recreate_fbo(fbo_rect, gl->fbo[i], &chain->fbo_texture[i]); /* Update feedback texture in-place so we avoid having to * juggle two different fbo_rect structs since they get updated here. */ @@ -269,10 +281,11 @@ static void gl2_renderchain_check_fbo_dimensions(void *data, void *chain_data) { int i; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; /* Check if we have to recreate our FBO textures. */ - for (i = 0; i < gl->fbo_pass; i++) + for (i = 0; i < chain->fbo_pass; i++) { struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; if (fbo_rect) @@ -282,7 +295,7 @@ static void gl2_renderchain_check_fbo_dimensions(void *data, if ((fbo_rect->max_img_width > fbo_rect->width) || (fbo_rect->max_img_height > fbo_rect->height)) - gl_check_fbo_dimension(gl, i, update_feedback); + gl_check_fbo_dimension(gl, chain_data, i, update_feedback); } } } @@ -317,7 +330,7 @@ static void gl2_renderchain_render( /* Calculate viewports, texture coordinates etc, * and render all passes from FBOs, to another FBO. */ - for (i = 1; i < gl->fbo_pass; i++) + for (i = 1; i < chain->fbo_pass; i++) { video_shader_ctx_coords_t coords; video_shader_ctx_params_t params; @@ -331,7 +344,7 @@ static void gl2_renderchain_render( set_texture_coords(fbo_tex_coords, xamt, yamt); - fbo_info->tex = gl->fbo_texture[i - 1]; + fbo_info->tex = chain->fbo_texture[i - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; @@ -346,7 +359,7 @@ static void gl2_renderchain_render( shader_info.set_active = true; video_shader_driver_use(shader_info); - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[i - 1]); + glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[i - 1]); mip_level = i + 1; @@ -395,16 +408,16 @@ static void gl2_renderchain_render( #endif /* Render our last FBO texture directly to screen. */ - prev_rect = &gl->fbo_rect[gl->fbo_pass - 1]; + prev_rect = &gl->fbo_rect[chain->fbo_pass - 1]; xamt = (GLfloat)prev_rect->img_width / prev_rect->width; yamt = (GLfloat)prev_rect->img_height / prev_rect->height; set_texture_coords(fbo_tex_coords, xamt, yamt); /* Push final FBO to list. */ - fbo_info = &fbo_tex_info[gl->fbo_pass - 1]; + fbo_info = &fbo_tex_info[chain->fbo_pass - 1]; - fbo_info->tex = gl->fbo_texture[gl->fbo_pass - 1]; + fbo_info->tex = chain->fbo_texture[chain->fbo_pass - 1]; fbo_info->input_size[0] = prev_rect->img_width; fbo_info->input_size[1] = prev_rect->img_height; fbo_info->tex_size[0] = prev_rect->width; @@ -416,14 +429,14 @@ static void gl2_renderchain_render( gl2_renderchain_bind_backbuffer(gl, chain_data); shader_info.data = gl; - shader_info.idx = gl->fbo_pass + 1; + shader_info.idx = chain->fbo_pass + 1; shader_info.set_active = true; video_shader_driver_use(shader_info); - glBindTexture(GL_TEXTURE_2D, gl->fbo_texture[gl->fbo_pass - 1]); + glBindTexture(GL_TEXTURE_2D, chain->fbo_texture[chain->fbo_pass - 1]); - mip_level = gl->fbo_pass + 1; + mip_level = chain->fbo_pass + 1; if (video_shader_driver_mipmap_input(&mip_level) && gl->have_mipmap) @@ -469,15 +482,16 @@ static void gl2_renderchain_render( static void gl2_renderchain_deinit_fbo(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; if (!gl) return; - glDeleteTextures(gl->fbo_pass, gl->fbo_texture); - gl2_delete_fb(gl->fbo_pass, gl->fbo); + glDeleteTextures(chain->fbo_pass, chain->fbo_texture); + gl2_delete_fb(chain->fbo_pass, gl->fbo); - memset(gl->fbo_texture, 0, sizeof(gl->fbo_texture)); + memset(chain->fbo_texture, 0, sizeof(chain->fbo_texture)); memset(gl->fbo, 0, sizeof(gl->fbo)); if (gl->fbo_feedback) @@ -485,9 +499,10 @@ static void gl2_renderchain_deinit_fbo(void *data, if (gl->fbo_feedback_texture) glDeleteTextures(1, &gl->fbo_feedback_texture); + chain->fbo_pass = 0; + gl->fbo_inited = false; gl->fbo_feedback_enable = false; - gl->fbo_pass = 0; gl->fbo_feedback_pass = 0; gl->fbo_feedback_texture = 0; gl->fbo_feedback = 0; @@ -497,7 +512,8 @@ static void gl2_renderchain_deinit_hw_render( void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; if (!gl) return; @@ -505,8 +521,8 @@ static void gl2_renderchain_deinit_hw_render( if (gl->hw_render_fbo_init) gl2_delete_fb(gl->textures, gl->hw_render_fbo); - if (gl->hw_render_depth_init) - gl2_delete_rb(gl->textures, gl->hw_render_depth); + if (chain->hw_render_depth_init) + gl2_delete_rb(gl->textures, chain->hw_render_depth); gl->hw_render_fbo_init = false; context_bind_hw_render(false); @@ -520,20 +536,21 @@ static void gl2_renderchain_free(void *data, void *chain_data) gl2_renderchain_deinit_hw_render(gl, chain_data); } -static bool gl_create_fbo_targets(gl_t *gl) +static bool gl_create_fbo_targets(gl_t *gl, void *chain_data) { int i; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; glBindTexture(GL_TEXTURE_2D, 0); - gl2_gen_fb(gl->fbo_pass, gl->fbo); + gl2_gen_fb(chain->fbo_pass, gl->fbo); - for (i = 0; i < gl->fbo_pass; i++) + for (i = 0; i < chain->fbo_pass; i++) { GLenum status; gl2_bind_fb(gl->fbo[i]); gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, - RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, gl->fbo_texture[i], 0); + RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, chain->fbo_texture[i], 0); status = gl2_check_fb_status(RARCH_GL_FRAMEBUFFER); if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) @@ -563,7 +580,7 @@ static bool gl_create_fbo_targets(gl_t *gl) return true; error: - gl2_delete_fb(gl->fbo_pass, gl->fbo); + gl2_delete_fb(chain->fbo_pass, gl->fbo); if (gl->fbo_feedback) gl2_delete_fb(1, &gl->fbo_feedback); RARCH_ERR("[GL]: Failed to set up frame buffer objects. Multi-pass shading will not work.\n"); @@ -675,14 +692,16 @@ static void gl_create_fbo_texture(gl_t *gl, } } -static void gl_create_fbo_textures(gl_t *gl) +static void gl_create_fbo_textures(gl_t *gl, void *chain_data) { int i; - glGenTextures(gl->fbo_pass, gl->fbo_texture); + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - for (i = 0; i < gl->fbo_pass; i++) + glGenTextures(chain->fbo_pass, chain->fbo_texture); + + for (i = 0; i < chain->fbo_pass; i++) gl_create_fbo_texture(gl, gl->renderchain_data, - i, gl->fbo_texture[i]); + i, chain->fbo_texture[i]); if (gl->fbo_feedback_enable) { @@ -707,6 +726,7 @@ static void gl2_renderchain_recompute_pass_sizes( { int i; gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; bool size_modified = false; GLint max_size = 0; unsigned last_width = width; @@ -717,7 +737,7 @@ static void gl2_renderchain_recompute_pass_sizes( glGetIntegerv(GL_MAX_TEXTURE_SIZE, &max_size); /* Calculate viewports for FBOs. */ - for (i = 0; i < gl->fbo_pass; i++) + for (i = 0; i < chain->fbo_pass; i++) { struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i]; @@ -808,7 +828,8 @@ void gl2_renderchain_init( video_shader_ctx_scale_t scaler; video_shader_ctx_info_t shader_info; struct gfx_fbo_scale scale, scale_last; - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; if (!video_shader_driver_info(&shader_info)) return; @@ -838,9 +859,9 @@ void gl2_renderchain_init( return; } - gl->fbo_pass = shader_info.num - 1; + chain->fbo_pass = shader_info.num - 1; if (scale_last.valid) - gl->fbo_pass++; + chain->fbo_pass++; if (!scale.valid) { @@ -852,7 +873,7 @@ void gl2_renderchain_init( gl->fbo_scale[0] = scale; - for (i = 1; i < gl->fbo_pass; i++) + for (i = 1; i < chain->fbo_pass; i++) { scaler.idx = i + 1; scaler.scale = &gl->fbo_scale[i]; @@ -872,7 +893,7 @@ void gl2_renderchain_init( chain_data, fbo_width, fbo_height, width, height); - for (i = 0; i < gl->fbo_pass; i++) + for (i = 0; i < chain->fbo_pass; i++) { gl->fbo_rect[i].width = next_pow2(gl->fbo_rect[i].img_width); gl->fbo_rect[i].height = next_pow2(gl->fbo_rect[i].img_height); @@ -884,7 +905,7 @@ void gl2_renderchain_init( &gl->fbo_feedback_pass); if (gl->fbo_feedback_enable && gl->fbo_feedback_pass - < (unsigned)gl->fbo_pass) + < (unsigned)chain->fbo_pass) { RARCH_LOG("[GL]: Creating feedback FBO %d @ %ux%u\n", i, gl->fbo_rect[gl->fbo_feedback_pass].width, @@ -893,14 +914,14 @@ void gl2_renderchain_init( else if (gl->fbo_feedback_enable) { RARCH_WARN("[GL]: Tried to create feedback FBO of pass #%u, but there are only %d FBO passes. Will use input texture as feedback texture.\n", - gl->fbo_feedback_pass, gl->fbo_pass); + gl->fbo_feedback_pass, chain->fbo_pass); gl->fbo_feedback_enable = false; } - gl_create_fbo_textures(gl); - if (!gl || !gl_create_fbo_targets(gl)) + gl_create_fbo_textures(gl, chain); + if (!gl || !gl_create_fbo_targets(gl, chain)) { - glDeleteTextures(gl->fbo_pass, gl->fbo_texture); + glDeleteTextures(chain->fbo_pass, chain->fbo_texture); RARCH_ERR("[GL]: Failed to create FBO targets. Will continue without FBO.\n"); return; } @@ -922,6 +943,7 @@ static bool gl2_renderchain_init_hw_render( struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; /* We can only share texture objects through contexts. * FBOs are "abstract" objects and are not shared. */ @@ -946,8 +968,8 @@ static bool gl2_renderchain_init_hw_render( if (depth) { - gl2_gen_rb(gl->textures, gl->hw_render_depth); - gl->hw_render_depth_init = true; + gl2_gen_rb(gl->textures, chain->hw_render_depth); + chain->hw_render_depth_init = true; } for (i = 0; i < gl->textures; i++) @@ -958,7 +980,7 @@ static bool gl2_renderchain_init_hw_render( if (depth) { - gl2_bind_rb(RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + gl2_bind_rb(RARCH_GL_RENDERBUFFER, chain->hw_render_depth[i]); gl2_rb_storage(RARCH_GL_RENDERBUFFER, stencil ? RARCH_GL_DEPTH24_STENCIL8 : GL_DEPTH_COMPONENT16, width, height); @@ -971,22 +993,26 @@ static bool gl2_renderchain_init_hw_render( * There's no GL_DEPTH_STENCIL_ATTACHMENT like in desktop GL. */ gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_DEPTH_ATTACHMENT, - RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + RARCH_GL_RENDERBUFFER, + chain->hw_render_depth[i]); gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_STENCIL_ATTACHMENT, - RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + RARCH_GL_RENDERBUFFER, + chain->hw_render_depth[i]); #else /* We use ARB FBO extensions, no need to check. */ gl2_fb_rb(RARCH_GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, - RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + RARCH_GL_RENDERBUFFER, + chain->hw_render_depth[i]); #endif } else { gl2_fb_rb(RARCH_GL_FRAMEBUFFER, RARCH_GL_DEPTH_ATTACHMENT, - RARCH_GL_RENDERBUFFER, gl->hw_render_depth[i]); + RARCH_GL_RENDERBUFFER, + chain->hw_render_depth[i]); } } @@ -1011,7 +1037,8 @@ static void gl2_renderchain_bind_prev_texture( void *chain_data, const struct video_tex_info *tex_info) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; memmove(gl->prev_info + 1, gl->prev_info, sizeof(*tex_info) * (gl->textures - 1)); @@ -1025,9 +1052,9 @@ static void gl2_renderchain_bind_prev_texture( GLuint tmp_fbo = gl->fbo_feedback; GLuint tmp_tex = gl->fbo_feedback_texture; gl->fbo_feedback = gl->fbo[gl->fbo_feedback_pass]; - gl->fbo_feedback_texture = gl->fbo_texture[gl->fbo_feedback_pass]; + gl->fbo_feedback_texture = chain->fbo_texture[gl->fbo_feedback_pass]; gl->fbo[gl->fbo_feedback_pass] = tmp_fbo; - gl->fbo_texture[gl->fbo_feedback_pass] = tmp_tex; + chain->fbo_texture[gl->fbo_feedback_pass] = tmp_tex; } } @@ -1178,37 +1205,34 @@ static void *gl2_renderchain_new(void) static void gl2_renderchain_bind_vao(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; - if (!gl) + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + if (!chain) return; - glBindVertexArray(gl->vao); + glBindVertexArray(chain->vao); } static void gl2_renderchain_unbind_vao(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; - if (!gl) - return; glBindVertexArray(0); } static void gl2_renderchain_new_vao(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; - if (!gl) + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + if (!chain) return; - glGenVertexArrays(1, &gl->vao); + glGenVertexArrays(1, &chain->vao); } static void gl2_renderchain_free_vao(void *data, void *chain_data) { - gl_t *gl = (gl_t*)data; - if (!gl) + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + if (!chain) return; - glDeleteVertexArrays(1, &gl->vao); + glDeleteVertexArrays(1, &chain->vao); } #endif From 2fd720bcb349043ae973ff4788deb8f0badb458b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 13:21:23 +0100 Subject: [PATCH 038/698] move more variables over --- gfx/common/gl_common.h | 1 - gfx/drivers_renderchain/gl2_renderchain.c | 20 +++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index c413d653c0..48458363c3 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -236,7 +236,6 @@ typedef struct gl video_info_t video_info; struct video_tex_info prev_info[GFX_MAX_TEXTURES]; struct video_fbo_rect fbo_rect[GFX_MAX_SHADERS]; - struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; const gl_renderchain_driver_t *renderchain_driver; void *renderchain_data; diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 0b0eff8ff3..972d93844c 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -70,6 +70,8 @@ typedef struct gl2_renderchain unsigned fence_count; GLsync fences[MAX_FENCES]; + + struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; } gl2_renderchain_t; #if (!defined(HAVE_OPENGLES) || defined(HAVE_OPENGLES3)) @@ -623,7 +625,7 @@ static void gl_create_fbo_texture(gl_t *gl, gl_bind_texture(texture, wrap_enum, mag_filter, min_filter); - fp_fbo = gl->fbo_scale[i].fp_fbo; + fp_fbo = chain->fbo_scale[i].fp_fbo; if (fp_fbo) { @@ -643,7 +645,7 @@ static void gl_create_fbo_texture(gl_t *gl, #endif { #ifndef HAVE_OPENGLES - bool srgb_fbo = gl->fbo_scale[i].srgb_fbo; + bool srgb_fbo = chain->fbo_scale[i].srgb_fbo; if (!fp_fbo && srgb_fbo) { @@ -740,7 +742,7 @@ static void gl2_renderchain_recompute_pass_sizes( for (i = 0; i < chain->fbo_pass; i++) { struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; - struct gfx_fbo_scale *fbo_scale = &gl->fbo_scale[i]; + struct gfx_fbo_scale *fbo_scale = &chain->fbo_scale[i]; gl2_renderchain_convert_geometry( gl, fbo_rect, fbo_scale, @@ -871,21 +873,21 @@ void gl2_renderchain_init( scale.valid = true; } - gl->fbo_scale[0] = scale; + chain->fbo_scale[0] = scale; for (i = 1; i < chain->fbo_pass; i++) { scaler.idx = i + 1; - scaler.scale = &gl->fbo_scale[i]; + scaler.scale = &chain->fbo_scale[i]; video_shader_driver_scale(&scaler); - if (!gl->fbo_scale[i].valid) + if (!chain->fbo_scale[i].valid) { - gl->fbo_scale[i].scale_x = gl->fbo_scale[i].scale_y = 1.0f; - gl->fbo_scale[i].type_x = gl->fbo_scale[i].type_y = + chain->fbo_scale[i].scale_x = chain->fbo_scale[i].scale_y = 1.0f; + chain->fbo_scale[i].type_x = chain->fbo_scale[i].type_y = RARCH_SCALE_INPUT; - gl->fbo_scale[i].valid = true; + chain->fbo_scale[i].valid = true; } } From f08b04952004397f51478184b5c3b63de314340e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 13:24:27 +0100 Subject: [PATCH 039/698] Move more variables --- gfx/common/gl_common.h | 1 - gfx/drivers_renderchain/gl2_renderchain.c | 21 +++++++++++---------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 48458363c3..7fb5527dcf 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -199,7 +199,6 @@ typedef struct gl GLuint menu_texture; GLuint pbo_readback[4]; GLuint texture[GFX_MAX_TEXTURES]; - GLuint fbo[GFX_MAX_SHADERS]; GLuint hw_render_fbo[GFX_MAX_TEXTURES]; unsigned tex_index; /* For use with PREV. */ diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 972d93844c..a74e0d6637 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -64,6 +64,7 @@ typedef struct gl2_renderchain int fbo_pass; GLuint vao; + GLuint fbo[GFX_MAX_SHADERS]; GLuint fbo_texture[GFX_MAX_SHADERS]; GLuint hw_render_depth[GFX_MAX_TEXTURES]; @@ -256,7 +257,7 @@ static void gl_check_fbo_dimension(gl_t *gl, fbo_rect->width = pow2_size; fbo_rect->height = pow2_size; - gl_recreate_fbo(fbo_rect, gl->fbo[i], &chain->fbo_texture[i]); + gl_recreate_fbo(fbo_rect, chain->fbo[i], &chain->fbo_texture[i]); /* Update feedback texture in-place so we avoid having to * juggle two different fbo_rect structs since they get updated here. */ @@ -354,7 +355,7 @@ static void gl2_renderchain_render( memcpy(fbo_info->coord, fbo_tex_coords, sizeof(fbo_tex_coords)); fbo_tex_info_cnt++; - gl2_bind_fb(gl->fbo[i]); + gl2_bind_fb(chain->fbo[i]); shader_info.data = gl; shader_info.idx = i + 1; @@ -491,10 +492,10 @@ static void gl2_renderchain_deinit_fbo(void *data, return; glDeleteTextures(chain->fbo_pass, chain->fbo_texture); - gl2_delete_fb(chain->fbo_pass, gl->fbo); + gl2_delete_fb(chain->fbo_pass, chain->fbo); memset(chain->fbo_texture, 0, sizeof(chain->fbo_texture)); - memset(gl->fbo, 0, sizeof(gl->fbo)); + memset(chain->fbo, 0, sizeof(chain->fbo)); if (gl->fbo_feedback) gl2_delete_fb(1, &gl->fbo_feedback); @@ -544,13 +545,13 @@ static bool gl_create_fbo_targets(gl_t *gl, void *chain_data) gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; glBindTexture(GL_TEXTURE_2D, 0); - gl2_gen_fb(chain->fbo_pass, gl->fbo); + gl2_gen_fb(chain->fbo_pass, chain->fbo); for (i = 0; i < chain->fbo_pass; i++) { GLenum status; - gl2_bind_fb(gl->fbo[i]); + gl2_bind_fb(chain->fbo[i]); gl2_fb_texture_2d(RARCH_GL_FRAMEBUFFER, RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, chain->fbo_texture[i], 0); @@ -582,7 +583,7 @@ static bool gl_create_fbo_targets(gl_t *gl, void *chain_data) return true; error: - gl2_delete_fb(chain->fbo_pass, gl->fbo); + gl2_delete_fb(chain->fbo_pass, chain->fbo); if (gl->fbo_feedback) gl2_delete_fb(1, &gl->fbo_feedback); RARCH_ERR("[GL]: Failed to set up frame buffer objects. Multi-pass shading will not work.\n"); @@ -802,7 +803,7 @@ static void gl2_renderchain_start_render(void *data, gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); - gl2_bind_fb(gl->fbo[0]); + gl2_bind_fb(chain->fbo[0]); gl_set_viewport(gl, video_info, gl->fbo_rect[0].img_width, @@ -1053,9 +1054,9 @@ static void gl2_renderchain_bind_prev_texture( { GLuint tmp_fbo = gl->fbo_feedback; GLuint tmp_tex = gl->fbo_feedback_texture; - gl->fbo_feedback = gl->fbo[gl->fbo_feedback_pass]; + gl->fbo_feedback = chain->fbo[gl->fbo_feedback_pass]; gl->fbo_feedback_texture = chain->fbo_texture[gl->fbo_feedback_pass]; - gl->fbo[gl->fbo_feedback_pass] = tmp_fbo; + chain->fbo[gl->fbo_feedback_pass] = tmp_fbo; chain->fbo_texture[gl->fbo_feedback_pass] = tmp_tex; } } From 50148c03e27083af64f194ab32595566b9442718 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:27:05 +0100 Subject: [PATCH 040/698] not used anymore https://github.com/libretro/RetroArch/commit/4e66962ba83941b85b206778828596c6ad20be33 --- libretro-common/include/streams/file_stream.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index e6d6bbca1c..c57731d76a 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -63,10 +63,9 @@ const char *filestream_get_ext(RFILE *stream); * @bufsize : optional buffer size (-1 or 0 to use default) * * Opens a file for reading or writing, depending on the requested mode. - * If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. **/ -RFILE *filestream_open(const char *path, unsigned mode, ssize_t bufsize); +RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused); ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence); From 89f7afdc8f28a3e28f6a14c707671ea62f44bfb3 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:28:38 +0100 Subject: [PATCH 041/698] silence warning --- libretro-common/streams/file_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index c4dcddf0a7..ff742674b7 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -166,7 +166,6 @@ void filestream_set_size(RFILE *stream) * @bufsize : optional buffer size (-1 or 0 to use default) * * Opens a file for reading or writing, depending on the requested mode. - * If bufsize is > 0 for unbuffered modes (like RFILE_MODE_WRITE), file will instead be fully buffered. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. **/ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) @@ -192,6 +191,7 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) (void)mode_int; (void)flags; + (void)bufsize; stream->hints = mode; From df55e6b4d1b094794bc08356eea01468f2fa6e06 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:30:38 +0100 Subject: [PATCH 042/698] actually, let's just completely remove it --- libretro-common/streams/file_stream.c | 27 +++++++++++---------------- 1 file changed, 11 insertions(+), 16 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index ff742674b7..f8db1c9442 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -170,7 +170,6 @@ void filestream_set_size(RFILE *stream) **/ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) { - ssize_t bufsize = 0x4000; int flags = 0; int mode_int = 0; #if defined(HAVE_BUFFERED_IO) @@ -191,7 +190,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) (void)mode_int; (void)flags; - (void)bufsize; stream->hints = mode; @@ -298,20 +296,17 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) if (!stream->fp) goto error; - if (bufsize > 0) - { - /* Regarding setvbuf: - * - * https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html - * - * If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and - * released on close. This is an extension to ANSI C. - * - * Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it. - */ - stream->buf = (char*)calloc(1, bufsize); - setvbuf(stream->fp, stream->buf, _IOFBF, bufsize); - } + /* Regarding setvbuf: + * + * https://www.freebsd.org/cgi/man.cgi?query=setvbuf&apropos=0&sektion=0&manpath=FreeBSD+11.1-RELEASE&arch=default&format=html + * + * If the size argument is not zero but buf is NULL, a buffer of the given size will be allocated immediately, and + * released on close. This is an extension to ANSI C. + * + * Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it. + */ + stream->buf = (char*)calloc(1, 0x4000); + setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000); } else #endif From 0d4ac123100f8c473a30064eb0fa7ea9982f5a9c Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:34:15 +0100 Subject: [PATCH 043/698] Update file_stream.c --- libretro-common/streams/file_stream.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index f8db1c9442..5703a69b1d 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -305,6 +305,7 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) * * Since C89 does not support specifying a null buffer with a non-zero size, we create and track our own buffer for it. */ + /* TODO: this is only useful for a few platforms, find which and add ifdef */ stream->buf = (char*)calloc(1, 0x4000); setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000); } From 2b3cc8898a0ae2312feba3c40d1ba7639b7fd9dc Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:41:04 +0100 Subject: [PATCH 044/698] Fix this one for non-stdio backends Why does filestream_get_fp exist --- playlist.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/playlist.c b/playlist.c index 2c22d9243d..5ccc40cd2e 100644 --- a/playlist.c +++ b/playlist.c @@ -381,7 +381,6 @@ void playlist_write_file(playlist_t *playlist) { size_t i; RFILE *file = NULL; - FILE *fp = NULL; if (!playlist || !playlist->modified) return; @@ -394,10 +393,8 @@ void playlist_write_file(playlist_t *playlist) return; } - fp = filestream_get_fp(file); - for (i = 0; i < playlist->size; i++) - fprintf(fp, "%s\n%s\n%s\n%s\n%s\n%s\n", + filestream_printf(file, "%s\n%s\n%s\n%s\n%s\n%s\n", playlist->entries[i].path ? playlist->entries[i].path : "", playlist->entries[i].label ? playlist->entries[i].label : "", playlist->entries[i].core_path, From 130e4522e2c580dec7989736dfe898dcd9dc188c Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:51:25 +0100 Subject: [PATCH 045/698] Update file_stream.h --- libretro-common/include/streams/file_stream.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index c57731d76a..ee8cc8e0ba 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -99,8 +99,11 @@ int filestream_printf(RFILE *stream, const char* format, ...); int filestream_error(RFILE *stream); -int filestream_get_fd(RFILE *stream); +/* DO NOT put this function back, unless you want to deal with + the UNAVOIDABLE REGRESSIONS on platforms using unexpected rfile backends +int filestream_get_fd(RFILE *stream); */ +/* TODO: remove, for the same reason as the above */ FILE* filestream_get_fp(RFILE *stream); int filestream_flush(RFILE *stream); From e4bb8e7aeb286b2c3e4e0bc890b72ee2a435c3f0 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 13:52:11 +0100 Subject: [PATCH 046/698] Update file_stream.c --- libretro-common/streams/file_stream.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 5703a69b1d..fce0934a92 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -121,17 +121,6 @@ FILE* filestream_get_fp(RFILE *stream) return stream->fp; } -int filestream_get_fd(RFILE *stream) -{ - if (!stream) - return -1; -#if defined(HAVE_BUFFERED_IO) - if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) - return fileno(stream->fp); -#endif - return stream->fd; -} - const char *filestream_get_ext(RFILE *stream) { if (!stream) From 1aa6ae1b389c2a18ca2ec48161b9a5b4cd53e812 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 14:25:16 +0100 Subject: [PATCH 047/698] Use FILE* all the way Fixes platforms where RFILE isn't using the FILE* backend, needed for #5664 --- verbosity.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/verbosity.c b/verbosity.c index 83dca5d02f..368067fa96 100644 --- a/verbosity.c +++ b/verbosity.c @@ -49,8 +49,8 @@ /* If this is non-NULL. RARCH_LOG and friends * will write to this file. */ -static RFILE *log_file = NULL; static FILE *log_file_fp = NULL; +static void* log_file_buf = NULL; static bool main_verbosity = false; static bool log_file_initialized = false; @@ -96,17 +96,21 @@ void retro_main_log_file_init(const char *path) if (path == NULL) return; - log_file = filestream_open(path, RFILE_MODE_WRITE, -1); - log_file_fp = filestream_get_fp(log_file); + log_file_fp = fopen(path, "wb"); log_file_initialized = true; + + /* TODO: this is only useful for a few platforms, find which and add ifdef */ + log_file_buf = (char*)calloc(1, 0x4000); + setvbuf(log_file_fp, log_file_buf, _IOFBF, 0x4000); } void retro_main_log_file_deinit(void) { - if (log_file && log_file_fp != stderr) - filestream_close(log_file); - log_file = NULL; + if (log_file_fp && log_file_fp != stderr) + fclose(log_file_fp); + if (log_file_buf) free(log_file_buf); log_file_fp = NULL; + log_file_buf = NULL; } #if !defined(HAVE_LOGGER) From b9900b1fb8e7c570d338325dd827badc044e98ab Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 14:27:36 +0100 Subject: [PATCH 048/698] This cast isn't needed, and probably breaks CXX_BUILD --- verbosity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verbosity.c b/verbosity.c index 368067fa96..2fb735e6bf 100644 --- a/verbosity.c +++ b/verbosity.c @@ -100,7 +100,7 @@ void retro_main_log_file_init(const char *path) log_file_initialized = true; /* TODO: this is only useful for a few platforms, find which and add ifdef */ - log_file_buf = (char*)calloc(1, 0x4000); + log_file_buf = calloc(1, 0x4000); setvbuf(log_file_fp, log_file_buf, _IOFBF, 0x4000); } From 300052626fc4db994a1e94a46c4ed93d3dd179b4 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 14:30:32 +0100 Subject: [PATCH 049/698] Use FILE* all the way Fixes platforms where RFILE isn't using the FILE* backend, needed for #5664 --- libretro-common/file/config_file.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 70f7b64aab..67c0703ff6 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -912,20 +912,28 @@ void config_set_bool(config_file_t *conf, const char *key, bool val) bool config_file_write(config_file_t *conf, const char *path) { - RFILE *file = NULL; + FILE* file = NULL; + void* buf = NULL; if (!string_is_empty(path)) { - file = filestream_open(path, RFILE_MODE_WRITE, 0x4000); + file = fopen(path, "wb"); if (!file) return false; - config_file_dump(conf, filestream_get_fp(file)); + + /* TODO: this is only useful for a few platforms, find which and add ifdef */ + buf = calloc(1, 0x4000); + setvbuf(file, buf, _IOFBF, 0x4000); + + config_file_dump(conf, file); } else config_file_dump(conf, stdout); - if (file) - filestream_close(file); + if (file && file != stdout) + fclose(file); + if (buf) + free(buf); return true; } From dca30d533fc415d04a03a79965e223f2f3a4d39e Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 14:31:11 +0100 Subject: [PATCH 050/698] Update file_stream.h --- libretro-common/include/streams/file_stream.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index ee8cc8e0ba..06cdf33ded 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -99,12 +99,10 @@ int filestream_printf(RFILE *stream, const char* format, ...); int filestream_error(RFILE *stream); -/* DO NOT put this function back, unless you want to deal with +/* DO NOT put these functions back, unless you want to deal with the UNAVOIDABLE REGRESSIONS on platforms using unexpected rfile backends -int filestream_get_fd(RFILE *stream); */ - -/* TODO: remove, for the same reason as the above */ -FILE* filestream_get_fp(RFILE *stream); +int filestream_get_fd(RFILE *stream); +FILE* filestream_get_fp(RFILE *stream); */ int filestream_flush(RFILE *stream); From c10859b745cfd902246b646c05e666c7461345a4 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 14:31:31 +0100 Subject: [PATCH 051/698] Update file_stream.c --- libretro-common/streams/file_stream.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index fce0934a92..9fdf995d8f 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -114,13 +114,6 @@ struct RFILE char *buf; }; -FILE* filestream_get_fp(RFILE *stream) -{ - if (!stream) - return NULL; - return stream->fp; -} - const char *filestream_get_ext(RFILE *stream) { if (!stream) From fbd3a435d2f93ed6d217257b055e411d700a66c5 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 15:01:57 +0100 Subject: [PATCH 052/698] Turns out this is char*, let's cast because CXX_BUILD wants that --- verbosity.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/verbosity.c b/verbosity.c index 2fb735e6bf..734dcaba39 100644 --- a/verbosity.c +++ b/verbosity.c @@ -101,7 +101,7 @@ void retro_main_log_file_init(const char *path) /* TODO: this is only useful for a few platforms, find which and add ifdef */ log_file_buf = calloc(1, 0x4000); - setvbuf(log_file_fp, log_file_buf, _IOFBF, 0x4000); + setvbuf(log_file_fp, (char*)log_file_buf, _IOFBF, 0x4000); } void retro_main_log_file_deinit(void) From ff4dca86f95ab0cf34004ddca9cacc353127bda4 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 15:01:58 +0100 Subject: [PATCH 053/698] Turns out this is char*, let's cast because CXX_BUILD wants that --- libretro-common/file/config_file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 67c0703ff6..66e03f3f7b 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -923,7 +923,7 @@ bool config_file_write(config_file_t *conf, const char *path) /* TODO: this is only useful for a few platforms, find which and add ifdef */ buf = calloc(1, 0x4000); - setvbuf(file, buf, _IOFBF, 0x4000); + setvbuf(file, (char*)buf, _IOFBF, 0x4000); config_file_dump(conf, file); } From 059354de2f60e14c3894382d53641a1cb1d09845 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 4 Dec 2017 16:26:28 +0100 Subject: [PATCH 054/698] Cleanup for config_file_write --- libretro-common/file/config_file.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 66e03f3f7b..9e23012168 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -912,12 +912,10 @@ void config_set_bool(config_file_t *conf, const char *key, bool val) bool config_file_write(config_file_t *conf, const char *path) { - FILE* file = NULL; - void* buf = NULL; - if (!string_is_empty(path)) { - file = fopen(path, "wb"); + void* buf = NULL; + FILE *file = fopen(path, "wb"); if (!file) return false; @@ -926,15 +924,14 @@ bool config_file_write(config_file_t *conf, const char *path) setvbuf(file, (char*)buf, _IOFBF, 0x4000); config_file_dump(conf, file); + + if (file != stdout) + fclose(file); + free(buf); } else config_file_dump(conf, stdout); - if (file && file != stdout) - fclose(file); - if (buf) - free(buf); - return true; } From d74ad6cd5e9fe19bcba0e299369aaa9960533c0b Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:32:40 +0100 Subject: [PATCH 055/698] Create fopen_utf8.h --- libretro-common/include/compat/fopen_utf8.h | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 libretro-common/include/compat/fopen_utf8.h diff --git a/libretro-common/include/compat/fopen_utf8.h b/libretro-common/include/compat/fopen_utf8.h new file mode 100644 index 0000000000..0c6d44d778 --- /dev/null +++ b/libretro-common/include/compat/fopen_utf8.h @@ -0,0 +1,5 @@ +#include +#ifdef _WIN32 +#define fopen fopen_utf8 +FILE* fopen_utf8(const char * filename, const char * mode); +#endif From 8df699984ea1820fa6ce64b0921db6689acbbf24 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:34:56 +0100 Subject: [PATCH 056/698] Update fopen_utf8.h --- libretro-common/include/compat/fopen_utf8.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libretro-common/include/compat/fopen_utf8.h b/libretro-common/include/compat/fopen_utf8.h index 0c6d44d778..583b558a26 100644 --- a/libretro-common/include/compat/fopen_utf8.h +++ b/libretro-common/include/compat/fopen_utf8.h @@ -1,5 +1,9 @@ #include #ifdef _WIN32 -#define fopen fopen_utf8 +/* defined to error rather than fopen_utf8, to make clear to everyone reading the code that not worrying about utf16 is fine */ +/* TODO: enable */ +/* #define fopen (use fopen_utf8 instead) */ FILE* fopen_utf8(const char * filename, const char * mode); +#else +#define fopen_utf8 fopen #endif From 8a93a9eb8eac185850f79eb54653cdb4bec2de7c Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:44:34 +0100 Subject: [PATCH 057/698] Create fopen_utf8.c --- libretro-common/compat/fopen_utf8.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 libretro-common/compat/fopen_utf8.c diff --git a/libretro-common/compat/fopen_utf8.c b/libretro-common/compat/fopen_utf8.c new file mode 100644 index 0000000000..a17ad81542 --- /dev/null +++ b/libretro-common/compat/fopen_utf8.c @@ -0,0 +1,25 @@ +#include +#include + +#ifdef _WIN32 +#undef fopen + +FILE* fopen_utf8(const char * filename, const char * mode) +{ +#if defined(_XBOX) + return fopen(filename, mode); +#elif defined(LEGACY_WIN32) + char * filename_local = utf8_to_local_string_alloc(path); + FILE* ret = fopen(filename_local, mode); + free(filename_local); + return ret; +#else + wchar_t * filename_w = utf8_to_utf16_string_alloc(filename); + wchar_t * mode_w = utf8_to_utf16_string_alloc(mode); + FILE* ret = _wfopen(filename_w, mode_w); + free(filename_w); + free(mode_w); + return ret; +#endif +} +#endif From cc2dd827b568a05f68bf6beeea2d90dff8bc5e75 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:46:59 +0100 Subject: [PATCH 058/698] Update Makefile.common --- Makefile.common | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile.common b/Makefile.common index 58158f33aa..14caf2e201 100644 --- a/Makefile.common +++ b/Makefile.common @@ -170,6 +170,7 @@ OBJ += frontend/frontend.o \ tasks/task_audio_mixer.o \ $(LIBRETRO_COMM_DIR)/encodings/encoding_utf.o \ $(LIBRETRO_COMM_DIR)/encodings/encoding_crc32.o \ + $(LIBRETRO_COMM_DIR)/compat/fopen_utf8.o \ $(LIBRETRO_COMM_DIR)/lists/file_list.o \ $(LIBRETRO_COMM_DIR)/lists/dir_list.o \ $(LIBRETRO_COMM_DIR)/file/retro_dirent.o \ From a6ef704369348a6cc57c35b847379d42d7e373ba Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:47:27 +0100 Subject: [PATCH 059/698] Update config_file.c --- libretro-common/file/config_file.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 9e23012168..cf105bbc3a 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -915,7 +916,7 @@ bool config_file_write(config_file_t *conf, const char *path) if (!string_is_empty(path)) { void* buf = NULL; - FILE *file = fopen(path, "wb"); + FILE *file = fopen_utf8(path, "wb"); if (!file) return false; From 486d5e77e3015e44c0df9334ca3b60b281ac7f25 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 16:48:17 +0100 Subject: [PATCH 060/698] Update verbosity.c --- verbosity.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/verbosity.c b/verbosity.c index 734dcaba39..a260f79949 100644 --- a/verbosity.c +++ b/verbosity.c @@ -35,6 +35,7 @@ #include #include +#include #ifdef HAVE_CONFIG_H #include "config.h" @@ -96,7 +97,7 @@ void retro_main_log_file_init(const char *path) if (path == NULL) return; - log_file_fp = fopen(path, "wb"); + log_file_fp = fopen_utf8(path, "wb"); log_file_initialized = true; /* TODO: this is only useful for a few platforms, find which and add ifdef */ From 6359aee509704c6488ef174d899b3d6233fafc9e Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 17:03:53 +0100 Subject: [PATCH 061/698] Update fopen_utf8.c --- libretro-common/compat/fopen_utf8.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libretro-common/compat/fopen_utf8.c b/libretro-common/compat/fopen_utf8.c index a17ad81542..843c449cc1 100644 --- a/libretro-common/compat/fopen_utf8.c +++ b/libretro-common/compat/fopen_utf8.c @@ -1,6 +1,12 @@ #include #include +#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +#ifndef LEGACY_WIN32 +#define LEGACY_WIN32 +#endif +#endif + #ifdef _WIN32 #undef fopen From 90dd2892b0449231f7d66eb33c85ec1ef8445b16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Jos=C3=A9=20Garc=C3=ADa=20Garc=C3=ADa?= Date: Mon, 4 Dec 2017 18:09:37 +0100 Subject: [PATCH 062/698] FIX sceIoOpen return error --- libretro-common/streams/file_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 9fdf995d8f..fd792bc40c 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -251,7 +251,7 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) #if defined(PSP) stream->fd = sceIoOpen(path, flags, mode_int); - if (stream->fd == -1) + if (stream->fd < 0) goto error; #else #if defined(HAVE_BUFFERED_IO) From 84691c7b9bb2c294b6cad03ca5096aa308238aa2 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 19:15:35 +0100 Subject: [PATCH 063/698] Update retro_miscellaneous.h --- libretro-common/include/retro_miscellaneous.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index bfa3fcb741..c2e11b021f 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -80,7 +80,7 @@ #define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31))) #define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31))) #define BIT128_GET(a, bit) ((a).data[(bit) >> 5] & (1 << ((bit) & 31))) -#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)); +#define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)) /* Helper macros and struct to keep track of many booleans. * To check for multiple bits, use &&, not &. From 908784b0ae3bc075382d9da41ac1d182bb3a79a1 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 20:19:35 +0100 Subject: [PATCH 064/698] Update griffin.c --- griffin/griffin.c | 1 + 1 file changed, 1 insertion(+) diff --git a/griffin/griffin.c b/griffin/griffin.c index 2bbb31a47b..8ac7762892 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -58,6 +58,7 @@ COMPATIBILITY #endif #include "../libretro-common/compat/compat_fnmatch.c" +#include "../libretro-common/compat/fopen_utf8.c" #include "../libretro-common/memmap/memalign.c" /*============================================================ From 2f1bcb64093e153561878fe33058e8db1033226f Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 20:20:10 +0100 Subject: [PATCH 065/698] Update fopen_utf8.c --- libretro-common/compat/fopen_utf8.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libretro-common/compat/fopen_utf8.c b/libretro-common/compat/fopen_utf8.c index 843c449cc1..1fd64187fb 100644 --- a/libretro-common/compat/fopen_utf8.c +++ b/libretro-common/compat/fopen_utf8.c @@ -1,5 +1,6 @@ #include #include +#include #if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) #ifndef LEGACY_WIN32 From 75c59aedcf6d45642bbd399aa7f348b96112123b Mon Sep 17 00:00:00 2001 From: Alcaro Date: Mon, 4 Dec 2017 20:23:45 +0100 Subject: [PATCH 066/698] Update fopen_utf8.h --- libretro-common/include/compat/fopen_utf8.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libretro-common/include/compat/fopen_utf8.h b/libretro-common/include/compat/fopen_utf8.h index 583b558a26..67cc289aa6 100644 --- a/libretro-common/include/compat/fopen_utf8.h +++ b/libretro-common/include/compat/fopen_utf8.h @@ -1,9 +1,14 @@ +#ifndef __FOPEN_UTF8_H +#define __FOPEN_UTF8_H + #include + #ifdef _WIN32 -/* defined to error rather than fopen_utf8, to make clear to everyone reading the code that not worrying about utf16 is fine */ +/* defined to error rather than fopen_utf8, to make it clear to everyone reading the code that not worrying about utf16 is fine */ /* TODO: enable */ /* #define fopen (use fopen_utf8 instead) */ FILE* fopen_utf8(const char * filename, const char * mode); #else #define fopen_utf8 fopen #endif +#endif From e8a9471afdbc17064ed47807f72cf972b89a17bb Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Mon, 4 Dec 2017 18:53:34 -0500 Subject: [PATCH 067/698] Fix to ARM to ensure chain has been declared --- gfx/drivers_renderchain/gl2_renderchain.c | 1 + 1 file changed, 1 insertion(+) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index a74e0d6637..ebdb9709b0 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -1281,6 +1281,7 @@ static void gl2_renderchain_copy_frame( } #elif defined(HAVE_OPENGLES) #if defined(HAVE_EGL) + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; if (chain->egl_images) { gfx_ctx_image_t img_info; From 49d02998086d0e154f22385d627710835ebb536c Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 4 Dec 2017 22:49:08 -0500 Subject: [PATCH 068/698] LEGACY_WIN32: check for target of less than Win2K instead of < vc2005, since Win98 does not support Unicode --- gfx/common/win32_common.c | 4 ++-- libretro-common/compat/fopen_utf8.c | 4 ++-- libretro-common/file/file_path.c | 8 ++++---- libretro-common/file/nbio/nbio_stdio.c | 4 ++-- libretro-common/file/nbio/nbio_windowsmmap.c | 4 ++-- libretro-common/file/retro_dirent.c | 2 +- libretro-common/streams/file_stream.c | 4 ++-- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index 40a807a2c0..a8a696cbb2 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -53,8 +53,8 @@ #include -/* Assume W-functions do not work below VC2005 and Xbox platforms */ -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 diff --git a/libretro-common/compat/fopen_utf8.c b/libretro-common/compat/fopen_utf8.c index 1fd64187fb..b61c53ebd1 100644 --- a/libretro-common/compat/fopen_utf8.c +++ b/libretro-common/compat/fopen_utf8.c @@ -2,7 +2,7 @@ #include #include -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 #endif @@ -16,7 +16,7 @@ FILE* fopen_utf8(const char * filename, const char * mode) #if defined(_XBOX) return fopen(filename, mode); #elif defined(LEGACY_WIN32) - char * filename_local = utf8_to_local_string_alloc(path); + char * filename_local = utf8_to_local_string_alloc(filename); FILE* ret = fopen(filename_local, mode); free(filename_local); return ret; diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 62ee9f20e7..8d9f8414b2 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -84,8 +84,8 @@ #include /* stat() is defined here */ #endif -/* Assume W-functions do not work below VC2005 and Xbox platforms */ -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 @@ -936,7 +936,7 @@ bool path_file_remove(const char *path) (void)path_wide; #if defined(_WIN32) && !defined(_XBOX) -#if defined(_MSC_VER) && _MSC_VER < 1400 +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 path_local = utf8_to_local_string_alloc(path); if (path_local) @@ -982,7 +982,7 @@ bool path_file_rename(const char *old_path, const char *new_path) (void)new_path_wide; #if defined(_WIN32) && !defined(_XBOX) -#if defined(_MSC_VER) && _MSC_VER < 1400 +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 old_path_local = utf8_to_local_string_alloc(old_path); new_path_local = utf8_to_local_string_alloc(new_path); diff --git a/libretro-common/file/nbio/nbio_stdio.c b/libretro-common/file/nbio/nbio_stdio.c index 3e6f4094f1..d3425f7de0 100644 --- a/libretro-common/file/nbio/nbio_stdio.c +++ b/libretro-common/file/nbio/nbio_stdio.c @@ -26,8 +26,8 @@ #include #include -/* Assume W-functions do not work below VC2005 and Xbox platforms */ -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 diff --git a/libretro-common/file/nbio/nbio_windowsmmap.c b/libretro-common/file/nbio/nbio_windowsmmap.c index caf0d72514..25208571b2 100644 --- a/libretro-common/file/nbio/nbio_windowsmmap.c +++ b/libretro-common/file/nbio/nbio_windowsmmap.c @@ -31,8 +31,8 @@ #include -/* Assume W-functions do not work below VC2005 and Xbox platforms */ -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 diff --git a/libretro-common/file/retro_dirent.c b/libretro-common/file/retro_dirent.c index 98328e30c1..aa221c888c 100644 --- a/libretro-common/file/retro_dirent.c +++ b/libretro-common/file/retro_dirent.c @@ -67,7 +67,7 @@ #include /* stat() is defined here */ #endif -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 #endif diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index fd792bc40c..da29d4864d 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -65,8 +65,8 @@ #include #endif -/* Assume W-functions do not work below VC2005 and Xbox platforms */ -#if defined(_MSC_VER) && _MSC_VER < 1400 || defined(_XBOX) +/* Assume W-functions do not work below Win2K and Xbox platforms */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0500 || defined(_XBOX) #ifndef LEGACY_WIN32 #define LEGACY_WIN32 From 0215648a83e931de88a613b6c1e34c1ed2bd0e84 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Tue, 5 Dec 2017 08:34:29 +0100 Subject: [PATCH 069/698] Make booleans boolean again #5856 why do both BIT_ and BIT128_ exist --- libretro-common/include/retro_miscellaneous.h | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index c2e11b021f..c26899eb9f 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -60,31 +60,29 @@ #define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7))) #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) -#define BIT_GET(a, bit) ((a)[(bit) >> 3] & (1 << ((bit) & 7))) +#define BIT_GET(a, bit) (((a).data[(bit) >> 3] >> ((bit) & 7)) & 1) #define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15))) #define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15))) -#define BIT16_GET(a, bit) (!!((a) & (1 << ((bit) & 15)))) +#define BIT16_GET(a, bit) (((a) >> ((bit) & 15)) & 1) #define BIT16_CLEAR_ALL(a) ((a) = 0) #define BIT32_SET(a, bit) ((a) |= (1 << ((bit) & 31))) #define BIT32_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 31))) -#define BIT32_GET(a, bit) (!!((a) & (1 << ((bit) & 31)))) +#define BIT32_GET(a, bit) (((a) >> ((bit) & 31)) & 1) #define BIT32_CLEAR_ALL(a) ((a) = 0) #define BIT64_SET(a, bit) ((a) |= (UINT64_C(1) << ((bit) & 63))) #define BIT64_CLEAR(a, bit) ((a) &= ~(UINT64_C(1) << ((bit) & 63))) -#define BIT64_GET(a, bit) (!!((a) & (UINT64_C(1) << ((bit) & 63)))) +#define BIT64_GET(a, bit) (((a) >> ((bit) & 63)) & 1) #define BIT64_CLEAR_ALL(a) ((a) = 0) #define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31))) #define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31))) -#define BIT128_GET(a, bit) ((a).data[(bit) >> 5] & (1 << ((bit) & 31))) +#define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1) #define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)) -/* Helper macros and struct to keep track of many booleans. - * To check for multiple bits, use &&, not &. - * For OR, | can be used. */ +/* Helper macros and struct to keep track of many booleans. */ typedef struct { uint32_t data[8]; From 3ccce249ea3e4fd7f67881d3893818009b0c02e5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 08:50:24 +0100 Subject: [PATCH 070/698] Fixes hotkey issues with MSVC --- input/input_defines.h | 25 +++++++++++++------ libretro-common/include/retro_miscellaneous.h | 3 +++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/input/input_defines.h b/input/input_defines.h index fa697c54a4..54eac4a25b 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -158,12 +158,12 @@ enum analog_dpad_mode #define GET_HAT_DIR(x) (x & HAT_MASK) #define GET_HAT(x) (x & (~HAT_MASK)) -#define RARCH_INPUT_STATE_BIT_SET(a,bit) ((a).data [((bit) >> 5)] |= (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) ((a)->data[((bit) >> 5)] |= (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_GET(a,bit) ((a).data [((bit) >> 5)] & (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) ((a)->data[((bit) >> 5)] & (1 << ((bit) & 31))) -#define RARCH_INPUT_STATE_CLEAR(a) memset(&a, 0, sizeof(a)); -#define RARCH_INPUT_STATE_CLEAR_PTR(a) memset(a, 0, sizeof(retro_bits_t)); +#define RARCH_INPUT_STATE_BIT_SET(a,bit) BIT128_SET(a, bit) +#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) BIT128_SET_PTR(a, bit) +#define RARCH_INPUT_STATE_BIT_GET(a,bit) BIT128_GET(a, bit) +#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) BIT128_GET_PTR(a, bit) +#define RARCH_INPUT_STATE_CLEAR(a) BIT128_CLEAR_ALL(a) +#define RARCH_INPUT_STATE_CLEAR_PTR(a) BIT128_CLEAR_ALL_PTR(a) #define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) #define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ @@ -178,8 +178,17 @@ enum analog_dpad_mode ((a).data[6])&=(~((b).data[6])); \ ((a).data[7])&=(~((b).data[7])); -#define RARCH_INPUT_STATE_COPY16_PTR(a,bits) {memset(a, 0, sizeof(retro_bits_t));((a)->data[0] = (bits)&0xffff);} -#define RARCH_INPUT_STATE_COPY32_PTR(a,bits) {memset(a, 0, sizeof(retro_bits_t));((a)->data[0] = (bits));} +#define RARCH_INPUT_STATE_COPY16_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + ((a)->data[0] = (bits) & 0xffff); \ +} + +#define RARCH_INPUT_STATE_COPY32_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + ((a)->data[0] = (bits)); \ +} RETRO_END_DECLS diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index c26899eb9f..9baf2e0214 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -78,9 +78,12 @@ #define BIT64_CLEAR_ALL(a) ((a) = 0) #define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31))) +#define BIT128_SET_PTR(a, bit) ((a)->data[(bit) >> 5] |= (1 << ((bit) & 31))) #define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31))) #define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1) +#define BIT128_GET_PTR(a, bit) (((a)->data[(bit) >> 5] >> ((bit) & 31)) & 1) #define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)) +#define BIT128_CLEAR_ALL_PTR(a) memset((a), 0, sizeof(retro_bits_t)) /* Helper macros and struct to keep track of many booleans. */ typedef struct From 0691c9e0d316e847e11ded8167d9e0e6113a79d2 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Tue, 5 Dec 2017 08:55:42 +0100 Subject: [PATCH 071/698] Let's not duplicate those macros more than needed --- libretro-common/include/retro_miscellaneous.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 9baf2e0214..b29c5cdc54 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -78,14 +78,17 @@ #define BIT64_CLEAR_ALL(a) ((a) = 0) #define BIT128_SET(a, bit) ((a).data[(bit) >> 5] |= (1 << ((bit) & 31))) -#define BIT128_SET_PTR(a, bit) ((a)->data[(bit) >> 5] |= (1 << ((bit) & 31))) #define BIT128_CLEAR(a, bit) ((a).data[(bit) >> 5] &= ~(1 << ((bit) & 31))) #define BIT128_GET(a, bit) (((a).data[(bit) >> 5] >> ((bit) & 31)) & 1) -#define BIT128_GET_PTR(a, bit) (((a)->data[(bit) >> 5] >> ((bit) & 31)) & 1) #define BIT128_CLEAR_ALL(a) memset(&(a), 0, sizeof(a)) -#define BIT128_CLEAR_ALL_PTR(a) memset((a), 0, sizeof(retro_bits_t)) + +#define BIT128_SET_PTR(a, bit) BIT128_SET(*a, bit) +#define BIT128_CLEAR_PTR(a, bit) BIT128_CLEAR(*a, bit) +#define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit) +#define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a) /* Helper macros and struct to keep track of many booleans. */ +/* This struct has 256 bits, but the macros are named 128 due to some historical accident. */ typedef struct { uint32_t data[8]; From e94300a581ca46975a1a07b9b7424e22b6be7e5f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 09:22:33 +0100 Subject: [PATCH 072/698] Get rid of a lot of RARCH_INPUT_STATE_BIT_ macros - replace them with BIT128_ equivalents instead --- input/connect/connect_nesusb.c | 7 +- input/connect/connect_ps2adapter.c | 7 +- input/connect/connect_ps3.c | 9 +-- input/connect/connect_ps4.c | 91 +++++++++------------ input/connect/connect_psxadapter.c | 7 +- input/connect/connect_snesusb.c | 7 +- input/connect/connect_wiiugca.c | 7 +- input/connect/connect_wiiupro.c | 90 +++++++++------------ input/connect/joypad_connection.c | 7 +- input/drivers/cocoa_input.c | 7 +- input/drivers/wiiu_input.c | 4 +- input/drivers_hid/btstack_hid.c | 5 +- input/drivers_hid/iohidmanager_hid.c | 4 +- input/drivers_hid/libusb_hid.c | 4 +- input/drivers_hid/null_hid.c | 2 +- input/drivers_hid/wiiusb_hid.c | 4 +- input/drivers_joypad/ctr_joypad.c | 7 +- input/drivers_joypad/gx_joypad.c | 7 +- input/drivers_joypad/hid_joypad.c | 7 +- input/drivers_joypad/linuxraw_joypad.c | 7 +- input/drivers_joypad/null_joypad.c | 2 +- input/drivers_joypad/parport_joypad.c | 7 +- input/drivers_joypad/ps3_joypad.c | 7 +- input/drivers_joypad/psp_joypad.c | 7 +- input/drivers_joypad/udev_joypad.c | 7 +- input/drivers_joypad/wiiu_joypad.c | 7 +- input/drivers_joypad/xdk_joypad.c | 7 +- input/input_defines.h | 6 -- input/input_driver.c | 29 +++---- menu/menu_event.c | 48 +++++------ retroarch.c | 107 ++++++++++++------------- retroarch.h | 2 - 32 files changed, 250 insertions(+), 276 deletions(-) diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c index 24c5f0532e..b39936be06 100644 --- a/input/connect/connect_nesusb.c +++ b/input/connect/connect_nesusb.c @@ -62,11 +62,12 @@ static void hidpad_nesusb_deinit(void *data) static void hidpad_nesusb_get_buttons(void *data, retro_bits_t* state) { struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; - if (device) { + if (device) + { RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_nesusb_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c index 78c3cf9c92..29b2c932fe 100644 --- a/input/connect/connect_ps2adapter.c +++ b/input/connect/connect_ps2adapter.c @@ -62,11 +62,12 @@ static void hidpad_ps2adapter_deinit(void *data) static void hidpad_ps2adapter_get_buttons(void *data, retro_bits_t *state) { struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*)data; - if ( device ) { + if (device) + { RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_ps2adapter_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index 422a1b02a2..de4e8fa3ec 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -114,14 +114,11 @@ static void hidpad_ps3_get_buttons(void *data, retro_bits_t *state) RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); /*PS button?*/ - if ( device->buttons & 0x10000 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); - } + if (device->buttons & 0x10000) + BIT128_SET_PTR(state, RARCH_MENU_TOGGLE); } else - { - RARCH_INPUT_STATE_CLEAR_PTR( state ); - } + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_ps3_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index 47a9cdabe6..901e693d80 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -20,6 +20,7 @@ #include #include +#include #include "joypad_connection.h" #include "../input_defines.h" @@ -187,64 +188,48 @@ static bool hidpad_ps4_check_dpad(struct ps4 *rpt, unsigned id) static void hidpad_ps4_get_buttons(void *data, retro_bits_t* state) { struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data; - struct ps4 *rpt = device ? (struct ps4*)&device->data : NULL; + struct ps4 *rpt = device ? + (struct ps4*)&device->data : NULL; if (!device || !rpt) return; - RARCH_INPUT_STATE_CLEAR_PTR( state ); + BIT128_CLEAR_ALL_PTR( state ); - if ( rpt->btn.r3 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); - } - if ( rpt->btn.l3 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); - } - if ( rpt->btn.options ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); - } - if ( rpt->btn.share ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); - } - if ( rpt->btn.r2 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); - } - if ( rpt->btn.l2 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); - } - if ( rpt->btn.r1 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); - } - if ( rpt->btn.l1 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); - } - if ( rpt->btn.triangle ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); - } - if ( rpt->btn.circle ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); - } - if ( rpt->btn.cross ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); - } - if ( rpt->btn.square ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); - } - if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_LEFT)) ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); - } - if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_DOWN)) ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); - } - if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); - } - if ( (hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_UP)) ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); - } - if ( rpt->btn.ps ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); - } + if (rpt->btn.r3) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); + if (rpt->btn.l3) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); + if (rpt->btn.options) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); + if ( rpt->btn.share) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); + if ( rpt->btn.r2) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); + if (rpt->btn.l2) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); + if (rpt->btn.r1) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); + if (rpt->btn.l1) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); + if (rpt->btn.triangle) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); + if (rpt->btn.circle) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); + if (rpt->btn.cross) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); + if (rpt->btn.square) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); + if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_LEFT))) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); + if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_DOWN))) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); + if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_RIGHT))) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); + if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_UP))) + BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); + if (rpt->btn.ps) + BIT128_SET_PTR( state, RARCH_MENU_TOGGLE ); } static int16_t hidpad_ps4_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c index 6f77e77f72..a4fcf78587 100644 --- a/input/connect/connect_psxadapter.c +++ b/input/connect/connect_psxadapter.c @@ -62,11 +62,12 @@ static void hidpad_psxadapter_deinit(void *data) static void hidpad_psxadapter_get_buttons(void *data, retro_bits_t *state) { struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; - if ( device ) { + if (device) + { RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_psxadapter_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c index bbc9fb43a4..b7cb594905 100644 --- a/input/connect/connect_snesusb.c +++ b/input/connect/connect_snesusb.c @@ -63,11 +63,12 @@ static void hidpad_snesusb_deinit(void *data) static void hidpad_snesusb_get_buttons(void *data, retro_bits_t *state) { struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; - if ( device ) { + if (device) + { RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_snesusb_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index 0f368e01fe..69ceaa0739 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -66,11 +66,12 @@ static void hidpad_wiiugca_deinit(void *data) static void hidpad_wiiugca_get_buttons(void *data, retro_bits_t *state) { struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data; - if ( device ) { + if (device) + { RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hidpad_wiiugca_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index d380e119a0..b7e148a010 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -121,64 +121,48 @@ static void hidpad_wiiupro_deinit(void *data) static void hidpad_wiiupro_get_buttons(void *data, retro_bits_t *state) { struct hidpad_wiiupro_data *device = (struct hidpad_wiiupro_data*)data; - struct wiiupro *rpt = device ? (struct wiiupro*)&device->data : NULL; + struct wiiupro *rpt = device ? + (struct wiiupro*)&device->data : NULL; if (!device || !rpt) return; - RARCH_INPUT_STATE_CLEAR_PTR( state ); + BIT128_CLEAR_ALL_PTR(state); - if ( rpt->btn.r3 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); - } - if ( rpt->btn.l3 ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); - } - if ( rpt->btn.plus ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); - } - if ( rpt->btn.minus ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); - } - if ( rpt->btn.zr ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); - } - if ( rpt->btn.zl ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); - } - if ( rpt->btn.r ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); - } - if ( rpt->btn.l ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); - } - if ( rpt->btn.x ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); - } - if ( rpt->btn.a ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); - } - if ( rpt->btn.b ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); - } - if ( rpt->btn.y ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); - } - if ( rpt->btn.left ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); - } - if ( rpt->btn.down ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); - } - if ( rpt->btn.right ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); - } - if ( rpt->btn.up ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); - } - if ( rpt->btn.home ) { - RARCH_INPUT_STATE_BIT_SET_PTR( state, RARCH_MENU_TOGGLE ); - } + if (rpt->btn.r3) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R3); + if (rpt->btn.l3) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L3); + if (rpt->btn.plus) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_START); + if ( rpt->btn.minus) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_SELECT); + if ( rpt->btn.zr) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R2); + if ( rpt->btn.zl) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L2); + if ( rpt->btn.r) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R); + if ( rpt->btn.l) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L); + if ( rpt->btn.x) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_X); + if ( rpt->btn.a) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_A); + if ( rpt->btn.b) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_B); + if ( rpt->btn.y) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_Y); + if ( rpt->btn.left) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_LEFT); + if ( rpt->btn.down) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_DOWN); + if ( rpt->btn.right) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_RIGHT); + if ( rpt->btn.up) + BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_UP); + if ( rpt->btn.home) + BIT128_SET_PTR(state, RARCH_MENU_TOGGLE); } static int16_t hidpad_wiiupro_get_axis(void *data, unsigned axis) diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 18ae10612d..178d32fcd2 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -175,11 +175,12 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad, void pad_connection_get_buttons(joypad_connection_t *joyconn, unsigned pad, retro_bits_t* state) { - if (joyconn->iface) { + if (joyconn->iface) + { joyconn->iface->get_buttons(joyconn->data, state); - } else { - RARCH_INPUT_STATE_CLEAR_PTR( state ); } + else + BIT128_CLEAR_ALL_PTR( state ); } int16_t pad_connection_get_axis(joypad_connection_t *joyconn, diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c index ceeaf417b1..2ce55ddb38 100644 --- a/input/drivers/cocoa_input.c +++ b/input/drivers/cocoa_input.c @@ -17,14 +17,17 @@ #include #include +#include + #ifdef HAVE_CONFIG_H #include "../../config.h" #endif #include "../input_driver.h" - #include "../input_keymaps.h" + #include "cocoa_input.h" + #include "../../gfx/video_driver.h" #include "../../driver.h" @@ -56,7 +59,7 @@ static int cocoa_input_find_any_button_ret(cocoa_input_data_t *apple, if (state) for (i = 0; i < 256; i++) - if (RARCH_INPUT_STATE_BIT_GET_PTR(state,i)) + if (BIT128_GET_PTR(state,i)) return i; return -1; } diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 7cb9444b3c..99d8087e65 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -107,8 +107,8 @@ static int16_t wiiu_pointer_device_state(wiiu_input_t* wiiu, unsigned id) case RETRO_DEVICE_ID_POINTER_PRESSED: { retro_bits_t state; - wiiu->joypad->get_buttons(0,&state); - return RARCH_INPUT_STATE_BIT_GET(state, VPAD_BUTTON_TOUCH) ? 1 : 0; + wiiu->joypad->get_buttons(0, &state); + return BIT128_GET(state, VPAD_BUTTON_TOUCH) ? 1 : 0; } case RETRO_DEVICE_ID_POINTER_X: return wiiu->joypad->axis(0, 0xFFFF0004UL); diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 83eec68c61..2166a2d2a3 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -27,6 +27,7 @@ #endif #include +#include #include #ifdef HAVE_DYNAMIC #include @@ -1369,7 +1370,7 @@ static void btstack_hid_joypad_get_buttons(void *data, unsigned port, retro_bits if (hid) pad_connection_get_buttons(&hid->slots[port], port, state); else - RARCH_INPUT_STATE_CLEAR_PTR(state); + BIT128_CLEAR_ALL_PTR(state); } static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey) @@ -1383,7 +1384,7 @@ static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); + return (BIT128_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index aac33afd56..3d479fce40 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -114,7 +114,7 @@ static void iohidmanager_hid_joypad_get_buttons(void *data, unsigned port, retro if (hid) return pad_connection_get_buttons(&hid->slots[port], port, state); else - RARCH_INPUT_STATE_CLEAR_PTR(state); + BIT128_CLEAR_ALL_PTR(state); } static bool iohidmanager_hid_joypad_button(void *data, @@ -150,7 +150,7 @@ static bool iohidmanager_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0) + return (BIT128_GET(buttons, joykey) != 0) || ((hid->buttons[port] & (1 << joykey)) != 0); return false; diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index 257b4819cc..a653b6b9bc 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -449,7 +449,7 @@ static void libusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ if (hid) return pad_connection_get_buttons(&hid->slots[port], port, state); else - RARCH_INPUT_STATE_CLEAR_PTR(state); + BIT128_CLEAR_ALL_PTR(state); } static bool libusb_hid_joypad_button(void *data, @@ -464,7 +464,7 @@ static bool libusb_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); + return (BIT128_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_hid/null_hid.c b/input/drivers_hid/null_hid.c index 34f8bdb7d6..74b61d051e 100644 --- a/input/drivers_hid/null_hid.c +++ b/input/drivers_hid/null_hid.c @@ -43,7 +43,7 @@ static void null_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t (void)data; (void)port; - RARCH_INPUT_STATE_CLEAR_PTR(state); + BIT128_CLEAR_ALL_PTR(state); } static bool null_hid_joypad_button(void *data, unsigned port, uint16_t joykey) diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index 3f0fdb282c..b550915689 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -484,7 +484,7 @@ static void wiiusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ if (hid) return pad_connection_get_buttons(&hid->connections[port], port, state); else - RARCH_INPUT_STATE_CLEAR_PTR(state); + BIT128_CLEAR_ALL_PTR(state); } static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) @@ -499,7 +499,7 @@ static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (RARCH_INPUT_STATE_BIT_GET(buttons, joykey) != 0); + return (BIT128_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index a31a7511fe..7350c71d78 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -72,11 +72,12 @@ static bool ctr_joypad_button(unsigned port_num, uint16_t key) static void ctr_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - if ( port_num < MAX_PADS ) { + if ( port_num < MAX_PADS ) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t ctr_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index 318eb637ed..2dc568df78 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -164,11 +164,12 @@ static bool gx_joypad_button(unsigned port, uint16_t key) static void gx_joypad_get_buttons(unsigned port, retro_bits_t *state) { - if ( port < MAX_PADS ) { + if (port < MAX_PADS) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port] ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/hid_joypad.c b/input/drivers_joypad/hid_joypad.c index eaed7efbed..fe0badd38a 100644 --- a/input/drivers_joypad/hid_joypad.c +++ b/input/drivers_joypad/hid_joypad.c @@ -57,11 +57,10 @@ static bool hid_joypad_button(unsigned port, uint16_t joykey) static void hid_joypad_get_buttons(unsigned port, retro_bits_t *state) { - if (generic_hid && generic_hid->get_buttons) { + if (generic_hid && generic_hid->get_buttons) generic_hid->get_buttons((void*)hid_driver_get_data(), port, state); - } else { - RARCH_INPUT_STATE_CLEAR_PTR( state ); - } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t hid_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index 212aeb8adc..f8cf299464 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -329,11 +329,12 @@ static bool linuxraw_joypad_button(unsigned port, uint16_t joykey) static void linuxraw_joypad_get_buttons(unsigned port, retro_bits_t *state) { const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port]; - if ( pad ) { + if (pad) + { RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/null_joypad.c b/input/drivers_joypad/null_joypad.c index d364433e06..f938e802e4 100644 --- a/input/drivers_joypad/null_joypad.c +++ b/input/drivers_joypad/null_joypad.c @@ -39,7 +39,7 @@ static bool null_joypad_button(unsigned port_num, uint16_t joykey) static void null_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - RARCH_INPUT_STATE_CLEAR_PTR( state ); + BIT128_CLEAR_ALL_PTR(state); } static int16_t null_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index 062e6dd958..61879842c8 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -343,11 +343,12 @@ static bool parport_joypad_button(unsigned port, uint16_t joykey) static void parport_joypad_get_buttons(unsigned port, retro_bits_t *state) { const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; - if ( pad ) { + if (pad) + { RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t parport_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index c14277924c..cd11cda4b7 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -70,11 +70,12 @@ static bool ps3_joypad_button(unsigned port_num, uint16_t joykey) static void ps3_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - if ( port_num < MAX_PADS ) { + if (port_num < MAX_PADS) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index 967e9092e8..c86ee65a0b 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -126,11 +126,12 @@ static bool psp_joypad_button(unsigned port_num, uint16_t key) static void psp_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - if ( port_num < PSP_MAX_PADS ) { + if (port_num < PSP_MAX_PADS) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 3aa6ba092a..50cfec8f20 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -607,11 +607,12 @@ static bool udev_joypad_button(unsigned port, uint16_t joykey) static void udev_joypad_get_buttons(unsigned port, retro_bits_t *state) { const struct udev_joypad *pad = (const struct udev_joypad*)&udev_pads[port]; - if ( pad ) { + if (pad) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad->buttons ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index ed62f14e09..67f8708b25 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -137,11 +137,12 @@ static bool wiiu_joypad_button(unsigned port_num, uint16_t key) static void wiiu_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - if ( port_num < MAX_PADS ) { + if (port_num < MAX_PADS) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLAR_ALL_PTR(state); } static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/xdk_joypad.c b/input/drivers_joypad/xdk_joypad.c index b9e25268b4..92fa8b02eb 100644 --- a/input/drivers_joypad/xdk_joypad.c +++ b/input/drivers_joypad/xdk_joypad.c @@ -78,11 +78,12 @@ static bool xdk_joypad_button(unsigned port_num, uint16_t joykey) static void xdk_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - if ( port_num < MAX_PADS ) { + if (port_num < MAX_PADS) + { RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); - } else { - RARCH_INPUT_STATE_CLEAR_PTR(state); } + else + BIT128_CLEAR_ALL_PTR(state); } static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/input_defines.h b/input/input_defines.h index 54eac4a25b..489122d3b1 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -158,12 +158,6 @@ enum analog_dpad_mode #define GET_HAT_DIR(x) (x & HAT_MASK) #define GET_HAT(x) (x & (~HAT_MASK)) -#define RARCH_INPUT_STATE_BIT_SET(a,bit) BIT128_SET(a, bit) -#define RARCH_INPUT_STATE_BIT_SET_PTR(a,bit) BIT128_SET_PTR(a, bit) -#define RARCH_INPUT_STATE_BIT_GET(a,bit) BIT128_GET(a, bit) -#define RARCH_INPUT_STATE_BIT_GET_PTR(a,bit) BIT128_GET_PTR(a, bit) -#define RARCH_INPUT_STATE_CLEAR(a) BIT128_CLEAR_ALL(a) -#define RARCH_INPUT_STATE_CLEAR_PTR(a) BIT128_CLEAR_ALL_PTR(a) #define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) #define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ diff --git a/input/input_driver.c b/input/input_driver.c index b2e216c191..ca491bea9f 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -810,7 +810,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) joypad_info.joy_idx = 0; joypad_info.auto_binds = NULL; - RARCH_INPUT_STATE_CLEAR_PTR( p_new_state ); + BIT128_CLEAR_ALL_PTR(p_new_state); input_driver_block_libretro_input = false; input_driver_block_hotkey = false; @@ -912,7 +912,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (pressed) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } } @@ -922,7 +922,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) { if (current_input->meta_key_pressed(current_input_data, i)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } } @@ -930,7 +930,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) #ifdef HAVE_OVERLAY if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } #endif @@ -945,7 +945,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (command_get(&handle)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } } @@ -954,7 +954,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) #ifdef HAVE_NETWORKGAMEPAD if (input_driver_remote && input_remote_key_pressed(i, 0)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } #endif @@ -1007,9 +1007,10 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) for (i = 0; i < 13; i++) { - if (current_input->input_state(current_input_data, joypad_info, binds, 0, + if (current_input->input_state(current_input_data, + joypad_info, binds, 0, RETRO_DEVICE_KEYBOARD, 0, ids[i][0])) - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, ids[i][1]); + BIT128_SET_PTR(p_new_state, ids[i][1]); } } } @@ -1036,7 +1037,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) const struct retro_keybind *enable_hotkey = &input_config_binds[0][RARCH_ENABLE_HOTKEY]; bool game_focus_toggle_valid = false; - RARCH_INPUT_STATE_CLEAR_PTR( p_new_state ); + BIT128_CLEAR_ALL_PTR(p_new_state); joypad_info.joy_idx = settings->uints.input_joypad_map[0]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; @@ -1082,7 +1083,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) 0, RETRO_DEVICE_JOYPAD, 0, i) ) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } @@ -1090,7 +1091,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) current_input->meta_key_pressed(current_input_data, i) ) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } @@ -1098,7 +1099,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } #endif @@ -1113,7 +1114,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (command_get(&handle)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } } @@ -1123,7 +1124,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (input_driver_remote && input_remote_key_pressed(i, 0)) { - RARCH_INPUT_STATE_BIT_SET_PTR(p_new_state, i); + BIT128_SET_PTR(p_new_state, i); continue; } #endif diff --git a/menu/menu_event.c b/menu/menu_event.c index c8fe862dbb..6af08b3e5a 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -160,7 +160,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) unsigned menu_cancel_btn = (!input_swap_override && settings->bools.input_menu_swap_ok_cancel_buttons) ? RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B; - unsigned ok_current = RARCH_INPUT_STATE_BIT_GET_PTR(p_input, menu_ok_btn ); + unsigned ok_current = BIT128_GET_PTR(p_input, menu_ok_btn ); unsigned ok_trigger = ok_current & ~ok_old; ok_old = ok_current; @@ -221,31 +221,31 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) { menu_event_osk_iterate(); - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (menu_event_get_osk_ptr() < 33) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + OSK_CHARS_PER_LINE); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) { if (menu_event_get_osk_ptr() >= OSK_CHARS_PER_LINE) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - OSK_CHARS_PER_LINE); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) { if (menu_event_get_osk_ptr() < 43) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + 1); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) { if (menu_event_get_osk_ptr() >= 1) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - 1); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) { if (menu_event_get_osk_idx() > OSK_TYPE_UNKNOWN + 1) menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() - 1)); @@ -253,7 +253,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_LAST - 1)); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) { if (menu_event_get_osk_idx() < OSK_TYPE_LAST - 1) menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() + 1)); @@ -261,50 +261,50 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1)); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_ok_btn)) + if (BIT128_GET_PTR(p_trigger_input, menu_ok_btn)) { if (menu_event_get_osk_ptr() >= 0) menu_event_osk_append(menu_event_get_osk_ptr()); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_cancel_btn)) + if (BIT128_GET_PTR(p_trigger_input, menu_cancel_btn)) { input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); } /* send return key to close keyboard input window */ - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); - RARCH_INPUT_STATE_CLEAR_PTR(p_trigger_input); + BIT128_CLEAR_ALL_PTR(p_trigger_input); } else { - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) + if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) ret = MENU_ACTION_SCROLL_UP; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) ret = MENU_ACTION_SCROLL_DOWN; else if (ok_trigger) ret = MENU_ACTION_OK; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, menu_cancel_btn)) + else if (BIT128_GET_PTR(p_trigger_input, menu_cancel_btn)) ret = MENU_ACTION_CANCEL; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X)) ret = MENU_ACTION_SEARCH; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) ret = MENU_ACTION_START; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) ret = MENU_ACTION_INFO; - else if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE)) + else if (BIT128_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; } @@ -314,7 +314,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_kb_set_internal(RETROK_F11, 0); } - if (RARCH_INPUT_STATE_BIT_GET_PTR(p_trigger_input, RARCH_QUIT_KEY)) + if (BIT128_GET_PTR(p_trigger_input, RARCH_QUIT_KEY)) return MENU_ACTION_QUIT; mouse_enabled = settings->bools.menu_mouse_enable; diff --git a/retroarch.c b/retroarch.c index 88173a0266..f9d7b6aae9 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2315,35 +2315,35 @@ static bool input_driver_toggle_button_combo( switch (mode) { case INPUT_TOGGLE_DOWN_Y_L_R: - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_Y)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_Y)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) return false; break; case INPUT_TOGGLE_L3_R3: - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L3)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L3)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R3)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R3)) return false; break; case INPUT_TOGGLE_L1_R1_START_SELECT: - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) return false; break; case INPUT_TOGGLE_START_SELECT: - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) return false; - if (!RARCH_INPUT_STATE_BIT_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) return false; break; default: @@ -2375,7 +2375,7 @@ static enum runloop_state runloop_check_state( retro_bits_t current_input; - if ( menu_is_alive && !(settings->bools.menu_unified_controls && !menu_input_dialog_get_display_kb()) ) + if (menu_is_alive && !(settings->bools.menu_unified_controls && !menu_input_dialog_get_display_kb())) input_menu_keys_pressed(settings, ¤t_input); else input_keys_pressed(settings, ¤t_input); @@ -2391,9 +2391,7 @@ static enum runloop_state runloop_check_state( ((settings->uints.input_menu_toggle_gamepad_combo != INPUT_TOGGLE_NONE) && input_driver_toggle_button_combo( settings->uints.input_menu_toggle_gamepad_combo, &last_input))) - { - RARCH_INPUT_STATE_BIT_SET(current_input, RARCH_MENU_TOGGLE); - } + BIT128_SET(current_input, RARCH_MENU_TOGGLE); #endif if (input_driver_flushing_input) @@ -2401,9 +2399,9 @@ static enum runloop_state runloop_check_state( input_driver_flushing_input = false; if (RARCH_INPUT_STATE_ANY_SET(current_input)) { - RARCH_INPUT_STATE_CLEAR( current_input ); + BIT128_CLEAR_ALL(current_input); if (runloop_paused) - RARCH_INPUT_STATE_BIT_SET(current_input, RARCH_PAUSE_TOGGLE); + BIT128_SET(current_input, RARCH_PAUSE_TOGGLE); input_driver_flushing_input = true; } } @@ -2412,14 +2410,14 @@ static enum runloop_state runloop_check_state( #ifdef HAVE_MENU if (menu_driver_binding_state) - RARCH_INPUT_STATE_CLEAR( current_input ); + BIT128_CLEAR_ALL(current_input); #endif #ifdef HAVE_OVERLAY /* Check next overlay */ { static bool old_should_check_next_overlay = false; - bool should_check_next_overlay = runloop_cmd_press( + bool should_check_next_overlay = BIT128_GET( current_input, RARCH_OVERLAY_NEXT); if (should_check_next_overlay && !old_should_check_next_overlay) @@ -2431,7 +2429,7 @@ static enum runloop_state runloop_check_state( /* Check fullscreen toggle */ { - bool fs_toggle_pressed = runloop_cmd_press( + bool fs_toggle_pressed = BIT128_GET( current_input, RARCH_FULLSCREEN_TOGGLE_KEY); fs_toggle_triggered = fs_toggle_pressed && !old_fs_toggle_pressed; @@ -2454,7 +2452,7 @@ static enum runloop_state runloop_check_state( /* Check mouse grab toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_GRAB_MOUSE_TOGGLE); if (pressed && !old_pressed) @@ -2489,7 +2487,7 @@ static enum runloop_state runloop_check_state( /* Check quit key */ { static bool old_quit_key = false; - bool quit_key = runloop_cmd_press( + bool quit_key = BIT128_GET( current_input, RARCH_QUIT_KEY); bool trig_quit_key = quit_key && !old_quit_key; @@ -2544,7 +2542,7 @@ static enum runloop_state runloop_check_state( bool focused; trigger_input = current_input; - RARCH_INPUT_STATE_CLEAR_BITS( trigger_input, old_input ); + RARCH_INPUT_STATE_CLEAR_BITS(trigger_input, old_input); action = (enum menu_action)menu_event(¤t_input, &trigger_input); focused = pause_nonactive ? is_focused : true; @@ -2583,7 +2581,7 @@ static enum runloop_state runloop_check_state( /* Check game focus toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_GAME_FOCUS_TOGGLE); if (pressed && !old_pressed) @@ -2596,7 +2594,7 @@ static enum runloop_state runloop_check_state( /* Check menu toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_MENU_TOGGLE); if (menu_event_kb_is_set(RETROK_F1) == 1) @@ -2646,7 +2644,7 @@ static enum runloop_state runloop_check_state( /* Check screenshot toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_SCREENSHOT); if (pressed && old_pressed) @@ -2658,7 +2656,7 @@ static enum runloop_state runloop_check_state( /* Check audio mute toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_MUTE); if (pressed && !old_pressed) @@ -2670,8 +2668,7 @@ static enum runloop_state runloop_check_state( /* Check OSK toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( - current_input, RARCH_OSK); + bool pressed = BIT128_GET(current_input, RARCH_OSK); if (pressed && !old_pressed) { @@ -2687,9 +2684,9 @@ static enum runloop_state runloop_check_state( old_pressed = pressed; } - if (runloop_cmd_press(current_input, RARCH_VOLUME_UP)) + if (BIT128_GET(current_input, RARCH_VOLUME_UP)) command_event(CMD_EVENT_VOLUME_UP, NULL); - else if (runloop_cmd_press(current_input, RARCH_VOLUME_DOWN)) + else if (BIT128_GET(current_input, RARCH_VOLUME_DOWN)) command_event(CMD_EVENT_VOLUME_DOWN, NULL); #ifdef HAVE_NETWORKING @@ -2697,9 +2694,9 @@ static enum runloop_state runloop_check_state( { static bool old_netplay_flip = false; static bool old_netplay_watch = false; - bool netplay_flip = runloop_cmd_press( + bool netplay_flip = BIT128_GET( current_input, RARCH_NETPLAY_FLIP); - bool netplay_watch = runloop_cmd_press( + bool netplay_watch = BIT128_GET( current_input, RARCH_NETPLAY_GAME_WATCH); if (netplay_flip && !old_netplay_flip) @@ -2718,9 +2715,9 @@ static enum runloop_state runloop_check_state( static bool old_frameadvance = false; static bool old_pause_pressed = false; bool check_is_oneshot = true; - bool frameadvance_pressed = runloop_cmd_press( + bool frameadvance_pressed = BIT128_GET( current_input, RARCH_FRAMEADVANCE); - bool pause_pressed = runloop_cmd_press( + bool pause_pressed = BIT128_GET( current_input, RARCH_PAUSE_TOGGLE); bool trig_frameadvance = frameadvance_pressed && !old_frameadvance; @@ -2744,7 +2741,7 @@ static enum runloop_state runloop_check_state( if (runloop_paused) { check_is_oneshot = trig_frameadvance || - runloop_cmd_press(current_input, RARCH_REWIND); + BIT128_GET(current_input, RARCH_REWIND); if (fs_toggle_triggered) { @@ -2769,9 +2766,9 @@ static enum runloop_state runloop_check_state( { static bool old_button_state = false; static bool old_hold_button_state = false; - bool new_button_state = runloop_cmd_press( + bool new_button_state = BIT128_GET( current_input, RARCH_FAST_FORWARD_KEY); - bool new_hold_button_state = runloop_cmd_press( + bool new_hold_button_state = BIT128_GET( current_input, RARCH_FAST_FORWARD_HOLD_KEY); if (new_button_state && !old_button_state) @@ -2812,9 +2809,9 @@ static enum runloop_state runloop_check_state( { static bool old_should_slot_increase = false; static bool old_should_slot_decrease = false; - bool should_slot_increase = runloop_cmd_press( + bool should_slot_increase = BIT128_GET( current_input, RARCH_STATE_SLOT_PLUS); - bool should_slot_decrease = runloop_cmd_press( + bool should_slot_decrease = BIT128_GET( current_input, RARCH_STATE_SLOT_MINUS); /* Checks if the state increase/decrease keys have been pressed @@ -2865,9 +2862,9 @@ static enum runloop_state runloop_check_state( { static bool old_should_savestate = false; static bool old_should_loadstate = false; - bool should_savestate = runloop_cmd_press( + bool should_savestate = BIT128_GET( current_input, RARCH_SAVE_STATE_KEY); - bool should_loadstate = runloop_cmd_press( + bool should_loadstate = BIT128_GET( current_input, RARCH_LOAD_STATE_KEY); if (should_savestate && !old_should_savestate) @@ -2888,14 +2885,14 @@ static enum runloop_state runloop_check_state( s[0] = '\0'; - if (state_manager_check_rewind(runloop_cmd_press(current_input, RARCH_REWIND), + if (state_manager_check_rewind(BIT128_GET(current_input, RARCH_REWIND), settings->uints.rewind_granularity, runloop_paused, s, sizeof(s), &t)) runloop_msg_queue_push(s, 0, t, true); } /* Checks if slowmotion toggle/hold was being pressed and/or held. */ { - runloop_slowmotion = runloop_cmd_press(current_input, RARCH_SLOWMOTION); + runloop_slowmotion = BIT128_GET(current_input, RARCH_SLOWMOTION); if (runloop_slowmotion) { @@ -2917,7 +2914,7 @@ static enum runloop_state runloop_check_state( /* Check movie record toggle */ { static bool old_pressed = false; - bool pressed = runloop_cmd_press( + bool pressed = BIT128_GET( current_input, RARCH_MOVIE_RECORD_TOGGLE); if (pressed && !old_pressed) @@ -2930,9 +2927,9 @@ static enum runloop_state runloop_check_state( { static bool old_shader_next = false; static bool old_shader_prev = false; - bool shader_next = runloop_cmd_press( + bool shader_next = BIT128_GET( current_input, RARCH_SHADER_NEXT); - bool shader_prev = runloop_cmd_press( + bool shader_prev = BIT128_GET( current_input, RARCH_SHADER_PREV); bool trig_shader_next = shader_next && !old_shader_next; bool trig_shader_prev = shader_prev && !old_shader_prev; @@ -2949,11 +2946,11 @@ static enum runloop_state runloop_check_state( static bool old_disk_eject = false; static bool old_disk_next = false; static bool old_disk_prev = false; - bool disk_eject = runloop_cmd_press( + bool disk_eject = BIT128_GET( current_input, RARCH_DISK_EJECT_TOGGLE); - bool disk_next = runloop_cmd_press( + bool disk_next = BIT128_GET( current_input, RARCH_DISK_NEXT); - bool disk_prev = runloop_cmd_press( + bool disk_prev = BIT128_GET( current_input, RARCH_DISK_PREV); if (disk_eject && !old_disk_eject) @@ -2971,7 +2968,7 @@ static enum runloop_state runloop_check_state( /* Check reset */ { static bool old_state = false; - bool new_state = runloop_cmd_press( + bool new_state = BIT128_GET( current_input, RARCH_RESET); if (new_state && !old_state) @@ -2985,11 +2982,11 @@ static enum runloop_state runloop_check_state( static bool old_cheat_index_plus = false; static bool old_cheat_index_minus = false; static bool old_cheat_index_toggle = false; - bool cheat_index_plus = runloop_cmd_press( + bool cheat_index_plus = BIT128_GET( current_input, RARCH_CHEAT_INDEX_PLUS); - bool cheat_index_minus = runloop_cmd_press( + bool cheat_index_minus = BIT128_GET( current_input, RARCH_CHEAT_INDEX_MINUS); - bool cheat_index_toggle = runloop_cmd_press( + bool cheat_index_toggle = BIT128_GET( current_input, RARCH_CHEAT_TOGGLE); if (cheat_index_plus && !old_cheat_index_plus) diff --git a/retroarch.h b/retroarch.h index 3cd1b742d3..6c45f744c1 100644 --- a/retroarch.h +++ b/retroarch.h @@ -27,8 +27,6 @@ #include "core_type.h" #include "core.h" -#define runloop_cmd_press(current_input, id) (RARCH_INPUT_STATE_BIT_GET(current_input, id)) - RETRO_BEGIN_DECLS enum rarch_ctl_state From 31cc6a8dd769707dfc009d5980335abafde9bdbd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 09:51:58 +0100 Subject: [PATCH 073/698] Create 256 bit macros --- libretro-common/include/retro_miscellaneous.h | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index b29c5cdc54..e42f6b345b 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -87,8 +87,18 @@ #define BIT128_GET_PTR(a, bit) BIT128_GET(*a, bit) #define BIT128_CLEAR_ALL_PTR(a) BIT128_CLEAR_ALL(*a) +#define BIT256_SET(a, bit) BIT128_SET(a, bit) +#define BIT256_CLEAR(a, bit) BIT128_CLEAR(a, bit) +#define BIT256_GET(a, bit) BIT128_GET(a, bit) +#define BIT256_CLEAR_ALL(a) BIT128_CLEAR_ALL(a) + +#define BIT256_SET_PTR(a, bit) BIT256_SET(*a, bit) +#define BIT256_CLEAR_PTR(a, bit) BIT256_CLEAR(*a, bit) +#define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit) +#define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a) + /* Helper macros and struct to keep track of many booleans. */ -/* This struct has 256 bits, but the macros are named 128 due to some historical accident. */ +/* This struct has 256 bits. */ typedef struct { uint32_t data[8]; From 6c09661a643f02b0bb92b7802e41022b759b166c Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 10:42:37 +0100 Subject: [PATCH 074/698] Move defines to retro_miscellaneous.h --- input/connect/connect_nesusb.c | 2 +- input/connect/connect_ps2adapter.c | 2 +- input/connect/connect_ps3.c | 2 +- input/connect/connect_psxadapter.c | 2 +- input/connect/connect_snesusb.c | 2 +- input/connect/connect_wii.c | 6 ++--- input/connect/connect_wiiugca.c | 2 +- input/drivers_joypad/ctr_joypad.c | 2 +- input/drivers_joypad/gx_joypad.c | 2 +- input/drivers_joypad/linuxraw_joypad.c | 2 +- input/drivers_joypad/mfi_joypad.m | 2 +- input/drivers_joypad/parport_joypad.c | 2 +- input/drivers_joypad/ps3_joypad.c | 2 +- input/drivers_joypad/psp_joypad.c | 2 +- input/drivers_joypad/udev_joypad.c | 2 +- input/drivers_joypad/wiiu_joypad.c | 2 +- input/drivers_joypad/xdk_joypad.c | 2 +- input/input_defines.h | 27 ------------------- libretro-common/include/retro_miscellaneous.h | 27 +++++++++++++++++++ menu/menu_event.c | 2 +- retroarch.c | 10 +++---- 21 files changed, 51 insertions(+), 53 deletions(-) diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c index b39936be06..797f83e7ae 100644 --- a/input/connect/connect_nesusb.c +++ b/input/connect/connect_nesusb.c @@ -64,7 +64,7 @@ static void hidpad_nesusb_get_buttons(void *data, retro_bits_t* state) struct hidpad_nesusb_data *device = (struct hidpad_nesusb_data*)data; if (device) { - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c index 29b2c932fe..c79aac8df3 100644 --- a/input/connect/connect_ps2adapter.c +++ b/input/connect/connect_ps2adapter.c @@ -64,7 +64,7 @@ static void hidpad_ps2adapter_get_buttons(void *data, retro_bits_t *state) struct hidpad_ps2adapter_data *device = (struct hidpad_ps2adapter_data*)data; if (device) { - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index de4e8fa3ec..6ef05f8e4e 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -111,7 +111,7 @@ static void hidpad_ps3_get_buttons(void *data, retro_bits_t *state) if ( device ) { /*copy first 16 bits - standard RetroPad controls*/ - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); /*PS button?*/ if (device->buttons & 0x10000) diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c index a4fcf78587..03193fd606 100644 --- a/input/connect/connect_psxadapter.c +++ b/input/connect/connect_psxadapter.c @@ -64,7 +64,7 @@ static void hidpad_psxadapter_get_buttons(void *data, retro_bits_t *state) struct hidpad_psxadapter_data *device = (struct hidpad_psxadapter_data*)data; if (device) { - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c index b7cb594905..51570d82fa 100644 --- a/input/connect/connect_snesusb.c +++ b/input/connect/connect_snesusb.c @@ -65,7 +65,7 @@ static void hidpad_snesusb_get_buttons(void *data, retro_bits_t *state) struct hidpad_snesusb_data *device = (struct hidpad_snesusb_data*)data; if (device) { - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/connect/connect_wii.c b/input/connect/connect_wii.c index ec4ceaaa72..83ac50d736 100644 --- a/input/connect/connect_wii.c +++ b/input/connect/connect_wii.c @@ -677,9 +677,9 @@ static void hidpad_wii_get_buttons(void *data, retro_bits_t *state) struct connect_wii_wiimote_t* device = (struct connect_wii_wiimote_t*)data; if ( device ) { - uint32_t b; - b = device->btns | (device->exp.cc.classic.btns << 16); /*broken? this doesn't match retropad!!*/ - RARCH_INPUT_STATE_COPY32_PTR(state, b); + /* TODO/FIXME - Broken? this doesn't match retropad! */ + uint32_t b = device->btns | (device->exp.cc.classic.btns << 16); + BITS_COPY32_PTR(state, b); } } diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index 69ceaa0739..cd0ea8b33e 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -68,7 +68,7 @@ static void hidpad_wiiugca_get_buttons(void *data, retro_bits_t *state) struct hidpad_wiiugca_data *device = (struct hidpad_wiiugca_data*)data; if (device) { - RARCH_INPUT_STATE_COPY16_PTR(state, device->buttons); + BITS_COPY16_PTR(state, device->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index 7350c71d78..a98fce76fc 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -74,7 +74,7 @@ static void ctr_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { if ( port_num < MAX_PADS ) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state ); + BITS_COPY16_PTR( state, pad_state ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index 2dc568df78..bccc6f467b 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -166,7 +166,7 @@ static void gx_joypad_get_buttons(unsigned port, retro_bits_t *state) { if (port < MAX_PADS) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port] ); + BITS_COPY16_PTR( state, pad_state[port] ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index f8cf299464..c43ea0b93a 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -331,7 +331,7 @@ static void linuxraw_joypad_get_buttons(unsigned port, retro_bits_t *state) const struct linuxraw_joypad *pad = (const struct linuxraw_joypad*)&linuxraw_pads[port]; if (pad) { - RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); + BITS_COPY16_PTR(state, pad->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/mfi_joypad.m b/input/drivers_joypad/mfi_joypad.m index 10964893f0..94f56b2147 100644 --- a/input/drivers_joypad/mfi_joypad.m +++ b/input/drivers_joypad/mfi_joypad.m @@ -223,7 +223,7 @@ static bool apple_gamecontroller_joypad_button(unsigned port, uint16_t joykey) static void apple_gamecontroller_joypad_get_buttons(unsigned port, retro_bits_t *state) { - RARCH_INPUT_STATE_COPY16_PTR(state, mfi_buttons[port]); + BITS_COPY16_PTR(state, mfi_buttons[port]); } static int16_t apple_gamecontroller_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index 61879842c8..f24c2706a5 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -345,7 +345,7 @@ static void parport_joypad_get_buttons(unsigned port, retro_bits_t *state) const struct parport_joypad *pad = (const struct parport_joypad*)&parport_pads[port]; if (pad) { - RARCH_INPUT_STATE_COPY16_PTR(state, pad->buttons); + BITS_COPY16_PTR(state, pad->buttons); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index cd11cda4b7..f37822642d 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -72,7 +72,7 @@ static void ps3_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { if (port_num < MAX_PADS) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + BITS_COPY16_PTR( state, pad_state[port_num] ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index c86ee65a0b..60ca2daff3 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -128,7 +128,7 @@ static void psp_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { if (port_num < PSP_MAX_PADS) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + BITS_COPY16_PTR( state, pad_state[port_num] ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 50cfec8f20..283e1bd38b 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -609,7 +609,7 @@ static void udev_joypad_get_buttons(unsigned port, retro_bits_t *state) const struct udev_joypad *pad = (const struct udev_joypad*)&udev_pads[port]; if (pad) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad->buttons ); + BITS_COPY16_PTR( state, pad->buttons ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 67f8708b25..8a3d8189db 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -139,7 +139,7 @@ static void wiiu_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { if (port_num < MAX_PADS) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + BITS_COPY16_PTR( state, pad_state[port_num] ); } else BIT128_CLAR_ALL_PTR(state); diff --git a/input/drivers_joypad/xdk_joypad.c b/input/drivers_joypad/xdk_joypad.c index 92fa8b02eb..6553346160 100644 --- a/input/drivers_joypad/xdk_joypad.c +++ b/input/drivers_joypad/xdk_joypad.c @@ -80,7 +80,7 @@ static void xdk_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { if (port_num < MAX_PADS) { - RARCH_INPUT_STATE_COPY16_PTR( state, pad_state[port_num] ); + BITS_COPY16_PTR( state, pad_state[port_num] ); } else BIT128_CLEAR_ALL_PTR(state); diff --git a/input/input_defines.h b/input/input_defines.h index 489122d3b1..b005e90f58 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -158,33 +158,6 @@ enum analog_dpad_mode #define GET_HAT_DIR(x) (x & HAT_MASK) #define GET_HAT(x) (x & (~HAT_MASK)) -#define RARCH_INPUT_STATE_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ - ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) -#define RARCH_INPUT_STATE_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ - ((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) ) -#define RARCH_INPUT_STATE_CLEAR_BITS(a,b) \ - ((a).data[0])&=(~((b).data[0])); \ - ((a).data[1])&=(~((b).data[1])); \ - ((a).data[2])&=(~((b).data[2])); \ - ((a).data[3])&=(~((b).data[3])); \ - ((a).data[4])&=(~((b).data[4])); \ - ((a).data[5])&=(~((b).data[5])); \ - ((a).data[6])&=(~((b).data[6])); \ - ((a).data[7])&=(~((b).data[7])); - -#define RARCH_INPUT_STATE_COPY16_PTR(a,bits) \ -{ \ - BIT128_CLEAR_ALL_PTR(a); \ - ((a)->data[0] = (bits) & 0xffff); \ -} - -#define RARCH_INPUT_STATE_COPY32_PTR(a,bits) \ -{ \ - BIT128_CLEAR_ALL_PTR(a); \ - ((a)->data[0] = (bits)); \ -} - - RETRO_END_DECLS #endif diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index e42f6b345b..c69afed90b 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -58,6 +58,33 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define BITS_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ + ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) +#define BITS_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ + ((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) ) +#define BITS_CLEAR_BITS(a,b) \ + ((a).data[0])&=(~((b).data[0])); \ + ((a).data[1])&=(~((b).data[1])); \ + ((a).data[2])&=(~((b).data[2])); \ + ((a).data[3])&=(~((b).data[3])); \ + ((a).data[4])&=(~((b).data[4])); \ + ((a).data[5])&=(~((b).data[5])); \ + ((a).data[6])&=(~((b).data[6])); \ + ((a).data[7])&=(~((b).data[7])); + +#define BITS_COPY16_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + ((a)->data[0] = (bits) & 0xffff); \ +} + +#define BITS_COPY32_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + ((a)->data[0] = (bits)); \ +} + + #define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7))) #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) #define BIT_GET(a, bit) (((a).data[(bit) >> 3] >> ((bit) & 7)) & 1) diff --git a/menu/menu_event.c b/menu/menu_event.c index 6af08b3e5a..a492aca726 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -165,7 +165,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) ok_old = ok_current; - if (RARCH_INPUT_STATE_ANY_SET_PTR(p_input)) + if (BITS_ANY_SET_PTR(p_input)) { if (!first_held) { diff --git a/retroarch.c b/retroarch.c index f9d7b6aae9..d7a2d3170a 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2397,7 +2397,7 @@ static enum runloop_state runloop_check_state( if (input_driver_flushing_input) { input_driver_flushing_input = false; - if (RARCH_INPUT_STATE_ANY_SET(current_input)) + if (BITS_ANY_SET(current_input)) { BIT128_CLEAR_ALL(current_input); if (runloop_paused) @@ -2537,12 +2537,10 @@ static enum runloop_state runloop_check_state( retro_ctx.poll_cb(); { - retro_bits_t trigger_input; enum menu_action action; - bool focused; - - trigger_input = current_input; - RARCH_INPUT_STATE_CLEAR_BITS(trigger_input, old_input); + bool focused = false; + retro_bits_t trigger_input = current_input; + BITS_CLEAR_BITS(trigger_input, old_input); action = (enum menu_action)menu_event(¤t_input, &trigger_input); focused = pause_nonactive ? is_focused : true; From f0c143766e38fb49d8871125bbfa147b7dcc3f5b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 12:07:35 +0100 Subject: [PATCH 075/698] Change to 256bit macros --- audio/drivers/xaudio.h | 11 +-- input/connect/connect_nesusb.c | 2 +- input/connect/connect_ps2adapter.c | 2 +- input/connect/connect_ps3.c | 4 +- input/connect/connect_ps4.c | 36 ++++----- input/connect/connect_psxadapter.c | 2 +- input/connect/connect_snesusb.c | 2 +- input/connect/connect_wiiugca.c | 2 +- input/connect/connect_wiiupro.c | 36 ++++----- input/connect/joypad_connection.c | 4 +- input/drivers/cocoa_input.c | 2 +- input/drivers/wiiu_input.c | 2 +- input/drivers/winraw_input.c | 3 +- input/drivers_hid/btstack_hid.c | 4 +- input/drivers_hid/iohidmanager_hid.c | 4 +- input/drivers_hid/libusb_hid.c | 11 ++- input/drivers_hid/null_hid.c | 2 +- input/drivers_hid/wiiusb_hid.c | 10 ++- input/drivers_joypad/ctr_joypad.c | 2 +- input/drivers_joypad/gx_joypad.c | 2 +- input/drivers_joypad/hid_joypad.c | 2 +- input/drivers_joypad/linuxraw_joypad.c | 2 +- input/drivers_joypad/null_joypad.c | 2 +- input/drivers_joypad/parport_joypad.c | 2 +- input/drivers_joypad/ps3_joypad.c | 2 +- input/drivers_joypad/psp_joypad.c | 2 +- input/drivers_joypad/udev_joypad.c | 2 +- input/drivers_joypad/wiiu_joypad.c | 2 +- input/drivers_joypad/xdk_joypad.c | 2 +- input/input_driver.c | 26 +++--- menu/menu_event.c | 48 +++++------ retroarch.c | 106 ++++++++++++------------- 32 files changed, 168 insertions(+), 173 deletions(-) diff --git a/audio/drivers/xaudio.h b/audio/drivers/xaudio.h index 41e21be09d..266f89a59c 100644 --- a/audio/drivers/xaudio.h +++ b/audio/drivers/xaudio.h @@ -324,16 +324,11 @@ STDAPI XAudio2Create(__deref_out IXAudio2** ppXAudio2, UINT32 Flags X2DEFAULT(0) #else static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_PROCESSOR proc) { - HRESULT hr; IXAudio2 *pXAudio2 = NULL; - - (void)flags; - (void)proc; - #ifdef __cplusplus - hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2); + HRESULT hr = CoCreateInstance(CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, IID_IXAudio2, (void**)&pXAudio2); #else - hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); + HRESULT hr = CoCreateInstance(&CLSID_XAudio2, NULL, CLSCTX_INPROC_SERVER, &IID_IXAudio2, (void**)&pXAudio2); #endif if (SUCCEEDED(hr)) @@ -342,9 +337,7 @@ static INLINE HRESULT XAudio2Create(IXAudio2 **ppXAudio2, UINT32 flags, XAUDIO2_ if (SUCCEEDED(hr)) *ppXAudio2 = pXAudio2; else - { IXAudio2_Release(pXAudio2); - } } return hr; } diff --git a/input/connect/connect_nesusb.c b/input/connect/connect_nesusb.c index 797f83e7ae..bf21fbb901 100644 --- a/input/connect/connect_nesusb.c +++ b/input/connect/connect_nesusb.c @@ -67,7 +67,7 @@ static void hidpad_nesusb_get_buttons(void *data, retro_bits_t* state) BITS_COPY16_PTR(state, device->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_nesusb_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps2adapter.c b/input/connect/connect_ps2adapter.c index c79aac8df3..87b174bd4e 100644 --- a/input/connect/connect_ps2adapter.c +++ b/input/connect/connect_ps2adapter.c @@ -67,7 +67,7 @@ static void hidpad_ps2adapter_get_buttons(void *data, retro_bits_t *state) BITS_COPY16_PTR(state, device->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_ps2adapter_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps3.c b/input/connect/connect_ps3.c index 6ef05f8e4e..7e96e5a7f4 100644 --- a/input/connect/connect_ps3.c +++ b/input/connect/connect_ps3.c @@ -115,10 +115,10 @@ static void hidpad_ps3_get_buttons(void *data, retro_bits_t *state) /*PS button?*/ if (device->buttons & 0x10000) - BIT128_SET_PTR(state, RARCH_MENU_TOGGLE); + BIT256_SET_PTR(state, RARCH_MENU_TOGGLE); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_ps3_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index 901e693d80..dcdd88a41e 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -194,42 +194,42 @@ static void hidpad_ps4_get_buttons(void *data, retro_bits_t* state) if (!device || !rpt) return; - BIT128_CLEAR_ALL_PTR( state ); + BIT256_CLEAR_ALL_PTR( state ); if (rpt->btn.r3) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R3 ); if (rpt->btn.l3) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L3 ); if (rpt->btn.options) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_START ); if ( rpt->btn.share) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_SELECT ); if ( rpt->btn.r2) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R2 ); if (rpt->btn.l2) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L2 ); if (rpt->btn.r1) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_R ); if (rpt->btn.l1) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_L ); if (rpt->btn.triangle) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_X ); if (rpt->btn.circle) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_A ); if (rpt->btn.cross) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_B ); if (rpt->btn.square) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_Y ); if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_LEFT))) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_LEFT ); if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_DOWN))) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_DOWN ); if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_RIGHT))) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_RIGHT ); if ((hidpad_ps4_check_dpad(rpt, RETRO_DEVICE_ID_JOYPAD_UP))) - BIT128_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); + BIT256_SET_PTR( state, RETRO_DEVICE_ID_JOYPAD_UP ); if (rpt->btn.ps) - BIT128_SET_PTR( state, RARCH_MENU_TOGGLE ); + BIT256_SET_PTR( state, RARCH_MENU_TOGGLE ); } static int16_t hidpad_ps4_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_psxadapter.c b/input/connect/connect_psxadapter.c index 03193fd606..b9d2e7f9ba 100644 --- a/input/connect/connect_psxadapter.c +++ b/input/connect/connect_psxadapter.c @@ -67,7 +67,7 @@ static void hidpad_psxadapter_get_buttons(void *data, retro_bits_t *state) BITS_COPY16_PTR(state, device->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_psxadapter_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_snesusb.c b/input/connect/connect_snesusb.c index 51570d82fa..62759b51fb 100644 --- a/input/connect/connect_snesusb.c +++ b/input/connect/connect_snesusb.c @@ -68,7 +68,7 @@ static void hidpad_snesusb_get_buttons(void *data, retro_bits_t *state) BITS_COPY16_PTR(state, device->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_snesusb_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_wiiugca.c b/input/connect/connect_wiiugca.c index cd0ea8b33e..5705a7acdf 100644 --- a/input/connect/connect_wiiugca.c +++ b/input/connect/connect_wiiugca.c @@ -71,7 +71,7 @@ static void hidpad_wiiugca_get_buttons(void *data, retro_bits_t *state) BITS_COPY16_PTR(state, device->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hidpad_wiiugca_get_axis(void *data, unsigned axis) diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index b7e148a010..6356fc94fa 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -127,42 +127,42 @@ static void hidpad_wiiupro_get_buttons(void *data, retro_bits_t *state) if (!device || !rpt) return; - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); if (rpt->btn.r3) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R3); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R3); if (rpt->btn.l3) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L3); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L3); if (rpt->btn.plus) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_START); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_START); if ( rpt->btn.minus) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_SELECT); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_SELECT); if ( rpt->btn.zr) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R2); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R2); if ( rpt->btn.zl) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L2); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L2); if ( rpt->btn.r) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_R); if ( rpt->btn.l) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_L); if ( rpt->btn.x) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_X); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_X); if ( rpt->btn.a) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_A); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_A); if ( rpt->btn.b) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_B); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_B); if ( rpt->btn.y) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_Y); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_Y); if ( rpt->btn.left) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_LEFT); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_LEFT); if ( rpt->btn.down) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_DOWN); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_DOWN); if ( rpt->btn.right) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_RIGHT); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_RIGHT); if ( rpt->btn.up) - BIT128_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_UP); + BIT256_SET_PTR(state, RETRO_DEVICE_ID_JOYPAD_UP); if ( rpt->btn.home) - BIT128_SET_PTR(state, RARCH_MENU_TOGGLE); + BIT256_SET_PTR(state, RARCH_MENU_TOGGLE); } static int16_t hidpad_wiiupro_get_axis(void *data, unsigned axis) diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 178d32fcd2..90cb9cf06b 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -176,11 +176,9 @@ void pad_connection_packet(joypad_connection_t *joyconn, uint32_t pad, void pad_connection_get_buttons(joypad_connection_t *joyconn, unsigned pad, retro_bits_t* state) { if (joyconn->iface) - { joyconn->iface->get_buttons(joyconn->data, state); - } else - BIT128_CLEAR_ALL_PTR( state ); + BIT256_CLEAR_ALL_PTR( state ); } int16_t pad_connection_get_axis(joypad_connection_t *joyconn, diff --git a/input/drivers/cocoa_input.c b/input/drivers/cocoa_input.c index 2ce55ddb38..f14932ab23 100644 --- a/input/drivers/cocoa_input.c +++ b/input/drivers/cocoa_input.c @@ -59,7 +59,7 @@ static int cocoa_input_find_any_button_ret(cocoa_input_data_t *apple, if (state) for (i = 0; i < 256; i++) - if (BIT128_GET_PTR(state,i)) + if (BIT256_GET_PTR(state,i)) return i; return -1; } diff --git a/input/drivers/wiiu_input.c b/input/drivers/wiiu_input.c index 99d8087e65..7bf5a752e0 100644 --- a/input/drivers/wiiu_input.c +++ b/input/drivers/wiiu_input.c @@ -108,7 +108,7 @@ static int16_t wiiu_pointer_device_state(wiiu_input_t* wiiu, unsigned id) { retro_bits_t state; wiiu->joypad->get_buttons(0, &state); - return BIT128_GET(state, VPAD_BUTTON_TOUCH) ? 1 : 0; + return BIT256_GET(state, VPAD_BUTTON_TOUCH) ? 1 : 0; } case RETRO_DEVICE_ID_POINTER_X: return wiiu->joypad->axis(0, 0xFFFF0004UL); diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index 31f86cadb5..fa6011291d 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -356,9 +356,8 @@ static bool winraw_keyboard_pressed(winraw_input_t *wr, unsigned key) static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key) { unsigned i; - bool result; winraw_mouse_t *mouse = NULL; - settings_t *settings = config_get_ptr(); + settings_t *settings = config_get_ptr(); if (port >= MAX_USERS) return false; diff --git a/input/drivers_hid/btstack_hid.c b/input/drivers_hid/btstack_hid.c index 2166a2d2a3..9946e1f6dc 100644 --- a/input/drivers_hid/btstack_hid.c +++ b/input/drivers_hid/btstack_hid.c @@ -1370,7 +1370,7 @@ static void btstack_hid_joypad_get_buttons(void *data, unsigned port, retro_bits if (hid) pad_connection_get_buttons(&hid->slots[port], port, state); else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey) @@ -1384,7 +1384,7 @@ static bool btstack_hid_joypad_button(void *data, unsigned port, uint16_t joykey /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (BIT128_GET(buttons, joykey) != 0); + return (BIT256_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_hid/iohidmanager_hid.c b/input/drivers_hid/iohidmanager_hid.c index 3d479fce40..8f4e0cb71b 100644 --- a/input/drivers_hid/iohidmanager_hid.c +++ b/input/drivers_hid/iohidmanager_hid.c @@ -114,7 +114,7 @@ static void iohidmanager_hid_joypad_get_buttons(void *data, unsigned port, retro if (hid) return pad_connection_get_buttons(&hid->slots[port], port, state); else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static bool iohidmanager_hid_joypad_button(void *data, @@ -150,7 +150,7 @@ static bool iohidmanager_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (BIT128_GET(buttons, joykey) != 0) + return (BIT256_GET(buttons, joykey) != 0) || ((hid->buttons[port] & (1 << joykey)) != 0); return false; diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index a653b6b9bc..f2fd6d0bca 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -447,9 +447,12 @@ static void libusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ { libusb_hid_t *hid = (libusb_hid_t*)data; if (hid) - return pad_connection_get_buttons(&hid->slots[port], port, state); - else - BIT128_CLEAR_ALL_PTR(state); + { + pad_connection_get_buttons(&hid->slots[port], port, state); + return; + } + + BIT256_CLEAR_ALL_PTR(state); } static bool libusb_hid_joypad_button(void *data, @@ -464,7 +467,7 @@ static bool libusb_hid_joypad_button(void *data, /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (BIT128_GET(buttons, joykey) != 0); + return (BIT256_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_hid/null_hid.c b/input/drivers_hid/null_hid.c index 74b61d051e..ce657d8b90 100644 --- a/input/drivers_hid/null_hid.c +++ b/input/drivers_hid/null_hid.c @@ -43,7 +43,7 @@ static void null_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_t (void)data; (void)port; - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static bool null_hid_joypad_button(void *data, unsigned port, uint16_t joykey) diff --git a/input/drivers_hid/wiiusb_hid.c b/input/drivers_hid/wiiusb_hid.c index b550915689..e50657c64d 100644 --- a/input/drivers_hid/wiiusb_hid.c +++ b/input/drivers_hid/wiiusb_hid.c @@ -482,9 +482,11 @@ static void wiiusb_hid_joypad_get_buttons(void *data, unsigned port, retro_bits_ { wiiusb_hid_t *hid = (wiiusb_hid_t*)data; if (hid) - return pad_connection_get_buttons(&hid->connections[port], port, state); - else - BIT128_CLEAR_ALL_PTR(state); + { + pad_connection_get_buttons(&hid->connections[port], port, state); + return; + } + BIT256_CLEAR_ALL_PTR(state); } static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) @@ -499,7 +501,7 @@ static bool wiiusb_hid_joypad_button(void *data, unsigned port, uint16_t joykey) /* Check the button. */ if ((port < MAX_USERS) && (joykey < 32)) - return (BIT128_GET(buttons, joykey) != 0); + return (BIT256_GET(buttons, joykey) != 0); return false; } diff --git a/input/drivers_joypad/ctr_joypad.c b/input/drivers_joypad/ctr_joypad.c index a98fce76fc..711b88493d 100644 --- a/input/drivers_joypad/ctr_joypad.c +++ b/input/drivers_joypad/ctr_joypad.c @@ -77,7 +77,7 @@ static void ctr_joypad_get_buttons(unsigned port_num, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t ctr_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/gx_joypad.c b/input/drivers_joypad/gx_joypad.c index bccc6f467b..392cb602a9 100644 --- a/input/drivers_joypad/gx_joypad.c +++ b/input/drivers_joypad/gx_joypad.c @@ -169,7 +169,7 @@ static void gx_joypad_get_buttons(unsigned port, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state[port] ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t gx_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/hid_joypad.c b/input/drivers_joypad/hid_joypad.c index fe0badd38a..203a272922 100644 --- a/input/drivers_joypad/hid_joypad.c +++ b/input/drivers_joypad/hid_joypad.c @@ -60,7 +60,7 @@ static void hid_joypad_get_buttons(unsigned port, retro_bits_t *state) if (generic_hid && generic_hid->get_buttons) generic_hid->get_buttons((void*)hid_driver_get_data(), port, state); else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t hid_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/linuxraw_joypad.c b/input/drivers_joypad/linuxraw_joypad.c index c43ea0b93a..4d852f406b 100644 --- a/input/drivers_joypad/linuxraw_joypad.c +++ b/input/drivers_joypad/linuxraw_joypad.c @@ -334,7 +334,7 @@ static void linuxraw_joypad_get_buttons(unsigned port, retro_bits_t *state) BITS_COPY16_PTR(state, pad->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t linuxraw_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/null_joypad.c b/input/drivers_joypad/null_joypad.c index f938e802e4..058d01d5b3 100644 --- a/input/drivers_joypad/null_joypad.c +++ b/input/drivers_joypad/null_joypad.c @@ -39,7 +39,7 @@ static bool null_joypad_button(unsigned port_num, uint16_t joykey) static void null_joypad_get_buttons(unsigned port_num, retro_bits_t *state) { - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t null_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/parport_joypad.c b/input/drivers_joypad/parport_joypad.c index f24c2706a5..e236a36fc5 100644 --- a/input/drivers_joypad/parport_joypad.c +++ b/input/drivers_joypad/parport_joypad.c @@ -348,7 +348,7 @@ static void parport_joypad_get_buttons(unsigned port, retro_bits_t *state) BITS_COPY16_PTR(state, pad->buttons); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t parport_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/ps3_joypad.c b/input/drivers_joypad/ps3_joypad.c index f37822642d..a85a23fcf9 100644 --- a/input/drivers_joypad/ps3_joypad.c +++ b/input/drivers_joypad/ps3_joypad.c @@ -75,7 +75,7 @@ static void ps3_joypad_get_buttons(unsigned port_num, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state[port_num] ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t ps3_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/psp_joypad.c b/input/drivers_joypad/psp_joypad.c index 60ca2daff3..d9cb4dd65a 100644 --- a/input/drivers_joypad/psp_joypad.c +++ b/input/drivers_joypad/psp_joypad.c @@ -131,7 +131,7 @@ static void psp_joypad_get_buttons(unsigned port_num, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state[port_num] ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t psp_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 283e1bd38b..20ee084ec8 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -612,7 +612,7 @@ static void udev_joypad_get_buttons(unsigned port, retro_bits_t *state) BITS_COPY16_PTR( state, pad->buttons ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t udev_joypad_axis(unsigned port, uint32_t joyaxis) diff --git a/input/drivers_joypad/wiiu_joypad.c b/input/drivers_joypad/wiiu_joypad.c index 8a3d8189db..b7c46b995f 100644 --- a/input/drivers_joypad/wiiu_joypad.c +++ b/input/drivers_joypad/wiiu_joypad.c @@ -142,7 +142,7 @@ static void wiiu_joypad_get_buttons(unsigned port_num, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state[port_num] ); } else - BIT128_CLAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t wiiu_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/drivers_joypad/xdk_joypad.c b/input/drivers_joypad/xdk_joypad.c index 6553346160..517ddaa972 100644 --- a/input/drivers_joypad/xdk_joypad.c +++ b/input/drivers_joypad/xdk_joypad.c @@ -83,7 +83,7 @@ static void xdk_joypad_get_buttons(unsigned port_num, retro_bits_t *state) BITS_COPY16_PTR( state, pad_state[port_num] ); } else - BIT128_CLEAR_ALL_PTR(state); + BIT256_CLEAR_ALL_PTR(state); } static int16_t xdk_joypad_axis(unsigned port_num, uint32_t joyaxis) diff --git a/input/input_driver.c b/input/input_driver.c index ca491bea9f..d17fb5fc61 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -810,7 +810,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) joypad_info.joy_idx = 0; joypad_info.auto_binds = NULL; - BIT128_CLEAR_ALL_PTR(p_new_state); + BIT256_CLEAR_ALL_PTR(p_new_state); input_driver_block_libretro_input = false; input_driver_block_hotkey = false; @@ -912,7 +912,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (pressed) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } } @@ -922,7 +922,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) { if (current_input->meta_key_pressed(current_input_data, i)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } } @@ -930,7 +930,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) #ifdef HAVE_OVERLAY if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } #endif @@ -945,7 +945,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (command_get(&handle)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } } @@ -954,7 +954,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) #ifdef HAVE_NETWORKGAMEPAD if (input_driver_remote && input_remote_key_pressed(i, 0)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } #endif @@ -1010,7 +1010,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (current_input->input_state(current_input_data, joypad_info, binds, 0, RETRO_DEVICE_KEYBOARD, 0, ids[i][0])) - BIT128_SET_PTR(p_new_state, ids[i][1]); + BIT256_SET_PTR(p_new_state, ids[i][1]); } } } @@ -1037,7 +1037,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) const struct retro_keybind *enable_hotkey = &input_config_binds[0][RARCH_ENABLE_HOTKEY]; bool game_focus_toggle_valid = false; - BIT128_CLEAR_ALL_PTR(p_new_state); + BIT256_CLEAR_ALL_PTR(p_new_state); joypad_info.joy_idx = settings->uints.input_joypad_map[0]; joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; @@ -1083,7 +1083,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) 0, RETRO_DEVICE_JOYPAD, 0, i) ) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } @@ -1091,7 +1091,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) current_input->meta_key_pressed(current_input_data, i) ) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } @@ -1099,7 +1099,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } #endif @@ -1114,7 +1114,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (command_get(&handle)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } } @@ -1124,7 +1124,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) if (input_driver_remote && input_remote_key_pressed(i, 0)) { - BIT128_SET_PTR(p_new_state, i); + BIT256_SET_PTR(p_new_state, i); continue; } #endif diff --git a/menu/menu_event.c b/menu/menu_event.c index a492aca726..87449d3ff6 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -160,7 +160,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) unsigned menu_cancel_btn = (!input_swap_override && settings->bools.input_menu_swap_ok_cancel_buttons) ? RETRO_DEVICE_ID_JOYPAD_A : RETRO_DEVICE_ID_JOYPAD_B; - unsigned ok_current = BIT128_GET_PTR(p_input, menu_ok_btn ); + unsigned ok_current = BIT256_GET_PTR(p_input, menu_ok_btn ); unsigned ok_trigger = ok_current & ~ok_old; ok_old = ok_current; @@ -221,31 +221,31 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) { menu_event_osk_iterate(); - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) { if (menu_event_get_osk_ptr() < 33) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + OSK_CHARS_PER_LINE); } - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) { if (menu_event_get_osk_ptr() >= OSK_CHARS_PER_LINE) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - OSK_CHARS_PER_LINE); } - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) { if (menu_event_get_osk_ptr() < 43) menu_event_set_osk_ptr(menu_event_get_osk_ptr() + 1); } - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) { if (menu_event_get_osk_ptr() >= 1) menu_event_set_osk_ptr(menu_event_get_osk_ptr() - 1); } - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) { if (menu_event_get_osk_idx() > OSK_TYPE_UNKNOWN + 1) menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() - 1)); @@ -253,7 +253,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_LAST - 1)); } - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) { if (menu_event_get_osk_idx() < OSK_TYPE_LAST - 1) menu_event_set_osk_idx((enum osk_type)(menu_event_get_osk_idx() + 1)); @@ -261,50 +261,50 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_set_osk_idx((enum osk_type)(OSK_TYPE_UNKNOWN + 1)); } - if (BIT128_GET_PTR(p_trigger_input, menu_ok_btn)) + if (BIT256_GET_PTR(p_trigger_input, menu_ok_btn)) { if (menu_event_get_osk_ptr() >= 0) menu_event_osk_append(menu_event_get_osk_ptr()); } - if (BIT128_GET_PTR(p_trigger_input, menu_cancel_btn)) + if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn)) { input_keyboard_event(true, '\x7f', '\x7f', 0, RETRO_DEVICE_KEYBOARD); } /* send return key to close keyboard input window */ - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) input_keyboard_event(true, '\n', '\n', 0, RETRO_DEVICE_KEYBOARD); - BIT128_CLEAR_ALL_PTR(p_trigger_input); + BIT256_CLEAR_ALL_PTR(p_trigger_input); } else { - if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) + if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_UP)) ret = MENU_ACTION_UP; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) ret = MENU_ACTION_DOWN; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_LEFT)) ret = MENU_ACTION_LEFT; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_RIGHT)) ret = MENU_ACTION_RIGHT; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_L)) ret = MENU_ACTION_SCROLL_UP; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_R)) ret = MENU_ACTION_SCROLL_DOWN; else if (ok_trigger) ret = MENU_ACTION_OK; - else if (BIT128_GET_PTR(p_trigger_input, menu_cancel_btn)) + else if (BIT256_GET_PTR(p_trigger_input, menu_cancel_btn)) ret = MENU_ACTION_CANCEL; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_X)) ret = MENU_ACTION_SEARCH; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_Y)) ret = MENU_ACTION_SCAN; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_START)) ret = MENU_ACTION_START; - else if (BIT128_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + else if (BIT256_GET_PTR(p_trigger_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) ret = MENU_ACTION_INFO; - else if (BIT128_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE)) + else if (BIT256_GET_PTR(p_trigger_input, RARCH_MENU_TOGGLE)) ret = MENU_ACTION_TOGGLE; } @@ -314,7 +314,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) menu_event_kb_set_internal(RETROK_F11, 0); } - if (BIT128_GET_PTR(p_trigger_input, RARCH_QUIT_KEY)) + if (BIT256_GET_PTR(p_trigger_input, RARCH_QUIT_KEY)) return MENU_ACTION_QUIT; mouse_enabled = settings->bools.menu_mouse_enable; diff --git a/retroarch.c b/retroarch.c index d7a2d3170a..0de71056dc 100644 --- a/retroarch.c +++ b/retroarch.c @@ -1931,7 +1931,7 @@ bool retroarch_override_setting_is_set(enum rarch_override_setting enum_idx, voi if (val) { unsigned bit = *val; - return BIT128_GET(has_set_libretro_device, bit); + return BIT256_GET(has_set_libretro_device, bit); } } break; @@ -1980,7 +1980,7 @@ void retroarch_override_setting_set(enum rarch_override_setting enum_idx, void * if (val) { unsigned bit = *val; - BIT128_SET(has_set_libretro_device, bit); + BIT256_SET(has_set_libretro_device, bit); } } break; @@ -2039,7 +2039,7 @@ void retroarch_override_setting_unset(enum rarch_override_setting enum_idx, void if (val) { unsigned bit = *val; - BIT128_CLEAR(has_set_libretro_device, bit); + BIT256_CLEAR(has_set_libretro_device, bit); } } break; @@ -2315,35 +2315,35 @@ static bool input_driver_toggle_button_combo( switch (mode) { case INPUT_TOGGLE_DOWN_Y_L_R: - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_DOWN)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_Y)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_Y)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) return false; break; case INPUT_TOGGLE_L3_R3: - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L3)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L3)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R3)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R3)) return false; break; case INPUT_TOGGLE_L1_R1_START_SELECT: - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_L)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_R)) return false; break; case INPUT_TOGGLE_START_SELECT: - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_START)) return false; - if (!BIT128_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) + if (!BIT256_GET_PTR(p_input, RETRO_DEVICE_ID_JOYPAD_SELECT)) return false; break; default: @@ -2391,7 +2391,7 @@ static enum runloop_state runloop_check_state( ((settings->uints.input_menu_toggle_gamepad_combo != INPUT_TOGGLE_NONE) && input_driver_toggle_button_combo( settings->uints.input_menu_toggle_gamepad_combo, &last_input))) - BIT128_SET(current_input, RARCH_MENU_TOGGLE); + BIT256_SET(current_input, RARCH_MENU_TOGGLE); #endif if (input_driver_flushing_input) @@ -2399,9 +2399,9 @@ static enum runloop_state runloop_check_state( input_driver_flushing_input = false; if (BITS_ANY_SET(current_input)) { - BIT128_CLEAR_ALL(current_input); + BIT256_CLEAR_ALL(current_input); if (runloop_paused) - BIT128_SET(current_input, RARCH_PAUSE_TOGGLE); + BIT256_SET(current_input, RARCH_PAUSE_TOGGLE); input_driver_flushing_input = true; } } @@ -2410,14 +2410,14 @@ static enum runloop_state runloop_check_state( #ifdef HAVE_MENU if (menu_driver_binding_state) - BIT128_CLEAR_ALL(current_input); + BIT256_CLEAR_ALL(current_input); #endif #ifdef HAVE_OVERLAY /* Check next overlay */ { static bool old_should_check_next_overlay = false; - bool should_check_next_overlay = BIT128_GET( + bool should_check_next_overlay = BIT256_GET( current_input, RARCH_OVERLAY_NEXT); if (should_check_next_overlay && !old_should_check_next_overlay) @@ -2429,7 +2429,7 @@ static enum runloop_state runloop_check_state( /* Check fullscreen toggle */ { - bool fs_toggle_pressed = BIT128_GET( + bool fs_toggle_pressed = BIT256_GET( current_input, RARCH_FULLSCREEN_TOGGLE_KEY); fs_toggle_triggered = fs_toggle_pressed && !old_fs_toggle_pressed; @@ -2452,7 +2452,7 @@ static enum runloop_state runloop_check_state( /* Check mouse grab toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_GRAB_MOUSE_TOGGLE); if (pressed && !old_pressed) @@ -2487,7 +2487,7 @@ static enum runloop_state runloop_check_state( /* Check quit key */ { static bool old_quit_key = false; - bool quit_key = BIT128_GET( + bool quit_key = BIT256_GET( current_input, RARCH_QUIT_KEY); bool trig_quit_key = quit_key && !old_quit_key; @@ -2579,7 +2579,7 @@ static enum runloop_state runloop_check_state( /* Check game focus toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_GAME_FOCUS_TOGGLE); if (pressed && !old_pressed) @@ -2592,7 +2592,7 @@ static enum runloop_state runloop_check_state( /* Check menu toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_MENU_TOGGLE); if (menu_event_kb_is_set(RETROK_F1) == 1) @@ -2642,7 +2642,7 @@ static enum runloop_state runloop_check_state( /* Check screenshot toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_SCREENSHOT); if (pressed && old_pressed) @@ -2654,7 +2654,7 @@ static enum runloop_state runloop_check_state( /* Check audio mute toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_MUTE); if (pressed && !old_pressed) @@ -2666,7 +2666,7 @@ static enum runloop_state runloop_check_state( /* Check OSK toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET(current_input, RARCH_OSK); + bool pressed = BIT256_GET(current_input, RARCH_OSK); if (pressed && !old_pressed) { @@ -2682,9 +2682,9 @@ static enum runloop_state runloop_check_state( old_pressed = pressed; } - if (BIT128_GET(current_input, RARCH_VOLUME_UP)) + if (BIT256_GET(current_input, RARCH_VOLUME_UP)) command_event(CMD_EVENT_VOLUME_UP, NULL); - else if (BIT128_GET(current_input, RARCH_VOLUME_DOWN)) + else if (BIT256_GET(current_input, RARCH_VOLUME_DOWN)) command_event(CMD_EVENT_VOLUME_DOWN, NULL); #ifdef HAVE_NETWORKING @@ -2692,9 +2692,9 @@ static enum runloop_state runloop_check_state( { static bool old_netplay_flip = false; static bool old_netplay_watch = false; - bool netplay_flip = BIT128_GET( + bool netplay_flip = BIT256_GET( current_input, RARCH_NETPLAY_FLIP); - bool netplay_watch = BIT128_GET( + bool netplay_watch = BIT256_GET( current_input, RARCH_NETPLAY_GAME_WATCH); if (netplay_flip && !old_netplay_flip) @@ -2713,9 +2713,9 @@ static enum runloop_state runloop_check_state( static bool old_frameadvance = false; static bool old_pause_pressed = false; bool check_is_oneshot = true; - bool frameadvance_pressed = BIT128_GET( + bool frameadvance_pressed = BIT256_GET( current_input, RARCH_FRAMEADVANCE); - bool pause_pressed = BIT128_GET( + bool pause_pressed = BIT256_GET( current_input, RARCH_PAUSE_TOGGLE); bool trig_frameadvance = frameadvance_pressed && !old_frameadvance; @@ -2739,7 +2739,7 @@ static enum runloop_state runloop_check_state( if (runloop_paused) { check_is_oneshot = trig_frameadvance || - BIT128_GET(current_input, RARCH_REWIND); + BIT256_GET(current_input, RARCH_REWIND); if (fs_toggle_triggered) { @@ -2764,9 +2764,9 @@ static enum runloop_state runloop_check_state( { static bool old_button_state = false; static bool old_hold_button_state = false; - bool new_button_state = BIT128_GET( + bool new_button_state = BIT256_GET( current_input, RARCH_FAST_FORWARD_KEY); - bool new_hold_button_state = BIT128_GET( + bool new_hold_button_state = BIT256_GET( current_input, RARCH_FAST_FORWARD_HOLD_KEY); if (new_button_state && !old_button_state) @@ -2807,9 +2807,9 @@ static enum runloop_state runloop_check_state( { static bool old_should_slot_increase = false; static bool old_should_slot_decrease = false; - bool should_slot_increase = BIT128_GET( + bool should_slot_increase = BIT256_GET( current_input, RARCH_STATE_SLOT_PLUS); - bool should_slot_decrease = BIT128_GET( + bool should_slot_decrease = BIT256_GET( current_input, RARCH_STATE_SLOT_MINUS); /* Checks if the state increase/decrease keys have been pressed @@ -2860,9 +2860,9 @@ static enum runloop_state runloop_check_state( { static bool old_should_savestate = false; static bool old_should_loadstate = false; - bool should_savestate = BIT128_GET( + bool should_savestate = BIT256_GET( current_input, RARCH_SAVE_STATE_KEY); - bool should_loadstate = BIT128_GET( + bool should_loadstate = BIT256_GET( current_input, RARCH_LOAD_STATE_KEY); if (should_savestate && !old_should_savestate) @@ -2883,14 +2883,14 @@ static enum runloop_state runloop_check_state( s[0] = '\0'; - if (state_manager_check_rewind(BIT128_GET(current_input, RARCH_REWIND), + if (state_manager_check_rewind(BIT256_GET(current_input, RARCH_REWIND), settings->uints.rewind_granularity, runloop_paused, s, sizeof(s), &t)) runloop_msg_queue_push(s, 0, t, true); } /* Checks if slowmotion toggle/hold was being pressed and/or held. */ { - runloop_slowmotion = BIT128_GET(current_input, RARCH_SLOWMOTION); + runloop_slowmotion = BIT256_GET(current_input, RARCH_SLOWMOTION); if (runloop_slowmotion) { @@ -2912,7 +2912,7 @@ static enum runloop_state runloop_check_state( /* Check movie record toggle */ { static bool old_pressed = false; - bool pressed = BIT128_GET( + bool pressed = BIT256_GET( current_input, RARCH_MOVIE_RECORD_TOGGLE); if (pressed && !old_pressed) @@ -2925,9 +2925,9 @@ static enum runloop_state runloop_check_state( { static bool old_shader_next = false; static bool old_shader_prev = false; - bool shader_next = BIT128_GET( + bool shader_next = BIT256_GET( current_input, RARCH_SHADER_NEXT); - bool shader_prev = BIT128_GET( + bool shader_prev = BIT256_GET( current_input, RARCH_SHADER_PREV); bool trig_shader_next = shader_next && !old_shader_next; bool trig_shader_prev = shader_prev && !old_shader_prev; @@ -2944,11 +2944,11 @@ static enum runloop_state runloop_check_state( static bool old_disk_eject = false; static bool old_disk_next = false; static bool old_disk_prev = false; - bool disk_eject = BIT128_GET( + bool disk_eject = BIT256_GET( current_input, RARCH_DISK_EJECT_TOGGLE); - bool disk_next = BIT128_GET( + bool disk_next = BIT256_GET( current_input, RARCH_DISK_NEXT); - bool disk_prev = BIT128_GET( + bool disk_prev = BIT256_GET( current_input, RARCH_DISK_PREV); if (disk_eject && !old_disk_eject) @@ -2966,7 +2966,7 @@ static enum runloop_state runloop_check_state( /* Check reset */ { static bool old_state = false; - bool new_state = BIT128_GET( + bool new_state = BIT256_GET( current_input, RARCH_RESET); if (new_state && !old_state) @@ -2980,11 +2980,11 @@ static enum runloop_state runloop_check_state( static bool old_cheat_index_plus = false; static bool old_cheat_index_minus = false; static bool old_cheat_index_toggle = false; - bool cheat_index_plus = BIT128_GET( + bool cheat_index_plus = BIT256_GET( current_input, RARCH_CHEAT_INDEX_PLUS); - bool cheat_index_minus = BIT128_GET( + bool cheat_index_minus = BIT256_GET( current_input, RARCH_CHEAT_INDEX_MINUS); - bool cheat_index_toggle = BIT128_GET( + bool cheat_index_toggle = BIT256_GET( current_input, RARCH_CHEAT_TOGGLE); if (cheat_index_plus && !old_cheat_index_plus) From 53ce29ca315b4e3ec8ef074795ec239edcdc39dc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 12:49:59 +0100 Subject: [PATCH 076/698] Cleanups --- libretro-common/include/retro_miscellaneous.h | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index c69afed90b..30bb2de69d 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -58,33 +58,38 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -#define BITS_ANY_SET(a) ( ((a).data[0])||((a).data[1])||((a).data[2])||((a).data[3])|| \ - ((a).data[4])||((a).data[5])||((a).data[6])||((a).data[7]) ) -#define BITS_ANY_SET_PTR(a) ( ((a)->data[0])||((a)->data[1])||((a)->data[2])||((a)->data[3])|| \ - ((a)->data[4])||((a)->data[5])||((a)->data[6])||((a)->data[7]) ) +#define BITS_GET_ELEM(a, i) ((a).data[i]) +#define BITS_GET_ELEM_PTR(a, i) ((a)->data[i]) + +#define BITS_ANY_SET(a) ( BITS_GET_ELEM(a, 0)|| BITS_GET_ELEM(a, 1) || BITS_GET_ELEM(a, 2) || BITS_GET_ELEM(a, 3) || \ + BITS_GET_ELEM(a, 4) || BITS_GET_ELEM(a, 5) || BITS_GET_ELEM(a, 6) || BITS_GET_ELEM(a, 7) ) +#define BITS_ANY_SET_PTR(a) ( BITS_GET_ELEM_PTR(a, 0)|| BITS_GET_ELEM_PTR(a, 1) || BITS_GET_ELEM_PTR(a, 2) || BITS_GET_ELEM_PTR(a, 3) || \ + BITS_GET_ELEM_PTR(a, 4) || BITS_GET_ELEM_PTR(a, 5) || BITS_GET_ELEM_PTR(a, 6) || BITS_GET_ELEM_PTR(a, 7) ) + #define BITS_CLEAR_BITS(a,b) \ - ((a).data[0])&=(~((b).data[0])); \ - ((a).data[1])&=(~((b).data[1])); \ - ((a).data[2])&=(~((b).data[2])); \ - ((a).data[3])&=(~((b).data[3])); \ - ((a).data[4])&=(~((b).data[4])); \ - ((a).data[5])&=(~((b).data[5])); \ - ((a).data[6])&=(~((b).data[6])); \ - ((a).data[7])&=(~((b).data[7])); +{ \ + BITS_GET_ELEM(a, 0) &= (~BITS_GET_ELEM(b, 0)); \ + BITS_GET_ELEM(a, 1) &= (~BITS_GET_ELEM(b, 1)); \ + BITS_GET_ELEM(a, 2) &= (~BITS_GET_ELEM(b, 2)); \ + BITS_GET_ELEM(a, 3) &= (~BITS_GET_ELEM(b, 3)); \ + BITS_GET_ELEM(a, 4) &= (~BITS_GET_ELEM(b, 4)); \ + BITS_GET_ELEM(a, 5) &= (~BITS_GET_ELEM(b, 5)); \ + BITS_GET_ELEM(a, 6) &= (~BITS_GET_ELEM(b, 6)); \ + BITS_GET_ELEM(a, 7) &= (~BITS_GET_ELEM(b, 7)); \ +} #define BITS_COPY16_PTR(a,bits) \ { \ BIT128_CLEAR_ALL_PTR(a); \ - ((a)->data[0] = (bits) & 0xffff); \ + BITS_GET_ELEM_PTR(a, 0) = (bits) & 0xffff; \ } #define BITS_COPY32_PTR(a,bits) \ { \ BIT128_CLEAR_ALL_PTR(a); \ - ((a)->data[0] = (bits)); \ + BITS_GET_ELEM_PTR(a, 0) = (bits); \ } - #define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7))) #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) #define BIT_GET(a, bit) (((a).data[(bit) >> 3] >> ((bit) & 7)) & 1) From 332aee5b0f777a22e404654a3d4ecdbfcc53fdb7 Mon Sep 17 00:00:00 2001 From: Alcaro Date: Tue, 5 Dec 2017 13:03:34 +0100 Subject: [PATCH 077/698] Dehardcode some sizes (#5856) --- libretro-common/include/retro_miscellaneous.h | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 30bb2de69d..60da013743 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -24,6 +24,7 @@ #define __RARCH_MISCELLANEOUS_H #include +#include #if defined(_WIN32) && !defined(_XBOX) #ifndef WIN32_LEAN_AND_MEAN @@ -61,23 +62,30 @@ #define BITS_GET_ELEM(a, i) ((a).data[i]) #define BITS_GET_ELEM_PTR(a, i) ((a)->data[i]) -#define BITS_ANY_SET(a) ( BITS_GET_ELEM(a, 0)|| BITS_GET_ELEM(a, 1) || BITS_GET_ELEM(a, 2) || BITS_GET_ELEM(a, 3) || \ - BITS_GET_ELEM(a, 4) || BITS_GET_ELEM(a, 5) || BITS_GET_ELEM(a, 6) || BITS_GET_ELEM(a, 7) ) -#define BITS_ANY_SET_PTR(a) ( BITS_GET_ELEM_PTR(a, 0)|| BITS_GET_ELEM_PTR(a, 1) || BITS_GET_ELEM_PTR(a, 2) || BITS_GET_ELEM_PTR(a, 3) || \ - BITS_GET_ELEM_PTR(a, 4) || BITS_GET_ELEM_PTR(a, 5) || BITS_GET_ELEM_PTR(a, 6) || BITS_GET_ELEM_PTR(a, 7) ) - -#define BITS_CLEAR_BITS(a,b) \ -{ \ - BITS_GET_ELEM(a, 0) &= (~BITS_GET_ELEM(b, 0)); \ - BITS_GET_ELEM(a, 1) &= (~BITS_GET_ELEM(b, 1)); \ - BITS_GET_ELEM(a, 2) &= (~BITS_GET_ELEM(b, 2)); \ - BITS_GET_ELEM(a, 3) &= (~BITS_GET_ELEM(b, 3)); \ - BITS_GET_ELEM(a, 4) &= (~BITS_GET_ELEM(b, 4)); \ - BITS_GET_ELEM(a, 5) &= (~BITS_GET_ELEM(b, 5)); \ - BITS_GET_ELEM(a, 6) &= (~BITS_GET_ELEM(b, 6)); \ - BITS_GET_ELEM(a, 7) &= (~BITS_GET_ELEM(b, 7)); \ +static inline bool bits_any_set(uint32_t* ptr, uint32_t count) +{ + uint32_t i; + for (i=0;i Date: Tue, 5 Dec 2017 13:15:15 +0100 Subject: [PATCH 078/698] Cleanups --- libretro-common/include/retro_miscellaneous.h | 69 +++++++++---------- menu/menu_event.c | 2 +- retroarch.c | 6 +- 3 files changed, 37 insertions(+), 40 deletions(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 60da013743..b51cc15e60 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -25,6 +25,7 @@ #include #include +#include #if defined(_WIN32) && !defined(_XBOX) #ifndef WIN32_LEAN_AND_MEAN @@ -41,6 +42,24 @@ #include #endif +static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count) +{ + uint32_t i; + for (i = 0; i < count;i++) + a[i] &= b[i]; +} + +static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) +{ + uint32_t i; + for (i = 0; i < count; i++) + { + if (ptr[i] != 0) + return true; + } + return false; +} + #ifndef PATH_MAX_LENGTH #if defined(_XBOX1) || defined(_3DS) || defined(PSP) || defined(GEKKO)|| defined(WIIU) #define PATH_MAX_LENGTH 512 @@ -57,47 +76,11 @@ #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #define BITS_GET_ELEM(a, i) ((a).data[i]) #define BITS_GET_ELEM_PTR(a, i) ((a)->data[i]) -static inline bool bits_any_set(uint32_t* ptr, uint32_t count) -{ - uint32_t i; - for (i=0;i> 3] |= (1 << ((bit) & 7))) #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) #define BIT_GET(a, bit) (((a).data[(bit) >> 3] >> ((bit) & 7)) & 1) @@ -137,6 +120,18 @@ static inline void bits_clear_bits(uint32_t* a, uint32_t* b, uint32_t count) #define BIT256_GET_PTR(a, bit) BIT256_GET(*a, bit) #define BIT256_CLEAR_ALL_PTR(a) BIT256_CLEAR_ALL(*a) +#define BITS_COPY16_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + BITS_GET_ELEM_PTR(a, 0) = (bits) & 0xffff; \ +} + +#define BITS_COPY32_PTR(a,bits) \ +{ \ + BIT128_CLEAR_ALL_PTR(a); \ + BITS_GET_ELEM_PTR(a, 0) = (bits); \ +} + /* Helper macros and struct to keep track of many booleans. */ /* This struct has 256 bits. */ typedef struct diff --git a/menu/menu_event.c b/menu/menu_event.c index 87449d3ff6..9c2c8eaecc 100644 --- a/menu/menu_event.c +++ b/menu/menu_event.c @@ -165,7 +165,7 @@ unsigned menu_event(retro_bits_t* p_input, retro_bits_t* p_trigger_input) ok_old = ok_current; - if (BITS_ANY_SET_PTR(p_input)) + if (bits_any_set(p_input->data, ARRAY_SIZE(p_input->data))) { if (!first_held) { diff --git a/retroarch.c b/retroarch.c index 0de71056dc..2545b79424 100644 --- a/retroarch.c +++ b/retroarch.c @@ -2397,7 +2397,7 @@ static enum runloop_state runloop_check_state( if (input_driver_flushing_input) { input_driver_flushing_input = false; - if (BITS_ANY_SET(current_input)) + if (bits_any_set(current_input.data, ARRAY_SIZE(current_input.data))) { BIT256_CLEAR_ALL(current_input); if (runloop_paused) @@ -2540,7 +2540,9 @@ static enum runloop_state runloop_check_state( enum menu_action action; bool focused = false; retro_bits_t trigger_input = current_input; - BITS_CLEAR_BITS(trigger_input, old_input); + + bits_clear_bits(trigger_input.data, old_input.data, + ARRAY_SIZE(trigger_input.data)); action = (enum menu_action)menu_event(¤t_input, &trigger_input); focused = pause_nonactive ? is_focused : true; From b432fb4668bd8cbf68d12a6b90d86232ad6249d4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 13:21:29 +0100 Subject: [PATCH 079/698] Bugfix --- libretro-common/include/retro_miscellaneous.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index b51cc15e60..010b04f19c 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -46,7 +46,7 @@ static INLINE void bits_clear_bits(uint32_t *a, uint32_t *b, uint32_t count) { uint32_t i; for (i = 0; i < count;i++) - a[i] &= b[i]; + a[i] &= ~b[i]; } static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) From fafc96d3777ac7102d1bafd39777c8884d47f677 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 13:31:51 +0100 Subject: [PATCH 080/698] Cleanups --- gfx/drivers_renderchain/gl2_renderchain.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index ebdb9709b0..1b246ce143 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -1262,7 +1262,9 @@ static void gl2_renderchain_copy_frame( const void *frame, unsigned width, unsigned height, unsigned pitch) { - gl_t *gl = (gl_t*)data; + gl_t *gl = (gl_t*)data; + gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + #if defined(HAVE_PSGL) { unsigned h; @@ -1281,7 +1283,6 @@ static void gl2_renderchain_copy_frame( } #elif defined(HAVE_OPENGLES) #if defined(HAVE_EGL) - gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; if (chain->egl_images) { gfx_ctx_image_t img_info; From df8a2274dfe8dce3a304cd99b6809f52fc57d639 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 13:47:23 +0100 Subject: [PATCH 081/698] Update CHANGES.md --- CHANGES.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index 17bb6ec41b..cabe1a0b9c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,21 @@ # 1.7.0 (future) -- CHEEVOS: Add badges +- CHEEVOS: Add badges for achievements, shows thumbnail images of achievements. +- COMMON: Add 'Automatically Load Content To Playlist' feature, enabled by default. +- COMMON: Fix slowmotion ratio always being reset back to 1. +- COMMON: Optimized NBIO implementations now for Apple, Windows, and Linux. Uses mmap for Linux/Windows/BSD if/when available. File I/O should now be much faster for loading images inside the menu. +- COMMON: Native Blissbox support now for latest firmware as of writing (2.0). Implementation through libusb and/or native Windows HID. +- COMMON: New lightgun API. +- FREEBSD: Support libusb HID input driver. +- HAIKU: Buildfix. +- LOCALIZATION: Update Italian translation. +- LOCALIZATION: Update Portuguese-Brazilian translation. +- LOCALIZATION: Update Russian translation. +- OSX/PPC: Fix the GL2 renderchain, had to use EXT versions of framebuffer/renderbuffer functions. +- SCANNER: Fix crash from Windows-incompatible format string. +- WIIU: Disabled the controller patcher for now since it was the source of many stability issues. +- WINDOWS: Raw input driver now supports new lightgun code. +- X11: Add RetroArch logo to window title bar. +- X11: Input driver now supports new lightgun code. # 1.6.9 - COMMON: Small memory leak. From c486fa08cabc977a46cb328a9b2b72bcd3dddffe Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 14:11:50 +0100 Subject: [PATCH 082/698] Cut down on code duplication --- menu/cbs/menu_cbs_deferred_push.c | 414 ++++++------------------------ 1 file changed, 80 insertions(+), 334 deletions(-) diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 538198987c..77ad57d4c4 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -58,90 +58,85 @@ static int deferred_push_dlist(menu_displaylist_info_t *info, enum menu_displayl return 0; } -static int deferred_push_core_information(menu_displaylist_info_t *info) +static int deferred_push_database_manager_list_deferred( + menu_displaylist_info_t *info) { - return deferred_push_dlist(info, DISPLAYLIST_CORE_INFO); + if (!string_is_empty(info->path_b)) + free(info->path_b); + if (!string_is_empty(info->path_c)) + free(info->path_c); + + info->path_b = strdup(info->path); + info->path_c = NULL; + + return deferred_push_dlist(info, DISPLAYLIST_DATABASE_QUERY); } -static int deferred_push_system_information(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SYSTEM_INFO); +#define generic_deferred_push(name, type) \ +static int (name)(menu_displaylist_info_t *info) \ +{ \ + return deferred_push_dlist(info, type); \ } -static int deferred_push_network_information(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_NETWORK_INFO); -} - -static int deferred_push_achievement_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ACHIEVEMENT_LIST); -} - -static int deferred_push_rdb_collection(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_PLAYLIST_COLLECTION); -} - -static int deferred_main_menu_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_MAIN_MENU); -} - -static int deferred_music_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_MUSIC_LIST); -} - -static int deferred_user_binds_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_USER_BINDS_LIST); -} - -static int deferred_push_accounts_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ACCOUNTS_LIST); -} - -static int deferred_push_driver_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DRIVER_SETTINGS_LIST); -} - -static int deferred_push_core_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORE_SETTINGS_LIST); -} - -static int deferred_push_video_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_VIDEO_SETTINGS_LIST); -} - -static int deferred_push_configuration_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST); -} - -static int deferred_push_saving_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SAVING_SETTINGS_LIST); -} - -static int deferred_push_logging_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_LOGGING_SETTINGS_LIST); -} - -static int deferred_push_frame_throttle_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST); -} - -static int deferred_push_rewind_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_REWIND_SETTINGS_LIST); -} +generic_deferred_push(deferred_push_video_shader_preset_parameters, DISPLAYLIST_SHADER_PARAMETERS_PRESET) +generic_deferred_push(deferred_push_video_shader_parameters, DISPLAYLIST_SHADER_PARAMETERS) +generic_deferred_push(deferred_push_settings, DISPLAYLIST_SETTINGS_ALL) +generic_deferred_push(deferred_push_shader_options, DISPLAYLIST_OPTIONS_SHADERS) +generic_deferred_push(deferred_push_options, DISPLAYLIST_OPTIONS) +generic_deferred_push(deferred_push_netplay, DISPLAYLIST_NETPLAY_ROOM_LIST) +generic_deferred_push(deferred_push_netplay_sublist, DISPLAYLIST_NETPLAY) +generic_deferred_push(deferred_push_content_settings, DISPLAYLIST_CONTENT_SETTINGS) +generic_deferred_push(deferred_push_add_content_list, DISPLAYLIST_ADD_CONTENT_LIST) +generic_deferred_push(deferred_push_history_list, DISPLAYLIST_HISTORY) +generic_deferred_push(deferred_push_database_manager_list, DISPLAYLIST_DATABASES) +generic_deferred_push(deferred_push_cursor_manager_list, DISPLAYLIST_DATABASE_CURSORS) +generic_deferred_push(deferred_push_content_collection_list, DISPLAYLIST_DATABASE_PLAYLISTS) +generic_deferred_push(deferred_push_configurations_list, DISPLAYLIST_CONFIGURATIONS_LIST) +generic_deferred_push(deferred_push_load_content_special, DISPLAYLIST_LOAD_CONTENT_LIST) +generic_deferred_push(deferred_push_load_content_list, DISPLAYLIST_LOAD_CONTENT_LIST) +generic_deferred_push(deferred_push_information_list, DISPLAYLIST_INFORMATION_LIST) +generic_deferred_push(deferred_archive_action_detect_core, DISPLAYLIST_ARCHIVE_ACTION_DETECT_CORE) +generic_deferred_push(deferred_archive_action, DISPLAYLIST_ARCHIVE_ACTION) +generic_deferred_push(deferred_push_management_options, DISPLAYLIST_OPTIONS_MANAGEMENT) +generic_deferred_push(deferred_push_core_counters, DISPLAYLIST_PERFCOUNTERS_CORE) +generic_deferred_push(deferred_push_frontend_counters, DISPLAYLIST_PERFCOUNTERS_FRONTEND) +generic_deferred_push(deferred_push_core_cheat_options, DISPLAYLIST_OPTIONS_CHEATS) +generic_deferred_push(deferred_push_core_input_remapping_options, DISPLAYLIST_OPTIONS_REMAPPINGS) +generic_deferred_push(deferred_push_core_options, DISPLAYLIST_CORE_OPTIONS) +generic_deferred_push(deferred_push_disk_options, DISPLAYLIST_OPTIONS_DISK) +generic_deferred_push(deferred_push_browse_url_list, DISPLAYLIST_BROWSE_URL_LIST) +generic_deferred_push(deferred_push_browse_url_start, DISPLAYLIST_BROWSE_URL_START) +generic_deferred_push(deferred_push_core_list, DISPLAYLIST_CORES) +generic_deferred_push(deferred_push_configurations, DISPLAYLIST_CONFIG_FILES) +generic_deferred_push(deferred_push_video_shader_preset, DISPLAYLIST_SHADER_PRESET) +generic_deferred_push(deferred_push_video_shader_pass, DISPLAYLIST_SHADER_PASS) +generic_deferred_push(deferred_push_video_filter, DISPLAYLIST_VIDEO_FILTERS) +generic_deferred_push(deferred_push_images, DISPLAYLIST_IMAGES) +generic_deferred_push(deferred_push_audio_dsp_plugin, DISPLAYLIST_AUDIO_FILTERS) +generic_deferred_push(deferred_push_cheat_file_load, DISPLAYLIST_CHEAT_FILES) +generic_deferred_push(deferred_push_remap_file_load, DISPLAYLIST_REMAP_FILES) +generic_deferred_push(deferred_push_record_configfile, DISPLAYLIST_RECORD_CONFIG_FILES) +generic_deferred_push(deferred_push_input_overlay, DISPLAYLIST_OVERLAYS) +generic_deferred_push(deferred_push_video_font_path, DISPLAYLIST_FONTS) +generic_deferred_push(deferred_push_xmb_font_path, DISPLAYLIST_FONTS) +generic_deferred_push(deferred_push_content_history_path, DISPLAYLIST_CONTENT_HISTORY) +generic_deferred_push(deferred_push_core_information, DISPLAYLIST_CORE_INFO) +generic_deferred_push(deferred_push_system_information, DISPLAYLIST_SYSTEM_INFO) +generic_deferred_push(deferred_push_network_information, DISPLAYLIST_NETWORK_INFO) +generic_deferred_push(deferred_push_achievement_list, DISPLAYLIST_ACHIEVEMENT_LIST) +generic_deferred_push(deferred_push_rdb_collection, DISPLAYLIST_PLAYLIST_COLLECTION) +generic_deferred_push(deferred_main_menu_list, DISPLAYLIST_MAIN_MENU) +generic_deferred_push(deferred_music_list, DISPLAYLIST_MUSIC_LIST) +generic_deferred_push(deferred_user_binds_list, DISPLAYLIST_USER_BINDS_LIST) +generic_deferred_push(deferred_push_accounts_list, DISPLAYLIST_ACCOUNTS_LIST) +generic_deferred_push(deferred_push_driver_settings_list, DISPLAYLIST_DRIVER_SETTINGS_LIST) +generic_deferred_push(deferred_push_core_settings_list, DISPLAYLIST_CORE_SETTINGS_LIST) +generic_deferred_push(deferred_push_video_settings_list, DISPLAYLIST_VIDEO_SETTINGS_LIST) +generic_deferred_push(deferred_push_configuration_settings_list, DISPLAYLIST_CONFIGURATION_SETTINGS_LIST) +generic_deferred_push(deferred_push_saving_settings_list, DISPLAYLIST_SAVING_SETTINGS_LIST) +generic_deferred_push(deferred_push_logging_settings_list, DISPLAYLIST_LOGGING_SETTINGS_LIST) +generic_deferred_push(deferred_push_frame_throttle_settings_list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST) +generic_deferred_push(deferred_push_rewind_settings_list, DISPLAYLIST_REWIND_SETTINGS_LIST) static int deferred_push_onscreen_display_settings_list(menu_displaylist_info_t *info) { @@ -279,165 +274,16 @@ static int deferred_push_core_collection_list_deferred( return deferred_push_dlist(info, DISPLAYLIST_CORES_COLLECTION_SUPPORTED); } -static int deferred_push_database_manager_list_deferred( - menu_displaylist_info_t *info) -{ - if (!string_is_empty(info->path_b)) - free(info->path_b); - if (!string_is_empty(info->path_c)) - free(info->path_c); - - info->path_b = strdup(info->path); - info->path_c = NULL; - - return deferred_push_dlist(info, DISPLAYLIST_DATABASE_QUERY); -} - -static int deferred_push_video_shader_preset_parameters( - menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SHADER_PARAMETERS_PRESET); -} - -static int deferred_push_video_shader_parameters( - menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SHADER_PARAMETERS); -} - -static int deferred_push_settings(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SETTINGS_ALL); -} - -static int deferred_push_shader_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS_SHADERS); -} - -static int deferred_push_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS); -} - -static int deferred_push_netplay(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_NETPLAY_ROOM_LIST); -} - -static int deferred_push_netplay_sublist(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_NETPLAY); -} - -static int deferred_push_content_settings(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CONTENT_SETTINGS); -} - -static int deferred_push_add_content_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ADD_CONTENT_LIST); -} - -static int deferred_push_configurations_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CONFIGURATIONS_LIST); -} - -static int deferred_push_load_content_special(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_LOAD_CONTENT_LIST); -} - -static int deferred_push_load_content_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_LOAD_CONTENT_LIST); -} - -static int deferred_push_information_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_INFORMATION_LIST); -} - -static int deferred_push_management_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS_MANAGEMENT); -} - -static int deferred_push_core_counters(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_PERFCOUNTERS_CORE); -} - -static int deferred_push_frontend_counters(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_PERFCOUNTERS_FRONTEND); -} - -static int deferred_push_core_cheat_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS_CHEATS); -} - -static int deferred_push_core_input_remapping_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS_REMAPPINGS); -} - -static int deferred_push_core_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORE_OPTIONS); -} - -static int deferred_push_disk_options(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OPTIONS_DISK); -} #ifdef HAVE_NETWORKING -static int deferred_push_thumbnails_updater_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_THUMBNAILS_UPDATER); -} - -static int deferred_push_core_updater_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORES_UPDATER); -} - -static int deferred_push_core_content_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORE_CONTENT); -} - -static int deferred_push_core_content_dirs_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORE_CONTENT_DIRS); -} - -static int deferred_push_core_content_dirs_subdir_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORE_CONTENT_DIRS_SUBDIR); -} - -static int deferred_push_lakka_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_LAKKA); -} - +generic_deferred_push(deferred_push_thumbnails_updater_list, DISPLAYLIST_THUMBNAILS_UPDATER) +generic_deferred_push(deferred_push_core_updater_list, DISPLAYLIST_CORES_UPDATER) +generic_deferred_push(deferred_push_core_content_list, DISPLAYLIST_CORE_CONTENT) +generic_deferred_push(deferred_push_core_content_dirs_list, DISPLAYLIST_CORE_CONTENT_DIRS) +generic_deferred_push(deferred_push_core_content_dirs_subdir_list, DISPLAYLIST_CORE_CONTENT_DIRS_SUBDIR) +generic_deferred_push(deferred_push_lakka_list, DISPLAYLIST_LAKKA) #endif -static int deferred_archive_action_detect_core(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ARCHIVE_ACTION_DETECT_CORE); -} - -static int deferred_archive_action(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ARCHIVE_ACTION); -} - static int deferred_push_cursor_manager_list_deferred( menu_displaylist_info_t *info) { @@ -941,111 +787,11 @@ static int deferred_push_default(menu_displaylist_info_t *info) return general_push(info, PUSH_DEFAULT, DISPLAYLIST_DEFAULT); } -static int deferred_push_history_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_HISTORY); -} - -static int deferred_push_database_manager_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DATABASES); -} - -static int deferred_push_cursor_manager_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DATABASE_CURSORS); -} - -static int deferred_push_content_collection_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DATABASE_PLAYLISTS); -} - static int deferred_push_favorites_list(menu_displaylist_info_t *info) { return general_push(info, PUSH_DEFAULT, DISPLAYLIST_FAVORITES); } -static int deferred_push_browse_url_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_BROWSE_URL_LIST); -} - -static int deferred_push_browse_url_start(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_BROWSE_URL_START); -} - -static int deferred_push_core_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORES); -} - -static int deferred_push_configurations(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CONFIG_FILES); -} - -static int deferred_push_video_shader_preset(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SHADER_PRESET); -} - -static int deferred_push_video_shader_pass(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_SHADER_PASS); -} - -static int deferred_push_video_filter(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_VIDEO_FILTERS); -} - -static int deferred_push_images(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_IMAGES); -} - -static int deferred_push_audio_dsp_plugin(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_AUDIO_FILTERS); -} - -static int deferred_push_cheat_file_load(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CHEAT_FILES); -} - -static int deferred_push_remap_file_load(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_REMAP_FILES); -} - -static int deferred_push_record_configfile(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_RECORD_CONFIG_FILES); -} - -static int deferred_push_input_overlay(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_OVERLAYS); -} - -static int deferred_push_video_font_path(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_FONTS); -} - -static int deferred_push_xmb_font_path(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_FONTS); -} - -static int deferred_push_content_history_path(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CONTENT_HISTORY); -} - static int menu_cbs_init_bind_deferred_push_compare_label( menu_file_list_cbs_t *cbs, const char *label, uint32_t label_hash) From 264d9903e886e8f5e60a814ebea64c641716a678 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 14:24:06 +0100 Subject: [PATCH 083/698] Update NL --- intl/msg_hash_nl.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/intl/msg_hash_nl.h b/intl/msg_hash_nl.h index f912f35260..f2a3b58f4b 100644 --- a/intl/msg_hash_nl.h +++ b/intl/msg_hash_nl.h @@ -2313,6 +2313,8 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, "Bokeh") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "Sneeuwvlok") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, "Refresh Room List") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, From 5d8df93c99bc46d7dbf2b8e3ac77544e06d91817 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 14:30:54 +0100 Subject: [PATCH 084/698] Cleanups --- menu/cbs/menu_cbs_deferred_push.c | 164 +++++------------------------- 1 file changed, 27 insertions(+), 137 deletions(-) diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 77ad57d4c4..3d158cc4b9 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -137,143 +137,33 @@ generic_deferred_push(deferred_push_saving_settings_list, DISPLAYLIST_ generic_deferred_push(deferred_push_logging_settings_list, DISPLAYLIST_LOGGING_SETTINGS_LIST) generic_deferred_push(deferred_push_frame_throttle_settings_list, DISPLAYLIST_FRAME_THROTTLE_SETTINGS_LIST) generic_deferred_push(deferred_push_rewind_settings_list, DISPLAYLIST_REWIND_SETTINGS_LIST) - -static int deferred_push_onscreen_display_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST); -} - -static int deferred_push_onscreen_notifications_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST); -} - -static int deferred_push_onscreen_overlay_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ONSCREEN_OVERLAY_SETTINGS_LIST); -} - -static int deferred_push_menu_file_browser_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_MENU_FILE_BROWSER_SETTINGS_LIST); -} - -static int deferred_push_menu_views_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_MENU_VIEWS_SETTINGS_LIST); -} - -static int deferred_push_quick_menu_views_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST); -} - -static int deferred_push_menu_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_MENU_SETTINGS_LIST); -} - -static int deferred_push_user_interface_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_USER_INTERFACE_SETTINGS_LIST); -} - -static int deferred_push_retro_achievements_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_RETRO_ACHIEVEMENTS_SETTINGS_LIST); -} - -static int deferred_push_updater_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_UPDATER_SETTINGS_LIST); -} - -static int deferred_push_wifi_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_WIFI_SETTINGS_LIST); -} - -static int deferred_push_network_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_NETWORK_SETTINGS_LIST); -} - -static int deferred_push_lakka_services_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_LAKKA_SERVICES_LIST); -} - -static int deferred_push_user_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_USER_SETTINGS_LIST); -} - -static int deferred_push_directory_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DIRECTORY_SETTINGS_LIST); -} - -static int deferred_push_privacy_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_PRIVACY_SETTINGS_LIST); -} - -static int deferred_push_audio_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_AUDIO_SETTINGS_LIST); -} - -static int deferred_push_input_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_INPUT_SETTINGS_LIST); -} - -static int deferred_push_recording_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_RECORDING_SETTINGS_LIST); -} - -static int deferred_push_playlist_settings_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_PLAYLIST_SETTINGS_LIST); -} - -static int deferred_push_input_hotkey_binds_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_INPUT_HOTKEY_BINDS_LIST); -} - -static int deferred_push_accounts_cheevos_list(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_ACCOUNTS_CHEEVOS_LIST); -} - -static int deferred_push_help(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_HELP_SCREEN_LIST); -} - -static int deferred_push_rdb_entry_detail(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_DATABASE_ENTRY); -} - -static int deferred_push_rpl_entry_actions(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS); -} - -static int deferred_push_core_list_deferred(menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORES_SUPPORTED); -} - -static int deferred_push_core_collection_list_deferred( - menu_displaylist_info_t *info) -{ - return deferred_push_dlist(info, DISPLAYLIST_CORES_COLLECTION_SUPPORTED); -} - +generic_deferred_push(deferred_push_onscreen_display_settings_list, DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST) +generic_deferred_push(deferred_push_onscreen_notifications_settings_list, DISPLAYLIST_ONSCREEN_NOTIFICATIONS_SETTINGS_LIST) +generic_deferred_push(deferred_push_onscreen_overlay_settings_list, DISPLAYLIST_ONSCREEN_OVERLAY_SETTINGS_LIST) +generic_deferred_push(deferred_push_menu_file_browser_settings_list,DISPLAYLIST_MENU_FILE_BROWSER_SETTINGS_LIST) +generic_deferred_push(deferred_push_menu_views_settings_list, DISPLAYLIST_MENU_VIEWS_SETTINGS_LIST) +generic_deferred_push(deferred_push_quick_menu_views_settings_list, DISPLAYLIST_QUICK_MENU_VIEWS_SETTINGS_LIST) +generic_deferred_push(deferred_push_menu_settings_list, DISPLAYLIST_MENU_SETTINGS_LIST) +generic_deferred_push(deferred_push_user_interface_settings_list, DISPLAYLIST_USER_INTERFACE_SETTINGS_LIST) +generic_deferred_push(deferred_push_retro_achievements_settings_list,DISPLAYLIST_RETRO_ACHIEVEMENTS_SETTINGS_LIST) +generic_deferred_push(deferred_push_updater_settings_list, DISPLAYLIST_UPDATER_SETTINGS_LIST) +generic_deferred_push(deferred_push_wifi_settings_list, DISPLAYLIST_WIFI_SETTINGS_LIST) +generic_deferred_push(deferred_push_network_settings_list, DISPLAYLIST_NETWORK_SETTINGS_LIST) +generic_deferred_push(deferred_push_lakka_services_list, DISPLAYLIST_LAKKA_SERVICES_LIST) +generic_deferred_push(deferred_push_user_settings_list, DISPLAYLIST_USER_SETTINGS_LIST) +generic_deferred_push(deferred_push_directory_settings_list, DISPLAYLIST_DIRECTORY_SETTINGS_LIST) +generic_deferred_push(deferred_push_privacy_settings_list, DISPLAYLIST_PRIVACY_SETTINGS_LIST) +generic_deferred_push(deferred_push_audio_settings_list, DISPLAYLIST_AUDIO_SETTINGS_LIST) +generic_deferred_push(deferred_push_input_settings_list, DISPLAYLIST_INPUT_SETTINGS_LIST) +generic_deferred_push(deferred_push_recording_settings_list, DISPLAYLIST_RECORDING_SETTINGS_LIST) +generic_deferred_push(deferred_push_playlist_settings_list, DISPLAYLIST_PLAYLIST_SETTINGS_LIST) +generic_deferred_push(deferred_push_input_hotkey_binds_list, DISPLAYLIST_INPUT_HOTKEY_BINDS_LIST) +generic_deferred_push(deferred_push_accounts_cheevos_list, DISPLAYLIST_ACCOUNTS_CHEEVOS_LIST) +generic_deferred_push(deferred_push_help, DISPLAYLIST_HELP_SCREEN_LIST) +generic_deferred_push(deferred_push_rdb_entry_detail, DISPLAYLIST_DATABASE_ENTRY) +generic_deferred_push(deferred_push_rpl_entry_actions, DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS) +generic_deferred_push(deferred_push_core_list_deferred, DISPLAYLIST_CORES_SUPPORTED) +generic_deferred_push(deferred_push_core_collection_list_deferred, DISPLAYLIST_CORES_COLLECTION_SUPPORTED) #ifdef HAVE_NETWORKING generic_deferred_push(deferred_push_thumbnails_updater_list, DISPLAYLIST_THUMBNAILS_UPDATER) From 7ba46356e698e6979814fe364565f0f7487d2aca Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 15:44:41 +0100 Subject: [PATCH 085/698] Cut down on code duplication --- menu/cbs/menu_cbs_deferred_push.c | 112 ++++++------------------------ 1 file changed, 20 insertions(+), 92 deletions(-) diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 3d158cc4b9..9a93e60dda 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -259,101 +259,29 @@ end: return ret; } -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_max_users( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_MAX_USERS); +#define generic_deferred_cursor_manager(name, type) \ +static int (name)(menu_displaylist_info_t *info) \ +{ \ + return deferred_push_cursor_manager_list_generic(info, type); \ } -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_famitsu_magazine_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_FAMITSU_MAGAZINE_RATING); -} +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_max_users, DATABASE_QUERY_ENTRY_MAX_USERS) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_famitsu_magazine_rating, DATABASE_QUERY_ENTRY_FAMITSU_MAGAZINE_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_edge_magazine_rating, DATABASE_QUERY_ENTRY_EDGE_MAGAZINE_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_edge_magazine_issue, DATABASE_QUERY_ENTRY_EDGE_MAGAZINE_ISSUE) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_elspa_rating, DATABASE_QUERY_ENTRY_ELSPA_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_cero_rating, DATABASE_QUERY_ENTRY_CERO_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_pegi_rating, DATABASE_QUERY_ENTRY_PEGI_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_bbfc_rating, DATABASE_QUERY_ENTRY_BBFC_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_esrb_rating, DATABASE_QUERY_ENTRY_ESRB_RATING) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_enhancement_hw, DATABASE_QUERY_ENTRY_ENHANCEMENT_HW) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_franchise, DATABASE_QUERY_ENTRY_FRANCHISE) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_publisher, DATABASE_QUERY_ENTRY_PUBLISHER) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_developer, DATABASE_QUERY_ENTRY_DEVELOPER) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_origin, DATABASE_QUERY_ENTRY_ORIGIN) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_releasemonth, DATABASE_QUERY_ENTRY_RELEASEDATE_MONTH) +generic_deferred_cursor_manager(deferred_push_cursor_manager_list_deferred_query_rdb_entry_releaseyear, DATABASE_QUERY_ENTRY_RELEASEDATE_YEAR) -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_edge_magazine_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_EDGE_MAGAZINE_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_edge_magazine_issue( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_EDGE_MAGAZINE_ISSUE); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_elspa_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_ELSPA_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_cero_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_CERO_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_pegi_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_PEGI_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_bbfc_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_BBFC_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_esrb_rating( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_ESRB_RATING); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_enhancement_hw( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_ENHANCEMENT_HW); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_franchise( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_FRANCHISE); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_publisher( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_PUBLISHER); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_developer( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_DEVELOPER); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_origin( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_ORIGIN); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_releasemonth( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_RELEASEDATE_MONTH); -} - -static int deferred_push_cursor_manager_list_deferred_query_rdb_entry_releaseyear( - menu_displaylist_info_t *info) -{ - return deferred_push_cursor_manager_list_generic(info, DATABASE_QUERY_ENTRY_RELEASEDATE_YEAR); -} #endif #if 0 From 4b4ae0c1a005c589362a578f73b3ea6404f7ab43 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:09:19 +0100 Subject: [PATCH 086/698] Update CHANGES.md --- CHANGES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index cabe1a0b9c..bef6f254b5 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,8 @@ - COMMON: New lightgun API. - FREEBSD: Support libusb HID input driver. - HAIKU: Buildfix. +- LINUX/X11: Add RetroArch logo to window title bar. +- LINUX/X11: Input driver now supports new lightgun code. - LOCALIZATION: Update Italian translation. - LOCALIZATION: Update Portuguese-Brazilian translation. - LOCALIZATION: Update Russian translation. @@ -14,8 +16,6 @@ - SCANNER: Fix crash from Windows-incompatible format string. - WIIU: Disabled the controller patcher for now since it was the source of many stability issues. - WINDOWS: Raw input driver now supports new lightgun code. -- X11: Add RetroArch logo to window title bar. -- X11: Input driver now supports new lightgun code. # 1.6.9 - COMMON: Small memory leak. From 4cb739d45aacb17c3137eb48e5548aced18b4b17 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:09:44 +0100 Subject: [PATCH 087/698] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index bef6f254b5..9a962e0dcf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ - COMMON: Optimized NBIO implementations now for Apple, Windows, and Linux. Uses mmap for Linux/Windows/BSD if/when available. File I/O should now be much faster for loading images inside the menu. - COMMON: Native Blissbox support now for latest firmware as of writing (2.0). Implementation through libusb and/or native Windows HID. - COMMON: New lightgun API. +- COMMON: Fixed some playlist bugs. - FREEBSD: Support libusb HID input driver. - HAIKU: Buildfix. - LINUX/X11: Add RetroArch logo to window title bar. From 69295c21790c85820576541544589ddcfc4caffd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:20:52 +0100 Subject: [PATCH 088/698] Fix BIT_GET --- libretro-common/include/retro_miscellaneous.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/include/retro_miscellaneous.h b/libretro-common/include/retro_miscellaneous.h index 010b04f19c..bfebd1f8e8 100644 --- a/libretro-common/include/retro_miscellaneous.h +++ b/libretro-common/include/retro_miscellaneous.h @@ -83,7 +83,7 @@ static INLINE bool bits_any_set(uint32_t* ptr, uint32_t count) #define BIT_SET(a, bit) ((a)[(bit) >> 3] |= (1 << ((bit) & 7))) #define BIT_CLEAR(a, bit) ((a)[(bit) >> 3] &= ~(1 << ((bit) & 7))) -#define BIT_GET(a, bit) (((a).data[(bit) >> 3] >> ((bit) & 7)) & 1) +#define BIT_GET(a, bit) (((a)[(bit) >> 3] >> ((bit) & 7)) & 1) #define BIT16_SET(a, bit) ((a) |= (1 << ((bit) & 15))) #define BIT16_CLEAR(a, bit) ((a) &= ~(1 << ((bit) & 15))) From 88b85c2d15e18c0fc5b5bcdb1ad0822b313a63a0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:27:39 +0100 Subject: [PATCH 089/698] Fix it for C89 --- intl/msg_hash_de.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 333f191a49..24b7eb69ce 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -904,13 +904,19 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) break; case MENU_ENUM_LABEL_VIDEO_SHADER_SCALE_PASS: snprintf(s, len, + " \n" + ); + { + /* Work around C89 limitations */ + const char * t = "Für diesen durchgang skalieren. \n" " \n" "Der Skalierungsfaktor wird multipliziert, \n" "d.h. 2x im ersten durchgang und 2x im \n" "zweiten durchgang bedeute eine 4x Gesamt- \n" "Skalierung." - " \n" + " \n"; + const char * u = "Wenn es im letzten durchgang einen \n" "Skalierungsfaktor gibt, wird das Ergebnis \n" "mit dem als 'Standardfilter' eingestellten \n" @@ -919,8 +925,10 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Wenn 'Ignorieren' eingestellt ist, wird \n" "entweder einfache Skalierung oder Vollbild- \n" "Streckung verwendet - abhängig davon, ob \n" - "es der letzte durchgang ist oder nicht." - ); + "es der letzte durchgang ist oder nicht."; + strlcpy(s, t, len); + strlcat(s, u, len); + } break; case MENU_ENUM_LABEL_VIDEO_SHADER_NUM_PASSES: snprintf(s, len, From de900325c6247fd20be59c5c7460927abb4099e4 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:31:58 +0100 Subject: [PATCH 090/698] More C89_BUILD fixes --- intl/msg_hash_de.c | 51 +++++++++++++++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 16 deletions(-) diff --git a/intl/msg_hash_de.c b/intl/msg_hash_de.c index 24b7eb69ce..6f56a0dd5a 100644 --- a/intl/msg_hash_de.c +++ b/intl/msg_hash_de.c @@ -1141,7 +1141,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Verwendet für Inhalt, der auf mehreren Datenträgern ausgeliefert wird. "); break; case MENU_ENUM_LABEL_ENABLE_HOTKEY: - snprintf(s, len, + { + /* Work around C89 limitations */ + const char * t = "Andere Tastenkürzel aktivieren. \n" " \n" "Wenn dieses Tastenkürzel entweder einer\n" @@ -1149,14 +1151,18 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Controller-Achse zugeordnet ist, werden alle \n" "anderen Tastenkürzel nur aktiviert, wenn dieses \n" "Tastenkürzel zur gleichen Zeit gehalten wird. \n" - " \n" + " \n"; + const char * u = "Dies ist hilfreich für Implementierungen, die auf \n" "RETRO_KEYBOARD ausgelegt sind und eine große \n" "Fläche auf der Tastatur benötigen, wo es nicht \n" "gewünscht ist, dass es zu Kollisionen mit Tastenkürzeln kommt \n." " \n" "Alternativ können auch alle Tastatur-Kürzel durch \n" - "den Benutzer deaktiviert werden."); + "den Benutzer deaktiviert werden."; + strlcpy(s, t, len); + strlcat(s, u, len); + } break; case MENU_ENUM_LABEL_REWIND_ENABLE: snprintf(s, len, @@ -1173,7 +1179,9 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "Libretro-Core-Implementierungen gesucht wird."); break; case MENU_ENUM_LABEL_VIDEO_REFRESH_RATE_AUTO: - snprintf(s, len, + { + /* Work around C89 limitations */ + const char * t = "Bildwiederholrate.\n" " \n" "Die genaue Bildwiederholrate deines Bildschirms (Hz).\n" @@ -1182,14 +1190,19 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) " \n" "audio_input_rate = Spiel-Eingaberate * Bildschirm- \n" "Wiederholrate / Spiel-Wiederholrate\n" - " \n" + " \n"; + const char * u = "Wenn die Implementierung keinen Wert liefert, \n" "werden aus Kompatiblitätsgründen die Werte für NTSC \n" "angenommen.\n" " \n" "Dieser Wert sollte nahe 60Hz liegen, um Tonsprünge zu vermeiden. \n" "Wenn dein Bildschirm nicht auf 60Hz oder einem ähnlichen Wert läuft, \n" - "deaktiviere VSync und lasse diese Einstellung unverändert. \n"); + "deaktiviere VSync und lasse diese Einstellung unverändert. \n"; + ; + strlcpy(s, t, len); + strlcat(s, u, len); + } break; case MENU_ENUM_LABEL_VIDEO_ROTATION: snprintf(s, len, @@ -1602,20 +1615,26 @@ int menu_hash_get_help_de_enum(enum msg_hash_enums msg, char *s, size_t len) "tritt keine Netplay-Verzögerung auf.\n"); break; case MENU_ENUM_LABEL_NETPLAY_CHECK_FRAMES: - snprintf(s, len, + { + /* Work around C89 limitations */ + const char * t = "Die Frequenz in Einzelbildern, mit der Netplay \n" "sicherstellen wird, dass Host und Clients \n" "synchronisiert sind. \n" " \n" - "Bei den meisten Cores wird diese Einstellungen \n" - "keine sichtbaren Auswirkungen haben und kann ignoriert werden. \n" - "Bei nichtdeterministischen Cores legt dieser Wert fest, \n" - "wie oft die Netplay-Mitglieder miteinander synchronisiert \n" - "werden. Bei fehlerhaften Cores wird ein \n" - "anderer Wert als 0 für diese Einstellung erhebliche \n" - "Leistungsprobleme verursachen. Auf 0 setzen, um keine \n" - "Überprüfungen durchzuführen. Diese Einstellung wird nur \n" - "auf dem Netplay-Host verwendet. \n"); + "Bei den meisten Cores wird diese Einstellungen \n" + "keine sichtbaren Auswirkungen haben und kann ignoriert werden. \n"; + const char *u = + "Bei nichtdeterministischen Cores legt dieser Wert fest, \n" + "wie oft die Netplay-Mitglieder miteinander synchronisiert \n" + "werden. Bei fehlerhaften Cores wird ein \n" + "anderer Wert als 0 für diese Einstellung erhebliche \n" + "Leistungsprobleme verursachen. Auf 0 setzen, um keine \n" + "Überprüfungen durchzuführen. Diese Einstellung wird nur \n" + "auf dem Netplay-Host verwendet. \n"; + strlcpy(s, t, len); + strlcat(s, u, len); + } break; case MENU_ENUM_LABEL_NETPLAY_INPUT_LATENCY_FRAMES_MIN: snprintf(s, len, From 3ede6a9aebd704361530a7f6b3b41bae2b278d0d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:35:03 +0100 Subject: [PATCH 091/698] Some C89_BUILD fixes --- cheevos/cheevos.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index b2cf87154b..b9df229ac7 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1796,6 +1796,7 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) } else if (valid) { + char msg[256]; char url[256]; url[0] = '\0'; @@ -1807,7 +1808,6 @@ static void cheevos_test_cheevo_set(const cheevoset_t *set) RARCH_LOG("[CHEEVOS]: awarding cheevo %u: %s (%s).\n", cheevo->id, cheevo->title, cheevo->description); - char msg[256]; snprintf(msg, sizeof(msg), "Achievement Unlocked: %s", cheevo->title); msg[sizeof(msg) - 1] = 0; runloop_msg_queue_push(msg, 0, 2 * 60, false); @@ -1856,10 +1856,11 @@ static int cheevos_expr_value(cheevos_expr_t* expr) { cheevos_term_t* term = expr->terms; unsigned i; - /* Separate possible values with '$' operator, submit the largest */ unsigned current_value = 0; + /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ int values[expr->compare_count]; + memset(values, 0, sizeof values); for (i = expr->count; i != 0; i--, term++) @@ -1974,12 +1975,13 @@ static void cheevos_test_leaderboards(void) else { char url[256]; + char msg[256]; + char formatted_value[16]; + cheevos_make_lboard_url(lboard, url, sizeof(url)); task_push_http_transfer(url, true, NULL, cheevos_lboard_submit, lboard); RARCH_LOG("[CHEEVOS]: submit lboard %s\n", lboard->title); - char msg[256]; - char formatted_value[16]; cheevos_format_value(value, lboard->format, formatted_value, sizeof(formatted_value)); snprintf(msg, sizeof(msg), "Submitted %s for %s", formatted_value, lboard->title); msg[sizeof(msg) - 1] = 0; @@ -1998,11 +2000,12 @@ static void cheevos_test_leaderboards(void) { if (cheevos_test_lboard_condition(&lboard->start)) { + char msg[256]; + RARCH_LOG("[CHEEVOS]: start lboard %s\n", lboard->title); lboard->active = 1; lboard->last_value = -1; - char msg[256]; snprintf(msg, sizeof(msg), "Leaderboard Active: %s", lboard->title); msg[sizeof(msg) - 1] = 0; runloop_msg_queue_push(msg, 0, 2 * 60, false); @@ -2835,10 +2838,10 @@ static int cheevos_iterate(coro_t* coro) { if(cheevos_locals.core.count > 0) { + int mode; const cheevo_t* cheevo = cheevos_locals.core.cheevos; const cheevo_t* end = cheevo + cheevos_locals.core.count; int number_of_unlocked = cheevos_locals.core.count; - int mode; char msg[256]; if(CHEEVOS_VAR_SETTINGS->bools.cheevos_hardcore_mode_enable) From 3e81996bd363db34a4b5f951348ce3587e6ddcbd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:40:13 +0100 Subject: [PATCH 092/698] Update D3D headers --- gfx/include/d3d9/d3dx9shader.h | 2 +- gfx/include/d3d9caps.h | 204 ++++++++++++++++----------------- gfx/include/d3d9types.h | 41 +++---- 3 files changed, 120 insertions(+), 127 deletions(-) diff --git a/gfx/include/d3d9/d3dx9shader.h b/gfx/include/d3d9/d3dx9shader.h index 46ddf4c85a..74e40cfc80 100644 --- a/gfx/include/d3d9/d3dx9shader.h +++ b/gfx/include/d3d9/d3dx9shader.h @@ -643,4 +643,4 @@ typedef struct _D3DXSHADER_STRUCTMEMBERINFO -#endif //__D3DX9SHADER_H__ +#endif /* __D3DX9SHADER_H__ */ diff --git a/gfx/include/d3d9caps.h b/gfx/include/d3d9caps.h index 96a9bef9d4..adc3fb1f8d 100644 --- a/gfx/include/d3d9caps.h +++ b/gfx/include/d3d9caps.h @@ -12,9 +12,9 @@ #ifndef DIRECT3D_VERSION #define DIRECT3D_VERSION 0x0900 -#endif //DIRECT3D_VERSION +#endif /* DIRECT3D_VERSION */ -// include this file content only if compiling for DX9 interfaces +/* include this file content only if compiling for DX9 interfaces */ #if(DIRECT3D_VERSION >= 0x0900) @@ -117,7 +117,7 @@ DEFINE_GUID(D3DKEYEXCHANGE_RSAES_OAEP, DEFINE_GUID(D3DKEYEXCHANGE_DXVA, 0x43d3775c, 0x38e5, 0x4924, 0x8d, 0x86, 0xd3, 0xfc, 0xcf, 0x15, 0x3e, 0x9b); -#endif // !D3D_DISABLE_9EX +#endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ typedef struct _D3DCAPS9 @@ -146,13 +146,13 @@ typedef struct _D3DCAPS9 DWORD AlphaCmpCaps; DWORD ShadeCaps; DWORD TextureCaps; - DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's - DWORD CubeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DCubeTexture9's - DWORD VolumeTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DVolumeTexture9's - DWORD TextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DTexture9's - DWORD VolumeTextureAddressCaps; // D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's + DWORD TextureFilterCaps; /* D3DPTFILTERCAPS for IDirect3DTexture9's */ + DWORD CubeTextureFilterCaps; /* D3DPTFILTERCAPS for IDirect3DCubeTexture9's */ + DWORD VolumeTextureFilterCaps; /* D3DPTFILTERCAPS for IDirect3DVolumeTexture9's */ + DWORD TextureAddressCaps; /* D3DPTADDRESSCAPS for IDirect3DTexture9's */ + DWORD VolumeTextureAddressCaps; /* D3DPTADDRESSCAPS for IDirect3DVolumeTexture9's */ - DWORD LineCaps; // D3DLINECAPS + DWORD LineCaps; /* D3DLINECAPS */ DWORD MaxTextureWidth, MaxTextureHeight; DWORD MaxVolumeExtent; @@ -183,51 +183,49 @@ typedef struct _D3DCAPS9 float MaxPointSize; - DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxPrimitiveCount; /* max number of primitives per DrawPrimitive call */ DWORD MaxVertexIndex; DWORD MaxStreams; - DWORD MaxStreamStride; // max stride for SetStreamSource + DWORD MaxStreamStride; /* max stride for SetStreamSource */ DWORD VertexShaderVersion; - DWORD MaxVertexShaderConst; // number of vertex shader constant registers + DWORD MaxVertexShaderConst; /* number of vertex shader constant registers */ DWORD PixelShaderVersion; - float PixelShader1xMaxValue; // max value storable in registers of ps.1.x shaders + float PixelShader1xMaxValue; /* max value storable in registers of ps.1.x shaders */ - // Here are the DX9 specific ones + /* Here are the DX9 specific ones */ DWORD DevCaps2; float MaxNpatchTessellationLevel; DWORD Reserved5; - UINT MasterAdapterOrdinal; // ordinal of master adaptor for adapter group - UINT AdapterOrdinalInGroup; // ordinal inside the adapter group - UINT NumberOfAdaptersInGroup; // number of adapters in this adapter group (only if master) - DWORD DeclTypes; // Data types, supported in vertex declarations - DWORD NumSimultaneousRTs; // Will be at least 1 - DWORD StretchRectFilterCaps; // Filter caps supported by StretchRect + UINT MasterAdapterOrdinal; /* ordinal of master adaptor for adapter group */ + UINT AdapterOrdinalInGroup; /* ordinal inside the adapter group */ + UINT NumberOfAdaptersInGroup; /* number of adapters in this adapter group (only if master) */ + DWORD DeclTypes; /* Data types, supported in vertex declarations */ + DWORD NumSimultaneousRTs; /* Will be at least 1 */ + DWORD StretchRectFilterCaps; /* Filter caps supported by StretchRect */ D3DVSHADERCAPS2_0 VS20Caps; D3DPSHADERCAPS2_0 PS20Caps; - DWORD VertexTextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders - DWORD MaxVShaderInstructionsExecuted; // maximum number of vertex shader instructions that can be executed - DWORD MaxPShaderInstructionsExecuted; // maximum number of pixel shader instructions that can be executed + DWORD VertexTextureFilterCaps; /* D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders */ + DWORD MaxVShaderInstructionsExecuted; /* maximum number of vertex shader instructions that can be executed */ + DWORD MaxPShaderInstructionsExecuted; /* maximum number of pixel shader instructions that can be executed */ DWORD MaxVertexShader30InstructionSlots; DWORD MaxPixelShader30InstructionSlots; } D3DCAPS9; -// -// BIT DEFINES FOR D3DCAPS9 DWORD MEMBERS -// +/* + * BIT DEFINES FOR D3DCAPS9 DWORD MEMBERS + */ -// -// Caps -// +/* + * Caps + */ #define D3DCAPS_OVERLAY 0x00000800L #define D3DCAPS_READ_SCANLINE 0x00020000L -// -// Caps2 -// +/* Caps2 */ #define D3DCAPS2_FULLSCREENGAMMA 0x00020000L #define D3DCAPS2_CANCALIBRATEGAMMA 0x00100000L #define D3DCAPS2_RESERVED 0x02000000L @@ -240,21 +238,21 @@ typedef struct _D3DCAPS9 #define D3DCAPS2_CANSHARERESOURCE 0x80000000L -#endif // !D3D_DISABLE_9EX +#endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ -// -// Caps3 -// +/* Caps3 */ #define D3DCAPS3_RESERVED 0x8000001fL -// Indicates that the device can respect the ALPHABLENDENABLE render state -// when fullscreen while using the FLIP or DISCARD swap effect. -// COPY and COPYVSYNC swap effects work whether or not this flag is set. +/* Indicates that the device can respect the ALPHABLENDENABLE render state + * when fullscreen while using the FLIP or DISCARD swap effect. + * COPY and COPYVSYNC swap effects work whether or not this flag is set. + */ #define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020L -// Indicates that the device can perform a gamma correction from -// a windowed back buffer containing linear content to the sRGB desktop. +/* Indicates that the device can perform a gamma correction from + * a windowed back buffer containing linear content to the sRGB desktop. + */ #define D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION 0x00000080L #define D3DCAPS3_COPY_TO_VIDMEM 0x00000100L /* Device can acclerate copies from sysmem to local vidmem */ @@ -262,10 +260,7 @@ typedef struct _D3DCAPS9 #define D3DCAPS3_DXVAHD 0x00000400L #define D3DCAPS3_DXVAHD_LIMITED 0x00000800L - -// -// PresentationIntervals -// +/* PresentationIntervals */ #define D3DPRESENT_INTERVAL_DEFAULT 0x00000000L #define D3DPRESENT_INTERVAL_ONE 0x00000001L #define D3DPRESENT_INTERVAL_TWO 0x00000002L @@ -273,17 +268,13 @@ typedef struct _D3DCAPS9 #define D3DPRESENT_INTERVAL_FOUR 0x00000008L #define D3DPRESENT_INTERVAL_IMMEDIATE 0x80000000L -// -// CursorCaps -// -// Driver supports HW color cursor in at least hi-res modes(height >=400) +/* CursorCaps */ +/* Driver supports HW color cursor in at least hi-res modes(height >=400) */ #define D3DCURSORCAPS_COLOR 0x00000001L -// Driver supports HW cursor also in low-res modes(height < 400) +/* Driver supports HW cursor also in low-res modes(height < 400) */ #define D3DCURSORCAPS_LOWRES 0x00000002L -// -// DevCaps -// +/* DevCaps */ #define D3DDEVCAPS_EXECUTESYSTEMMEMORY 0x00000010L /* Device can use execute buffers from system memory */ #define D3DDEVCAPS_EXECUTEVIDEOMEMORY 0x00000020L /* Device can use execute buffers from video memory */ #define D3DDEVCAPS_TLVERTEXSYSTEMMEMORY 0x00000040L /* Device can use TL buffers from system memory */ @@ -305,9 +296,9 @@ typedef struct _D3DCAPS9 #define D3DDEVCAPS_RTPATCHHANDLEZERO 0x00800000L /* Indicates that RT Patches may be drawn efficiently using handle 0 */ #define D3DDEVCAPS_NPATCHES 0x01000000L /* Device supports N-Patches */ -// -// PrimitiveMiscCaps -// +/* + * PrimitiveMiscCaps + */ #define D3DPMISCCAPS_MASKZ 0x00000002L #define D3DPMISCCAPS_CULLNONE 0x00000010L #define D3DPMISCCAPS_CULLCW 0x00000020L @@ -332,13 +323,13 @@ typedef struct _D3DCAPS9 #define D3DPMISCCAPS_POSTBLENDSRGBCONVERT 0x00200000L /* Indicates device can perform conversion to sRGB after blending. */ -#endif // !D3D_DISABLE_9EX +#endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ -// -// LineCaps -// +/* + * LineCaps + */ #define D3DLINECAPS_TEXTURE 0x00000001L #define D3DLINECAPS_ZTEST 0x00000002L #define D3DLINECAPS_BLEND 0x00000004L @@ -346,9 +337,9 @@ typedef struct _D3DCAPS9 #define D3DLINECAPS_FOG 0x00000010L #define D3DLINECAPS_ANTIALIAS 0x00000020L -// -// RasterCaps -// +/* + * RasterCaps + */ #define D3DPRASTERCAPS_DITHER 0x00000001L #define D3DPRASTERCAPS_ZTEST 0x00000010L #define D3DPRASTERCAPS_FOGVERTEX 0x00000080L @@ -366,9 +357,9 @@ typedef struct _D3DCAPS9 #define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L #define D3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000L -// -// ZCmpCaps, AlphaCmpCaps -// +/* + * ZCmpCaps, AlphaCmpCaps + */ #define D3DPCMPCAPS_NEVER 0x00000001L #define D3DPCMPCAPS_LESS 0x00000002L #define D3DPCMPCAPS_EQUAL 0x00000004L @@ -378,9 +369,9 @@ typedef struct _D3DCAPS9 #define D3DPCMPCAPS_GREATEREQUAL 0x00000040L #define D3DPCMPCAPS_ALWAYS 0x00000080L -// -// SourceBlendCaps, DestBlendCaps -// +/* + * SourceBlendCaps, DestBlendCaps + */ #define D3DPBLENDCAPS_ZERO 0x00000001L #define D3DPBLENDCAPS_ONE 0x00000002L #define D3DPBLENDCAPS_SRCCOLOR 0x00000004L @@ -402,31 +393,32 @@ typedef struct _D3DCAPS9 #define D3DPBLENDCAPS_SRCCOLOR2 0x00004000L #define D3DPBLENDCAPS_INVSRCCOLOR2 0x00008000L -#endif // !D3D_DISABLE_9EX +#endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ - -// -// ShadeCaps -// +/* + * ShadeCaps + */ #define D3DPSHADECAPS_COLORGOURAUDRGB 0x00000008L #define D3DPSHADECAPS_SPECULARGOURAUDRGB 0x00000200L #define D3DPSHADECAPS_ALPHAGOURAUDBLEND 0x00004000L #define D3DPSHADECAPS_FOGGOURAUD 0x00080000L -// -// TextureCaps -// +/* + * TextureCaps + */ #define D3DPTEXTURECAPS_PERSPECTIVE 0x00000001L /* Perspective-correct texturing is supported */ #define D3DPTEXTURECAPS_POW2 0x00000002L /* Power-of-2 texture dimensions are required - applies to non-Cube/Volume textures only. */ #define D3DPTEXTURECAPS_ALPHA 0x00000004L /* Alpha in texture pixels is supported */ #define D3DPTEXTURECAPS_SQUAREONLY 0x00000020L /* Only square textures are supported */ #define D3DPTEXTURECAPS_TEXREPEATNOTSCALEDBYSIZE 0x00000040L /* Texture indices are not scaled by the texture size prior to interpolation */ #define D3DPTEXTURECAPS_ALPHAPALETTE 0x00000080L /* Device can draw alpha from texture palettes */ -// Device can use non-POW2 textures if: -// 1) D3DTEXTURE_ADDRESS is set to CLAMP for this texture's stage -// 2) D3DRS_WRAP(N) is zero for this texture's coordinates -// 3) mip mapping is not enabled (use magnification filter only) + +/* Device can use non-POW2 textures if: + * 1) D3DTEXTURE_ADDRESS is set to CLAMP for this texture's stage + * 2) D3DRS_WRAP(N) is zero for this texture's coordinates + * 3) mip mapping is not enabled (use magnification filter only) + */ #define D3DPTEXTURECAPS_NONPOW2CONDITIONAL 0x00000100L #define D3DPTEXTURECAPS_PROJECTED 0x00000400L /* Device can do D3DTTFF_PROJECTED */ #define D3DPTEXTURECAPS_CUBEMAP 0x00000800L /* Device can do cubemap textures */ @@ -439,9 +431,9 @@ typedef struct _D3DCAPS9 #define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation in programmable and fixed function pixel shaders */ -// -// TextureFilterCaps, StretchRectFilterCaps -// +/* + * TextureFilterCaps, StretchRectFilterCaps + */ #define D3DPTFILTERCAPS_MINFPOINT 0x00000100L /* Min Filter */ #define D3DPTFILTERCAPS_MINFLINEAR 0x00000200L #define D3DPTFILTERCAPS_MINFANISOTROPIC 0x00000400L @@ -455,7 +447,7 @@ typedef struct _D3DCAPS9 #define D3DPTFILTERCAPS_CONVOLUTIONMONO 0x00040000L /* Min and Mag for the convolution mono filter */ -#endif // !D3D_DISABLE_9EX +#endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ #define D3DPTFILTERCAPS_MAGFPOINT 0x01000000L /* Mag Filter */ @@ -464,9 +456,9 @@ typedef struct _D3DCAPS9 #define D3DPTFILTERCAPS_MAGFPYRAMIDALQUAD 0x08000000L #define D3DPTFILTERCAPS_MAGFGAUSSIANQUAD 0x10000000L -// -// TextureAddressCaps -// +/* + * TextureAddressCaps + */ #define D3DPTADDRESSCAPS_WRAP 0x00000001L #define D3DPTADDRESSCAPS_MIRROR 0x00000002L #define D3DPTADDRESSCAPS_CLAMP 0x00000004L @@ -474,9 +466,9 @@ typedef struct _D3DCAPS9 #define D3DPTADDRESSCAPS_INDEPENDENTUV 0x00000010L #define D3DPTADDRESSCAPS_MIRRORONCE 0x00000020L -// -// StencilCaps -// +/* + * StencilCaps + */ #define D3DSTENCILCAPS_KEEP 0x00000001L #define D3DSTENCILCAPS_ZERO 0x00000002L #define D3DSTENCILCAPS_REPLACE 0x00000004L @@ -487,9 +479,9 @@ typedef struct _D3DCAPS9 #define D3DSTENCILCAPS_DECR 0x00000080L #define D3DSTENCILCAPS_TWOSIDED 0x00000100L -// -// TextureOpCaps -// +/* + * TextureOpCaps + */ #define D3DTEXOPCAPS_DISABLE 0x00000001L #define D3DTEXOPCAPS_SELECTARG1 0x00000002L #define D3DTEXOPCAPS_SELECTARG2 0x00000004L @@ -517,16 +509,16 @@ typedef struct _D3DCAPS9 #define D3DTEXOPCAPS_MULTIPLYADD 0x01000000L #define D3DTEXOPCAPS_LERP 0x02000000L -// -// FVFCaps -// +/* + * FVFCaps + */ #define D3DFVFCAPS_TEXCOORDCOUNTMASK 0x0000ffffL /* mask for texture coordinate count field */ #define D3DFVFCAPS_DONOTSTRIPELEMENTS 0x00080000L /* Device prefers that vertex elements not be stripped */ #define D3DFVFCAPS_PSIZE 0x00100000L /* Device can receive point size */ -// -// VertexProcessingCaps -// +/* + * VertexProcessingCaps + */ #define D3DVTXPCAPS_TEXGEN 0x00000001L /* device can do texgen */ #define D3DVTXPCAPS_MATERIALSOURCE7 0x00000002L /* device can do DX7-level colormaterialsource ops */ #define D3DVTXPCAPS_DIRECTIONALLIGHTS 0x00000008L /* device can do directional lights */ @@ -537,9 +529,9 @@ typedef struct _D3DCAPS9 #define D3DVTXPCAPS_NO_TEXGEN_NONLOCALVIEWER 0x00000200L /* device does not support TexGen in non-local viewer mode */ -// -// DevCaps2 -// +/* + * DevCaps2 + */ #define D3DDEVCAPS2_STREAMOFFSET 0x00000001L /* Device supports offsets in streams. Must be set by DX9 drivers */ #define D3DDEVCAPS2_DMAPNPATCH 0x00000002L /* Device supports displacement maps for N-Patches*/ #define D3DDEVCAPS2_ADAPTIVETESSRTPATCH 0x00000004L /* Device supports adaptive tesselation of RT-patches*/ @@ -548,9 +540,9 @@ typedef struct _D3DCAPS9 #define D3DDEVCAPS2_PRESAMPLEDDMAPNPATCH 0x00000020L /* Device supports presampled displacement maps for N-Patches */ #define D3DDEVCAPS2_VERTEXELEMENTSCANSHARESTREAMOFFSET 0x00000040L /* Vertex elements in a vertex declaration can share the same stream offset */ -// -// DeclTypes -// +/* + * DeclTypes + */ #define D3DDTCAPS_UBYTE4 0x00000001L #define D3DDTCAPS_UBYTE4N 0x00000002L #define D3DDTCAPS_SHORT2N 0x00000004L diff --git a/gfx/include/d3d9types.h b/gfx/include/d3d9types.h index 80fabba9e8..b4b9a94ddf 100644 --- a/gfx/include/d3d9types.h +++ b/gfx/include/d3d9types.h @@ -565,25 +565,25 @@ typedef enum _D3DTEXTUREOP D3DTOP_MODULATE4X = 6, /* multiply and 2 bits */ /* Add */ - D3DTOP_ADD = 7, // add arguments together - D3DTOP_ADDSIGNED = 8, // add with -0.5 bias - D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit - D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation - D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product - // Arg1 + Arg2 - Arg1*Arg2 - // = Arg1 + (1-Arg1)*Arg2 + D3DTOP_ADD = 7, /* add arguments together */ + D3DTOP_ADDSIGNED = 8, /* add with -0.5 bias */ + D3DTOP_ADDSIGNED2X = 9, /* as above but left 1 bit */ + D3DTOP_SUBTRACT = 10, /* Arg1 - Arg2, with no saturation */ + D3DTOP_ADDSMOOTH = 11, /* add 2 args, subtract product */ + /* Arg1 + Arg2 - Arg1*Arg2 */ + /* = Arg1 + (1-Arg1)*Arg2 */ - // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) - D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha - D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha - D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR + /* Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) */ + D3DTOP_BLENDDIFFUSEALPHA = 12, /* iterated alpha */ + D3DTOP_BLENDTEXTUREALPHA = 13, /* texture alpha */ + D3DTOP_BLENDFACTORALPHA = 14, /* alpha from D3DRS_TEXTUREFACTOR */ - // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) - D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha - D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + /* Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) */ + D3DTOP_BLENDTEXTUREALPHAPM = 15, /* texture alpha */ + D3DTOP_BLENDCURRENTALPHA = 16, /* by alpha of current color */ - // Specular mapping - D3DTOP_PREMODULATE = 17, // modulate with next texture before use + /* Specular mapping */ + D3DTOP_PREMODULATE = 17, /* modulate with next texture before use */ D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB // COLOROP only D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A @@ -1601,10 +1601,11 @@ typedef enum _D3DRESOURCETYPE { #endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ -// When passed to CheckDeviceFormat, D3DUSAGE_AUTOGENMIPMAP may return -// D3DOK_NOAUTOGEN if the device doesn't support autogeneration for that format. -// D3DOK_NOAUTOGEN is a success code, not a failure code... the SUCCEEDED and FAILED macros -// will return true and false respectively for this code. +/* When passed to CheckDeviceFormat, D3DUSAGE_AUTOGENMIPMAP may return + * D3DOK_NOAUTOGEN if the device doesn't support autogeneration for that format. + * D3DOK_NOAUTOGEN is a success code, not a failure code... the SUCCEEDED and FAILED macros + * will return true and false respectively for this code. + */ #define D3DUSAGE_AUTOGENMIPMAP (0x00000400L) #define D3DUSAGE_DMAP (0x00004000L) From 863858ab0095c8f792b212fe86487e19657fc8d5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:42:37 +0100 Subject: [PATCH 093/698] Can't have anonymous variadic macros in C89 --- cheevos/var.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/cheevos/var.c b/cheevos/var.c index 36828b46b3..45ae9ac866 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -24,10 +24,15 @@ #include "../core.h" #include "../verbosity.h" +static void STUB_LOG(const char *fmt, ...) +{ + (void)fmt; +} + #ifdef CHEEVOS_VERBOSE #define CHEEVOS_LOG RARCH_LOG #else -#define CHEEVOS_LOG(...) +#define CHEEVOS_LOG STUB_LOG #endif /***************************************************************************** From f9fa2ab2b78bd806401fa4331eed57aac9034c54 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:44:05 +0100 Subject: [PATCH 094/698] More C89_BUILD fixes --- cheevos/cheevos.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index b9df229ac7..87517d6164 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1872,8 +1872,10 @@ static int cheevos_expr_value(cheevos_expr_t* expr) if (expr->compare_count > 1) { + unsigned j; int maximum = values[0]; - for (unsigned j = 1; j < expr->compare_count; j++) + + for (j = 1; j < expr->compare_count; j++) maximum = values[j] > maximum ? values[j] : maximum; return maximum; @@ -3171,10 +3173,12 @@ static int cheevos_iterate(coro_t* coro) badges_ctx = new_badges_ctx; - settings_t *settings = config_get_ptr(); - if (!string_is_equal(settings->arrays.menu_driver, "xmb") || - !settings->bools.cheevos_badges_enable) - CORO_RET(); + { + settings_t *settings = config_get_ptr(); + if (!string_is_equal(settings->arrays.menu_driver, "xmb") || + !settings->bools.cheevos_badges_enable) + CORO_RET(); + } CHEEVOS_VAR_CHEEVO_CURR = cheevos_locals.core.cheevos; CHEEVOS_VAR_CHEEVO_END = cheevos_locals.core.cheevos + cheevos_locals.core.count; From 32c1c3134ef79178cdfbd4742c94df980e85eca1 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:45:57 +0100 Subject: [PATCH 095/698] Fix another C89 issue --- cheevos/badges.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cheevos/badges.c b/cheevos/badges.c index 961fbc600e..5ac1112222 100644 --- a/cheevos/badges.c +++ b/cheevos/badges.c @@ -21,15 +21,16 @@ bool badge_exists(const char* filepath) void set_badge_menu_texture(badges_ctx_t * badges, int i) { + char fullpath[PATH_MAX_LENGTH]; const char * locked_suffix = (badges->badge_locked[i] == true) ? "_lock.png" : ".png"; unsigned int bufferSize = 16; + /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ char badge_file[bufferSize]; snprintf(badge_file, bufferSize, "%s", badges->badge_id_list[i]); strcat(badge_file, locked_suffix); - char fullpath[PATH_MAX_LENGTH]; fill_pathname_application_special(fullpath, PATH_MAX_LENGTH * sizeof(char), APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); From b69622ea885114491d6198a356e94f0cf6e9d28b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 16:56:33 +0100 Subject: [PATCH 096/698] Avoid usage of GLsync type --- gfx/drivers_renderchain/gl2_renderchain.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 1b246ce143..62ebde2275 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -70,7 +70,7 @@ typedef struct gl2_renderchain unsigned fence_count; - GLsync fences[MAX_FENCES]; + void *fences[MAX_FENCES]; struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; } gl2_renderchain_t; @@ -1454,7 +1454,7 @@ static void gl2_renderchain_fence_iterate( chain->fence_count--; memmove(chain->fences, chain->fences + 1, - chain->fence_count * sizeof(GLsync)); + chain->fence_count * sizeof(void*)); } } From 763e6f766c921de5cf1254a5ea333f3f29a23000 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Tue, 5 Dec 2017 16:58:20 +0100 Subject: [PATCH 097/698] Silence warning --- gfx/drivers_renderchain/gl2_renderchain.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 62ebde2275..99913d414e 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -1264,6 +1264,8 @@ static void gl2_renderchain_copy_frame( { gl_t *gl = (gl_t*)data; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + + (void)chain; #if defined(HAVE_PSGL) { From db4387bd30d6d016f88fedf02e3fad075065f6f2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 17:10:31 +0100 Subject: [PATCH 098/698] See if it's always defined this way --- gfx/drivers_renderchain/gl2_renderchain.c | 2 +- gfx/include/GL/glext.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 99913d414e..d2a4d2c3a1 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -70,7 +70,7 @@ typedef struct gl2_renderchain unsigned fence_count; - void *fences[MAX_FENCES]; + GLsync fences[MAX_FENCES]; struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; } gl2_renderchain_t; diff --git a/gfx/include/GL/glext.h b/gfx/include/GL/glext.h index 44ab7c62e1..a1381696b4 100644 --- a/gfx/include/GL/glext.h +++ b/gfx/include/GL/glext.h @@ -6220,8 +6220,8 @@ typedef uint64_t GLuint64EXT; #ifndef GL_ARB_sync typedef int64_t GLint64; typedef uint64_t GLuint64; -typedef struct __GLsync *GLsync; #endif +typedef struct __GLsync *GLsync; #ifndef GL_ARB_cl_event /* These incomplete types let us declare types compatible with OpenCL's cl_context and cl_event */ From 38b899e4d6c9f72bedc0b3541ed34b0ff55a880e Mon Sep 17 00:00:00 2001 From: Jean-Paul Mari Date: Tue, 5 Dec 2017 11:23:38 -0500 Subject: [PATCH 099/698] Added Visual Studio 2017 support The msvc-2017 is based on msvc-2015 --- .gitignore | 2 + pkg/msvc/RetroArch-msvc2017.sln | 34 ++ pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj | 379 ++++++++++++++++++ .../RetroArch-msvc2017.vcxproj.filters | 19 + 4 files changed, 434 insertions(+) create mode 100644 pkg/msvc/RetroArch-msvc2017.sln create mode 100644 pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj create mode 100644 pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters diff --git a/.gitignore b/.gitignore index ad6ea6ab19..292bff2bbd 100644 --- a/.gitignore +++ b/.gitignore @@ -102,6 +102,8 @@ obj-unix/ /pkg/msvc/Release Cg/*.lpl /pkg/msvc/Release Cg/*.cfg /pkg/msvc/*.db +/pkg/msvc/.vs +/pkg/msvc/*/.vs /pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.tlog /pkg/msvc/msvc-2010/Release Cg/RetroArc.27FF7CE1.tlog/*.lastbuildstate /pkg/msvc/msvc-2010/Release Cg/*.log diff --git a/pkg/msvc/RetroArch-msvc2017.sln b/pkg/msvc/RetroArch-msvc2017.sln new file mode 100644 index 0000000000..31c8e476ac --- /dev/null +++ b/pkg/msvc/RetroArch-msvc2017.sln @@ -0,0 +1,34 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual C++ Express 2015 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RetroArch-msvc2017", "msvc-2017\RetroArch-msvc2017.vcxproj", "{27FF7CE1-4059-4AA1-8062-FD529560FA54}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug Cg|Win32 = Debug Cg|Win32 + Debug Cg|x64 = Debug Cg|x64 + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release Cg|Win32 = Release Cg|Win32 + Release Cg|x64 = Release Cg|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.ActiveCfg = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|Win32.Build.0 = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug Cg|x64.ActiveCfg = Debug Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|Win32.Build.0 = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Debug|x64.ActiveCfg = Debug|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.ActiveCfg = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|Win32.Build.0 = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release Cg|x64.ActiveCfg = Release Cg|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.ActiveCfg = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|Win32.Build.0 = Release|Win32 + {27FF7CE1-4059-4AA1-8062-FD529560FA54}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj new file mode 100644 index 0000000000..447350a93f --- /dev/null +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -0,0 +1,379 @@ + + + + + Debug Cg + Win32 + + + Debug Cg + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release Cg + Win32 + + + Release Cg + x64 + + + Release + Win32 + + + Release + x64 + + + + {27FF7CE1-4059-4AA1-8062-FD529560FA54} + Win32Proj + RetroArchmsvc2015 + 10.0.16299.0 + + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) + AllRules.ruleset + + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + \ No newline at end of file diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters new file mode 100644 index 0000000000..0b7f0bbd44 --- /dev/null +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj.filters @@ -0,0 +1,19 @@ + + + + + + + + {9fc175c7-a869-47cf-a0ce-5447d6015ce9} + + + + + griffin + + + griffin + + + From 35ab48ee615421c666cb75f8fc9935504d530049 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 5 Dec 2017 12:47:16 -0500 Subject: [PATCH 100/698] xinput: copy VID/PID from dinput so autoconfig does not rely solely on HID name --- input/drivers_joypad/dinput_joypad.c | 23 ++++++++++++++++++++++ input/drivers_joypad/dinput_joypad.h | 29 ++++++++++++++++++++++++++++ input/drivers_joypad/xinput_joypad.c | 28 ++++++++++++++++++++------- 3 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 input/drivers_joypad/dinput_joypad.h diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index 4793d83256..403a13a56a 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -63,6 +63,29 @@ extern bool g_xinput_block_pads; extern int g_xinput_pad_indexes[MAX_USERS]; extern LPDIRECTINPUT8 g_dinput_ctx; +bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(g_xinput_pad_indexes); i++) + { + if (index == g_xinput_pad_indexes[i]) + { + RARCH_LOG("[DINPUT]: Found XInput pad at index %d (DINPUT index %d)\n", index, i); + + if (vid) + *vid = g_pads[i].vid; + + if (pid) + *pid = g_pads[i].pid; + + return true; + } + } + + return false; +} + static void dinput_joypad_destroy(void) { unsigned i; diff --git a/input/drivers_joypad/dinput_joypad.h b/input/drivers_joypad/dinput_joypad.h new file mode 100644 index 0000000000..e7705bfa30 --- /dev/null +++ b/input/drivers_joypad/dinput_joypad.h @@ -0,0 +1,29 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2016 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 __DINPUT_JOYPAD_H +#define __DINPUT_JOYPAD_H + +#include + +RETRO_BEGIN_DECLS + +bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid, int *dinput_index); + +RETRO_END_DECLS + +#endif diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index d753a889dc..17d3a42973 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -40,6 +40,12 @@ #include "../../verbosity.h" +#ifndef HAVE_DINPUT +#error Cannot compile xinput without dinput. +#endif + +#include "dinput_joypad.h" + /* Check if the definitions do not already exist. * Official and mingw xinput headers have different include guards. */ @@ -92,10 +98,6 @@ typedef struct #define ERROR_DEVICE_NOT_CONNECTED 1167 #endif -#ifndef HAVE_DINPUT -#error Cannot compile xinput without dinput. -#endif - /* Due to 360 pads showing up under both XInput and DirectInput, * and since we are going to have to pass through unhandled * joypad numbers to DirectInput, a slightly ugly @@ -270,16 +272,28 @@ static bool xinput_joypad_init(void *data) for (j = 0; j < MAX_USERS; j++) { - RARCH_LOG("[XInput]: Attempting autoconf for, user #%u\n", j); + if (xinput_joypad_name(j)) + RARCH_LOG("[XInput]: Attempting autoconf for \"%s\", user #%u\n", xinput_joypad_name(j), j); + else + RARCH_LOG("[XInput]: Attempting autoconf for user #%u\n", j); + if (pad_index_to_xuser_index(j) > -1) { + int vid = 0; + int pid = 0; + int dinput_index = 0; + bool success = dinput_joypad_get_vidpid_from_xinput_index(j, &vid, &pid, &dinput_index); + + if (success) + RARCH_LOG("[XInput]: Found VID/PID (%04X/%04X) from DINPUT index %d for \"%s\", user #%u\n", vid, pid, dinput_index, xinput_joypad_name(j), j); + if (!input_autoconfigure_connect( xinput_joypad_name(j), NULL, xinput_joypad.ident, j, - 0, - 0)) + vid, + pid)) input_config_set_device_name(j, xinput_joypad_name(j)); } } From 4c9bde61b534a0d0422e871899ca734a67c1f03f Mon Sep 17 00:00:00 2001 From: bparker06 Date: Tue, 5 Dec 2017 13:54:15 -0500 Subject: [PATCH 101/698] dinput: fix memory leak of joypad name --- input/drivers/dinput.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/drivers/dinput.c b/input/drivers/dinput.c index 9b2e14f66e..6550bec50e 100644 --- a/input/drivers/dinput.c +++ b/input/drivers/dinput.c @@ -852,7 +852,7 @@ static void dinput_free(void *data) if (di->mouse) IDirectInputDevice8_Release(di->mouse); - if (string_is_empty(di->joypad_driver_name)) + if (di->joypad_driver_name) free(di->joypad_driver_name); free(di); From 408878a7e10685a11b7956d821160c68211922fe Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 20:04:12 +0100 Subject: [PATCH 102/698] Start making it possible for xinput_joypad to be used without DirectInput --- input/drivers_joypad/xinput_joypad.c | 36 +++++++++++++++++++++------- 1 file changed, 28 insertions(+), 8 deletions(-) diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index 17d3a42973..5cc96815f6 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -40,11 +40,9 @@ #include "../../verbosity.h" -#ifndef HAVE_DINPUT -#error Cannot compile xinput without dinput. -#endif - +#ifdef HAVE_DINPUT #include "dinput_joypad.h" +#endif /* Check if the definitions do not already exist. * Official and mingw xinput headers have different include guards. @@ -159,6 +157,8 @@ static const char* const XBOX_ONE_CONTROLLER_NAMES[4] = const char *xinput_joypad_name(unsigned pad) { int xuser = pad_index_to_xuser_index(pad); + +#ifdef HAVE_DINPUT /* Use the real controller name for XBOX One controllers since they are slightly different */ if (xuser < 0) @@ -166,6 +166,7 @@ const char *xinput_joypad_name(unsigned pad) if (strstr(dinput_joypad.name(pad), "Xbox One For Windows")) return XBOX_ONE_CONTROLLER_NAMES[xuser]; +#endif return XBOX_CONTROLLER_NAMES[xuser]; } @@ -262,6 +263,7 @@ static bool xinput_joypad_init(void *data) #endif g_xinput_block_pads = true; +#ifdef HAVE_DINPUT /* We're going to have to be buddies with dinput if we want to be able * to use XInput and non-XInput controllers together. */ if (!dinput_joypad.init(data)) @@ -269,6 +271,7 @@ static bool xinput_joypad_init(void *data) g_xinput_block_pads = false; return false; } +#endif for (j = 0; j < MAX_USERS; j++) { @@ -279,13 +282,16 @@ static bool xinput_joypad_init(void *data) if (pad_index_to_xuser_index(j) > -1) { - int vid = 0; - int pid = 0; + int vid = 0; + int pid = 0; +#ifdef HAVE_DINPUT int dinput_index = 0; - bool success = dinput_joypad_get_vidpid_from_xinput_index(j, &vid, &pid, &dinput_index); + bool success = dinput_joypad_get_vidpid_from_xinput_index(j, &vid, &pid, &dinput_index); if (success) - RARCH_LOG("[XInput]: Found VID/PID (%04X/%04X) from DINPUT index %d for \"%s\", user #%u\n", vid, pid, dinput_index, xinput_joypad_name(j), j); + RARCH_LOG("[XInput]: Found VID/PID (%04X/%04X) from DINPUT index %d for \"%s\", user #%u\n", + vid, pid, dinput_index, xinput_joypad_name(j), j); +#endif if (!input_autoconfigure_connect( xinput_joypad_name(j), @@ -306,7 +312,11 @@ static bool xinput_joypad_query_pad(unsigned pad) int xuser = pad_index_to_xuser_index(pad); if (xuser > -1) return g_xinput_states[xuser].connected; +#ifdef HAVE_DINPUT return dinput_joypad.query_pad(pad); +#else + return false; +#endif } static void xinput_joypad_destroy(void) @@ -322,7 +332,9 @@ static void xinput_joypad_destroy(void) g_XInputGetStateEx = NULL; g_XInputSetState = NULL; +#ifdef HAVE_DINPUT dinput_joypad.destroy(); +#endif g_xinput_block_pads = false; } @@ -351,8 +363,10 @@ static bool xinput_joypad_button(unsigned port_num, uint16_t joykey) unsigned hat_dir = 0; int xuser = pad_index_to_xuser_index(port_num); +#ifdef HAVE_DINPUT if (xuser == -1) return dinput_joypad.button(port_num, joykey); +#endif if (!(g_xinput_states[xuser].connected)) return false; @@ -400,8 +414,10 @@ static int16_t xinput_joypad_axis (unsigned port_num, uint32_t joyaxis) xuser = pad_index_to_xuser_index(port_num); +#ifdef HAVE_DINPUT if (xuser == -1) return dinput_joypad.axis(port_num, joyaxis); +#endif if (!(g_xinput_states[xuser].connected)) return 0; @@ -469,7 +485,9 @@ static void xinput_joypad_poll(void) } } +#ifdef HAVE_DINPUT dinput_joypad.poll(); +#endif } static bool xinput_joypad_rumble(unsigned pad, @@ -479,8 +497,10 @@ static bool xinput_joypad_rumble(unsigned pad, if (xuser == -1) { +#ifdef HAVE_DINPUT if (dinput_joypad.set_rumble) return dinput_joypad.set_rumble(pad, effect, strength); +#endif return false; } From 2bdf4a5bb481f7a2f79d619750f8d8a619ba67ae Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 5 Dec 2017 20:08:18 +0100 Subject: [PATCH 103/698] update --- input/drivers_joypad/xinput_joypad.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index 5cc96815f6..e2d08929d5 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -254,13 +254,9 @@ static bool xinput_joypad_init(void *data) (!g_xinput_states[2].connected) && (!g_xinput_states[3].connected)) return false; -#if (1) - else - { - RARCH_LOG("[XInput]: Pads connected: %d\n", g_xinput_states[0].connected + - g_xinput_states[1].connected + g_xinput_states[2].connected + g_xinput_states[3].connected); - } -#endif + + RARCH_LOG("[XInput]: Pads connected: %d\n", g_xinput_states[0].connected + + g_xinput_states[1].connected + g_xinput_states[2].connected + g_xinput_states[3].connected); g_xinput_block_pads = true; #ifdef HAVE_DINPUT From bc4bbe79aa2172b0a987b0f198d21896b3cfe306 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 5 Dec 2017 14:26:41 -0500 Subject: [PATCH 104/698] don't define UNICODE at all, we don't need it and it causes dinput problems (names are wchar_t) --- gfx/drivers_context/wgl_ctx.c | 4 ---- input/drivers_joypad/dinput_joypad.c | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 64c4be8a09..39dbb26cdb 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -23,10 +23,6 @@ #define _WIN32_WINNT 0x0500 //_WIN32_WINNT_WIN2K #endif -#if !defined(_MSC_VER) || _MSC_VER > 1400 -#define UNICODE -#endif - #include #include diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index 403a13a56a..b390e315cf 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -97,7 +97,7 @@ static void dinput_joypad_destroy(void) IDirectInputDevice8_Unacquire(g_pads[i].joypad); IDirectInputDevice8_Release(g_pads[i].joypad); } - + free(g_pads[i].joy_name); g_pads[i].joy_name = NULL; free(g_pads[i].joy_friendly_name); From dbe6af08ddc39a52a3509daedb0046927399901f Mon Sep 17 00:00:00 2001 From: radius Date: Tue, 5 Dec 2017 14:28:24 -0500 Subject: [PATCH 105/698] Improve vscode support add c properties add ming32 config too rename tasks to allow other targets --- .vscode/c_cpp_properties.json | 125 ++++++++++++++++++++++++++++++++++ .vscode/launch.json | 22 +++++- .vscode/tasks.json | 10 +-- 3 files changed, 151 insertions(+), 6 deletions(-) create mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000..81c2529184 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,125 @@ +{ + "configurations": [ + { + "name": "Mac", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + }, + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ] + }, + { + "name": "Linux", + "includePath": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "defines": [], + "intelliSenseMode": "clang-x64", + "browse": { + "path": [ + "/usr/include", + "/usr/local/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "Win32", + "includePath": [ + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/um", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/ucrt", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/shared", + "C:/Program Files (x86)/Windows Kits/10/Include/10.0.15063.0/winrt", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "msys2-mingw32", + "includePath": [ + "C:/msys64/mingw32/include", + "C:/msys64/mingw32/i686-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/msys64/mingw32/include", + "C:/msys64/mingw32/i686-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + }, + { + "name": "msys2-mingw64", + "includePath": [ + "C:/msys64/mingw64/include", + "C:/msys64/mingw64/x86_64-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "defines": [ + "_DEBUG", + "UNICODE" + ], + "intelliSenseMode": "msvc-x64", + "browse": { + "path": [ + "C:/msys64/mingw64/include", + "C:/msys64/mingw64/x86_64-w64-mingw32/include", + "${workspaceRoot}/libretro-common/include", + "${workspaceRoot}/include", + "${workspaceRoot}" + ], + "limitSymbolsToIncludedHeaders": true, + "databaseFilename": "" + } + } + ], + "version": 3 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 53837e538f..6e1f69631a 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,7 +5,7 @@ "version": "0.2.0", "configurations": [ { - "name": "MINGW64 (MSYS2) debug", + "name": "msys2-mingw64 debug", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/retroarch.exe", @@ -23,6 +23,26 @@ "ignoreFailures": true } ] + }, + { + "name": "msys2-mingw32 debug", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}/retroarch.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": true, + "MIMode": "gdb", + "miDebuggerPath": "c:\\msys64\\mingw32\\bin\\gdb.exe", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 496810ecfa..b271c66e8f 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ "version": "2.0.0", "tasks": [ { - "taskName": "Build", + "taskName": "msys2-mingw64 build", "type": "shell", "group": { @@ -22,7 +22,7 @@ } } { - "taskName": "Build with debugging symbols", + "taskName": "msys2-mingw64 build with debug symbols", "type": "shell", "group": "build", @@ -38,7 +38,7 @@ } } { - "taskName": "Build without reconfiguring", + "taskName": "msys2-mingw64 rebuild", "type": "shell", "group": "build", @@ -54,7 +54,7 @@ } } { - "taskName": "Clean", + "taskName": "msys2-mingw64 clean", "type": "shell", "group": "build", @@ -70,7 +70,7 @@ } } { - "taskName": "Start", + "taskName": "msys2-mingw64 run", "type": "shell", "group": { From 6bb2a0e14266bb363fd72c761020f134706b7335 Mon Sep 17 00:00:00 2001 From: ToKe79 Date: Tue, 5 Dec 2017 21:58:01 +0100 Subject: [PATCH 106/698] GLsync build fix for HAVE_OPENGLES2 --- gfx/drivers_renderchain/gl2_renderchain.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index d2a4d2c3a1..81a6f9ff78 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -53,6 +53,12 @@ #define MAX_FENCES 4 +#ifndef HAVE_PSGL +#if defined(HAVE_OPENGLES2) + typedef struct __GLsync *GLsync; +#endif +#endif + typedef struct gl2_renderchain { bool egl_images; From 0d189ae0670efe77c694427d25518970eda44a4e Mon Sep 17 00:00:00 2001 From: David Walters Date: Tue, 5 Dec 2017 21:21:29 +0000 Subject: [PATCH 107/698] Don't limit available input devices to user count. --- input/input_defines.h | 2 ++ input/input_driver.c | 14 +++++++++++++- input/input_driver.h | 2 ++ menu/menu_setting.c | 14 +++++++------- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/input/input_defines.h b/input/input_defines.h index b005e90f58..3255a85180 100644 --- a/input/input_defines.h +++ b/input/input_defines.h @@ -26,6 +26,8 @@ RETRO_BEGIN_DECLS #define MAX_USERS 16 +#define MAX_INPUT_DEVICES 16 + #define RARCH_FIRST_CUSTOM_BIND 16 #define RARCH_FIRST_LIGHTGUN_BIND RARCH_ANALOG_BIND_LIST_END #define RARCH_FIRST_MISC_CUSTOM_BIND RARCH_LIGHTGUN_BIND_LIST_END diff --git a/input/input_driver.c b/input/input_driver.c index d17fb5fc61..59ca11e205 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -233,7 +233,7 @@ static const uint8_t buttons[] = { static uint16_t input_config_vid[MAX_USERS]; static uint16_t input_config_pid[MAX_USERS]; -char input_device_names[MAX_USERS][64]; +char input_device_names[MAX_INPUT_DEVICES][64]; struct retro_keybind input_config_binds[MAX_USERS][RARCH_BIND_LIST_END]; struct retro_keybind input_autoconf_binds[MAX_USERS][RARCH_BIND_LIST_END]; const struct retro_keybind *libretro_input_binds[MAX_USERS]; @@ -2691,6 +2691,18 @@ void input_config_get_bind_string(char *buf, const struct retro_keybind *bind, strlcat(buf, "---", size); } +unsigned input_config_get_device_count() +{ + unsigned num_devices; + for ( num_devices = 0; num_devices < MAX_INPUT_DEVICES; ++num_devices ) + { + const char *device_name = input_config_get_device_name(num_devices); + if ( string_is_empty(device_name) ) + break; + } + return num_devices; +} + const char *input_config_get_device_name(unsigned port) { if (string_is_empty(input_device_names[port])) diff --git a/input/input_driver.h b/input/input_driver.h index 3222237a41..1f7b711917 100644 --- a/input/input_driver.h +++ b/input/input_driver.h @@ -761,6 +761,8 @@ void input_config_set_device_name(unsigned port, const char *name); void input_config_clear_device_name(unsigned port); +unsigned input_config_get_device_count(); + unsigned *input_config_get_device_ptr(unsigned port); unsigned input_config_get_device(unsigned port); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 86cca1a42a..112ce021f5 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1305,7 +1305,7 @@ static int setting_action_left_bind_device(void *data, bool wraparound) { unsigned index_offset; unsigned *p = NULL; - unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + unsigned max_devices = input_config_get_device_count(); rarch_setting_t *setting = (rarch_setting_t*)data; settings_t *settings = config_get_ptr(); @@ -1316,8 +1316,8 @@ static int setting_action_left_bind_device(void *data, bool wraparound) p = &settings->uints.input_joypad_map[index_offset]; - if ((*p) >= max_users) - *p = max_users - 1; + if ((*p) >= max_devices) + *p = max_devices - 1; else if ((*p) > 0) (*p)--; @@ -1328,7 +1328,7 @@ static int setting_action_right_bind_device(void *data, bool wraparound) { unsigned index_offset; unsigned *p = NULL; - unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + unsigned max_devices = input_config_get_device_count(); rarch_setting_t *setting = (rarch_setting_t*)data; settings_t *settings = config_get_ptr(); @@ -1339,7 +1339,7 @@ static int setting_action_right_bind_device(void *data, bool wraparound) p = &settings->uints.input_joypad_map[index_offset]; - if (*p < max_users) + if (*p < max_devices) (*p)++; return 0; @@ -1497,7 +1497,7 @@ static void get_string_representation_bind_device(void * data, char *s, size_t len) { unsigned index_offset, map = 0; - unsigned max_users = *(input_driver_get_uint(INPUT_ACTION_MAX_USERS)); + unsigned max_devices = input_config_get_device_count(); rarch_setting_t *setting = (rarch_setting_t*)data; settings_t *settings = config_get_ptr(); @@ -1507,7 +1507,7 @@ static void get_string_representation_bind_device(void * data, char *s, index_offset = setting->index_offset; map = settings->uints.input_joypad_map[index_offset]; - if (map < max_users) + if (map < max_devices) { const char *device_name = input_config_get_device_name(map); From 609bcb4dc209f0fa8273ca11d544588c20a00a2a Mon Sep 17 00:00:00 2001 From: David Walters Date: Tue, 5 Dec 2017 22:03:56 +0000 Subject: [PATCH 108/698] fix device indexing --- input/input_driver.c | 5 +++++ tasks/task_autodetect.c | 48 ++++++++++++++++++++++++++--------------- tasks/tasks_internal.h | 2 ++ 3 files changed, 38 insertions(+), 17 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 59ca11e205..0866d5e890 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -2713,14 +2713,19 @@ const char *input_config_get_device_name(unsigned port) void input_config_set_device_name(unsigned port, const char *name) { if (!string_is_empty(name)) + { strlcpy(input_device_names[port], name, sizeof(input_device_names[port])); + + input_autoconfigure_joypad_reindex_devices(); + } } void input_config_clear_device_name(unsigned port) { input_device_names[port][0] = '\0'; + input_autoconfigure_joypad_reindex_devices(); } unsigned *input_config_get_device_ptr(unsigned port) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index 66080478f8..be8e9ee4ed 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -96,7 +96,7 @@ struct autoconfig_params }; static bool input_autoconfigured[MAX_USERS]; -static unsigned input_device_name_index[MAX_USERS]; +static unsigned input_device_name_index[MAX_INPUT_DEVICES]; static bool input_autoconfigure_swap_override; bool input_autoconfigure_get_swap_override(void) @@ -106,24 +106,38 @@ bool input_autoconfigure_get_swap_override(void) /* Adds an index for devices with the same name, * so they can be identified in the GUI. */ -static void input_autoconfigure_joypad_reindex_devices(autoconfig_params_t *params) +void input_autoconfigure_joypad_reindex_devices() { - unsigned i; + unsigned i, j, k; - for(i = 0; i < params->max_users; i++) + for(i = 0; i < MAX_INPUT_DEVICES; i++) input_device_name_index[i] = 0; - for(i = 0; i < params->max_users; i++) + for(i = 0; i < MAX_INPUT_DEVICES; i++) { - unsigned j; const char *tmp = input_config_get_device_name(i); - int k = 1; + if ( !tmp || input_device_name_index[i] ) + continue; - for(j = 0; j < params->max_users; j++) + k = 2; /*Additional devices start at two*/ + + for(j = i+1; j < MAX_INPUT_DEVICES; j++) { - if(string_is_equal(tmp, input_config_get_device_name(j)) - && input_device_name_index[i] == 0) + const char *other = input_config_get_device_name(j); + + if (!other) + continue; + + /*another device with the same name found, for the first time*/ + if(string_is_equal(tmp, other) && + input_device_name_index[j]==0 ) + { + /*Mark the first device of the set*/ + input_device_name_index[i] = 1; + + /*count this additional device, from two up*/ input_device_name_index[j] = k++; + } } } } @@ -190,7 +204,7 @@ static void input_autoconfigure_joypad_add(config_file_t *conf, char msg[128], display_name[128], device_type[128]; /* This will be the case if input driver is reinitialized. * No reason to spam autoconfigure messages every time. */ - bool block_osd_spam = + bool block_osd_spam = input_autoconfigured[params->idx] && !string_is_empty(params->name); @@ -228,7 +242,7 @@ static void input_autoconfigure_joypad_add(config_file_t *conf, bool tmp = false; snprintf(msg, sizeof(msg), "%s %s #%u.", (string_is_empty(display_name) && - !string_is_empty(params->name)) + !string_is_empty(params->name)) ? params->name : (!string_is_empty(display_name) ? display_name : "N/A"), msg_hash_to_str(MSG_DEVICE_CONFIGURED_IN_PORT), params->idx); @@ -250,7 +264,7 @@ static void input_autoconfigure_joypad_add(config_file_t *conf, } - input_autoconfigure_joypad_reindex_devices(params); + input_autoconfigure_joypad_reindex_devices(); } static int input_autoconfigure_joypad_from_conf( @@ -393,7 +407,7 @@ static const blissbox_pad_type_t* input_autoconfigure_get_blissbox_pad_type_win3 BOOL bResult = TRUE; BOOL success = FALSE; GUID guidDeviceInterface = {0}; - PSP_DEVICE_INTERFACE_DETAIL_DATA + PSP_DEVICE_INTERFACE_DETAIL_DATA pInterfaceDetailData = NULL; ULONG requiredLength = 0; LPTSTR lpDevicePath = NULL; @@ -845,7 +859,7 @@ bool input_autoconfigure_disconnect(unsigned i, const char *ident) state->idx = i; - snprintf(msg, sizeof(msg), "%s #%u (%s).", + snprintf(msg, sizeof(msg), "%s #%u (%s).", msg_hash_to_str(MSG_DEVICE_DISCONNECTED_FROM_PORT), i, ident); @@ -942,10 +956,10 @@ bool input_autoconfigure_connect( { input_autoconf_binds[state->idx][i].joykey = NO_BTN; input_autoconf_binds[state->idx][i].joyaxis = AXIS_NONE; - if ( + if ( !string_is_empty(input_autoconf_binds[state->idx][i].joykey_label)) free(input_autoconf_binds[state->idx][i].joykey_label); - if ( + if ( !string_is_empty(input_autoconf_binds[state->idx][i].joyaxis_label)) free(input_autoconf_binds[state->idx][i].joyaxis_label); input_autoconf_binds[state->idx][i].joykey_label = NULL; diff --git a/tasks/tasks_internal.h b/tasks/tasks_internal.h index bf32504ef0..dc5c160b52 100644 --- a/tasks/tasks_internal.h +++ b/tasks/tasks_internal.h @@ -245,6 +245,8 @@ bool input_autoconfigure_disconnect(unsigned i, const char *ident); bool input_autoconfigure_get_swap_override(void); +void input_autoconfigure_joypad_reindex_devices(void); + void task_push_get_powerstate(void); enum frontend_powerstate get_last_powerstate(int *percent); From 8907a1251ee8f50a3fcfc071cc5bb6955d7dabe6 Mon Sep 17 00:00:00 2001 From: David Walters Date: Tue, 5 Dec 2017 22:10:34 +0000 Subject: [PATCH 109/698] Only show " (#x)" after a device name if it's part of a set (x of y similarly named devices) --- menu/menu_setting.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 112ce021f5..31d1d618b8 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1512,16 +1512,32 @@ static void get_string_representation_bind_device(void * data, char *s, const char *device_name = input_config_get_device_name(map); if (!string_is_empty(device_name)) - snprintf(s, len, - "%s (#%u)", - device_name, - input_autoconfigure_get_device_name_index(map)); + { + unsigned idx = input_autoconfigure_get_device_name_index(map); + + /*if idx is non-zero, it's part of a set*/ + if ( idx > 0 ) + { + snprintf(s, len, + "%s (#%u)", + device_name, + idx); + } + else + { + snprintf(s, len, + "%s", + device_name); + } + } else + { snprintf(s, len, "%s (%s #%u)", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), msg_hash_to_str(MENU_ENUM_LABEL_VALUE_PORT), map); + } } else strlcpy(s, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_DISABLED), len); From f5ea4a0c65edbf83b15e699524db8f8462ced776 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Tue, 5 Dec 2017 17:19:17 -0500 Subject: [PATCH 110/698] dinput: add missing function parameter --- input/drivers_joypad/dinput_joypad.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index b390e315cf..1a9f6325eb 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -63,7 +63,7 @@ extern bool g_xinput_block_pads; extern int g_xinput_pad_indexes[MAX_USERS]; extern LPDIRECTINPUT8 g_dinput_ctx; -bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid) +bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid, int *dinput_index) { int i; @@ -79,6 +79,9 @@ bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid) if (pid) *pid = g_pads[i].pid; + if (dinput_index) + *dinput_index = i; + return true; } } From 27e5adad27214715f1d363360630b632122e7168 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 04:05:38 +0100 Subject: [PATCH 111/698] Cleanups --- menu/cbs/menu_cbs_deferred_push.c | 63 +++++++++---------------------- 1 file changed, 18 insertions(+), 45 deletions(-) diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 9a93e60dda..4040f46aa3 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -559,56 +559,29 @@ static int general_push(menu_displaylist_info_t *info, return deferred_push_dlist(info, state); } -static int deferred_push_detect_core_list(menu_displaylist_info_t *info) -{ - return general_push(info, PUSH_DETECT_CORE_LIST, - DISPLAYLIST_CORES_DETECTED); +#define generic_deferred_push_general(name, a, b) \ +static int (name)(menu_displaylist_info_t *info) \ +{ \ + return general_push(info, a, b); \ } -static int deferred_playlist_list(menu_displaylist_info_t *info) -{ - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_PLAYLIST); +#define generic_deferred_push_clear_general(name, a, b) \ +static int (name)(menu_displaylist_info_t *info) \ +{ \ + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); \ + return general_push(info, a, b); \ } -static int deferred_music_history_list(menu_displaylist_info_t *info) -{ - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_MUSIC_HISTORY); -} +generic_deferred_push_general(deferred_push_detect_core_list, PUSH_DETECT_CORE_LIST, DISPLAYLIST_CORES_DETECTED) +generic_deferred_push_general(deferred_archive_open_detect_core, PUSH_ARCHIVE_OPEN_DETECT_CORE, DISPLAYLIST_DEFAULT) +generic_deferred_push_general(deferred_archive_open, PUSH_ARCHIVE_OPEN, DISPLAYLIST_DEFAULT) +generic_deferred_push_general(deferred_push_default, PUSH_DEFAULT, DISPLAYLIST_DEFAULT) +generic_deferred_push_general(deferred_push_favorites_list, PUSH_DEFAULT, DISPLAYLIST_FAVORITES) -static int deferred_image_history_list(menu_displaylist_info_t *info) -{ - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_IMAGES_HISTORY); -} - -static int deferred_video_history_list(menu_displaylist_info_t *info) -{ - menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_VIDEO_HISTORY); -} - -static int deferred_archive_open_detect_core(menu_displaylist_info_t *info) -{ - return general_push(info, PUSH_ARCHIVE_OPEN_DETECT_CORE, - DISPLAYLIST_DEFAULT); -} - -static int deferred_archive_open(menu_displaylist_info_t *info) -{ - return general_push(info, PUSH_ARCHIVE_OPEN, DISPLAYLIST_DEFAULT); -} - -static int deferred_push_default(menu_displaylist_info_t *info) -{ - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_DEFAULT); -} - -static int deferred_push_favorites_list(menu_displaylist_info_t *info) -{ - return general_push(info, PUSH_DEFAULT, DISPLAYLIST_FAVORITES); -} +generic_deferred_push_clear_general(deferred_playlist_list, PUSH_DEFAULT, DISPLAYLIST_PLAYLIST) +generic_deferred_push_clear_general(deferred_music_history_list, PUSH_DEFAULT, DISPLAYLIST_MUSIC_HISTORY) +generic_deferred_push_clear_general(deferred_image_history_list, PUSH_DEFAULT, DISPLAYLIST_IMAGES_HISTORY) +generic_deferred_push_clear_general(deferred_video_history_list, PUSH_DEFAULT, DISPLAYLIST_VIDEO_HISTORY) static int menu_cbs_init_bind_deferred_push_compare_label( menu_file_list_cbs_t *cbs, From 0c9fce98a26edf933f079198df3346c0ba5fbe37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Tue, 5 Dec 2017 22:07:48 -0500 Subject: [PATCH 112/698] fix vid/pid enumeration on xinput controllers when the xinput controllers are interleaved with dinput (#5872) --- input/drivers_joypad/xinput_joypad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index e2d08929d5..524d461160 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -282,7 +282,7 @@ static bool xinput_joypad_init(void *data) int pid = 0; #ifdef HAVE_DINPUT int dinput_index = 0; - bool success = dinput_joypad_get_vidpid_from_xinput_index(j, &vid, &pid, &dinput_index); + bool success = dinput_joypad_get_vidpid_from_xinput_index(pad_index_to_xuser_index(j), &vid, &pid, &dinput_index); if (success) RARCH_LOG("[XInput]: Found VID/PID (%04X/%04X) from DINPUT index %d for \"%s\", user #%u\n", From de9b0127f87c51e0a9bc517334348c48770a85cc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 04:33:54 +0100 Subject: [PATCH 113/698] (MSVC) Buildfix --- input/drivers_joypad/dinput_joypad.c | 3 ++- input/drivers_joypad/dinput_joypad.h | 4 +++- input/drivers_joypad/xinput_joypad.c | 9 +++++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index 1a9f6325eb..b04e739790 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -34,6 +34,7 @@ #include "../input_driver.h" #include "../input_keymaps.h" #include "../../verbosity.h" +#include "dinput_joypad.h" struct dinput_joypad { @@ -63,7 +64,7 @@ extern bool g_xinput_block_pads; extern int g_xinput_pad_indexes[MAX_USERS]; extern LPDIRECTINPUT8 g_dinput_ctx; -bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid, int *dinput_index) +bool dinput_joypad_get_vidpid_from_xinput_index(int32_t index, int32_t *vid, int32_t *pid, int32_t *dinput_index) { int i; diff --git a/input/drivers_joypad/dinput_joypad.h b/input/drivers_joypad/dinput_joypad.h index e7705bfa30..12d491f3b9 100644 --- a/input/drivers_joypad/dinput_joypad.h +++ b/input/drivers_joypad/dinput_joypad.h @@ -18,11 +18,13 @@ #ifndef __DINPUT_JOYPAD_H #define __DINPUT_JOYPAD_H +#include +#include #include RETRO_BEGIN_DECLS -bool dinput_joypad_get_vidpid_from_xinput_index(int index, int *vid, int *pid, int *dinput_index); +bool dinput_joypad_get_vidpid_from_xinput_index(int32_t index, int32_t *vid, int32_t *pid, int32_t *dinput_index); RETRO_END_DECLS diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index 524d461160..f7eb8bd347 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -278,11 +278,12 @@ static bool xinput_joypad_init(void *data) if (pad_index_to_xuser_index(j) > -1) { - int vid = 0; - int pid = 0; + int32_t vid = 0; + int32_t pid = 0; #ifdef HAVE_DINPUT - int dinput_index = 0; - bool success = dinput_joypad_get_vidpid_from_xinput_index(pad_index_to_xuser_index(j), &vid, &pid, &dinput_index); + int32_t dinput_index = 0; + bool success = dinput_joypad_get_vidpid_from_xinput_index((int32_t)pad_index_to_xuser_index(j), (int32_t*)&vid, (int32_t*)&pid, + (int32_t*)&dinput_index); if (success) RARCH_LOG("[XInput]: Found VID/PID (%04X/%04X) from DINPUT index %d for \"%s\", user #%u\n", From 24b02bc06213252510b1e3845d6adac0929443ba Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 04:52:51 +0100 Subject: [PATCH 114/698] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 9a962e0dcf..bb2dfb3d35 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -16,6 +16,7 @@ - OSX/PPC: Fix the GL2 renderchain, had to use EXT versions of framebuffer/renderbuffer functions. - SCANNER: Fix crash from Windows-incompatible format string. - WIIU: Disabled the controller patcher for now since it was the source of many stability issues. +- WINDOWS: Add MSVC 2017 solution. - WINDOWS: Raw input driver now supports new lightgun code. # 1.6.9 From 21dc6500003901994eac5671f190ae33a15bb690 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 6 Dec 2017 00:57:35 -0500 Subject: [PATCH 115/698] update JP translation --- intl/msg_hash_ja.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index c1087e8ede..ec16dabcc3 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -438,6 +438,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_HARDCORE_MODE_ENABLE, "ハードコアモード" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_LEADERBOARDS_ENABLE, + "ランキング" + ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_BADGES_ENABLE, + "実績バッジ" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_LOCKED_ACHIEVEMENTS, "解除された実績:" @@ -466,6 +474,10 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY, "解除されている" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_CHEEVOS_UNLOCKED_ENTRY_HARDCORE, + "解除されている(ハードコア)" + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_CLOSE_CONTENT, "閉じる" @@ -2514,6 +2526,8 @@ MSG_HASH( ) MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_BOKEH, "ボケ") +MSG_HASH(MENU_ENUM_LABEL_VALUE_SHADER_PIPELINE_SNOWFLAKE, + "スノーフレーク") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_REFRESH_ROOMS, "ルーム表を更新") MSG_HASH(MENU_ENUM_LABEL_VALUE_NETPLAY_ROOM_NICKNAME, From 1828e891ad98155da724c1712d4c1f9c0917e769 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 6 Dec 2017 00:57:57 -0500 Subject: [PATCH 116/698] Update CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index bb2dfb3d35..570c2afade 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -11,6 +11,7 @@ - LINUX/X11: Add RetroArch logo to window title bar. - LINUX/X11: Input driver now supports new lightgun code. - LOCALIZATION: Update Italian translation. +- LOCALIZATION: Update Japanese translation. - LOCALIZATION: Update Portuguese-Brazilian translation. - LOCALIZATION: Update Russian translation. - OSX/PPC: Fix the GL2 renderchain, had to use EXT versions of framebuffer/renderbuffer functions. From 75eed7997b6ca2742bdd1ee8e6a7a58e153eefaa Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 6 Dec 2017 01:41:00 -0500 Subject: [PATCH 117/698] GDI: use configured message color for OSD/menu text --- gfx/drivers_font/gdi_font.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gfx/drivers_font/gdi_font.c b/gfx/drivers_font/gdi_font.c index c89eb99df9..177b38b2bf 100644 --- a/gfx/drivers_font/gdi_font.c +++ b/gfx/drivers_font/gdi_font.c @@ -91,6 +91,9 @@ static void gdi_render_msg( const struct font_params *params = (const struct font_params*)userdata; unsigned width = video_info->width; unsigned height = video_info->height; + unsigned red; + unsigned green; + unsigned blue; if (!font || string_is_empty(msg)) return; @@ -101,6 +104,9 @@ static void gdi_render_msg( y = params->y; scale = params->scale; align = params->text_align; + red = FONT_COLOR_GET_RED(params->color); + green = FONT_COLOR_GET_GREEN(params->color); + blue = FONT_COLOR_GET_BLUE(params->color); } else { @@ -108,6 +114,9 @@ static void gdi_render_msg( y = video_info->font_msg_pos_y; scale = 1.0f; align = TEXT_ALIGN_LEFT; + red = video_info->font_msg_color_r * 255.0f; + green = video_info->font_msg_color_g * 255.0f; + blue = video_info->font_msg_color_b * 255.0f; } if (!font->gdi) @@ -135,7 +144,7 @@ static void gdi_render_msg( font->gdi->bmp_old = (HBITMAP)SelectObject(font->gdi->memDC, font->gdi->bmp); SetBkMode(font->gdi->memDC, TRANSPARENT); - SetTextColor(font->gdi->memDC, RGB(255,255,255)); + SetTextColor(font->gdi->memDC, RGB(red, green, blue)); TextOut(font->gdi->memDC, newX, newY, msg, len); SelectObject(font->gdi->memDC, font->gdi->bmp_old); } From 1755cdcdf356b627a8ad4c78db4f8dcbdfa6717e Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Wed, 6 Dec 2017 01:41:06 -0500 Subject: [PATCH 118/698] Update CHANGES.md --- CHANGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 570c2afade..dfa858dfe6 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,7 @@ - COMMON: Fixed some playlist bugs. - FREEBSD: Support libusb HID input driver. - HAIKU: Buildfix. +- INPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names - LINUX/X11: Add RetroArch logo to window title bar. - LINUX/X11: Input driver now supports new lightgun code. - LOCALIZATION: Update Italian translation. @@ -19,6 +20,7 @@ - WIIU: Disabled the controller patcher for now since it was the source of many stability issues. - WINDOWS: Add MSVC 2017 solution. - WINDOWS: Raw input driver now supports new lightgun code. +- WINDOWS: Use configured OSD/text message color on GDI driver. # 1.6.9 - COMMON: Small memory leak. From 0cd5b9d14cddadabfbd872fccac5fd438891f902 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 12:04:04 +0100 Subject: [PATCH 119/698] Update CHANGES.md --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index dfa858dfe6..8a96ac498c 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,6 @@ - COMMON: Fixed some playlist bugs. - FREEBSD: Support libusb HID input driver. - HAIKU: Buildfix. -- INPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names - LINUX/X11: Add RetroArch logo to window title bar. - LINUX/X11: Input driver now supports new lightgun code. - LOCALIZATION: Update Italian translation. @@ -21,6 +20,7 @@ - WINDOWS: Add MSVC 2017 solution. - WINDOWS: Raw input driver now supports new lightgun code. - WINDOWS: Use configured OSD/text message color on GDI driver. +- WINDOWS/XINPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names # 1.6.9 - COMMON: Small memory leak. From 47a19483d15c9624509ac7863a068d825dd060e5 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 12:43:02 +0100 Subject: [PATCH 120/698] Don't show Overlay Settings if HAVE_OVERLAY is not defined --- menu/menu_displaylist.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index b42384394d..051f17d62a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5205,8 +5205,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) break; case DISPLAYLIST_ONSCREEN_DISPLAY_SETTINGS_LIST: menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); +#ifdef HAVE_OVERLAY menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ONSCREEN_OVERLAY_SETTINGS, PARSE_ACTION, false); +#endif menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_ONSCREEN_NOTIFICATIONS_SETTINGS, PARSE_ACTION, false); From 30eb7f91b4c91a4f49a4b5d1ccb5b87d802ec2fb Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 14:25:41 +0100 Subject: [PATCH 121/698] Fix Coverity warning --- menu/cbs/menu_cbs_ok.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index dedf26bd8e..006fe6d43f 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -1633,7 +1633,7 @@ static int action_ok_playlist_entry(const char *path, NULL, new_core_path); } - else + else if (!string_is_empty(core_path)) strlcpy(new_core_path, core_path, sizeof(new_core_path)); playlist_info.data = playlist; @@ -1651,7 +1651,8 @@ static int action_ok_playlist_entry(const char *path, playlist_info.idx, &path, NULL, NULL, NULL, NULL, NULL); - return default_action_ok_load_content_from_playlist_from_menu(new_core_path, path, entry_label); + return default_action_ok_load_content_from_playlist_from_menu( + new_core_path, path, entry_label); } static int action_ok_playlist_entry_start_content(const char *path, From 06a948c706dc8dab3a164a3fcdedb41de05a70b7 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 14:27:14 +0100 Subject: [PATCH 122/698] Update --- deps/stb/stb_vorbis.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/stb/stb_vorbis.h b/deps/stb/stb_vorbis.h index fd27e6eedc..f662695711 100644 --- a/deps/stb/stb_vorbis.h +++ b/deps/stb/stb_vorbis.h @@ -2497,7 +2497,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start, for (i=0; i < map->submaps; ++i) { float *residue_buffers[STB_VORBIS_MAX_CHANNELS]; int r; - uint8_t do_not_decode[256]; + uint8_t do_not_decode[256] = {0}; int ch = 0; for (j=0; j < f->channels; ++j) { if (map->chan[j].mux == i) { From a53927c5aad8675434b8f6f72d9e8be318b5ec57 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 16:53:19 +0100 Subject: [PATCH 123/698] Fix PS3 build --- gfx/drivers_renderchain/gl2_renderchain.c | 17 +++++++++++++++-- libretro-common/net/net_compat.c | 2 +- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 81a6f9ff78..9981c7996c 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -53,9 +53,13 @@ #define MAX_FENCES 4 -#ifndef HAVE_PSGL +#if !defined(HAVE_PSGL) +#define HAVE_GL_SYNC +#endif + +#ifdef HAVE_GL_SYNC #if defined(HAVE_OPENGLES2) - typedef struct __GLsync *GLsync; +typedef struct __GLsync *GLsync; #endif #endif @@ -76,7 +80,9 @@ typedef struct gl2_renderchain unsigned fence_count; +#ifdef HAVE_GL_SYNC GLsync fences[MAX_FENCES]; +#endif struct gfx_fbo_scale fbo_scale[GFX_MAX_SHADERS]; } gl2_renderchain_t; @@ -1449,6 +1455,7 @@ static void gl2_renderchain_fence_iterate( void *chain_data, unsigned hard_sync_frames) { +#ifdef HAVE_GL_SYNC gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; chain->fences[chain->fence_count++] = @@ -1464,11 +1471,13 @@ static void gl2_renderchain_fence_iterate( memmove(chain->fences, chain->fences + 1, chain->fence_count * sizeof(void*)); } +#endif } static void gl2_renderchain_fence_free(void *data, void *chain_data) { +#ifdef HAVE_GL_SYNC unsigned i; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; @@ -1479,6 +1488,7 @@ static void gl2_renderchain_fence_free(void *data, glDeleteSync(chain->fences[i]); } chain->fence_count = 0; +#endif } #endif @@ -1489,6 +1499,9 @@ static void gl2_renderchain_init_textures_reference( { gl_t *gl = (gl_t*)data; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; + + (void)chain; + #ifdef HAVE_PSGL glTextureReferenceSCE(GL_TEXTURE_2D, 1, gl->tex_w, gl->tex_h, 0, diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index d9de1d8ceb..614a2a8228 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -525,7 +525,7 @@ const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt) { #if defined(VITA) || defined(__ORBIS__) return sceNetInetNtop(af,src,dst,cnt); -#elif defined(WIIU) +#elif defined(WIIU) || defined(__CELLOS_LV2__) return inet_ntop(af, src, dst, cnt); #elif defined(_XBOX) return isockaddr_ntop(af, src, dst, cnt); From 23e6f0be3700aa3d61ab2c6749bba2da05b95488 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 16:54:23 +0100 Subject: [PATCH 124/698] Update --- libretro-common/net/net_compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index 614a2a8228..d9de1d8ceb 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -525,7 +525,7 @@ const char *inet_ntop_compat(int af, const void *src, char *dst, socklen_t cnt) { #if defined(VITA) || defined(__ORBIS__) return sceNetInetNtop(af,src,dst,cnt); -#elif defined(WIIU) || defined(__CELLOS_LV2__) +#elif defined(WIIU) return inet_ntop(af, src, dst, cnt); #elif defined(_XBOX) return isockaddr_ntop(af, src, dst, cnt); From b1f1f519d5bf4a7118ef54bb62267ef98f87003e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 18:28:57 +0100 Subject: [PATCH 125/698] Don't redefine HAVE_GL_SYNC --- gfx/drivers_renderchain/gl2_renderchain.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 9981c7996c..9f4a14fb07 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -54,9 +54,13 @@ #define MAX_FENCES 4 #if !defined(HAVE_PSGL) + +#ifndef HAVE_GL_SYNC #define HAVE_GL_SYNC #endif +#endif + #ifdef HAVE_GL_SYNC #if defined(HAVE_OPENGLES2) typedef struct __GLsync *GLsync; From d5b3104cfb121dbab04f5a0c3a1e64a0f4046f87 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 19:51:07 +0100 Subject: [PATCH 126/698] Cleanups/warning fixes --- gfx/common/vulkan_common.c | 3 +- gfx/drivers_font/vulkan_raster_font.c | 10 +- menu/drivers_display/menu_display_vulkan.c | 7 +- pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj | 762 +++++++++--------- 4 files changed, 394 insertions(+), 388 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 461e61131e..553655372f 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -1398,7 +1398,6 @@ static bool vulkan_context_init_device(gfx_ctx_vulkan_data_t *vk) { bool use_device_ext; uint32_t queue_count; - VkResult res; unsigned i; static const float one = 1.0f; bool found_queue = false; diff --git a/gfx/drivers_font/vulkan_raster_font.c b/gfx/drivers_font/vulkan_raster_font.c index 5897637f12..c76910b500 100644 --- a/gfx/drivers_font/vulkan_raster_font.c +++ b/gfx/drivers_font/vulkan_raster_font.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * * RetroArch is free software: you can redistribute it and/or modify it under the terms @@ -107,11 +107,11 @@ static INLINE void vulkan_raster_font_update_glyph(vulkan_raster_t *font, const { if(font->atlas->dirty) { - int row; - for(row = glyph->atlas_offset_y; row < (glyph->atlas_offset_y + glyph->height); row++) + unsigned row; + for (row = glyph->atlas_offset_y; row < (glyph->atlas_offset_y + glyph->height); row++) { - uint8_t* src = font->atlas->buffer + row * font->atlas->width + glyph->atlas_offset_x; - uint8_t* dst = (uint8_t*)font->texture.mapped + row * font->texture.stride + glyph->atlas_offset_x; + uint8_t *src = font->atlas->buffer + row * font->atlas->width + glyph->atlas_offset_x; + uint8_t *dst = (uint8_t*)font->texture.mapped + row * font->texture.stride + glyph->atlas_offset_x; memcpy(dst, src, glyph->width); } diff --git a/menu/drivers_display/menu_display_vulkan.c b/menu/drivers_display/menu_display_vulkan.c index 385ca402a8..0e7bf488d9 100644 --- a/menu/drivers_display/menu_display_vulkan.c +++ b/menu/drivers_display/menu_display_vulkan.c @@ -1,4 +1,4 @@ -/* RetroArch - A frontend for libretro. +/* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * @@ -328,7 +328,10 @@ static bool menu_display_vk_font_init_first( is_threaded, FONT_DRIVER_RENDER_VULKAN_API); - return *handle; + if (*handle) + return true; + + return false; } menu_display_ctx_driver_t menu_display_ctx_vulkan = { diff --git a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj index 447350a93f..5b77affb19 100644 --- a/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj +++ b/pkg/msvc/msvc-2017/RetroArch-msvc2017.vcxproj @@ -1,379 +1,383 @@ - - - - - Debug Cg - Win32 - - - Debug Cg - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release Cg - Win32 - - - Release Cg - x64 - - - Release - Win32 - - - Release - x64 - - - - {27FF7CE1-4059-4AA1-8062-FD529560FA54} - Win32Proj - RetroArchmsvc2015 - 10.0.16299.0 - - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - Application - false - true - NotSet - v141 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - true - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(LibraryPath) - AllRules.ruleset - - - - - true - $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) - AllRules.ruleset - - - - - true - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x64;$(LibraryPath) - AllRules.ruleset - - - - - true - $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) - $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) - AllRules.ruleset - - - - - false - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(LibraryPath) - AllRules.ruleset - - - - - false - $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) - $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) - AllRules.ruleset - - - - - false - $(DXSDK_DIR)Include;$(IncludePath) - $(DXSDK_DIR)Lib\x64;$(LibraryPath) - AllRules.ruleset - - - - - false - $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) - $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) - AllRules.ruleset - - - - - - - - Level3 - Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreadedDebug - CompileAsCpp - Fast - StreamingSIMDExtensions - - - Console - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreadedDebug - CompileAsCpp - Fast - StreamingSIMDExtensions - - - Console - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - $(CG_LIB_PATH) - - - - - - - Level3 - Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreadedDebug - CompileAsCpp - Fast - StreamingSIMDExtensions2 - - - Console - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - - - - - - - Level3 - Disabled - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreadedDebug - CompileAsCpp - Fast - StreamingSIMDExtensions2 - - - Console - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - $(CG_LIB64_PATH) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreaded - CompileAsCpp - Fast - StreamingSIMDExtensions - true - - - Console - true - true - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreaded - CompileAsCpp - Fast - StreamingSIMDExtensions - true - - - Console - true - true - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - $(CG_LIB_PATH) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreaded - CompileAsCpp - Fast - StreamingSIMDExtensions2 - true - - - Console - true - true - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - - - - - Level3 - - - MaxSpeed - true - true - WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT - $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) - MultiThreaded - CompileAsCpp - Fast - StreamingSIMDExtensions2 - true - - - Console - true - true - true - msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) - $(CG_LIB64_PATH) - - - - - - - - CompileAsC - CompileAsC - CompileAsC - CompileAsC - - - - - - - \ No newline at end of file + + + + + Debug Cg + Win32 + + + Debug Cg + x64 + + + Debug + Win32 + + + Debug + x64 + + + Release Cg + Win32 + + + Release Cg + x64 + + + Release + Win32 + + + Release + x64 + + + + {27FF7CE1-4059-4AA1-8062-FD529560FA54} + Win32Proj + RetroArchmsvc2015 + 10.0.16299.0 + + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + Application + false + true + NotSet + v141 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath) + AllRules.ruleset + + + + + true + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x86;$(CG_LIB_PATH);$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(LibraryPath) + AllRules.ruleset + + + + + false + $(DXSDK_DIR)Include;$(CG_INC_PATH);$(IncludePath) + $(DXSDK_DIR)Lib\x64;$(CG_LIB64_PATH);$(LibraryPath) + AllRules.ruleset + + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + + + Level3 + Disabled + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_DEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreadedDebug + CompileAsCpp + Fast + StreamingSIMDExtensions2 + + + Console + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;__SSE__;__i686__;HAVE_OVERLAY;HAVE_MENU;HAVE_RGUI;HAVE_GL_SYNC;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB_PATH) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + + + + + Level3 + + + MaxSpeed + true + true + WIN32;RARCH_INTERNAL;HAVE_CC_RESAMPLER;HAVE_UPDATE_ASSETS;HAVE_D3D;HAVE_D3D9;HAVE_CG;HAVE_GLSL;HAVE_GRIFFIN;HAVE_LANGEXTRA;HAVE_FBO;HAVE_ZLIB;HAVE_XMB;HAVE_SHADERPIPELINE;WANT_ZLIB;HAVE_FBO;NDEBUG;_WINDOWS;%(PreprocessorDefinitions);HAVE_DINPUT;HAVE_XINPUT;HAVE_XAUDIO;HAVE_DSOUND;HAVE_OPENGL;HAVE_DYLIB;HAVE_NETWORKING;HAVE_NETWORK_CMD;HAVE_COMMAND;HAVE_STDIN_CMD;HAVE_THREADS;HAVE_DYNAMIC;HAVE_RPNG;HAVE_RJPEG;HAVE_RBMP;HAVE_RTGA;HAVE_IMAGEVIEWER;WANT_ZLIB;_CRT_SECURE_NO_WARNINGS;__SSE__;__SSE2__;__x86_64__;HAVE_OVERLAY;HAVE_RGUI;HAVE_GL_SYNC;HAVE_MENU;HAVE_7ZIP;HAVE_MATERIALUI;HAVE_LIBRETRODB;HAVE_STB_FONT + $(MSBuildProjectDirectory);$(MSBuildProjectDirectory)\..\..\..\;$(CG_INC_PATH);$(MSBuildProjectDirectory)\..\..\..\deps\zlib;$(MSBuildProjectDirectory)\..\..\..\libretro-common\include;$(MSBuildProjectDirectory)\..\..\..\deps;$(MSBuildProjectDirectory)\..\..\..\deps\glslang;$(MSBuildProjectDirectory)\..\..\..\deps\SPIRV-Cross;$(MSBuildProjectDirectory)\..\..\..\deps\stb;$(MSBuildProjectDirectory)\..\..\..\gfx\include;%(AdditionalIncludeDirectories) + MultiThreaded + CompileAsCpp + Fast + StreamingSIMDExtensions2 + true + + + Console + true + true + true + msimg32.lib;winmm.lib;Dinput8.lib;dxguid.lib;Iphlpapi.lib;%(AdditionalDependencies) + $(CG_LIB64_PATH) + + + + + + + + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + CompileAsC + + + + + + + From 494ba8685e10222d631af6709379b3ed68d56bab Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Wed, 6 Dec 2017 14:34:20 -0500 Subject: [PATCH 127/698] Update make install for new retroarch-assets src The assets over at [retroarch-assets](https://github.com/libretro/retroarch-assets) have [moved the source files](https://github.com/libretro/retroarch-assets/pull/191) so that the asset installation process is a much easier. We no longer have the need to delete the theme src directories. --- Makefile | 7 ------- 1 file changed, 7 deletions(-) diff --git a/Makefile b/Makefile index 8e70dd430d..b820c54233 100644 --- a/Makefile +++ b/Makefile @@ -205,13 +205,6 @@ install: $(TARGET) mkdir -p $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/glui; \ cp -r media/assets/xmb/ $(DESTDIR)$(ASSETS_DIR)/retroarch/assets; \ cp -r media/assets/glui/ $(DESTDIR)$(ASSETS_DIR)/retroarch/assets; \ - echo "Removing unneeded source image files.."; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/flatui/src; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/monochrome/src; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/retroactive/src; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/neoactive/src; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/retrosystem/src; \ - rm -rf $(DESTDIR)$(ASSETS_DIR)/retroarch/assets/xmb/dot-art/src; \ echo "Asset copying done."; \ fi From 4e9cb21e0322e4d1bfac006c47a392d43752a585 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 20:38:22 +0100 Subject: [PATCH 128/698] Don't use hashes --- driver.c | 121 ++++++++++++++++++++++++++----------------------------- 1 file changed, 58 insertions(+), 63 deletions(-) diff --git a/driver.c b/driver.c index 96fc0c2c73..7fe0193d29 100644 --- a/driver.c +++ b/driver.c @@ -44,17 +44,6 @@ #include "retroarch.h" #include "verbosity.h" -#define HASH_LOCATION_DRIVER 0x09189689U -#define HASH_CAMERA_DRIVER 0xf25db959U -#define HASH_MENU_DRIVER 0xd607fb05U -#define HASH_INPUT_DRIVER 0x4c087840U -#define HASH_INPUT_JOYPAD_DRIVER 0xab124146U -#define HASH_VIDEO_DRIVER 0x1805a5e7U -#define HASH_AUDIO_DRIVER 0x26594002U -#define HASH_AUDIO_RESAMPLER_DRIVER 0xedcba9ecU -#define HASH_RECORD_DRIVER 0x144cd2cfU -#define HASH_WIFI_DRIVER 0x64d7d17fU - /** * find_driver_nonempty: * @label : string of driver type to be found. @@ -72,62 +61,68 @@ static const void *find_driver_nonempty(const char *label, int i, char *s, size_t len) { const void *drv = NULL; - uint32_t hash = msg_hash_calculate(label); - switch (hash) + if (string_is_equal(label, "camera_driver")) { - case HASH_CAMERA_DRIVER: - drv = camera_driver_find_handle(i); - if (drv) - strlcpy(s, camera_driver_find_ident(i), len); - break; - case HASH_LOCATION_DRIVER: - drv = location_driver_find_handle(i); - if (drv) - strlcpy(s, location_driver_find_ident(i), len); - break; - case HASH_MENU_DRIVER: + drv = camera_driver_find_handle(i); + if (drv) + strlcpy(s, camera_driver_find_ident(i), len); + } + else if (string_is_equal(label, "location_driver")) + { + drv = location_driver_find_handle(i); + if (drv) + strlcpy(s, location_driver_find_ident(i), len); + } #ifdef HAVE_MENU - drv = menu_driver_find_handle(i); - if (drv) - strlcpy(s, menu_driver_find_ident(i), len); + else if (string_is_equal(label, "menu_driver")) + { + drv = menu_driver_find_handle(i); + if (drv) + strlcpy(s, menu_driver_find_ident(i), len); + } #endif - break; - case HASH_INPUT_DRIVER: - drv = input_driver_find_handle(i); - if (drv) - strlcpy(s, input_driver_find_ident(i), len); - break; - case HASH_INPUT_JOYPAD_DRIVER: - drv = joypad_driver_find_handle(i); - if (drv) - strlcpy(s, joypad_driver_find_ident(i), len); - break; - case HASH_VIDEO_DRIVER: - drv = video_driver_find_handle(i); - if (drv) - strlcpy(s, video_driver_find_ident(i), len); - break; - case HASH_AUDIO_DRIVER: - drv = audio_driver_find_handle(i); - if (drv) - strlcpy(s, audio_driver_find_ident(i), len); - break; - case HASH_RECORD_DRIVER: - drv = record_driver_find_handle(i); - if (drv) - strlcpy(s, record_driver_find_ident(i), len); - break; - case HASH_AUDIO_RESAMPLER_DRIVER: - drv = audio_resampler_driver_find_handle(i); - if (drv) - strlcpy(s, audio_resampler_driver_find_ident(i), len); - break; - case HASH_WIFI_DRIVER: - drv = wifi_driver_find_handle(i); - if (drv) - strlcpy(s, wifi_driver_find_ident(i), len); - break; + else if (string_is_equal(label, "input_driver")) + { + drv = input_driver_find_handle(i); + if (drv) + strlcpy(s, input_driver_find_ident(i), len); + } + else if (string_is_equal(label, "joypad_driver")) + { + drv = joypad_driver_find_handle(i); + if (drv) + strlcpy(s, joypad_driver_find_ident(i), len); + } + else if (string_is_equal(label, "video_driver")) + { + drv = video_driver_find_handle(i); + if (drv) + strlcpy(s, video_driver_find_ident(i), len); + } + else if (string_is_equal(label, "audio_driver")) + { + drv = audio_driver_find_handle(i); + if (drv) + strlcpy(s, audio_driver_find_ident(i), len); + } + else if (string_is_equal(label, "record_driver")) + { + drv = record_driver_find_handle(i); + if (drv) + strlcpy(s, record_driver_find_ident(i), len); + } + else if (string_is_equal(label, "audio_resampler_driver")) + { + drv = audio_resampler_driver_find_handle(i); + if (drv) + strlcpy(s, audio_resampler_driver_find_ident(i), len); + } + else if (string_is_equal(label, "wifi_driver")) + { + drv = wifi_driver_find_handle(i); + if (drv) + strlcpy(s, wifi_driver_find_ident(i), len); } return drv; From fd23a751e40a5ef7362f0dbe60d371e2b38491e0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 20:40:18 +0100 Subject: [PATCH 129/698] Fix joypad_driver --- driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/driver.c b/driver.c index 7fe0193d29..fbee1c29f1 100644 --- a/driver.c +++ b/driver.c @@ -88,7 +88,7 @@ static const void *find_driver_nonempty(const char *label, int i, if (drv) strlcpy(s, input_driver_find_ident(i), len); } - else if (string_is_equal(label, "joypad_driver")) + else if (string_is_equal(label, "input_joypad_driver")) { drv = joypad_driver_find_handle(i); if (drv) From fbf4b4813c82dc6cb63968e71b9ae9f9a7c7938b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 20:52:29 +0100 Subject: [PATCH 130/698] Cleanup path_set_redirect - no more hashes --- paths.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/paths.c b/paths.c index 1b831ca598..54698213be 100644 --- a/paths.c +++ b/paths.c @@ -62,8 +62,7 @@ void path_set_redirect(void) size_t path_size = PATH_MAX_LENGTH * sizeof(char); char *new_savefile_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); char *new_savestate_dir = (char*)malloc(PATH_MAX_LENGTH * sizeof(char)); - uint32_t library_name_hash = 0; - bool check_library_name_hash = false; + bool check_library_name = false; global_t *global = global_get_ptr(); const char *old_savefile_dir = dir_get(RARCH_DIR_SAVEFILE); const char *old_savestate_dir = dir_get(RARCH_DIR_SAVESTATE); @@ -72,22 +71,21 @@ void path_set_redirect(void) new_savefile_dir[0] = new_savestate_dir[0] = '\0'; - if (info && !string_is_empty(info->info.library_name)) - library_name_hash = - msg_hash_calculate(info->info.library_name); - /* Initialize current save directories * with the values from the config. */ strlcpy(new_savefile_dir, old_savefile_dir, path_size); strlcpy(new_savestate_dir, old_savestate_dir, path_size); - check_library_name_hash = (library_name_hash != 0); + if (info && !string_is_empty(info->info.library_name)) + { #ifdef HAVE_MENU - check_library_name_hash = check_library_name_hash && - (library_name_hash != MENU_VALUE_NO_CORE); + if (!string_is_equal(info->info.library_name, + msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NO_CORE))) #endif + check_library_name = true; + } - if (check_library_name_hash) + if (check_library_name) { /* per-core saves: append the library_name to the save location */ if (settings->bools.sort_savefiles_enable From 542235ffd7c8b1807419a12dc9d041903df37cae Mon Sep 17 00:00:00 2001 From: twinaphex Date: Wed, 6 Dec 2017 21:55:21 +0100 Subject: [PATCH 131/698] (XMB) Get rid of hashes --- menu/drivers/xmb.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/menu/drivers/xmb.c b/menu/drivers/xmb.c index 0185ec76ee..f51c088d71 100755 --- a/menu/drivers/xmb.c +++ b/menu/drivers/xmb.c @@ -2376,30 +2376,29 @@ static int xmb_draw_item( } else { - enum msg_file_type type = FILE_TYPE_NONE; - if (!string_is_empty(entry->value)) - type = msg_hash_to_file_type(msg_hash_calculate(entry->value)); - - switch (type) { - case FILE_TYPE_IN_CARCHIVE: - case FILE_TYPE_COMPRESSED: - case FILE_TYPE_MORE: - case FILE_TYPE_CORE: - case FILE_TYPE_DIRECT_LOAD: - case FILE_TYPE_RDB: - case FILE_TYPE_CURSOR: - case FILE_TYPE_PLAIN: - case FILE_TYPE_DIRECTORY: - case FILE_TYPE_MUSIC: - case FILE_TYPE_IMAGE: - case FILE_TYPE_MOVIE: - break; - default: - do_draw_text = true; - break; + if ( + string_is_equal(entry->value, "...") || + string_is_equal(entry->value, "(COMP)") || + string_is_equal(entry->value, "(CORE)") || + string_is_equal(entry->value, "(MOVIE)") || + string_is_equal(entry->value, "(MUSIC)") || + string_is_equal(entry->value, "(DIR)") || + string_is_equal(entry->value, "(RDB)") || + string_is_equal(entry->value, "(CURSOR)")|| + string_is_equal(entry->value, "(CFILE)") || + string_is_equal(entry->value, "(FILE)") || + string_is_equal(entry->value, "(IMAGE)") + ) + { + } + else + do_draw_text = true; } + else + do_draw_text = true; + } if (string_is_empty(entry->value)) From 951918a245abd821bcfd533fc732cd6064420a98 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Thu, 7 Dec 2017 05:54:54 +0100 Subject: [PATCH 132/698] Reduce size of Makefiles --- Makefile.common | 44 ++++++++++++++++++++++++++++++++++++++++++++ Makefile.ctr | 30 ++---------------------------- Makefile.emscripten | 22 ++-------------------- Makefile.vita | 20 ++------------------ Makefile.wiiu | 20 ++------------------ 5 files changed, 52 insertions(+), 84 deletions(-) diff --git a/Makefile.common b/Makefile.common index 14caf2e201..07bf65126d 100644 --- a/Makefile.common +++ b/Makefile.common @@ -127,6 +127,10 @@ ifeq ($(HAVE_UNIX), 1) OBJ += frontend/drivers/platform_unix.o endif +ifeq ($(TARGET), retroarch_3ds) + OBJ += frontend/drivers/platform_ctr.o +endif + ifeq ($(findstring Haiku,$(OS)),) LIBS += -lm DEBUG_FLAG = -g @@ -570,12 +574,21 @@ ifeq ($(HAVE_CORETEXT), 1) OBJ += gfx/drivers_font_renderer/coretext.o endif +ifeq ($(TARGET), retroarch_3ds) + OBJ += gfx/drivers_font/ctr_font.o +endif + ifeq ($(HAVE_OSS), 1) OBJ += audio/drivers/oss.o else ifeq ($(HAVE_OSS_BSD), 1) OBJ += audio/drivers/oss.o endif +ifeq ($(TARGET), retroarch_3ds) + OBJ += audio/drivers/ctr_csnd_audio.o \ + audio/drivers/ctr_dsp_audio.o +endif + ifeq ($(HAVE_ALSA), 1) OBJ += audio/drivers/alsa.o @@ -845,6 +858,13 @@ endif CFLAGS += -I$(DEPS_DIR)/libvita2d/include endif +ifeq ($(TARGET), retroarch_3ds) + OBJ += gfx/drivers/ctr_gfx.o \ + menu/drivers_display/menu_display_ctr.o \ + input/drivers/ctr_input.o \ + input/drivers_joypad/ctr_joypad.o +endif + ifeq ($(HAVE_WAYLAND), 1) OBJ += gfx/drivers_context/wayland_ctx.o \ input/drivers/wayland_input.o @@ -1584,3 +1604,27 @@ ifneq ($(findstring DOS,$(OS)),) OBJ += menu/drivers_display/menu_display_vga.o endif endif + +ifeq ($(HAVE_STATIC_VIDEO_FILTERS), 1) +OBJ += gfx/video_filters/2xsai.o \ + gfx/video_filters/super2xsai.o \ + gfx/video_filters/supereagle.o \ + gfx/video_filters/2xbr.o \ + gfx/video_filters/darken.o \ + gfx/video_filters/epx.o \ + gfx/video_filters/scale2x.o \ + gfx/video_filters/blargg_ntsc_snes.o \ + gfx/video_filters/lq2x.o \ + gfx/video_filters/phosphor2x.o +endif + +ifeq ($(HAVE_STATIC_AUDIO_FILTERS), 1) +OBJ += libretro-common/audio/dsp_filters/echo.o \ + libretro-common/audio/dsp_filters/eq.o \ + libretro-common/audio/dsp_filters/chorus.o \ + libretro-common/audio/dsp_filters/iir.o \ + libretro-common/audio/dsp_filters/panning.o \ + libretro-common/audio/dsp_filters/phaser.o \ + libretro-common/audio/dsp_filters/reverb.o \ + libretro-common/audio/dsp_filters/wahwah.o +endif diff --git a/Makefile.ctr b/Makefile.ctr index c277d3df77..79e34c8a8c 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -61,42 +61,16 @@ else HAVE_ZARCH = 0 HAVE_MATERIALUI = 1 HAVE_XMB = 1 + HAVE_STATIC_VIDEO_FILTERS = 1 + HAVE_STATIC_AUDIO_FILTERS = 1 include Makefile.common BLACKLIST := BLACKLIST += input/input_overlay.o BLACKLIST += tasks/task_overlay.o OBJ := $(filter-out $(BLACKLIST),$(OBJ)) - - OBJ += gfx/drivers/ctr_gfx.o - OBJ += gfx/drivers_font/ctr_font.o - OBJ += menu/drivers_display/menu_display_ctr.o - OBJ += input/drivers/ctr_input.o - OBJ += input/drivers_joypad/ctr_joypad.o - OBJ += audio/drivers/ctr_csnd_audio.o - OBJ += audio/drivers/ctr_dsp_audio.o - OBJ += frontend/drivers/platform_ctr.o - OBJ += gfx/video_filters/2xsai.o - OBJ += gfx/video_filters/super2xsai.o - OBJ += gfx/video_filters/supereagle.o - OBJ += gfx/video_filters/2xbr.o - OBJ += gfx/video_filters/darken.o - OBJ += gfx/video_filters/epx.o - OBJ += gfx/video_filters/scale2x.o - OBJ += gfx/video_filters/blargg_ntsc_snes.o - OBJ += gfx/video_filters/lq2x.o - OBJ += gfx/video_filters/phosphor2x.o - OBJ += libretro-common/audio/dsp_filters/echo.o - OBJ += libretro-common/audio/dsp_filters/eq.o - OBJ += libretro-common/audio/dsp_filters/chorus.o - OBJ += libretro-common/audio/dsp_filters/iir.o - OBJ += libretro-common/audio/dsp_filters/panning.o - OBJ += libretro-common/audio/dsp_filters/phaser.o - OBJ += libretro-common/audio/dsp_filters/reverb.o - OBJ += libretro-common/audio/dsp_filters/wahwah.o endif - ifeq ($(strip $(DEVKITPRO)),) $(error "Please set DEVKITPRO in your environment. export DEVKITPRO=devkitpro") endif diff --git a/Makefile.emscripten b/Makefile.emscripten index fb3a215339..e191cfd874 100644 --- a/Makefile.emscripten +++ b/Makefile.emscripten @@ -20,6 +20,8 @@ HAVE_SDL = 0 HAVE_SDL2 = 1 HAVE_ZLIB = 1 WANT_ZLIB = 1 +HAVE_STATIC_VIDEO_FILTERS = 1 +HAVE_STATIC_AUDIO_FILTERS = 1 MEMORY = 536870912 # XXX: setting this to 1/2 currently crashes Firefox nightly @@ -51,26 +53,6 @@ endif include Makefile.common -OBJ += gfx/video_filters/2xsai.o -OBJ += gfx/video_filters/super2xsai.o -OBJ += gfx/video_filters/supereagle.o -OBJ += gfx/video_filters/2xbr.o -OBJ += gfx/video_filters/darken.o -OBJ += gfx/video_filters/epx.o -OBJ += gfx/video_filters/scale2x.o -OBJ += gfx/video_filters/blargg_ntsc_snes.o -OBJ += gfx/video_filters/lq2x.o -OBJ += gfx/video_filters/phosphor2x.o - -OBJ += libretro-common/audio/dsp_filters/echo.o -OBJ += libretro-common/audio/dsp_filters/eq.o -OBJ += libretro-common/audio/dsp_filters/chorus.o -OBJ += libretro-common/audio/dsp_filters/iir.o -OBJ += libretro-common/audio/dsp_filters/panning.o -OBJ += libretro-common/audio/dsp_filters/phaser.o -OBJ += libretro-common/audio/dsp_filters/reverb.o -OBJ += libretro-common/audio/dsp_filters/wahwah.o - CFLAGS += -Ideps/libz -Ideps -Ideps/stb libretro = libretro_emscripten.bc diff --git a/Makefile.vita b/Makefile.vita index 3138442913..25d79a673e 100644 --- a/Makefile.vita +++ b/Makefile.vita @@ -47,6 +47,8 @@ else HAVE_CC_RESAMPLER := 1 HAVE_CHEEVOS := 1 RARCH_CONSOLE := 1 + HAVE_STATIC_VIDEO_FILTERS = 1 + HAVE_STATIC_AUDIO_FILTERS = 1 ifeq ($(DEBUG), 1) HAVE_NETLOGGER = 1 @@ -60,24 +62,6 @@ else OBJ += input/drivers_joypad/psp_joypad.o OBJ += audio/drivers/psp_audio.o OBJ += frontend/drivers/platform_psp.o - OBJ += gfx/video_filters/2xsai.o - OBJ += gfx/video_filters/super2xsai.o - OBJ += gfx/video_filters/supereagle.o - OBJ += gfx/video_filters/2xbr.o - OBJ += gfx/video_filters/darken.o - OBJ += gfx/video_filters/epx.o - OBJ += gfx/video_filters/scale2x.o - OBJ += gfx/video_filters/blargg_ntsc_snes.o - OBJ += gfx/video_filters/lq2x.o - OBJ += gfx/video_filters/phosphor2x.o - OBJ += libretro-common/audio/dsp_filters/echo.o - OBJ += libretro-common/audio/dsp_filters/eq.o - OBJ += libretro-common/audio/dsp_filters/chorus.o - OBJ += libretro-common/audio/dsp_filters/iir.o - OBJ += libretro-common/audio/dsp_filters/panning.o - OBJ += libretro-common/audio/dsp_filters/phaser.o - OBJ += libretro-common/audio/dsp_filters/reverb.o - OBJ += libretro-common/audio/dsp_filters/wahwah.o endif diff --git a/Makefile.wiiu b/Makefile.wiiu index 00881ed117..b3389af1af 100644 --- a/Makefile.wiiu +++ b/Makefile.wiiu @@ -71,6 +71,8 @@ else HAVE_NETWORKING = 1 HAVE_CHEEVOS = 1 # WANT_IFADDRS = 1 + HAVE_STATIC_VIDEO_FILTERS = 1 + HAVE_STATIC_AUDIO_FILTERS = 1 include Makefile.common BLACKLIST := @@ -86,24 +88,6 @@ else OBJ += input/drivers_joypad/wiiu_joypad.o OBJ += audio/drivers/wiiu_audio.o OBJ += frontend/drivers/platform_wiiu.o - OBJ += gfx/video_filters/2xsai.o - OBJ += gfx/video_filters/super2xsai.o - OBJ += gfx/video_filters/supereagle.o - OBJ += gfx/video_filters/2xbr.o - OBJ += gfx/video_filters/darken.o - OBJ += gfx/video_filters/epx.o - OBJ += gfx/video_filters/scale2x.o - OBJ += gfx/video_filters/blargg_ntsc_snes.o - OBJ += gfx/video_filters/lq2x.o - OBJ += gfx/video_filters/phosphor2x.o - OBJ += libretro-common/audio/dsp_filters/echo.o - OBJ += libretro-common/audio/dsp_filters/eq.o - OBJ += libretro-common/audio/dsp_filters/chorus.o - OBJ += libretro-common/audio/dsp_filters/iir.o - OBJ += libretro-common/audio/dsp_filters/panning.o - OBJ += libretro-common/audio/dsp_filters/phaser.o - OBJ += libretro-common/audio/dsp_filters/reverb.o - OBJ += libretro-common/audio/dsp_filters/wahwah.o endif DEFINES += -DHAVE_KEYMAPPER From fa7cd77d7d16dca7ddd18a647b2316c63c7ec12f Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 7 Dec 2017 13:49:07 -0500 Subject: [PATCH 133/698] win32: improve version reporting under System Information --- CHANGES.md | 1 + frontend/drivers/platform_win32.c | 122 ++++++++++++++++++++++++++---- menu/menu_displaylist.c | 2 +- 3 files changed, 109 insertions(+), 16 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 8a96ac498c..ddb34e00e7 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -21,6 +21,7 @@ - WINDOWS: Raw input driver now supports new lightgun code. - WINDOWS: Use configured OSD/text message color on GDI driver. - WINDOWS/XINPUT: Populate XInput VID/PID from DInput so autoconfig doesn't rely solely on joypad names +- WINDOWS: Improve version reporting under System Information. # 1.6.9 - COMMON: Small memory leak. diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 2988b75c4e..b523c487a0 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -1,5 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker * * 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,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -130,40 +132,110 @@ static void gfx_set_dwm(void) static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) { - uint32_t version = GetVersion(); + char buildStr[11] = {0}; + bool server = false; + const char *arch = ""; + bool serverR2 = false; - *major = (DWORD)(LOBYTE(LOWORD(version))); - *minor = (DWORD)(HIBYTE(LOWORD(version))); +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Windows 2000 and later */ + SYSTEM_INFO si = {0}; + OSVERSIONINFOEX vi = {0}; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - switch (*major) + server = vi.wProductType != VER_NT_WORKSTATION; + + serverR2 = GetSystemMetrics(SM_SERVERR2); + + GetSystemInfo(&si); + + switch (si.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + arch = "x64"; + break; + case PROCESSOR_ARCHITECTURE_INTEL: + arch = "x86"; + break; + case PROCESSOR_ARCHITECTURE_ARM: + arch = "ARM"; + break; + default: + break; + } +#else + OSVERSIONINFO vi = {0}; + vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); +#endif + + /* Available from NT 3.5 and Win95 */ + GetVersionEx((OSVERSIONINFO*)&vi); + + if (major) + *major = vi.dwMajorVersion; + + if (minor) + *minor = vi.dwMinorVersion; + + if (vi.dwMajorVersion == 4 && vi.dwMinorVersion == 0) + snprintf(buildStr, sizeof(buildStr), "%lu", (DWORD)(LOWORD(vi.dwBuildNumber))); /* Windows 95 build number is in the low-order word only */ + else + snprintf(buildStr, sizeof(buildStr), "%lu", vi.dwBuildNumber); + + switch (vi.dwMajorVersion) { case 10: - strlcpy(s, "Windows 10", len); + if (server) + strlcpy(s, "Windows Server 2016", len); + else + strlcpy(s, "Windows 10", len); break; case 6: - switch (*minor) + switch (vi.dwMinorVersion) { case 3: - strlcpy(s, "Windows 8.1", len); + if (server) + strlcpy(s, "Windows Server 2012 R2", len); + else + strlcpy(s, "Windows 8.1", len); break; case 2: - strlcpy(s, "Windows 8", len); + if (server) + strlcpy(s, "Windows Server 2012", len); + else + strlcpy(s, "Windows 8", len); break; case 1: - strlcpy(s, "Windows 7/2008 R2", len); + if (server) + strlcpy(s, "Windows Server 2008 R2", len); + else + strlcpy(s, "Windows 7", len); break; case 0: - strlcpy(s, "Windows Vista/2008", len); + if (server) + strlcpy(s, "Windows Server 2008", len); + else + strlcpy(s, "Windows Vista", len); break; default: break; } break; case 5: - switch (*minor) + switch (vi.dwMinorVersion) { case 2: - strlcpy(s, "Windows 2003", len); + if (server) + if (serverR2) + strlcpy(s, "Windows Server 2003 R2", len); + else + strlcpy(s, "Windows Server 2003", len); + else + { + /* Yes, XP Pro x64 is a higher version number than XP x86 */ + if (string_is_equal(arch, "x64")) + strlcpy(s, "Windows XP", len); + } break; case 1: strlcpy(s, "Windows XP", len); @@ -174,10 +246,15 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) } break; case 4: - switch (*minor) + switch (vi.dwMinorVersion) { case 0: - strlcpy(s, "Windows NT 4.0", len); + if (vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) + strlcpy(s, "Windows 95", len); + else if (vi.dwPlatformId == VER_PLATFORM_WIN32_NT) + strlcpy(s, "Windows NT 4.0", len); + else + strlcpy(s, "Unknown", len); break; case 90: strlcpy(s, "Windows ME", len); @@ -188,9 +265,24 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) } break; default: - sprintf(s, "Windows %i.%i", *major, *minor); + snprintf(s, len, "Windows %i.%i", *major, *minor); break; } + + if (!string_is_empty(arch)) + { + strlcat(s, " ", len); + strlcat(s, arch, len); + } + + strlcat(s, " Build ", len); + strlcat(s, buildStr, len); + + if (!string_is_empty(vi.szCSDVersion)) + { + strlcat(s, " ", len); + strlcat(s, vi.szCSDVersion, len); + } } static void frontend_win32_init(void *data) diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 051f17d62a..a7da756206 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -805,7 +805,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) if (frontend->get_os) { frontend->get_os(tmp2, sizeof(tmp2), &major, &minor); - snprintf(tmp, sizeof(tmp), "%s : %s %d.%d", + snprintf(tmp, sizeof(tmp), "%s : %s (v%d.%d)", msg_hash_to_str(MENU_ENUM_LABEL_VALUE_SYSTEM_INFO_FRONTEND_OS), frontend->get_os ? tmp2 : msg_hash_to_str(MENU_ENUM_LABEL_VALUE_NOT_AVAILABLE), From d6daf2f573705b521e39870754814d5cc21a168e Mon Sep 17 00:00:00 2001 From: clienthax Date: Thu, 7 Dec 2017 19:49:11 +0000 Subject: [PATCH 134/698] [PS3] Possible fix for 0x0 resolution on --- gfx/drivers_context/ps3_ctx.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index e7c48bfdcd..0c3775ec58 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -129,10 +129,11 @@ static void gfx_ctx_ps3_get_available_resolutions(void) * make the last resolution that was added to the list (the highest resolution) the default resolution */ - if (global->console.screen.resolutions.current.id > num_videomodes - || defaultresolution) - global->console.screen.resolutions.current.idx = - global->console.screen.resolutions.count - 1; + if (global->console.screen.resolutions.current.id > num_videomodes || defaultresolution) + { + global->console.screen.resolutions.current.idx = resolution_count - 1; + global->console.screen.resolutions.current.id = global->console.screen.resolutions.list[global->console.screen.resolutions.current.idx]; + } global->console.screen.resolutions.check = true; } From 130a0018469b5452d4f79d55e7ecfa6c4e258599 Mon Sep 17 00:00:00 2001 From: leiradel Date: Thu, 7 Dec 2017 19:49:39 +0000 Subject: [PATCH 135/698] Fixed wrong leaderboard count --- cheevos/cheevos.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 662c8b6dea..e70e425667 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -802,6 +802,7 @@ static int cheevos_count_cheevos(const char *json, int res; cheevos_countud_t ud; ud.in_cheevos = 0; + ud.in_lboards = 0; ud.core_count = 0; ud.unofficial_count = 0; ud.lboard_count = 0; @@ -2829,6 +2830,7 @@ static int cheevos_iterate(coro_t* coro) && cheevos_locals.lboard_count == 0) cheevos_unload(); + CORO_GOSUB(GET_BADGES); CORO_STOP(); /************************************************************************** From 55b738a07ab6b50796f6b1d11b8570fcb2d95279 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 7 Dec 2017 16:32:01 -0500 Subject: [PATCH 136/698] implement frontend get_architecture() for windows --- frontend/drivers/platform_win32.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index b523c487a0..d3d466a40a 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -338,7 +338,28 @@ enum frontend_powerstate frontend_win32_get_powerstate(int *seconds, int *percen enum frontend_architecture frontend_win32_get_architecture(void) { - /* stub */ +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Windows 2000 and later */ + SYSTEM_INFO si = {0}; + + GetSystemInfo(&si); + + switch (si.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + return FRONTEND_ARCH_X86_64; + break; + case PROCESSOR_ARCHITECTURE_INTEL: + return FRONTEND_ARCH_X86; + break; + case PROCESSOR_ARCHITECTURE_ARM: + return FRONTEND_ARCH_ARM; + break; + default: + break; + } +#endif + return FRONTEND_ARCH_NONE; } From a565ba0149cf91fe4aecb1b7cd93d9925627bef9 Mon Sep 17 00:00:00 2001 From: clienthax Date: Thu, 7 Dec 2017 22:20:02 +0000 Subject: [PATCH 137/698] [PS3] Partial fix of networking --- libretro-common/net/net_compat.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index d9de1d8ceb..13fdbfff87 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -193,6 +193,12 @@ int getaddrinfo_retro(const char *node, const char *service, in_addr->sin_family = AF_INET; in_addr->sin_port = inet_htons(strtoul(service, NULL, 0)); + //sin_port seems to be the wrong endian for ps3 + #if defined(__CELLOS_LV2__) && !defined(__PSL1GHT__) + in_addr->sin_port = (in_addr->sin_port>>8) | (in_addr->sin_port<<8); + #endif + + if (!node && (hints->ai_flags & AI_PASSIVE)) in_addr->sin_addr.s_addr = INADDR_ANY; else if (node && isdigit(*node)) @@ -204,7 +210,8 @@ int getaddrinfo_retro(const char *node, const char *service, if (!host || !host->h_addr_list[0]) goto error; - in_addr->sin_addr.s_addr = inet_addr(host->h_addr_list[0]); + in_addr->sin_family = host->h_addrtype; + memcpy(&in_addr->sin_addr, host->h_addr, host->h_length); } else goto error; From b0445e1e210ef2c47ff1b58e1eebfc20a0e0c299 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Thu, 7 Dec 2017 17:47:16 -0500 Subject: [PATCH 138/698] Bliss-Box: Work around Windows sharing violation bug by trying to open device as read/write if read-only fails. Show OSD message if it still fails. --- tasks/task_autodetect.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/tasks/task_autodetect.c b/tasks/task_autodetect.c index be8e9ee4ed..f29dd82e7f 100644 --- a/tasks/task_autodetect.c +++ b/tasks/task_autodetect.c @@ -60,6 +60,7 @@ const GUID GUID_NULL = {0, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0}}; #include "../file_path_special.h" #include "../list_special.h" #include "../verbosity.h" +#include "../retroarch.h" #include "tasks_internal.h" @@ -591,8 +592,27 @@ found: if (hDeviceHandle == INVALID_HANDLE_VALUE) { - RARCH_ERR("[Autoconf]: Can't open device: %d.", GetLastError()); - goto done; + /* Windows sometimes erroneously fails to open with a sharing violation: + * https://github.com/signal11/hidapi/issues/231 + * If this happens, trying again with read + write usually works for some reason. + */ + + /* Open the device */ + hDeviceHandle = CreateFileA( + devicePath, + GENERIC_READ | GENERIC_WRITE, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + 0, /*FILE_FLAG_OVERLAPPED,*/ + NULL); + + if (hDeviceHandle == INVALID_HANDLE_VALUE) + { + RARCH_ERR("[Autoconf]: Can't open device for reading and writing: %d.", GetLastError()); + runloop_msg_queue_push("Bliss-Box already in use. Please make sure other programs are not using it.", 2, 300, false); + goto done; + } } done: From 124ddcd27affdb1c577e60703515349787b2d74e Mon Sep 17 00:00:00 2001 From: David Walters Date: Thu, 7 Dec 2017 23:44:29 +0000 Subject: [PATCH 139/698] Add dolphin bar VID/PID - treat like a wii over bluetooth connection --- input/connect/joypad_connection.c | 1 + 1 file changed, 1 insertion(+) diff --git a/input/connect/joypad_connection.c b/input/connect/joypad_connection.c index 90cb9cf06b..e79fa9a82c 100644 --- a/input/connect/joypad_connection.c +++ b/input/connect/joypad_connection.c @@ -84,6 +84,7 @@ int32_t pad_connection_pad_init(joypad_connection_t *joyconn, { "Wii U GC Controller Adapter", 1406, 823, &pad_connection_wiiugca }, { "PS2/PSX Controller Adapter", 2064, 1, &pad_connection_ps2adapter }, { "PSX to PS3 Controller Adapter", 2064, 3, &pad_connection_psxadapter }, + { "Mayflash DolphinBar", 1406, 774, &pad_connection_wii }, { 0, 0} }; joypad_connection_t *s = NULL; From bf8f7b444bdd92240b67bb33a4a81a3dc82083ac Mon Sep 17 00:00:00 2001 From: leiradel Date: Thu, 7 Dec 2017 23:48:03 +0000 Subject: [PATCH 140/698] Fixed cheevos_expr_value to be C89 compliant --- cheevos/cheevos.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 87517d6164..c11984a229 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1859,13 +1859,26 @@ static int cheevos_expr_value(cheevos_expr_t* expr) /* Separate possible values with '$' operator, submit the largest */ unsigned current_value = 0; /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ - int values[expr->compare_count]; + int values[16]; + + if (expr->compare_count >= sizeof(values) / sizeof(values[0])) + { + RARCH_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", expr->compare_count); + return 0; + } memset(values, 0, sizeof values); for (i = expr->count; i != 0; i--, term++) { + if (current_value >= sizeof(values) / sizeof(values[0])) + { + RARCH_ERR("[CHEEVOS]: too many values in the leaderboard expression: %u\n", current_value); + return 0; + } + values[current_value] += cheevos_var_get_value(&term->var) * term->multiplier; + if (term->compare_next) current_value++; } @@ -1880,7 +1893,8 @@ static int cheevos_expr_value(cheevos_expr_t* expr) return maximum; } - else return values[0]; + else + return values[0]; } static void cheevos_make_lboard_url(const cheevos_leaderboard_t *lboard, From 305cb6d6472c631301878ed1044bcfab4b65e0f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Thu, 7 Dec 2017 18:49:35 -0500 Subject: [PATCH 141/698] fix OS identification (#5880) --- frontend/drivers/platform_win32.c | 15 +++++++++------ menu/menu_displaylist.c | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index d3d466a40a..64703e4dcb 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -143,12 +143,14 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) OSVERSIONINFOEX vi = {0}; vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - server = vi.wProductType != VER_NT_WORKSTATION; - - serverR2 = GetSystemMetrics(SM_SERVERR2); - GetSystemInfo(&si); + /* Available from NT 3.5 and Win95 */ + GetVersionEx((OSVERSIONINFO*)&vi); + + server = vi.wProductType != VER_NT_WORKSTATION; + serverR2 = GetSystemMetrics(SM_SERVERR2); + switch (si.wProcessorArchitecture) { case PROCESSOR_ARCHITECTURE_AMD64: @@ -166,10 +168,11 @@ static void frontend_win32_get_os(char *s, size_t len, int *major, int *minor) #else OSVERSIONINFO vi = {0}; vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); -#endif /* Available from NT 3.5 and Win95 */ - GetVersionEx((OSVERSIONINFO*)&vi); + GetVersionEx(&vi); +#endif + if (major) *major = vi.dwMajorVersion; diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index a7da756206..8a60cf2735 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -681,7 +681,7 @@ static int menu_displaylist_parse_system_info(menu_displaylist_info_t *info) strlcpy(cpu_arch_str, "x86", sizeof(cpu_arch_str)); break; case FRONTEND_ARCH_X86_64: - strlcpy(cpu_arch_str, "x86-64", sizeof(cpu_arch_str)); + strlcpy(cpu_arch_str, "x64", sizeof(cpu_arch_str)); break; case FRONTEND_ARCH_PPC: strlcpy(cpu_arch_str, "PPC", sizeof(cpu_arch_str)); From c53d3d35b8962962b47ce86f22ab7b095cef5b3c Mon Sep 17 00:00:00 2001 From: leiradel Date: Thu, 7 Dec 2017 23:51:15 +0000 Subject: [PATCH 142/698] Removed TODO comment --- cheevos/cheevos.c | 1 - 1 file changed, 1 deletion(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index c11984a229..5a7687dc64 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -1858,7 +1858,6 @@ static int cheevos_expr_value(cheevos_expr_t* expr) unsigned i; /* Separate possible values with '$' operator, submit the largest */ unsigned current_value = 0; - /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ int values[16]; if (expr->compare_count >= sizeof(values) / sizeof(values[0])) From 8c1e3e5d5b5ae80932b96bfc502d8db9e46ff8aa Mon Sep 17 00:00:00 2001 From: leiradel Date: Fri, 8 Dec 2017 00:08:16 +0000 Subject: [PATCH 143/698] Fixed CXX_BUILD --- cheevos/cheevos.c | 6 +++--- cheevos/cheevos.h | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 5a7687dc64..0b9a1ea075 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -258,7 +258,7 @@ typedef struct typedef struct { - int console_id; + cheevos_console_t console_id; bool core_supports; bool addrs_patched; int add_buffer; @@ -276,7 +276,7 @@ typedef struct static cheevos_locals_t cheevos_locals = { - /* console_id */ 0, + /* console_id */ CHEEVOS_CONSOLE_NONE, /* core_supports */ true, /* addrs_patched */ false, /* add_buffer */ 0, @@ -1385,7 +1385,7 @@ static int cheevos_read__json_number(void *userdata, } else if (ud->is_console_id) { - cheevos_locals.console_id = (int)strtol(number, NULL, 10); + cheevos_locals.console_id = (cheevos_console_t)strtol(number, NULL, 10); ud->is_console_id = 0; } diff --git a/cheevos/cheevos.h b/cheevos/cheevos.h index cf2526e504..ed1baae311 100644 --- a/cheevos/cheevos.h +++ b/cheevos/cheevos.h @@ -47,6 +47,7 @@ typedef struct cheevos_ctx_desc typedef enum { + CHEEVOS_CONSOLE_NONE = 0, /* Don't change those, the values match the console IDs * at retroachievements.org. */ CHEEVOS_CONSOLE_MEGA_DRIVE = 1, From a15820f86a91189ed8563e390fde35270b605955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s?= Date: Fri, 8 Dec 2017 10:25:00 -0500 Subject: [PATCH 144/698] Update index.html --- pkg/emscripten/libretro/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/emscripten/libretro/index.html b/pkg/emscripten/libretro/index.html index 37cfe0cc30..2f450e7e41 100644 --- a/pkg/emscripten/libretro/index.html +++ b/pkg/emscripten/libretro/index.html @@ -146,7 +146,7 @@ - +
From 8f7810d92167028ac966eb9929097b6bbef199f6 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Fri, 8 Dec 2017 18:15:22 -0500 Subject: [PATCH 145/698] emscripten: only fire keyup once, and don't wait so long to do so (libretro.js) --- pkg/emscripten/libretro/libretro.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/emscripten/libretro/libretro.js b/pkg/emscripten/libretro/libretro.js index 5b45e7353b..300c6ff1bd 100644 --- a/pkg/emscripten/libretro/libretro.js +++ b/pkg/emscripten/libretro/libretro.js @@ -389,7 +389,7 @@ $(function() { function keyPress(k) { kp(k, "keydown"); - setInterval(function(){kp(k, "keyup")}, 1000); + setTimeout(function(){kp(k, "keyup")}, 50); } kp = function(k, event) { From 004c1d2f0a18c513e32014a27ea39b82486651e8 Mon Sep 17 00:00:00 2001 From: David Walters Date: Fri, 8 Dec 2017 23:37:07 +0000 Subject: [PATCH 146/698] Fix for relative paths being normalised and generating a duplicate history entry. --- tasks/task_content.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks/task_content.c b/tasks/task_content.c index 0c8f0b4129..926d2e1d62 100644 --- a/tasks/task_content.c +++ b/tasks/task_content.c @@ -996,7 +996,7 @@ static bool command_event_cmd_exec(const char *data, #if defined(HAVE_DYNAMIC) if (!task_load_content(&content_info, content_ctx, - false, launched_from_cli, error_string)) + true, launched_from_cli, error_string)) return false; #else frontend_driver_set_fork(FRONTEND_FORK_CORE_WITH_ARGS); From deb017e17f9cf0da499c6df692b332535b7064e7 Mon Sep 17 00:00:00 2001 From: David Walters Date: Fri, 8 Dec 2017 23:50:00 +0000 Subject: [PATCH 147/698] On Windows builds, don't use case sensitive path comparisons when pushing to a playlist. --- playlist.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/playlist.c b/playlist.c index 5ccc40cd2e..7406e75df0 100644 --- a/playlist.c +++ b/playlist.c @@ -309,9 +309,17 @@ bool playlist_push(playlist_t *playlist, for (i = 0; i < playlist->size; i++) { struct playlist_entry tmp; - bool equal_path = (!path && !playlist->entries[i].path) || + bool equal_path; + + equal_path = (!path && !playlist->entries[i].path) || (path && playlist->entries[i].path && - string_is_equal(path,playlist->entries[i].path)); +#ifdef _WIN32 + /*prevent duplicates on case-insensitive operating systems*/ + string_is_equal_noncase(path,playlist->entries[i].path) +#else + string_is_equal(path,playlist->entries[i].path) +#endif + ); /* Core name can have changed while still being the same core. * Differentiate based on the core path only. */ From ed1a920f465beee58040daabfb44ecd563dc8492 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sat, 9 Dec 2017 01:05:55 +0100 Subject: [PATCH 148/698] Update config.def.h --- config.def.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index c3fb49f6f6..34eefd9fa4 100644 --- a/config.def.h +++ b/config.def.h @@ -293,7 +293,7 @@ static bool xmb_show_add = true; #endif #endif -#if defined(HAVE_LIBRETRODB) && !defined(RARCH_CONSOLE) +#if defined(HAVE_LIBRETRODB) && !defined(RARCH_CONSOLE) && !defined(EMSCRIPTEN) static bool automatically_add_content_to_playlist = true; #else static bool automatically_add_content_to_playlist = false; From 0d58d9ca0d642933c271c0dcbe1528002288b467 Mon Sep 17 00:00:00 2001 From: Fabio Date: Sat, 9 Dec 2017 08:24:19 +0100 Subject: [PATCH 149/698] Added label to wii controllers, inverted the right stick Y axis of classic controller The right stick Y axis of classic controller was wrong --- input/input_autodetect_builtin.c | 99 ++++++++++++++++---------------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/input/input_autodetect_builtin.c b/input/input_autodetect_builtin.c index bd6fdaf768..e9fb439510 100644 --- a/input/input_autodetect_builtin.c +++ b/input/input_autodetect_builtin.c @@ -361,58 +361,61 @@ DECL_AXIS(r_y_plus, -3) \ DECL_AXIS(r_y_minus, +3) #define GXINPUT_WIIMOTE_DEFAULT_BINDS \ -DECL_BTN(a, 31) \ -DECL_BTN(b, 30) \ -DECL_BTN(x, 29) \ -DECL_BTN(y, 28) \ -DECL_BTN(start, 32) \ -DECL_BTN(select, 33) \ -DECL_BTN(up, 35) \ -DECL_BTN(down, 36) \ -DECL_BTN(left, 37) \ -DECL_BTN(right, 38) +DECL_BTN_EX(a, 31, "2") \ +DECL_BTN_EX(b, 30, "1") \ +DECL_BTN_EX(x, 29, "B") \ +DECL_BTN_EX(y, 28, "A") \ +DECL_BTN_EX(start, 32, "+") \ +DECL_BTN_EX(select, 33, "-") \ +DECL_BTN_EX(menu_toggle, 34, "Home") \ +DECL_BTN_EX(up, 35, "D-Pad Up") \ +DECL_BTN_EX(down, 36, "D-Pad Down") \ +DECL_BTN_EX(left, 37, "D-Pad Left") \ +DECL_BTN_EX(right, 38, "D-Pad right") #define GXINPUT_NUNCHUK_DEFAULT_BINDS \ -DECL_BTN(a, 28) \ -DECL_BTN(b, 29) \ -DECL_BTN(x, 30) \ -DECL_BTN(y, 31) \ -DECL_BTN(start, 32) \ -DECL_BTN(select, 33) \ -DECL_BTN(up, 35) \ -DECL_BTN(down, 36) \ -DECL_BTN(left, 37) \ -DECL_BTN(right, 38) \ -DECL_BTN(l, 39) \ -DECL_BTN(r, 40) \ -DECL_AXIS(l_x_plus, +0) \ -DECL_AXIS(l_x_minus, -0) \ -DECL_AXIS(l_y_plus, +1) \ -DECL_AXIS(l_y_minus, -1) +DECL_BTN_EX(a, 28, "A") \ +DECL_BTN_EX(b, 29, "B") \ +DECL_BTN_EX(x, 30, "1") \ +DECL_BTN_EX(y, 31, "2") \ +DECL_BTN_EX(start, 32, "+") \ +DECL_BTN_EX(select, 33, "-") \ +DECL_BTN_EX(menu_toggle, 34, "Home") \ +DECL_BTN_EX(up, 35, "D-Pad Up" ) \ +DECL_BTN_EX(down, 36, "D-Pad Down") \ +DECL_BTN_EX(left, 37, "D-Pad Left") \ +DECL_BTN_EX(right, 38, "D-Pad right") \ +DECL_BTN_EX(l, 39, "Z") \ +DECL_BTN_EX(r, 40, "C") \ +DECL_AXIS_EX(l_x_plus, +0, "Stick Right") \ +DECL_AXIS_EX(l_x_minus, -0, "Stick Left") \ +DECL_AXIS_EX(l_y_plus, +1, "Stick Down") \ +DECL_AXIS_EX(l_y_minus, -1, "Stick Up") #define GXINPUT_CLASSIC_DEFAULT_BINDS \ -DECL_BTN(a, 13) \ -DECL_BTN(b, 14) \ -DECL_BTN(x, 15) \ -DECL_BTN(y, 16) \ -DECL_BTN(start, 17) \ -DECL_BTN(select, 18) \ -DECL_BTN(up, 24) \ -DECL_BTN(down, 25) \ -DECL_BTN(left, 26) \ -DECL_BTN(right, 27) \ -DECL_BTN(l, 20) \ -DECL_BTN(r, 21) \ -DECL_BTN(l2, 22) \ -DECL_BTN(r2, 23) \ -DECL_AXIS(l_x_plus, +0) \ -DECL_AXIS(l_x_minus, -0) \ -DECL_AXIS(l_y_plus, +1) \ -DECL_AXIS(l_y_minus, -1) \ -DECL_AXIS(r_x_plus, +2) \ -DECL_AXIS(r_x_minus, -2) \ -DECL_AXIS(r_y_plus, -3) \ -DECL_AXIS(r_y_minus, +3) +DECL_BTN_EX(a, 13, "A") \ +DECL_BTN_EX(b, 14, "B") \ +DECL_BTN_EX(x, 15, "X") \ +DECL_BTN_EX(y, 16, "Y") \ +DECL_BTN_EX(start, 17, "+") \ +DECL_BTN_EX(select, 18, "-") \ +DECL_BTN_EX(menu_toggle, 19, "Home") \ +DECL_BTN_EX(up, 24, "D-Pad Up") \ +DECL_BTN_EX(down, 25, "D-Pad Down") \ +DECL_BTN_EX(left, 26, "D-Pad left") \ +DECL_BTN_EX(right, 27, "D-Pad right") \ +DECL_BTN_EX(l, 20, "L") \ +DECL_BTN_EX(r, 21, "R") \ +DECL_BTN_EX(l2, 22, "ZL") \ +DECL_BTN_EX(r2, 23, "ZR") \ +DECL_AXIS_EX(l_x_plus, +0, "L-Stick Right") \ +DECL_AXIS_EX(l_x_minus, -0, "L-Stick Left") \ +DECL_AXIS_EX(l_y_plus, +1, "L-Stick Down") \ +DECL_AXIS_EX(l_y_minus, -1, "L-Stick Up") \ +DECL_AXIS_EX(r_x_plus, +2, "R-Stick Right") \ +DECL_AXIS_EX(r_x_minus, -2, "R-Stick Left") \ +DECL_AXIS_EX(r_y_plus, +3, "R-Stick Down") \ +DECL_AXIS_EX(r_y_minus, -3, "R-Stick Up") #define PS3INPUT_DEFAULT_BINDS \ DECL_BTN(a, 8) \ From 54aec6c9e8db5882ed7d4edbfb473d27deabe01a Mon Sep 17 00:00:00 2001 From: cpsw <33490332+cpsw@users.noreply.github.com> Date: Sat, 9 Dec 2017 11:01:03 -0300 Subject: [PATCH 150/698] Small code style change Suggesting a code style change. --- ctr/ctr_system.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ctr/ctr_system.c b/ctr/ctr_system.c index 5f118dfc7e..29594251e7 100644 --- a/ctr/ctr_system.c +++ b/ctr/ctr_system.c @@ -77,7 +77,10 @@ void __system_allocateHeaps(void) void __attribute__((weak)) __libctru_init(void (*retAddr)(void)) { /* Store the return address */ - __system_retAddr = envIsHomebrew() ? retAddr : NULL; + __system_retAddr = NULL; + if (envIsHomebrew()) { + __system_retAddr = retAddr; + } /* Initialize the synchronization subsystem */ __sync_init(); From 714684a4d33b22ba2e55147f298dd319c6f5befc Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 8 Dec 2017 14:38:57 +0100 Subject: [PATCH 151/698] Don't wait for WSI fence unless it has been signalled. --- gfx/common/vulkan_common.c | 8 +++++--- gfx/common/vulkan_common.h | 1 + gfx/drivers/vulkan.c | 2 ++ 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 553655372f..314f0f415d 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -2275,16 +2275,18 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk) vkCreateSemaphore(vk->context.device, &sem_info, NULL, &vk->context.swapchain_semaphores[index]); - vkWaitForFences(vk->context.device, 1, &fence, true, UINT64_MAX); + if (err == VK_SUCCESS) + vkWaitForFences(vk->context.device, 1, &fence, true, UINT64_MAX); vkDestroyFence(vk->context.device, fence, NULL); next_fence = &vk->context.swapchain_fences[index]; if (*next_fence != VK_NULL_HANDLE) { - vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX); - + if (vk->context.swapchain_fences_signalled[index]) + vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX); vkResetFences(vk->context.device, 1, next_fence); + vk->context.swapchain_fences_signalled[index] = false; } else vkCreateFence(vk->context.device, &fence_info, NULL, next_fence); diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 04785517fd..26ade3cd30 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -109,6 +109,7 @@ typedef struct vulkan_context VkImage swapchain_images[VULKAN_MAX_SWAPCHAIN_IMAGES]; VkFence swapchain_fences[VULKAN_MAX_SWAPCHAIN_IMAGES]; + bool swapchain_fences_signalled[VULKAN_MAX_SWAPCHAIN_IMAGES]; VkSemaphore swapchain_semaphores[VULKAN_MAX_SWAPCHAIN_IMAGES]; VkFormat swapchain_format; diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 45be4a4e70..1e14aeb11b 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1569,6 +1569,7 @@ static void vulkan_inject_black_frame(vk_t *vk, video_frame_info_t *video_info) #endif vkQueueSubmit(vk->context->queue, 1, &submit_info, vk->context->swapchain_fences[frame_index]); + vk->context->swapchain_fences_signalled[frame_index] = true; #ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); #endif @@ -1935,6 +1936,7 @@ static bool vulkan_frame(void *data, const void *frame, #endif vkQueueSubmit(vk->context->queue, 1, &submit_info, vk->context->swapchain_fences[frame_index]); + vk->context->swapchain_fences_signalled[frame_index] = true; #ifdef HAVE_THREADS slock_unlock(vk->context->queue_lock); #endif From ac42b874009dfdf7cdd203d764dad5956a1df4c8 Mon Sep 17 00:00:00 2001 From: Themaister Date: Fri, 8 Dec 2017 14:52:53 +0100 Subject: [PATCH 152/698] Recreate swapchain directly if vkAcquireNextImageKHR fails. --- gfx/common/vulkan_common.c | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 314f0f415d..970c228380 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -2263,7 +2263,9 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk) VkFenceCreateInfo fence_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; VkFence *next_fence = NULL; + bool is_retrying = false; +retry: vkCreateFence(vk->context.device, &fence_info, NULL, &fence); err = vkAcquireNextImageKHR(vk->context.device, @@ -2293,8 +2295,27 @@ void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk) if (err != VK_SUCCESS) { - RARCH_LOG("[Vulkan]: AcquireNextImage failed, invalidating swapchain.\n"); - vk->context.invalid_swapchain = true; + if (is_retrying) + { + RARCH_ERR("[Vulkan]: Tried acquring next swapchain image after creating new one, but failed ...\n"); + } + else + { + RARCH_LOG("[Vulkan]: AcquireNextImage failed, invalidating swapchain.\n"); + vk->context.invalid_swapchain = true; + + RARCH_LOG("[Vulkan]: AcquireNextImage failed, so trying to recreate swapchain.\n"); + if (!vulkan_create_swapchain(vk, vk->context.swapchain_width, + vk->context.swapchain_height, vk->context.swap_interval)) + { + RARCH_ERR("[Vulkan]: Failed to create new swapchain.\n"); + } + else + { + is_retrying = true; + goto retry; + } + } } } @@ -2517,6 +2538,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, vkDestroyFence(vk->context.device, vk->context.swapchain_fences[i], NULL); vk->context.swapchain_fences[i] = VK_NULL_HANDLE; + vk->context.swapchain_fences_signalled[i] = false; } } From 75b84b4f94e64cc1999332d7fadbfbd400d72dd8 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 9 Dec 2017 12:58:11 +0100 Subject: [PATCH 153/698] Support pending swapchain creation. --- gfx/common/vulkan_common.c | 131 ++++++++++++++++++----- gfx/drivers/vulkan.c | 145 ++++++++++++++------------ gfx/drivers_context/android_ctx.c | 1 + gfx/drivers_context/khr_display_ctx.c | 2 + gfx/drivers_context/wayland_ctx.c | 3 + gfx/drivers_context/wgl_ctx.c | 1 + gfx/drivers_context/x_ctx.c | 1 + 7 files changed, 194 insertions(+), 90 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index 970c228380..d7f9d2e239 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -28,6 +28,7 @@ #endif #include "vulkan_common.h" +#include "../../libretro-common/include/retro_timers.h" #include "../../configuration.h" static dylib_t vulkan_library; @@ -2162,6 +2163,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, vk, width, height, swap_interval)) return false; + vulkan_acquire_next_image(vk); return true; } @@ -2171,6 +2173,13 @@ void vulkan_present(gfx_ctx_vulkan_data_t *vk, unsigned index) VkResult result = VK_SUCCESS; VkResult err = VK_SUCCESS; + /* We're still waiting for a proper swapchain, so just fake it. */ + if (vk->swapchain == VK_NULL_HANDLE) + { + retro_sleep(10); + return; + } + present.swapchainCount = 1; present.pSwapchains = &vk->swapchain; present.pImageIndices = &index; @@ -2253,18 +2262,71 @@ void vulkan_context_destroy(gfx_ctx_vulkan_data_t *vk, } } +static void vulkan_acquire_clear_fences(gfx_ctx_vulkan_data_t *vk) +{ + unsigned i; + for (i = 0; i < vk->context.num_swapchain_images; i++) + { + if (vk->context.swapchain_fences[i]) + { + vkDestroyFence(vk->context.device, + vk->context.swapchain_fences[i], NULL); + vk->context.swapchain_fences[i] = VK_NULL_HANDLE; + vk->context.swapchain_fences_signalled[i] = false; + } + } +} + +static void vulkan_acquire_wait_fences(gfx_ctx_vulkan_data_t *vk) +{ + VkFenceCreateInfo fence_info = + { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; + + unsigned index = vk->context.current_swapchain_index; + VkFence *next_fence = &vk->context.swapchain_fences[index]; + + if (*next_fence != VK_NULL_HANDLE) + { + if (vk->context.swapchain_fences_signalled[index]) + vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX); + vkResetFences(vk->context.device, 1, next_fence); + vk->context.swapchain_fences_signalled[index] = false; + } + else + vkCreateFence(vk->context.device, &fence_info, NULL, next_fence); +} + void vulkan_acquire_next_image(gfx_ctx_vulkan_data_t *vk) { unsigned index; VkResult err; VkFence fence; - VkSemaphoreCreateInfo sem_info = - { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; VkFenceCreateInfo fence_info = { VK_STRUCTURE_TYPE_FENCE_CREATE_INFO }; - VkFence *next_fence = NULL; + VkSemaphoreCreateInfo sem_info = + { VK_STRUCTURE_TYPE_SEMAPHORE_CREATE_INFO }; bool is_retrying = false; + if (vk->swapchain == VK_NULL_HANDLE) + { + /* We don't have a swapchain, try to create one now. */ + if (!vulkan_create_swapchain(vk, vk->context.swapchain_width, + vk->context.swapchain_height, vk->context.swap_interval)) + { + RARCH_ERR("[Vulkan]: Failed to create new swapchain.\n"); + return; + } + + if (vk->swapchain == VK_NULL_HANDLE) + { + /* We still don't have a swapchain, so just fake it ... */ + vk->context.current_swapchain_index = 0; + vulkan_acquire_clear_fences(vk); + vulkan_acquire_wait_fences(vk); + return; + } + } + retry: vkCreateFence(vk->context.device, &fence_info, NULL, &fence); @@ -2281,17 +2343,7 @@ retry: vkWaitForFences(vk->context.device, 1, &fence, true, UINT64_MAX); vkDestroyFence(vk->context.device, fence, NULL); - next_fence = &vk->context.swapchain_fences[index]; - - if (*next_fence != VK_NULL_HANDLE) - { - if (vk->context.swapchain_fences_signalled[index]) - vkWaitForFences(vk->context.device, 1, next_fence, true, UINT64_MAX); - vkResetFences(vk->context.device, 1, next_fence); - vk->context.swapchain_fences_signalled[index] = false; - } - else - vkCreateFence(vk->context.device, &fence_info, NULL, next_fence); + vulkan_acquire_wait_fences(vk); if (err != VK_SUCCESS) { @@ -2430,6 +2482,43 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, else swapchain_size = surface_properties.currentExtent; +#if 0 + /* Tests for deferred creation. */ + static unsigned retry_count = 0; + if (++retry_count < 50) + { + surface_properties.maxImageExtent.width = 0; + surface_properties.maxImageExtent.height = 0; + surface_properties.minImageExtent.width = 0; + surface_properties.minImageExtent.height = 0; + } +#endif + + /* Clamp swapchain size to boundaries. */ + if (swapchain_size.width > surface_properties.maxImageExtent.width) + swapchain_size.width = surface_properties.maxImageExtent.width; + if (swapchain_size.width < surface_properties.minImageExtent.width) + swapchain_size.width = surface_properties.minImageExtent.width; + if (swapchain_size.height > surface_properties.maxImageExtent.height) + swapchain_size.height = surface_properties.maxImageExtent.height; + if (swapchain_size.height < surface_properties.minImageExtent.height) + swapchain_size.height = surface_properties.minImageExtent.height; + + if (swapchain_size.width == 0 && swapchain_size.height == 0) + { + /* Cannot create swapchain yet, try again later. */ + if (vk->swapchain != VK_NULL_HANDLE) + vkDestroySwapchainKHR(vk->context.device, vk->swapchain, NULL); + vk->swapchain = VK_NULL_HANDLE; + vk->context.swapchain_width = width; + vk->context.swapchain_height = height; + vk->context.num_swapchain_images = 1; + + memset(vk->context.swapchain_images, 0, sizeof(vk->context.swapchain_images)); + RARCH_LOG("[Vulkan]: Cannot create a swapchain yet. Will try again later ...\n"); + return true; + } + RARCH_LOG("[Vulkan]: Using swapchain size %u x %u.\n", swapchain_size.width, swapchain_size.height); @@ -2531,18 +2620,8 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, RARCH_LOG("[Vulkan]: Got %u swapchain images.\n", vk->context.num_swapchain_images); - for (i = 0; i < vk->context.num_swapchain_images; i++) - { - if (vk->context.swapchain_fences[i]) - { - vkDestroyFence(vk->context.device, - vk->context.swapchain_fences[i], NULL); - vk->context.swapchain_fences[i] = VK_NULL_HANDLE; - vk->context.swapchain_fences_signalled[i] = false; - } - } - - vulkan_acquire_next_image(vk); + vulkan_acquire_clear_fences(vk); + vk->context.invalid_swapchain = true; return true; } diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index 1e14aeb11b..dafcb40fb7 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -128,7 +128,14 @@ static void vulkan_init_framebuffers( VkFramebufferCreateInfo info = { VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO }; - vk->swapchain[i].backbuffer.image = vk->context->swapchain_images[i]; + vk->swapchain[i].backbuffer.image = vk->context->swapchain_images[i]; + + if (vk->context->swapchain_images[i] == VK_NULL_HANDLE) + { + vk->swapchain[i].backbuffer.view = VK_NULL_HANDLE; + vk->swapchain[i].backbuffer.framebuffer = VK_NULL_HANDLE; + continue; + } /* Create an image view which we can render into. */ view.viewType = VK_IMAGE_VIEW_TYPE_2D; @@ -716,10 +723,17 @@ static void vulkan_deinit_framebuffers(vk_t *vk) unsigned i; for (i = 0; i < vk->num_swapchain_images; i++) { - vkDestroyFramebuffer(vk->context->device, - vk->swapchain[i].backbuffer.framebuffer, NULL); - vkDestroyImageView(vk->context->device, - vk->swapchain[i].backbuffer.view, NULL); + if (vk->swapchain[i].backbuffer.framebuffer) + { + vkDestroyFramebuffer(vk->context->device, + vk->swapchain[i].backbuffer.framebuffer, NULL); + } + + if (vk->swapchain[i].backbuffer.view) + { + vkDestroyImageView(vk->context->device, + vk->swapchain[i].backbuffer.view, NULL); + } } vkDestroyRenderPass(vk->context->device, vk->render_pass, NULL); @@ -1748,88 +1762,92 @@ static bool vulkan_frame(void *data, const void *frame, (vulkan_filter_chain_t*)vk->filter_chain, vk->cmd, &vk->vk_vp); /* Render to backbuffer. */ - rp_info.renderPass = vk->render_pass; - rp_info.framebuffer = chain->backbuffer.framebuffer; - rp_info.renderArea.extent.width = vk->context->swapchain_width; - rp_info.renderArea.extent.height = vk->context->swapchain_height; - rp_info.clearValueCount = 1; - rp_info.pClearValues = &clear_color; + if (chain->backbuffer.image != VK_NULL_HANDLE) + { + rp_info.renderPass = vk->render_pass; + rp_info.framebuffer = chain->backbuffer.framebuffer; + rp_info.renderArea.extent.width = vk->context->swapchain_width; + rp_info.renderArea.extent.height = vk->context->swapchain_height; + rp_info.clearValueCount = 1; + rp_info.pClearValues = &clear_color; - clear_color.color.float32[0] = 0.0f; - clear_color.color.float32[1] = 0.0f; - clear_color.color.float32[2] = 0.0f; - clear_color.color.float32[3] = 0.0f; + clear_color.color.float32[0] = 0.0f; + clear_color.color.float32[1] = 0.0f; + clear_color.color.float32[2] = 0.0f; + clear_color.color.float32[3] = 0.0f; - /* Prepare backbuffer for rendering. We don't use WSI semaphores here. */ - vulkan_image_layout_transition(vk, vk->cmd, chain->backbuffer.image, - VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, - 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, - VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, - VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); + /* Prepare backbuffer for rendering. We don't use WSI semaphores here. */ + vulkan_image_layout_transition(vk, vk->cmd, chain->backbuffer.image, + VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + 0, VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | VK_ACCESS_COLOR_ATTACHMENT_READ_BIT, + VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, + VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT); - /* Begin render pass and set up viewport */ - vkCmdBeginRenderPass(vk->cmd, &rp_info, VK_SUBPASS_CONTENTS_INLINE); + /* Begin render pass and set up viewport */ + vkCmdBeginRenderPass(vk->cmd, &rp_info, VK_SUBPASS_CONTENTS_INLINE); - vulkan_filter_chain_build_viewport_pass( - (vulkan_filter_chain_t*)vk->filter_chain, vk->cmd, - &vk->vk_vp, vk->mvp.data); + vulkan_filter_chain_build_viewport_pass( + (vulkan_filter_chain_t*)vk->filter_chain, vk->cmd, + &vk->vk_vp, vk->mvp.data); #if defined(HAVE_MENU) - if (vk->menu.enable) - { - menu_driver_frame(video_info); - - if (vk->menu.textures[vk->menu.last_index].image != VK_NULL_HANDLE) + if (vk->menu.enable) { - struct vk_draw_quad quad; - struct vk_texture *optimal = &vk->menu.textures_optimal[vk->menu.last_index]; - vulkan_set_viewport(vk, width, height, vk->menu.full_screen, false); + menu_driver_frame(video_info); - quad.pipeline = vk->pipelines.alpha_blend; - quad.texture = &vk->menu.textures[vk->menu.last_index]; - - if (optimal->memory != VK_NULL_HANDLE) + if (vk->menu.textures[vk->menu.last_index].image != VK_NULL_HANDLE) { - if (vk->menu.dirty[vk->menu.last_index]) + struct vk_draw_quad quad; + struct vk_texture *optimal = &vk->menu.textures_optimal[vk->menu.last_index]; + vulkan_set_viewport(vk, width, height, vk->menu.full_screen, false); + + quad.pipeline = vk->pipelines.alpha_blend; + quad.texture = &vk->menu.textures[vk->menu.last_index]; + + if (optimal->memory != VK_NULL_HANDLE) { - vulkan_copy_staging_to_dynamic(vk, vk->cmd, - optimal, - quad.texture); - vk->menu.dirty[vk->menu.last_index] = false; + if (vk->menu.dirty[vk->menu.last_index]) + { + vulkan_copy_staging_to_dynamic(vk, vk->cmd, + optimal, + quad.texture); + vk->menu.dirty[vk->menu.last_index] = false; + } + quad.texture = optimal; } - quad.texture = optimal; + + quad.sampler = optimal->mipmap ? + vk->samplers.mipmap_linear : vk->samplers.linear; + + quad.mvp = &vk->mvp_no_rot; + quad.color.r = 1.0f; + quad.color.g = 1.0f; + quad.color.b = 1.0f; + quad.color.a = vk->menu.alpha; + vulkan_draw_quad(vk, &quad); } - - quad.sampler = optimal->mipmap ? - vk->samplers.mipmap_linear : vk->samplers.linear; - - quad.mvp = &vk->mvp_no_rot; - quad.color.r = 1.0f; - quad.color.g = 1.0f; - quad.color.b = 1.0f; - quad.color.a = vk->menu.alpha; - vulkan_draw_quad(vk, &quad); } - } #endif - if (msg) - font_driver_render_msg(video_info, NULL, msg, NULL); + if (msg) + font_driver_render_msg(video_info, NULL, msg, NULL); #ifdef HAVE_OVERLAY - if (vk->overlay.enable) - vulkan_render_overlay(vk, video_info); + if (vk->overlay.enable) + vulkan_render_overlay(vk, video_info); #endif - /* End the render pass. We're done rendering to backbuffer now. */ - vkCmdEndRenderPass(vk->cmd); + /* End the render pass. We're done rendering to backbuffer now. */ + vkCmdEndRenderPass(vk->cmd); + } /* End the filter chain frame. * This must happen outside a render pass. */ vulkan_filter_chain_end_frame((vulkan_filter_chain_t*)vk->filter_chain, vk->cmd); - if (vk->readback.pending || vk->readback.streamed) + if (chain->backbuffer.image != VK_NULL_HANDLE && + (vk->readback.pending || vk->readback.streamed)) { /* We cannot safely read back from an image which * has already been presented as we need to @@ -1860,7 +1878,7 @@ static bool vulkan_frame(void *data, const void *frame, vk->readback.pending = false; } - else + else if (chain->backbuffer.image != VK_NULL_HANDLE) { /* Prepare backbuffer for presentation. */ vulkan_image_layout_transition(vk, vk->cmd, @@ -1930,7 +1948,6 @@ static bool vulkan_frame(void *data, const void *frame, } submit_info.pSignalSemaphores = submit_info.signalSemaphoreCount ? signal_semaphores : NULL; - #ifdef HAVE_THREADS slock_lock(vk->context->queue_lock); #endif diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index d2212f94c9..341aa465c6 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -281,6 +281,7 @@ static bool android_gfx_ctx_set_resize(void *data, return false; } + vulkan_acquire_next_image(&and->vk); and->vk.context.invalid_swapchain = true; and->vk.need_new_swapchain = false; #endif diff --git a/gfx/drivers_context/khr_display_ctx.c b/gfx/drivers_context/khr_display_ctx.c index 745d770055..53e3bfb528 100644 --- a/gfx/drivers_context/khr_display_ctx.c +++ b/gfx/drivers_context/khr_display_ctx.c @@ -103,6 +103,8 @@ static bool gfx_ctx_khr_display_set_resize(void *data, return false; } + vulkan_acquire_next_image(&khr->vk); + khr->vk.context.invalid_swapchain = true; khr->vk.need_new_swapchain = false; return false; diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index 6c7b8be4be..cde0887fb0 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -684,7 +684,10 @@ static bool gfx_ctx_wl_set_resize(void *data, unsigned width, unsigned height) wl->height = height; if (vulkan_create_swapchain(&wl->vk, width, height, wl->swap_interval)) + { wl->vk.context.invalid_swapchain = true; + vulkan_acquire_next_image(&wl->vk); + } else { RARCH_ERR("[Wayland/Vulkan]: Failed to update swapchain.\n"); diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 39dbb26cdb..9b5e441503 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -395,6 +395,7 @@ static bool gfx_ctx_wgl_set_resize(void *data, return false; } + vulkan_acquire_next_image(&win32_vk); win32_vk.context.invalid_swapchain = true; win32_vk.need_new_swapchain = false; #endif diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 08e6b7bcef..1faa28b95f 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -448,6 +448,7 @@ static bool gfx_ctx_x_set_resize(void *data, return false; } + vulkan_acquire_next_image(&x->vk); x->vk.context.invalid_swapchain = true; x->vk.need_new_swapchain = false; } From f8447c46483ff4c97c0264ae6d89d892b862cf22 Mon Sep 17 00:00:00 2001 From: Themaister Date: Sat, 9 Dec 2017 15:59:21 +0100 Subject: [PATCH 154/698] Set correct buffer size. --- gfx/common/vulkan_common.c | 2 +- gfx/common/vulkan_common.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index d7f9d2e239..cab3af0bd3 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -987,7 +987,7 @@ struct vk_buffer vulkan_create_buffer( vkAllocateMemory(context->device, &alloc, NULL, &buffer.memory); vkBindBufferMemory(context->device, buffer.buffer, buffer.memory, 0); - buffer.size = alloc.allocationSize; + buffer.size = size; vkMapMemory(context->device, buffer.memory, 0, buffer.size, 0, &buffer.mapped); diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 26ade3cd30..732e7173e1 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -22,7 +22,7 @@ #define VULKAN_DESCRIPTOR_MANAGER_BLOCK_SETS 16 #define VULKAN_MAX_DESCRIPTOR_POOL_SIZES 16 -#define VULKAN_BUFFER_BLOCK_SIZE (4 * 1024) +#define VULKAN_BUFFER_BLOCK_SIZE (64 * 1024) #define VULKAN_MAX_SWAPCHAIN_IMAGES 8 From 3318cd969ba826c6b1dadb2d67bc39d2b3423bca Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 9 Dec 2017 14:26:21 -0500 Subject: [PATCH 155/698] win95: fallback to strdup when MultiByteToWideChar fails (it only works with MSLU) --- libretro-common/encodings/encoding_utf.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libretro-common/encodings/encoding_utf.c b/libretro-common/encodings/encoding_utf.c index 2148fcb470..11cf363de1 100644 --- a/libretro-common/encodings/encoding_utf.c +++ b/libretro-common/encodings/encoding_utf.c @@ -297,6 +297,10 @@ static char* mb_to_mb_string_alloc(const char *str, return strdup(str); #else + /* Windows 95 will return 0 from these functions with a UTF8 codepage set without MSLU. From an unknown MSDN version (others omit this info): + * - CP_UTF8 Windows 98/Me, Windows NT 4.0 and later: Translate using UTF-8. When this is set, dwFlags must be zero. + * - Windows 95: Under the Microsoft Layer for Unicode, MultiByteToWideChar also supports CP_UTF7 and CP_UTF8. + */ path_buf_wide_len = MultiByteToWideChar(cp_in, 0, str, -1, NULL, 0); if (path_buf_wide_len) @@ -334,9 +338,16 @@ static char* mb_to_mb_string_alloc(const char *str, return NULL; } } + else + { + free(path_buf_wide); + return strdup(str); + } } } } + else + return strdup(str); if (path_buf_wide) free(path_buf_wide); @@ -385,6 +396,8 @@ wchar_t* utf8_to_utf16_string_alloc(const char *str) out_len = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len); } + else + return strdup(str); if (out_len < 0) { @@ -442,6 +455,8 @@ char* utf16_to_utf8_string_alloc(const wchar_t *str) out_len = WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL); } + else + return strdup(str); if (out_len < 0) { From 812a99e5ca580c4fac1b80e6d9a14fc8054c98f2 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 9 Dec 2017 14:35:58 -0500 Subject: [PATCH 156/698] utf: fallback to ANSI codepage on windows if UTF8 conversion isn't available --- libretro-common/encodings/encoding_utf.c | 30 ++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/libretro-common/encodings/encoding_utf.c b/libretro-common/encodings/encoding_utf.c index 11cf363de1..6a89da543f 100644 --- a/libretro-common/encodings/encoding_utf.c +++ b/libretro-common/encodings/encoding_utf.c @@ -397,7 +397,20 @@ wchar_t* utf8_to_utf16_string_alloc(const char *str) out_len = MultiByteToWideChar(CP_UTF8, 0, str, -1, buf, len); } else - return strdup(str); + { + /* fallback to ANSI codepage instead */ + len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0); + + if (len) + { + buf = (wchar_t*)calloc(len, sizeof(wchar_t)); + + if (!buf) + return NULL; + + out_len = MultiByteToWideChar(CP_ACP, 0, str, -1, buf, len); + } + } if (out_len < 0) { @@ -456,7 +469,20 @@ char* utf16_to_utf8_string_alloc(const wchar_t *str) out_len = WideCharToMultiByte(CP_UTF8, 0, str, -1, buf, len, NULL, NULL); } else - return strdup(str); + { + /* fallback to ANSI codepage instead */ + len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL); + + if (len) + { + buf = (char*)calloc(len, sizeof(char)); + + if (!buf) + return NULL; + + out_len = WideCharToMultiByte(CP_ACP, 0, str, -1, buf, len, NULL, NULL); + } + } if (out_len < 0) { From cfde6a44db7304e6eac4f9cabc65b8e4590d3d21 Mon Sep 17 00:00:00 2001 From: Monroe88 Date: Sat, 9 Dec 2017 14:17:54 -0600 Subject: [PATCH 157/698] input_driver: Map Delete key to Y button for non-unified menu keyboard controls --- input/input_driver.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/input/input_driver.c b/input/input_driver.c index 0866d5e890..bbd4ed099b 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -968,7 +968,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) if (!menu_input_dialog_get_display_kb()) { - unsigned ids[13][2]; + unsigned ids[14][2]; const struct retro_keybind *quitkey = &input_config_binds[0][RARCH_QUIT_KEY]; const struct retro_keybind *fskey = &input_config_binds[0][RARCH_FULLSCREEN_TOGGLE_KEY]; @@ -998,6 +998,8 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) ids[11][1] = RETRO_DEVICE_ID_JOYPAD_B; ids[12][0] = RETROK_RETURN; ids[12][1] = RETRO_DEVICE_ID_JOYPAD_A; + ids[13][0] = RETROK_DELETE; + ids[13][1] = RETRO_DEVICE_ID_JOYPAD_Y; if (settings->bools.input_menu_swap_ok_cancel_buttons) { @@ -1005,7 +1007,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) ids[12][1] = RETRO_DEVICE_ID_JOYPAD_B; } - for (i = 0; i < 13; i++) + for (i = 0; i < 14; i++) { if (current_input->input_state(current_input_data, joypad_info, binds, 0, From 1a928b9c5045dc518ad742305999f3ea0f0a4809 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sat, 9 Dec 2017 16:38:33 -0500 Subject: [PATCH 158/698] omit extra slash at end of path, Win95/98 doesn't like them --- libretro-common/file/retro_dirent.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libretro-common/file/retro_dirent.c b/libretro-common/file/retro_dirent.c index aa221c888c..0b716e6e56 100644 --- a/libretro-common/file/retro_dirent.c +++ b/libretro-common/file/retro_dirent.c @@ -103,6 +103,7 @@ struct RDIR *retro_opendir(const char *name) char path_buf[1024]; char *path_local = NULL; wchar_t *path_wide = NULL; + unsigned path_len; #endif struct RDIR *rdir = (struct RDIR*)calloc(1, sizeof(*rdir)); @@ -114,7 +115,13 @@ struct RDIR *retro_opendir(const char *name) (void)path_local; path_buf[0] = '\0'; - snprintf(path_buf, sizeof(path_buf), "%s\\*", name); + path_len = strlen(name); + + /* Non-NT platforms don't like extra slashes in the path */ + if (name[path_len - 1] == '\\') + snprintf(path_buf, sizeof(path_buf), "%s*", name); + else + snprintf(path_buf, sizeof(path_buf), "%s\\*", name); #if defined(LEGACY_WIN32) path_local = utf8_to_local_string_alloc(path_buf); rdir->directory = FindFirstFile(path_local, &rdir->entry); From d6fd9f0cc1ced58bcb75258bbf898c1ed09bd577 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 01:19:58 +0100 Subject: [PATCH 159/698] Add fallback AF_INET6 path --- libretro-common/net/net_compat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libretro-common/net/net_compat.c b/libretro-common/net/net_compat.c index 13fdbfff87..8ef567eb88 100644 --- a/libretro-common/net/net_compat.c +++ b/libretro-common/net/net_compat.c @@ -211,7 +211,13 @@ int getaddrinfo_retro(const char *node, const char *service, goto error; in_addr->sin_family = host->h_addrtype; + +#ifdef AF_INET6 + /* TODO/FIXME - In case we ever want to support IPv6 */ + in_addr->sin_addr.s_addr = inet_addr(host->h_addr_list[0]); +#else memcpy(&in_addr->sin_addr, host->h_addr, host->h_length); +#endif } else goto error; From e07ed18105420db831d6c8965f30c515934d784c Mon Sep 17 00:00:00 2001 From: Alcaro Date: Sun, 10 Dec 2017 21:00:24 +0100 Subject: [PATCH 160/698] Fix text mode dependency --- libretro-common/file/config_file.c | 4 +++- playlist.c | 8 ++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index cf105bbc3a..d345338bfe 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -107,7 +107,9 @@ static char *getaline(RFILE *file) newline = newline_tmp; } - newline[idx++] = in; + /* ignore MS line endings */ + if (in != '\r') + newline[idx++] = in; in = filestream_getc(file); } newline[idx] = '\0'; diff --git a/playlist.c b/playlist.c index 7406e75df0..1911fb799e 100644 --- a/playlist.c +++ b/playlist.c @@ -519,10 +519,10 @@ static bool playlist_read_file( /* Read playlist entry and terminate string with NUL character * regardless of Windows or Unix line endings */ - if((last = strrchr(buf[i], '\r'))) - *last = '\0'; - else if((last = strrchr(buf[i], '\n'))) - *last = '\0'; + if((last = strrchr(buf[i], '\r'))) + *last = '\0'; + else if((last = strrchr(buf[i], '\n'))) + *last = '\0'; } entry = &playlist->entries[playlist->size]; From 95cc8e12d266914d25d63fde376930eb8eaf8119 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 21:28:13 +0100 Subject: [PATCH 161/698] Get rid of RFILE_MODE_READ_TEXT dependency for config file/playlist --- libretro-common/file/config_file.c | 2 +- playlist.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index d345338bfe..e613f02a34 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -392,7 +392,7 @@ static config_file_t *config_file_new_internal( goto error; conf->include_depth = depth; - file = filestream_open(path, RFILE_MODE_READ_TEXT, 0x4000); + file = filestream_open(path, RFILE_MODE_READ, 0x4000); if (!file) { diff --git a/playlist.c b/playlist.c index 1911fb799e..13154d6bbe 100644 --- a/playlist.c +++ b/playlist.c @@ -493,7 +493,7 @@ static bool playlist_read_file( unsigned i; char buf[PLAYLIST_ENTRIES][1024]; RFILE *file = filestream_open( - path, RFILE_MODE_READ_TEXT, -1); + path, RFILE_MODE_READ, -1); for (i = 0; i < PLAYLIST_ENTRIES; i++) buf[i][0] = '\0'; From 9d54da14b68c93b6b4c6ddcda2afcb78d6c8e8db Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 21:29:49 +0100 Subject: [PATCH 162/698] Get rid of READ_TEXT requirement for features_cpu --- libretro-common/features/features_cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index 94bf644b1f..aa43eaa2d2 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -320,7 +320,7 @@ static unsigned char check_arm_cpu_feature(const char* feature) { char line[1024]; unsigned char status = 0; - RFILE *fp = filestream_open("/proc/cpuinfo", RFILE_MODE_READ_TEXT, -1); + RFILE *fp = filestream_open("/proc/cpuinfo", RFILE_MODE_READ, -1); if (!fp) return 0; From 40f82c26f7e7ca6cf9ea80fe1323c0a95861d2b2 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:01:48 +0100 Subject: [PATCH 163/698] use RFILE_MODE_READ for video_shader_parse --- gfx/video_shader_parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 26aee9aedd..5b88be1608 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -545,7 +545,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, /* If that doesn't work, fallback to the old path. * Ideally, we'd get rid of this path sooner or later. */ #endif - file = filestream_open(path, RFILE_MODE_READ_TEXT, -1); + file = filestream_open(path, RFILE_MODE_READ, -1); if (!file) { From a8e031777e38dcf6e42cc246db0b627dc2b578b6 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:05:24 +0100 Subject: [PATCH 164/698] * Get rid of RFILE_MODE_READ_TEXT * Get rid of PSP ifdef sinside file_stream.c --- libretro-common/include/streams/file_stream.h | 1 - libretro-common/streams/file_stream.c | 79 ++----------------- .../streams/file_stream_transforms.c | 2 +- 3 files changed, 7 insertions(+), 75 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 06cdf33ded..85f086b030 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -41,7 +41,6 @@ typedef struct RFILE RFILE; enum { RFILE_MODE_READ = 0, - RFILE_MODE_READ_TEXT, RFILE_MODE_WRITE, RFILE_MODE_READ_WRITE, diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index da29d4864d..553b087bb6 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -86,9 +86,6 @@ struct RFILE char *ext; int64_t size; FILE *fp; -#if defined(PSP) - SceUID fd; -#else #define HAVE_BUFFERED_IO 1 @@ -110,7 +107,6 @@ struct RFILE uint64_t mapsize; #endif int fd; -#endif char *buf; }; @@ -185,36 +181,22 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) switch (mode & 0xff) { case RFILE_MODE_READ_TEXT: -#if defined(PSP) - mode_int = 0666; - flags = PSP_O_RDONLY; -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ; #endif /* No "else" here */ flags = O_RDONLY; -#endif break; case RFILE_MODE_READ: -#if defined(PSP) - mode_int = 0666; - flags = PSP_O_RDONLY; -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ_UNBUF; #endif /* No "else" here */ flags = O_RDONLY; -#endif break; case RFILE_MODE_WRITE: -#if defined(PSP) - mode_int = 0666; - flags = PSP_O_CREAT | PSP_O_WRONLY | PSP_O_TRUNC; -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_UNBUF; @@ -226,13 +208,8 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) flags |= S_IRUSR | S_IWUSR; #endif } -#endif break; case RFILE_MODE_READ_WRITE: -#if defined(PSP) - mode_int = 0666; - flags = PSP_O_RDWR; -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_PLUS; @@ -244,16 +221,9 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) flags |= O_BINARY; #endif } -#endif break; } -#if defined(PSP) - stream->fd = sceIoOpen(path, flags, mode_int); - - if (stream->fd < 0) - goto error; -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0 && mode_str) { @@ -335,7 +305,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) } #endif } -#endif { const char *ld = (const char*)strrchr(path, '.'); @@ -391,15 +360,7 @@ char *filestream_gets(RFILE *stream, char *s, size_t len) { if (!stream) return NULL; -#if defined(HAVE_BUFFERED_IO) return fgets(s, (int)len, stream->fp); -#elif defined(PSP) - if(filestream_read(stream,s,len)==len) - return s; - return NULL; -#else - return gets(s); -#endif } int filestream_getc(RFILE *stream) @@ -408,15 +369,7 @@ int filestream_getc(RFILE *stream) (void)c; if (!stream) return 0; -#if defined(HAVE_BUFFERED_IO) - return fgetc(stream->fp); -#elif defined(PSP) - if(filestream_read(stream, &c, 1) == 1) - return (int)c; - return EOF; -#else - return getc(stream->fd); -#endif + return fgetc(stream->fp); } ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) @@ -424,11 +377,6 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) if (!stream) goto error; -#if defined(PSP) - if (sceIoLseek(stream->fd, (SceOff)offset, whence) == -1) - goto error; -#else - #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fseek(stream->fp, (long)offset, whence); @@ -472,8 +420,6 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) if (lseek(stream->fd, offset, whence) < 0) goto error; -#endif - return 0; error: @@ -508,10 +454,7 @@ ssize_t filestream_tell(RFILE *stream) { if (!stream) goto error; -#if defined(PSP) - if (sceIoLseek(stream->fd, 0, SEEK_CUR) < 0) - goto error; -#else + #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return ftell(stream->fp); @@ -524,7 +467,6 @@ ssize_t filestream_tell(RFILE *stream) #endif if (lseek(stream->fd, 0, SEEK_CUR) < 0) goto error; -#endif return 0; @@ -541,13 +483,12 @@ ssize_t filestream_read(RFILE *stream, void *s, size_t len) { if (!stream || !s) goto error; -#if defined(PSP) - return sceIoRead(stream->fd, s, len); -#else + #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fread(s, 1, len, stream->fp); #endif + #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) { @@ -563,8 +504,8 @@ ssize_t filestream_read(RFILE *stream, void *s, size_t len) return len; } #endif + return read(stream->fd, s, len); -#endif error: return -1; @@ -583,9 +524,7 @@ ssize_t filestream_write(RFILE *stream, const void *s, size_t len) { if (!stream) goto error; -#if defined(PSP) - return sceIoWrite(stream->fd, s, len); -#else + #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fwrite(s, 1, len, stream->fp); @@ -595,7 +534,6 @@ ssize_t filestream_write(RFILE *stream, const void *s, size_t len) goto error; #endif return write(stream->fd, s, len); -#endif error: return -1; @@ -655,10 +593,6 @@ int filestream_close(RFILE *stream) if (!string_is_empty(stream->ext)) free(stream->ext); -#if defined(PSP) - if (stream->fd > 0) - sceIoClose(stream->fd); -#else #if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { @@ -674,7 +608,6 @@ int filestream_close(RFILE *stream) if (stream->fd > 0) close(stream->fd); -#endif if (stream->buf) free(stream->buf); free(stream); diff --git a/libretro-common/streams/file_stream_transforms.c b/libretro-common/streams/file_stream_transforms.c index d1e8f2f26e..cec3a4c458 100644 --- a/libretro-common/streams/file_stream_transforms.c +++ b/libretro-common/streams/file_stream_transforms.c @@ -26,7 +26,7 @@ RFILE* rfopen(const char *path, const char *mode) { - unsigned int retro_mode = RFILE_MODE_READ_TEXT; + unsigned int retro_mode = 0; if (strstr(mode, "r")) if (strstr(mode, "b")) retro_mode = RFILE_MODE_READ; From 1298a257ae14871941d2bbac247dd7016ad21694 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:07:42 +0100 Subject: [PATCH 165/698] Make HAVE_BUFFERED_IO the new default --- libretro-common/streams/file_stream.c | 61 ++++++--------------------- 1 file changed, 13 insertions(+), 48 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 553b087bb6..1b342290ca 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -87,8 +87,6 @@ struct RFILE int64_t size; FILE *fp; -#define HAVE_BUFFERED_IO 1 - #if !defined(_WIN32) || defined(LEGACY_WIN32) #define MODE_STR_READ "r" #define MODE_STR_READ_UNBUF "rb" @@ -148,19 +146,17 @@ void filestream_set_size(RFILE *stream) **/ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) { - int flags = 0; - int mode_int = 0; -#if defined(HAVE_BUFFERED_IO) + int flags = 0; + int mode_int = 0; #if !defined(_WIN32) || defined(LEGACY_WIN32) - const char *mode_str = NULL; + const char *mode_str = NULL; #else const wchar_t *mode_str = NULL; #endif -#endif - RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); + RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); #if defined(_WIN32) && !defined(_XBOX) - char *path_local = NULL; - wchar_t *path_wide = NULL; + char *path_local = NULL; + wchar_t *path_wide = NULL; #endif if (!stream) @@ -181,26 +177,20 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) switch (mode & 0xff) { case RFILE_MODE_READ_TEXT: -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ; -#endif /* No "else" here */ flags = O_RDONLY; break; case RFILE_MODE_READ: -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ_UNBUF; -#endif /* No "else" here */ flags = O_RDONLY; break; case RFILE_MODE_WRITE: -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_UNBUF; -#endif else { flags = O_WRONLY | O_CREAT | O_TRUNC; @@ -210,10 +200,8 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) } break; case RFILE_MODE_READ_WRITE: -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_PLUS; -#endif else { flags = O_RDWR; @@ -224,7 +212,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) break; } -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0 && mode_str) { #if defined(_WIN32) && !defined(_XBOX) @@ -262,7 +249,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) setvbuf(stream->fp, stream->buf, _IOFBF, 0x4000); } else -#endif { #if defined(_WIN32) && !defined(_XBOX) #if defined(LEGACY_WIN32) @@ -279,7 +265,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) free(path_wide); #endif #else - /* FIXME: HAVE_BUFFERED_IO is always 1, but if it is ever changed, this open() needs to have an alternate _wopen() for Windows. */ stream->fd = open(path, flags, mode_int); #endif @@ -377,10 +362,8 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) if (!stream) goto error; -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fseek(stream->fp, (long)offset, whence); -#endif #ifdef HAVE_MMAP /* Need to check stream->mapped because this function is @@ -455,10 +438,9 @@ ssize_t filestream_tell(RFILE *stream) if (!stream) goto error; -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return ftell(stream->fp); -#endif + #ifdef HAVE_MMAP /* Need to check stream->mapped because this function * is called in filestream_open() */ @@ -484,10 +466,8 @@ ssize_t filestream_read(RFILE *stream, void *s, size_t len) if (!stream || !s) goto error; -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fread(s, 1, len, stream->fp); -#endif #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) @@ -513,11 +493,7 @@ error: int filestream_flush(RFILE *stream) { -#if defined(HAVE_BUFFERED_IO) return fflush(stream->fp); -#else - return 0; -#endif } ssize_t filestream_write(RFILE *stream, const void *s, size_t len) @@ -525,10 +501,9 @@ ssize_t filestream_write(RFILE *stream, const void *s, size_t len) if (!stream) goto error; -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) return fwrite(s, 1, len, stream->fp); -#endif + #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) goto error; @@ -544,22 +519,17 @@ int filestream_putc(RFILE *stream, int c) if (!stream) return EOF; -#if defined(HAVE_BUFFERED_IO) return fputc(c, stream->fp); -#else - /* unimplemented */ - return EOF; -#endif } int filestream_vprintf(RFILE *stream, const char* format, va_list args) { static char buffer[8 * 1024]; - int numChars = vsprintf(buffer, format, args); + int num_chars = vsprintf(buffer, format, args); - if (numChars < 0) + if (num_chars < 0) return -1; - else if (numChars == 0) + else if (num_chars == 0) return 0; return filestream_write(stream, buffer, numChars); @@ -577,12 +547,7 @@ int filestream_printf(RFILE *stream, const char* format, ...) int filestream_error(RFILE *stream) { -#if defined(HAVE_BUFFERED_IO) return ferror(stream->fp); -#else - /* stub */ - return 0; -#endif } int filestream_close(RFILE *stream) @@ -593,18 +558,18 @@ int filestream_close(RFILE *stream) if (!string_is_empty(stream->ext)) free(stream->ext); -#if defined(HAVE_BUFFERED_IO) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { if (stream->fp) fclose(stream->fp); } else -#endif + { #ifdef HAVE_MMAP if (stream->hints & RFILE_HINT_MMAP) munmap(stream->mapped, stream->mapsize); #endif + } if (stream->fd > 0) close(stream->fd); From d19eaeaab8d6a24a85e5cda7077eccd1c06be469 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:10:32 +0100 Subject: [PATCH 166/698] (file_stream.c) Cleanups; buildfix --- libretro-common/streams/file_stream.c | 36 ++++++++------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 1b342290ca..6f3ce60e6f 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -147,22 +147,16 @@ void filestream_set_size(RFILE *stream) RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) { int flags = 0; - int mode_int = 0; #if !defined(_WIN32) || defined(LEGACY_WIN32) const char *mode_str = NULL; #else const wchar_t *mode_str = NULL; #endif RFILE *stream = (RFILE*)calloc(1, sizeof(*stream)); -#if defined(_WIN32) && !defined(_XBOX) - char *path_local = NULL; - wchar_t *path_wide = NULL; -#endif if (!stream) return NULL; - (void)mode_int; (void)flags; stream->hints = mode; @@ -176,12 +170,6 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) switch (mode & 0xff) { - case RFILE_MODE_READ_TEXT: - if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) - mode_str = MODE_STR_READ; - /* No "else" here */ - flags = O_RDONLY; - break; case RFILE_MODE_READ: if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ_UNBUF; @@ -215,16 +203,14 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0 && mode_str) { #if defined(_WIN32) && !defined(_XBOX) - (void)path_local; - (void)path_wide; #if defined(LEGACY_WIN32) - path_local = utf8_to_local_string_alloc(path); - stream->fp = fopen(path_local, mode_str); + char *path_local = utf8_to_local_string_alloc(path); + stream->fp = fopen(path_local, mode_str); if (path_local) free(path_local); #else - path_wide = utf8_to_utf16_string_alloc(path); - stream->fp = _wfopen(path_wide, mode_str); + wchar_t * path_wide = utf8_to_utf16_string_alloc(path); + stream->fp = _wfopen(path_wide, mode_str); if (path_wide) free(path_wide); #endif @@ -252,20 +238,18 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) { #if defined(_WIN32) && !defined(_XBOX) #if defined(LEGACY_WIN32) - (void)path_wide; - path_local = utf8_to_local_string_alloc(path); - stream->fd = open(path_local, flags, mode_int); + char *path_local = utf8_to_local_string_alloc(path); + stream->fd = open(path_local, flags, 0); if (path_local) free(path_local); #else - (void)path_local; - path_wide = utf8_to_utf16_string_alloc(path); - stream->fd = _wopen(path_wide, flags, mode_int); + wchar_t * path_wide = utf8_to_utf16_string_alloc(path); + stream->fd = _wopen(path_wide, flags, 0); if (path_wide) free(path_wide); #endif #else - stream->fd = open(path, flags, mode_int); + stream->fd = open(path, flags, 0); #endif if (stream->fd == -1) @@ -532,7 +516,7 @@ int filestream_vprintf(RFILE *stream, const char* format, va_list args) else if (num_chars == 0) return 0; - return filestream_write(stream, buffer, numChars); + return filestream_write(stream, buffer, num_chars); } int filestream_printf(RFILE *stream, const char* format, ...) From 2e979ec53746b8693cc17ee843c18e2589a13354 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:25:38 +0100 Subject: [PATCH 167/698] Replace function signatures of file_stream file functions --- cheevos/cheevos.c | 3 ++- configuration.c | 9 ++++++--- gfx/drivers/gx_gfx.c | 2 +- gfx/video_shader_parse.c | 2 +- libretro-common/features/features_cpu.c | 3 ++- libretro-common/file/config_file.c | 3 ++- libretro-common/file/file_path.c | 2 +- libretro-common/formats/bmp/rbmp_encode.c | 2 +- libretro-common/formats/png/rpng_encode.c | 2 +- libretro-common/formats/xml/rxml.c | 2 +- libretro-common/hash/rhash.c | 2 +- libretro-common/include/streams/file_stream.h | 14 ++++++++------ libretro-common/include/streams/interface_stream.h | 2 +- libretro-common/streams/file_stream.c | 13 +++++++------ libretro-common/streams/interface_stream.c | 4 ++-- libretro-db/c_converter.c | 2 +- libretro-db/libretrodb.c | 4 ++-- libretro-db/lua/lua_converter.c | 3 ++- libretro-db/lua/testlib.c | 2 +- libretro-db/rmsgpack_test.c | 2 +- menu/menu_setting.c | 3 ++- movie.c | 4 ++-- playlist.c | 5 +++-- tasks/task_database.c | 6 +++--- tasks/task_database_cue.c | 9 ++++----- tasks/task_save.c | 9 ++++++--- 26 files changed, 64 insertions(+), 50 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 3e12224565..e92c796397 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2640,7 +2640,8 @@ static int cheevos_iterate(coro_t* coro) /* Load the content into memory, or copy it over to our own buffer */ if (!CHEEVOS_VAR_DATA) { - CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, RFILE_MODE_READ, -1); + CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, + RFILE_MODE_READ, RFILE_HINT_NONE); if (!CHEEVOS_VAR_STREAM) CORO_STOP(); diff --git a/configuration.c b/configuration.c index 8edb392412..bb4ef4cc3e 100644 --- a/configuration.c +++ b/configuration.c @@ -3791,15 +3791,18 @@ bool config_save_file(const char *path) #ifdef HAVE_LAKKA if (settings->bools.ssh_enable) - filestream_close(filestream_open(LAKKA_SSH_PATH, RFILE_MODE_WRITE, -1)); + filestream_close(filestream_open(LAKKA_SSH_PATH, + RFILE_MODE_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_SSH_PATH); if (settings->bools.samba_enable) - filestream_close(filestream_open(LAKKA_SAMBA_PATH, RFILE_MODE_WRITE, -1)); + filestream_close(filestream_open(LAKKA_SAMBA_PATH, + RFILE_MODE_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_SAMBA_PATH); if (settings->bools.bluetooth_enable) - filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH, RFILE_MODE_WRITE, -1)); + filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH, + RFILE_MODE_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_BLUETOOTH_PATH); #endif diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index bf7727909e..0aa1e9c976 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -719,7 +719,7 @@ static void gx_efb_screenshot(void) { int x, y; uint8_t tga_header[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x18, 0x00}; - RFILE *out = filestream_open("/screenshot.tga", RFILE_MODE_WRITE, -1); + RFILE *out = filestream_open("/screenshot.tga", RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!out) return; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 5b88be1608..0d3a6434cb 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -545,7 +545,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, /* If that doesn't work, fallback to the old path. * Ideally, we'd get rid of this path sooner or later. */ #endif - file = filestream_open(path, RFILE_MODE_READ, -1); + file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!file) { diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index aa43eaa2d2..a52df70056 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -320,7 +320,8 @@ static unsigned char check_arm_cpu_feature(const char* feature) { char line[1024]; unsigned char status = 0; - RFILE *fp = filestream_open("/proc/cpuinfo", RFILE_MODE_READ, -1); + RFILE *fp = filestream_open("/proc/cpuinfo", + RFILE_MODE_READ, RFILE_HINT_NONE); if (!fp) return 0; diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index e613f02a34..b4d7251d1a 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -392,7 +392,8 @@ static config_file_t *config_file_new_internal( goto error; conf->include_depth = depth; - file = filestream_open(path, RFILE_MODE_READ, 0x4000); + file = filestream_open(path, + RFILE_MODE_READ, RFILE_HINT_NONE); if (!file) { diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index 8d9f8414b2..f5493017e5 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -410,7 +410,7 @@ bool path_file_exists(const char *path) if (!path || !*path) return false; - dummy = filestream_open(path, RFILE_MODE_READ, -1); + dummy = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!dummy) return false; diff --git a/libretro-common/formats/bmp/rbmp_encode.c b/libretro-common/formats/bmp/rbmp_encode.c index 9c2e199ab0..9a30b27a92 100644 --- a/libretro-common/formats/bmp/rbmp_encode.c +++ b/libretro-common/formats/bmp/rbmp_encode.c @@ -215,7 +215,7 @@ bool rbmp_save_image( unsigned pitch, enum rbmp_source_type type) { bool ret = false; - RFILE *file = filestream_open(filename, RFILE_MODE_WRITE, -1); + RFILE *file = filestream_open(filename, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!file) return false; diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index fe46e03598..ab67614a73 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -227,7 +227,7 @@ static bool rpng_save_image(const char *path, void *stream = NULL; uint32_t total_in = 0; uint32_t total_out = 0; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, -1); + RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!file) GOTO_END_ERROR(); diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index c53ed9220a..b00129c99c 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -419,7 +419,7 @@ rxml_document_t *rxml_load_document(const char *path) char *new_memory_buffer = NULL; const char *mem_ptr = NULL; long len = 0; - RFILE *file = filestream_open(path, RFILE_MODE_READ, -1); + RFILE *file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!file) return NULL; diff --git a/libretro-common/hash/rhash.c b/libretro-common/hash/rhash.c index 3d4aa1ca5d..03f96d7e92 100644 --- a/libretro-common/hash/rhash.c +++ b/libretro-common/hash/rhash.c @@ -511,7 +511,7 @@ int sha1_calculate(const char *path, char *result) SHA1Context sha; unsigned char buff[4096]; int rv = 1; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, -1); + RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!fd) goto error; diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 85f086b030..fde5b36a4c 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -38,15 +38,17 @@ RETRO_BEGIN_DECLS typedef struct RFILE RFILE; +#define RFILE_HINT_NONE (0) +/* There is no guarantee these requests will be attended. */ +#define RFILE_HINT_UNBUFFERED (1 << 8) +/* requires RFILE_MODE_READ */ +#define RFILE_HINT_MMAP (1 << 9) + enum { RFILE_MODE_READ = 0, RFILE_MODE_WRITE, - RFILE_MODE_READ_WRITE, - - /* There is no guarantee these requests will be attended. */ - RFILE_HINT_UNBUFFERED = 1<<8, - RFILE_HINT_MMAP = 1<<9 /* requires RFILE_MODE_READ */ + RFILE_MODE_READ_WRITE }; int64_t filestream_get_size(RFILE *stream); @@ -64,7 +66,7 @@ const char *filestream_get_ext(RFILE *stream); * Opens a file for reading or writing, depending on the requested mode. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. **/ -RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused); +RFILE *filestream_open(const char *path, unsigned mode, unsigned hints); ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence); diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index 7eda0e7f8f..b6d437e058 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -66,7 +66,7 @@ bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info); bool intfstream_open(intfstream_internal_t *intf, - const char *path, unsigned mode, ssize_t len); + const char *path, unsigned mode, unsigned hints); ssize_t intfstream_read(intfstream_internal_t *intf, void *s, size_t len); diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 6f3ce60e6f..4e601e31f8 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -144,7 +144,7 @@ void filestream_set_size(RFILE *stream) * Opens a file for reading or writing, depending on the requested mode. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. **/ -RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) +RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) { int flags = 0; #if !defined(_WIN32) || defined(LEGACY_WIN32) @@ -159,16 +159,16 @@ RFILE *filestream_open(const char *path, unsigned mode, ssize_t unused) (void)flags; - stream->hints = mode; + stream->hints = hints; #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP && (stream->hints & 0xff) == RFILE_MODE_READ) + if (stream->hints & RFILE_HINT_MMAP && (stream->mode == RFILE_MODE_READ)) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif stream->hints &= ~RFILE_HINT_MMAP; - switch (mode & 0xff) + switch (mode) { case RFILE_MODE_READ: if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) @@ -582,7 +582,8 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) ssize_t ret = 0; ssize_t content_buf_size = 0; void *content_buf = NULL; - RFILE *file = filestream_open(path, RFILE_MODE_READ, -1); + RFILE *file = filestream_open(path, + RFILE_MODE_READ, RFILE_HINT_NONE); if (!file) { @@ -648,7 +649,7 @@ error: bool filestream_write_file(const char *path, const void *data, ssize_t size) { ssize_t ret = 0; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, -1); + RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!file) return false; diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index fcd1edf8cc..0f4f175197 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -83,7 +83,7 @@ bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info) } bool intfstream_open(intfstream_internal_t *intf, const char *path, - unsigned mode, ssize_t len) + unsigned mode, unsigned hints) { if (!intf) return false; @@ -91,7 +91,7 @@ bool intfstream_open(intfstream_internal_t *intf, const char *path, switch (intf->type) { case INTFSTREAM_FILE: - intf->file.fp = filestream_open(path, mode, len); + intf->file.fp = filestream_open(path, mode, hints); if (!intf->file.fp) return false; break; diff --git a/libretro-db/c_converter.c b/libretro-db/c_converter.c index ae6b219d0b..edc8c10cf1 100644 --- a/libretro-db/c_converter.c +++ b/libretro-db/c_converter.c @@ -804,7 +804,7 @@ int main(int argc, char** argv) dat_buffer++; } - rdb_file = filestream_open(rdb_path, RFILE_MODE_WRITE, -1); + rdb_file = filestream_open(rdb_path, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!rdb_file) { diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index c4d39d0be8..1ba782afe8 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -217,7 +217,7 @@ int libretrodb_open(const char *path, libretrodb_t *db) libretrodb_header_t header; libretrodb_metadata_t md; int rv; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, -1); + RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!fd) return -errno; @@ -431,7 +431,7 @@ int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, if (!db || string_is_empty(db->path)) return -errno; - cursor->fd = filestream_open(db->path, RFILE_MODE_READ | RFILE_HINT_MMAP, -1); + cursor->fd = filestream_open(db->path, RFILE_MODE_READ, RFILE_HINT_MMAP); if (!cursor->fd) return -errno; diff --git a/libretro-db/lua/lua_converter.c b/libretro-db/lua/lua_converter.c index a60dc1d22d..2c70a7bc3b 100644 --- a/libretro-db/lua/lua_converter.c +++ b/libretro-db/lua/lua_converter.c @@ -92,7 +92,8 @@ int main(int argc, char ** argv) call_init(L, argc - 2, (const char **) argv + 2); - dst = filestream_open(db_file, RFILE_MODE_WRITE, -1); + dst = filestream_open(db_file, RFILE_MODE_WRITE, RFILE_HINT_NONE); + if (!dst) { printf( diff --git a/libretro-db/lua/testlib.c b/libretro-db/lua/testlib.c index 524b9fe353..b2c9874db7 100644 --- a/libretro-db/lua/testlib.c +++ b/libretro-db/lua/testlib.c @@ -106,7 +106,7 @@ static int create_db(lua_State *L) } lua_setfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); - dst = filestream_open(db_file, RFILE_MODE_WRITE, -1); + dst = filestream_open(db_file, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!dst) { lua_pushstring(L, "Could not open destination file"); diff --git a/libretro-db/rmsgpack_test.c b/libretro-db/rmsgpack_test.c index 1c6f03cb57..b1e74dc981 100644 --- a/libretro-db/rmsgpack_test.c +++ b/libretro-db/rmsgpack_test.c @@ -186,7 +186,7 @@ static struct rmsgpack_read_callbacks stub_callbacks = { int main(void) { struct stub_state state; - RFILE *fd = filestream_open("test.msgpack", RFILE_MODE_READ, -1); + RFILE *fd = filestream_open("test.msgpack", RFILE_MODE_READ, RFILE_HINT_NONE); state.i = 0; state.stack[0] = 0; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 31d1d618b8..cddca2d23f 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1876,7 +1876,8 @@ static void systemd_service_toggle(const char *path, char *unit, bool enable) args[2] = unit; if (enable) - filestream_close(filestream_open(path, RFILE_MODE_WRITE, -1)); + filestream_close(filestream_open(path, + RFILE_MODE_WRITE, RFILE_HINT_NONE)); else path_file_remove(path); diff --git a/movie.c b/movie.c index 8ca184906e..0135d1c332 100644 --- a/movie.c +++ b/movie.c @@ -75,7 +75,7 @@ static bool bsv_movie_init_playback(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, RFILE_MODE_READ, -1); + RFILE *file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); if (!file) { @@ -152,7 +152,7 @@ static bool bsv_movie_init_record(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, -1); + RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!file) { diff --git a/playlist.c b/playlist.c index 13154d6bbe..f79278a4ef 100644 --- a/playlist.c +++ b/playlist.c @@ -393,7 +393,8 @@ void playlist_write_file(playlist_t *playlist) if (!playlist || !playlist->modified) return; - file = filestream_open(playlist->conf_path, RFILE_MODE_WRITE, -1); + file = filestream_open(playlist->conf_path, + RFILE_MODE_WRITE, RFILE_HINT_NONE); if (!file) { @@ -493,7 +494,7 @@ static bool playlist_read_file( unsigned i; char buf[PLAYLIST_ENTRIES][1024]; RFILE *file = filestream_open( - path, RFILE_MODE_READ, -1); + path, RFILE_MODE_READ, RFILE_HINT_NONE); for (i = 0; i < PLAYLIST_ENTRIES; i++) buf[i][0] = '\0'; diff --git a/tasks/task_database.c b/tasks/task_database.c index afe42dd83e..10382a4853 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -101,7 +101,7 @@ static intfstream_t* intfstream_open_file(const char *path) if (!fd) return NULL; - if (!intfstream_open(fd, path, RFILE_MODE_READ, -1)) + if (!intfstream_open(fd, path, RFILE_MODE_READ, RFILE_HINT_NONE)) goto error; return fd; @@ -130,7 +130,7 @@ static intfstream_t *open_memory(void *data, size_t size) if (!fd) return NULL; - if (!intfstream_open(fd, NULL, RFILE_MODE_READ, -1)) + if (!intfstream_open(fd, NULL, RFILE_MODE_READ, RFILE_HINT_NONE)) goto error; return fd; @@ -158,7 +158,7 @@ open_chd_track(const char *path, int32_t track) if (!fd) return NULL; - if (!intfstream_open(fd, path, RFILE_MODE_READ, -1)) + if (!intfstream_open(fd, path, RFILE_MODE_READ, RFILE_HINT_NONE)) goto error; return fd; diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c index 09557c2280..5e3ef10d51 100644 --- a/tasks/task_database_cue.c +++ b/tasks/task_database_cue.c @@ -413,10 +413,9 @@ clean: static ssize_t get_file_size(const char *path) { ssize_t rv; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, -1); - if (fd == NULL) { + RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + if (fd == NULL) return -1; - } rv = filestream_get_size(fd); filestream_close(fd); return rv; @@ -468,7 +467,7 @@ int cue_find_track(const char *cue_path, bool first, if (!fd) goto error; - if (!intfstream_open(fd, cue_path, RFILE_MODE_READ, -1)) + if (!intfstream_open(fd, cue_path, RFILE_MODE_READ, RFILE_HINT_NONE)) { RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path, strerror(errno)); @@ -622,7 +621,7 @@ int gdi_find_track(const char *gdi_path, bool first, if (!fd) goto error; - if (!intfstream_open(fd, gdi_path, RFILE_MODE_READ, -1)) + if (!intfstream_open(fd, gdi_path, RFILE_MODE_READ, RFILE_HINT_NONE)) { RARCH_LOG("Could not open GDI file '%s': %s\n", gdi_path, strerror(errno)); diff --git a/tasks/task_save.c b/tasks/task_save.c index 0986f79a8f..e1b64f9c90 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -157,7 +157,8 @@ static void autosave_thread(void *data) if (differ) { /* Should probably deal with this more elegantly. */ - RFILE *file = filestream_open(save->path, RFILE_MODE_WRITE, -1); + RFILE *file = filestream_open(save->path, + RFILE_MODE_WRITE, RFILE_HINT_NONE); if (file) { @@ -564,7 +565,8 @@ static void task_save_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, RFILE_MODE_WRITE, -1); + state->file = filestream_open(state->path, RFILE_MODE_WRITE, + RFILE_HINT_NONE); if (!state->file) return; @@ -736,7 +738,8 @@ static void task_load_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, RFILE_MODE_READ, -1); + state->file = filestream_open(state->path, RFILE_MODE_READ, + RFILE_HINT_NONE); if (!state->file) goto error; From 2fd8210e597c512375ddc6c95ad46fe36855aa75 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Sun, 10 Dec 2017 22:35:08 +0100 Subject: [PATCH 168/698] Create shareable filestream_getline --- libretro-common/file/config_file.c | 38 +----------------- libretro-common/include/streams/file_stream.h | 39 ++++++++++++++++++- libretro-common/streams/file_stream.c | 35 ----------------- 3 files changed, 38 insertions(+), 74 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index b4d7251d1a..c7b6a92f24 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -80,42 +80,6 @@ struct config_file static config_file_t *config_file_new_internal( const char *path, unsigned depth); -static char *getaline(RFILE *file) -{ - char* newline = (char*)malloc(9); - char* newline_tmp = NULL; - size_t cur_size = 8; - size_t idx = 0; - int in = filestream_getc(file); - - if (!newline) - return NULL; - - while (in != EOF && in != '\n') - { - if (idx == cur_size) - { - cur_size *= 2; - newline_tmp = (char*)realloc(newline, cur_size + 1); - - if (!newline_tmp) - { - free(newline); - return NULL; - } - - newline = newline_tmp; - } - - /* ignore MS line endings */ - if (in != '\r') - newline[idx++] = in; - in = filestream_getc(file); - } - newline[idx] = '\0'; - return newline; -} - static char *strip_comment(char *str) { /* Remove everything after comment. @@ -419,7 +383,7 @@ static config_file_t *config_file_new_internal( list->value = NULL; list->next = NULL; - line = getaline(file); + line = filestream_getline(file); if (!line) { diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index fde5b36a4c..c1b6fe951a 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -25,11 +25,13 @@ #include #include +#include #include #include #include +#include #include #include @@ -84,8 +86,6 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len); char *filestream_gets(RFILE *stream, char *s, size_t len); -char *filestream_getline(RFILE *stream); - int filestream_getc(RFILE *stream); int filestream_eof(RFILE *stream); @@ -107,6 +107,41 @@ FILE* filestream_get_fp(RFILE *stream); */ int filestream_flush(RFILE *stream); +static INLINE char *filestream_getline(RFILE *stream) +{ + char* newline = (char*)malloc(9); + char* newline_tmp = NULL; + size_t cur_size = 8; + size_t idx = 0; + int in = filestream_getc(stream); + + if (!newline) + return NULL; + + while (in != EOF && in != '\n') + { + if (idx == cur_size) + { + cur_size *= 2; + newline_tmp = (char*)realloc(newline, cur_size + 1); + + if (!newline_tmp) + { + free(newline); + return NULL; + } + + newline = newline_tmp; + } + + newline[idx++] = in; + in = filestream_getc(stream); + } + + newline[idx] = '\0'; + return newline; +} + RETRO_END_DECLS #endif diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 4e601e31f8..845e12c348 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -290,41 +290,6 @@ error: return NULL; } -char *filestream_getline(RFILE *stream) -{ - char* newline = (char*)malloc(9); - char* newline_tmp = NULL; - size_t cur_size = 8; - size_t idx = 0; - int in = filestream_getc(stream); - - if (!newline) - return NULL; - - while (in != EOF && in != '\n') - { - if (idx == cur_size) - { - cur_size *= 2; - newline_tmp = (char*)realloc(newline, cur_size + 1); - - if (!newline_tmp) - { - free(newline); - return NULL; - } - - newline = newline_tmp; - } - - newline[idx++] = in; - in = filestream_getc(stream); - } - - newline[idx] = '\0'; - return newline; -} - char *filestream_gets(RFILE *stream, char *s, size_t len) { if (!stream) From 85d9d986ebca44c909a4f249e161a48081109ddb Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Sun, 10 Dec 2017 22:46:39 +0100 Subject: [PATCH 169/698] Buildfix --- libretro-common/streams/file_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 845e12c348..3759e33090 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -162,7 +162,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) stream->hints = hints; #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP && (stream->mode == RFILE_MODE_READ)) + if (stream->hints & RFILE_HINT_MMAP && mode == RFILE_MODE_READ) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif From e877595ff7a40692fcc52a43504315e66fa40ec1 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 10 Dec 2017 20:16:41 -0500 Subject: [PATCH 170/698] add buildbot url for msvc2003 (Windows 95) --- config.def.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/config.def.h b/config.def.h index 34eefd9fa4..38dd96eb3f 100644 --- a/config.def.h +++ b/config.def.h @@ -662,11 +662,10 @@ static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/window static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2010/x86/latest/"; #endif #elif _MSC_VER == 1400 -#if defined(__x86_64__) -static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2005/x86_64/latest/"; -#elif defined(__i386__) || defined(__i486__) || defined(__i686__) || defined(_M_IX86) || defined(_M_IA64) static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2005/x86/latest/"; #endif +#elif _MSC_VER == 1310 +static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2003/x86/latest/"; #else #if defined(__x86_64__) static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows/x86_64/latest/"; From f3a58f4ff337cf8de60924978f1a1e1fe8fdb1e7 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Sun, 10 Dec 2017 22:07:25 -0500 Subject: [PATCH 171/698] remove extra #endif --- config.def.h | 1 - 1 file changed, 1 deletion(-) diff --git a/config.def.h b/config.def.h index 38dd96eb3f..4145be9d77 100644 --- a/config.def.h +++ b/config.def.h @@ -663,7 +663,6 @@ static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/window #endif #elif _MSC_VER == 1400 static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2005/x86/latest/"; -#endif #elif _MSC_VER == 1310 static char buildbot_server_url[] = "http://buildbot.libretro.com/nightly/windows-msvc2003/x86/latest/"; #else From b14598657c4b813c555b6cc6c6e81ec0830621c4 Mon Sep 17 00:00:00 2001 From: "Peter Y. Hammond" Date: Sun, 10 Dec 2017 22:22:01 -0700 Subject: [PATCH 172/698] Fixed a bug where the joypad devices were not always being assigned in the same order as they were numbered under /dev/input/. This showed up mainly when using an external USB Bluetooth dongle. In that case, controllers would be assigned often in reverse order. --- input/drivers_joypad/udev_joypad.c | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 20ee084ec8..902367ee67 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -82,6 +82,12 @@ struct udev_joypad int32_t pid; }; +struct joypad_udev_entry +{ + const char *devnode; + struct udev_list_entry *item; +}; + static struct udev *udev_joypad_fd = NULL; static struct udev_monitor *udev_joypad_mon = NULL; static struct udev_joypad udev_pads[MAX_USERS]; @@ -526,12 +532,22 @@ static void udev_joypad_poll(void) } } +// Used for sorting devnodes to appear in the correct order +static int sort_devnodes(const void *a, const void *b) +{ + const struct joypad_udev_entry *aa = a; + const struct joypad_udev_entry *bb = b; + return strcmp(aa->devnode, bb->devnode); +} + static bool udev_joypad_init(void *data) { unsigned i; + unsigned sorted_count = 0; struct udev_list_entry *devs = NULL; struct udev_list_entry *item = NULL; struct udev_enumerate *enumerate = NULL; + struct joypad_udev_entry sorted[MAX_USERS]; (void)data; @@ -564,6 +580,24 @@ static bool udev_joypad_init(void *data) struct udev_device *dev = udev_device_new_from_syspath(udev_joypad_fd, name); const char *devnode = udev_device_get_devnode(dev); + if (devnode != NULL) { + sorted[sorted_count].devnode = devnode; + sorted[sorted_count].item = item; + sorted_count++; + } else { + udev_device_unref(dev); + } + } + + // Sort the udev entries by devnode name so that they are created in the proper order + qsort(sorted, sorted_count, sizeof(struct joypad_udev_entry), sort_devnodes); + + for (i = 0; i < sorted_count; i++) + { + const char *name = udev_list_entry_get_name(sorted[i].item); + struct udev_device *dev = udev_device_new_from_syspath(udev_joypad_fd, name); + const char *devnode = udev_device_get_devnode(dev); + if (devnode) udev_check_device(dev, devnode); udev_device_unref(dev); From c950613098404c6438dd12578c6c791cd54bd901 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 11:28:48 +0100 Subject: [PATCH 173/698] C comments --- input/drivers_joypad/udev_joypad.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/input/drivers_joypad/udev_joypad.c b/input/drivers_joypad/udev_joypad.c index 902367ee67..0bd8c0598e 100644 --- a/input/drivers_joypad/udev_joypad.c +++ b/input/drivers_joypad/udev_joypad.c @@ -532,7 +532,7 @@ static void udev_joypad_poll(void) } } -// Used for sorting devnodes to appear in the correct order +/* Used for sorting devnodes to appear in the correct order */ static int sort_devnodes(const void *a, const void *b) { const struct joypad_udev_entry *aa = a; @@ -589,8 +589,10 @@ static bool udev_joypad_init(void *data) } } - // Sort the udev entries by devnode name so that they are created in the proper order - qsort(sorted, sorted_count, sizeof(struct joypad_udev_entry), sort_devnodes); + /* Sort the udev entries by devnode name so that they are + * created in the proper order */ + qsort(sorted, sorted_count, + sizeof(struct joypad_udev_entry), sort_devnodes); for (i = 0; i < sorted_count; i++) { From e1461cc0de8bca4f3469783a176ff845b19698a0 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 11:40:36 +0100 Subject: [PATCH 174/698] Get rid of hashes in config_file.c --- libretro-common/file/config_file.c | 24 ++++++------------- libretro-common/include/streams/file_stream.h | 5 ---- 2 files changed, 7 insertions(+), 22 deletions(-) diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index c7b6a92f24..334c9df62a 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #define MAX_INCLUDE_DEPTH 16 @@ -54,7 +53,6 @@ struct config_entry_list /* If we got this from an #include, * do not allow overwrite. */ bool readonly; - uint32_t key_hash; char *key; char *value; @@ -313,11 +311,11 @@ static bool parse_line(config_file_t *conf, key[idx++] = *line++; } - key[idx] = '\0'; - list->key = key; - list->key_hash = djb2_calculate(key); + key[idx] = '\0'; + list->key = key; + + list->value = extract_value(line, true); - list->value = extract_value(line, true); if (!list->value) { list->key = NULL; @@ -378,7 +376,6 @@ static config_file_t *config_file_new_internal( } list->readonly = false; - list->key_hash = 0; list->key = NULL; list->value = NULL; list->next = NULL; @@ -510,7 +507,6 @@ config_file_t *config_file_new_from_string(const char *from_string) } list->readonly = false; - list->key_hash = 0; list->key = NULL; list->value = NULL; list->next = NULL; @@ -545,17 +541,12 @@ config_file_t *config_file_new(const char *path) static struct config_entry_list *config_get_entry(const config_file_t *conf, const char *key, struct config_entry_list **prev) { - struct config_entry_list *entry; - struct config_entry_list *previous = NULL; - - uint32_t hash = djb2_calculate(key); - - if (prev) - previous = *prev; + struct config_entry_list *entry = NULL; + struct config_entry_list *previous = prev ? *prev : NULL; for (entry = conf->entries; entry; entry = entry->next) { - if (hash == entry->key_hash && string_is_equal(key, entry->key)) + if (string_is_equal(key, entry->key)) return entry; previous = entry; @@ -775,7 +766,6 @@ void config_set_string(config_file_t *conf, const char *key, const char *val) return; entry->readonly = false; - entry->key_hash = 0; entry->key = strdup(key); entry->value = strdup(val); entry->next = NULL; diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index c1b6fe951a..be380f0fc6 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -100,11 +100,6 @@ int filestream_printf(RFILE *stream, const char* format, ...); int filestream_error(RFILE *stream); -/* DO NOT put these functions back, unless you want to deal with - the UNAVOIDABLE REGRESSIONS on platforms using unexpected rfile backends -int filestream_get_fd(RFILE *stream); -FILE* filestream_get_fp(RFILE *stream); */ - int filestream_flush(RFILE *stream); static INLINE char *filestream_getline(RFILE *stream) From 93ee4df5f5bce7fc5d66ff63285823cd5fb98d7e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 11:47:13 +0100 Subject: [PATCH 175/698] Move RFILE_HINT_UNBUFFERED to file_stream.c --- libretro-common/include/streams/file_stream.h | 2 -- libretro-common/streams/file_stream.c | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index be380f0fc6..95d39a7c99 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -41,8 +41,6 @@ RETRO_BEGIN_DECLS typedef struct RFILE RFILE; #define RFILE_HINT_NONE (0) -/* There is no guarantee these requests will be attended. */ -#define RFILE_HINT_UNBUFFERED (1 << 8) /* requires RFILE_MODE_READ */ #define RFILE_HINT_MMAP (1 << 9) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 3759e33090..30ea5eec52 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -74,6 +74,8 @@ #endif +#define RFILE_HINT_UNBUFFERED (1 << 8) + #include #include #include From 318f17c4cb20a87d25efc0d81c1b3b3d4359bb2d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:15:00 +0100 Subject: [PATCH 176/698] Start using VFS API constant defines --- cheevos/cheevos.c | 2 +- configuration.c | 7 ++++--- gfx/drivers/gx_gfx.c | 4 +++- gfx/video_shader_parse.c | 4 +++- libretro-common/features/features_cpu.c | 2 +- libretro-common/file/config_file.c | 2 +- libretro-common/file/file_path.c | 4 +++- libretro-common/formats/bmp/rbmp_encode.c | 3 ++- libretro-common/formats/png/rpng_encode.c | 3 ++- libretro-common/formats/xml/rxml.c | 3 ++- libretro-common/hash/rhash.c | 3 ++- libretro-common/include/libretro.h | 7 +++++++ libretro-common/include/streams/file_stream.h | 14 +++++--------- libretro-common/streams/file_stream.c | 16 ++++++++++------ libretro-common/streams/file_stream_transforms.c | 11 ++++++----- libretro-db/c_converter.c | 3 ++- libretro-db/libretrodb.c | 16 ++++++++++------ libretro-db/lua/lua_converter.c | 3 ++- libretro-db/lua/testlib.c | 3 ++- libretro-db/rmsgpack_test.c | 5 +++-- menu/menu_setting.c | 3 ++- movie.c | 6 ++++-- playlist.c | 5 +++-- tasks/task_database.c | 7 ++++--- tasks/task_database_cue.c | 9 ++++++--- tasks/task_save.c | 7 ++++--- 26 files changed, 94 insertions(+), 58 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index e92c796397..08af2a72be 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2641,7 +2641,7 @@ static int cheevos_iterate(coro_t* coro) if (!CHEEVOS_VAR_DATA) { CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, - RFILE_MODE_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!CHEEVOS_VAR_STREAM) CORO_STOP(); diff --git a/configuration.c b/configuration.c index bb4ef4cc3e..77975d470e 100644 --- a/configuration.c +++ b/configuration.c @@ -19,6 +19,7 @@ #include +#include #include #include #include @@ -3792,17 +3793,17 @@ bool config_save_file(const char *path) #ifdef HAVE_LAKKA if (settings->bools.ssh_enable) filestream_close(filestream_open(LAKKA_SSH_PATH, - RFILE_MODE_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_SSH_PATH); if (settings->bools.samba_enable) filestream_close(filestream_open(LAKKA_SAMBA_PATH, - RFILE_MODE_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_SAMBA_PATH); if (settings->bools.bluetooth_enable) filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH, - RFILE_MODE_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); else path_file_remove(LAKKA_BLUETOOTH_PATH); #endif diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index 0aa1e9c976..c4886f199e 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -21,6 +21,7 @@ #include #include +#include #include #ifdef HAVE_CONFIG_H @@ -719,7 +720,8 @@ static void gx_efb_screenshot(void) { int x, y; uint8_t tga_header[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x18, 0x00}; - RFILE *out = filestream_open("/screenshot.tga", RFILE_MODE_WRITE, RFILE_HINT_NONE); + RFILE *out = filestream_open("/screenshot.tga", + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!out) return; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 0d3a6434cb..32cdae25c4 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -545,7 +546,8 @@ bool video_shader_resolve_parameters(config_file_t *conf, /* If that doesn't work, fallback to the old path. * Ideally, we'd get rid of this path sooner or later. */ #endif - file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!file) { diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index a52df70056..a64be01004 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -321,7 +321,7 @@ static unsigned char check_arm_cpu_feature(const char* feature) char line[1024]; unsigned char status = 0; RFILE *fp = filestream_open("/proc/cpuinfo", - RFILE_MODE_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fp) return 0; diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 334c9df62a..4ab05e7e47 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -355,7 +355,7 @@ static config_file_t *config_file_new_internal( conf->include_depth = depth; file = filestream_open(path, - RFILE_MODE_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!file) { diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index f5493017e5..f5e7eccd73 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -28,6 +28,7 @@ #include +#include #include #include #include @@ -410,7 +411,8 @@ bool path_file_exists(const char *path) if (!path || !*path) return false; - dummy = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + dummy = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!dummy) return false; diff --git a/libretro-common/formats/bmp/rbmp_encode.c b/libretro-common/formats/bmp/rbmp_encode.c index 9a30b27a92..c0502d8e52 100644 --- a/libretro-common/formats/bmp/rbmp_encode.c +++ b/libretro-common/formats/bmp/rbmp_encode.c @@ -215,7 +215,8 @@ bool rbmp_save_image( unsigned pitch, enum rbmp_source_type type) { bool ret = false; - RFILE *file = filestream_open(filename, RFILE_MODE_WRITE, RFILE_HINT_NONE); + RFILE *file = filestream_open(filename, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!file) return false; diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index ab67614a73..9be5f857c1 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -227,7 +227,8 @@ static bool rpng_save_image(const char *path, void *stream = NULL; uint32_t total_in = 0; uint32_t total_out = 0; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); + RFILE *file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!file) GOTO_END_ERROR(); diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index b00129c99c..2bac625b74 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -419,7 +419,8 @@ rxml_document_t *rxml_load_document(const char *path) char *new_memory_buffer = NULL; const char *mem_ptr = NULL; long len = 0; - RFILE *file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + RFILE *file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!file) return NULL; diff --git a/libretro-common/hash/rhash.c b/libretro-common/hash/rhash.c index 03f96d7e92..3ba15eeda8 100644 --- a/libretro-common/hash/rhash.c +++ b/libretro-common/hash/rhash.c @@ -511,7 +511,8 @@ int sha1_calculate(const char *path, char *result) SHA1Context sha; unsigned char buff[4096]; int rv = 1; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + RFILE *fd = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fd) goto error; diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index b900ac93e6..b10f18b968 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1044,6 +1044,13 @@ struct retro_hw_render_context_negotiation_interface * recognize or support. Should be set in either retro_init or retro_load_game, but not both. */ +/* File open flags + * Introduced in VFS API v1 */ +#define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */ +#define RETRO_VFS_FILE_ACCESS_WRITE (1 << 1) /* Write only mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified */ +#define RETRO_VFS_FILE_ACCESS_READ_WRITE (RETRO_VFS_FILE_ACCESS_READ | RETRO_VFS_FILE_ACCESS_WRITE) /* Read-write mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified*/ +#define RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING (1 << 2) /* Prevents discarding content of existing files opened for writing */ + #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 95d39a7c99..faf154723c 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -30,6 +30,7 @@ #include +#include #include #include #include @@ -40,16 +41,11 @@ RETRO_BEGIN_DECLS typedef struct RFILE RFILE; -#define RFILE_HINT_NONE (0) -/* requires RFILE_MODE_READ */ -#define RFILE_HINT_MMAP (1 << 9) +#define FILESTREAM_REQUIRED_VFS_VERSION 1 -enum -{ - RFILE_MODE_READ = 0, - RFILE_MODE_WRITE, - RFILE_MODE_READ_WRITE -}; +#define RFILE_HINT_NONE (0) +/* requires RETRO_VFS_FILE_ACCESS_READ */ +#define RFILE_HINT_MMAP (1 << 9) int64_t filestream_get_size(RFILE *stream); diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 30ea5eec52..59468832fb 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -164,7 +164,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) stream->hints = hints; #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP && mode == RFILE_MODE_READ) + if (stream->hints & RFILE_HINT_MMAP && mode == RETRO_VFS_FILE_ACCESS_READ) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif @@ -172,13 +172,13 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) switch (mode) { - case RFILE_MODE_READ: + case RETRO_VFS_FILE_ACCESS_READ: if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_READ_UNBUF; /* No "else" here */ flags = O_RDONLY; break; - case RFILE_MODE_WRITE: + case RETRO_VFS_FILE_ACCESS_WRITE: if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_UNBUF; else @@ -189,7 +189,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) #endif } break; - case RFILE_MODE_READ_WRITE: + case RETRO_VFS_FILE_ACCESS_READ_WRITE: if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) mode_str = MODE_STR_WRITE_PLUS; else @@ -200,6 +200,9 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) #endif } break; + /* TODO/FIXME - implement */ + case RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING: + break; } if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0 && mode_str) @@ -550,7 +553,7 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) ssize_t content_buf_size = 0; void *content_buf = NULL; RFILE *file = filestream_open(path, - RFILE_MODE_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!file) { @@ -616,7 +619,8 @@ error: bool filestream_write_file(const char *path, const void *data, ssize_t size) { ssize_t ret = 0; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); + RFILE *file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!file) return false; diff --git a/libretro-common/streams/file_stream_transforms.c b/libretro-common/streams/file_stream_transforms.c index cec3a4c458..0833040be3 100644 --- a/libretro-common/streams/file_stream_transforms.c +++ b/libretro-common/streams/file_stream_transforms.c @@ -19,22 +19,23 @@ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ - -#include #include #include +#include +#include + RFILE* rfopen(const char *path, const char *mode) { unsigned int retro_mode = 0; if (strstr(mode, "r")) if (strstr(mode, "b")) - retro_mode = RFILE_MODE_READ; + retro_mode = RETRO_VFS_FILE_ACCESS_READ; if (strstr(mode, "w")) - retro_mode = RFILE_MODE_WRITE; + retro_mode = RETRO_VFS_FILE_ACCESS_WRITE; if (strstr(mode, "+")) - retro_mode = RFILE_MODE_READ_WRITE; + retro_mode = RETRO_VFS_FILE_ACCESS_READ_WRITE; return filestream_open(path, retro_mode, -1); } diff --git a/libretro-db/c_converter.c b/libretro-db/c_converter.c index edc8c10cf1..3dc51496c3 100644 --- a/libretro-db/c_converter.c +++ b/libretro-db/c_converter.c @@ -804,7 +804,8 @@ int main(int argc, char** argv) dat_buffer++; } - rdb_file = filestream_open(rdb_path, RFILE_MODE_WRITE, RFILE_HINT_NONE); + rdb_file = filestream_open(rdb_path, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!rdb_file) { diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index 1ba782afe8..5deed1d426 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -216,8 +216,9 @@ int libretrodb_open(const char *path, libretrodb_t *db) { libretrodb_header_t header; libretrodb_metadata_t md; - int rv; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + int rv = 0; + RFILE *fd = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fd) return -errno; @@ -428,18 +429,21 @@ void libretrodb_cursor_close(libretrodb_cursor_t *cursor) int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, libretrodb_query_t *q) { + RFILE *fd = NULL; if (!db || string_is_empty(db->path)) return -errno; - cursor->fd = filestream_open(db->path, RFILE_MODE_READ, RFILE_HINT_MMAP); + fd = filestream_open(db->path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_MMAP); - if (!cursor->fd) + if (!fd) return -errno; - cursor->db = db; + cursor->fd = fd; + cursor->db = db; cursor->is_valid = 1; libretrodb_cursor_reset(cursor); - cursor->query = q; + cursor->query = q; if (q) libretrodb_query_inc_ref(q); diff --git a/libretro-db/lua/lua_converter.c b/libretro-db/lua/lua_converter.c index 2c70a7bc3b..81c495f455 100644 --- a/libretro-db/lua/lua_converter.c +++ b/libretro-db/lua/lua_converter.c @@ -92,7 +92,8 @@ int main(int argc, char ** argv) call_init(L, argc - 2, (const char **) argv + 2); - dst = filestream_open(db_file, RFILE_MODE_WRITE, RFILE_HINT_NONE); + dst = filestream_open(db_file, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!dst) { diff --git a/libretro-db/lua/testlib.c b/libretro-db/lua/testlib.c index b2c9874db7..bc5bd56a4c 100644 --- a/libretro-db/lua/testlib.c +++ b/libretro-db/lua/testlib.c @@ -106,7 +106,8 @@ static int create_db(lua_State *L) } lua_setfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); - dst = filestream_open(db_file, RFILE_MODE_WRITE, RFILE_HINT_NONE); + dst = filestream_open(db_file, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!dst) { lua_pushstring(L, "Could not open destination file"); diff --git a/libretro-db/rmsgpack_test.c b/libretro-db/rmsgpack_test.c index b1e74dc981..c6383cdc0e 100644 --- a/libretro-db/rmsgpack_test.c +++ b/libretro-db/rmsgpack_test.c @@ -186,9 +186,10 @@ static struct rmsgpack_read_callbacks stub_callbacks = { int main(void) { struct stub_state state; - RFILE *fd = filestream_open("test.msgpack", RFILE_MODE_READ, RFILE_HINT_NONE); + RFILE *fd = filestream_open("test.msgpack", + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); - state.i = 0; + state.i = 0; state.stack[0] = 0; rmsgpack_read(fd, &stub_callbacks, &state); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index cddca2d23f..f2307cfbc3 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -22,6 +22,7 @@ #include #endif +#include #include #include #include @@ -1877,7 +1878,7 @@ static void systemd_service_toggle(const char *path, char *unit, bool enable) if (enable) filestream_close(filestream_open(path, - RFILE_MODE_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); else path_file_remove(path); diff --git a/movie.c b/movie.c index 0135d1c332..9e6e6bcc04 100644 --- a/movie.c +++ b/movie.c @@ -75,7 +75,8 @@ static bool bsv_movie_init_playback(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + RFILE *file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!file) { @@ -152,7 +153,8 @@ static bool bsv_movie_init_record(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, RFILE_MODE_WRITE, RFILE_HINT_NONE); + RFILE *file = filestream_open(path, + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!file) { diff --git a/playlist.c b/playlist.c index f79278a4ef..2168272214 100644 --- a/playlist.c +++ b/playlist.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -394,7 +395,7 @@ void playlist_write_file(playlist_t *playlist) return; file = filestream_open(playlist->conf_path, - RFILE_MODE_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!file) { @@ -494,7 +495,7 @@ static bool playlist_read_file( unsigned i; char buf[PLAYLIST_ENTRIES][1024]; RFILE *file = filestream_open( - path, RFILE_MODE_READ, RFILE_HINT_NONE); + path, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); for (i = 0; i < PLAYLIST_ENTRIES; i++) buf[i][0] = '\0'; diff --git a/tasks/task_database.c b/tasks/task_database.c index 10382a4853..14e4af2a88 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -101,7 +101,7 @@ static intfstream_t* intfstream_open_file(const char *path) if (!fd) return NULL; - if (!intfstream_open(fd, path, RFILE_MODE_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) goto error; return fd; @@ -130,7 +130,7 @@ static intfstream_t *open_memory(void *data, size_t size) if (!fd) return NULL; - if (!intfstream_open(fd, NULL, RFILE_MODE_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, NULL, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) goto error; return fd; @@ -158,7 +158,8 @@ open_chd_track(const char *path, int32_t track) if (!fd) return NULL; - if (!intfstream_open(fd, path, RFILE_MODE_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) goto error; return fd; diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c index 5e3ef10d51..ae134aee63 100644 --- a/tasks/task_database_cue.c +++ b/tasks/task_database_cue.c @@ -413,7 +413,8 @@ clean: static ssize_t get_file_size(const char *path) { ssize_t rv; - RFILE *fd = filestream_open(path, RFILE_MODE_READ, RFILE_HINT_NONE); + RFILE *fd = filestream_open(path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (fd == NULL) return -1; rv = filestream_get_size(fd); @@ -467,7 +468,8 @@ int cue_find_track(const char *cue_path, bool first, if (!fd) goto error; - if (!intfstream_open(fd, cue_path, RFILE_MODE_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, cue_path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) { RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path, strerror(errno)); @@ -621,7 +623,8 @@ int gdi_find_track(const char *gdi_path, bool first, if (!fd) goto error; - if (!intfstream_open(fd, gdi_path, RFILE_MODE_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, gdi_path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) { RARCH_LOG("Could not open GDI file '%s': %s\n", gdi_path, strerror(errno)); diff --git a/tasks/task_save.c b/tasks/task_save.c index e1b64f9c90..5d29865a6a 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -158,7 +158,7 @@ static void autosave_thread(void *data) { /* Should probably deal with this more elegantly. */ RFILE *file = filestream_open(save->path, - RFILE_MODE_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (file) { @@ -565,7 +565,7 @@ static void task_save_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, RFILE_MODE_WRITE, + state->file = filestream_open(state->path, RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); if (!state->file) @@ -738,7 +738,8 @@ static void task_load_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, RFILE_MODE_READ, + state->file = filestream_open(state->path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!state->file) From 6897f9a987e71f2a1585e9ac1035ede843d8dc6f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:20:06 +0100 Subject: [PATCH 177/698] Pass hints to intfstream_open_file --- tasks/task_database.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tasks/task_database.c b/tasks/task_database.c index 14e4af2a88..8d1b8f3325 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -90,7 +90,7 @@ int detect_gc_game(intfstream_t *fd, char *game_id); int detect_serial_ascii_game(intfstream_t *fd, char *game_id); -static intfstream_t* intfstream_open_file(const char *path) +static intfstream_t* intfstream_open_file(const char *path, unsigned hints) { intfstream_info_t info; intfstream_t *fd = NULL; @@ -101,7 +101,7 @@ static intfstream_t* intfstream_open_file(const char *path) if (!fd) return NULL; - if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, hints)) goto error; return fd; @@ -289,7 +289,7 @@ static bool intfstream_file_get_serial(const char *name, int rv; uint8_t *data = NULL; ssize_t file_size = -1; - intfstream_t *fd = intfstream_open_file(name); + intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); if (!fd) return 0; @@ -432,7 +432,7 @@ static bool intfstream_file_get_crc(const char *name, size_t offset, size_t size, uint32_t *crc) { int rv; - intfstream_t *fd = intfstream_open_file(name); + intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); uint8_t *data = NULL; ssize_t file_size = -1; @@ -574,7 +574,7 @@ static void task_database_cue_prune(database_info_handle_t *db, { size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); - intfstream_t *fd = intfstream_open_file(name); + intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); if (!fd) goto end; @@ -606,7 +606,7 @@ static void gdi_prune(database_info_handle_t *db, const char *name) { size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); - intfstream_t *fd = intfstream_open_file(name); + intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); if (!fd) goto end; From 8aa4d6d1487a6961ef6d9c089d335fd9ef0c3c40 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:23:40 +0100 Subject: [PATCH 178/698] Move convenience functions to interface_stream.c --- .../include/streams/interface_stream.h | 9 ++ libretro-common/streams/interface_stream.c | 83 ++++++++++++++++ tasks/task_database.c | 95 ++----------------- 3 files changed, 100 insertions(+), 87 deletions(-) diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index b6d437e058..a0a26caeba 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -90,6 +90,15 @@ void intfstream_putc(intfstream_internal_t *intf, int c); int intfstream_close(intfstream_internal_t *intf); +intfstream_t* intfstream_open_file(const char *path, + unsigned hints); + +intfstream_t *intfstream_open_memory(void *data, + size_t size, unsigned hints); + +intfstream_t *intfstream_open_chd_track(const char *path, + int32_t track, unsigned hints); + RETRO_END_DECLS #endif diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index 0f4f175197..0363231b56 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -340,3 +340,86 @@ void intfstream_putc(intfstream_internal_t *intf, int c) break; } } + +intfstream_t* intfstream_open_file(const char *path, unsigned hints) +{ + intfstream_info_t info; + intfstream_t *fd = NULL; + + info.type = INTFSTREAM_FILE; + fd = (intfstream_t*)intfstream_init(&info); + + if (!fd) + return NULL; + + if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, hints)) + goto error; + + return fd; + +error: + if (fd) + { + intfstream_close(fd); + free(fd); + } + return NULL; +} + +intfstream_t *intfstream_open_memory(void *data, size_t size, unsigned hints) +{ + intfstream_info_t info; + intfstream_t *fd = NULL; + + info.type = INTFSTREAM_MEMORY; + info.memory.buf.data = (uint8_t*)data; + info.memory.buf.size = size; + info.memory.writable = false; + + fd = (intfstream_t*)intfstream_init(&info); + + if (!fd) + return NULL; + + if (!intfstream_open(fd, NULL, RETRO_VFS_FILE_ACCESS_READ, hints)) + goto error; + + return fd; + +error: + if (fd) + { + intfstream_close(fd); + free(fd); + } + return NULL; +} + +intfstream_t *intfstream_open_chd_track(const char *path, + int32_t track, unsigned hints) +{ + intfstream_info_t info; + intfstream_t *fd = NULL; + + info.type = INTFSTREAM_CHD; + info.chd.track = track; + + fd = (intfstream_t*)intfstream_init(&info); + + if (!fd) + return NULL; + + if (!intfstream_open(fd, path, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) + goto error; + + return fd; + +error: + if (fd) + { + intfstream_close(fd); + free(fd); + } + return NULL; +} diff --git a/tasks/task_database.c b/tasks/task_database.c index 8d1b8f3325..7169d65ce4 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -90,89 +90,6 @@ int detect_gc_game(intfstream_t *fd, char *game_id); int detect_serial_ascii_game(intfstream_t *fd, char *game_id); -static intfstream_t* intfstream_open_file(const char *path, unsigned hints) -{ - intfstream_info_t info; - intfstream_t *fd = NULL; - - info.type = INTFSTREAM_FILE; - fd = (intfstream_t*)intfstream_init(&info); - - if (!fd) - return NULL; - - if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, hints)) - goto error; - - return fd; - -error: - if (fd) - { - intfstream_close(fd); - free(fd); - } - return NULL; -} - -static intfstream_t *open_memory(void *data, size_t size) -{ - intfstream_info_t info; - intfstream_t *fd = NULL; - - info.type = INTFSTREAM_MEMORY; - info.memory.buf.data = (uint8_t*)data; - info.memory.buf.size = size; - info.memory.writable = false; - - fd = (intfstream_t*)intfstream_init(&info); - - if (!fd) - return NULL; - - if (!intfstream_open(fd, NULL, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) - goto error; - - return fd; - -error: - if (fd) - { - intfstream_close(fd); - free(fd); - } - return NULL; -} - -static intfstream_t* -open_chd_track(const char *path, int32_t track) -{ - intfstream_info_t info; - intfstream_t *fd = NULL; - - info.type = INTFSTREAM_CHD; - info.chd.track = track; - - fd = (intfstream_t*)intfstream_init(&info); - - if (!fd) - return NULL; - - if (!intfstream_open(fd, path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) - goto error; - - return fd; - -error: - if (fd) - { - intfstream_close(fd); - free(fd); - } - return NULL; -} - static void database_info_set_type( database_info_handle_t *handle, enum database_type type) @@ -320,7 +237,7 @@ static bool intfstream_file_get_serial(const char *name, intfstream_close(fd); free(fd); - fd = open_memory(data, size); + fd = intfstream_open_memory(data, size, RFILE_HINT_NONE); if (!fd) { free(data); @@ -401,7 +318,9 @@ static int task_database_gdi_get_serial(const char *name, char* serial) static int task_database_chd_get_serial(const char *name, char* serial) { int result; - intfstream_t *fd = open_chd_track(name, CHDSTREAM_TRACK_FIRST_DATA); + intfstream_t *fd = intfstream_open_chd_track( + name, CHDSTREAM_TRACK_FIRST_DATA, + RFILE_HINT_NONE); if (!fd) return 0; @@ -462,7 +381,7 @@ static bool intfstream_file_get_crc(const char *name, intfstream_close(fd); free(fd); - fd = open_memory(data, size); + fd = intfstream_open_memory(data, size, RFILE_HINT_NONE); if (!fd) goto error; @@ -552,7 +471,9 @@ static int task_database_gdi_get_crc(const char *name, uint32_t *crc) static bool task_database_chd_get_crc(const char *name, uint32_t *crc) { int rv; - intfstream_t *fd = open_chd_track(name, CHDSTREAM_TRACK_PRIMARY); + intfstream_t *fd = intfstream_open_chd_track( + name, CHDSTREAM_TRACK_PRIMARY, + RFILE_HINT_NONE); if (!fd) return 0; From fde596fae4f851720f63be6ed3db75fd9c17585b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:25:44 +0100 Subject: [PATCH 179/698] Cleanups --- libretro-common/streams/interface_stream.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index 0363231b56..06a4113526 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -276,7 +276,7 @@ int intfstream_getc(intfstream_internal_t *intf) #ifdef HAVE_CHD return chdstream_getc(intf->chd.fp); #else - return -1; + break; #endif } @@ -298,7 +298,7 @@ int intfstream_tell(intfstream_internal_t *intf) #ifdef HAVE_CHD return (int)chdstream_tell(intf->chd.fp); #else - return -1; + break; #endif } From 38e6d2443fcd162d17d90f52742c82a3dd8f1d80 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:31:14 +0100 Subject: [PATCH 180/698] Change functions --- .../include/streams/interface_stream.h | 6 ++-- libretro-common/streams/interface_stream.c | 15 ++++----- tasks/task_database.c | 31 +++++++++++++------ 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index a0a26caeba..3a21567d3f 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -91,13 +91,13 @@ void intfstream_putc(intfstream_internal_t *intf, int c); int intfstream_close(intfstream_internal_t *intf); intfstream_t* intfstream_open_file(const char *path, - unsigned hints); + unsigned mode, unsigned hints); intfstream_t *intfstream_open_memory(void *data, - size_t size, unsigned hints); + unsigned mode, unsigned hints, size_t size); intfstream_t *intfstream_open_chd_track(const char *path, - int32_t track, unsigned hints); + unsigned mode, unsigned hints, int32_t track); RETRO_END_DECLS diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index 06a4113526..78bb4c525a 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -341,7 +341,8 @@ void intfstream_putc(intfstream_internal_t *intf, int c) } } -intfstream_t* intfstream_open_file(const char *path, unsigned hints) +intfstream_t* intfstream_open_file(const char *path, + unsigned mode, unsigned hints) { intfstream_info_t info; intfstream_t *fd = NULL; @@ -352,7 +353,7 @@ intfstream_t* intfstream_open_file(const char *path, unsigned hints) if (!fd) return NULL; - if (!intfstream_open(fd, path, RETRO_VFS_FILE_ACCESS_READ, hints)) + if (!intfstream_open(fd, path, mode, hints)) goto error; return fd; @@ -366,7 +367,8 @@ error: return NULL; } -intfstream_t *intfstream_open_memory(void *data, size_t size, unsigned hints) +intfstream_t *intfstream_open_memory(void *data, + unsigned mode, unsigned hints, size_t size) { intfstream_info_t info; intfstream_t *fd = NULL; @@ -381,7 +383,7 @@ intfstream_t *intfstream_open_memory(void *data, size_t size, unsigned hints) if (!fd) return NULL; - if (!intfstream_open(fd, NULL, RETRO_VFS_FILE_ACCESS_READ, hints)) + if (!intfstream_open(fd, NULL, mode, hints)) goto error; return fd; @@ -396,7 +398,7 @@ error: } intfstream_t *intfstream_open_chd_track(const char *path, - int32_t track, unsigned hints) + unsigned mode, unsigned hints, int32_t track) { intfstream_info_t info; intfstream_t *fd = NULL; @@ -409,8 +411,7 @@ intfstream_t *intfstream_open_chd_track(const char *path, if (!fd) return NULL; - if (!intfstream_open(fd, path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) + if (!intfstream_open(fd, path, mode, hints)) goto error; return fd; diff --git a/tasks/task_database.c b/tasks/task_database.c index 7169d65ce4..48f59bfbfe 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -206,7 +206,8 @@ static bool intfstream_file_get_serial(const char *name, int rv; uint8_t *data = NULL; ssize_t file_size = -1; - intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); + intfstream_t *fd = intfstream_open_file(name, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fd) return 0; @@ -237,7 +238,9 @@ static bool intfstream_file_get_serial(const char *name, intfstream_close(fd); free(fd); - fd = intfstream_open_memory(data, size, RFILE_HINT_NONE); + fd = intfstream_open_memory(data, RETRO_VFS_FILE_ACCESS_READ, + RFILE_HINT_NONE, + size); if (!fd) { free(data); @@ -319,8 +322,10 @@ static int task_database_chd_get_serial(const char *name, char* serial) { int result; intfstream_t *fd = intfstream_open_chd_track( - name, CHDSTREAM_TRACK_FIRST_DATA, - RFILE_HINT_NONE); + name, + RETRO_VFS_FILE_ACCESS_READ, + RFILE_HINT_NONE, + CHDSTREAM_TRACK_FIRST_DATA); if (!fd) return 0; @@ -351,7 +356,8 @@ static bool intfstream_file_get_crc(const char *name, size_t offset, size_t size, uint32_t *crc) { int rv; - intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); + intfstream_t *fd = intfstream_open_file(name, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); uint8_t *data = NULL; ssize_t file_size = -1; @@ -381,7 +387,8 @@ static bool intfstream_file_get_crc(const char *name, intfstream_close(fd); free(fd); - fd = intfstream_open_memory(data, size, RFILE_HINT_NONE); + fd = intfstream_open_memory(data, RETRO_VFS_FILE_ACCESS_READ, + RFILE_HINT_NONE, size); if (!fd) goto error; @@ -472,8 +479,10 @@ static bool task_database_chd_get_crc(const char *name, uint32_t *crc) { int rv; intfstream_t *fd = intfstream_open_chd_track( - name, CHDSTREAM_TRACK_PRIMARY, - RFILE_HINT_NONE); + name, + RETRO_VFS_FILE_ACCESS_READ, + RFILE_HINT_NONE, + CHDSTREAM_TRACK_PRIMARY); if (!fd) return 0; @@ -495,7 +504,8 @@ static void task_database_cue_prune(database_info_handle_t *db, { size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); - intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); + intfstream_t *fd = intfstream_open_file(name, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fd) goto end; @@ -527,7 +537,8 @@ static void gdi_prune(database_info_handle_t *db, const char *name) { size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); - intfstream_t *fd = intfstream_open_file(name, RFILE_HINT_NONE); + intfstream_t *fd = intfstream_open_file(name, + RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); if (!fd) goto end; From 61d3f90cae77f747bc6495f3f247f4911f9fe94b Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:53:47 +0100 Subject: [PATCH 181/698] Add hint defines to libretro.h --- cheevos/cheevos.c | 6 ++- configuration.c | 9 ++-- gfx/drivers/gx_gfx.c | 3 +- gfx/video_shader_parse.c | 3 +- libretro-common/features/features_cpu.c | 3 +- libretro-common/file/config_file.c | 3 +- libretro-common/file/file_path.c | 3 +- libretro-common/formats/bmp/rbmp_encode.c | 3 +- libretro-common/formats/png/rpng_encode.c | 3 +- libretro-common/formats/xml/rxml.c | 3 +- libretro-common/hash/rhash.c | 3 +- libretro-common/include/libretro.h | 3 ++ libretro-common/include/streams/file_stream.h | 4 -- libretro-common/streams/file_stream.c | 25 ++++++----- libretro-db/c_converter.c | 3 +- libretro-db/libretrodb.c | 6 ++- libretro-db/lua/lua_converter.c | 3 +- libretro-db/lua/testlib.c | 3 +- libretro-db/rmsgpack_test.c | 3 +- menu/menu_setting.c | 3 +- movie.c | 44 ++++++++++--------- playlist.c | 5 ++- tasks/task_database.c | 16 +++---- tasks/task_database_cue.c | 6 +-- tasks/task_save.c | 6 +-- 25 files changed, 100 insertions(+), 72 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 08af2a72be..34f7b5e4d4 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2640,8 +2640,10 @@ static int cheevos_iterate(coro_t* coro) /* Load the content into memory, or copy it over to our own buffer */ if (!CHEEVOS_VAR_DATA) { - CHEEVOS_VAR_STREAM = filestream_open(CHEEVOS_VAR_PATH, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + CHEEVOS_VAR_STREAM = filestream_open( + CHEEVOS_VAR_PATH, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!CHEEVOS_VAR_STREAM) CORO_STOP(); diff --git a/configuration.c b/configuration.c index 77975d470e..bcb7b0c578 100644 --- a/configuration.c +++ b/configuration.c @@ -3793,17 +3793,20 @@ bool config_save_file(const char *path) #ifdef HAVE_LAKKA if (settings->bools.ssh_enable) filestream_close(filestream_open(LAKKA_SSH_PATH, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE)); else path_file_remove(LAKKA_SSH_PATH); if (settings->bools.samba_enable) filestream_close(filestream_open(LAKKA_SAMBA_PATH, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE)); else path_file_remove(LAKKA_SAMBA_PATH); if (settings->bools.bluetooth_enable) filestream_close(filestream_open(LAKKA_BLUETOOTH_PATH, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE)); else path_file_remove(LAKKA_BLUETOOTH_PATH); #endif diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index c4886f199e..ef676d6312 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -721,7 +721,8 @@ static void gx_efb_screenshot(void) int x, y; uint8_t tga_header[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x18, 0x00}; RFILE *out = filestream_open("/screenshot.tga", - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!out) return; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index 32cdae25c4..d2e8aa7801 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -547,7 +547,8 @@ bool video_shader_resolve_parameters(config_file_t *conf, * Ideally, we'd get rid of this path sooner or later. */ #endif file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { diff --git a/libretro-common/features/features_cpu.c b/libretro-common/features/features_cpu.c index a64be01004..0188375999 100644 --- a/libretro-common/features/features_cpu.c +++ b/libretro-common/features/features_cpu.c @@ -321,7 +321,8 @@ static unsigned char check_arm_cpu_feature(const char* feature) char line[1024]; unsigned char status = 0; RFILE *fp = filestream_open("/proc/cpuinfo", - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fp) return 0; diff --git a/libretro-common/file/config_file.c b/libretro-common/file/config_file.c index 4ab05e7e47..c762efc310 100644 --- a/libretro-common/file/config_file.c +++ b/libretro-common/file/config_file.c @@ -355,7 +355,8 @@ static config_file_t *config_file_new_internal( conf->include_depth = depth; file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { diff --git a/libretro-common/file/file_path.c b/libretro-common/file/file_path.c index f5e7eccd73..753a1a9c09 100644 --- a/libretro-common/file/file_path.c +++ b/libretro-common/file/file_path.c @@ -412,7 +412,8 @@ bool path_file_exists(const char *path) return false; dummy = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!dummy) return false; diff --git a/libretro-common/formats/bmp/rbmp_encode.c b/libretro-common/formats/bmp/rbmp_encode.c index c0502d8e52..8b22f5ce31 100644 --- a/libretro-common/formats/bmp/rbmp_encode.c +++ b/libretro-common/formats/bmp/rbmp_encode.c @@ -216,7 +216,8 @@ bool rbmp_save_image( { bool ret = false; RFILE *file = filestream_open(filename, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) return false; diff --git a/libretro-common/formats/png/rpng_encode.c b/libretro-common/formats/png/rpng_encode.c index 9be5f857c1..5599e5290a 100644 --- a/libretro-common/formats/png/rpng_encode.c +++ b/libretro-common/formats/png/rpng_encode.c @@ -228,7 +228,8 @@ static bool rpng_save_image(const char *path, uint32_t total_in = 0; uint32_t total_out = 0; RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) GOTO_END_ERROR(); diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index 2bac625b74..59e3e5a793 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -420,7 +420,8 @@ rxml_document_t *rxml_load_document(const char *path) const char *mem_ptr = NULL; long len = 0; RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) return NULL; diff --git a/libretro-common/hash/rhash.c b/libretro-common/hash/rhash.c index 3ba15eeda8..7dbadea78a 100644 --- a/libretro-common/hash/rhash.c +++ b/libretro-common/hash/rhash.c @@ -512,7 +512,8 @@ int sha1_calculate(const char *path, char *result) unsigned char buff[4096]; int rv = 1; RFILE *fd = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fd) goto error; diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index b10f18b968..6a0929b302 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1051,6 +1051,9 @@ struct retro_hw_render_context_negotiation_interface #define RETRO_VFS_FILE_ACCESS_READ_WRITE (RETRO_VFS_FILE_ACCESS_READ | RETRO_VFS_FILE_ACCESS_WRITE) /* Read-write mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified*/ #define RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING (1 << 2) /* Prevents discarding content of existing files opened for writing */ +#define RETRO_VFS_FILE_ACCESS_HINT_NONE (0) +/* Indicate that we would want to map the file into memory if possible. Requires RETRO_VFS_FILE_ACCESS_READ. This is only a hint and it is up to the frontend to honor and implement it. */ +#define RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP (1 << 0) #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index faf154723c..543de8621a 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -43,10 +43,6 @@ typedef struct RFILE RFILE; #define FILESTREAM_REQUIRED_VFS_VERSION 1 -#define RFILE_HINT_NONE (0) -/* requires RETRO_VFS_FILE_ACCESS_READ */ -#define RFILE_HINT_MMAP (1 << 9) - int64_t filestream_get_size(RFILE *stream); void filestream_set_size(RFILE *stream); diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 59468832fb..d6bfc020da 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -76,6 +76,7 @@ #define RFILE_HINT_UNBUFFERED (1 << 8) +#include #include #include #include @@ -164,11 +165,11 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) stream->hints = hints; #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP && mode == RETRO_VFS_FILE_ACCESS_READ) + if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP && mode == RETRO_VFS_FILE_ACCESS_READ) stream->hints |= RFILE_HINT_UNBUFFERED; else #endif - stream->hints &= ~RFILE_HINT_MMAP; + stream->hints &= ~RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP; switch (mode) { @@ -260,7 +261,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) if (stream->fd == -1) goto error; #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP) + if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) { stream->mappos = 0; stream->mapped = NULL; @@ -275,7 +276,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) stream->mapsize, PROT_READ, MAP_SHARED, stream->fd, 0); if (stream->mapped == MAP_FAILED) - stream->hints &= ~RFILE_HINT_MMAP; + stream->hints &= ~RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP; } #endif } @@ -322,7 +323,7 @@ ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) #ifdef HAVE_MMAP /* Need to check stream->mapped because this function is * called in filestream_open() */ - if (stream->mapped && stream->hints & RFILE_HINT_MMAP) + if (stream->mapped && stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) { /* fseek() returns error on under/overflow but allows cursor > EOF for read-only file descriptors. */ @@ -398,7 +399,7 @@ ssize_t filestream_tell(RFILE *stream) #ifdef HAVE_MMAP /* Need to check stream->mapped because this function * is called in filestream_open() */ - if (stream->mapped && stream->hints & RFILE_HINT_MMAP) + if (stream->mapped && stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) return stream->mappos; #endif if (lseek(stream->fd, 0, SEEK_CUR) < 0) @@ -424,7 +425,7 @@ ssize_t filestream_read(RFILE *stream, void *s, size_t len) return fread(s, 1, len, stream->fp); #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP) + if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) { if (stream->mappos > stream->mapsize) goto error; @@ -459,7 +460,7 @@ ssize_t filestream_write(RFILE *stream, const void *s, size_t len) return fwrite(s, 1, len, stream->fp); #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP) + if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) goto error; #endif return write(stream->fd, s, len); @@ -520,7 +521,7 @@ int filestream_close(RFILE *stream) else { #ifdef HAVE_MMAP - if (stream->hints & RFILE_HINT_MMAP) + if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) munmap(stream->mapped, stream->mapsize); #endif } @@ -553,7 +554,8 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) ssize_t content_buf_size = 0; void *content_buf = NULL; RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { @@ -620,7 +622,8 @@ bool filestream_write_file(const char *path, const void *data, ssize_t size) { ssize_t ret = 0; RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) return false; diff --git a/libretro-db/c_converter.c b/libretro-db/c_converter.c index 3dc51496c3..d114188553 100644 --- a/libretro-db/c_converter.c +++ b/libretro-db/c_converter.c @@ -805,7 +805,8 @@ int main(int argc, char** argv) } rdb_file = filestream_open(rdb_path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!rdb_file) { diff --git a/libretro-db/libretrodb.c b/libretro-db/libretrodb.c index 5deed1d426..6bbc076c66 100644 --- a/libretro-db/libretrodb.c +++ b/libretro-db/libretrodb.c @@ -218,7 +218,8 @@ int libretrodb_open(const char *path, libretrodb_t *db) libretrodb_metadata_t md; int rv = 0; RFILE *fd = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fd) return -errno; @@ -434,7 +435,8 @@ int libretrodb_cursor_open(libretrodb_t *db, libretrodb_cursor_t *cursor, return -errno; fd = filestream_open(db->path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_MMAP); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP); if (!fd) return -errno; diff --git a/libretro-db/lua/lua_converter.c b/libretro-db/lua/lua_converter.c index 81c495f455..c99bd7f70f 100644 --- a/libretro-db/lua/lua_converter.c +++ b/libretro-db/lua/lua_converter.c @@ -93,7 +93,8 @@ int main(int argc, char ** argv) call_init(L, argc - 2, (const char **) argv + 2); dst = filestream_open(db_file, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!dst) { diff --git a/libretro-db/lua/testlib.c b/libretro-db/lua/testlib.c index bc5bd56a4c..cf4f8d2317 100644 --- a/libretro-db/lua/testlib.c +++ b/libretro-db/lua/testlib.c @@ -107,7 +107,8 @@ static int create_db(lua_State *L) lua_setfield(L, LUA_REGISTRYINDEX, "testlib_get_value"); dst = filestream_open(db_file, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!dst) { lua_pushstring(L, "Could not open destination file"); diff --git a/libretro-db/rmsgpack_test.c b/libretro-db/rmsgpack_test.c index c6383cdc0e..da281c8ef5 100644 --- a/libretro-db/rmsgpack_test.c +++ b/libretro-db/rmsgpack_test.c @@ -187,7 +187,8 @@ int main(void) { struct stub_state state; RFILE *fd = filestream_open("test.msgpack", - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); state.i = 0; state.stack[0] = 0; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index f2307cfbc3..d55a5c8c81 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -1878,7 +1878,8 @@ static void systemd_service_toggle(const char *path, char *unit, bool enable) if (enable) filestream_close(filestream_open(path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE)); + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE)); else path_file_remove(path); diff --git a/movie.c b/movie.c index 9e6e6bcc04..1e8f99402a 100644 --- a/movie.c +++ b/movie.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include "configuration.h" #include "movie.h" @@ -35,7 +35,7 @@ struct bsv_movie { - RFILE *file; + intfstream_t *file; /* A ring buffer keeping track of positions * in the file for each frame. */ @@ -75,8 +75,9 @@ static bool bsv_movie_init_playback(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + intfstream_t *file = intfstream_open_file(path, + RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { @@ -87,7 +88,7 @@ static bool bsv_movie_init_playback(bsv_movie_t *handle, const char *path) handle->file = file; handle->playback = true; - filestream_read(handle->file, header, sizeof(uint32_t) * 4); + intfstream_read(handle->file, header, sizeof(uint32_t) * 4); /* Compatibility with old implementation that * used incorrect documentation. */ if (swap_if_little32(header[MAGIC_INDEX]) != BSV_MAGIC @@ -123,7 +124,8 @@ static bool bsv_movie_init_playback(bsv_movie_t *handle, const char *path) handle->state = buf; handle->state_size = state_size; - if (filestream_read(handle->file, handle->state, state_size) != state_size) + if (intfstream_read(handle->file, + handle->state, state_size) != state_size) { RARCH_ERR("%s\n", msg_hash_to_str(MSG_COULD_NOT_READ_STATE_FROM_MOVIE)); return false; @@ -153,8 +155,9 @@ static bool bsv_movie_init_record(bsv_movie_t *handle, const char *path) uint32_t state_size = 0; uint32_t content_crc = 0; uint32_t header[4] = {0}; - RFILE *file = filestream_open(path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + intfstream_t *file = intfstream_open_file(path, + RETRO_VFS_FILE_ACCESS_WRITE, + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { @@ -183,7 +186,7 @@ static bool bsv_movie_init_record(bsv_movie_t *handle, const char *path) RARCH_ERR("----- debug %u -----\n", header[3]); #endif - filestream_write(handle->file, header, 4 * sizeof(uint32_t)); + intfstream_write(handle->file, header, 4 * sizeof(uint32_t)); handle->min_file_pos = sizeof(header) + state_size; handle->state_size = state_size; @@ -201,7 +204,8 @@ static bool bsv_movie_init_record(bsv_movie_t *handle, const char *path) core_serialize(&serial_info); - filestream_write(handle->file, handle->state, state_size); + intfstream_write(handle->file, + handle->state, state_size); } return true; @@ -212,7 +216,7 @@ static void bsv_movie_free(bsv_movie_t *handle) if (!handle) return; - filestream_close(handle->file); + intfstream_close(handle->file); free(handle->state); free(handle->frame_pos); @@ -258,7 +262,7 @@ void bsv_movie_set_frame_start(void) { if (bsv_movie_state_handle) bsv_movie_state_handle->frame_pos[bsv_movie_state_handle->frame_ptr] - = filestream_tell(bsv_movie_state_handle->file); + = intfstream_tell(bsv_movie_state_handle->file); } void bsv_movie_set_frame_end(void) @@ -284,7 +288,7 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) { /* If we're at the beginning... */ handle->frame_ptr = 0; - filestream_seek(handle->file, handle->min_file_pos, SEEK_SET); + intfstream_seek(handle->file, handle->min_file_pos, SEEK_SET); } else { @@ -296,11 +300,11 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) * plus another. */ handle->frame_ptr = (handle->frame_ptr - (handle->first_rewind ? 1 : 2)) & handle->frame_mask; - filestream_seek(handle->file, + intfstream_seek(handle->file, handle->frame_pos[handle->frame_ptr], SEEK_SET); } - if (filestream_tell(handle->file) <= (long)handle->min_file_pos) + if (intfstream_tell(handle->file) <= (long)handle->min_file_pos) { /* We rewound past the beginning. */ @@ -311,17 +315,17 @@ static void bsv_movie_frame_rewind(bsv_movie_t *handle) /* If recording, we simply reset * the starting point. Nice and easy. */ - filestream_seek(handle->file, 4 * sizeof(uint32_t), SEEK_SET); + intfstream_seek(handle->file, 4 * sizeof(uint32_t), SEEK_SET); serial_info.data = handle->state; serial_info.size = handle->state_size; core_serialize(&serial_info); - filestream_write(handle->file, handle->state, handle->state_size); + intfstream_write(handle->file, handle->state, handle->state_size); } else - filestream_seek(handle->file, handle->min_file_pos, SEEK_SET); + intfstream_seek(handle->file, handle->min_file_pos, SEEK_SET); } } @@ -389,7 +393,7 @@ bool bsv_movie_init(void) bool bsv_movie_get_input(int16_t *bsv_data) { - if (filestream_read(bsv_movie_state_handle->file, bsv_data, 1) != 1) + if (intfstream_read(bsv_movie_state_handle->file, bsv_data, 1) != 1) return false; *bsv_data = swap_if_big16(*bsv_data); @@ -450,7 +454,7 @@ bool bsv_movie_ctl(enum bsv_ctl_state state, void *data) int16_t *bsv_data = (int16_t*)data; *bsv_data = swap_if_big16(*bsv_data); - filestream_write(bsv_movie_state_handle->file, bsv_data, 1); + intfstream_write(bsv_movie_state_handle->file, bsv_data, 1); } break; case BSV_MOVIE_CTL_NONE: diff --git a/playlist.c b/playlist.c index 2168272214..9a8924740f 100644 --- a/playlist.c +++ b/playlist.c @@ -395,7 +395,7 @@ void playlist_write_file(playlist_t *playlist) return; file = filestream_open(playlist->conf_path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!file) { @@ -495,7 +495,8 @@ static bool playlist_read_file( unsigned i; char buf[PLAYLIST_ENTRIES][1024]; RFILE *file = filestream_open( - path, RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + path, RETRO_VFS_FILE_ACCESS_READ, + RETRO_VFS_FILE_ACCESS_HINT_NONE); for (i = 0; i < PLAYLIST_ENTRIES; i++) buf[i][0] = '\0'; diff --git a/tasks/task_database.c b/tasks/task_database.c index 48f59bfbfe..f274fc554b 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -207,7 +207,7 @@ static bool intfstream_file_get_serial(const char *name, uint8_t *data = NULL; ssize_t file_size = -1; intfstream_t *fd = intfstream_open_file(name, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fd) return 0; @@ -239,7 +239,7 @@ static bool intfstream_file_get_serial(const char *name, intfstream_close(fd); free(fd); fd = intfstream_open_memory(data, RETRO_VFS_FILE_ACCESS_READ, - RFILE_HINT_NONE, + RETRO_VFS_FILE_ACCESS_HINT_NONE, size); if (!fd) { @@ -324,7 +324,7 @@ static int task_database_chd_get_serial(const char *name, char* serial) intfstream_t *fd = intfstream_open_chd_track( name, RETRO_VFS_FILE_ACCESS_READ, - RFILE_HINT_NONE, + RETRO_VFS_FILE_ACCESS_HINT_NONE, CHDSTREAM_TRACK_FIRST_DATA); if (!fd) return 0; @@ -357,7 +357,7 @@ static bool intfstream_file_get_crc(const char *name, { int rv; intfstream_t *fd = intfstream_open_file(name, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); uint8_t *data = NULL; ssize_t file_size = -1; @@ -388,7 +388,7 @@ static bool intfstream_file_get_crc(const char *name, intfstream_close(fd); free(fd); fd = intfstream_open_memory(data, RETRO_VFS_FILE_ACCESS_READ, - RFILE_HINT_NONE, size); + RETRO_VFS_FILE_ACCESS_HINT_NONE, size); if (!fd) goto error; @@ -481,7 +481,7 @@ static bool task_database_chd_get_crc(const char *name, uint32_t *crc) intfstream_t *fd = intfstream_open_chd_track( name, RETRO_VFS_FILE_ACCESS_READ, - RFILE_HINT_NONE, + RETRO_VFS_FILE_ACCESS_HINT_NONE, CHDSTREAM_TRACK_PRIMARY); if (!fd) return 0; @@ -505,7 +505,7 @@ static void task_database_cue_prune(database_info_handle_t *db, size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); intfstream_t *fd = intfstream_open_file(name, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fd) goto end; @@ -538,7 +538,7 @@ static void gdi_prune(database_info_handle_t *db, const char *name) size_t i; char *path = (char *)malloc(PATH_MAX_LENGTH + 1); intfstream_t *fd = intfstream_open_file(name, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!fd) goto end; diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c index ae134aee63..2215d8c975 100644 --- a/tasks/task_database_cue.c +++ b/tasks/task_database_cue.c @@ -414,7 +414,7 @@ static ssize_t get_file_size(const char *path) { ssize_t rv; RFILE *fd = filestream_open(path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (fd == NULL) return -1; rv = filestream_get_size(fd); @@ -469,7 +469,7 @@ int cue_find_track(const char *cue_path, bool first, goto error; if (!intfstream_open(fd, cue_path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE)) { RARCH_LOG("Could not open CUE file '%s': %s\n", cue_path, strerror(errno)); @@ -624,7 +624,7 @@ int gdi_find_track(const char *gdi_path, bool first, goto error; if (!intfstream_open(fd, gdi_path, - RETRO_VFS_FILE_ACCESS_READ, RFILE_HINT_NONE)) + RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE)) { RARCH_LOG("Could not open GDI file '%s': %s\n", gdi_path, strerror(errno)); diff --git a/tasks/task_save.c b/tasks/task_save.c index 5d29865a6a..c3538aa905 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -158,7 +158,7 @@ static void autosave_thread(void *data) { /* Should probably deal with this more elegantly. */ RFILE *file = filestream_open(save->path, - RETRO_VFS_FILE_ACCESS_WRITE, RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (file) { @@ -566,7 +566,7 @@ static void task_save_handler(retro_task_t *task) if (!state->file) { state->file = filestream_open(state->path, RETRO_VFS_FILE_ACCESS_WRITE, - RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!state->file) return; @@ -740,7 +740,7 @@ static void task_load_handler(retro_task_t *task) { state->file = filestream_open(state->path, RETRO_VFS_FILE_ACCESS_READ, - RFILE_HINT_NONE); + RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!state->file) goto error; From 54ce2ec5e94e859fc9236a50247172ab6525aa27 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 12:57:53 +0100 Subject: [PATCH 182/698] playlist.c - use intfstream --- playlist.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/playlist.c b/playlist.c index 9a8924740f..87b7632d9d 100644 --- a/playlist.c +++ b/playlist.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -494,19 +495,19 @@ static bool playlist_read_file( { unsigned i; char buf[PLAYLIST_ENTRIES][1024]; - RFILE *file = filestream_open( + intfstream_t *file = intfstream_open_file( path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); - for (i = 0; i < PLAYLIST_ENTRIES; i++) - buf[i][0] = '\0'; - /* If playlist file does not exist, * create an empty playlist instead. */ if (!file) return true; + for (i = 0; i < PLAYLIST_ENTRIES; i++) + buf[i][0] = '\0'; + for (playlist->size = 0; playlist->size < playlist->cap; ) { unsigned i; @@ -516,7 +517,7 @@ static bool playlist_read_file( char *last = NULL; *buf[i] = '\0'; - if (!filestream_gets(file, buf[i], sizeof(buf[i]))) + if (!intfstream_gets(file, buf[i], sizeof(buf[i]))) goto end; /* Read playlist entry and terminate string with NUL character @@ -548,7 +549,7 @@ static bool playlist_read_file( } end: - filestream_close(file); + intfstream_close(file); return true; } From 12e6f389997274658eba5f197f35e0b9f4a6ef65 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 13:01:17 +0100 Subject: [PATCH 183/698] (gfx/video_shader_parse) Use intfstream instead of file_stream --- gfx/video_shader_parse.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index d2e8aa7801..c25d309124 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -25,7 +25,7 @@ #include "video_driver.h" /* video_context_driver_get_api */ #include #include -#include +#include #include "../msg_hash.h" #include "../verbosity.h" @@ -521,10 +521,10 @@ bool video_shader_resolve_parameters(config_file_t *conf, for (i = 0; i < shader->passes; i++) { - RFILE *file = NULL; - size_t line_size = 4096 * sizeof(char); - char *line = (char*)malloc(4096 * sizeof(char)); - const char *path = shader->pass[i].source.path; + intfstream_t *file = NULL; + size_t line_size = 4096 * sizeof(char); + char *line = (char*)malloc(4096 * sizeof(char)); + const char *path = shader->pass[i].source.path; if (string_is_empty(path)) { @@ -546,7 +546,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, /* If that doesn't work, fallback to the old path. * Ideally, we'd get rid of this path sooner or later. */ #endif - file = filestream_open(path, + file = intfstream_open_file(path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); @@ -559,7 +559,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, line[0] = '\0'; while (shader->num_parameters < ARRAY_SIZE(shader->parameters) - && filestream_gets(file, line, line_size)) + && intfstream_gets(file, line, line_size)) { int ret = sscanf(line, "#pragma parameter %63s \"%63[^\"]\" %f %f %f %f", @@ -585,7 +585,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, } free(line); - filestream_close(file); + intfstream_close(file); } if (conf && !video_shader_resolve_current_parameters(conf, shader)) From e62e9233d7a92027c777b3ff637ce41f2c28b89d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 13:21:44 +0100 Subject: [PATCH 184/698] Add intfstream_get_size --- cheevos/cheevos.c | 13 +++++++------ .../include/streams/interface_stream.h | 3 +++ libretro-common/streams/interface_stream.c | 19 +++++++++++++++++++ tasks/task_database_cue.c | 14 +++++++------- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 34f7b5e4d4..dae27cbb5c 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -2488,7 +2489,7 @@ typedef struct size_t romsize, bytes; \ int mapper; \ bool round; \ - RFILE* stream; \ + intfstream_t *stream; \ size_t size; \ char url[256]; \ struct http_connection_t *conn; \ @@ -2640,7 +2641,7 @@ static int cheevos_iterate(coro_t* coro) /* Load the content into memory, or copy it over to our own buffer */ if (!CHEEVOS_VAR_DATA) { - CHEEVOS_VAR_STREAM = filestream_open( + CHEEVOS_VAR_STREAM = intfstream_open_file( CHEEVOS_VAR_PATH, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); @@ -2650,7 +2651,7 @@ static int cheevos_iterate(coro_t* coro) CORO_YIELD(); CHEEVOS_VAR_LEN = 0; - CHEEVOS_VAR_COUNT = filestream_get_size(CHEEVOS_VAR_STREAM); + CHEEVOS_VAR_COUNT = intfstream_get_size(CHEEVOS_VAR_STREAM); if (CHEEVOS_VAR_COUNT > CHEEVOS_SIZE_LIMIT) CHEEVOS_VAR_COUNT = CHEEVOS_SIZE_LIMIT; @@ -2659,7 +2660,7 @@ static int cheevos_iterate(coro_t* coro) if (!CHEEVOS_VAR_DATA) { - filestream_close(CHEEVOS_VAR_STREAM); + intfstream_close(CHEEVOS_VAR_STREAM); CORO_STOP(); } @@ -2671,7 +2672,7 @@ static int cheevos_iterate(coro_t* coro) if (to_read > CHEEVOS_VAR_COUNT) to_read = CHEEVOS_VAR_COUNT; - num_read = filestream_read(CHEEVOS_VAR_STREAM, (void*)buffer, to_read); + num_read = intfstream_read(CHEEVOS_VAR_STREAM, (void*)buffer, to_read); if (num_read <= 0) break; @@ -2685,7 +2686,7 @@ static int cheevos_iterate(coro_t* coro) CORO_YIELD(); } - filestream_close(CHEEVOS_VAR_STREAM); + intfstream_close(CHEEVOS_VAR_STREAM); } /* Use the supported extensions as a hint diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index 3a21567d3f..ebcb8fda7d 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -90,6 +90,8 @@ void intfstream_putc(intfstream_internal_t *intf, int c); int intfstream_close(intfstream_internal_t *intf); +int64_t intfstream_get_size(intfstream_internal_t *intf); + intfstream_t* intfstream_open_file(const char *path, unsigned mode, unsigned hints); @@ -99,6 +101,7 @@ intfstream_t *intfstream_open_memory(void *data, intfstream_t *intfstream_open_chd_track(const char *path, unsigned mode, unsigned hints, int32_t track); + RETRO_END_DECLS #endif diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index 78bb4c525a..fb34bb3657 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -57,6 +57,25 @@ struct intfstream_internal #endif }; +int64_t intfstream_get_size(intfstream_internal_t *intf) +{ + if (!intf) + return 0; + + switch (intf->type) + { + case INTFSTREAM_FILE: + return filestream_get_size(intf->file.fp); + case INTFSTREAM_MEMORY: + return intf->memory.buf.size; + case INTFSTREAM_CHD: + /* TODO/FIXME - implement this */ + break; + } + + return 0; +} + bool intfstream_resize(intfstream_internal_t *intf, intfstream_info_t *info) { if (!intf || !info) diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c index 2215d8c975..cb8e366c74 100644 --- a/tasks/task_database_cue.c +++ b/tasks/task_database_cue.c @@ -410,15 +410,15 @@ clean: return rv; } -static ssize_t get_file_size(const char *path) +static ssize_t intfstream_get_file_size(const char *path) { ssize_t rv; - RFILE *fd = filestream_open(path, + intfstream_t *fd = intfstream_open_file(path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); - if (fd == NULL) + if (!fd) return -1; - rv = filestream_get_size(fd); - filestream_close(fd); + rv = intfstream_get_size(fd); + intfstream_close(fd); return rv; } @@ -503,7 +503,7 @@ int cue_find_track(const char *cue_path, bool first, get_token(fd, tmp_token, MAX_TOKEN_LEN); fill_pathname_join(last_file, cue_dir, tmp_token, PATH_MAX_LENGTH); - file_size = get_file_size(last_file); + file_size = intfstream_get_file_size(last_file); get_token(fd, tmp_token, MAX_TOKEN_LEN); @@ -685,7 +685,7 @@ int gdi_find_track(const char *gdi_path, bool first, fill_pathname_join(last_file, gdi_dir, tmp_token, PATH_MAX_LENGTH); - file_size = get_file_size(last_file); + file_size = intfstream_get_file_size(last_file); if (file_size < 0) { free(gdi_dir); From 1cd7568f1fece1025c27be132b0e15fa218fc9ba Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 13:26:52 +0100 Subject: [PATCH 185/698] (gx_gfx) Go through intfstream --- gfx/drivers/gx_gfx.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index ef676d6312..e826b143dd 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -22,7 +22,7 @@ #include #include -#include +#include #ifdef HAVE_CONFIG_H #include "../../config.h" @@ -720,14 +720,14 @@ static void gx_efb_screenshot(void) { int x, y; uint8_t tga_header[] = {0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x02, 0xE0, 0x01, 0x18, 0x00}; - RFILE *out = filestream_open("/screenshot.tga", + intfstream_t *out = intfstream_open("/screenshot.tga", RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!out) return; - filestream_write(out, tga_header, sizeof(tga_header)); + intfstream_write(out, tga_header, sizeof(tga_header)); for (y = 479; y >= 0; --y) { @@ -742,10 +742,10 @@ static void gx_efb_screenshot(void) line[i++] = color.g; line[i++] = color.r; } - filestream_write(out, line, sizeof(line)); + intfstream_write(out, line, sizeof(line)); } - filestream_close(out); + intfstream_close(out); } #endif From 32511090ca9eead8efcb3eb9ead02d4dba2d5acd Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 14:56:58 +0100 Subject: [PATCH 186/698] (task_save.c) Move to intfstream --- .../include/streams/interface_stream.h | 2 ++ libretro-common/streams/interface_stream.c | 18 ++++++++++++ tasks/task_save.c | 29 ++++++++++--------- 3 files changed, 35 insertions(+), 14 deletions(-) diff --git a/libretro-common/include/streams/interface_stream.h b/libretro-common/include/streams/interface_stream.h index ebcb8fda7d..98c0d61f99 100644 --- a/libretro-common/include/streams/interface_stream.h +++ b/libretro-common/include/streams/interface_stream.h @@ -92,6 +92,8 @@ int intfstream_close(intfstream_internal_t *intf); int64_t intfstream_get_size(intfstream_internal_t *intf); +int intfstream_flush(intfstream_internal_t *intf); + intfstream_t* intfstream_open_file(const char *path, unsigned mode, unsigned hints); diff --git a/libretro-common/streams/interface_stream.c b/libretro-common/streams/interface_stream.c index fb34bb3657..c1156ecb47 100644 --- a/libretro-common/streams/interface_stream.c +++ b/libretro-common/streams/interface_stream.c @@ -133,6 +133,24 @@ bool intfstream_open(intfstream_internal_t *intf, const char *path, return true; } +int intfstream_flush(intfstream_internal_t *intf) +{ + if (!intf) + return -1; + + switch (intf->type) + { + case INTFSTREAM_FILE: + return filestream_flush(intf->file.fp); + case INTFSTREAM_MEMORY: + case INTFSTREAM_CHD: + /* Should we stub this for these interfaces? */ + break; + } + + return 0; +} + int intfstream_close(intfstream_internal_t *intf) { if (!intf) diff --git a/tasks/task_save.c b/tasks/task_save.c index c3538aa905..eab39754b1 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -78,7 +79,7 @@ struct sram_block typedef struct { - RFILE *file; + intfstream_t *file; char path[PATH_MAX_LENGTH]; void *data; void *undo_data; @@ -157,7 +158,7 @@ static void autosave_thread(void *data) if (differ) { /* Should probably deal with this more elegantly. */ - RFILE *file = filestream_open(save->path, + intfstream_t *file = intfstream_open_file(save->path, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (file) @@ -174,9 +175,9 @@ static void autosave_thread(void *data) else RARCH_LOG("SRAM changed ... autosaving ...\n"); - failed |= ((size_t)filestream_write(file, save->buffer, save->bufsize) != save->bufsize); - failed |= (filestream_flush(file) != 0); - failed |= (filestream_close(file) != 0); + failed |= ((size_t)intfstream_write(file, save->buffer, save->bufsize) != save->bufsize); + failed |= (intfstream_flush(file) != 0); + failed |= (intfstream_close(file) != 0); if (failed) RARCH_WARN("Failed to autosave SRAM. Disk might be full.\n"); } @@ -530,7 +531,7 @@ static void task_save_handler_finished(retro_task_t *task, task_set_finished(task, true); - filestream_close(state->file); + intfstream_close(state->file); if (!task_get_error(task) && task_get_cancelled(task)) task_set_error(task, strdup("Task canceled")); @@ -565,7 +566,7 @@ static void task_save_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, RETRO_VFS_FILE_ACCESS_WRITE, + state->file = intfstream_open_file(state->path, RETRO_VFS_FILE_ACCESS_WRITE, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!state->file) @@ -573,7 +574,7 @@ static void task_save_handler(retro_task_t *task) } remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK); - written = (int)filestream_write(state->file, + written = (int)intfstream_write(state->file, (uint8_t*)state->data + state->written, remaining); state->written += written; @@ -712,7 +713,7 @@ static void task_load_handler_finished(retro_task_t *task, task_set_finished(task, true); if (state->file) - filestream_close(state->file); + intfstream_close(state->file); if (!task_get_error(task) && task_get_cancelled(task)) task_set_error(task, strdup("Task canceled")); @@ -738,22 +739,22 @@ static void task_load_handler(retro_task_t *task) if (!state->file) { - state->file = filestream_open(state->path, + state->file = intfstream_open_file(state->path, RETRO_VFS_FILE_ACCESS_READ, RETRO_VFS_FILE_ACCESS_HINT_NONE); if (!state->file) goto error; - if (filestream_seek(state->file, 0, SEEK_END) != 0) + if (intfstream_seek(state->file, 0, SEEK_END) != 0) goto error; - state->size = filestream_tell(state->file); + state->size = intfstream_tell(state->file); if (state->size < 0) goto error; - filestream_rewind(state->file); + intfstream_rewind(state->file); state->data = malloc(state->size + 1); @@ -762,7 +763,7 @@ static void task_load_handler(retro_task_t *task) } remaining = MIN(state->size - state->bytes_read, SAVE_STATE_CHUNK); - bytes_read = filestream_read(state->file, + bytes_read = intfstream_read(state->file, (uint8_t*)state->data + state->bytes_read, remaining); state->bytes_read += bytes_read; From 5b8f8b50e3a9335fa9ee710dd42f369f81b526ae Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 17:36:20 +0100 Subject: [PATCH 187/698] Reimplement filestream_eof --- libretro-common/streams/file_stream.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index d6bfc020da..bb60a9b9f7 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -366,26 +366,12 @@ error: int filestream_eof(RFILE *stream) { - return feof(stream->fp); - - /* TODO: FIXME: I can't figure out why this breaks on Windows. - The while loop in config_file_new_internal just never exits. - The current position seems to jump backwards a few lines, - but it doesn't start until somewhere in the middle of the file. - */ - /* - size_t current_position = filestream_tell(stream); - size_t end_position; - - filestream_seek(stream, 0, SEEK_END); - end_position = filestream_tell(stream); - - filestream_seek(stream, current_position, SEEK_SET); + int64_t current_position = filestream_tell(stream); + int64_t end_position = filestream_get_size(stream); if (current_position >= end_position) return 1; return 0; - */ } ssize_t filestream_tell(RFILE *stream) From 43c9bb374d96743f7ece5cfbebdd027fac5bf07d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 17:39:56 +0100 Subject: [PATCH 188/698] filestream_set_size can be made a static function --- libretro-common/include/streams/file_stream.h | 2 -- libretro-common/streams/file_stream.c | 5 +---- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 543de8621a..ebcfa056d6 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -45,8 +45,6 @@ typedef struct RFILE RFILE; int64_t filestream_get_size(RFILE *stream); -void filestream_set_size(RFILE *stream); - const char *filestream_get_ext(RFILE *stream); /** diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index bb60a9b9f7..8c654d6351 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -125,11 +125,8 @@ int64_t filestream_get_size(RFILE *stream) return stream->size; } -void filestream_set_size(RFILE *stream) +static void filestream_set_size(RFILE *stream) { - if (!stream) - return; - filestream_seek(stream, 0, SEEK_SET); filestream_seek(stream, 0, SEEK_END); From ad70bb9866dd009a5fa74902692e67458d03469f Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 17:42:00 +0100 Subject: [PATCH 189/698] Get rid of unused filestream_get_ext --- libretro-common/include/streams/file_stream.h | 2 -- libretro-common/streams/file_stream.c | 17 ----------------- 2 files changed, 19 deletions(-) diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index ebcfa056d6..2ee44ec096 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -45,8 +45,6 @@ typedef struct RFILE RFILE; int64_t filestream_get_size(RFILE *stream); -const char *filestream_get_ext(RFILE *stream); - /** * filestream_open: * @path : path to file diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 8c654d6351..36b9f94b3a 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -86,7 +86,6 @@ struct RFILE { unsigned hints; - char *ext; int64_t size; FILE *fp; @@ -111,13 +110,6 @@ struct RFILE char *buf; }; -const char *filestream_get_ext(RFILE *stream) -{ - if (!stream) - return NULL; - return stream->ext; -} - int64_t filestream_get_size(RFILE *stream) { if (!stream) @@ -278,12 +270,6 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) #endif } - { - const char *ld = (const char*)strrchr(path, '.'); - if (ld) - stream->ext = strdup(ld + 1); - } - filestream_set_size(stream); return stream; @@ -493,9 +479,6 @@ int filestream_close(RFILE *stream) if (!stream) goto error; - if (!string_is_empty(stream->ext)) - free(stream->ext); - if ((stream->hints & RFILE_HINT_UNBUFFERED) == 0) { if (stream->fp) From 5960cd80d2073d499c8390fe73a236c898f39cdc Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 17:59:18 +0100 Subject: [PATCH 190/698] Simplify filestream_read_file --- libretro-common/streams/file_stream.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 36b9f94b3a..224fea7a5a 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -517,7 +517,7 @@ error: int filestream_read_file(const char *path, void **buf, ssize_t *len) { ssize_t ret = 0; - ssize_t content_buf_size = 0; + int64_t content_buf_size = 0; void *content_buf = NULL; RFILE *file = filestream_open(path, RETRO_VFS_FILE_ACCESS_READ, @@ -529,15 +529,11 @@ int filestream_read_file(const char *path, void **buf, ssize_t *len) goto error; } - if (filestream_seek(file, 0, SEEK_END) != 0) - goto error; + content_buf_size = filestream_get_size(file); - content_buf_size = filestream_tell(file); if (content_buf_size < 0) goto error; - filestream_rewind(file); - content_buf = malloc(content_buf_size + 1); if (!content_buf) From a1ce8b58c4096103d2693313017164772930499e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 18:01:56 +0100 Subject: [PATCH 191/698] Simply formats/xml/rxml.c --- libretro-common/formats/xml/rxml.c | 5 +---- libretro-common/streams/file_stream.c | 1 + 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libretro-common/formats/xml/rxml.c b/libretro-common/formats/xml/rxml.c index 59e3e5a793..0f0b072a70 100644 --- a/libretro-common/formats/xml/rxml.c +++ b/libretro-common/formats/xml/rxml.c @@ -429,10 +429,7 @@ rxml_document_t *rxml_load_document(const char *path) if (!doc) goto error; - filestream_seek(file, 0, SEEK_END); - len = filestream_tell(file); - filestream_rewind(file); - + len = filestream_get_size(file); memory_buffer = (char*)malloc(len + 1); if (!memory_buffer) goto error; diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 224fea7a5a..c34fcae506 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -249,6 +249,7 @@ RFILE *filestream_open(const char *path, unsigned mode, unsigned hints) if (stream->fd == -1) goto error; + #ifdef HAVE_MMAP if (stream->hints & RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP) { From 784bb32c64d2249d8cc0cb53c99c3661606b2a47 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 19:55:42 +0100 Subject: [PATCH 192/698] Cleanups --- libretro-common/streams/file_stream.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index c34fcae506..59bc1f90d4 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -131,7 +131,7 @@ static void filestream_set_size(RFILE *stream) * filestream_open: * @path : path to file * @mode : file mode to use when opening (read/write) - * @bufsize : optional buffer size (-1 or 0 to use default) + * @hints : * * Opens a file for reading or writing, depending on the requested mode. * Returns a pointer to an RFILE if opened successfully, otherwise NULL. @@ -289,8 +289,6 @@ char *filestream_gets(RFILE *stream, char *s, size_t len) int filestream_getc(RFILE *stream) { - char c = 0; - (void)c; if (!stream) return 0; return fgetc(stream->fp); From c4d8a8c8008bad786fb072da36643ffb278c79d8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 20:24:00 +0100 Subject: [PATCH 193/698] Free after intfstream_close --- cheevos/cheevos.c | 2 ++ gfx/drivers/gx_gfx.c | 1 + gfx/video_shader_parse.c | 1 + movie.c | 1 + playlist.c | 1 + tasks/task_database.c | 2 +- tasks/task_database_cue.c | 1 + tasks/task_save.c | 5 +++++ 8 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index dae27cbb5c..5d1c7515ac 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -2661,6 +2661,7 @@ static int cheevos_iterate(coro_t* coro) if (!CHEEVOS_VAR_DATA) { intfstream_close(CHEEVOS_VAR_STREAM); + free(CHEEVOS_VAR_STREAM); CORO_STOP(); } @@ -2687,6 +2688,7 @@ static int cheevos_iterate(coro_t* coro) } intfstream_close(CHEEVOS_VAR_STREAM); + free(CHEEVOS_VAR_STREAM); } /* Use the supported extensions as a hint diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index e826b143dd..14b7f61c38 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -746,6 +746,7 @@ static void gx_efb_screenshot(void) } intfstream_close(out); + free(out); } #endif diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index c25d309124..b7a36c7af4 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -586,6 +586,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, free(line); intfstream_close(file); + free(file); } if (conf && !video_shader_resolve_current_parameters(conf, shader)) diff --git a/movie.c b/movie.c index 1e8f99402a..131062d42c 100644 --- a/movie.c +++ b/movie.c @@ -217,6 +217,7 @@ static void bsv_movie_free(bsv_movie_t *handle) return; intfstream_close(handle->file); + free(handle->file); free(handle->state); free(handle->frame_pos); diff --git a/playlist.c b/playlist.c index 87b7632d9d..ae48833cba 100644 --- a/playlist.c +++ b/playlist.c @@ -550,6 +550,7 @@ static bool playlist_read_file( end: intfstream_close(file); + free(file); return true; } diff --git a/tasks/task_database.c b/tasks/task_database.c index f274fc554b..8c8a26e57d 100644 --- a/tasks/task_database.c +++ b/tasks/task_database.c @@ -250,8 +250,8 @@ static bool intfstream_file_get_serial(const char *name, rv = intfstream_get_serial(fd, serial); intfstream_close(fd); - free(data); free(fd); + free(data); return rv; error: diff --git a/tasks/task_database_cue.c b/tasks/task_database_cue.c index cb8e366c74..ef43985101 100644 --- a/tasks/task_database_cue.c +++ b/tasks/task_database_cue.c @@ -419,6 +419,7 @@ static ssize_t intfstream_get_file_size(const char *path) return -1; rv = intfstream_get_size(fd); intfstream_close(fd); + free(fd); return rv; } diff --git a/tasks/task_save.c b/tasks/task_save.c index eab39754b1..ed081d89ef 100644 --- a/tasks/task_save.c +++ b/tasks/task_save.c @@ -178,6 +178,7 @@ static void autosave_thread(void *data) failed |= ((size_t)intfstream_write(file, save->buffer, save->bufsize) != save->bufsize); failed |= (intfstream_flush(file) != 0); failed |= (intfstream_close(file) != 0); + free(file); if (failed) RARCH_WARN("Failed to autosave SRAM. Disk might be full.\n"); } @@ -532,6 +533,7 @@ static void task_save_handler_finished(retro_task_t *task, task_set_finished(task, true); intfstream_close(state->file); + free(state->file); if (!task_get_error(task) && task_get_cancelled(task)) task_set_error(task, strdup("Task canceled")); @@ -713,7 +715,10 @@ static void task_load_handler_finished(retro_task_t *task, task_set_finished(task, true); if (state->file) + { intfstream_close(state->file); + free(state->file); + } if (!task_get_error(task) && task_get_cancelled(task)) task_set_error(task, strdup("Task canceled")); From 2a5bda2b14b843f5eba5178272aeb0c17bfad2ce Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 20:40:59 +0100 Subject: [PATCH 194/698] C89_BUILD fix --- audio/drivers/wasapi.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/audio/drivers/wasapi.c b/audio/drivers/wasapi.c index 973be6411c..e11d8056e0 100644 --- a/audio/drivers/wasapi.c +++ b/audio/drivers/wasapi.c @@ -336,8 +336,9 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device, if (hr == AUDCLNT_E_ALREADY_INITIALIZED) { + HRESULT hr; WASAPI_RELEASE(client); - HRESULT hr = _IMMDevice_Activate(device, + hr = _IMMDevice_Activate(device, IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); From c03b791b46073c63cdca912cf98cf4b82046bea8 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 20:51:46 +0100 Subject: [PATCH 195/698] Start adding stub VFS implementation --- Makefile.common | 1 + griffin/griffin.c | 1 + .../include/vfs/vfs_implementation.h | 63 ++++++++++ libretro-common/vfs/vfs_implementation.c | 117 ++++++++++++++++++ 4 files changed, 182 insertions(+) create mode 100644 libretro-common/include/vfs/vfs_implementation.h create mode 100644 libretro-common/vfs/vfs_implementation.c diff --git a/Makefile.common b/Makefile.common index 07bf65126d..5192894c41 100644 --- a/Makefile.common +++ b/Makefile.common @@ -183,6 +183,7 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/streams/file_stream_transforms.o \ $(LIBRETRO_COMM_DIR)/streams/interface_stream.o \ $(LIBRETRO_COMM_DIR)/streams/memory_stream.o \ + $(LIBRETRO_COMM_DIR)/vfs/vfs_implementation.o \ $(LIBRETRO_COMM_DIR)/lists/string_list.o \ $(LIBRETRO_COMM_DIR)/string/stdstring.o \ $(LIBRETRO_COMM_DIR)/memmap/memalign.o \ diff --git a/griffin/griffin.c b/griffin/griffin.c index 8ac7762892..9d866cb00e 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -820,6 +820,7 @@ FILE #include "../libretro-common/streams/file_stream_transforms.c" #include "../libretro-common/streams/interface_stream.c" #include "../libretro-common/streams/memory_stream.c" +#include "../libretro-common/vfs/vfs_implementation.c" #include "../list_special.c" #include "../libretro-common/string/stdstring.c" #include "../libretro-common/file/nbio/nbio_stdio.c" diff --git a/libretro-common/include/vfs/vfs_implementation.h b/libretro-common/include/vfs/vfs_implementation.h new file mode 100644 index 0000000000..852907b5d2 --- /dev/null +++ b/libretro-common/include/vfs/vfs_implementation.h @@ -0,0 +1,63 @@ +/* Copyright (C) 2010-2017 The RetroArch team +* +* --------------------------------------------------------------------------------------- +* The following license statement only applies to this file (vfs_implementation.h). +* --------------------------------------------------------------------------------------- +* +* Permission is hereby granted, free of charge, +* to any person obtaining a copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef __LIBRETRO_SDK_VFS_IMPLEMENTATION_H +#define __LIBRETRO_SDK_VFS_IMPLEMENTATION_H + +#include +#include + +/* Replace the following symbol with something appropriate + * to signify the file is being compiled for a front end instead of a core. + * This allows the same code to act as reference implementation + * for VFS and as fallbacks for when the front end does not provide VFS functionality. + */ + +#ifdef VFS_FRONTEND +typedef struct retro_vfs_file_handle libretro_vfs_implementation_file; +#else +typedef struct libretro_vfs_implementation_file libretro_vfs_implementation_file; +#endif + +libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uint64_t flags); + +int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream); + +int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream); + +int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream); + +int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream); + +int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset); + +int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len); + +int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, const void *s, uint64_t len); + +int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream); + +int retro_vfs_file_delete_impl(const char *path); + +const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream); + +#endif diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c new file mode 100644 index 0000000000..d705e8be64 --- /dev/null +++ b/libretro-common/vfs/vfs_implementation.c @@ -0,0 +1,117 @@ +/* Copyright (C) 2010-2017 The RetroArch team +* +* --------------------------------------------------------------------------------------- +* The following license statement only applies to this file (vfs_implementation.c). +* --------------------------------------------------------------------------------------- +* +* Permission is hereby granted, free of charge, +* to any person obtaining a copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation the rights to +* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, +* and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include + +enum libretro_file_hints +{ + RFILE_HINT_MMAP = 1 << 8, + RFILE_HINT_UNBUFFERED = 1 << 9 +}; + +#ifdef VFS_FRONTEND +struct retro_vfs_file_handle +#else +struct libretro_vfs_implementation_file +#endif +{ + void *empty; +}; + +int64_t retro_vfs_file_seek_internal(libretro_vfs_implementation_file *stream, int64_t offset, int whence) +{ + return -1; +} + +libretro_vfs_implementation_file *retro_vfs_file_open_impl(const char *path, uint64_t mode) +{ + libretro_vfs_implementation_file *stream = (libretro_vfs_implementation_file*)calloc(1, sizeof(*stream)); + + if (!stream) + return NULL; + + return stream; +} + +int retro_vfs_file_close_impl(libretro_vfs_implementation_file *stream) +{ + return -1; +} + +int retro_vfs_file_error_impl(libretro_vfs_implementation_file *stream) +{ + return 0; +} + +int64_t retro_vfs_file_size_impl(libretro_vfs_implementation_file *stream) +{ + return -1; +} + +int64_t retro_vfs_file_tell_impl(libretro_vfs_implementation_file *stream) +{ + return -1; +} + +int64_t retro_vfs_file_seek_impl(libretro_vfs_implementation_file *stream, int64_t offset) +{ + return retro_vfs_file_seek_internal(stream, offset, SEEK_SET); +} + +int64_t retro_vfs_file_read_impl(libretro_vfs_implementation_file *stream, void *s, uint64_t len) +{ + return -1; +} + +int64_t retro_vfs_file_write_impl(libretro_vfs_implementation_file *stream, const void *s, uint64_t len) +{ + return -1; +} + +int retro_vfs_file_flush_impl(libretro_vfs_implementation_file *stream) +{ + return 0; +} + +int retro_vfs_file_delete_impl(const char *path) +{ + return 0; +} + +const char *retro_vfs_file_get_path_impl(libretro_vfs_implementation_file *stream) +{ + return NULL; +} + From 57b730ab611406c989f507205c2f59688ce14c0d Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 21:24:14 +0100 Subject: [PATCH 196/698] Start implementing VFS layer ; first split up VFS libretro functionality to separate header until things are finalized --- gfx/video_shader_parse.c | 2 +- libretro-common/include/libretro.h | 11 -- libretro-common/include/libretro_vfs.h | 129 ++++++++++++++++++ libretro-common/include/streams/file_stream.h | 2 +- libretro-common/streams/file_stream.c | 48 +++++++ libretro-common/vfs/vfs_implementation.c | 6 - movie.c | 1 + 7 files changed, 180 insertions(+), 19 deletions(-) create mode 100644 libretro-common/include/libretro_vfs.h diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index b7a36c7af4..e8f18968a7 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -17,7 +17,7 @@ #include #include -#include +#include #include #include #include diff --git a/libretro-common/include/libretro.h b/libretro-common/include/libretro.h index 6a0929b302..0525d1a0eb 100644 --- a/libretro-common/include/libretro.h +++ b/libretro-common/include/libretro.h @@ -1044,17 +1044,6 @@ struct retro_hw_render_context_negotiation_interface * recognize or support. Should be set in either retro_init or retro_load_game, but not both. */ -/* File open flags - * Introduced in VFS API v1 */ -#define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */ -#define RETRO_VFS_FILE_ACCESS_WRITE (1 << 1) /* Write only mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified */ -#define RETRO_VFS_FILE_ACCESS_READ_WRITE (RETRO_VFS_FILE_ACCESS_READ | RETRO_VFS_FILE_ACCESS_WRITE) /* Read-write mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified*/ -#define RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING (1 << 2) /* Prevents discarding content of existing files opened for writing */ - -#define RETRO_VFS_FILE_ACCESS_HINT_NONE (0) -/* Indicate that we would want to map the file into memory if possible. Requires RETRO_VFS_FILE_ACCESS_READ. This is only a hint and it is up to the frontend to honor and implement it. */ -#define RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP (1 << 0) - #define RETRO_MEMDESC_CONST (1 << 0) /* The frontend will never change this memory area once retro_load_game has returned. */ #define RETRO_MEMDESC_BIGENDIAN (1 << 1) /* The memory area contains big endian data. Default is little endian. */ #define RETRO_MEMDESC_ALIGN_2 (1 << 16) /* All memory access in this area is aligned to their own size, or 2, whichever is smaller. */ diff --git a/libretro-common/include/libretro_vfs.h b/libretro-common/include/libretro_vfs.h new file mode 100644 index 0000000000..c0a40afe01 --- /dev/null +++ b/libretro-common/include/libretro_vfs.h @@ -0,0 +1,129 @@ +/* Copyright (C) 2010-2017 The RetroArch team + * + * --------------------------------------------------------------------------------------- + * The following license statement only applies to this libretro API header (libretro_vfs.h). + * --------------------------------------------------------------------------------------- + * + * Permission is hereby granted, free of charge, + * to any person obtaining a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LIBRETRO_VFS_H__ +#define LIBRETRO_VFS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/* Opaque file handle + * Introduced in VFS API v1 */ +struct retro_vfs_file_handle; + +/* File open flags + * Introduced in VFS API v1 */ +#define RETRO_VFS_FILE_ACCESS_READ (1 << 0) /* Read only mode */ +#define RETRO_VFS_FILE_ACCESS_WRITE (1 << 1) /* Write only mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified */ +#define RETRO_VFS_FILE_ACCESS_READ_WRITE (RETRO_VFS_FILE_ACCESS_READ | RETRO_VFS_FILE_ACCESS_WRITE) /* Read-write mode, discard contents and overwrites existing file unless RETRO_VFS_FILE_ACCESS_UPDATE is also specified*/ +#define RETRO_VFS_FILE_ACCESS_UPDATE_EXISTING (1 << 2) /* Prevents discarding content of existing files opened for writing */ + +#define RETRO_VFS_FILE_ACCESS_HINT_NONE (0) +/* Indicate that we would want to map the file into memory if possible. Requires RETRO_VFS_FILE_ACCESS_READ. This is only a hint and it is up to the frontend to honor and implement it. */ +#define RETRO_VFS_FILE_ACCESS_HINT_MEMORY_MAP (1 << 0) + + +/* Get path from opaque handle. Returns the exact same path passed to file_open when getting the handle + * Introduced in VFS API v1 */ +typedef const char *(RETRO_CALLCONV *retro_vfs_file_get_path_t)(struct retro_vfs_file_handle *stream); + +/* Open a file for reading or writing. If path points to a directory, this will + * fail. Returns the opaque file handle, or NULL for error. + * Introduced in VFS API v1 */ +typedef struct retro_vfs_file_handle *(RETRO_CALLCONV *retro_vfs_file_open_t)(const char *path, uint64_t flags); + +/* Close the file and release its resources. Must be called if open_file returns non-NULL. Returns 0 on succes, -1 on failure. + * Whether the call succeeds ot not, the handle passed as parameter becomes invalid and should no longer be used. + * Introduced in VFS API v1 */ +typedef int (RETRO_CALLCONV *retro_vfs_file_close_t)(struct retro_vfs_file_handle *stream); + +/* Return the size of the file in bytes, or -1 for error. + * Introduced in VFS API v1 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_file_size_t)(struct retro_vfs_file_handle *stream); + +/* Get the current read / write position for the file. Returns - 1 for error. + * Introduced in VFS API v1 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_file_tell_t)(struct retro_vfs_file_handle *stream); + +/* Set the current read/write position for the file. Returns the new position, -1 for error. + * Introduced in VFS API v1 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_file_seek_t)(struct retro_vfs_file_handle *stream, int64_t offset); + +/* Read data from a file. Returns the number of bytes read, or -1 for error. + * Introduced in VFS API v1 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_file_read_t)(struct retro_vfs_file_handle *stream, void *s, uint64_t len); + +/* Write data to a file. Returns the number of bytes written, or -1 for error. + * Introduced in VFS API v1 */ +typedef int64_t (RETRO_CALLCONV *retro_vfs_file_write_t)(struct retro_vfs_file_handle *stream, const void *s, uint64_t len); + +/* Flush pending writes to file, if using buffered IO. Returns 0 on sucess, or -1 on failure. + * Introduced in VFS API v1 */ +typedef int (RETRO_CALLCONV *retro_vfs_file_flush_t)(struct retro_vfs_file_handle *stream); + +/* Delete the specified file. Returns 0 on success, -1 on failure + * Introduced in VFS API v1 */ +typedef int (RETRO_CALLCONV *retro_vfs_file_delete_t)(const char *path); + +struct retro_vfs_interface +{ + retro_vfs_file_get_path_t file_get_path; + retro_vfs_file_open_t file_open; + retro_vfs_file_close_t file_close; + retro_vfs_file_size_t file_size; + retro_vfs_file_tell_t file_tell; + retro_vfs_file_seek_t file_seek; + retro_vfs_file_read_t file_read; + retro_vfs_file_write_t file_write; + retro_vfs_file_flush_t file_flush; + retro_vfs_file_delete_t file_delete; +}; + +struct retro_vfs_interface_info +{ + /* Set by core: should this be higher than the version the front end supports, + * front end will return false in the RETRO_ENVIRONMENT_GET_VFS_INTERFACE call + * Introduced in VFS API v1 */ + uint32_t required_interface_version; + + /* Frontend writes interface pointer here. The frontend also sets the actual + * version, must be at least required_interface_version. + * Introduced in VFS API v1 */ + struct retro_vfs_interface *iface; +}; + +#define RETRO_ENVIRONMENT_GET_VFS_INTERFACE (45 | RETRO_ENVIRONMENT_EXPERIMENTAL) + /* struct retro_vfs_interface_info * -- + * Gets access to the VFS interface. + * VFS presence needs to be queried prior to load_game or any + * get_system/save/other_directory being called to let front end know + * core supports VFS before it starts handing out paths. + * It is recomended to do so in retro_set_environment */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libretro-common/include/streams/file_stream.h b/libretro-common/include/streams/file_stream.h index 2ee44ec096..41b7ed6c59 100644 --- a/libretro-common/include/streams/file_stream.h +++ b/libretro-common/include/streams/file_stream.h @@ -30,7 +30,7 @@ #include -#include +#include #include #include #include diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 59bc1f90d4..c7d062a9ed 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -78,11 +78,23 @@ #include #include +#include #include #include #include #include +retro_vfs_file_get_path_t filestream_get_path_cb = NULL; +retro_vfs_file_open_t filestream_open_cb = NULL; +retro_vfs_file_close_t filestream_close_cb = NULL; +retro_vfs_file_size_t filestream_size_cb = NULL; +retro_vfs_file_tell_t filestream_tell_cb = NULL; +retro_vfs_file_seek_t filestream_seek_cb = NULL; +retro_vfs_file_read_t filestream_read_cb = NULL; +retro_vfs_file_write_t filestream_write_cb = NULL; +retro_vfs_file_flush_t filestream_flush_cb = NULL; +retro_vfs_file_delete_t filestream_delete_cb = NULL; + struct RFILE { unsigned hints; @@ -110,6 +122,42 @@ struct RFILE char *buf; }; +/* VFS Initialization */ + +void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info) +{ + const struct retro_vfs_interface* vfs_iface; + + filestream_get_path_cb = NULL; + filestream_open_cb = NULL; + filestream_close_cb = NULL; + filestream_tell_cb = NULL; + filestream_size_cb = NULL; + filestream_seek_cb = NULL; + filestream_read_cb = NULL; + filestream_write_cb = NULL; + filestream_flush_cb = NULL; + filestream_delete_cb = NULL; + + vfs_iface = vfs_info->iface; + + if (vfs_info->required_interface_version < FILESTREAM_REQUIRED_VFS_VERSION || vfs_iface == NULL) + return; + + filestream_get_path_cb = vfs_iface->file_get_path; + filestream_open_cb = vfs_iface->file_open; + filestream_close_cb = vfs_iface->file_close; + filestream_size_cb = vfs_iface->file_size; + filestream_tell_cb = vfs_iface->file_tell; + filestream_seek_cb = vfs_iface->file_seek; + filestream_read_cb = vfs_iface->file_read; + filestream_write_cb = vfs_iface->file_write; + filestream_flush_cb = vfs_iface->file_flush; + filestream_delete_cb = vfs_iface->file_delete; +} + +/* Callback wrappers */ + int64_t filestream_get_size(RFILE *stream) { if (!stream) diff --git a/libretro-common/vfs/vfs_implementation.c b/libretro-common/vfs/vfs_implementation.c index d705e8be64..b0046889b3 100644 --- a/libretro-common/vfs/vfs_implementation.c +++ b/libretro-common/vfs/vfs_implementation.c @@ -35,12 +35,6 @@ #include #include -enum libretro_file_hints -{ - RFILE_HINT_MMAP = 1 << 8, - RFILE_HINT_UNBUFFERED = 1 << 9 -}; - #ifdef VFS_FRONTEND struct retro_vfs_file_handle #else diff --git a/movie.c b/movie.c index 131062d42c..535b8eacef 100644 --- a/movie.c +++ b/movie.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include From dca96ba6ad2d924121534472c193a4d30d5281ef Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 21:49:51 +0100 Subject: [PATCH 197/698] Reimplement filestream_getc --- libretro-common/streams/file_stream.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index c7d062a9ed..7bcc85fade 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -337,9 +337,13 @@ char *filestream_gets(RFILE *stream, char *s, size_t len) int filestream_getc(RFILE *stream) { + char c = 0; + (void)c; if (!stream) return 0; - return fgetc(stream->fp); + if(filestream_read(stream, &c, 1) == 1) + return (int)c; + return EOF; } ssize_t filestream_seek(RFILE *stream, ssize_t offset, int whence) From 779d9a4258c9ce1af5bc4967d4d879650bbf63be Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 11 Dec 2017 21:58:17 +0100 Subject: [PATCH 198/698] Cleanup --- libretro-common/streams/file_stream.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index 7bcc85fade..a605b42a69 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -338,7 +338,6 @@ char *filestream_gets(RFILE *stream, char *s, size_t len) int filestream_getc(RFILE *stream) { char c = 0; - (void)c; if (!stream) return 0; if(filestream_read(stream, &c, 1) == 1) From 9aa3dc2423c5c00866781e9544ca9bfb2285d085 Mon Sep 17 00:00:00 2001 From: Twinaphex Date: Mon, 11 Dec 2017 22:01:54 +0100 Subject: [PATCH 199/698] Buildfix --- libretro-common/streams/file_stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libretro-common/streams/file_stream.c b/libretro-common/streams/file_stream.c index a605b42a69..7fe5b0d555 100644 --- a/libretro-common/streams/file_stream.c +++ b/libretro-common/streams/file_stream.c @@ -78,7 +78,7 @@ #include #include -#include +#include #include #include #include From 940f0c6b0b68c027e3c953802fa91e23102f6b60 Mon Sep 17 00:00:00 2001 From: ggf906 Date: Tue, 12 Dec 2017 00:04:35 +0100 Subject: [PATCH 200/698] (PSP) Strip and user 64MB where available --- Makefile.psp1 | 6 ++++-- Makefile.psp1.salamander | 7 ++++--- bootstrap/psp1/kernel_functions_prx/Makefile | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/Makefile.psp1 b/Makefile.psp1 index a99c89e754..b5e143cf0a 100644 --- a/Makefile.psp1 +++ b/Makefile.psp1 @@ -1,6 +1,8 @@ -BUILD_PRX = 1 +BUILD_PRX = 0 +PSP_LARGE_MEMORY = 1 DEBUG = 0 HAVE_KERNEL_PRX = 1 +HAVE_LOGGER = 0 HAVE_FILE_LOGGER = 0 HAVE_THREADS = 0 BIG_STACK = 0 @@ -11,7 +13,7 @@ TARGET = retroarchpsp ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g else - OPTIMIZE_LV := -O3 -g + OPTIMIZE_LV := -O3 endif ifeq ($(WHOLE_ARCHIVE_LINK), 1) diff --git a/Makefile.psp1.salamander b/Makefile.psp1.salamander index 68e0732582..a59603fa93 100644 --- a/Makefile.psp1.salamander +++ b/Makefile.psp1.salamander @@ -1,4 +1,5 @@ -BUILD_PRX = 1 +BUILD_PRX = 0 +PSP_LARGE_MEMORY = 1 HAVE_FILE_LOGGER = 0 DEBUG = 0 @@ -7,7 +8,7 @@ TARGET = retroarchpsp_salamander ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g else - OPTIMIZE_LV := -O2 -g + OPTIMIZE_LV := -O2 endif INCDIR = $(PSPPATH)/include libretro-common/include @@ -24,7 +25,7 @@ ifeq ($(HAVE_FILE_LOGGER), 1) CFLAGS += -DHAVE_FILE_LOGGER endif -CFLAGS += $(RARCH_DEFINES) +CFLAGS += $(RARCH_DEFINES) EXTRA_TARGETS = EBOOT.PBP PSP_EBOOT_TITLE = RetroArch diff --git a/bootstrap/psp1/kernel_functions_prx/Makefile b/bootstrap/psp1/kernel_functions_prx/Makefile index 0b6cdc3d41..810ade49ca 100644 --- a/bootstrap/psp1/kernel_functions_prx/Makefile +++ b/bootstrap/psp1/kernel_functions_prx/Makefile @@ -14,7 +14,7 @@ USE_KERNEL_LIBC=1 USE_KERNEL_LIBS=1 LIBDIR = -LDFLAGS = -mno-crt0 -nostartfiles +LDFLAGS = -nostartfiles LIBS = -lpspdebug -lpspge -lpspsdk -lc -lpspuser PSPSDK=$(shell psp-config --pspsdk-path) include $(PSPSDK)/lib/build.mak From 247b9ea97334857e35325d5f8be8fa7ee4c2cb5f Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 11 Dec 2017 18:12:32 -0500 Subject: [PATCH 201/698] add menu setting for window opacity, includes generic display server interface --- Makefile.common | 3 ++ config.def.h | 5 +++ configuration.c | 1 + configuration.h | 1 + gfx/common/win32_common.c | 10 +++++ gfx/display_servers/dispserv_null.c | 43 ++++++++++++++++++++ gfx/display_servers/dispserv_win32.c | 60 ++++++++++++++++++++++++++++ gfx/video_display_server.c | 55 +++++++++++++++++++++++++ gfx/video_display_server.h | 43 ++++++++++++++++++++ gfx/video_driver.c | 4 ++ griffin/griffin.c | 5 ++- intl/msg_hash_ja.h | 2 + intl/msg_hash_lbl.h | 2 + intl/msg_hash_us.h | 2 + menu/menu_displaylist.c | 3 ++ menu/menu_setting.c | 17 ++++++++ msg_hash.h | 1 + 17 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 gfx/display_servers/dispserv_null.c create mode 100644 gfx/display_servers/dispserv_win32.c create mode 100644 gfx/video_display_server.c create mode 100644 gfx/video_display_server.h diff --git a/Makefile.common b/Makefile.common index 5192894c41..3c4e25dcc0 100644 --- a/Makefile.common +++ b/Makefile.common @@ -202,6 +202,7 @@ OBJ += frontend/frontend.o \ $(LIBRETRO_COMM_DIR)/audio/audio_mixer.o \ input/input_driver.o \ gfx/video_coord_array.o \ + gfx/video_display_server.o \ gfx/video_driver.o \ camera/camera_driver.o \ wifi/wifi_driver.o \ @@ -248,6 +249,7 @@ OBJ += frontend/frontend.o \ camera/drivers/nullcamera.o \ wifi/drivers/nullwifi.o \ gfx/drivers/nullgfx.o \ + gfx/display_servers/dispserv_null.o \ audio/drivers/nullaudio.o \ input/drivers/nullinput.o \ input/drivers_hid/null_hid.o \ @@ -1551,6 +1553,7 @@ ifneq ($(findstring Win32,$(OS)),) OBJ += gfx/drivers/gdi_gfx.o \ gfx/drivers_context/gdi_ctx.o \ gfx/drivers_font/gdi_font.o \ + gfx/display_servers/dispserv_win32.o \ menu/drivers_display/menu_display_gdi.o LIBS += -lmsimg32 -lhid -lsetupapi diff --git a/config.def.h b/config.def.h index 4145be9d77..50036db322 100644 --- a/config.def.h +++ b/config.def.h @@ -115,6 +115,11 @@ static const unsigned window_y = 0; static const unsigned fullscreen_x = 0; static const unsigned fullscreen_y = 0; +/* Amount of transparency to use for the main window. + * 1 is the most transparent while 100 is opaque. + */ +static const unsigned window_opacity = 100; + #if defined(RARCH_CONSOLE) || defined(__APPLE__) static const bool load_dummy_on_core_shutdown = false; #else diff --git a/configuration.c b/configuration.c index bcb7b0c578..bec0b42878 100644 --- a/configuration.c +++ b/configuration.c @@ -1378,6 +1378,7 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings, SETTING_UINT("video_fullscreen_y", &settings->uints.video_fullscreen_y, true, fullscreen_y, false); SETTING_UINT("video_window_x", &settings->uints.video_window_x, true, fullscreen_x, false); SETTING_UINT("video_window_y", &settings->uints.video_window_y, true, fullscreen_y, false); + SETTING_UINT("video_window_opacity", &settings->uints.video_window_opacity, true, window_opacity, false); #ifdef HAVE_COMMAND SETTING_UINT("network_cmd_port", &settings->uints.network_cmd_port, true, network_cmd_port, false); #endif diff --git a/configuration.h b/configuration.h index c81a53f962..c94b215209 100644 --- a/configuration.h +++ b/configuration.h @@ -325,6 +325,7 @@ typedef struct settings unsigned keymapper_port; unsigned video_window_x; unsigned video_window_y; + unsigned video_window_opacity; unsigned video_monitor_index; unsigned video_fullscreen_x; unsigned video_fullscreen_y; diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index a8a696cbb2..426632bbd0 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -45,6 +45,7 @@ #include "../../input/input_driver.h" #include "../../input/input_keymaps.h" #include "../video_thread_wrapper.h" +#include "../video_display_server.h" #include #ifdef HAVE_MENU @@ -742,6 +743,7 @@ bool win32_window_create(void *data, unsigned style, RECT *mon_rect, unsigned width, unsigned height, bool fullscreen) { + settings_t *settings = config_get_ptr(); #ifndef _XBOX main_window.hwnd = CreateWindowEx(0, "RetroArch", "RetroArch", @@ -756,6 +758,14 @@ bool win32_window_create(void *data, unsigned style, video_driver_display_type_set(RARCH_DISPLAY_WIN32); video_driver_display_set(0); video_driver_window_set((uintptr_t)main_window.hwnd); + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Windows 2000 and above use layered windows to enable transparency */ + SetWindowLongPtr(main_window.hwnd, + GWL_EXSTYLE, + GetWindowLongPtr(main_window.hwnd, GWL_EXSTYLE) | WS_EX_LAYERED); + SetLayeredWindowAttributes(main_window.hwnd, 0, (255 * settings->uints.video_window_opacity) / 100, LWA_ALPHA); +#endif #endif return true; } diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c new file mode 100644 index 0000000000..c40ef5bfc1 --- /dev/null +++ b/gfx/display_servers/dispserv_null.c @@ -0,0 +1,43 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 "../video_display_server.h" + +static void* null_display_server_init() +{ + return NULL; +} + +static void null_display_server_destroy() +{ + +} + +static bool null_set_window_opacity(void *data, unsigned opacity) +{ + (void)data; + (void)opacity; + return true; +} + +const video_display_server_t dispserv_null = { + null_display_server_init, + null_display_server_destroy, + null_set_window_opacity, + "null" +}; + diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c new file mode 100644 index 0000000000..fb66660640 --- /dev/null +++ b/gfx/display_servers/dispserv_win32.c @@ -0,0 +1,60 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 "../video_display_server.h" +#include "../common/win32_common.h" + +typedef struct +{ + unsigned opacity; +} dispserv_win32_t; + +static void* win32_display_server_init() +{ + dispserv_win32_t *dispserv = calloc(1, sizeof(*dispserv)); + + return dispserv; +} + +static void win32_display_server_destroy() +{ + +} + +static bool win32_set_window_opacity(void *data, unsigned opacity) +{ + HWND hwnd = win32_get_window(); + dispserv_win32_t *serv = (dispserv_win32_t*)data; + + serv->opacity = opacity; + +#if defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0500 + /* Set window transparency on Windows 2000 and above */ + return SetLayeredWindowAttributes(hwnd, 0, opacity, LWA_ALPHA); +#else + return false; +#endif +} + +const video_display_server_t dispserv_win32 = { + win32_display_server_init, + win32_display_server_destroy, + win32_set_window_opacity, + "win32" +}; + diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c new file mode 100644 index 0000000000..67793d962f --- /dev/null +++ b/gfx/video_display_server.c @@ -0,0 +1,55 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 "video_display_server.h" +#include "video_driver.h" +#include "../verbosity.h" + +static const video_display_server_t *current_display_server = NULL; +static void *current_display_server_data = NULL; + +void* video_display_server_init() +{ + enum rarch_display_type type = video_driver_display_type_get(); + + switch (type) + { + case RARCH_DISPLAY_WIN32: + current_display_server = &dispserv_win32; + break; + default: + current_display_server = &dispserv_null; + break; + } + + current_display_server_data = current_display_server->init(); + + RARCH_LOG("[Video]: Found display server: %s\n", current_display_server->ident); + + return current_display_server_data; +} + +void video_display_server_destroy() +{ + +} + +bool video_display_server_set_window_opacity(unsigned opacity) +{ + return current_display_server->set_window_opacity(current_display_server_data, opacity); +} diff --git a/gfx/video_display_server.h b/gfx/video_display_server.h new file mode 100644 index 0000000000..1b16c75b97 --- /dev/null +++ b/gfx/video_display_server.h @@ -0,0 +1,43 @@ +/* RetroArch - A frontend for libretro. + * Copyright (C) 2010-2014 - Hans-Kristian Arntzen + * Copyright (C) 2011-2017 - Daniel De Matteis + * Copyright (C) 2016-2017 - Brad Parker + * + * 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 __VIDEO_DISPLAY_SERVER__H +#define __VIDEO_DISPLAY_SERVER__H + +#include +#include + +RETRO_BEGIN_DECLS + +typedef struct video_display_server +{ + void *(*init)(void); + void (*destroy)(void); + bool (*set_window_opacity)(void *data, unsigned opacity); + const char *ident; +} video_display_server_t; + +void* video_display_server_init(void); +void video_display_server_destroy(void); +bool video_display_server_set_window_opacity(unsigned opacity); + +extern const video_display_server_t dispserv_win32; +extern const video_display_server_t dispserv_null; + +RETRO_END_DECLS + +#endif diff --git a/gfx/video_driver.c b/gfx/video_driver.c index c4174e6726..b07d869967 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -48,6 +48,7 @@ #include "video_thread_wrapper.h" #include "video_driver.h" +#include "video_display_server.h" #include "../frontend/frontend_driver.h" #include "../record/record_driver.h" @@ -1089,6 +1090,8 @@ static bool video_driver_init_internal(bool *video_is_threaded) video_context_driver_reset(); + video_display_server_init(); + return true; error: @@ -1550,6 +1553,7 @@ static void video_driver_lock_new(void) void video_driver_destroy(void) { + video_display_server_destroy(); video_driver_cb_has_focus = null_driver_has_focus; video_driver_use_rgba = false; video_driver_data_own = false; diff --git a/griffin/griffin.c b/griffin/griffin.c index 9d866cb00e..720965d34d 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -188,9 +188,8 @@ VIDEO CONTEXT #include "../gfx/drivers_context/wgl_ctx.c" #endif -#if defined(_WIN32) && !defined(_XBOX) #include "../gfx/drivers_context/gdi_ctx.c" -#endif +#include "../gfx/display_servers/dispserv_win32.c" #if defined(HAVE_FFMPEG) #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES3) @@ -371,6 +370,7 @@ VIDEO DRIVER #endif #include "../gfx/drivers_renderchain/null_renderchain.c" +#include "../gfx/display_servers/dispserv_null.c" #ifdef HAVE_OPENGL #include "../gfx/common/gl_common.c" @@ -746,6 +746,7 @@ AUDIO DRIVERS ============================================================ */ #include "../gfx/video_driver.c" +#include "../gfx/video_display_server.c" #include "../gfx/video_coord_array.c" #include "../input/input_driver.c" #include "../audio/audio_driver.c" diff --git a/intl/msg_hash_ja.h b/intl/msg_hash_ja.h index ec16dabcc3..ab498da29b 100644 --- a/intl/msg_hash_ja.h +++ b/intl/msg_hash_ja.h @@ -3263,3 +3263,5 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Automatically scans loaded content so they appear inside playlists.") MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, "Scanning of file finished") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "ウィンドウの不透明性") diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index a097ee5c90..bc5721bce0 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1377,3 +1377,5 @@ MSG_HASH(MENU_ENUM_LABEL_FRAMECOUNT_SHOW, "framecount_show") MSG_HASH(MENU_ENUM_LABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "automatically_add_content_to_playlist") +MSG_HASH(MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + "video_window_opacity") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 25a36dda4f..e7ad35b7cc 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -3341,3 +3341,5 @@ MSG_HASH(MENU_ENUM_SUBLABEL_AUTOMATICALLY_ADD_CONTENT_TO_PLAYLIST, "Automatically scans loaded content so they appear inside playlists.") MSG_HASH(MSG_SCANNING_OF_FILE_FINISHED, "Scanning of file finished") +MSG_HASH(MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + "Window Opacity") diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 8a60cf2735..d3167f036a 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -6028,6 +6028,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, void *data) menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_WINDOW_HEIGHT, PARSE_ONLY_UINT, false); + menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + PARSE_ONLY_UINT, false); menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_VIDEO_SCALE_INTEGER, PARSE_ONLY_BOOL, false); diff --git a/menu/menu_setting.c b/menu/menu_setting.c index d55a5c8c81..f9ddce0cc1 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -81,6 +81,7 @@ #include "../setting_list.h" #include "../lakka.h" #include "../retroarch.h" +#include "../gfx/video_display_server.h" #include "../tasks/tasks_internal.h" @@ -1834,6 +1835,9 @@ void general_write_handler(void *data) retroarch_override_setting_set(RARCH_OVERRIDE_SETTING_NETPLAY_CHECK_FRAMES, NULL); #endif break; + case MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY: + video_display_server_set_window_opacity((255 * settings->uints.video_window_opacity) / 100); + break; default: break; } @@ -3628,6 +3632,19 @@ static bool setting_append_list( general_read_handler); menu_settings_list_current_add_range(list, list_info, 0, 4320, 8, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); + CONFIG_UINT( + list, list_info, + &settings->uints.video_window_opacity, + MENU_ENUM_LABEL_VIDEO_WINDOW_OPACITY, + MENU_ENUM_LABEL_VALUE_VIDEO_WINDOW_OPACITY, + window_opacity, + &group_info, + &subgroup_info, + parent_group, + general_write_handler, + general_read_handler); + menu_settings_list_current_add_range(list, list_info, 1, 100, 1, true, true); + settings_data_list_current_add_flags(list, list_info, SD_FLAG_LAKKA_ADVANCED); } CONFIG_BOOL( diff --git a/msg_hash.h b/msg_hash.h index f9e92af1d3..48b55122ee 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -676,6 +676,7 @@ enum msg_hash_enums MENU_LABEL(VIDEO_WINDOWED_FULLSCREEN), MENU_LABEL(VIDEO_WINDOW_WIDTH), MENU_LABEL(VIDEO_WINDOW_HEIGHT), + MENU_LABEL(VIDEO_WINDOW_OPACITY), MENU_LABEL(VIDEO_FULLSCREEN_X), MENU_LABEL(VIDEO_FULLSCREEN_Y), MENU_LABEL(VIDEO_FORCE_SRGB_DISABLE), From 621d89c52eaffec1834c632fd2c19b4c7cfb8990 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Tue, 12 Dec 2017 00:17:17 +0100 Subject: [PATCH 202/698] (PSP1) Change to -O2 --- Makefile.psp1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile.psp1 b/Makefile.psp1 index b5e143cf0a..31f5751f74 100644 --- a/Makefile.psp1 +++ b/Makefile.psp1 @@ -13,7 +13,7 @@ TARGET = retroarchpsp ifeq ($(DEBUG), 1) OPTIMIZE_LV := -O0 -g else - OPTIMIZE_LV := -O3 + OPTIMIZE_LV := -O2 endif ifeq ($(WHOLE_ARCHIVE_LINK), 1) From c265c8328cf3f5f7a1a21958a40cc4772339f6be Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 11 Dec 2017 18:22:40 -0500 Subject: [PATCH 203/698] buildfixes --- gfx/display_servers/dispserv_null.c | 1 + gfx/display_servers/dispserv_win32.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c index c40ef5bfc1..7974726cb4 100644 --- a/gfx/display_servers/dispserv_null.c +++ b/gfx/display_servers/dispserv_null.c @@ -15,6 +15,7 @@ * If not, see . */ +#include #include "../video_display_server.h" static void* null_display_server_init() diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c index fb66660640..53e942eefc 100644 --- a/gfx/display_servers/dispserv_win32.c +++ b/gfx/display_servers/dispserv_win32.c @@ -26,7 +26,7 @@ typedef struct static void* win32_display_server_init() { - dispserv_win32_t *dispserv = calloc(1, sizeof(*dispserv)); + dispserv_win32_t *dispserv = (dispserv_win32_t*)calloc(1, sizeof(*dispserv)); return dispserv; } From b6644e2c3a27ffe8f6b24d3045e64f416ba9228f Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 11 Dec 2017 18:27:11 -0500 Subject: [PATCH 204/698] buildfix again --- gfx/video_display_server.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index 67793d962f..6ae67590a2 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -29,9 +29,11 @@ void* video_display_server_init() switch (type) { +#if defined(_WIN32) && !defined(_XBOX) case RARCH_DISPLAY_WIN32: current_display_server = &dispserv_win32; break; +#endif default: current_display_server = &dispserv_null; break; From d53dbbfd4e593971f2d278adac8bf6bde3609929 Mon Sep 17 00:00:00 2001 From: Brad Parker Date: Mon, 11 Dec 2017 18:50:10 -0500 Subject: [PATCH 205/698] style nits --- gfx/display_servers/dispserv_null.c | 4 ++-- gfx/display_servers/dispserv_win32.c | 4 ++-- gfx/video_display_server.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gfx/display_servers/dispserv_null.c b/gfx/display_servers/dispserv_null.c index 7974726cb4..40697ac0b8 100644 --- a/gfx/display_servers/dispserv_null.c +++ b/gfx/display_servers/dispserv_null.c @@ -18,12 +18,12 @@ #include #include "../video_display_server.h" -static void* null_display_server_init() +static void* null_display_server_init(void) { return NULL; } -static void null_display_server_destroy() +static void null_display_server_destroy(void) { } diff --git a/gfx/display_servers/dispserv_win32.c b/gfx/display_servers/dispserv_win32.c index 53e942eefc..41958aabd8 100644 --- a/gfx/display_servers/dispserv_win32.c +++ b/gfx/display_servers/dispserv_win32.c @@ -24,14 +24,14 @@ typedef struct unsigned opacity; } dispserv_win32_t; -static void* win32_display_server_init() +static void* win32_display_server_init(void) { dispserv_win32_t *dispserv = (dispserv_win32_t*)calloc(1, sizeof(*dispserv)); return dispserv; } -static void win32_display_server_destroy() +static void win32_display_server_destroy(void) { } diff --git a/gfx/video_display_server.c b/gfx/video_display_server.c index 6ae67590a2..22a3b06cd0 100644 --- a/gfx/video_display_server.c +++ b/gfx/video_display_server.c @@ -23,7 +23,7 @@ static const video_display_server_t *current_display_server = NULL; static void *current_display_server_data = NULL; -void* video_display_server_init() +void* video_display_server_init(void) { enum rarch_display_type type = video_driver_display_type_get(); @@ -46,7 +46,7 @@ void* video_display_server_init() return current_display_server_data; } -void video_display_server_destroy() +void video_display_server_destroy(void) { } From 6904101c4430b8cd213453fbfb0480838ccc958e Mon Sep 17 00:00:00 2001 From: gblues Date: Mon, 11 Dec 2017 23:55:31 -0800 Subject: [PATCH 206/698] Clean up trailing whitespace == DETAILS Really simple code cleanup, because my editor flags trailing whitespaces and it's pretty annoying. --- audio/audio_driver.c | 76 +- audio/audio_driver.h | 6 +- audio/audio_thread_wrapper.c | 10 +- audio/audio_thread_wrapper.h | 2 +- audio/drivers/alsa.c | 4 +- audio/drivers/alsa_qsa.c | 10 +- audio/drivers/alsathread.c | 6 +- audio/drivers/coreaudio.c | 20 +- audio/drivers/ctr_csnd_audio.c | 6 +- audio/drivers/dsound.c | 14 +- audio/drivers/gx_audio.c | 6 +- audio/drivers/jack.c | 6 +- audio/drivers/nullaudio.c | 2 +- audio/drivers/openal.c | 2 +- audio/drivers/opensl.c | 4 +- audio/drivers/oss.c | 4 +- audio/drivers/ps3_audio.c | 6 +- audio/drivers/psp_audio.c | 8 +- audio/drivers/pulse.c | 12 +- audio/drivers/roar.c | 2 +- audio/drivers/rsound.c | 2 +- audio/drivers/rsound.h | 72 +- audio/drivers/rwebaudio.c | 2 +- audio/drivers/sdl_audio.c | 6 +- audio/drivers/tinyalsa.c | 10 +- audio/drivers/wasapi.c | 24 +- audio/drivers/xaudio.c | 52 +- audio/drivers/xaudio.h | 44 +- audio/drivers/xenon360_audio.c | 4 +- audio/drivers_resampler/cc_resampler.c | 4 +- audio/librsound.c | 40 +- autosave.h | 2 +- bootstrap/psp1/kernel_functions_prx/main.c | 2 +- bootstrap/vita/threading.c | 10 +- camera/camera_driver.c | 14 +- camera/camera_driver.h | 2 +- camera/drivers/android.c | 8 +- camera/drivers/nullcamera.c | 2 +- camera/drivers/rwebcam.c | 2 +- camera/drivers/video4linux2.c | 2 +- cheevos/badges.c | 110 +- cheevos/badges.h | 58 +- cheevos/cheevos.c | 4 +- cheevos/var.c | 4 +- command.c | 12 +- command.h | 2 +- configuration.h | 2 +- core.h | 8 +- core_info.c | 28 +- core_info.h | 2 +- core_type.h | 4 +- cores/dynamic_dummy.c | 2 +- cores/internal_cores.h | 2 +- cores/libretro-ffmpeg/ffmpeg_core.c | 42 +- cores/libretro-ffmpeg/ffmpeg_fft.c | 14 +- .../gl_shaders/ffmpeg_es.glsl.frag.h | 2 +- .../gl_shaders/fft_heightmap.glsl.vert.h | 2 +- cores/libretro-imageviewer/image_core.c | 8 +- .../video_processor_v4l2.c | 16 +- defaults.h | 4 +- defines/d3d_defines.h | 4 +- defines/gx_defines.h | 2 +- defines/ps3_defines.h | 2 +- deps/7zip/7z.h | 414 +- deps/7zip/7zBuf.c | 74 +- deps/7zip/7zBuf.h | 54 +- deps/7zip/7zCrc.c | 152 +- deps/7zip/7zCrc.h | 58 +- deps/7zip/7zCrcOpt.c | 76 +- deps/7zip/7zDec.c | 720 +-- deps/7zip/7zFile.c | 570 +-- deps/7zip/7zFile.h | 174 +- deps/7zip/7zIn.c | 2742 ++++++------ deps/7zip/7zStream.c | 346 +- deps/7zip/7zVersion.h | 14 +- deps/7zip/Bcj2.c | 298 +- deps/7zip/Bcj2.h | 76 +- deps/7zip/Bra.c | 268 +- deps/7zip/Bra.h | 136 +- deps/7zip/Bra86.c | 172 +- deps/7zip/CpuArch.h | 142 +- deps/7zip/LzFind.c | 58 +- deps/7zip/LzFind.h | 4 +- deps/7zip/Lzma2Dec.c | 694 +-- deps/7zip/Lzma2Dec.h | 170 +- deps/7zip/LzmaDec.c | 2080 ++++----- deps/7zip/LzmaDec.h | 440 +- deps/7zip/LzmaEnc.c | 56 +- deps/SPIRV-Cross/GLSL.std.450.h | 2 +- deps/glslang/glslang/SPIRV/GLSL.std.450.h | 2 +- deps/glslang/glslang/SPIRV/SPVRemapper.h | 10 +- deps/glslang/glslang/SPIRV/SpvBuilder.h | 2 +- deps/glslang/glslang/SPIRV/doc.h | 2 +- deps/glslang/glslang/SPIRV/spvIR.h | 10 +- deps/glslang/glslang/StandAlone/Worklist.h | 10 +- .../glslang/glslang/Include/BaseTypes.h | 4 +- deps/glslang/glslang/glslang/Include/Common.h | 8 +- .../glslang/glslang/Include/ConstantUnion.h | 42 +- .../glslang/glslang/Include/InfoSink.h | 10 +- .../glslang/glslang/Include/PoolAlloc.h | 28 +- .../glslang/glslang/Include/ResourceLimits.h | 2 +- .../glslang/glslang/Include/ShHandle.h | 16 +- deps/glslang/glslang/glslang/Include/Types.h | 4 +- .../glslang/glslang/Include/intermediate.h | 18 +- .../glslang/MachineIndependent/Initialize.h | 4 +- .../glslang/MachineIndependent/ParseHelper.h | 2 +- .../glslang/glslang/MachineIndependent/Scan.h | 2 +- .../glslang/MachineIndependent/SymbolTable.h | 22 +- .../MachineIndependent/glslang_tab.cpp.h | 10 +- .../MachineIndependent/localintermediate.h | 10 +- .../preprocessor/PpContext.h | 18 +- .../preprocessor/PpTokens.h | 4 +- .../glslang/MachineIndependent/reflection.h | 6 +- .../glslang/glslang/Public/ShaderLang.h | 12 +- deps/glslang/glslang/gtests/TestFixture.h | 4 +- deps/glslang/glslang/hlsl/hlslGrammar.h | 2 +- deps/glslang/glslang/hlsl/hlslParseHelper.h | 2 +- deps/glslang/glslang/hlsl/hlslParseables.h | 2 +- deps/glslang/glslang/hlsl/hlslTokens.h | 2 +- deps/ibxm/ibxm.c | 3844 ++++++++--------- deps/libvita2d/source/vita2d_texture.c | 2 +- deps/mbedtls/ecjpake.c | 2 +- deps/mbedtls/mbedtls/ecp_internal.h | 2 +- deps/mbedtls/mbedtls/rsa.h | 8 +- deps/mbedtls/mbedtls/ssl_ciphersuites.h | 2 +- deps/mbedtls/ssl_cli.c | 4 +- deps/mbedtls/ssl_srv.c | 8 +- deps/mbedtls/x509_crt.c | 2 +- deps/stb/stb_image.h | 4 +- deps/stb/stb_rect_pack.h | 6 +- deps/stb/stb_truetype.h | 48 +- deps/stb/stb_vorbis.h | 160 +- dirs.c | 4 +- dirs.h | 2 +- driver.c | 24 +- driver.h | 6 +- dynamic.c | 54 +- dynamic.h | 6 +- file_path_str.c | 2 +- frontend/drivers/platform_ctr.c | 4 +- frontend/drivers/platform_gx.c | 2 +- frontend/drivers/platform_ps3.c | 6 +- frontend/drivers/platform_qnx.c | 2 +- frontend/drivers/platform_unix.c | 18 +- frontend/drivers/platform_unix.h | 4 +- frontend/drivers/platform_wii.c | 8 +- frontend/drivers/platform_win32.c | 36 +- frontend/drivers/platform_xdk.c | 20 +- frontend/frontend.c | 2 +- frontend/frontend.h | 4 +- frontend/frontend_salamander.c | 8 +- gfx/common/d3d_common.c | 14 +- gfx/common/d3d_common.h | 4 +- gfx/common/dbus_common.c | 4 +- gfx/common/dbus_common.h | 2 +- gfx/common/drm_common.c | 2 +- gfx/common/drm_common.h | 2 +- gfx/common/egl_common.c | 4 +- gfx/common/egl_common.h | 2 +- gfx/common/gl_common.c | 2 +- gfx/common/gl_common.h | 2 +- gfx/common/vita2d_common.h | 14 +- gfx/common/vksym.h | 2 +- gfx/common/vulkan_common.c | 60 +- gfx/common/vulkan_common.h | 2 +- gfx/common/wayland_common.h | 2 +- gfx/common/win32_common.c | 6 +- gfx/common/win32_common.h | 2 +- gfx/common/x11_common.c | 12 +- gfx/common/x11_common.h | 2 +- gfx/common/xinerama_common.c | 2 +- gfx/common/xinerama_common.h | 2 +- gfx/drivers/ctr_gfx.c | 4 +- gfx/drivers/d3d.c | 26 +- gfx/drivers/d3d.h | 2 +- gfx/drivers/dispmanx_gfx.c | 146 +- gfx/drivers/drm_gfx.c | 206 +- gfx/drivers/exynos_gfx.c | 8 +- gfx/drivers/gdi_gfx.c | 4 +- gfx/drivers/gl.c | 14 +- .../gl_shaders/pipeline_snowflake.glsl.frag.h | 24 +- .../pipeline_xmb_ribbon_simple.cg.h | 2 +- gfx/drivers/gx_gfx.c | 30 +- gfx/drivers/gx_gfx_vi_encoder.c | 826 ++-- gfx/drivers/nullgfx.c | 2 +- gfx/drivers/omap_gfx.c | 8 +- gfx/drivers/psp1_gfx.c | 34 +- gfx/drivers/psp1_gfx.h | 2 +- gfx/drivers/sdl2_gfx.c | 8 +- gfx/drivers/sdl_gfx.c | 6 +- gfx/drivers/sunxi_gfx.c | 58 +- gfx/drivers/vga_gfx.c | 2 +- gfx/drivers/vita2d_gfx.c | 44 +- gfx/drivers/vulkan.c | 86 +- gfx/drivers/xenon360_gfx.c | 4 +- gfx/drivers/xshm_gfx.c | 54 +- gfx/drivers/xvideo.c | 52 +- gfx/drivers_context/android_ctx.c | 8 +- gfx/drivers_context/cgl_ctx.c | 18 +- gfx/drivers_context/d3d_ctx.c | 4 +- gfx/drivers_context/drm_ctx.c | 36 +- gfx/drivers_context/gdi_ctx.c | 4 +- gfx/drivers_context/gfx_null_ctx.c | 4 +- gfx/drivers_context/khr_display_ctx.c | 4 +- gfx/drivers_context/mali_fbdev_ctx.c | 4 +- gfx/drivers_context/opendingux_fbdev_ctx.c | 4 +- gfx/drivers_context/ps3_ctx.c | 16 +- gfx/drivers_context/sdl_gl_ctx.c | 2 +- gfx/drivers_context/vc_egl_ctx.c | 24 +- gfx/drivers_context/vivante_fbdev_ctx.c | 2 +- gfx/drivers_context/wayland_ctx.c | 10 +- gfx/drivers_context/wgl_ctx.c | 12 +- gfx/drivers_context/x_ctx.c | 26 +- gfx/drivers_context/xegl_ctx.c | 22 +- gfx/drivers_font/caca_font.c | 2 +- gfx/drivers_font/ctr_font.c | 2 +- gfx/drivers_font/d3d_w32_font.c | 2 +- gfx/drivers_font/gdi_font.c | 2 +- gfx/drivers_font/gl_raster_font.c | 4 +- gfx/drivers_font/ps_libdbgfont.c | 4 +- gfx/drivers_font/vga_font.c | 2 +- gfx/drivers_font/vita2d_font.c | 12 +- gfx/drivers_font/vulkan_raster_font.c | 14 +- gfx/drivers_font/xdk1_xfonts.c | 4 +- gfx/drivers_font_renderer/bitmap.h | 2 +- gfx/drivers_font_renderer/bitmapfont.c | 12 +- gfx/drivers_font_renderer/coretext.c | 10 +- gfx/drivers_font_renderer/freetype.c | 4 +- gfx/drivers_font_renderer/stb_unicode.c | 2 +- gfx/drivers_renderchain/d3d8_renderchain.c | 20 +- .../d3d9_hlsl_renderchain.c | 26 +- gfx/drivers_renderchain/gl1_renderchain.c | 4 +- gfx/drivers_renderchain/gl2_renderchain.c | 66 +- gfx/drivers_renderchain/null_renderchain.c | 2 +- gfx/drivers_shader/shader_gl_cg.c | 26 +- gfx/drivers_shader/shader_glsl.c | 10 +- gfx/drivers_shader/shader_glsl.h | 2 +- gfx/drivers_shader/shader_hlsl.c | 8 +- gfx/drivers_shader/shader_hlsl.h | 2 +- gfx/drivers_shader/shader_null.c | 2 +- gfx/drivers_shader/shader_vulkan.h | 4 +- gfx/drivers_shader/slang_preprocess.h | 2 +- gfx/drivers_tracker/video_state_python.h | 4 +- gfx/font_driver.c | 10 +- gfx/font_driver.h | 14 +- gfx/include/GL/glext.h | 6 +- gfx/include/d3d8/d3d8.h | 2558 +++++------ gfx/include/d3d8/d3dx8.h | 88 +- gfx/include/d3d8/d3dx8core.h | 1126 ++--- gfx/include/d3d8/d3dx8effect.h | 452 +- gfx/include/d3d8/d3dx8math.h | 2426 +++++------ gfx/include/d3d8/d3dx8mesh.h | 1520 +++---- gfx/include/d3d8/d3dx8shape.h | 440 +- gfx/include/d3d8/d3dx8tex.h | 3184 +++++++------- gfx/include/d3d9/d3dx9anim.h | 170 +- gfx/include/d3d9/d3dx9core.h | 52 +- gfx/include/d3d9/d3dx9effect.h | 50 +- gfx/include/d3d9/d3dx9math.h | 72 +- gfx/include/d3d9/d3dx9mesh.h | 716 +-- gfx/include/d3d9/d3dx9shader.h | 28 +- gfx/include/d3d9/d3dx9shape.h | 32 +- gfx/include/d3d9/d3dx9tex.h | 14 +- gfx/include/d3d9/d3dx9xof.h | 20 +- gfx/include/d3d9caps.h | 16 +- gfx/include/d3d9types.h | 78 +- gfx/include/vulkan/vulkan.h | 4 +- gfx/video_coord_array.c | 2 +- gfx/video_coord_array.h | 2 +- gfx/video_driver.c | 82 +- gfx/video_driver.h | 64 +- gfx/video_filter.c | 8 +- gfx/video_filters/2xbr.c | 118 +- gfx/video_filters/2xsai.c | 14 +- gfx/video_filters/blargg_ntsc_snes.c | 8 +- gfx/video_filters/darken.c | 6 +- gfx/video_filters/epx.c | 6 +- gfx/video_filters/lq2x.c | 12 +- gfx/video_filters/phosphor2x.c | 72 +- gfx/video_filters/scale2x.c | 12 +- gfx/video_filters/snes_ntsc/snes_ntsc.c | 48 +- gfx/video_filters/snes_ntsc/snes_ntsc.h | 4 +- gfx/video_filters/snes_ntsc/snes_ntsc_impl.h | 42 +- gfx/video_filters/softfilter.h | 30 +- gfx/video_filters/super2xsai.c | 8 +- gfx/video_filters/supereagle.c | 4 +- gfx/video_shader_parse.c | 56 +- gfx/video_shader_parse.h | 20 +- gfx/video_state_tracker.c | 12 +- gfx/video_state_tracker.h | 2 +- gfx/video_thread_wrapper.c | 28 +- gfx/video_thread_wrapper.h | 6 +- input/common/input_x11_common.c | 2 +- input/common/input_x11_common.h | 2 +- input/common/linux_common.c | 8 +- input/common/linux_common.h | 2 +- input/connect/connect_ps4.c | 2 +- input/connect/connect_wiiupro.c | 2 +- input/drivers/android_input.c | 60 +- input/drivers/cocoa_input.h | 2 +- input/drivers/ctr_input.c | 2 +- input/drivers/gx_input.c | 2 +- input/drivers/linuxraw_input.c | 4 +- input/drivers/nullinput.c | 2 +- input/drivers/ps3_input.c | 8 +- input/drivers/rwebinput_input.c | 6 +- input/drivers/sdl_input.c | 8 +- input/drivers/wayland_input.c | 14 +- input/drivers/winraw_input.c | 1714 ++++---- input/drivers/x11_input.c | 16 +- input/drivers/xdk_xinput_input.c | 8 +- input/drivers/xenon360_input.c | 2 +- input/drivers_hid/libusb_hid.c | 14 +- input/drivers_joypad/dinput_joypad.c | 8 +- input/drivers_joypad/sdl_joypad.c | 2 +- input/drivers_joypad/xinput_joypad.c | 20 +- .../drivers_keyboard/keyboard_event_android.c | 4 +- .../drivers_keyboard/keyboard_event_android.h | 2 +- input/drivers_keyboard/keyboard_event_dos.c | 2 +- input/drivers_keyboard/keyboard_event_dos.h | 2 +- input/drivers_keyboard/keyboard_event_xkb.c | 2 +- input/include/GameController/GCController.h | 46 +- .../GameController/GCControllerAxisInput.h | 2 +- .../GameController/GCControllerButtonInput.h | 4 +- .../GameController/GCControllerDirectionPad.h | 2 +- .../GameController/GCExtendedGamepad.h | 14 +- .../GCExtendedGamepadSnapshot.h | 14 +- input/include/GameController/GCGamepad.h | 12 +- .../GameController/GCGamepadSnapshot.h | 16 +- input/input_driver.c | 76 +- input/input_keymaps.c | 6 +- input/input_keymaps.h | 4 +- input/input_mapper.c | 6 +- input/input_mapper.h | 2 +- input/input_overlay.c | 22 +- input/input_overlay.h | 10 +- input/input_remapping.c | 14 +- input/input_remote.c | 4 +- input/input_remote.h | 2 +- intl/msg_hash_pt_br.c | 12 +- lakka.h | 2 +- libretro-common/audio/audio_mix.c | 6 +- libretro-common/audio/audio_mixer.c | 84 +- .../audio/conversion/float_to_s16.c | 6 +- .../audio/conversion/s16_to_float.c | 6 +- libretro-common/audio/dsp_filter.c | 6 +- libretro-common/audio/dsp_filters/chorus.c | 2 +- libretro-common/audio/dsp_filters/eq.c | 6 +- libretro-common/audio/dsp_filters/iir.c | 10 +- libretro-common/audio/dsp_filters/panning.c | 2 +- .../audio/resampler/audio_resampler.c | 2 +- .../resampler/drivers/nearest_resampler.c | 20 +- .../audio/resampler/drivers/null_resampler.c | 10 +- .../audio/resampler/drivers/sinc_resampler.c | 34 +- libretro-common/compat/compat_fnmatch.c | 12 +- libretro-common/compat/compat_getopt.c | 6 +- libretro-common/compat/compat_ifaddrs.c | 10 +- libretro-common/compat/compat_snprintf.c | 20 +- libretro-common/encodings/encoding_utf.c | 6 +- libretro-common/features/features_cpu.c | 12 +- libretro-common/file/archive_file.c | 4 +- libretro-common/file/archive_file_zlib.c | 2 +- libretro-common/file/config_file.c | 4 +- libretro-common/file/config_file_userdata.c | 8 +- libretro-common/file/file_path.c | 12 +- libretro-common/file/nbio/nbio_intf.c | 170 +- libretro-common/file/nbio/nbio_linux.c | 8 +- libretro-common/file/nbio/nbio_stdio.c | 536 +-- libretro-common/file/nbio/nbio_unixmmap.c | 10 +- libretro-common/file/nbio/nbio_windowsmmap.c | 6 +- libretro-common/formats/bmp/rbmp.c | 8 +- libretro-common/formats/image_texture.c | 12 +- libretro-common/formats/image_transfer.c | 2 +- libretro-common/formats/jpeg/rjpeg.c | 18 +- libretro-common/formats/json/jsonsax_full.c | 22 +- libretro-common/formats/libchdr/bitstream.c | 2 +- libretro-common/formats/libchdr/cdrom.c | 848 ++-- libretro-common/formats/libchdr/chd.c | 22 +- libretro-common/formats/libchdr/flac.c | 668 +-- libretro-common/formats/libchdr/huffman.c | 1134 ++--- libretro-common/formats/png/rpng.c | 42 +- libretro-common/formats/png/rpng_encode.c | 4 +- libretro-common/formats/tga/rtga.c | 6 +- libretro-common/formats/wav/rwav.c | 6 +- libretro-common/formats/xml/rxml.c | 12 +- libretro-common/formats/xml/test/rxml_test.c | 2 +- libretro-common/gfx/gl_capabilities.c | 2 +- libretro-common/gfx/scaler/pixconv.c | 2 +- libretro-common/gfx/scaler/scaler.c | 4 +- libretro-common/gfx/scaler/scaler_filter.c | 6 +- libretro-common/gfx/scaler/scaler_int.c | 26 +- libretro-common/glsm/glsm.c | 154 +- libretro-common/hash/rhash.c | 30 +- .../include/audio/audio_resampler.h | 18 +- .../include/audio/conversion/float_to_s16.h | 2 +- libretro-common/include/compat/getopt.h | 6 +- libretro-common/include/compat/intrinsics.h | 2 +- libretro-common/include/compat/msvc.h | 62 +- libretro-common/include/compat/msvc/stdint.h | 14 +- libretro-common/include/compat/strcasestr.h | 2 +- libretro-common/include/compat/strl.h | 2 +- libretro-common/include/encodings/win32.h | 126 +- libretro-common/include/file/config_file.h | 6 +- libretro-common/include/file/file_path.h | 38 +- libretro-common/include/file/nbio.h | 2 +- libretro-common/include/formats/rwav.h | 8 +- libretro-common/include/formats/rxml.h | 12 +- libretro-common/include/gfx/math/matrix_4x4.h | 8 +- libretro-common/include/gfx/math/vector_2.h | 4 +- libretro-common/include/glsm/glsmsym.h | 2 +- libretro-common/include/libchdr/cdrom.h | 140 +- libretro-common/include/libchdr/chd.h | 4 +- libretro-common/include/libchdr/flac.h | 104 +- libretro-common/include/libchdr/huffman.h | 180 +- libretro-common/include/libchdr/minmax.h | 42 +- libretro-common/include/libretro.h | 570 +-- libretro-common/include/libretro_dspfilter.h | 42 +- libretro-common/include/libretro_vulkan.h | 106 +- libretro-common/include/lists/file_list.h | 8 +- libretro-common/include/net/net_http.h | 6 +- libretro-common/include/net/net_ifinfo.h | 2 +- libretro-common/include/queues/task_queue.h | 40 +- libretro-common/include/retro_common.h | 2 +- libretro-common/include/retro_common_api.h | 4 +- libretro-common/include/retro_endianness.h | 24 +- libretro-common/include/retro_miscellaneous.h | 10 +- libretro-common/include/rthreads/rthreads.h | 34 +- libretro-common/libco/armeabi.c | 2 +- libretro-common/libco/ppc.c | 32 +- libretro-common/lists/file_list.c | 8 +- libretro-common/memmap/memmap.c | 4 +- libretro-common/net/net_compat.c | 12 +- libretro-common/net/net_http.c | 6 +- libretro-common/net/net_ifinfo.c | 2 +- libretro-common/net/net_socket.c | 4 +- libretro-common/queues/message_queue.c | 6 +- libretro-common/queues/task_queue.c | 4 +- libretro-common/rthreads/rthreads.c | 94 +- .../samples/formats/png/rpng_test.c | 2 +- libretro-common/samples/net/net_http_test.c | 6 +- libretro-common/samples/net/udp-test.c | 116 +- libretro-common/streams/chd_stream.c | 4 +- .../streams/file_stream_transforms.c | 205 +- libretro-common/streams/memory_stream.c | 4 +- libretro-common/string/stdstring.c | 8 +- libretro-common/utils/crc32.c | 86 +- libretro-common/utils/sha1.c | 16 +- libretro-common/utils/sha1_main.c | 4 +- libretro-db/libretrodb_tool.c | 8 +- libretro-db/query.c | 12 +- libretro-db/rmsgpack_dom.c | 4 +- list_special.c | 2 +- list_special.h | 2 +- location/drivers/android.c | 4 +- location/drivers/nulllocation.c | 2 +- location/location_driver.c | 16 +- location/location_driver.h | 4 +- managers/cheat_manager.h | 2 +- managers/core_manager.c | 2 +- managers/core_manager.h | 2 +- managers/core_option_manager.c | 8 +- managers/core_option_manager.h | 6 +- managers/state_manager.c | 88 +- managers/state_manager.h | 2 +- memory/wii/mem2_manager.c | 14 +- memory/wii/mem2_manager.h | 2 +- menu/cbs/menu_cbs_deferred_push.c | 18 +- menu/cbs/menu_cbs_get_value.c | 4 +- menu/cbs/menu_cbs_info.c | 2 +- menu/cbs/menu_cbs_left.c | 22 +- menu/cbs/menu_cbs_ok.c | 8 +- menu/cbs/menu_cbs_right.c | 10 +- menu/cbs/menu_cbs_scan.c | 2 +- menu/cbs/menu_cbs_select.c | 10 +- menu/cbs/menu_cbs_start.c | 4 +- menu/cbs/menu_cbs_title.c | 46 +- menu/drivers/materialui.c | 158 +- menu/drivers/menu_generic.c | 2 +- menu/drivers/nuklear.c | 6 +- menu/drivers/nuklear/nk_common.c | 2 +- menu/drivers/nuklear/nk_menu.c | 68 +- menu/drivers/rgui.c | 6 +- menu/drivers/xmb.c | 2 +- menu/drivers/zarch.c | 34 +- menu/drivers_display/menu_display_caca.c | 2 +- menu/drivers_display/menu_display_ctr.c | 4 +- menu/drivers_display/menu_display_d3d.c | 6 +- menu/drivers_display/menu_display_vga.c | 2 +- menu/drivers_display/menu_display_vita2d.c | 36 +- menu/drivers_display/menu_display_vulkan.c | 6 +- menu/menu_animation.c | 6 +- menu/menu_cbs.c | 16 +- menu/menu_cbs.h | 4 +- menu/menu_content.c | 4 +- menu/menu_displaylist.h | 2 +- menu/menu_driver.c | 30 +- menu/menu_entries.c | 6 +- menu/menu_entries.h | 2 +- menu/menu_event.c | 10 +- menu/menu_event.h | 4 +- menu/menu_input.c | 12 +- menu/menu_setting.h | 2 +- menu/menu_shader.c | 28 +- menu/menu_shader.h | 6 +- menu/widgets/menu_entry.c | 8 +- menu/widgets/menu_filebrowser.c | 2 +- menu/widgets/menu_input_bind_dialog.c | 2 +- movie.c | 16 +- movie.h | 2 +- network/httpserver/httpserver.c | 2 +- network/net_http_special.h | 2 +- network/net_logger.c | 2 +- network/netplay/netplay.h | 2 +- network/netplay/netplay_buf.c | 2 +- network/netplay/netplay_discovery.c | 12 +- network/netplay/netplay_discovery.h | 2 +- network/netplay/netplay_frontend.c | 30 +- network/netplay/netplay_handshake.c | 8 +- network/netplay/netplay_init.c | 18 +- network/netplay/netplay_io.c | 4 +- network/netplay/netplay_private.h | 6 +- paths.c | 14 +- paths.h | 2 +- performance_counters.h | 6 +- playlist.c | 12 +- playlist.h | 10 +- record/drivers/record_ffmpeg.c | 34 +- record/record_driver.c | 10 +- record/record_driver.h | 2 +- retroarch.h | 10 +- setting_list.c | 48 +- setting_list.h | 10 +- tasks/task_audio_mixer.c | 8 +- tasks/task_content.c | 40 +- tasks/task_database.c | 10 +- tasks/task_http.c | 2 +- tasks/task_image.c | 12 +- tasks/task_netplay_find_content.c | 18 +- tasks/task_netplay_lan_scan.c | 2 +- tasks/task_overlay.c | 4 +- tasks/task_patch.c | 76 +- tasks/task_save.c | 8 +- tasks/task_screenshot.c | 8 +- tasks/task_wifi.c | 2 +- tasks/tasks_internal.h | 4 +- tools/ps3/ps3py/crypt.c | 10 +- ui/drivers/cocoa/cocoa_common.h | 4 +- ui/drivers/qt/wimp/wimp.h | 126 +- ui/drivers/qt/wimp/wimp_global.h | 56 +- ui/drivers/qt/wrapper/wrapper.h | 76 +- ui/drivers/ui_cocoa.h | 2 +- ui/drivers/ui_win32.c | 64 +- ui/drivers/ui_win32.h | 2 +- ui/drivers/ui_win32_resource.h | 64 +- ui/drivers/win32/ui_win32_browser_window.c | 2 +- ui/drivers/win32/ui_win32_window.c | 2 +- ui/ui_companion_driver.c | 2 +- ui/ui_companion_driver.h | 6 +- verbosity.c | 2 +- version.h | 2 +- version_git.c | 2 +- version_git.h | 4 +- wifi/drivers/connmanctl.c | 4 +- wifi/drivers/nullwifi.c | 2 +- wifi/wifi_driver.c | 14 +- wifi/wifi_driver.h | 2 +- wii/app_booter/main.c | 2 +- wii/libogc/include/bte/bd_addr.h | 28 +- wii/libogc/include/debug.h | 2 +- wii/libogc/include/gctypes.h | 6 +- wii/libogc/include/ipv4/lwip/icmp.h | 30 +- wii/libogc/include/ipv4/lwip/inet.h | 28 +- wii/libogc/include/ipv4/lwip/ip.h | 30 +- wii/libogc/include/ipv4/lwip/ip_frag.h | 28 +- wii/libogc/include/iso9660.h | 2 +- wii/libogc/include/lwip/api.h | 28 +- wii/libogc/include/lwip/api_msg.h | 28 +- wii/libogc/include/lwip/arch.h | 28 +- wii/libogc/include/lwip/debug.h | 40 +- wii/libogc/include/lwip/def.h | 28 +- wii/libogc/include/lwip/dhcp.h | 22 +- wii/libogc/include/lwip/err.h | 28 +- wii/libogc/include/lwip/lwipopts.h | 2 +- wii/libogc/include/lwip/mem.h | 28 +- wii/libogc/include/lwip/memp.h | 32 +- wii/libogc/include/lwip/netif.h | 28 +- wii/libogc/include/lwip/opt.h | 56 +- wii/libogc/include/lwip/pbuf.h | 42 +- wii/libogc/include/lwip/sio.h | 26 +- wii/libogc/include/lwip/snmp.h | 54 +- wii/libogc/include/lwip/sockets.h | 32 +- wii/libogc/include/lwip/stats.h | 32 +- wii/libogc/include/lwip/sys.h | 28 +- wii/libogc/include/lwip/tcp.h | 68 +- wii/libogc/include/lwip/tcpip.h | 28 +- wii/libogc/include/lwip/udp.h | 34 +- wii/libogc/include/netif/arch/cc.h | 48 +- wii/libogc/include/netif/arch/cpu.h | 48 +- wii/libogc/include/netif/arch/init.h | 48 +- wii/libogc/include/netif/arch/lib.h | 48 +- wii/libogc/include/netif/arch/perf.h | 48 +- wii/libogc/include/netif/arch/sys_arch.h | 48 +- wii/libogc/include/netif/etharp.h | 28 +- wii/libogc/include/netif/loopif.h | 28 +- wii/libogc/include/ogc/aram.h | 36 +- wii/libogc/include/ogc/arqmgr.h | 4 +- wii/libogc/include/ogc/arqueue.h | 4 +- wii/libogc/include/ogc/audio.h | 54 +- wii/libogc/include/ogc/card.h | 28 +- wii/libogc/include/ogc/cond.h | 6 +- wii/libogc/include/ogc/disc_io.h | 2 +- wii/libogc/include/ogc/dsp.h | 18 +- wii/libogc/include/ogc/dvd.h | 64 +- wii/libogc/include/ogc/exi.h | 4 +- wii/libogc/include/ogc/gu.h | 2 +- wii/libogc/include/ogc/gx.h | 14 +- wii/libogc/include/ogc/gx_struct.h | 4 +- wii/libogc/include/ogc/lwp.h | 4 +- wii/libogc/include/ogc/lwp_mutex.h | 2 +- wii/libogc/include/ogc/lwp_stack.h | 2 +- wii/libogc/include/ogc/lwp_states.h | 2 +- wii/libogc/include/ogc/lwp_threads.h | 2 +- wii/libogc/include/ogc/lwp_watchdog.h | 6 +- wii/libogc/include/ogc/machine/asm.h | 30 +- wii/libogc/include/ogc/machine/spinlock.h | 4 +- wii/libogc/include/ogc/message.h | 4 +- wii/libogc/include/ogc/mutex.h | 4 +- wii/libogc/include/ogc/semaphore.h | 4 +- wii/libogc/include/ogc/video.h | 34 +- wii/libogc/include/sdcard/gcsd.h | 2 +- wii/libogc/include/sdcard/wiisd_io.h | 2 +- wii/libogc/include/wiiuse/wiiuse.h | 2 +- wii/libogc/include/wiiuse/wpad.h | 8 +- wii/libogc/libdb/debug.c | 26 +- wii/libogc/libdb/debug_supp.c | 12 +- wii/libogc/libdb/geckousb.c | 2 +- wii/libogc/libdb/tcpip.c | 42 +- wii/libogc/libdb/uIP/bba.c | 48 +- wii/libogc/libdb/uIP/memb.c | 2 +- wii/libogc/libdb/uIP/memr.c | 10 +- wii/libogc/libdb/uIP/uip.h | 22 +- wii/libogc/libdb/uIP/uip_arch.c | 30 +- wii/libogc/libdb/uIP/uip_arch.h | 22 +- wii/libogc/libdb/uIP/uip_arp.c | 48 +- wii/libogc/libdb/uIP/uip_arp.h | 32 +- wii/libogc/libdb/uIP/uip_icmp.c | 10 +- wii/libogc/libdb/uIP/uip_ip.c | 42 +- wii/libogc/libdb/uIP/uip_ip.h | 6 +- wii/libogc/libdb/uIP/uip_netif.c | 14 +- wii/libogc/libdb/uIP/uip_netif.h | 8 +- wii/libogc/libdb/uIP/uip_pbuf.c | 16 +- wii/libogc/libdb/uIP/uip_tcp.c | 112 +- wii/libogc/libdb/uIP/uip_tcp.h | 26 +- wii/libogc/libdb/uIP/uipopt.h | 28 +- wii/libogc/libfat/bit_ops.h | 2 +- wii/libogc/libfat/directory.h | 10 +- wii/libogc/libfat/disc.c | 14 +- wii/libogc/libfat/disc.h | 12 +- wii/libogc/libfat/fatdir.h | 6 +- wii/libogc/libfat/fatfile.h | 6 +- wii/libogc/libfat/file_allocation_table.h | 6 +- wii/libogc/libfat/filetime.c | 20 +- wii/libogc/libfat/filetime.h | 2 +- wii/libogc/libfat/libfat.c | 8 +- wii/libogc/libfat/mem_allocate.h | 2 +- wii/libogc/libogc/argv.c | 6 +- wii/libogc/libogc/arqmgr.c | 8 +- wii/libogc/libogc/arqueue.c | 10 +- wii/libogc/libogc/card.c | 388 +- wii/libogc/libogc/cond.c | 8 +- wii/libogc/libogc/conf.c | 76 +- wii/libogc/libogc/console.c | 30 +- wii/libogc/libogc/depackrnc1.c | 2 +- wii/libogc/libogc/dvd.c | 2 +- wii/libogc/libogc/es.c | 10 +- wii/libogc/libogc/exception.c | 4 +- wii/libogc/libogc/gcsd.c | 2 +- wii/libogc/libogc/gu.c | 36 +- wii/libogc/libogc/ios.c | 8 +- wii/libogc/libogc/isfs.c | 66 +- wii/libogc/libogc/lock_supp.c | 10 +- wii/libogc/libogc/lwp.c | 20 +- wii/libogc/libogc/lwp_heap.c | 34 +- wii/libogc/libogc/lwp_messages.c | 18 +- wii/libogc/libogc/lwp_mutex.c | 8 +- wii/libogc/libogc/lwp_objmgr.c | 2 +- wii/libogc/libogc/lwp_priority.c | 4 +- wii/libogc/libogc/lwp_queue.c | 10 +- wii/libogc/libogc/lwp_sema.c | 6 +- wii/libogc/libogc/lwp_stack.c | 2 +- wii/libogc/libogc/lwp_threadq.c | 22 +- wii/libogc/libogc/lwp_threads.c | 60 +- wii/libogc/libogc/lwp_watchdog.c | 2 +- wii/libogc/libogc/malloc_lock.c | 6 +- wii/libogc/libogc/mutex.c | 4 +- wii/libogc/libogc/network_common.c | 4 +- wii/libogc/libogc/newlibc.c | 4 +- wii/libogc/libogc/pad.c | 2 +- wii/libogc/libogc/sbrk.c | 2 +- wii/libogc/libogc/sdgecko_buf.c | 6 +- wii/libogc/libogc/sdgecko_io.c | 92 +- wii/libogc/libogc/semaphore.c | 4 +- wii/libogc/libogc/stm.c | 26 +- wii/libogc/libogc/texconv.c | 2 +- wii/libogc/libogc/timesupp.c | 4 +- wii/libogc/libogc/timesupp.h | 2 +- wii/libogc/libogc/tpl.c | 6 +- wii/libogc/libogc/usbstorage.c | 28 +- wii/libogc/libogc/wiilaunch.c | 4 +- wii/libogc/libogc/wiisd.c | 154 +- wii/libogc/libwiikeyboard/ukbdmap.c | 2 +- wii/libogc/lwbt/bt.h | 22 +- wii/libogc/lwbt/btarch.h | 28 +- wii/libogc/lwbt/bte.c | 22 +- wii/libogc/lwbt/btmemb.c | 4 +- wii/libogc/lwbt/btmemr.c | 10 +- wii/libogc/lwbt/btopt.h | 50 +- wii/libogc/lwbt/btpbuf.c | 16 +- wii/libogc/lwbt/hci.c | 176 +- wii/libogc/lwbt/hci.h | 6 +- wii/libogc/lwbt/l2cap.c | 192 +- wii/libogc/lwbt/l2cap.h | 2 +- wii/libogc/lwbt/physbusif.h | 20 +- wii/libogc/lwip/core/dhcp.c | 16 +- wii/libogc/lwip/core/inet.c | 12 +- wii/libogc/lwip/core/inet6.c | 42 +- wii/libogc/lwip/core/ipv4/ip.c | 8 +- wii/libogc/lwip/core/ipv4/ip_addr.c | 32 +- wii/libogc/lwip/core/ipv4/ip_frag.c | 46 +- wii/libogc/lwip/core/mem.c | 74 +- wii/libogc/lwip/core/memp.c | 64 +- wii/libogc/lwip/core/netif.c | 16 +- wii/libogc/lwip/core/pbuf.c | 20 +- wii/libogc/lwip/core/raw.c | 14 +- wii/libogc/lwip/core/stats.c | 76 +- wii/libogc/lwip/core/tcp.c | 140 +- wii/libogc/lwip/core/tcp_in.c | 18 +- wii/libogc/lwip/core/tcp_out.c | 22 +- wii/libogc/lwip/core/udp.c | 16 +- wii/libogc/lwip/netif/etharp.c | 44 +- wii/libogc/lwip/netif/loopif.c | 40 +- wii/libogc/lwip/netif/skeleton/ethernetif.c | 72 +- wii/libogc/lwip/netif/skeleton/slipif.c | 84 +- wii/libogc/lwip/netio.c | 8 +- wii/libogc/lwip/network.c | 154 +- wii/libogc/wiiuse/classic.h | 2 +- wii/libogc/wiiuse/dynamics.c | 2 +- wii/libogc/wiiuse/dynamics.h | 2 +- wii/libogc/wiiuse/events.c | 10 +- wii/libogc/wiiuse/events.h | 2 +- wii/libogc/wiiuse/io.h | 2 +- wii/libogc/wiiuse/io_wii.c | 8 +- wii/libogc/wiiuse/ir.c | 4 +- wii/libogc/wiiuse/ir.h | 2 +- wii/libogc/wiiuse/motion_plus.c | 8 +- wii/libogc/wiiuse/motion_plus.h | 2 +- wii/libogc/wiiuse/nunchuk.c | 4 +- wii/libogc/wiiuse/nunchuk.h | 2 +- wii/libogc/wiiuse/os.h | 2 +- wii/libogc/wiiuse/speaker.c | 2 +- wii/libogc/wiiuse/speaker.h | 2 +- wii/libogc/wiiuse/wiiuse.c | 14 +- wii/libogc/wiiuse/wiiuse_internal.h | 2 +- wii/libogc/wiiuse/wpad.c | 6 +- wiiu/include/wiiu/nsyskbd.h | 4 +- wiiu/include/wiiu/syshid.h | 92 +- 765 files changed, 23365 insertions(+), 23366 deletions(-) diff --git a/audio/audio_driver.c b/audio/audio_driver.c index 6acb0b2ca7..6cd70cf681 100644 --- a/audio/audio_driver.c +++ b/audio/audio_driver.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -111,7 +111,7 @@ static const audio_driver_t *audio_drivers[] = { #endif #if defined(PSP) || defined(VITA) &audio_psp, -#endif +#endif #ifdef _3DS &audio_ctr_csnd, &audio_ctr_dsp, @@ -150,7 +150,7 @@ static uint64_t audio_driver_free_samples_count = 0; static size_t audio_driver_buffer_size = 0; static size_t audio_driver_data_ptr = 0; -static bool audio_driver_control = false; +static bool audio_driver_control = false; static bool audio_driver_mixer_mute_enable = false; static bool audio_driver_mute_enable = false; static bool audio_driver_use_float = false; @@ -212,12 +212,12 @@ static void compute_audio_buffer_statistics(void) accum_var += diff * diff; } -#if defined(_MSC_VER) && _MSC_VER <= 1200 +#if defined(_MSC_VER) && _MSC_VER <= 1200 /* FIXME: error C2520: conversion from unsigned __int64 to double not implemented, use signed __int64 */ -#else - stddev = (unsigned)sqrt((double)accum_var / (samples - 2)); - avg_filled = 1.0f - (float)avg / audio_driver_buffer_size; - deviation = (float)stddev / audio_driver_buffer_size; +#else + stddev = (unsigned)sqrt((double)accum_var / (samples - 2)); + avg_filled = 1.0f - (float)avg / audio_driver_buffer_size; + deviation = (float)stddev / audio_driver_buffer_size; #endif low_water_size = (unsigned)(audio_driver_buffer_size * 3 / 4); high_water_size = (unsigned)(audio_driver_buffer_size / 4); @@ -335,13 +335,13 @@ static bool audio_driver_init_internal(bool audio_cb_inited) size_t max_bufsamples = AUDIO_CHUNK_SIZE_NONBLOCKING * 2; settings_t *settings = config_get_ptr(); /* Accomodate rewind since at some point we might have two full buffers. */ - size_t outsamples_max = AUDIO_CHUNK_SIZE_NONBLOCKING * 2 * AUDIO_MAX_RATIO * + size_t outsamples_max = AUDIO_CHUNK_SIZE_NONBLOCKING * 2 * AUDIO_MAX_RATIO * settings->floats.slowmotion_ratio; convert_s16_to_float_init_simd(); convert_float_to_s16_init_simd(); - conv_buf = (int16_t*)malloc(outsamples_max + conv_buf = (int16_t*)malloc(outsamples_max * sizeof(int16_t)); /* Used for recording even if audio isn't enabled. */ retro_assert(conv_buf != NULL); @@ -379,9 +379,9 @@ static bool audio_driver_init_internal(bool audio_cb_inited) if (!audio_init_thread( ¤t_audio, &audio_driver_context_audio_data, - *settings->arrays.audio_device + *settings->arrays.audio_device ? settings->arrays.audio_device : NULL, - settings->uints.audio_out_rate, &new_rate, + settings->uints.audio_out_rate, &new_rate, settings->uints.audio_latency, settings->uints.audio_block_frames, current_audio)) @@ -393,7 +393,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) else #endif { - audio_driver_context_audio_data = + audio_driver_context_audio_data = current_audio->init(*settings->arrays.audio_device ? settings->arrays.audio_device : NULL, settings->uints.audio_out_rate, @@ -414,7 +414,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) } audio_driver_use_float = false; - if ( audio_driver_active + if ( audio_driver_active && current_audio->use_float(audio_driver_context_audio_data)) audio_driver_use_float = true; @@ -470,7 +470,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) if ( !audio_cb_inited - && audio_driver_active + && audio_driver_active && settings->bools.audio_rate_control ) { @@ -478,7 +478,7 @@ static bool audio_driver_init_internal(bool audio_cb_inited) * and buffer_size to be implemented. */ if (current_audio->buffer_size) { - audio_driver_buffer_size = + audio_driver_buffer_size = current_audio->buffer_size(audio_driver_context_audio_data); audio_driver_control = true; } @@ -516,8 +516,8 @@ void audio_driver_set_nonblocking_state(bool enable) audio_driver_context_audio_data, settings->bools.audio_sync ? enable : true); - audio_driver_chunk_size = enable ? - audio_driver_chunk_nonblock_size : + audio_driver_chunk_size = enable ? + audio_driver_chunk_nonblock_size : audio_driver_chunk_block_size; } @@ -541,7 +541,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) bool is_slowmotion = false; const void *output_data = NULL; unsigned output_frames = 0; - float audio_volume_gain = !audio_driver_mute_enable ? + float audio_volume_gain = !audio_driver_mute_enable ? audio_driver_volume_gain : 0.0f; src_data.data_in = NULL; @@ -597,7 +597,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) unsigned write_idx = audio_driver_free_samples_count++ & (AUDIO_BUFFER_FREE_SAMPLES_COUNT - 1); int half_size = (int)(audio_driver_buffer_size / 2); - int avail = + int avail = (int)current_audio->write_avail(audio_driver_context_audio_data); int delta_mid = avail - half_size; double direction = (double)delta_mid / half_size; @@ -610,7 +610,7 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) audio_driver_free_samples_buf [write_idx] = avail; - audio_source_ratio_current = + audio_source_ratio_current = audio_source_ratio_original * adjust; #if 0 @@ -632,9 +632,9 @@ static bool audio_driver_flush(const int16_t *data, size_t samples) if (audio_mixer_active) { - bool override = audio_driver_mixer_mute_enable ? true : + bool override = audio_driver_mixer_mute_enable ? true : (audio_driver_mixer_volume_gain != 0.0f) ? true : false; - float mixer_gain = !audio_driver_mixer_mute_enable ? + float mixer_gain = !audio_driver_mixer_mute_enable ? audio_driver_mixer_volume_gain : 0.0f; audio_mixer_mix(audio_driver_output_samples_buf, src_data.output_frames, mixer_gain, override); @@ -679,7 +679,7 @@ void audio_driver_sample(int16_t left, int16_t right) if (audio_driver_data_ptr < audio_driver_chunk_size) return; - audio_driver_flush(audio_driver_output_samples_conv_buf, + audio_driver_flush(audio_driver_output_samples_conv_buf, audio_driver_data_ptr); audio_driver_data_ptr = 0; @@ -710,8 +710,8 @@ size_t audio_driver_sample_batch(const int16_t *data, size_t frames) * @left : value of the left audio channel. * @right : value of the right audio channel. * - * Audio sample render callback function (rewind version). - * This callback function will be used instead of + * Audio sample render callback function (rewind version). + * This callback function will be used instead of * audio_driver_sample when rewinding is activated. **/ void audio_driver_sample_rewind(int16_t left, int16_t right) @@ -725,9 +725,9 @@ void audio_driver_sample_rewind(int16_t left, int16_t right) * @data : pointer to audio buffer. * @frames : amount of audio frames to push. * - * Batched audio sample render callback function (rewind version). + * Batched audio sample render callback function (rewind version). * - * This callback function will be used instead of + * This callback function will be used instead of * audio_driver_sample_batch when rewinding is activated. * * Returns: amount of frames sampled. Will be equal to @frames @@ -800,9 +800,9 @@ void audio_driver_monitor_adjust_system_rates(void) struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); float video_refresh_rate = settings->floats.video_refresh_rate; float max_timing_skew = settings->floats.audio_max_timing_skew; - const struct retro_system_timing *info = av_info ? + const struct retro_system_timing *info = av_info ? (const struct retro_system_timing*)&av_info->timing : NULL; - + if (!info || info->sample_rate <= 0.0) return; @@ -882,7 +882,7 @@ bool audio_driver_free_devices_list(void) if (!current_audio || !current_audio->device_list_free || !audio_driver_context_audio_data) return false; - current_audio->device_list_free(audio_driver_context_audio_data, + current_audio->device_list_free(audio_driver_context_audio_data, audio_driver_devices_list); audio_driver_devices_list = NULL; return true; @@ -1003,7 +1003,7 @@ bool audio_driver_mixer_add_stream(audio_mixer_stream_params_t *params) audio_mixer_stop_cb_t stop_cb = audio_mixer_play_stop_cb; bool looped = false; void *buf = NULL; - + if (audio_mixer_current_max_idx >= AUDIO_MIXER_MAX_STREAMS) return false; @@ -1132,7 +1132,7 @@ bool audio_driver_set_callback(const void *data) bool audio_driver_enable_callback(void) { if (!audio_callback.callback) - return false; + return false; if (audio_callback.set_state) audio_callback.set_state(true); return true; @@ -1152,7 +1152,7 @@ bool audio_driver_disable_callback(void) void audio_driver_monitor_set_rate(void) { settings_t *settings = config_get_ptr(); - double new_src_ratio = (double)settings->uints.audio_out_rate / + double new_src_ratio = (double)settings->uints.audio_out_rate / audio_driver_input; audio_source_ratio_original = new_src_ratio; @@ -1191,8 +1191,8 @@ bool audio_driver_mixer_toggle_mute(void) static INLINE bool audio_driver_alive(void) { - if ( current_audio - && current_audio->alive + if ( current_audio + && current_audio->alive && audio_driver_context_audio_data) return current_audio->alive(audio_driver_context_audio_data); return false; @@ -1200,7 +1200,7 @@ static INLINE bool audio_driver_alive(void) bool audio_driver_start(bool is_shutdown) { - if (!current_audio || !current_audio->start + if (!current_audio || !current_audio->start || !audio_driver_context_audio_data) goto error; if (!current_audio->start(audio_driver_context_audio_data, is_shutdown)) @@ -1218,7 +1218,7 @@ error: bool audio_driver_stop(void) { - if (!current_audio || !current_audio->stop + if (!current_audio || !current_audio->stop || !audio_driver_context_audio_data) return false; if (!audio_driver_alive()) diff --git a/audio/audio_driver.h b/audio/audio_driver.h index 3a62b95c29..27b6a4205c 100644 --- a/audio/audio_driver.h +++ b/audio/audio_driver.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -90,7 +90,7 @@ typedef struct audio_driver /* Is the audio driver currently running? */ bool (*alive)(void *data); - /* Should we care about blocking in audio thread? Fast forwarding. + /* Should we care about blocking in audio thread? Fast forwarding. * * If state is true, nonblocking operation is assumed. * This is typically used for fast-forwarding. If driver cannot @@ -103,7 +103,7 @@ typedef struct audio_driver void (*free)(void *data); /* Defines if driver will take standard floating point samples, - * or int16_t samples. + * or int16_t samples. * * If true is returned, the audio driver is capable of using * floating point data. This will likely increase performance as the diff --git a/audio/audio_thread_wrapper.c b/audio/audio_thread_wrapper.c index 196fd201c6..76e130fd44 100644 --- a/audio/audio_thread_wrapper.c +++ b/audio/audio_thread_wrapper.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -56,7 +56,7 @@ static void audio_thread_loop(void *data) return; RARCH_LOG("[Audio Thread]: Initializing audio driver.\n"); - thr->driver_data = thr->driver->init(thr->device, thr->out_rate, thr->latency, + thr->driver_data = thr->driver->init(thr->device, thr->out_rate, thr->latency, thr->block_frames, thr->new_rate); slock_lock(thr->lock); thr->inited = thr->driver_data ? 1 : -1; @@ -68,7 +68,7 @@ static void audio_thread_loop(void *data) if (thr->inited < 0) return; - /* Wait until we start to avoid calling + /* Wait until we start to avoid calling * stop immediately after initialization. */ slock_lock(thr->lock); while (thr->stopped) @@ -188,7 +188,7 @@ static bool audio_thread_stop(void *data) audio_thread_t *thr = (audio_thread_t*)data; if (!thr) - return false; + return false; audio_thread_block(thr); thr->is_paused = true; @@ -274,7 +274,7 @@ static const audio_driver_t audio_thread = { * * Starts a audio driver in a new thread. * Access to audio driver will be mediated through this driver. - * This driver interfaces with audio callback and is + * This driver interfaces with audio callback and is * only used in that case. * * Returns: true (1) if successful, otherwise false (0). diff --git a/audio/audio_thread_wrapper.h b/audio/audio_thread_wrapper.h index 298941d4ff..fcb2e0d028 100644 --- a/audio/audio_thread_wrapper.h +++ b/audio/audio_thread_wrapper.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/alsa.c b/audio/drivers/alsa.c index 379b579658..c2f2a13f91 100644 --- a/audio/drivers/alsa.c +++ b/audio/drivers/alsa.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -121,7 +121,7 @@ static void *alsa_init(const char *device, unsigned rate, unsigned latency, if (snd_pcm_hw_params(alsa->pcm, params) < 0) goto error; - /* Shouldn't have to bother with this, + /* Shouldn't have to bother with this, * but some drivers are apparently broken. */ if (snd_pcm_hw_params_get_period_size(params, &buffer_size, NULL)) snd_pcm_hw_params_get_period_size_min(params, &buffer_size, NULL); diff --git a/audio/drivers/alsa_qsa.c b/audio/drivers/alsa_qsa.c index 6fe075cfd9..76d442db98 100644 --- a/audio/drivers/alsa_qsa.c +++ b/audio/drivers/alsa_qsa.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -231,7 +231,7 @@ static ssize_t alsa_qsa_write(void *data, const void *buf, size_t size) if (avail_write) { - memcpy(alsa->buffer[alsa->buffer_index] + + memcpy(alsa->buffer[alsa->buffer_index] + alsa->buffer_ptr, buf, avail_write); alsa->buffer_ptr += avail_write; @@ -355,8 +355,8 @@ static void alsa_qsa_free(void *data) static size_t alsa_qsa_write_avail(void *data) { alsa_t *alsa = (alsa_t*)data; - size_t avail = (alsa->buf_count - - (int)alsa->buffered_blocks - 1) * alsa->buf_size + + size_t avail = (alsa->buf_count - + (int)alsa->buffered_blocks - 1) * alsa->buf_size + (alsa->buf_size - (int)alsa->buffer_ptr); return avail; } @@ -364,7 +364,7 @@ static size_t alsa_qsa_write_avail(void *data) static size_t alsa_qsa_buffer_size(void *data) { alsa_t *alsa = (alsa_t*)data; - return alsa->buf_size * alsa->buf_count; + return alsa->buf_size * alsa->buf_count; } audio_driver_t audio_alsa = { diff --git a/audio/drivers/alsathread.c b/audio/drivers/alsathread.c index e6206eb65b..b01b6a424a 100644 --- a/audio/drivers/alsathread.c +++ b/audio/drivers/alsathread.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -77,7 +77,7 @@ static void alsa_worker_thread(void *data) frames = snd_pcm_writei(alsa->pcm, buf, alsa->period_frames); - if (frames == -EPIPE || frames == -EINTR || + if (frames == -EPIPE || frames == -EINTR || frames == -ESTRPIPE) { if (snd_pcm_recover(alsa->pcm, frames, 1) < 0) @@ -192,7 +192,7 @@ static void *alsa_thread_init(const char *device, TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params)); - /* Shouldn't have to bother with this, + /* Shouldn't have to bother with this, * but some drivers are apparently broken. */ if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL)) snd_pcm_hw_params_get_period_size_min( diff --git a/audio/drivers/coreaudio.c b/audio/drivers/coreaudio.c index 02ff2c6b9a..6f255bbc5b 100644 --- a/audio/drivers/coreaudio.c +++ b/audio/drivers/coreaudio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2014 - Chris Moeller - * + * * 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. @@ -112,7 +112,7 @@ static OSStatus audio_write_cb(void *userdata, slock_unlock(dev->lock); /* Technically possible to deadlock without. */ - scond_signal(dev->cond); + scond_signal(dev->cond); return noErr; } @@ -169,10 +169,10 @@ static void choose_output_device(coreaudio_t *dev, const char* device) size = 1024; if (AudioObjectGetPropertyData(devices[i], - &propaddr, 0, 0, &size, device_name) == noErr + &propaddr, 0, 0, &size, device_name) == noErr && string_is_equal(device_name, device)) { - AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice, + AudioUnitSetProperty(dev->dev, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Global, 0, &devices[i], sizeof(AudioDeviceID)); goto done; } @@ -244,7 +244,7 @@ static void *coreaudio_init(const char *device, #endif if (comp == NULL) goto error; - + #if (defined(__MACH__) && (defined(__ppc__) || defined(__ppc64__))) component_unavailable = (OpenAComponent(comp, &dev->dev) != noErr); #else @@ -269,17 +269,17 @@ static void *coreaudio_init(const char *device, stream_desc.mBytesPerFrame = 2 * sizeof(float); stream_desc.mFramesPerPacket = 1; stream_desc.mFormatID = kAudioFormatLinearPCM; - stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | - kAudioFormatFlagIsPacked | (is_little_endian() ? + stream_desc.mFormatFlags = kAudioFormatFlagIsFloat | + kAudioFormatFlagIsPacked | (is_little_endian() ? 0 : kAudioFormatFlagIsBigEndian); - + if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr) goto error; - + /* Check returned audio format. */ i_size = sizeof(real_desc); - if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, + if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr) goto error; diff --git a/audio/drivers/ctr_csnd_audio.c b/audio/drivers/ctr_csnd_audio.c index 4765cd7f5c..8731706c32 100644 --- a/audio/drivers/ctr_csnd_audio.c +++ b/audio/drivers/ctr_csnd_audio.c @@ -49,7 +49,7 @@ typedef struct static void ctr_csnd_audio_update_playpos(ctr_csnd_audio_t* ctr) { uint64_t current_tick = svcGetSystemTick(); - uint32_t samples_played = (current_tick - ctr->cpu_ticks_last) + uint32_t samples_played = (current_tick - ctr->cpu_ticks_last) / CTR_CSND_CPU_TICKS_PER_SAMPLE; ctr->playpos = (ctr->playpos + samples_played) & CTR_CSND_AUDIO_COUNT_MASK; @@ -94,7 +94,7 @@ Result csndPlaySound_custom(int chn, u32 flags, float vol, float pan, if (loopMode == CSND_LOOPMODE_NORMAL && paddr1 > paddr0) { - /* Now that the first block is playing, + /* Now that the first block is playing, * configure the size of the subsequent blocks */ size -= paddr1 - paddr0; CSND_SetBlock(chn, 1, paddr1, size); @@ -209,7 +209,7 @@ static ssize_t ctr_csnd_audio_write(void *data, const void *buf, size_t size) } static bool ctr_csnd_audio_stop(void *data) -{ +{ ctr_csnd_audio_t* ctr = (ctr_csnd_audio_t*)data; /* using SetPlayState would make tracking the playback diff --git a/audio/drivers/dsound.c b/audio/drivers/dsound.c index 9514236f4a..09b8119f87 100644 --- a/audio/drivers/dsound.c +++ b/audio/drivers/dsound.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -93,7 +93,7 @@ static INLINE bool grab_region(dsound_t *ds, uint32_t write_ptr, struct audio_lock *region) { const char *err = NULL; - HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, + HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); if (res == DSERR_BUFFERLOST) @@ -152,7 +152,7 @@ static void dsound_thread(void *data) struct audio_lock region; DWORD read_ptr, avail, fifo_avail; get_positions(ds, &read_ptr, NULL); - + avail = write_avail(read_ptr, write_ptr, ds->buffer_size); EnterCriticalSection(&ds->crit); @@ -161,12 +161,12 @@ static void dsound_thread(void *data) if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2))) { - /* No space to write, or we don't have data in our fifo, + /* No space to write, or we don't have data in our fifo, * but we can wait some time before it underruns ... */ /* We could opt for using the notification interface, - * but it is not guaranteed to work, so use high + * but it is not guaranteed to work, so use high * priority sleeping patterns. */ retro_sleep(1); @@ -182,7 +182,7 @@ static void dsound_thread(void *data) if (fifo_avail < CHUNK_SIZE) { - /* Got space to write, but nothing in FIFO (underrun), + /* Got space to write, but nothing in FIFO (underrun), * fill block with silence. */ memset(region.chunk1, 0, region.size1); @@ -191,7 +191,7 @@ static void dsound_thread(void *data) release_region(ds, ®ion); write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size; } - else + else { /* All is good. Pull from it and notify FIFO. */ diff --git a/audio/drivers/gx_audio.c b/audio/drivers/gx_audio.c index 7453060881..5e840a933f 100644 --- a/audio/drivers/gx_audio.c +++ b/audio/drivers/gx_audio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -129,9 +129,9 @@ static ssize_t gx_audio_write(void *data, const void *buf_, size_t size) if (frames < to_write) to_write = frames; - /* FIXME: Nonblocking audio should break out of loop + /* FIXME: Nonblocking audio should break out of loop * when it has nothing to write. */ - while ((wa->dma_write == wa->dma_next || + while ((wa->dma_write == wa->dma_next || wa->dma_write == wa->dma_busy) && !wa->nonblock) OSSleepThread(wa->cond); diff --git a/audio/drivers/jack.c b/audio/drivers/jack.c index 9b0758175f..40a116f292 100644 --- a/audio/drivers/jack.c +++ b/audio/drivers/jack.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - 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. @@ -181,7 +181,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency, RARCH_ERR("[JACK]: Failed to register ports.\n"); goto error; } - + jports = jack_get_ports(jd->client, NULL, NULL, JackPortIsPhysical | JackPortIsInput); if (jports == NULL) { @@ -222,7 +222,7 @@ static void *ja_init(const char *device, unsigned rate, unsigned latency, for (i = 0; i < parsed; i++) free(dest_ports[i]); - + jack_free(jports); return jd; diff --git a/audio/drivers/nullaudio.c b/audio/drivers/nullaudio.c index d0d9c0d36b..39be26d4d0 100644 --- a/audio/drivers/nullaudio.c +++ b/audio/drivers/nullaudio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/openal.c b/audio/drivers/openal.c index 69964f4225..6127ca9b4d 100644 --- a/audio/drivers/openal.c +++ b/audio/drivers/openal.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/opensl.c b/audio/drivers/opensl.c index fef08db8f2..113bce3567 100644 --- a/audio/drivers/opensl.c +++ b/audio/drivers/opensl.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -200,7 +200,7 @@ error: static bool sl_stop(void *data) { sl_t *sl = (sl_t*)data; - sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED) + sl->is_paused = (SLPlayItf_SetPlayState(sl->player, SL_PLAYSTATE_STOPPED) == SL_RESULT_SUCCESS) ? true : false; return sl->is_paused ? true : false; diff --git a/audio/drivers/oss.c b/audio/drivers/oss.c index d6d4d28ffa..1c6691187e 100644 --- a/audio/drivers/oss.c +++ b/audio/drivers/oss.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -51,7 +51,7 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency, int frags, frag, channels, format, new_rate; int *fd = (int*)calloc(1, sizeof(int)); const char *oss_device = device ? device : DEFAULT_OSS_DEV; - + if (!fd) return NULL; diff --git a/audio/drivers/ps3_audio.c b/audio/drivers/ps3_audio.c index 0d4e56e467..1f5eba29b6 100644 --- a/audio/drivers/ps3_audio.c +++ b/audio/drivers/ps3_audio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -110,11 +110,11 @@ static void *ps3_audio_init(const char *device, return NULL; } - data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES * + data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(float)); #ifdef __PSL1GHT__ - sys_lwmutex_attr_t lock_attr = + sys_lwmutex_attr_t lock_attr = {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"}; sys_lwmutex_attr_t cond_lock_attr = {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"}; diff --git a/audio/drivers/psp_audio.c b/audio/drivers/psp_audio.c index 808f21e3e5..48e0cdc823 100644 --- a/audio/drivers/psp_audio.c +++ b/audio/drivers/psp_audio.c @@ -244,9 +244,9 @@ static bool psp_audio_stop(void *data) SceUInt timeout = 100000; psp_audio_t* psp = (psp_audio_t*)data; - if(psp && !psp->running) + if(psp && !psp->running) return true; - + info.size = sizeof(SceKernelThreadInfo); if (sceKernelGetThreadInfo( @@ -269,8 +269,8 @@ static bool psp_audio_start(void *data, bool is_shutdown) { SceKernelThreadInfo info; psp_audio_t* psp = (psp_audio_t*)data; - - if(psp && psp->running) + + if(psp && psp->running) return true; info.size = sizeof(SceKernelThreadInfo); diff --git a/audio/drivers/pulse.c b/audio/drivers/pulse.c index 61e47fd08f..ce3e94bd5e 100644 --- a/audio/drivers/pulse.c +++ b/audio/drivers/pulse.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -88,7 +88,7 @@ static void context_state_cb(pa_context *c, void *data) } } -static void stream_state_cb(pa_stream *s, void *data) +static void stream_state_cb(pa_stream *s, void *data) { pa_t *pa = (pa_t*)data; @@ -104,7 +104,7 @@ static void stream_state_cb(pa_stream *s, void *data) } } -static void stream_request_cb(pa_stream *s, size_t length, void *data) +static void stream_request_cb(pa_stream *s, size_t length, void *data) { pa_t *pa = (pa_t*)data; @@ -114,7 +114,7 @@ static void stream_request_cb(pa_stream *s, size_t length, void *data) pa_threaded_mainloop_signal(pa->mainloop, 0); } -static void stream_latency_update_cb(pa_stream *s, void *data) +static void stream_latency_update_cb(pa_stream *s, void *data) { pa_t *pa = (pa_t*)data; @@ -149,7 +149,7 @@ static void buffer_attr_cb(pa_stream *s, void *data) } static void *pulse_init(const char *device, unsigned rate, - unsigned latency, + unsigned latency, unsigned block_frames, unsigned *new_rate) { @@ -232,7 +232,7 @@ static void *pulse_init(const char *device, unsigned rate, unlock_error: pa_threaded_mainloop_unlock(pa->mainloop); error: - pulse_free(pa); + pulse_free(pa); return NULL; } diff --git a/audio/drivers/roar.c b/audio/drivers/roar.c index 7e08f74749..815e5ade96 100644 --- a/audio/drivers/roar.c +++ b/audio/drivers/roar.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/rsound.c b/audio/drivers/rsound.c index 258f42aa2a..c6241c51d5 100644 --- a/audio/drivers/rsound.c +++ b/audio/drivers/rsound.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/rsound.h b/audio/drivers/rsound.h index 645eaa8316..236eeb16e6 100644 --- a/audio/drivers/rsound.h +++ b/audio/drivers/rsound.h @@ -1,6 +1,6 @@ /* RSound - A PCM audio client/server * Copyright (C) 2010-2014 - Hans-Kristian Arntzen - * + * * RSound 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. @@ -43,7 +43,7 @@ RETRO_BEGIN_DECLS #endif /* Feature tests */ -#define RSD_SAMPLERATE RSD_SAMPLERATE +#define RSD_SAMPLERATE RSD_SAMPLERATE #define RSD_CHANNELS RSD_CHANNELS #define RSD_HOST RSD_HOST #define RSD_PORT RSD_PORT @@ -125,7 +125,7 @@ enum rsd_settings /* Audio callback for rsd_set_callback. Return -1 to trigger an error in the stream. */ typedef ssize_t (*rsd_audio_callback_t)(void *data, size_t bytes, void *userdata); -/* Error callback. Signals caller that stream has been stopped, +/* Error callback. Signals caller that stream has been stopped, * either by audio callback returning -1 or stream was hung up. */ typedef void (*rsd_error_callback_t)(void *userdata); @@ -144,7 +144,7 @@ typedef struct rsound int conn_type; volatile int buffer_pointer; /* Obsolete, but kept for backwards header compatibility. */ - size_t buffer_size; + size_t buffer_size; fifo_buffer_t *fifo_buffer; volatile int thread_active; @@ -196,13 +196,13 @@ typedef struct rsound rsd_set_param(rd, RSD_HOST, "foohost"); *sets more params* rsd_start(rd); - rsd_write(rd, buf, size); + rsd_write(rd, buf, size); rsd_stop(rd); rsd_free(rd); */ int rsd_init (rsound_t **rd); -/* This is a simpler function that initializes an rsound struct, sets params as given, +/* This is a simpler function that initializes an rsound struct, sets params as given, and starts the stream. Should this function fail, the structure will stay uninitialized. Should NULL be passed in either host, port or ident, defaults will be used. */ @@ -211,29 +211,29 @@ int rsd_simple_start (rsound_t **rd, const char* host, const char* port, const c /* Sets params associated with an rsound_t. These options (int options) include: -RSD_HOST: Server to connect to. Expects (char *) in param. -If not set, will default to environmental variable RSD_SERVER or "localhost". +RSD_HOST: Server to connect to. Expects (char *) in param. +If not set, will default to environmental variable RSD_SERVER or "localhost". -RSD_PORT: Set port. Expects (char *) in param. +RSD_PORT: Set port. Expects (char *) in param. If not set, will default to environmental variable RSD_PORT or "12345". RSD_CHANNELS: Set number of audio channels. Expects (int *) in param. Mandatory. RSD_SAMPLERATE: Set samplerate of audio stream. Expects (int *) in param. Mandatory. -RSD_BUFSIZE: Sets internal buffersize for the stream. -Might be overridden if too small. +RSD_BUFSIZE: Sets internal buffersize for the stream. +Might be overridden if too small. Expects (int *) in param. Optional. -RSD_LATENCY: Sets maximum audio latency in milliseconds, -(must be used with rsd_delay_wait() or this will have no effect). -Most applications do not need this. -Might be overridden if too small. +RSD_LATENCY: Sets maximum audio latency in milliseconds, +(must be used with rsd_delay_wait() or this will have no effect). +Most applications do not need this. +Might be overridden if too small. Expects (int *) in param. Optional. -RSD_FORMAT: Sets sample format. -It defaults to S16_LE, so you probably will not use this. -Expects (int *) in param, with available values found in the format enum. +RSD_FORMAT: Sets sample format. +It defaults to S16_LE, so you probably will not use this. +Expects (int *) in param, with available values found in the format enum. If invalid format is given, param might be changed to reflect the sample format the library will use. RSD_IDENTITY: Sets an identity string associated with the client. @@ -244,14 +244,14 @@ Will be truncated if longer than 256 bytes. int rsd_set_param (rsound_t *rd, enum rsd_settings option, void* param); -/* Enables use of the callback interface. This must be set when stream is not active. - When callback is active, use of the blocking interface is disabled. - Only valid functions to call after rsd_start() is stopping the stream with either rsd_pause() or rsd_stop(). Calling any other function is undefined. - The callback is called at regular intervals and is asynchronous, so thread safety must be ensured by the caller. - If not enough data can be given to the callback, librsound will fill the rest of the callback data with silence. +/* Enables use of the callback interface. This must be set when stream is not active. + When callback is active, use of the blocking interface is disabled. + Only valid functions to call after rsd_start() is stopping the stream with either rsd_pause() or rsd_stop(). Calling any other function is undefined. + The callback is called at regular intervals and is asynchronous, so thread safety must be ensured by the caller. + If not enough data can be given to the callback, librsound will fill the rest of the callback data with silence. librsound will attempt to obey latency information given with RSD_LATENCY as given before calling rsd_start(). max_size signifies the maximum size that will ever be requested by librsound. Set this to 0 to let librsound decide the maximum size. - Should an error occur to the stream, err_callback will be called, and the stream will be stopped. The stream can be started again. + Should an error occur to the stream, err_callback will be called, and the stream will be stopped. The stream can be started again. Callbacks can be disabled by setting callbacks to NULL. */ @@ -260,37 +260,37 @@ void rsd_set_callback (rsound_t *rd, rsd_audio_callback_t callback, rsd_error_ca /* Lock and unlock the callback. When the callback lock is aquired, the callback is guaranteed to not be executing. The lock has to be unlocked afterwards. Attemping to call several rsd_callback_lock() in succession might cause a deadlock. - The lock should be held for as short period as possible. + The lock should be held for as short period as possible. Try to avoid calling code that may block when holding the lock. */ void rsd_callback_lock (rsound_t *rd); void rsd_callback_unlock (rsound_t *rd); -/* Establishes connection to server. Might fail if connection can't be established or that one of +/* Establishes connection to server. Might fail if connection can't be established or that one of the mandatory options isn't set in rsd_set_param(). This needs to be called after params have been set - with rsd_set_param(), and before rsd_write(). */ + with rsd_set_param(), and before rsd_write(). */ int rsd_start (rsound_t *rd); /* Shuts down the rsound data structures, but returns the file descriptor associated with the connection. - The control socket will be shut down. If this function returns a negative number, the exec failed, - but the data structures will not be teared down. + The control socket will be shut down. If this function returns a negative number, the exec failed, + but the data structures will not be teared down. Should a valid file descriptor be returned, it will always be blocking. This call will block until all internal buffers have been sent to the network. */ int rsd_exec (rsound_t *rd); -/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped. +/* Disconnects from server. All audio data still in network buffer and other buffers will be dropped. To continue playing, you will need to rsd_start() again. */ int rsd_stop (rsound_t *rd); -/* Writes from buf to the internal buffer. Might fail if no connection is established, +/* Writes from buf to the internal buffer. Might fail if no connection is established, or there was an unexpected error. This function will block until all data has been written to the buffer. This function will return the number of bytes written to the buffer, or 0 should it fail (disconnection from server). You will have to restart the stream again should this occur. */ size_t rsd_write (rsound_t *rd, const void* buf, size_t size); -/* Gets the position of the buffer pointer. - Not really interesting for normal applications. - Might be useful for implementing rsound on top of other blocking APIs. +/* Gets the position of the buffer pointer. + Not really interesting for normal applications. + Might be useful for implementing rsound on top of other blocking APIs. *NOTE* This function is deprecated, it should not be used in new applications. */ size_t rsd_pointer (rsound_t *rd); @@ -306,12 +306,12 @@ size_t rsd_delay_ms (rsound_t *rd); /* Returns bytes per sample */ int rsd_samplesize(rsound_t *rd); -/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY +/* Will sleep until latency of stream reaches maximum allowed latency defined earlier by rsd_set_param - RSD_LATENCY Useful for hard headed blocking I/O design where user defined latency is needed. If rsd_set_param hasn't been set with RSD_LATENCY, this function will do nothing. */ void rsd_delay_wait(rsound_t *rd); -/* Pauses or unpauses a stream. pause -> enable = 1 +/* Pauses or unpauses a stream. pause -> enable = 1 This function essentially calls on start() and stop(). This behavior might be changed later. */ int rsd_pause (rsound_t *rd, int enable); diff --git a/audio/drivers/rwebaudio.c b/audio/drivers/rwebaudio.c index 5a90e69233..3e819b2049 100644 --- a/audio/drivers/rwebaudio.c +++ b/audio/drivers/rwebaudio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2015 - Michael Lelli * Copyright (C) 2011-2017 - 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. diff --git a/audio/drivers/sdl_audio.c b/audio/drivers/sdl_audio.c index 49703948a2..31152a644b 100644 --- a/audio/drivers/sdl_audio.c +++ b/audio/drivers/sdl_audio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -93,7 +93,7 @@ static void *sdl_audio_init(const char *device, if (!sdl) return NULL; - /* We have to buffer up some data ourselves, so we let SDL + /* We have to buffer up some data ourselves, so we let SDL * carry approximately half of the latency. * * SDL double buffers audio and we do as well. */ @@ -119,7 +119,7 @@ static void *sdl_audio_init(const char *device, sdl->cond = scond_new(); #endif - RARCH_LOG("[SDL audio]: Requested %u ms latency, got %d ms\n", + RARCH_LOG("[SDL audio]: Requested %u ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / (*new_rate))); /* Create a buffer twice as big as needed and prefill the buffer. */ diff --git a/audio/drivers/tinyalsa.c b/audio/drivers/tinyalsa.c index 08e8ea4a1a..bb12d3a253 100644 --- a/audio/drivers/tinyalsa.c +++ b/audio/drivers/tinyalsa.c @@ -30,7 +30,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2017 - Charlton Head - * + * * 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. @@ -508,7 +508,7 @@ struct snd_pcm_sw_params struct snd_pcm_hw_params { unsigned int flags; - struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - + struct snd_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; struct snd_mask mres[5]; /* reserved masks */ struct snd_interval intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - @@ -2320,7 +2320,7 @@ tinyalsa_write(void *data, const void *buf_, size_t size_) } } - return written; + return written; } @@ -2366,7 +2366,7 @@ tinyalsa_start(void *data, bool is_shutdown) RARCH_ERR("[TINYALSA]: Failed to unpause.\n"); return false; } - + tinyalsa->is_paused = false; } @@ -2414,7 +2414,7 @@ static size_t tinyalsa_write_avail(void *data) static size_t tinyalsa_buffer_size(void *data) { tinyalsa_t *tinyalsa = (tinyalsa_t*)data; - + return tinyalsa->buffer_size; } diff --git a/audio/drivers/wasapi.c b/audio/drivers/wasapi.c index e11d8056e0..249ab3589d 100644 --- a/audio/drivers/wasapi.c +++ b/audio/drivers/wasapi.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -15,7 +15,7 @@ #include -#ifdef _WIN32_WINNT +#ifdef _WIN32_WINNT #undef _WIN32_WINNT #endif #define _WIN32_WINNT 0x0600 @@ -40,7 +40,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0 #ifdef __cplusplus #define _IMMDeviceCollection_Item(This,nDevice,ppdevice) (This)->Item(nDevice,ppdevice) -#define _IAudioClient_Start(This) ( (This)->Start() ) +#define _IAudioClient_Start(This) ( (This)->Start() ) #define _IAudioClient_Stop(This) ( (This)->Stop() ) #define _IAudioClient_GetCurrentPadding(This,pNumPaddingFrames) \ ( (This)->GetCurrentPadding(pNumPaddingFrames) ) @@ -62,7 +62,7 @@ DEFINE_PROPERTYKEY(PKEY_Device_FriendlyName, 0xa45c254e, 0xdf1c, 0x4efd, 0x80, 0 #define _IMMDeviceCollection_GetCount(This,cProps) ( (This)->GetCount(cProps) ) #else #define _IMMDeviceCollection_Item(This,nDevice,ppdevice) (This)->lpVtbl->Item(This,nDevice,ppdevice) -#define _IAudioClient_Start(This) ( (This)->lpVtbl -> Start(This) ) +#define _IAudioClient_Start(This) ( (This)->lpVtbl -> Start(This) ) #define _IAudioClient_Stop(This) ( (This)->lpVtbl -> Stop(This) ) #define _IAudioClient_GetCurrentPadding(This,pNumPaddingFrames) \ ( (This)->lpVtbl -> GetCurrentPadding(This,pNumPaddingFrames) ) @@ -163,7 +163,7 @@ static bool wasapi_check_device_id(IMMDevice *device, const char *id) id_length = MultiByteToWideChar(CP_ACP, 0, id, -1, dev_cmp_id, id_length); WASAPI_SR_CHECK(id_length > 0, "MultiByteToWideChar", goto error); - + hr = _IMMDevice_GetId(device, &dev_id); WASAPI_HR_CHECK(hr, "IMMDevice::GetId", goto error); @@ -306,7 +306,7 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device, bool float_fmt_res = *float_fmt; unsigned rate_res = *rate; HRESULT hr = _IMMDevice_Activate(device, - IID_IAudioClient, + IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); @@ -339,7 +339,7 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device, HRESULT hr; WASAPI_RELEASE(client); hr = _IMMDevice_Activate(device, - IID_IAudioClient, + IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); @@ -391,7 +391,7 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device, REFERENCE_TIME buffer_duration = 0; UINT32 buffer_length = 0; HRESULT hr = _IMMDevice_Activate(device, - IID_IAudioClient, + IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); @@ -433,7 +433,7 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device, WASAPI_RELEASE(client); hr = _IMMDevice_Activate(device, - IID_IAudioClient, + IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); @@ -452,7 +452,7 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device, { WASAPI_RELEASE(client); hr = _IMMDevice_Activate(device, - IID_IAudioClient, + IID_IAudioClient, CLSCTX_ALL, NULL, (void**)&client); WASAPI_HR_CHECK(hr, "IMMDevice::Activate", return NULL); @@ -669,7 +669,7 @@ static void *wasapi_init(const char *dev_id, unsigned rate, unsigned latency, error: WASAPI_RELEASE(w->renderer); - WASAPI_RELEASE(w->client); + WASAPI_RELEASE(w->client); WASAPI_RELEASE(w->device); if (w->write_event) CloseHandle(w->write_event); @@ -1045,7 +1045,7 @@ static size_t wasapi_write_avail(void *wh) hr = _IAudioClient_GetCurrentPadding(w->client, &padding); WASAPI_HR_CHECK(hr, "IAudioClient::GetCurrentPadding", return 0); - + return w->engine_buffer_size - padding * w->frame_size; } diff --git a/audio/drivers/xaudio.c b/audio/drivers/xaudio.c index cae0f8a289..f3c81a1741 100644 --- a/audio/drivers/xaudio.c +++ b/audio/drivers/xaudio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -69,7 +69,7 @@ struct xaudio2 virtual ~xaudio2() {} STDMETHOD_(void, OnBufferStart) (void *) {} - STDMETHOD_(void, OnBufferEnd) (void *) + STDMETHOD_(void, OnBufferEnd) (void *) { InterlockedDecrement((LONG volatile*)&buffers); SetEvent(hEvent); @@ -96,27 +96,27 @@ struct xaudio2 }; #ifndef __cplusplus -static void WINAPI voice_on_buffer_end(void *handle_, void *data) -{ - xaudio2_t *handle = (xaudio2_t*)handle_; - (void)data; - InterlockedDecrement((LONG volatile*)&handle->buffers); - SetEvent(handle->hEvent); -} +static void WINAPI voice_on_buffer_end(void *handle_, void *data) +{ + xaudio2_t *handle = (xaudio2_t*)handle_; + (void)data; + InterlockedDecrement((LONG volatile*)&handle->buffers); + SetEvent(handle->hEvent); +} -static void WINAPI dummy_voidp(void *handle, void *data) { (void)handle; (void)data; } -static void WINAPI dummy_nil(void *handle) { (void)handle; } -static void WINAPI dummy_uint32(void *handle, UINT32 dummy) { (void)handle; (void)dummy; } -static void WINAPI dummy_voidp_hresult(void *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; } +static void WINAPI dummy_voidp(void *handle, void *data) { (void)handle; (void)data; } +static void WINAPI dummy_nil(void *handle) { (void)handle; } +static void WINAPI dummy_uint32(void *handle, UINT32 dummy) { (void)handle; (void)dummy; } +static void WINAPI dummy_voidp_hresult(void *handle, void *data, HRESULT dummy) { (void)handle; (void)data; (void)dummy; } -const struct IXAudio2VoiceCallbackVtbl voice_vtable = { - dummy_uint32, - dummy_nil, - dummy_nil, - dummy_voidp, - voice_on_buffer_end, - dummy_voidp, - dummy_voidp_hresult, +const struct IXAudio2VoiceCallbackVtbl voice_vtable = { + dummy_uint32, + dummy_nil, + dummy_nil, + dummy_voidp, + voice_on_buffer_end, + dummy_voidp, + dummy_voidp_hresult, }; #endif @@ -225,9 +225,9 @@ static xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, xaudio2_set_wavefmt(&wfx, channels, samplerate); - if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2, - &handle->pSourceVoice, &wfx, - XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, + if (FAILED(IXAudio2_CreateSourceVoice(handle->pXAudio2, + &handle->pSourceVoice, &wfx, + XAUDIO2_VOICE_NOSRC, XAUDIO2_DEFAULT_FREQ_RATIO, (IXAudio2VoiceCallback*)handle, 0, 0))) goto error; @@ -240,7 +240,7 @@ static xaudio2_t *xaudio2_new(unsigned samplerate, unsigned channels, if (!handle->buf) goto error; - if (FAILED(IXAudio2SourceVoice_Start(handle->pSourceVoice, 0, + if (FAILED(IXAudio2SourceVoice_Start(handle->pSourceVoice, 0, XAUDIO2_COMMIT_NOW))) goto error; @@ -265,7 +265,7 @@ static size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_) { unsigned need = MIN(bytes, handle->bufsize - handle->bufptr); - memcpy(handle->buf + handle->write_buffer * + memcpy(handle->buf + handle->write_buffer * handle->bufsize + handle->bufptr, buffer, need); diff --git a/audio/drivers/xaudio.h b/audio/drivers/xaudio.h index 266f89a59c..4c03e60035 100644 --- a/audio/drivers/xaudio.h +++ b/audio/drivers/xaudio.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2010-2014 - OV2 - * + * * 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. @@ -58,7 +58,7 @@ DEFINE_IID(IXAudio2, 8bcf1f58, 9fe7, 4583, 8a, c6, e2, ad, c4, 65, c8, bb); #include #ifndef __cplusplus -#undef OPAQUE +#undef OPAQUE #define OPAQUE struct #endif @@ -131,7 +131,7 @@ typedef enum XAUDIO2_WINDOWS_PROCESSOR_SPECIFIER typedef enum XAUDIO2_FILTER_TYPE { LowPassFilter, BandPassFilter, - HighPassFilter + HighPassFilter } XAUDIO2_FILTER_TYPE; typedef struct XAUDIO2_DEVICE_DETAILS @@ -294,27 +294,27 @@ DECLARE_INTERFACE_(IXAudio2, IUnknown) #ifdef __cplusplus /* C++ hooks */ -#define IXAudio2_Initialize(handle,a,b) handle->Initialize(a, b) -#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, a, b) handle->SubmitSourceBuffer(a, b) -#define IXAudio2SourceVoice_Stop(handle, a, b) handle->Stop(a, b) -#define IXAudio2SourceVoice_DestroyVoice(handle) handle->DestroyVoice() -#define IXAudio2MasteringVoice_DestroyVoice(handle) handle->DestroyVoice() -#define IXAudio2_Release(handle) handle->Release() -#define IXAudio2_CreateSourceVoice(handle, a, b, c, d, e, f, g) handle->CreateSourceVoice(a, b, c, d, e, f, g) -#define IXAudio2_CreateMasteringVoice(handle, a, b, c, d, e, f) handle->CreateMasteringVoice(a, b, c, d, e, f) -#define IXAudio2SourceVoice_Start(handle, a, b) handle->Start(a, b) +#define IXAudio2_Initialize(handle,a,b) handle->Initialize(a, b) +#define IXAudio2SourceVoice_SubmitSourceBuffer(handle, a, b) handle->SubmitSourceBuffer(a, b) +#define IXAudio2SourceVoice_Stop(handle, a, b) handle->Stop(a, b) +#define IXAudio2SourceVoice_DestroyVoice(handle) handle->DestroyVoice() +#define IXAudio2MasteringVoice_DestroyVoice(handle) handle->DestroyVoice() +#define IXAudio2_Release(handle) handle->Release() +#define IXAudio2_CreateSourceVoice(handle, a, b, c, d, e, f, g) handle->CreateSourceVoice(a, b, c, d, e, f, g) +#define IXAudio2_CreateMasteringVoice(handle, a, b, c, d, e, f) handle->CreateMasteringVoice(a, b, c, d, e, f) +#define IXAudio2SourceVoice_Start(handle, a, b) handle->Start(a, b) #else /* C hooks */ -#define IXAudio2_Initialize(THIS,a,b) (THIS)->lpVtbl->Initialize(THIS, a, b) -#define IXAudio2_Release(THIS) (THIS)->lpVtbl->Release(THIS) -#define IXAudio2_CreateSourceVoice(THIS,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) (THIS)->lpVtbl->CreateSourceVoice(THIS, ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) -#define IXAudio2_CreateMasteringVoice(THIS,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) (THIS)->lpVtbl->CreateMasteringVoice(THIS, ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) -#define IXAudio2_GetDeviceCount(THIS, puCount) (THIS)->lpVtbl->GetDeviceCount(THIS, puCount) -#define IXAudio2_GetDeviceDetails(THIS, Index,pDeviceDetails) (THIS)->lpVtbl->GetDeviceDetails(THIS, Index, pDeviceDetails) -#define IXAudio2SourceVoice_Start(THIS, Flags, OperationSet) (THIS)->lpVtbl->Start(THIS, Flags, OperationSet) -#define IXAudio2SourceVoice_Stop(THIS, Flags, OperationSet) (THIS)->lpVtbl->Stop(THIS, Flags, OperationSet) -#define IXAudio2SourceVoice_SubmitSourceBuffer(THIS, pBuffer, pBufferWMA) (THIS)->lpVtbl->SubmitSourceBuffer(THIS, pBuffer, pBufferWMA) -#define IXAudio2SourceVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS) +#define IXAudio2_Initialize(THIS,a,b) (THIS)->lpVtbl->Initialize(THIS, a, b) +#define IXAudio2_Release(THIS) (THIS)->lpVtbl->Release(THIS) +#define IXAudio2_CreateSourceVoice(THIS,ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) (THIS)->lpVtbl->CreateSourceVoice(THIS, ppSourceVoice,pSourceFormat,Flags,MaxFrequencyRatio,pCallback,pSendList,pEffectChain) +#define IXAudio2_CreateMasteringVoice(THIS,ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) (THIS)->lpVtbl->CreateMasteringVoice(THIS, ppMasteringVoice,InputChannels,InputSampleRate,Flags,DeviceIndex,pEffectChain) +#define IXAudio2_GetDeviceCount(THIS, puCount) (THIS)->lpVtbl->GetDeviceCount(THIS, puCount) +#define IXAudio2_GetDeviceDetails(THIS, Index,pDeviceDetails) (THIS)->lpVtbl->GetDeviceDetails(THIS, Index, pDeviceDetails) +#define IXAudio2SourceVoice_Start(THIS, Flags, OperationSet) (THIS)->lpVtbl->Start(THIS, Flags, OperationSet) +#define IXAudio2SourceVoice_Stop(THIS, Flags, OperationSet) (THIS)->lpVtbl->Stop(THIS, Flags, OperationSet) +#define IXAudio2SourceVoice_SubmitSourceBuffer(THIS, pBuffer, pBufferWMA) (THIS)->lpVtbl->SubmitSourceBuffer(THIS, pBuffer, pBufferWMA) +#define IXAudio2SourceVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS) #define IXAudio2MasteringVoice_DestroyVoice(THIS) (THIS)->lpVtbl->DestroyVoice(THIS) #endif diff --git a/audio/drivers/xenon360_audio.c b/audio/drivers/xenon360_audio.c index b72e01fc4d..fdcd585572 100644 --- a/audio/drivers/xenon360_audio.c +++ b/audio/drivers/xenon360_audio.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -70,7 +70,7 @@ static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size) { while (xenon_sound_get_unplayed() >= MAX_BUFFER) { - /* libxenon doesn't have proper + /* libxenon doesn't have proper * synchronization primitives for this... */ udelay(50); } diff --git a/audio/drivers_resampler/cc_resampler.c b/audio/drivers_resampler/cc_resampler.c index b743338f10..5a3f920431 100644 --- a/audio/drivers_resampler/cc_resampler.c +++ b/audio/drivers_resampler/cc_resampler.c @@ -498,12 +498,12 @@ static void *resampler_CC_init(const struct resampler_config *config, rarch_CC_resampler_t *re = (rarch_CC_resampler_t*) memalign_alloc(32, sizeof(rarch_CC_resampler_t)); - /* TODO: lookup if NEON support can be detected at + /* TODO: lookup if NEON support can be detected at * runtime and a funcptr set at runtime for either * C codepath or NEON codepath. This will help out * Android. */ (void)mask; - (void)config; + (void)config; if (!re) return NULL; diff --git a/audio/librsound.c b/audio/librsound.c index 273fc13334..da2aaeaa86 100644 --- a/audio/librsound.c +++ b/audio/librsound.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -16,7 +16,7 @@ /* RSound - A PCM audio client/server * Copyright (C) 2010 - Hans-Kristian Arntzen - * + * * RSound 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. @@ -67,7 +67,7 @@ #include #include #include -#include +#include #include #include @@ -75,8 +75,8 @@ #include #include -/* - **************************************************************************** +/* + **************************************************************************** Naming convention. Functions for use in API are called rsd_*(), * internal function are called rsnd_*() * **************************************************************************** @@ -251,7 +251,7 @@ static int rsnd_connect_server( rsound_t *rd ) if ( rd->conn.ctl_socket < 0 ) goto error; - /* Uses non-blocking IO since it performed more deterministic with poll()/send() */ + /* Uses non-blocking IO since it performed more deterministic with poll()/send() */ #ifdef __CELLOS_LV2__ setsockopt(rd->conn.socket, SOL_SOCKET, SO_NBIO, &i, sizeof(int)); @@ -302,7 +302,7 @@ static int rsnd_send_header_info(rsound_t *rd) uint16_t temp16; uint32_t temp32; - /* These magic numbers represent the position of the elements in the wave header. + /* These magic numbers represent the position of the elements in the wave header. We can't simply send a wave struct over the network since the compiler is allowed to pad our structs as they like, so sizeof(waveheader) might not be similar on two different systems. */ @@ -353,7 +353,7 @@ static int rsnd_send_header_info(rsound_t *rd) } /* Since the values in the wave header we are interested in, are little endian (>_<), we need - to determine whether we're running it or not, so we can byte swap accordingly. + to determine whether we're running it or not, so we can byte swap accordingly. Could determine this compile time, but it was simpler to do it this way. */ // Fancy macros for embedding little endian values into the header. @@ -501,7 +501,7 @@ static int rsnd_get_backend_info ( rsound_t *rd ) // Can we read the last 8 bytes so we can use the protocol interface? // This is non-blocking. if ( rsnd_recv_chunk(rd->conn.socket, rsnd_header, RSND_HEADER_SIZE, 0) == RSND_HEADER_SIZE ) - rd->conn_type |= RSD_CONN_PROTO; + rd->conn_type |= RSD_CONN_PROTO; else { RSD_DEBUG("[RSound] Failed to get new proto.\n"); } @@ -515,7 +515,7 @@ static int rsnd_get_backend_info ( rsound_t *rd ) return 0; } -/* Makes sure that we're connected and done with wave header handshaking. Returns -1 on error, and 0 on success. +/* Makes sure that we're connected and done with wave header handshaking. Returns -1 on error, and 0 on success. This goes for all other functions in use. */ static int rsnd_create_connection(rsound_t *rd) { @@ -750,7 +750,7 @@ static int64_t rsnd_get_time_usec(void) /* Calculates how many bytes there are in total in the virtual buffer. This is calculated client side. It should be accurate enough unless we have big problems with buffer underruns. - This function is called by rsd_delay() to determine the latency. + This function is called by rsd_delay() to determine the latency. This function might be changed in the future to correctly determine latency from server. */ static void rsnd_drain(rsound_t *rd) { @@ -777,7 +777,7 @@ static void rsnd_drain(rsound_t *rd) } /* Tries to fill the buffer. Uses signals to determine when the buffer is ready to be filled. Should the thread not be active - it will treat this as an error. Crude implementation of a blocking FIFO. */ + it will treat this as an error. Crude implementation of a blocking FIFO. */ static size_t rsnd_fill_buffer(rsound_t *rd, const char *buf, size_t size) { @@ -851,7 +851,7 @@ static int rsnd_stop_thread(rsound_t *rd) sthread_join(rd->thread.thread); RSD_DEBUG("[RSound] Thread joined successfully.\n"); - + return 0; } else @@ -981,7 +981,7 @@ static int rsnd_close_ctl(rsound_t *rd) } -// Sends delay info request to server on the ctl socket. This code section isn't critical, and will work if it works. +// Sends delay info request to server on the ctl socket. This code section isn't critical, and will work if it works. // It will never block. static int rsnd_send_info_query(rsound_t *rd) { @@ -1111,7 +1111,7 @@ static void rsnd_thread ( void * thread_data ) // We only bother to check after 1 sec of audio has been played, as it might be quite inaccurate in the start of the stream. if ( (rd->conn_type & RSD_CONN_PROTO) && (rd->total_written > rd->channels * rd->rate * rd->samplesize) ) { - rsnd_send_info_query(rd); + rsnd_send_info_query(rd); rsnd_update_server_info(rd); } @@ -1263,7 +1263,7 @@ static void rsnd_cb_thread(void *thread_data) if ( (rd->conn_type & RSD_CONN_PROTO) && (rd->total_written > rd->channels * rd->rate * rd->samplesize) ) { - rsnd_send_info_query(rd); + rsnd_send_info_query(rd); rsnd_update_server_info(rd); } @@ -1304,7 +1304,7 @@ int rsd_stop(rsound_t *rd) const char buf[] = "RSD 5 STOP"; - // Do not really care about errors here. + // Do not really care about errors here. // The socket will be closed down in any case in rsnd_reset(). rsnd_send_chunk(rd->conn.ctl_socket, buf, strlen(buf), 0); @@ -1325,7 +1325,7 @@ size_t rsd_write( rsound_t *rsound, const void* buf, size_t size) while ( written < size ) { - size_t write_size = (size - written) > max_write ? max_write : (size - written); + size_t write_size = (size - written) > max_write ? max_write : (size - written); size_t result = rsnd_fill_buffer(rsound, (const char*)buf + written, write_size); if (result == 0) @@ -1454,7 +1454,7 @@ int rsd_set_param(rsound_t *rd, enum rsd_settings option, void* param) rd->max_latency = *((int*)param); break; - // Checks if format is valid. + // Checks if format is valid. case RSD_FORMAT: rd->format = (uint16_t)(*((int*)param)); rd->samplesize = rsnd_format_to_samplesize(rd->format); @@ -1509,7 +1509,7 @@ size_t rsd_pointer(rsound_t *rsound) retro_assert(rsound != NULL); int ptr; - ptr = rsnd_get_ptr(rsound); + ptr = rsnd_get_ptr(rsound); return ptr; } diff --git a/autosave.h b/autosave.h index 39cfe8a7a1..1421d60436 100644 --- a/autosave.h +++ b/autosave.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - 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. diff --git a/bootstrap/psp1/kernel_functions_prx/main.c b/bootstrap/psp1/kernel_functions_prx/main.c index 335b156097..08ae0bf0ba 100644 --- a/bootstrap/psp1/kernel_functions_prx/main.c +++ b/bootstrap/psp1/kernel_functions_prx/main.c @@ -66,7 +66,7 @@ int module_start(SceSize args, void *argp) (void)argp; buttons = 0; - thread_active = 0; + thread_active = 0; main_thread_id = sceKernelCreateThread("main Thread", main_thread, 0x11, 0x200, 0, NULL); if (main_thread >= 0) diff --git a/bootstrap/vita/threading.c b/bootstrap/vita/threading.c index cceca6b30a..8b0d10aa2a 100644 --- a/bootstrap/vita/threading.c +++ b/bootstrap/vita/threading.c @@ -34,7 +34,7 @@ int __vita_delete_thread_reent(int thid) // We only need to cleanup if reent is allocated, i.e. if it's on our TLS // We also don't need to clean up the global reent struct _reent **on_tls = NULL; - + if (thid == 0) on_tls = TLS_REENT_PTR; else @@ -141,16 +141,16 @@ struct _reent *__getreent_for_thread(int thid) { // A pointer to our reent should be on the TLS struct _reent **on_tls = NULL; - + if (thid == 0) on_tls = TLS_REENT_PTR; else - on_tls = TLS_REENT_THID_PTR(thid); - + on_tls = TLS_REENT_THID_PTR(thid); + if (*on_tls) { return *on_tls; } - + sceKernelLockMutex(_newlib_reent_mutex, 1, 0); // If it's not on the TLS this means the thread doesn't have a reent allocated yet diff --git a/camera/camera_driver.c b/camera/camera_driver.c index 34a5a31d88..0ee9a7f878 100644 --- a/camera/camera_driver.c +++ b/camera/camera_driver.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -139,7 +139,7 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data) case RARCH_CAMERA_CTL_OWNS_DRIVER: return camera_driver_data_own; case RARCH_CAMERA_CTL_SET_ACTIVE: - camera_driver_active = true; + camera_driver_active = true; break; case RARCH_CAMERA_CTL_FIND_DRIVER: { @@ -174,10 +174,10 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data) } break; case RARCH_CAMERA_CTL_UNSET_ACTIVE: - camera_driver_active = false; + camera_driver_active = false; break; case RARCH_CAMERA_CTL_IS_ACTIVE: - return camera_driver_active; + return camera_driver_active; case RARCH_CAMERA_CTL_DEINIT: if (camera_data && camera_driver) { @@ -191,8 +191,8 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data) camera_data = NULL; break; case RARCH_CAMERA_CTL_STOP: - if ( camera_driver - && camera_driver->stop + if ( camera_driver + && camera_driver->stop && camera_data) camera_driver->stop(camera_data); break; @@ -243,6 +243,6 @@ bool camera_driver_ctl(enum rarch_camera_ctl_state state, void *data) default: break; } - + return true; } diff --git a/camera/camera_driver.h b/camera/camera_driver.h index a916165689..25bbc71d38 100644 --- a/camera/camera_driver.h +++ b/camera/camera_driver.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/camera/drivers/android.c b/camera/drivers/android.c index 2ee7541e33..ab17640155 100644 --- a/camera/drivers/android.c +++ b/camera/drivers/android.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -152,7 +152,7 @@ static void android_camera_stop(void *data) CALL_VOID_METHOD(env, android_app->activity->clazz, androidcamera->onCameraStop); - + if (androidcamera->tex) video_driver_texture_unload((uintptr_t*)&androidcamera->tex); } @@ -171,12 +171,12 @@ static bool android_camera_poll(void *data, (void)frame_raw_cb; - CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz, + CALL_BOOLEAN_METHOD(env, newFrame, android_app->activity->clazz, androidcamera->onCameraPoll); if (newFrame) { - /* FIXME: Identity for now. Use proper texture matrix as + /* FIXME: Identity for now. Use proper texture matrix as * returned by Android Camera. */ static const float affine[] = { 1.0f, 0.0f, 0.0f, diff --git a/camera/drivers/nullcamera.c b/camera/drivers/nullcamera.c index bb0cc82c5c..332a671e34 100644 --- a/camera/drivers/nullcamera.c +++ b/camera/drivers/nullcamera.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2012-2015 - Michael Lelli * Copyright (C) 2011-2017 - 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. diff --git a/camera/drivers/rwebcam.c b/camera/drivers/rwebcam.c index c630f0f4c1..a7a39cab36 100644 --- a/camera/drivers/rwebcam.c +++ b/camera/drivers/rwebcam.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2012-2015 - Michael Lelli * Copyright (C) 2011-2017 - 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. diff --git a/camera/drivers/video4linux2.c b/camera/drivers/video4linux2.c index 2be990821e..1fa94fcfa6 100644 --- a/camera/drivers/video4linux2.c +++ b/camera/drivers/video4linux2.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. diff --git a/cheevos/badges.c b/cheevos/badges.c index 5ac1112222..b51ae3669f 100644 --- a/cheevos/badges.c +++ b/cheevos/badges.c @@ -1,55 +1,55 @@ -#include -#include -#include - -#include "../file_path_special.h" -#include "../configuration.h" -#include "../verbosity.h" -#include "../network/net_http_special.h" - -#include "badges.h" - -badges_ctx_t badges_ctx; - -bool badge_exists(const char* filepath) -{ - if(path_file_exists(filepath)) - return true; - else - return false; -} - -void set_badge_menu_texture(badges_ctx_t * badges, int i) -{ - char fullpath[PATH_MAX_LENGTH]; - const char * locked_suffix = (badges->badge_locked[i] == true) ? "_lock.png" : ".png"; - - unsigned int bufferSize = 16; - /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ - char badge_file[bufferSize]; - - snprintf(badge_file, bufferSize, "%s", badges->badge_id_list[i]); - strcat(badge_file, locked_suffix); - - fill_pathname_application_special(fullpath, - PATH_MAX_LENGTH * sizeof(char), - APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); - - menu_display_reset_textures_list(badge_file, fullpath, &badges->menu_texture_list[i],TEXTURE_FILTER_MIPMAP_LINEAR); -} - -void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active) -{ - badge_struct->badge_id_list[id] = badge_id; - badge_struct->badge_locked[id] = active; - set_badge_menu_texture(badge_struct, id); -} - -menu_texture_item get_badge_texture (int id) -{ - settings_t *settings = config_get_ptr(); - if (!settings->bools.cheevos_badges_enable) - return (menu_texture_item)NULL; - - return badges_ctx.menu_texture_list[id]; -} +#include +#include +#include + +#include "../file_path_special.h" +#include "../configuration.h" +#include "../verbosity.h" +#include "../network/net_http_special.h" + +#include "badges.h" + +badges_ctx_t badges_ctx; + +bool badge_exists(const char* filepath) +{ + if(path_file_exists(filepath)) + return true; + else + return false; +} + +void set_badge_menu_texture(badges_ctx_t * badges, int i) +{ + char fullpath[PATH_MAX_LENGTH]; + const char * locked_suffix = (badges->badge_locked[i] == true) ? "_lock.png" : ".png"; + + unsigned int bufferSize = 16; + /* TODO/FIXME - variable length forbidden in C89 - rewrite this! */ + char badge_file[bufferSize]; + + snprintf(badge_file, bufferSize, "%s", badges->badge_id_list[i]); + strcat(badge_file, locked_suffix); + + fill_pathname_application_special(fullpath, + PATH_MAX_LENGTH * sizeof(char), + APPLICATION_SPECIAL_DIRECTORY_THUMBNAILS_CHEEVOS_BADGES); + + menu_display_reset_textures_list(badge_file, fullpath, &badges->menu_texture_list[i],TEXTURE_FILTER_MIPMAP_LINEAR); +} + +void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active) +{ + badge_struct->badge_id_list[id] = badge_id; + badge_struct->badge_locked[id] = active; + set_badge_menu_texture(badge_struct, id); +} + +menu_texture_item get_badge_texture (int id) +{ + settings_t *settings = config_get_ptr(); + if (!settings->bools.cheevos_badges_enable) + return (menu_texture_item)NULL; + + return badges_ctx.menu_texture_list[id]; +} diff --git a/cheevos/badges.h b/cheevos/badges.h index 57a8de6ed2..05fe875a2a 100644 --- a/cheevos/badges.h +++ b/cheevos/badges.h @@ -1,29 +1,29 @@ -#ifndef __RARCH_BADGE_H -#define __RARCH_BADGE_H - -#include "../menu/menu_driver.h" - -#include - -RETRO_BEGIN_DECLS - -#define CHEEVOS_BADGE_LIMIT 256 - -typedef struct -{ - bool badge_locked[CHEEVOS_BADGE_LIMIT]; - const char * badge_id_list[CHEEVOS_BADGE_LIMIT]; - menu_texture_item menu_texture_list[CHEEVOS_BADGE_LIMIT]; -} badges_ctx_t; - -bool badge_exists(const char* filepath); -void set_badge_menu_texture(badges_ctx_t * badges, int i); -extern void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active); -extern menu_texture_item get_badge_texture(int id); - -extern badges_ctx_t badges_ctx; -static badges_ctx_t new_badges_ctx; - -RETRO_END_DECLS - -#endif +#ifndef __RARCH_BADGE_H +#define __RARCH_BADGE_H + +#include "../menu/menu_driver.h" + +#include + +RETRO_BEGIN_DECLS + +#define CHEEVOS_BADGE_LIMIT 256 + +typedef struct +{ + bool badge_locked[CHEEVOS_BADGE_LIMIT]; + const char * badge_id_list[CHEEVOS_BADGE_LIMIT]; + menu_texture_item menu_texture_list[CHEEVOS_BADGE_LIMIT]; +} badges_ctx_t; + +bool badge_exists(const char* filepath); +void set_badge_menu_texture(badges_ctx_t * badges, int i); +extern void set_badge_info (badges_ctx_t *badge_struct, int id, const char *badge_id, bool active); +extern menu_texture_item get_badge_texture(int id); + +extern badges_ctx_t badges_ctx; +static badges_ctx_t new_badges_ctx; + +RETRO_END_DECLS + +#endif diff --git a/cheevos/cheevos.c b/cheevos/cheevos.c index 5d1c7515ac..827cd2290a 100644 --- a/cheevos/cheevos.c +++ b/cheevos/cheevos.c @@ -3163,7 +3163,7 @@ static int cheevos_iterate(coro_t* coro) { settings_t *settings = config_get_ptr(); - if (!string_is_equal(settings->arrays.menu_driver, "xmb") || + if (!string_is_equal(settings->arrays.menu_driver, "xmb") || !settings->bools.cheevos_badges_enable) CORO_RET(); } @@ -3182,7 +3182,7 @@ static int cheevos_iterate(coro_t* coro) if (!path_is_directory(CHEEVOS_VAR_BADGE_BASE_PATH)) path_mkdir(CHEEVOS_VAR_BADGE_BASE_PATH); CORO_YIELD(); - if (CHEEVOS_VAR_J == 0) + if (CHEEVOS_VAR_J == 0) snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s.png", CHEEVOS_VAR_CHEEVO_CURR->badge); else snprintf(CHEEVOS_VAR_BADGE_NAME, sizeof(CHEEVOS_VAR_BADGE_NAME), "%s_lock.png", CHEEVOS_VAR_CHEEVO_CURR->badge); diff --git a/cheevos/var.c b/cheevos/var.c index 45ae9ac866..e0e6d5c6d8 100644 --- a/cheevos/var.c +++ b/cheevos/var.c @@ -256,7 +256,7 @@ void cheevos_var_patch_addr(cheevos_var_t* var, cheevos_console_t console) else { unsigned i; - + for (i = 0; i < 4; i++) { retro_ctx_memory_info_t meminfo; @@ -352,7 +352,7 @@ unsigned cheevos_var_get_value(cheevos_var_t* var) case CHEEVOS_VAR_TYPE_VALUE_COMP: value = var->value; break; - + case CHEEVOS_VAR_TYPE_ADDRESS: case CHEEVOS_VAR_TYPE_DELTA_MEM: memory = cheevos_var_get_memory(var); diff --git a/command.c b/command.c index 67fa8014c5..7b01a2b0d9 100644 --- a/command.c +++ b/command.c @@ -610,7 +610,7 @@ static void command_stdin_poll(command_t *handle) handle->stdin_buf_ptr += ret; handle->stdin_buf[handle->stdin_buf_ptr] = '\0'; - last_newline = + last_newline = strrchr(handle->stdin_buf, '\n'); if (!last_newline) @@ -1028,7 +1028,7 @@ static void command_event_init_controllers(void) break; case RETRO_DEVICE_JOYPAD: /* Ideally these checks shouldn't be required but if we always - * call core_set_controller_port_device input won't work on + * call core_set_controller_port_device input won't work on * cores that don't set port information properly */ if (info && info->ports.size != 0 && i < info->ports.size) set_controller = true; @@ -1126,7 +1126,7 @@ static void command_event_load_auto_state(void) msg_hash_to_str(MSG_AUTOLOADING_SAVESTATE_FROM), savestate_name_auto, ret ? "succeeded" : "failed"); RARCH_LOG("%s\n", msg); - + free(savestate_name_auto); return; @@ -1338,7 +1338,7 @@ static bool command_event_save_auto_state(void) bool is_inited = false; char *savestate_name_auto = (char*) calloc(PATH_MAX_LENGTH, sizeof(*savestate_name_auto)); - size_t + size_t savestate_name_auto_size = PATH_MAX_LENGTH * sizeof(char); settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); @@ -1383,7 +1383,7 @@ static bool command_event_save_config( char *s, size_t len) { bool path_exists = !string_is_empty(config_path); - const char *str = path_exists ? config_path : + const char *str = path_exists ? config_path : path_get(RARCH_PATH_CONFIG); if (path_exists && config_save_file(config_path)) @@ -1713,7 +1713,7 @@ void command_playlist_push_write( if (!playlist) return; - + if (playlist_push( playlist, path, diff --git a/command.h b/command.h index 286383fc83..858fcd820f 100644 --- a/command.h +++ b/command.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2016 - Brad Parker - * + * * 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. diff --git a/configuration.h b/configuration.h index c94b215209..881e94afee 100644 --- a/configuration.h +++ b/configuration.h @@ -38,7 +38,7 @@ { \ settings->modified = true; \ var = newvar; \ -} +} #define configuration_set_uint(settings, var, newvar) \ { \ diff --git a/core.h b/core.h index 08ec2e1f08..35878206b4 100644 --- a/core.h +++ b/core.h @@ -30,14 +30,14 @@ RETRO_BEGIN_DECLS enum { - /* Polling is performed before + /* Polling is performed before * call to retro_run. */ POLL_TYPE_EARLY = 0, /* Polling is performed when requested. */ POLL_TYPE_NORMAL, - /* Polling is performed on first call to + /* Polling is performed on first call to * retro_input_state per frame. */ POLL_TYPE_LATE }; @@ -65,7 +65,7 @@ typedef struct rarch_system_info const char *input_desc_btn[MAX_USERS][RARCH_FIRST_META_KEY]; char valid_extensions[255]; - struct retro_disk_control_callback disk_control_cb; + struct retro_disk_control_callback disk_control_cb; struct retro_location_callback location_cb; struct @@ -79,7 +79,7 @@ typedef struct rarch_system_info struct retro_controller_info *data; unsigned size; } ports; - + rarch_memory_map_t mmaps; } rarch_system_info_t; diff --git a/core_info.c b/core_info.c index c2989d883b..2194e29648 100644 --- a/core_info.c +++ b/core_info.c @@ -214,7 +214,7 @@ static bool core_info_list_iterate( fill_pathname_join(s, (!string_is_empty(settings->paths.path_libretro_info)) ? - settings->paths.path_libretro_info : + settings->paths.path_libretro_info : settings->paths.directory_libretro, info_path_base, len); @@ -255,9 +255,9 @@ static core_info_list_t *core_info_list_new(const char *path) info_path[0] = '\0'; - if ( + if ( core_info_list_iterate(info_path, info_path_size, - contents, i) + contents, i) && path_is_valid(info_path)) { char *tmp = NULL; @@ -270,14 +270,14 @@ static core_info_list_t *core_info_list_new(const char *path) if (!conf) continue; - if (config_get_string(conf, "display_name", &tmp) + if (config_get_string(conf, "display_name", &tmp) && !string_is_empty(tmp)) { core_info[i].display_name = strdup(tmp); free(tmp); tmp = NULL; } - if (config_get_string(conf, "corename", &tmp) + if (config_get_string(conf, "corename", &tmp) && !string_is_empty(tmp)) { core_info[i].core_name = strdup(tmp); @@ -285,7 +285,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "systemname", &tmp) + if (config_get_string(conf, "systemname", &tmp) && !string_is_empty(tmp)) { core_info[i].systemname = strdup(tmp); @@ -293,7 +293,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "manufacturer", &tmp) + if (config_get_string(conf, "manufacturer", &tmp) && !string_is_empty(tmp)) { core_info[i].system_manufacturer = strdup(tmp); @@ -305,7 +305,7 @@ static core_info_list_t *core_info_list_new(const char *path) core_info[i].firmware_count = count; - if (config_get_string(conf, "supported_extensions", &tmp) + if (config_get_string(conf, "supported_extensions", &tmp) && !string_is_empty(tmp)) { core_info[i].supported_extensions = strdup(tmp); @@ -316,7 +316,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "authors", &tmp) + if (config_get_string(conf, "authors", &tmp) && !string_is_empty(tmp)) { core_info[i].authors = strdup(tmp); @@ -327,7 +327,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "permissions", &tmp) + if (config_get_string(conf, "permissions", &tmp) && !string_is_empty(tmp)) { core_info[i].permissions = strdup(tmp); @@ -338,7 +338,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "license", &tmp) + if (config_get_string(conf, "license", &tmp) && !string_is_empty(tmp)) { core_info[i].licenses = strdup(tmp); @@ -349,7 +349,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "categories", &tmp) + if (config_get_string(conf, "categories", &tmp) && !string_is_empty(tmp)) { core_info[i].categories = strdup(tmp); @@ -360,7 +360,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "database", &tmp) + if (config_get_string(conf, "database", &tmp) && !string_is_empty(tmp)) { core_info[i].databases = strdup(tmp); @@ -371,7 +371,7 @@ static core_info_list_t *core_info_list_new(const char *path) tmp = NULL; } - if (config_get_string(conf, "notes", &tmp) + if (config_get_string(conf, "notes", &tmp) && !string_is_empty(tmp)) { core_info[i].notes = strdup(tmp); diff --git a/core_info.h b/core_info.h index a151091673..c058e8d937 100644 --- a/core_info.h +++ b/core_info.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. diff --git a/core_type.h b/core_type.h index 532b4e4fa6..e4a66058e5 100644 --- a/core_type.h +++ b/core_type.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -16,7 +16,7 @@ #ifndef __CORE_TYPE_H #define __CORE_TYPE_H -enum rarch_core_type +enum rarch_core_type { CORE_TYPE_PLAIN = 0, CORE_TYPE_DUMMY, diff --git a/cores/dynamic_dummy.c b/cores/dynamic_dummy.c index e5b3397f48..ad61faff97 100644 --- a/cores/dynamic_dummy.c +++ b/cores/dynamic_dummy.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. diff --git a/cores/internal_cores.h b/cores/internal_cores.h index 69c698d3f2..aa756ed349 100644 --- a/cores/internal_cores.h +++ b/cores/internal_cores.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. diff --git a/cores/libretro-ffmpeg/ffmpeg_core.c b/cores/libretro-ffmpeg/ffmpeg_core.c index f6ba5e51dd..1842f59809 100644 --- a/cores/libretro-ffmpeg/ffmpeg_core.c +++ b/cores/libretro-ffmpeg/ffmpeg_core.c @@ -214,7 +214,7 @@ void CORE_PREFIX(retro_init)(void) av_register_all(); #if 0 - /* FIXME: Occasionally crashes inside libavdevice + /* FIXME: Occasionally crashes inside libavdevice * for some odd reason on reentrancy. Likely a libavdevice bug. */ avdevice_register_all(); #endif @@ -548,7 +548,7 @@ void CORE_PREFIX(retro_run)(void) frame_cnt++; - /* Have to decode audio before video + /* Have to decode audio before video * incase there are PTS fuckups due * to seeking. */ if (audio_streams_num > 0) @@ -679,20 +679,20 @@ void CORE_PREFIX(retro_run)(void) if (!temporal_interpolation) mix_factor = 1.0f; - + glBindFramebuffer(GL_FRAMEBUFFER, hw_render.get_current_framebuffer()); glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT); glViewport(0, 0, media.width, media.height); glUseProgram(prog); - + glUniform1f(mix_loc, mix_factor); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, frames[1].tex); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, frames[0].tex); - - + + glBindBuffer(GL_ARRAY_BUFFER, vbo); glVertexAttribPointer(vertex_loc, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), (const GLvoid*)(0 * sizeof(GLfloat))); @@ -701,17 +701,17 @@ void CORE_PREFIX(retro_run)(void) glEnableVertexAttribArray(vertex_loc); glEnableVertexAttribArray(tex_loc); glBindBuffer(GL_ARRAY_BUFFER, 0); - + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); glDisableVertexAttribArray(vertex_loc); glDisableVertexAttribArray(tex_loc); - + glUseProgram(0); glActiveTexture(GL_TEXTURE1); glBindTexture(GL_TEXTURE_2D, 0); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); - + CORE_PREFIX(video_cb)(RETRO_HW_FRAME_BUFFER_VALID, media.width, media.height, media.width * sizeof(uint32_t)); } @@ -731,10 +731,10 @@ void CORE_PREFIX(retro_run)(void) while (frames) { unsigned to_read = frames; - + /* FFT size we use (1 << 11). Really shouldn't happen, * unless we use a crazy high sample rate. */ - if (to_read > (1 << 11)) + if (to_read > (1 << 11)) to_read = 1 << 11; fft_step_fft(fft, buffer, to_read); @@ -861,7 +861,7 @@ static bool open_codecs(void) break; case AVMEDIA_TYPE_VIDEO: - if ( !vctx + if ( !vctx && !codec_is_image(fctx->streams[i]->codec->codec_id)) { if (!open_codec(&vctx, i)) @@ -872,7 +872,7 @@ static bool open_codecs(void) case AVMEDIA_TYPE_SUBTITLE: #ifdef HAVE_SSA - if ( subtitle_streams_num < MAX_STREAMS + if ( subtitle_streams_num < MAX_STREAMS && codec_id_is_ass(fctx->streams[i]->codec->codec_id)) { int size; @@ -923,7 +923,7 @@ static bool init_media_info(void) { media.width = vctx->width; media.height = vctx->height; - media.aspect = (float)vctx->width * + media.aspect = (float)vctx->width * av_q2d(vctx->sample_aspect_ratio) / vctx->height; } @@ -1149,7 +1149,7 @@ static void render_ass_img(AVFrame *conv_frame, ASS_Image *img) dst_g = (g * src_alpha + dst_g * dst_alpha) >> 8; dst_b = (b * src_alpha + dst_b * dst_alpha) >> 8; - dst[x] = (0xffu << 24) | (dst_r << 16) | + dst[x] = (0xffu << 24) | (dst_r << 16) | (dst_g << 8) | (dst_b << 0); } } @@ -1171,7 +1171,7 @@ static void decode_thread(void *data) struct SwsContext *sws = NULL; (void)data; - + if (video_stream >= 0) sws = sws_getCachedContext(NULL, media.width, media.height, vctx->pix_fmt, @@ -1295,7 +1295,7 @@ static void decode_thread(void *data) int stride; unsigned y; const uint8_t *src = NULL; - + fifo_write(video_decode_fifo, &pts, sizeof(pts)); src = conv_frame->data[0]; stride = conv_frame->linesize[0]; @@ -1377,8 +1377,8 @@ static void context_destroy(void) #include "gl_shaders/ffmpeg.glsl.vert.h" -/* OpenGL ES note about main() - Get format as GL_RGBA/GL_UNSIGNED_BYTE. - * Assume little endian, so we get ARGB -> BGRA byte order, and +/* OpenGL ES note about main() - Get format as GL_RGBA/GL_UNSIGNED_BYTE. + * Assume little endian, so we get ARGB -> BGRA byte order, and * we have to swizzle to .BGR. */ #ifdef HAVE_OPENGLES #include "gl_shaders/ffmpeg_es.glsl.frag.h" @@ -1445,7 +1445,7 @@ static void context_reset(void) #if !defined(HAVE_OPENGLES) glGenBuffers(1, &frames[i].pbo); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, frames[i].pbo); - glBufferData(GL_PIXEL_UNPACK_BUFFER, media.width + glBufferData(GL_PIXEL_UNPACK_BUFFER, media.width * media.height * sizeof(uint32_t), NULL, GL_STREAM_DRAW); glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); #endif @@ -1611,7 +1611,7 @@ bool CORE_PREFIX(retro_load_game)(const struct retro_game_info *info) if (video_stream >= 0 || is_fft) { - video_decode_fifo = fifo_new(media.width + video_decode_fifo = fifo_new(media.width * media.height * sizeof(uint32_t) * 32); #if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) diff --git a/cores/libretro-ffmpeg/ffmpeg_fft.c b/cores/libretro-ffmpeg/ffmpeg_fft.c index 32405a0dea..8d8d22ba12 100644 --- a/cores/libretro-ffmpeg/ffmpeg_fft.c +++ b/cores/libretro-ffmpeg/ffmpeg_fft.c @@ -45,7 +45,7 @@ struct Pass GLuint parameter_tex; }; -struct GLFFT +struct GLFFT { GLuint ms_rb_color; GLuint ms_rb_ds; @@ -102,7 +102,7 @@ static GLuint fft_compile_shader(fft_t *fft, GLenum type, const char *source) glShaderSource(shader, 1, (const GLchar**)&source, NULL); glCompileShader(shader); - + glGetShaderiv(shader, GL_COMPILE_STATUS, &status); if (!status) @@ -153,7 +153,7 @@ typedef float stub_matrix4x4[4][4]; static INLINE unsigned log2i(unsigned x) { unsigned res; - + for (res = 0; x; x >>= 1) res++; return res - 1; @@ -297,7 +297,7 @@ static void fft_init(fft_t *fft) glUniform1i(glGetUniformLocation(fft->prog_complex, "sTexture"), 0); glUniform1i(glGetUniformLocation(fft->prog_complex, "sParameterTexture"), 1); glUniform4fv(glGetUniformLocation(fft->prog_complex, "uOffsetScale"), 1, unity); - + glUseProgram(fft->prog_resolve); glUniform1i(glGetUniformLocation(fft->prog_resolve, "sFFT"), 0); glUniform4fv(glGetUniformLocation(fft->prog_resolve, "uOffsetScale"), 1, unity); @@ -478,7 +478,7 @@ static bool fft_context_reset(fft_t *fft, unsigned fft_steps, return true; } -/* GLFFT requires either GLES3 or +/* GLFFT requires either GLES3 or * desktop GL with ES3_compat (supported by MESA on Linux) extension. */ fft_t *fft_new(unsigned fft_steps, rglgen_proc_address_t proc) { @@ -621,14 +621,14 @@ void fft_step_fft(fft_t *fft, const GLshort *audio_buffer, unsigned frames) if (i == fft->steps - 1) { glBindFramebuffer(GL_FRAMEBUFFER, fft->output.fbo); - glUniform1i(glGetUniformLocation(i == 0 + glUniform1i(glGetUniformLocation(i == 0 ? fft->prog_real : fft->prog_complex, "uViewportOffset"), fft->output_ptr); glViewport(0, fft->output_ptr, fft->size, 1); } else { - glUniform1i(glGetUniformLocation(i == 0 + glUniform1i(glGetUniformLocation(i == 0 ? fft->prog_real : fft->prog_complex, "uViewportOffset"), 0); glBindFramebuffer(GL_FRAMEBUFFER, fft->passes[i].target.fbo); glClear(GL_COLOR_BUFFER_BIT); diff --git a/cores/libretro-ffmpeg/gl_shaders/ffmpeg_es.glsl.frag.h b/cores/libretro-ffmpeg/gl_shaders/ffmpeg_es.glsl.frag.h index 49f4289a00..012a5c7ff0 100644 --- a/cores/libretro-ffmpeg/gl_shaders/ffmpeg_es.glsl.frag.h +++ b/cores/libretro-ffmpeg/gl_shaders/ffmpeg_es.glsl.frag.h @@ -7,7 +7,7 @@ static const char *fragment_source = GLSL( uniform float uMix; void main() { - gl_FragColor = vec4(pow(mix(pow(texture2D(sTex0, vTex).bgr, vec3(2.2)), pow(texture2D(sTex1, vTex).bgr, vec3(2.2)), uMix), vec3(1.0 / 2.2)), 1.0); + gl_FragColor = vec4(pow(mix(pow(texture2D(sTex0, vTex).bgr, vec3(2.2)), pow(texture2D(sTex1, vTex).bgr, vec3(2.2)), uMix), vec3(1.0 / 2.2)), 1.0); } ); diff --git a/cores/libretro-ffmpeg/gl_shaders/fft_heightmap.glsl.vert.h b/cores/libretro-ffmpeg/gl_shaders/fft_heightmap.glsl.vert.h index a5ea0adb2e..85fec8f668 100644 --- a/cores/libretro-ffmpeg/gl_shaders/fft_heightmap.glsl.vert.h +++ b/cores/libretro-ffmpeg/gl_shaders/fft_heightmap.glsl.vert.h @@ -21,7 +21,7 @@ static const char *fft_vertex_program_heightmap = GLSL_300( float lod = log2(world_pos.z + 1.0) - 6.0; vec4 heights = textureLod(sHeight, tex_coord, lod); - + float cangle = cos(angle); float sangle = sin(angle); diff --git a/cores/libretro-imageviewer/image_core.c b/cores/libretro-imageviewer/image_core.c index fdc28b9088..2c562b3e5f 100644 --- a/cores/libretro-imageviewer/image_core.c +++ b/cores/libretro-imageviewer/image_core.c @@ -274,7 +274,7 @@ bool IMAGE_CORE_PREFIX(retro_load_game)(const struct retro_game_info *info) dir_list_sort(file_list, false); free(dir); - + if (!IMAGE_CORE_PREFIX(environ_cb)(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt)) { if (IMAGE_CORE_PREFIX(log_cb)) @@ -437,7 +437,7 @@ void IMAGE_CORE_PREFIX(retro_run)(void) { uint32_t pixel = *buf; uint32_t a = pixel >> 24; - + if (a == 255) *buf = (pixel & 0x0000ff00) | ((pixel << 16) & 0x00ff0000) | ((pixel >> 16) & 0x000000ff); else @@ -446,11 +446,11 @@ void IMAGE_CORE_PREFIX(retro_run)(void) uint32_t g = (pixel & 0x00ff00) >> 8; uint32_t b = (pixel & 0xff0000) >> 16; uint32_t bg = ((x & 8) ^ (y & 8)) ? 0x66 : 0x99; - + r = a * r / 255 + (255 - a) * bg / 255; g = a * g / 255 + (255 - a) * bg / 255; b = a * b / 255 + (255 - a) * bg / 255; - + *buf = r << 16 | g << 8 | b; } } diff --git a/cores/libretro-video-processor/video_processor_v4l2.c b/cores/libretro-video-processor/video_processor_v4l2.c index d49d0900aa..d5f0813f19 100644 --- a/cores/libretro-video-processor/video_processor_v4l2.c +++ b/cores/libretro-video-processor/video_processor_v4l2.c @@ -219,7 +219,7 @@ enumerate_audio_devices(char *buf, size_t buflen) name = snd_device_name_get_hint(*n, "NAME"); ioid = snd_device_name_get_hint(*n, "IOID"); if ((ioid == NULL || string_is_equal(ioid, "Input")) && - (!strncmp(name, "hw:", strlen("hw:")) || + (!strncmp(name, "hw:", strlen("hw:")) || !strncmp(name, "default:", strlen("default:")))) { if (ndevs > 0) @@ -368,7 +368,7 @@ static bool open_devices(void) } error = snd_pcm_hw_params_set_format(audio_handle, hw_params, SND_PCM_FORMAT_S16_LE); if (error) - { + { printf("Couldn't set hw param format to SND_PCM_FORMAT_S16_LE: %s\n", snd_strerror(error)); return false; } @@ -460,12 +460,12 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_get_system_av_info)(struct retro_syst cc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; error = v4l2_ioctl(video_fd, VIDIOC_CROPCAP, &cc); if (error == 0) - info->geometry.aspect_ratio = (double)cc.pixelaspect.denominator + info->geometry.aspect_ratio = (double)cc.pixelaspect.denominator / (double)cc.pixelaspect.numerator; info->geometry.base_width = info->geometry.max_width = video_format.fmt.pix.width; info->geometry.base_height = info->geometry.max_height = video_format.fmt.pix.height; - info->timing.fps = (double)video_standard.frameperiod.denominator / + info->timing.fps = (double)video_standard.frameperiod.denominator / (double)video_standard.frameperiod.numerator; info->timing.sample_rate = AUDIO_SAMPLE_RATE; @@ -655,7 +655,7 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in buf.index = index; buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; buf.memory = V4L2_MEMORY_MMAP; - + error = v4l2_ioctl(video_fd, VIDIOC_QBUF, &buf); if (error != 0) { @@ -664,8 +664,8 @@ RETRO_API bool VIDEOPROC_CORE_PREFIX(retro_load_game)(const struct retro_game_in } } - conv_data = (uint16_t*)calloc(1, - video_format.fmt.pix.width * video_format.fmt.pix.height * 2); + conv_data = (uint16_t*)calloc(1, + video_format.fmt.pix.width * video_format.fmt.pix.height * 2); if (!conv_data) { printf("Cannot allocate conversion buffer\n"); @@ -707,7 +707,7 @@ RETRO_API void VIDEOPROC_CORE_PREFIX(retro_unload_game)(void) for (index = 0; index < video_nbuffers; index++) v4l2_munmap(video_buffer[index].start, video_buffer[index].len); } - + if (conv_data) free(conv_data); conv_data = NULL; diff --git a/defaults.h b/defaults.h index 66940f307e..2373d0bf00 100644 --- a/defaults.h +++ b/defaults.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -98,7 +98,7 @@ struct defaults float video_refresh_rate; bool video_threaded_enable; char menu[32]; - } settings; + } settings; #ifndef IS_SALAMANDER playlist_t *content_history; diff --git a/defines/d3d_defines.h b/defines/d3d_defines.h index 2e98aabfee..c4dccb2618 100644 --- a/defines/d3d_defines.h +++ b/defines/d3d_defines.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -65,7 +65,7 @@ #define ID3DSURFACE IDirect3DSurface8 #define D3DCREATE_CTX Direct3DCreate8 -#if !defined(D3DLOCK_NOSYSLOCK) && defined(_XBOX) +#if !defined(D3DLOCK_NOSYSLOCK) && defined(_XBOX) #define D3DLOCK_NOSYSLOCK (0) #endif #define D3DSAMP_ADDRESSU D3DTSS_ADDRESSU diff --git a/defines/gx_defines.h b/defines/gx_defines.h index e472b8231b..c9e7c28e7c 100644 --- a/defines/gx_defines.h +++ b/defines/gx_defines.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/defines/ps3_defines.h b/defines/ps3_defines.h index ac8e6f920c..2b4b0b3d75 100644 --- a/defines/ps3_defines.h +++ b/defines/ps3_defines.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/deps/7zip/7z.h b/deps/7zip/7z.h index 4f2ee95d88..84cd56c152 100644 --- a/deps/7zip/7z.h +++ b/deps/7zip/7z.h @@ -1,207 +1,207 @@ -/* 7z.h -- 7z interface -2010-03-11 : Igor Pavlov : Public domain */ - -#ifndef __7Z_H -#define __7Z_H - -#include "7zBuf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define k7zStartHeaderSize 0x20 -#define k7zSignatureSize 6 -extern uint8_t k7zSignature[k7zSignatureSize]; -#define k7zMajorVersion 0 - -enum EIdEnum -{ - k7zIdEnd, - k7zIdHeader, - k7zIdArchiveProperties, - k7zIdAdditionalStreamsInfo, - k7zIdMainStreamsInfo, - k7zIdFilesInfo, - k7zIdPackInfo, - k7zIdUnpackInfo, - k7zIdSubStreamsInfo, - k7zIdSize, - k7zIdCRC, - k7zIdFolder, - k7zIdCodersUnpackSize, - k7zIdNumUnpackStream, - k7zIdEmptyStream, - k7zIdEmptyFile, - k7zIdAnti, - k7zIdName, - k7zIdCTime, - k7zIdATime, - k7zIdMTime, - k7zIdWinAttributes, - k7zIdComment, - k7zIdEncodedHeader, - k7zIdStartPos, - k7zIdDummy -}; - -typedef struct -{ - uint32_t NumInStreams; - uint32_t NumOutStreams; - uint64_t MethodID; - CBuf Props; -} CSzCoderInfo; - -void SzCoderInfo_Init(CSzCoderInfo *p); -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); - -typedef struct -{ - uint32_t InIndex; - uint32_t OutIndex; -} CSzBindPair; - -typedef struct -{ - CSzCoderInfo *Coders; - CSzBindPair *BindPairs; - uint32_t *PackStreams; - uint64_t *UnpackSizes; - uint32_t NumCoders; - uint32_t NumBindPairs; - uint32_t NumPackStreams; - int UnpackCRCDefined; - uint32_t UnpackCRC; - - uint32_t NumUnpackStreams; -} CSzFolder; - -void SzFolder_Init(CSzFolder *p); -uint64_t SzFolder_GetUnpackSize(CSzFolder *p); -int SzFolder_FindBindPairForInStream(CSzFolder *p, uint32_t inStreamIndex); -uint32_t SzFolder_GetNumOutStreams(CSzFolder *p); -uint64_t SzFolder_GetUnpackSize(CSzFolder *p); - -SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes, - ILookInStream *stream, uint64_t startPos, - uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain); - -typedef struct -{ - uint32_t Low; - uint32_t High; -} CNtfsFileTime; - -typedef struct -{ - CNtfsFileTime MTime; - uint64_t Size; - uint32_t Crc; - uint32_t Attrib; - uint8_t HasStream; - uint8_t IsDir; - uint8_t IsAnti; - uint8_t CrcDefined; - uint8_t MTimeDefined; - uint8_t AttribDefined; -} CSzFileItem; - -void SzFile_Init(CSzFileItem *p); - -typedef struct -{ - uint64_t *PackSizes; - uint8_t *PackCRCsDefined; - uint32_t *PackCRCs; - CSzFolder *Folders; - CSzFileItem *Files; - uint32_t NumPackStreams; - uint32_t NumFolders; - uint32_t NumFiles; -} CSzAr; - -void SzAr_Init(CSzAr *p); -void SzAr_Free(CSzAr *p, ISzAlloc *alloc); - - -/* - SzExtract extracts file from archive - - *outBuffer must be 0 before first call for each new archive. - - Extracting cache: - If you need to decompress more than one file, you can send - these values from previous call: - *blockIndex, - *outBuffer, - *outBufferSize - You can consider "*outBuffer" as cache of solid block. If your archive is solid, - it will increase decompression speed. - - If you use external function, you can declare these 3 cache variables - (blockIndex, outBuffer, outBufferSize) as static in that external function. - - Free *outBuffer and set *outBuffer to 0, if you want to flush cache. -*/ - -typedef struct -{ - CSzAr db; - - uint64_t startPosAfterHeader; - uint64_t dataPos; - - uint32_t *FolderStartPackStreamIndex; - uint64_t *PackStreamStartPositions; - uint32_t *FolderStartFileIndex; - uint32_t *FileIndexToFolderIndexMap; - - size_t *FileNameOffsets; /* in 2-byte steps */ - CBuf FileNames; /* UTF-16-LE */ -} CSzArEx; - -void SzArEx_Init(CSzArEx *p); -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); -uint64_t SzArEx_GetFolderStreamPos(const CSzArEx *p, uint32_t folderIndex, uint32_t indexInFolder); -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, uint32_t folderIndex, uint64_t *resSize); - -/* -if dest == NULL, the return value specifies the required size of the buffer, - in 16-bit characters, including the null-terminating character. -if dest != NULL, the return value specifies the number of 16-bit characters that - are written to the dest, including the null-terminating character. */ - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, uint16_t *dest); - -SRes SzArEx_Extract( - const CSzArEx *db, - ILookInStream *inStream, - uint32_t fileIndex, /* index of file */ - uint32_t *blockIndex, /* index of solid block */ - uint8_t **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ - size_t *outBufferSize, /* buffer size for output buffer */ - size_t *offset, /* offset of stream for required file in *outBuffer */ - size_t *outSizeProcessed, /* size of file in *outBuffer */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp); - - -/* -SzArEx_Open Errors: -SZ_ERROR_NO_ARCHIVE -SZ_ERROR_ARCHIVE -SZ_ERROR_UNSUPPORTED -SZ_ERROR_MEM -SZ_ERROR_CRC -SZ_ERROR_INPUT_EOF -SZ_ERROR_FAIL -*/ - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); - -#ifdef __cplusplus -} -#endif - -#endif +/* 7z.h -- 7z interface +2010-03-11 : Igor Pavlov : Public domain */ + +#ifndef __7Z_H +#define __7Z_H + +#include "7zBuf.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define k7zStartHeaderSize 0x20 +#define k7zSignatureSize 6 +extern uint8_t k7zSignature[k7zSignatureSize]; +#define k7zMajorVersion 0 + +enum EIdEnum +{ + k7zIdEnd, + k7zIdHeader, + k7zIdArchiveProperties, + k7zIdAdditionalStreamsInfo, + k7zIdMainStreamsInfo, + k7zIdFilesInfo, + k7zIdPackInfo, + k7zIdUnpackInfo, + k7zIdSubStreamsInfo, + k7zIdSize, + k7zIdCRC, + k7zIdFolder, + k7zIdCodersUnpackSize, + k7zIdNumUnpackStream, + k7zIdEmptyStream, + k7zIdEmptyFile, + k7zIdAnti, + k7zIdName, + k7zIdCTime, + k7zIdATime, + k7zIdMTime, + k7zIdWinAttributes, + k7zIdComment, + k7zIdEncodedHeader, + k7zIdStartPos, + k7zIdDummy +}; + +typedef struct +{ + uint32_t NumInStreams; + uint32_t NumOutStreams; + uint64_t MethodID; + CBuf Props; +} CSzCoderInfo; + +void SzCoderInfo_Init(CSzCoderInfo *p); +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc); + +typedef struct +{ + uint32_t InIndex; + uint32_t OutIndex; +} CSzBindPair; + +typedef struct +{ + CSzCoderInfo *Coders; + CSzBindPair *BindPairs; + uint32_t *PackStreams; + uint64_t *UnpackSizes; + uint32_t NumCoders; + uint32_t NumBindPairs; + uint32_t NumPackStreams; + int UnpackCRCDefined; + uint32_t UnpackCRC; + + uint32_t NumUnpackStreams; +} CSzFolder; + +void SzFolder_Init(CSzFolder *p); +uint64_t SzFolder_GetUnpackSize(CSzFolder *p); +int SzFolder_FindBindPairForInStream(CSzFolder *p, uint32_t inStreamIndex); +uint32_t SzFolder_GetNumOutStreams(CSzFolder *p); +uint64_t SzFolder_GetUnpackSize(CSzFolder *p); + +SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes, + ILookInStream *stream, uint64_t startPos, + uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain); + +typedef struct +{ + uint32_t Low; + uint32_t High; +} CNtfsFileTime; + +typedef struct +{ + CNtfsFileTime MTime; + uint64_t Size; + uint32_t Crc; + uint32_t Attrib; + uint8_t HasStream; + uint8_t IsDir; + uint8_t IsAnti; + uint8_t CrcDefined; + uint8_t MTimeDefined; + uint8_t AttribDefined; +} CSzFileItem; + +void SzFile_Init(CSzFileItem *p); + +typedef struct +{ + uint64_t *PackSizes; + uint8_t *PackCRCsDefined; + uint32_t *PackCRCs; + CSzFolder *Folders; + CSzFileItem *Files; + uint32_t NumPackStreams; + uint32_t NumFolders; + uint32_t NumFiles; +} CSzAr; + +void SzAr_Init(CSzAr *p); +void SzAr_Free(CSzAr *p, ISzAlloc *alloc); + + +/* + SzExtract extracts file from archive + + *outBuffer must be 0 before first call for each new archive. + + Extracting cache: + If you need to decompress more than one file, you can send + these values from previous call: + *blockIndex, + *outBuffer, + *outBufferSize + You can consider "*outBuffer" as cache of solid block. If your archive is solid, + it will increase decompression speed. + + If you use external function, you can declare these 3 cache variables + (blockIndex, outBuffer, outBufferSize) as static in that external function. + + Free *outBuffer and set *outBuffer to 0, if you want to flush cache. +*/ + +typedef struct +{ + CSzAr db; + + uint64_t startPosAfterHeader; + uint64_t dataPos; + + uint32_t *FolderStartPackStreamIndex; + uint64_t *PackStreamStartPositions; + uint32_t *FolderStartFileIndex; + uint32_t *FileIndexToFolderIndexMap; + + size_t *FileNameOffsets; /* in 2-byte steps */ + CBuf FileNames; /* UTF-16-LE */ +} CSzArEx; + +void SzArEx_Init(CSzArEx *p); +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc); +uint64_t SzArEx_GetFolderStreamPos(const CSzArEx *p, uint32_t folderIndex, uint32_t indexInFolder); +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, uint32_t folderIndex, uint64_t *resSize); + +/* +if dest == NULL, the return value specifies the required size of the buffer, + in 16-bit characters, including the null-terminating character. +if dest != NULL, the return value specifies the number of 16-bit characters that + are written to the dest, including the null-terminating character. */ + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, uint16_t *dest); + +SRes SzArEx_Extract( + const CSzArEx *db, + ILookInStream *inStream, + uint32_t fileIndex, /* index of file */ + uint32_t *blockIndex, /* index of solid block */ + uint8_t **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */ + size_t *outBufferSize, /* buffer size for output buffer */ + size_t *offset, /* offset of stream for required file in *outBuffer */ + size_t *outSizeProcessed, /* size of file in *outBuffer */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp); + + +/* +SzArEx_Open Errors: +SZ_ERROR_NO_ARCHIVE +SZ_ERROR_ARCHIVE +SZ_ERROR_UNSUPPORTED +SZ_ERROR_MEM +SZ_ERROR_CRC +SZ_ERROR_INPUT_EOF +SZ_ERROR_FAIL +*/ + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/7zBuf.c b/deps/7zip/7zBuf.c index 3d30bfd270..832a7a9271 100644 --- a/deps/7zip/7zBuf.c +++ b/deps/7zip/7zBuf.c @@ -1,37 +1,37 @@ -/* 7zBuf.c -- Byte Buffer - 2008-03-28 - Igor Pavlov - Public domain */ - -#include -#include "7zBuf.h" - -void Buf_Init(CBuf *p) -{ - p->data = 0; - p->size = 0; -} - -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) -{ - p->size = 0; - if (size == 0) - { - p->data = 0; - return 1; - } - p->data = (uint8_t *)alloc->Alloc(alloc, size); - if (p->data != 0) - { - p->size = size; - return 1; - } - return 0; -} - -void Buf_Free(CBuf *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->data); - p->data = 0; - p->size = 0; -} +/* 7zBuf.c -- Byte Buffer + 2008-03-28 + Igor Pavlov + Public domain */ + +#include +#include "7zBuf.h" + +void Buf_Init(CBuf *p) +{ + p->data = 0; + p->size = 0; +} + +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc) +{ + p->size = 0; + if (size == 0) + { + p->data = 0; + return 1; + } + p->data = (uint8_t *)alloc->Alloc(alloc, size); + if (p->data != 0) + { + p->size = size; + return 1; + } + return 0; +} + +void Buf_Free(CBuf *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->data); + p->data = 0; + p->size = 0; +} diff --git a/deps/7zip/7zBuf.h b/deps/7zip/7zBuf.h index 485ec12610..4ce09cb767 100644 --- a/deps/7zip/7zBuf.h +++ b/deps/7zip/7zBuf.h @@ -1,27 +1,27 @@ -/* 7zBuf.h -- Byte Buffer -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __7Z_BUF_H -#define __7Z_BUF_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct -{ - uint8_t *data; - size_t size; -} CBuf; - -void Buf_Init(CBuf *p); -int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); -void Buf_Free(CBuf *p, ISzAlloc *alloc); - -#ifdef __cplusplus -} -#endif - -#endif +/* 7zBuf.h -- Byte Buffer +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __7Z_BUF_H +#define __7Z_BUF_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct +{ + uint8_t *data; + size_t size; +} CBuf; + +void Buf_Init(CBuf *p); +int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc); +void Buf_Free(CBuf *p, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/7zCrc.c b/deps/7zip/7zCrc.c index 0e95f17a34..02728d23d6 100644 --- a/deps/7zip/7zCrc.c +++ b/deps/7zip/7zCrc.c @@ -1,76 +1,76 @@ -/* 7zCrc.c -- CRC32 calculation - 2009-11-23 : Igor Pavlov : Public domain */ - -#include -#include "7zCrc.h" -#include "CpuArch.h" - -#define kCrcPoly 0xEDB88320 - -#ifdef MSB_FIRST -#define CRC_NUM_TABLES 1 -#else -#define CRC_NUM_TABLES 8 -#endif - -typedef uint32_t (MY_FAST_CALL *CRC_FUNC)(uint32_t v, const void *data, size_t size, const uint32_t *table); - -static CRC_FUNC g_CrcUpdate; -uint32_t g_CrcTable[256 * CRC_NUM_TABLES]; - -#if CRC_NUM_TABLES == 1 - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -static uint32_t MY_FAST_CALL CrcUpdateT1(uint32_t v, const void *data, size_t size, const uint32_t *table) -{ - const uint8_t *p = (const uint8_t *)data; - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -#else - -uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table); -uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table); - -#endif - -uint32_t MY_FAST_CALL CrcUpdate(uint32_t v, const void *data, size_t size) -{ - return g_CrcUpdate(v, data, size, g_CrcTable); -} - -uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size) -{ - return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; -} - -void MY_FAST_CALL CrcGenerateTable(void) -{ - uint32_t i; - for (i = 0; i < 256; i++) - { - uint32_t r = i; - unsigned j; - for (j = 0; j < 8; j++) - r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); - g_CrcTable[i] = r; - } -#if CRC_NUM_TABLES == 1 - g_CrcUpdate = CrcUpdateT1; -#else - for (; i < 256 * CRC_NUM_TABLES; i++) - { - uint32_t r = g_CrcTable[i - 256]; - g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); - } - -#ifdef MY_CPU_X86_OR_AMD64 - g_CrcUpdate = CrcUpdateT8; -#else - g_CrcUpdate = CrcUpdateT4; -#endif -#endif -} +/* 7zCrc.c -- CRC32 calculation + 2009-11-23 : Igor Pavlov : Public domain */ + +#include +#include "7zCrc.h" +#include "CpuArch.h" + +#define kCrcPoly 0xEDB88320 + +#ifdef MSB_FIRST +#define CRC_NUM_TABLES 1 +#else +#define CRC_NUM_TABLES 8 +#endif + +typedef uint32_t (MY_FAST_CALL *CRC_FUNC)(uint32_t v, const void *data, size_t size, const uint32_t *table); + +static CRC_FUNC g_CrcUpdate; +uint32_t g_CrcTable[256 * CRC_NUM_TABLES]; + +#if CRC_NUM_TABLES == 1 + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +static uint32_t MY_FAST_CALL CrcUpdateT1(uint32_t v, const void *data, size_t size, const uint32_t *table) +{ + const uint8_t *p = (const uint8_t *)data; + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +#else + +uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table); +uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table); + +#endif + +uint32_t MY_FAST_CALL CrcUpdate(uint32_t v, const void *data, size_t size) +{ + return g_CrcUpdate(v, data, size, g_CrcTable); +} + +uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size) +{ + return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL; +} + +void MY_FAST_CALL CrcGenerateTable(void) +{ + uint32_t i; + for (i = 0; i < 256; i++) + { + uint32_t r = i; + unsigned j; + for (j = 0; j < 8; j++) + r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1)); + g_CrcTable[i] = r; + } +#if CRC_NUM_TABLES == 1 + g_CrcUpdate = CrcUpdateT1; +#else + for (; i < 256 * CRC_NUM_TABLES; i++) + { + uint32_t r = g_CrcTable[i - 256]; + g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8); + } + +#ifdef MY_CPU_X86_OR_AMD64 + g_CrcUpdate = CrcUpdateT8; +#else + g_CrcUpdate = CrcUpdateT4; +#endif +#endif +} diff --git a/deps/7zip/7zCrc.h b/deps/7zip/7zCrc.h index 4b56a1c506..30890b8035 100644 --- a/deps/7zip/7zCrc.h +++ b/deps/7zip/7zCrc.h @@ -1,29 +1,29 @@ -/* 7zCrc.h -- CRC32 calculation - 2009-11-21 : Igor Pavlov : Public domain */ - -#ifndef __7Z_CRC_H -#define __7Z_CRC_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint32_t g_CrcTable[]; - -/* Call CrcGenerateTable one time before other CRC functions */ -void MY_FAST_CALL CrcGenerateTable(void); - -#define CRC_INIT_VAL 0xFFFFFFFF -#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) -#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -uint32_t MY_FAST_CALL CrcUpdate(uint32_t crc, const void *data, size_t size); -uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size); - -#ifdef __cplusplus -} -#endif - -#endif +/* 7zCrc.h -- CRC32 calculation + 2009-11-21 : Igor Pavlov : Public domain */ + +#ifndef __7Z_CRC_H +#define __7Z_CRC_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t g_CrcTable[]; + +/* Call CrcGenerateTable one time before other CRC functions */ +void MY_FAST_CALL CrcGenerateTable(void); + +#define CRC_INIT_VAL 0xFFFFFFFF +#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL) +#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +uint32_t MY_FAST_CALL CrcUpdate(uint32_t crc, const void *data, size_t size); +uint32_t MY_FAST_CALL CrcCalc(const void *data, size_t size); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/7zCrcOpt.c b/deps/7zip/7zCrcOpt.c index d2f18b372b..22bd4b1196 100644 --- a/deps/7zip/7zCrcOpt.c +++ b/deps/7zip/7zCrcOpt.c @@ -1,38 +1,38 @@ -/* 7zCrcOpt.c -- CRC32 calculation : optimized version - 2009-11-23 : Igor Pavlov : Public domain */ - -#include -#include "CpuArch.h" - -#ifndef MSB_FIRST - -#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) - -uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table); -uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table); - -uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table) -{ - const uint8_t *p = (const uint8_t*)data; - for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - for (; size >= 4; size -= 4, p += 4) - { - v ^= *(const uint32_t *)p; - v = - table[0x300 + (v & 0xFF)] ^ - table[0x200 + ((v >> 8) & 0xFF)] ^ - table[0x100 + ((v >> 16) & 0xFF)] ^ - table[0x000 + ((v >> 24))]; - } - for (; size > 0; size--, p++) - v = CRC_UPDATE_BYTE_2(v, *p); - return v; -} - -uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table) -{ - return CrcUpdateT4(v, data, size, table); -} - -#endif +/* 7zCrcOpt.c -- CRC32 calculation : optimized version + 2009-11-23 : Igor Pavlov : Public domain */ + +#include +#include "CpuArch.h" + +#ifndef MSB_FIRST + +#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8)) + +uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table); +uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table); + +uint32_t MY_FAST_CALL CrcUpdateT4(uint32_t v, const void *data, size_t size, const uint32_t *table) +{ + const uint8_t *p = (const uint8_t*)data; + for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + for (; size >= 4; size -= 4, p += 4) + { + v ^= *(const uint32_t *)p; + v = + table[0x300 + (v & 0xFF)] ^ + table[0x200 + ((v >> 8) & 0xFF)] ^ + table[0x100 + ((v >> 16) & 0xFF)] ^ + table[0x000 + ((v >> 24))]; + } + for (; size > 0; size--, p++) + v = CRC_UPDATE_BYTE_2(v, *p); + return v; +} + +uint32_t MY_FAST_CALL CrcUpdateT8(uint32_t v, const void *data, size_t size, const uint32_t *table) +{ + return CrcUpdateT4(v, data, size, table); +} + +#endif diff --git a/deps/7zip/7zDec.c b/deps/7zip/7zDec.c index 34eac2a832..4ed17b2340 100644 --- a/deps/7zip/7zDec.c +++ b/deps/7zip/7zDec.c @@ -1,360 +1,360 @@ -/* 7zDec.c -- Decoding from 7z folder -2010-11-02 : Igor Pavlov : Public domain */ - -#include -#include -#include - -#include "7z.h" - -#include "Bcj2.h" -#include "Bra.h" -#include "CpuArch.h" -#include "LzmaDec.h" -#include "Lzma2Dec.h" - -#define k_Copy 0 -#define k_LZMA2 0x21 -#define k_LZMA 0x30101 -#define k_BCJ 0x03030103 -#define k_PPC 0x03030205 -#define k_ARM 0x03030501 -#define k_ARMT 0x03030701 -#define k_SPARC 0x03030805 -#define k_BCJ2 0x0303011B - -static SRes SzDecodeLzma(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, - uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - CLzmaDec state; - SRes res = SZ_OK; - - LzmaDec_Construct(&state); - RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); - state.dic = outBuffer; - state.dicBufSize = outSize; - LzmaDec_Init(&state); - - for (;;) - { - uint8_t *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - size_t inProcessed = (size_t)lookahead, dicPos = state.dicPos; - ELzmaStatus status; - res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) - { - if (state.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK && - status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - LzmaDec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeLzma2(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, - uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - CLzma2Dec state; - SRes res = SZ_OK; - - Lzma2Dec_Construct(&state); - if (coder->Props.size != 1) - return SZ_ERROR_DATA; - RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); - state.decoder.dic = outBuffer; - state.decoder.dicBufSize = outSize; - Lzma2Dec_Init(&state); - - for (;;) - { - uint8_t *inBuf = NULL; - size_t lookahead = (1 << 18); - if (lookahead > inSize) - lookahead = (size_t)inSize; - res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); - if (res != SZ_OK) - break; - - { - size_t inProcessed = (size_t)lookahead, dicPos = state.decoder.dicPos; - ELzmaStatus status; - res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); - lookahead -= inProcessed; - inSize -= inProcessed; - if (res != SZ_OK) - break; - if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) - { - if (state.decoder.dicBufSize != outSize || lookahead != 0 || - (status != LZMA_STATUS_FINISHED_WITH_MARK)) - res = SZ_ERROR_DATA; - break; - } - res = inStream->Skip((void *)inStream, inProcessed); - if (res != SZ_OK) - break; - } - } - - Lzma2Dec_FreeProbs(&state, allocMain); - return res; -} - -static SRes SzDecodeCopy(uint64_t inSize, ILookInStream *inStream, uint8_t *outBuffer) -{ - while (inSize > 0) - { - void *inBuf; - size_t curSize = (1 << 18); - if (curSize > inSize) - curSize = (size_t)inSize; - RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); - if (curSize == 0) - return SZ_ERROR_INPUT_EOF; - memcpy(outBuffer, inBuf, curSize); - outBuffer += curSize; - inSize -= curSize; - RINOK(inStream->Skip((void *)inStream, curSize)); - } - return SZ_OK; -} - -static bool IS_MAIN_METHOD(uint32_t m) -{ - switch(m) - { - case k_Copy: - case k_LZMA: - case k_LZMA2: - return true; - } - return false; -} - -static bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) -{ - return - c->NumInStreams == 1 && - c->NumOutStreams == 1 && - c->MethodID <= (uint32_t)0xFFFFFFFF && - IS_MAIN_METHOD((uint32_t)c->MethodID); -} - -#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) - -static SRes CheckSupportedFolder(const CSzFolder *f) -{ - if (f->NumCoders < 1 || f->NumCoders > 4) - return SZ_ERROR_UNSUPPORTED; - if (!IS_SUPPORTED_CODER(&f->Coders[0])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumCoders == 1) - { - if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - if (f->NumCoders == 2) - { - CSzCoderInfo *c = &f->Coders[1]; - if (c->MethodID > (uint32_t)0xFFFFFFFF || - c->NumInStreams != 1 || - c->NumOutStreams != 1 || - f->NumPackStreams != 1 || - f->PackStreams[0] != 0 || - f->NumBindPairs != 1 || - f->BindPairs[0].InIndex != 1 || - f->BindPairs[0].OutIndex != 0) - return SZ_ERROR_UNSUPPORTED; - switch ((uint32_t)c->MethodID) - { - case k_BCJ: - case k_ARM: - break; - default: - return SZ_ERROR_UNSUPPORTED; - } - return SZ_OK; - } - if (f->NumCoders == 4) - { - if (!IS_SUPPORTED_CODER(&f->Coders[1]) || - !IS_SUPPORTED_CODER(&f->Coders[2]) || - !IS_BCJ2(&f->Coders[3])) - return SZ_ERROR_UNSUPPORTED; - if (f->NumPackStreams != 4 || - f->PackStreams[0] != 2 || - f->PackStreams[1] != 6 || - f->PackStreams[2] != 1 || - f->PackStreams[3] != 0 || - f->NumBindPairs != 3 || - f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || - f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || - f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) - return SZ_ERROR_UNSUPPORTED; - return SZ_OK; - } - return SZ_ERROR_UNSUPPORTED; -} - -static uint64_t GetSum(const uint64_t *values, uint32_t idx) -{ - uint64_t sum = 0; - uint32_t i; - for (i = 0; i < idx; i++) - sum += values[i]; - return sum; -} - -#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; - -static SRes SzFolder_Decode2(const CSzFolder *folder, const uint64_t *packSizes, - ILookInStream *inStream, uint64_t startPos, - uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain, - uint8_t *tempBuf[]) -{ - uint32_t ci; - size_t tempSizes[3] = { 0, 0, 0}; - size_t tempSize3 = 0; - uint8_t *tempBuf3 = 0; - - RINOK(CheckSupportedFolder(folder)); - - for (ci = 0; ci < folder->NumCoders; ci++) - { - CSzCoderInfo *coder = &folder->Coders[ci]; - - if (IS_MAIN_METHOD((uint32_t)coder->MethodID)) - { - uint32_t si = 0; - uint64_t offset; - uint64_t inSize; - uint8_t *outBufCur = outBuffer; - size_t outSizeCur = outSize; - if (folder->NumCoders == 4) - { - uint32_t indices[] = { 3, 2, 0 }; - uint64_t unpackSize = folder->UnpackSizes[ci]; - si = indices[ci]; - if (ci < 2) - { - uint8_t *temp; - outSizeCur = (size_t)unpackSize; - if (outSizeCur != unpackSize) - return SZ_ERROR_MEM; - temp = (uint8_t *)IAlloc_Alloc(allocMain, outSizeCur); - if (temp == 0 && outSizeCur != 0) - return SZ_ERROR_MEM; - outBufCur = tempBuf[1 - ci] = temp; - tempSizes[1 - ci] = outSizeCur; - } - else if (ci == 2) - { - if (unpackSize > outSize) /* check it */ - return SZ_ERROR_PARAM; - tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); - tempSize3 = outSizeCur = (size_t)unpackSize; - } - else - return SZ_ERROR_UNSUPPORTED; - } - offset = GetSum(packSizes, si); - inSize = packSizes[si]; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - - if (coder->MethodID == k_Copy) - { - if (inSize != outSizeCur) /* check it */ - return SZ_ERROR_DATA; - RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); - } - else if (coder->MethodID == k_LZMA) - { - RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else if (coder->MethodID == k_LZMA2) - { - RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); - } - else - return SZ_ERROR_UNSUPPORTED; - } - else if (coder->MethodID == k_BCJ2) - { - uint64_t offset = GetSum(packSizes, 1); - uint64_t s3Size = packSizes[1]; - SRes res; - if (ci != 3) - return SZ_ERROR_UNSUPPORTED; - RINOK(LookInStream_SeekTo(inStream, startPos + offset)); - tempSizes[2] = (size_t)s3Size; - if (tempSizes[2] != s3Size) - return SZ_ERROR_MEM; - tempBuf[2] = (uint8_t *)IAlloc_Alloc(allocMain, tempSizes[2]); - if (tempBuf[2] == 0 && tempSizes[2] != 0) - return SZ_ERROR_MEM; - res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); - RINOK(res) - - res = Bcj2_Decode( - tempBuf3, tempSize3, - tempBuf[0], tempSizes[0], - tempBuf[1], tempSizes[1], - tempBuf[2], tempSizes[2], - outBuffer, outSize); - RINOK(res) - } - else - { - if (ci != 1) - return SZ_ERROR_UNSUPPORTED; - switch(coder->MethodID) - { - case k_BCJ: - { - uint32_t state; - x86_Convert_Init(state); - x86_Convert(outBuffer, outSize, 0, &state, 0); - break; - } - CASE_BRA_CONV(ARM) - default: - return SZ_ERROR_UNSUPPORTED; - } - } - } - return SZ_OK; -} - -SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes, - ILookInStream *inStream, uint64_t startPos, - uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) -{ - uint8_t *tempBuf[3] = { 0, 0, 0}; - int i; - SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, - outBuffer, (size_t)outSize, allocMain, tempBuf); - for (i = 0; i < 3; i++) - IAlloc_Free(allocMain, tempBuf[i]); - return res; -} +/* 7zDec.c -- Decoding from 7z folder +2010-11-02 : Igor Pavlov : Public domain */ + +#include +#include +#include + +#include "7z.h" + +#include "Bcj2.h" +#include "Bra.h" +#include "CpuArch.h" +#include "LzmaDec.h" +#include "Lzma2Dec.h" + +#define k_Copy 0 +#define k_LZMA2 0x21 +#define k_LZMA 0x30101 +#define k_BCJ 0x03030103 +#define k_PPC 0x03030205 +#define k_ARM 0x03030501 +#define k_ARMT 0x03030701 +#define k_SPARC 0x03030805 +#define k_BCJ2 0x0303011B + +static SRes SzDecodeLzma(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, + uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + CLzmaDec state; + SRes res = SZ_OK; + + LzmaDec_Construct(&state); + RINOK(LzmaDec_AllocateProbs(&state, coder->Props.data, (unsigned)coder->Props.size, allocMain)); + state.dic = outBuffer; + state.dicBufSize = outSize; + LzmaDec_Init(&state); + + for (;;) + { + uint8_t *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + size_t inProcessed = (size_t)lookahead, dicPos = state.dicPos; + ELzmaStatus status; + res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos)) + { + if (state.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK && + status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + LzmaDec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeLzma2(CSzCoderInfo *coder, uint64_t inSize, ILookInStream *inStream, + uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + CLzma2Dec state; + SRes res = SZ_OK; + + Lzma2Dec_Construct(&state); + if (coder->Props.size != 1) + return SZ_ERROR_DATA; + RINOK(Lzma2Dec_AllocateProbs(&state, coder->Props.data[0], allocMain)); + state.decoder.dic = outBuffer; + state.decoder.dicBufSize = outSize; + Lzma2Dec_Init(&state); + + for (;;) + { + uint8_t *inBuf = NULL; + size_t lookahead = (1 << 18); + if (lookahead > inSize) + lookahead = (size_t)inSize; + res = inStream->Look((void *)inStream, (const void **)&inBuf, &lookahead); + if (res != SZ_OK) + break; + + { + size_t inProcessed = (size_t)lookahead, dicPos = state.decoder.dicPos; + ELzmaStatus status; + res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status); + lookahead -= inProcessed; + inSize -= inProcessed; + if (res != SZ_OK) + break; + if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos)) + { + if (state.decoder.dicBufSize != outSize || lookahead != 0 || + (status != LZMA_STATUS_FINISHED_WITH_MARK)) + res = SZ_ERROR_DATA; + break; + } + res = inStream->Skip((void *)inStream, inProcessed); + if (res != SZ_OK) + break; + } + } + + Lzma2Dec_FreeProbs(&state, allocMain); + return res; +} + +static SRes SzDecodeCopy(uint64_t inSize, ILookInStream *inStream, uint8_t *outBuffer) +{ + while (inSize > 0) + { + void *inBuf; + size_t curSize = (1 << 18); + if (curSize > inSize) + curSize = (size_t)inSize; + RINOK(inStream->Look((void *)inStream, (const void **)&inBuf, &curSize)); + if (curSize == 0) + return SZ_ERROR_INPUT_EOF; + memcpy(outBuffer, inBuf, curSize); + outBuffer += curSize; + inSize -= curSize; + RINOK(inStream->Skip((void *)inStream, curSize)); + } + return SZ_OK; +} + +static bool IS_MAIN_METHOD(uint32_t m) +{ + switch(m) + { + case k_Copy: + case k_LZMA: + case k_LZMA2: + return true; + } + return false; +} + +static bool IS_SUPPORTED_CODER(const CSzCoderInfo *c) +{ + return + c->NumInStreams == 1 && + c->NumOutStreams == 1 && + c->MethodID <= (uint32_t)0xFFFFFFFF && + IS_MAIN_METHOD((uint32_t)c->MethodID); +} + +#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumInStreams == 4 && (c)->NumOutStreams == 1) + +static SRes CheckSupportedFolder(const CSzFolder *f) +{ + if (f->NumCoders < 1 || f->NumCoders > 4) + return SZ_ERROR_UNSUPPORTED; + if (!IS_SUPPORTED_CODER(&f->Coders[0])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumCoders == 1) + { + if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBindPairs != 0) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + if (f->NumCoders == 2) + { + CSzCoderInfo *c = &f->Coders[1]; + if (c->MethodID > (uint32_t)0xFFFFFFFF || + c->NumInStreams != 1 || + c->NumOutStreams != 1 || + f->NumPackStreams != 1 || + f->PackStreams[0] != 0 || + f->NumBindPairs != 1 || + f->BindPairs[0].InIndex != 1 || + f->BindPairs[0].OutIndex != 0) + return SZ_ERROR_UNSUPPORTED; + switch ((uint32_t)c->MethodID) + { + case k_BCJ: + case k_ARM: + break; + default: + return SZ_ERROR_UNSUPPORTED; + } + return SZ_OK; + } + if (f->NumCoders == 4) + { + if (!IS_SUPPORTED_CODER(&f->Coders[1]) || + !IS_SUPPORTED_CODER(&f->Coders[2]) || + !IS_BCJ2(&f->Coders[3])) + return SZ_ERROR_UNSUPPORTED; + if (f->NumPackStreams != 4 || + f->PackStreams[0] != 2 || + f->PackStreams[1] != 6 || + f->PackStreams[2] != 1 || + f->PackStreams[3] != 0 || + f->NumBindPairs != 3 || + f->BindPairs[0].InIndex != 5 || f->BindPairs[0].OutIndex != 0 || + f->BindPairs[1].InIndex != 4 || f->BindPairs[1].OutIndex != 1 || + f->BindPairs[2].InIndex != 3 || f->BindPairs[2].OutIndex != 2) + return SZ_ERROR_UNSUPPORTED; + return SZ_OK; + } + return SZ_ERROR_UNSUPPORTED; +} + +static uint64_t GetSum(const uint64_t *values, uint32_t idx) +{ + uint64_t sum = 0; + uint32_t i; + for (i = 0; i < idx; i++) + sum += values[i]; + return sum; +} + +#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break; + +static SRes SzFolder_Decode2(const CSzFolder *folder, const uint64_t *packSizes, + ILookInStream *inStream, uint64_t startPos, + uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain, + uint8_t *tempBuf[]) +{ + uint32_t ci; + size_t tempSizes[3] = { 0, 0, 0}; + size_t tempSize3 = 0; + uint8_t *tempBuf3 = 0; + + RINOK(CheckSupportedFolder(folder)); + + for (ci = 0; ci < folder->NumCoders; ci++) + { + CSzCoderInfo *coder = &folder->Coders[ci]; + + if (IS_MAIN_METHOD((uint32_t)coder->MethodID)) + { + uint32_t si = 0; + uint64_t offset; + uint64_t inSize; + uint8_t *outBufCur = outBuffer; + size_t outSizeCur = outSize; + if (folder->NumCoders == 4) + { + uint32_t indices[] = { 3, 2, 0 }; + uint64_t unpackSize = folder->UnpackSizes[ci]; + si = indices[ci]; + if (ci < 2) + { + uint8_t *temp; + outSizeCur = (size_t)unpackSize; + if (outSizeCur != unpackSize) + return SZ_ERROR_MEM; + temp = (uint8_t *)IAlloc_Alloc(allocMain, outSizeCur); + if (temp == 0 && outSizeCur != 0) + return SZ_ERROR_MEM; + outBufCur = tempBuf[1 - ci] = temp; + tempSizes[1 - ci] = outSizeCur; + } + else if (ci == 2) + { + if (unpackSize > outSize) /* check it */ + return SZ_ERROR_PARAM; + tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize); + tempSize3 = outSizeCur = (size_t)unpackSize; + } + else + return SZ_ERROR_UNSUPPORTED; + } + offset = GetSum(packSizes, si); + inSize = packSizes[si]; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + + if (coder->MethodID == k_Copy) + { + if (inSize != outSizeCur) /* check it */ + return SZ_ERROR_DATA; + RINOK(SzDecodeCopy(inSize, inStream, outBufCur)); + } + else if (coder->MethodID == k_LZMA) + { + RINOK(SzDecodeLzma(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else if (coder->MethodID == k_LZMA2) + { + RINOK(SzDecodeLzma2(coder, inSize, inStream, outBufCur, outSizeCur, allocMain)); + } + else + return SZ_ERROR_UNSUPPORTED; + } + else if (coder->MethodID == k_BCJ2) + { + uint64_t offset = GetSum(packSizes, 1); + uint64_t s3Size = packSizes[1]; + SRes res; + if (ci != 3) + return SZ_ERROR_UNSUPPORTED; + RINOK(LookInStream_SeekTo(inStream, startPos + offset)); + tempSizes[2] = (size_t)s3Size; + if (tempSizes[2] != s3Size) + return SZ_ERROR_MEM; + tempBuf[2] = (uint8_t *)IAlloc_Alloc(allocMain, tempSizes[2]); + if (tempBuf[2] == 0 && tempSizes[2] != 0) + return SZ_ERROR_MEM; + res = SzDecodeCopy(s3Size, inStream, tempBuf[2]); + RINOK(res) + + res = Bcj2_Decode( + tempBuf3, tempSize3, + tempBuf[0], tempSizes[0], + tempBuf[1], tempSizes[1], + tempBuf[2], tempSizes[2], + outBuffer, outSize); + RINOK(res) + } + else + { + if (ci != 1) + return SZ_ERROR_UNSUPPORTED; + switch(coder->MethodID) + { + case k_BCJ: + { + uint32_t state; + x86_Convert_Init(state); + x86_Convert(outBuffer, outSize, 0, &state, 0); + break; + } + CASE_BRA_CONV(ARM) + default: + return SZ_ERROR_UNSUPPORTED; + } + } + } + return SZ_OK; +} + +SRes SzFolder_Decode(const CSzFolder *folder, const uint64_t *packSizes, + ILookInStream *inStream, uint64_t startPos, + uint8_t *outBuffer, size_t outSize, ISzAlloc *allocMain) +{ + uint8_t *tempBuf[3] = { 0, 0, 0}; + int i; + SRes res = SzFolder_Decode2(folder, packSizes, inStream, startPos, + outBuffer, (size_t)outSize, allocMain, tempBuf); + for (i = 0; i < 3; i++) + IAlloc_Free(allocMain, tempBuf[i]); + return res; +} diff --git a/deps/7zip/7zFile.c b/deps/7zip/7zFile.c index 8f0b628fff..6dc10da40c 100644 --- a/deps/7zip/7zFile.c +++ b/deps/7zip/7zFile.c @@ -1,285 +1,285 @@ -/* 7zFile.c -- File IO - 2009-11-24 : Igor Pavlov : Public domain */ - -#include -#include "7zFile.h" - -#ifndef USE_WINDOWS_FILE - -#ifndef UNDER_CE -#include -#endif - -#else - -/* - ReadFile and WriteFile functions in Windows have BUG: - If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) - from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES - (Insufficient system resources exist to complete the requested service). - Probably in some version of Windows there are problems with other sizes: - for 32 MB (maybe also for 16 MB). - And message can be "Network connection was lost" - */ - -#define kChunkSizeMax (1 << 22) - -#endif - -void File_Construct(CSzFile *p) -{ -#ifdef USE_WINDOWS_FILE - p->handle = INVALID_HANDLE_VALUE; -#else - p->file = NULL; -#endif -} - -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -static WRes File_Open(CSzFile *p, const char *name, int writeMode) -{ -#ifdef USE_WINDOWS_FILE - p->handle = CreateFileA(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); -#else - p->file = fopen(name, writeMode ? "wb+" : "rb"); - return (p->file != 0) ? 0 : -#ifdef UNDER_CE - 2; /* ENOENT */ -#else - errno; -#endif -#endif -} - -WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } -WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } -#endif - -#ifdef USE_WINDOWS_FILE -static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) -{ - p->handle = CreateFileW(name, - writeMode ? GENERIC_WRITE : GENERIC_READ, - FILE_SHARE_READ, NULL, - writeMode ? CREATE_ALWAYS : OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); - return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); -} -WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } -#endif - -WRes File_Close(CSzFile *p) -{ -#ifdef USE_WINDOWS_FILE - if (p->handle != INVALID_HANDLE_VALUE) - { - if (!CloseHandle(p->handle)) - return GetLastError(); - p->handle = INVALID_HANDLE_VALUE; - } -#else - if (p->file != NULL) - { - int res = fclose(p->file); - if (res != 0) - return res; - p->file = NULL; - } -#endif - return 0; -} - -WRes File_Read(CSzFile *p, void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - -#ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((uint8_t*)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - -#else - - *size = fread(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - -#endif -} - -WRes File_Write(CSzFile *p, const void *data, size_t *size) -{ - size_t originalSize = *size; - if (originalSize == 0) - return 0; - -#ifdef USE_WINDOWS_FILE - - *size = 0; - do - { - DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; - DWORD processed = 0; - BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); - data = (void *)((uint8_t*)data + processed); - originalSize -= processed; - *size += processed; - if (!res) - return GetLastError(); - if (processed == 0) - break; - } - while (originalSize > 0); - return 0; - -#else - - *size = fwrite(data, 1, originalSize, p->file); - if (*size == originalSize) - return 0; - return ferror(p->file); - -#endif -} - -WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin) -{ -#ifdef USE_WINDOWS_FILE - - LARGE_INTEGER value; - DWORD moveMethod; - value.LowPart = (DWORD)*pos; - value.HighPart = (LONG)((uint64_t)*pos >> 16 >> 16); /* for case when uint64_t is 32-bit only */ - switch (origin) - { - case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; - case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; - case SZ_SEEK_END: moveMethod = FILE_END; break; - default: return ERROR_INVALID_PARAMETER; - } - value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); - if (value.LowPart == 0xFFFFFFFF) - { - WRes res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *pos = ((int64_t)value.HighPart << 32) | value.LowPart; - return 0; - -#else - - int moveMethod; - int res; - switch (origin) - { - case SZ_SEEK_SET: moveMethod = SEEK_SET; break; - case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; - case SZ_SEEK_END: moveMethod = SEEK_END; break; - default: return 1; - } - res = fseek(p->file, (long)*pos, moveMethod); - *pos = ftell(p->file); - return res; - -#endif -} - -WRes File_GetLength(CSzFile *p, uint64_t *length) -{ -#ifdef USE_WINDOWS_FILE - - DWORD sizeHigh; - DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); - if (sizeLow == 0xFFFFFFFF) - { - DWORD res = GetLastError(); - if (res != NO_ERROR) - return res; - } - *length = (((uint64_t)sizeHigh) << 32) + sizeLow; - return 0; - -#else - - long pos = ftell(p->file); - int res = fseek(p->file, 0, SEEK_END); - *length = ftell(p->file); - fseek(p->file, pos, SEEK_SET); - return res; - -#endif -} - - -/* ---------- FileSeqInStream ---------- */ - -static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileSeqInStream *p = (CFileSeqInStream *)pp; - return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; -} - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p) -{ - p->s.Read = FileSeqInStream_Read; -} - - -/* ---------- FileInStream ---------- */ - -static SRes FileInStream_Read(void *pp, void *buf, size_t *size) -{ - CFileInStream *p = (CFileInStream *)pp; - return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; -} - -static SRes FileInStream_Seek(void *pp, int64_t *pos, ESzSeek origin) -{ - CFileInStream *p = (CFileInStream *)pp; - return File_Seek(&p->file, pos, origin); -} - -void FileInStream_CreateVTable(CFileInStream *p) -{ - p->s.Read = FileInStream_Read; - p->s.Seek = FileInStream_Seek; -} - - -/* ---------- FileOutStream ---------- */ - -static size_t FileOutStream_Write(void *pp, const void *data, size_t size) -{ - CFileOutStream *p = (CFileOutStream *)pp; - File_Write(&p->file, data, &size); - return size; -} - -void FileOutStream_CreateVTable(CFileOutStream *p) -{ - p->s.Write = FileOutStream_Write; -} +/* 7zFile.c -- File IO + 2009-11-24 : Igor Pavlov : Public domain */ + +#include +#include "7zFile.h" + +#ifndef USE_WINDOWS_FILE + +#ifndef UNDER_CE +#include +#endif + +#else + +/* + ReadFile and WriteFile functions in Windows have BUG: + If you Read or Write 64MB or more (probably min_failure_size = 64MB - 32KB + 1) + from/to Network file, it returns ERROR_NO_SYSTEM_RESOURCES + (Insufficient system resources exist to complete the requested service). + Probably in some version of Windows there are problems with other sizes: + for 32 MB (maybe also for 16 MB). + And message can be "Network connection was lost" + */ + +#define kChunkSizeMax (1 << 22) + +#endif + +void File_Construct(CSzFile *p) +{ +#ifdef USE_WINDOWS_FILE + p->handle = INVALID_HANDLE_VALUE; +#else + p->file = NULL; +#endif +} + +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +static WRes File_Open(CSzFile *p, const char *name, int writeMode) +{ +#ifdef USE_WINDOWS_FILE + p->handle = CreateFileA(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +#else + p->file = fopen(name, writeMode ? "wb+" : "rb"); + return (p->file != 0) ? 0 : +#ifdef UNDER_CE + 2; /* ENOENT */ +#else + errno; +#endif +#endif +} + +WRes InFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 0); } +WRes OutFile_Open(CSzFile *p, const char *name) { return File_Open(p, name, 1); } +#endif + +#ifdef USE_WINDOWS_FILE +static WRes File_OpenW(CSzFile *p, const WCHAR *name, int writeMode) +{ + p->handle = CreateFileW(name, + writeMode ? GENERIC_WRITE : GENERIC_READ, + FILE_SHARE_READ, NULL, + writeMode ? CREATE_ALWAYS : OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, NULL); + return (p->handle != INVALID_HANDLE_VALUE) ? 0 : GetLastError(); +} +WRes InFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 0); } +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name) { return File_OpenW(p, name, 1); } +#endif + +WRes File_Close(CSzFile *p) +{ +#ifdef USE_WINDOWS_FILE + if (p->handle != INVALID_HANDLE_VALUE) + { + if (!CloseHandle(p->handle)) + return GetLastError(); + p->handle = INVALID_HANDLE_VALUE; + } +#else + if (p->file != NULL) + { + int res = fclose(p->file); + if (res != 0) + return res; + p->file = NULL; + } +#endif + return 0; +} + +WRes File_Read(CSzFile *p, void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + +#ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = ReadFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((uint8_t*)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + +#else + + *size = fread(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + +#endif +} + +WRes File_Write(CSzFile *p, const void *data, size_t *size) +{ + size_t originalSize = *size; + if (originalSize == 0) + return 0; + +#ifdef USE_WINDOWS_FILE + + *size = 0; + do + { + DWORD curSize = (originalSize > kChunkSizeMax) ? kChunkSizeMax : (DWORD)originalSize; + DWORD processed = 0; + BOOL res = WriteFile(p->handle, data, curSize, &processed, NULL); + data = (void *)((uint8_t*)data + processed); + originalSize -= processed; + *size += processed; + if (!res) + return GetLastError(); + if (processed == 0) + break; + } + while (originalSize > 0); + return 0; + +#else + + *size = fwrite(data, 1, originalSize, p->file); + if (*size == originalSize) + return 0; + return ferror(p->file); + +#endif +} + +WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin) +{ +#ifdef USE_WINDOWS_FILE + + LARGE_INTEGER value; + DWORD moveMethod; + value.LowPart = (DWORD)*pos; + value.HighPart = (LONG)((uint64_t)*pos >> 16 >> 16); /* for case when uint64_t is 32-bit only */ + switch (origin) + { + case SZ_SEEK_SET: moveMethod = FILE_BEGIN; break; + case SZ_SEEK_CUR: moveMethod = FILE_CURRENT; break; + case SZ_SEEK_END: moveMethod = FILE_END; break; + default: return ERROR_INVALID_PARAMETER; + } + value.LowPart = SetFilePointer(p->handle, value.LowPart, &value.HighPart, moveMethod); + if (value.LowPart == 0xFFFFFFFF) + { + WRes res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *pos = ((int64_t)value.HighPart << 32) | value.LowPart; + return 0; + +#else + + int moveMethod; + int res; + switch (origin) + { + case SZ_SEEK_SET: moveMethod = SEEK_SET; break; + case SZ_SEEK_CUR: moveMethod = SEEK_CUR; break; + case SZ_SEEK_END: moveMethod = SEEK_END; break; + default: return 1; + } + res = fseek(p->file, (long)*pos, moveMethod); + *pos = ftell(p->file); + return res; + +#endif +} + +WRes File_GetLength(CSzFile *p, uint64_t *length) +{ +#ifdef USE_WINDOWS_FILE + + DWORD sizeHigh; + DWORD sizeLow = GetFileSize(p->handle, &sizeHigh); + if (sizeLow == 0xFFFFFFFF) + { + DWORD res = GetLastError(); + if (res != NO_ERROR) + return res; + } + *length = (((uint64_t)sizeHigh) << 32) + sizeLow; + return 0; + +#else + + long pos = ftell(p->file); + int res = fseek(p->file, 0, SEEK_END); + *length = ftell(p->file); + fseek(p->file, pos, SEEK_SET); + return res; + +#endif +} + + +/* ---------- FileSeqInStream ---------- */ + +static SRes FileSeqInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileSeqInStream *p = (CFileSeqInStream *)pp; + return File_Read(&p->file, buf, size) == 0 ? SZ_OK : SZ_ERROR_READ; +} + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p) +{ + p->s.Read = FileSeqInStream_Read; +} + + +/* ---------- FileInStream ---------- */ + +static SRes FileInStream_Read(void *pp, void *buf, size_t *size) +{ + CFileInStream *p = (CFileInStream *)pp; + return (File_Read(&p->file, buf, size) == 0) ? SZ_OK : SZ_ERROR_READ; +} + +static SRes FileInStream_Seek(void *pp, int64_t *pos, ESzSeek origin) +{ + CFileInStream *p = (CFileInStream *)pp; + return File_Seek(&p->file, pos, origin); +} + +void FileInStream_CreateVTable(CFileInStream *p) +{ + p->s.Read = FileInStream_Read; + p->s.Seek = FileInStream_Seek; +} + + +/* ---------- FileOutStream ---------- */ + +static size_t FileOutStream_Write(void *pp, const void *data, size_t size) +{ + CFileOutStream *p = (CFileOutStream *)pp; + File_Write(&p->file, data, &size); + return size; +} + +void FileOutStream_CreateVTable(CFileOutStream *p) +{ + p->s.Write = FileOutStream_Write; +} diff --git a/deps/7zip/7zFile.h b/deps/7zip/7zFile.h index 86c3ed1060..33910ec420 100644 --- a/deps/7zip/7zFile.h +++ b/deps/7zip/7zFile.h @@ -1,87 +1,87 @@ -/* 7zFile.h -- File IO -2009-11-24 : Igor Pavlov : Public domain */ - -#ifndef __7Z_FILE_H -#define __7Z_FILE_H - -#ifdef _WIN32 -#define USE_WINDOWS_FILE -#endif - -#ifdef USE_WINDOWS_FILE -#include -#else -#include -#endif - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------- File ---------- */ - -typedef struct -{ - #ifdef USE_WINDOWS_FILE - HANDLE handle; - #else - FILE *file; - #endif -} CSzFile; - -void File_Construct(CSzFile *p); -#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) -WRes InFile_Open(CSzFile *p, const char *name); -WRes OutFile_Open(CSzFile *p, const char *name); -#endif -#ifdef USE_WINDOWS_FILE -WRes InFile_OpenW(CSzFile *p, const WCHAR *name); -WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); -#endif -WRes File_Close(CSzFile *p); - -/* reads max(*size, remain file's size) bytes */ -WRes File_Read(CSzFile *p, void *data, size_t *size); - -/* writes *size bytes */ -WRes File_Write(CSzFile *p, const void *data, size_t *size); - -WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin); -WRes File_GetLength(CSzFile *p, uint64_t *length); - - -/* ---------- FileInStream ---------- */ - -typedef struct -{ - ISeqInStream s; - CSzFile file; -} CFileSeqInStream; - -void FileSeqInStream_CreateVTable(CFileSeqInStream *p); - - -typedef struct -{ - ISeekInStream s; - CSzFile file; -} CFileInStream; - -void FileInStream_CreateVTable(CFileInStream *p); - - -typedef struct -{ - ISeqOutStream s; - CSzFile file; -} CFileOutStream; - -void FileOutStream_CreateVTable(CFileOutStream *p); - -#ifdef __cplusplus -} -#endif - -#endif +/* 7zFile.h -- File IO +2009-11-24 : Igor Pavlov : Public domain */ + +#ifndef __7Z_FILE_H +#define __7Z_FILE_H + +#ifdef _WIN32 +#define USE_WINDOWS_FILE +#endif + +#ifdef USE_WINDOWS_FILE +#include +#else +#include +#endif + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- File ---------- */ + +typedef struct +{ + #ifdef USE_WINDOWS_FILE + HANDLE handle; + #else + FILE *file; + #endif +} CSzFile; + +void File_Construct(CSzFile *p); +#if !defined(UNDER_CE) || !defined(USE_WINDOWS_FILE) +WRes InFile_Open(CSzFile *p, const char *name); +WRes OutFile_Open(CSzFile *p, const char *name); +#endif +#ifdef USE_WINDOWS_FILE +WRes InFile_OpenW(CSzFile *p, const WCHAR *name); +WRes OutFile_OpenW(CSzFile *p, const WCHAR *name); +#endif +WRes File_Close(CSzFile *p); + +/* reads max(*size, remain file's size) bytes */ +WRes File_Read(CSzFile *p, void *data, size_t *size); + +/* writes *size bytes */ +WRes File_Write(CSzFile *p, const void *data, size_t *size); + +WRes File_Seek(CSzFile *p, int64_t *pos, ESzSeek origin); +WRes File_GetLength(CSzFile *p, uint64_t *length); + + +/* ---------- FileInStream ---------- */ + +typedef struct +{ + ISeqInStream s; + CSzFile file; +} CFileSeqInStream; + +void FileSeqInStream_CreateVTable(CFileSeqInStream *p); + + +typedef struct +{ + ISeekInStream s; + CSzFile file; +} CFileInStream; + +void FileInStream_CreateVTable(CFileInStream *p); + + +typedef struct +{ + ISeqOutStream s; + CSzFile file; +} CFileOutStream; + +void FileOutStream_CreateVTable(CFileOutStream *p); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/7zIn.c b/deps/7zip/7zIn.c index b2b67b063b..62c1d5eb82 100644 --- a/deps/7zip/7zIn.c +++ b/deps/7zip/7zIn.c @@ -1,1371 +1,1371 @@ -/* 7zIn.c -- 7z Input functions - 2010-10-29 : Igor Pavlov : Public domain */ - -#include -#include - -#include "7z.h" -#include "7zCrc.h" -#include "CpuArch.h" - -uint8_t k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - -#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } - -#define NUM_FOLDER_CODERS_MAX 32 -#define NUM_CODER_STREAMS_MAX 32 - -void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc); -int SzFolder_FindBindPairForOutStream(CSzFolder *p, uint32_t outStreamIndex); - -void SzCoderInfo_Init(CSzCoderInfo *p) -{ - Buf_Init(&p->Props); -} - -void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) -{ - Buf_Free(&p->Props, alloc); - SzCoderInfo_Init(p); -} - -void SzFolder_Init(CSzFolder *p) -{ - p->Coders = 0; - p->BindPairs = 0; - p->PackStreams = 0; - p->UnpackSizes = 0; - p->NumCoders = 0; - p->NumBindPairs = 0; - p->NumPackStreams = 0; - p->UnpackCRCDefined = 0; - p->UnpackCRC = 0; - p->NumUnpackStreams = 0; -} - -void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) -{ - uint32_t i; - if (p->Coders) - for (i = 0; i < p->NumCoders; i++) - SzCoderInfo_Free(&p->Coders[i], alloc); - IAlloc_Free(alloc, p->Coders); - IAlloc_Free(alloc, p->BindPairs); - IAlloc_Free(alloc, p->PackStreams); - IAlloc_Free(alloc, p->UnpackSizes); - SzFolder_Init(p); -} - -uint32_t SzFolder_GetNumOutStreams(CSzFolder *p) -{ - uint32_t result = 0; - uint32_t i; - for (i = 0; i < p->NumCoders; i++) - result += p->Coders[i].NumOutStreams; - return result; -} - -int SzFolder_FindBindPairForInStream(CSzFolder *p, uint32_t inStreamIndex) -{ - uint32_t i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].InIndex == inStreamIndex) - return i; - return -1; -} - - -int SzFolder_FindBindPairForOutStream(CSzFolder *p, uint32_t outStreamIndex) -{ - uint32_t i; - for (i = 0; i < p->NumBindPairs; i++) - if (p->BindPairs[i].OutIndex == outStreamIndex) - return i; - return -1; -} - -uint64_t SzFolder_GetUnpackSize(CSzFolder *p) -{ - int i = (int)SzFolder_GetNumOutStreams(p); - if (i == 0) - return 0; - for (i--; i >= 0; i--) - if (SzFolder_FindBindPairForOutStream(p, i) < 0) - return p->UnpackSizes[i]; - /* throw 1; */ - return 0; -} - -void SzFile_Init(CSzFileItem *p) -{ - p->HasStream = 1; - p->IsDir = 0; - p->IsAnti = 0; - p->CrcDefined = 0; - p->MTimeDefined = 0; -} - -void SzAr_Init(CSzAr *p) -{ - p->PackSizes = 0; - p->PackCRCsDefined = 0; - p->PackCRCs = 0; - p->Folders = 0; - p->Files = 0; - p->NumPackStreams = 0; - p->NumFolders = 0; - p->NumFiles = 0; -} - -void SzAr_Free(CSzAr *p, ISzAlloc *alloc) -{ - uint32_t i; - if (p->Folders) - for (i = 0; i < p->NumFolders; i++) - SzFolder_Free(&p->Folders[i], alloc); - - IAlloc_Free(alloc, p->PackSizes); - IAlloc_Free(alloc, p->PackCRCsDefined); - IAlloc_Free(alloc, p->PackCRCs); - IAlloc_Free(alloc, p->Folders); - IAlloc_Free(alloc, p->Files); - SzAr_Init(p); -} - - -void SzArEx_Init(CSzArEx *p) -{ - SzAr_Init(&p->db); - p->FolderStartPackStreamIndex = 0; - p->PackStreamStartPositions = 0; - p->FolderStartFileIndex = 0; - p->FileIndexToFolderIndexMap = 0; - p->FileNameOffsets = 0; - Buf_Init(&p->FileNames); -} - -void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) -{ - IAlloc_Free(alloc, p->FolderStartPackStreamIndex); - IAlloc_Free(alloc, p->PackStreamStartPositions); - IAlloc_Free(alloc, p->FolderStartFileIndex); - IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); - - IAlloc_Free(alloc, p->FileNameOffsets); - Buf_Free(&p->FileNames, alloc); - - SzAr_Free(&p->db, alloc); - SzArEx_Init(p); -} - -/* - uint64_t GetFolderPackStreamSize(int folderIndex, int streamIndex) const - { - return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; - } - - uint64_t GetFilePackSize(int fileIndex) const - { - int folderIndex = FileIndexToFolderIndexMap[fileIndex]; - if (folderIndex >= 0) - { - const CSzFolder &folderInfo = Folders[folderIndex]; - if (FolderStartFileIndex[folderIndex] == fileIndex) - return GetFolderFullPackSize(folderIndex); - } - return 0; - } - */ - -#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ - if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } - -static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) -{ - uint32_t startPos = 0; - uint64_t startPosSize = 0; - uint32_t i; - uint32_t folderIndex = 0; - uint32_t indexInFolder = 0; - MY_ALLOC(uint32_t, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); - for (i = 0; i < p->db.NumFolders; i++) - { - p->FolderStartPackStreamIndex[i] = startPos; - startPos += p->db.Folders[i].NumPackStreams; - } - - MY_ALLOC(uint64_t, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); - - for (i = 0; i < p->db.NumPackStreams; i++) - { - p->PackStreamStartPositions[i] = startPosSize; - startPosSize += p->db.PackSizes[i]; - } - - MY_ALLOC(uint32_t, p->FolderStartFileIndex, p->db.NumFolders, alloc); - MY_ALLOC(uint32_t, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); - - for (i = 0; i < p->db.NumFiles; i++) - { - CSzFileItem *file = p->db.Files + i; - int emptyStream = !file->HasStream; - if (emptyStream && indexInFolder == 0) - { - p->FileIndexToFolderIndexMap[i] = (uint32_t)-1; - continue; - } - if (indexInFolder == 0) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: Loop for skipping empty folders - */ - for (;;) - { - if (folderIndex >= p->db.NumFolders) - return SZ_ERROR_ARCHIVE; - p->FolderStartFileIndex[folderIndex] = i; - if (p->db.Folders[folderIndex].NumUnpackStreams != 0) - break; - folderIndex++; - } - } - p->FileIndexToFolderIndexMap[i] = folderIndex; - if (emptyStream) - continue; - indexInFolder++; - if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) - { - folderIndex++; - indexInFolder = 0; - } - } - return SZ_OK; -} - - -uint64_t SzArEx_GetFolderStreamPos(const CSzArEx *p, uint32_t folderIndex, uint32_t indexInFolder) -{ - return p->dataPos + - p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; -} - -int SzArEx_GetFolderFullPackSize(const CSzArEx *p, uint32_t folderIndex, uint64_t *resSize) -{ - uint32_t packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; - CSzFolder *folder = p->db.Folders + folderIndex; - uint64_t size = 0; - uint32_t i; - for (i = 0; i < folder->NumPackStreams; i++) - { - uint64_t t = size + p->db.PackSizes[packStreamIndex + i]; - if (t < size) /* check it */ - return SZ_ERROR_FAIL; - size = t; - } - *resSize = size; - return SZ_OK; -} - - -static int TestSignatureCandidate(uint8_t *testuint8_ts) -{ - size_t i; - for (i = 0; i < k7zSignatureSize; i++) - if (testuint8_ts[i] != k7zSignature[i]) - return 0; - return 1; -} - -typedef struct _CSzState -{ - uint8_t *Data; - size_t Size; -}CSzData; - -static SRes SzReaduint8_t(CSzData *sd, uint8_t *b) -{ - if (sd->Size == 0) - return SZ_ERROR_ARCHIVE; - sd->Size--; - *b = *sd->Data++; - return SZ_OK; -} - -static SRes SzReaduint8_ts(CSzData *sd, uint8_t *data, size_t size) -{ - size_t i; - for (i = 0; i < size; i++) - { - RINOK(SzReaduint8_t(sd, data + i)); - } - return SZ_OK; -} - -static SRes SzReaduint32_t(CSzData *sd, uint32_t *value) -{ - int i; - *value = 0; - for (i = 0; i < 4; i++) - { - uint8_t b; - RINOK(SzReaduint8_t(sd, &b)); - *value |= ((uint32_t)(b) << (8 * i)); - } - return SZ_OK; -} - -static SRes SzReadNumber(CSzData *sd, uint64_t *value) -{ - uint8_t firstuint8_t; - uint8_t mask = 0x80; - int i; - RINOK(SzReaduint8_t(sd, &firstuint8_t)); - *value = 0; - for (i = 0; i < 8; i++) - { - uint8_t b; - if ((firstuint8_t & mask) == 0) - { - uint64_t highPart = firstuint8_t & (mask - 1); - *value += (highPart << (8 * i)); - return SZ_OK; - } - RINOK(SzReaduint8_t(sd, &b)); - *value |= ((uint64_t)b << (8 * i)); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadNumber32(CSzData *sd, uint32_t *value) -{ - uint64_t value64; - RINOK(SzReadNumber(sd, &value64)); - if (value64 >= 0x80000000) - return SZ_ERROR_UNSUPPORTED; - if (value64 >= ((uint64_t)(1) << ((sizeof(size_t) - 1) * 8 + 2))) - return SZ_ERROR_UNSUPPORTED; - *value = (uint32_t)value64; - return SZ_OK; -} - -static SRes SzReadID(CSzData *sd, uint64_t *value) -{ - return SzReadNumber(sd, value); -} - -static SRes SzSkeepDataSize(CSzData *sd, uint64_t size) -{ - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - sd->Size -= (size_t)size; - sd->Data += (size_t)size; - return SZ_OK; -} - -static SRes SzSkeepData(CSzData *sd) -{ - uint64_t size; - RINOK(SzReadNumber(sd, &size)); - return SzSkeepDataSize(sd, size); -} - -static SRes SzReadArchiveProperties(CSzData *sd) -{ - for (;;) - { - uint64_t type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - SzSkeepData(sd); - } - return SZ_OK; -} - -static SRes SzWaitAttribute(CSzData *sd, uint64_t attribute) -{ - for (;;) - { - uint64_t type; - RINOK(SzReadID(sd, &type)); - if (type == attribute) - return SZ_OK; - if (type == k7zIdEnd) - return SZ_ERROR_ARCHIVE; - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadBoolVector(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc) -{ - uint8_t b = 0; - uint8_t mask = 0; - size_t i; - MY_ALLOC(uint8_t, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - { - if (mask == 0) - { - RINOK(SzReaduint8_t(sd, &b)); - mask = 0x80; - } - (*v)[i] = (uint8_t)(((b & mask) != 0) ? 1 : 0); - mask >>= 1; - } - return SZ_OK; -} - -static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc) -{ - uint8_t allAreDefined; - size_t i; - RINOK(SzReaduint8_t(sd, &allAreDefined)); - if (allAreDefined == 0) - return SzReadBoolVector(sd, numItems, v, alloc); - MY_ALLOC(uint8_t, *v, numItems, alloc); - for (i = 0; i < numItems; i++) - (*v)[i] = 1; - return SZ_OK; -} - -static SRes SzReadHashDigests( - CSzData *sd, - size_t numItems, - uint8_t **digestsDefined, - uint32_t **digests, - ISzAlloc *alloc) -{ - size_t i; - RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); - MY_ALLOC(uint32_t, *digests, numItems, alloc); - for (i = 0; i < numItems; i++) - if ((*digestsDefined)[i]) - { - RINOK(SzReaduint32_t(sd, (*digests) + i)); - } - return SZ_OK; -} - -static SRes SzReadPackInfo( - CSzData *sd, - uint64_t *dataOffset, - uint32_t *numPackStreams, - uint64_t **packSizes, - uint8_t **packCRCsDefined, - uint32_t **packCRCs, - ISzAlloc *alloc) -{ - uint32_t i; - RINOK(SzReadNumber(sd, dataOffset)); - RINOK(SzReadNumber32(sd, numPackStreams)); - - RINOK(SzWaitAttribute(sd, k7zIdSize)); - - MY_ALLOC(uint64_t, *packSizes, (size_t)*numPackStreams, alloc); - - for (i = 0; i < *numPackStreams; i++) - { - RINOK(SzReadNumber(sd, (*packSizes) + i)); - } - - for (;;) - { - uint64_t type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - if (type == k7zIdCRC) - { - RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); - continue; - } - RINOK(SzSkeepData(sd)); - } - if (*packCRCsDefined == 0) - { - MY_ALLOC(uint8_t, *packCRCsDefined, (size_t)*numPackStreams, alloc); - MY_ALLOC(uint32_t, *packCRCs, (size_t)*numPackStreams, alloc); - for (i = 0; i < *numPackStreams; i++) - { - (*packCRCsDefined)[i] = 0; - (*packCRCs)[i] = 0; - } - } - return SZ_OK; -} - -static SRes SzReadSwitch(CSzData *sd) -{ - uint8_t external; - RINOK(SzReaduint8_t(sd, &external)); - return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; -} - -static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) -{ - uint32_t numCoders, numBindPairs, numPackStreams, i; - uint32_t numInStreams = 0, numOutStreams = 0; - - RINOK(SzReadNumber32(sd, &numCoders)); - if (numCoders > NUM_FOLDER_CODERS_MAX) - return SZ_ERROR_UNSUPPORTED; - folder->NumCoders = numCoders; - - MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); - - for (i = 0; i < numCoders; i++) - SzCoderInfo_Init(folder->Coders + i); - - for (i = 0; i < numCoders; i++) - { - uint8_t mainuint8_t; - CSzCoderInfo *coder = folder->Coders + i; - { - unsigned idSize, j; - uint8_t longID[15]; - RINOK(SzReaduint8_t(sd, &mainuint8_t)); - idSize = (unsigned)(mainuint8_t & 0xF); - RINOK(SzReaduint8_ts(sd, longID, idSize)); - if (idSize > sizeof(coder->MethodID)) - return SZ_ERROR_UNSUPPORTED; - coder->MethodID = 0; - for (j = 0; j < idSize; j++) - coder->MethodID |= (uint64_t)longID[idSize - 1 - j] << (8 * j); - - if ((mainuint8_t & 0x10) != 0) - { - RINOK(SzReadNumber32(sd, &coder->NumInStreams)); - RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); - if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || - coder->NumOutStreams > NUM_CODER_STREAMS_MAX) - return SZ_ERROR_UNSUPPORTED; - } - else - { - coder->NumInStreams = 1; - coder->NumOutStreams = 1; - } - if ((mainuint8_t & 0x20) != 0) - { - uint64_t propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) - return SZ_ERROR_MEM; - RINOK(SzReaduint8_ts(sd, coder->Props.data, (size_t)propertiesSize)); - } - } - while ((mainuint8_t & 0x80) != 0) - { - RINOK(SzReaduint8_t(sd, &mainuint8_t)); - RINOK(SzSkeepDataSize(sd, (mainuint8_t & 0xF))); - if ((mainuint8_t & 0x10) != 0) - { - uint32_t n; - RINOK(SzReadNumber32(sd, &n)); - RINOK(SzReadNumber32(sd, &n)); - } - if ((mainuint8_t & 0x20) != 0) - { - uint64_t propertiesSize = 0; - RINOK(SzReadNumber(sd, &propertiesSize)); - RINOK(SzSkeepDataSize(sd, propertiesSize)); - } - } - numInStreams += coder->NumInStreams; - numOutStreams += coder->NumOutStreams; - } - - if (numOutStreams == 0) - return SZ_ERROR_UNSUPPORTED; - - folder->NumBindPairs = numBindPairs = numOutStreams - 1; - MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); - - for (i = 0; i < numBindPairs; i++) - { - CSzBindPair *bp = folder->BindPairs + i; - RINOK(SzReadNumber32(sd, &bp->InIndex)); - RINOK(SzReadNumber32(sd, &bp->OutIndex)); - } - - if (numInStreams < numBindPairs) - return SZ_ERROR_UNSUPPORTED; - - folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; - MY_ALLOC(uint32_t, folder->PackStreams, (size_t)numPackStreams, alloc); - - if (numPackStreams == 1) - { - for (i = 0; i < numInStreams ; i++) - if (SzFolder_FindBindPairForInStream(folder, i) < 0) - break; - if (i == numInStreams) - return SZ_ERROR_UNSUPPORTED; - folder->PackStreams[0] = i; - } - else - for (i = 0; i < numPackStreams; i++) - { - RINOK(SzReadNumber32(sd, folder->PackStreams + i)); - } - return SZ_OK; -} - -static SRes SzReadUnpackInfo( - CSzData *sd, - uint32_t *numFolders, - CSzFolder **folders, /* for alloc */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - uint32_t i; - RINOK(SzWaitAttribute(sd, k7zIdFolder)); - RINOK(SzReadNumber32(sd, numFolders)); - { - RINOK(SzReadSwitch(sd)); - - MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); - - for (i = 0; i < *numFolders; i++) - SzFolder_Init((*folders) + i); - - for (i = 0; i < *numFolders; i++) - { - RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); - } - } - - RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); - - for (i = 0; i < *numFolders; i++) - { - uint32_t j; - CSzFolder *folder = (*folders) + i; - uint32_t numOutStreams = SzFolder_GetNumOutStreams(folder); - - MY_ALLOC(uint64_t, folder->UnpackSizes, (size_t)numOutStreams, alloc); - - for (j = 0; j < numOutStreams; j++) - { - RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); - } - } - - for (;;) - { - uint64_t type; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - return SZ_OK; - if (type == k7zIdCRC) - { - SRes res; - uint8_t *crcsDefined = 0; - uint32_t *crcs = 0; - res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < *numFolders; i++) - { - CSzFolder *folder = (*folders) + i; - folder->UnpackCRCDefined = crcsDefined[i]; - folder->UnpackCRC = crcs[i]; - } - } - IAlloc_Free(allocTemp, crcs); - IAlloc_Free(allocTemp, crcsDefined); - RINOK(res); - continue; - } - RINOK(SzSkeepData(sd)); - } -} - -static SRes SzReadSubStreamsInfo( - CSzData *sd, - uint32_t numFolders, - CSzFolder *folders, - uint32_t *numUnpackStreams, - uint64_t **unpackSizes, - uint8_t **digestsDefined, - uint32_t **digests, - ISzAlloc *allocTemp) -{ - uint64_t type = 0; - uint32_t i; - uint32_t si = 0; - uint32_t numDigests = 0; - - for (i = 0; i < numFolders; i++) - folders[i].NumUnpackStreams = 1; - *numUnpackStreams = numFolders; - - for (;;) - { - RINOK(SzReadID(sd, &type)); - if (type == k7zIdNumUnpackStream) - { - *numUnpackStreams = 0; - for (i = 0; i < numFolders; i++) - { - uint32_t numStreams; - RINOK(SzReadNumber32(sd, &numStreams)); - folders[i].NumUnpackStreams = numStreams; - *numUnpackStreams += numStreams; - } - continue; - } - if (type == k7zIdCRC || type == k7zIdSize) - break; - if (type == k7zIdEnd) - break; - RINOK(SzSkeepData(sd)); - } - - if (*numUnpackStreams == 0) - { - *unpackSizes = 0; - *digestsDefined = 0; - *digests = 0; - } - else - { - *unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t)); - RINOM(*unpackSizes); - *digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t)); - RINOM(*digestsDefined); - *digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t)); - RINOM(*digests); - } - - for (i = 0; i < numFolders; i++) - { - /* - v3.13 incorrectly worked with empty folders - v4.07: we check that folder is empty - */ - uint64_t sum = 0; - uint32_t j; - uint32_t numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams == 0) - continue; - if (type == k7zIdSize) - for (j = 1; j < numSubstreams; j++) - { - uint64_t size; - RINOK(SzReadNumber(sd, &size)); - (*unpackSizes)[si++] = size; - sum += size; - } - (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; - } - if (type == k7zIdSize) - { - RINOK(SzReadID(sd, &type)); - } - - for (i = 0; i < *numUnpackStreams; i++) - { - (*digestsDefined)[i] = 0; - (*digests)[i] = 0; - } - - - for (i = 0; i < numFolders; i++) - { - uint32_t numSubstreams = folders[i].NumUnpackStreams; - if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) - numDigests += numSubstreams; - } - - - si = 0; - for (;;) - { - if (type == k7zIdCRC) - { - int digestIndex = 0; - uint8_t *digestsDefined2 = 0; - uint32_t *digests2 = 0; - SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); - if (res == SZ_OK) - { - for (i = 0; i < numFolders; i++) - { - CSzFolder *folder = folders + i; - uint32_t numSubstreams = folder->NumUnpackStreams; - if (numSubstreams == 1 && folder->UnpackCRCDefined) - { - (*digestsDefined)[si] = 1; - (*digests)[si] = folder->UnpackCRC; - si++; - } - else - { - uint32_t j; - for (j = 0; j < numSubstreams; j++, digestIndex++) - { - (*digestsDefined)[si] = digestsDefined2[digestIndex]; - (*digests)[si] = digests2[digestIndex]; - si++; - } - } - } - } - IAlloc_Free(allocTemp, digestsDefined2); - IAlloc_Free(allocTemp, digests2); - RINOK(res); - } - else if (type == k7zIdEnd) - return SZ_OK; - else - { - RINOK(SzSkeepData(sd)); - } - RINOK(SzReadID(sd, &type)); - } -} - - -static SRes SzReadStreamsInfo( - CSzData *sd, - uint64_t *dataOffset, - CSzAr *p, - uint32_t *numUnpackStreams, - uint64_t **unpackSizes, /* allocTemp */ - uint8_t **digestsDefined, /* allocTemp */ - uint32_t **digests, /* allocTemp */ - ISzAlloc *alloc, - ISzAlloc *allocTemp) -{ - for (;;) - { - uint64_t type; - RINOK(SzReadID(sd, &type)); - if ((uint64_t)(int)type != type) - return SZ_ERROR_UNSUPPORTED; - switch((int)type) - { - case k7zIdEnd: - return SZ_OK; - case k7zIdPackInfo: - { - RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, - &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); - break; - } - case k7zIdUnpackInfo: - { - RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); - break; - } - case k7zIdSubStreamsInfo: - { - RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, - numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); - break; - } - default: - return SZ_ERROR_UNSUPPORTED; - } - } -} - -size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, uint16_t *dest) -{ - size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; - if (dest != 0) - { - size_t i; - const uint8_t *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); - for (i = 0; i < len; i++) - dest[i] = GetUi16(src + i * 2); - } - return len; -} - -static SRes SzReadFileNames(const uint8_t *p, size_t size, uint32_t numFiles, size_t *sizes) -{ - uint32_t i; - size_t pos = 0; - for (i = 0; i < numFiles; i++) - { - sizes[i] = pos; - for (;;) - { - if (pos >= size) - return SZ_ERROR_ARCHIVE; - if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) - break; - pos++; - } - pos++; - } - sizes[i] = pos; - return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; -} - -static SRes SzReadHeader2( - CSzArEx *p, /* allocMain */ - CSzData *sd, - uint64_t **unpackSizes, /* allocTemp */ - uint8_t **digestsDefined, /* allocTemp */ - uint32_t **digests, /* allocTemp */ - uint8_t **emptyStreamVector, /* allocTemp */ - uint8_t **emptyFileVector, /* allocTemp */ - uint8_t **lwtVector, /* allocTemp */ - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - uint64_t type; - uint32_t numUnpackStreams = 0; - uint32_t numFiles = 0; - CSzFileItem *files = 0; - uint32_t numEmptyStreams = 0; - uint32_t i; - - RINOK(SzReadID(sd, &type)); - - if (type == k7zIdArchiveProperties) - { - RINOK(SzReadArchiveProperties(sd)); - RINOK(SzReadID(sd, &type)); - } - - - if (type == k7zIdMainStreamsInfo) - { - RINOK(SzReadStreamsInfo(sd, - &p->dataPos, - &p->db, - &numUnpackStreams, - unpackSizes, - digestsDefined, - digests, allocMain, allocTemp)); - p->dataPos += p->startPosAfterHeader; - RINOK(SzReadID(sd, &type)); - } - - if (type == k7zIdEnd) - return SZ_OK; - if (type != k7zIdFilesInfo) - return SZ_ERROR_ARCHIVE; - - RINOK(SzReadNumber32(sd, &numFiles)); - p->db.NumFiles = numFiles; - - MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); - - p->db.Files = files; - for (i = 0; i < numFiles; i++) - SzFile_Init(files + i); - - for (;;) - { - uint64_t size; - RINOK(SzReadID(sd, &type)); - if (type == k7zIdEnd) - break; - RINOK(SzReadNumber(sd, &size)); - if (size > sd->Size) - return SZ_ERROR_ARCHIVE; - if ((uint64_t)(int)type != type) - { - RINOK(SzSkeepDataSize(sd, size)); - } - else - switch((int)type) - { - case k7zIdName: - { - size_t namesSize; - RINOK(SzReadSwitch(sd)); - namesSize = (size_t)size - 1; - if ((namesSize & 1) != 0) - return SZ_ERROR_ARCHIVE; - if (!Buf_Create(&p->FileNames, namesSize, allocMain)) - return SZ_ERROR_MEM; - MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); - memcpy(p->FileNames.data, sd->Data, namesSize); - RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) - RINOK(SzSkeepDataSize(sd, namesSize)); - break; - } - case k7zIdEmptyStream: - { - RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); - numEmptyStreams = 0; - for (i = 0; i < numFiles; i++) - if ((*emptyStreamVector)[i]) - numEmptyStreams++; - break; - } - case k7zIdEmptyFile: - { - RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); - break; - } - case k7zIdWinAttributes: - { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); - RINOK(SzReadSwitch(sd)); - for (i = 0; i < numFiles; i++) - { - CSzFileItem *f = &files[i]; - uint8_t defined = (*lwtVector)[i]; - f->AttribDefined = defined; - f->Attrib = 0; - if (defined) - { - RINOK(SzReaduint32_t(sd, &f->Attrib)); - } - } - IAlloc_Free(allocTemp, *lwtVector); - *lwtVector = NULL; - break; - } - case k7zIdMTime: - { - RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); - RINOK(SzReadSwitch(sd)); - for (i = 0; i < numFiles; i++) - { - CSzFileItem *f = &files[i]; - uint8_t defined = (*lwtVector)[i]; - f->MTimeDefined = defined; - f->MTime.Low = f->MTime.High = 0; - if (defined) - { - RINOK(SzReaduint32_t(sd, &f->MTime.Low)); - RINOK(SzReaduint32_t(sd, &f->MTime.High)); - } - } - IAlloc_Free(allocTemp, *lwtVector); - *lwtVector = NULL; - break; - } - default: - { - RINOK(SzSkeepDataSize(sd, size)); - } - } - } - - { - uint32_t emptyFileIndex = 0; - uint32_t sizeIndex = 0; - for (i = 0; i < numFiles; i++) - { - CSzFileItem *file = files + i; - file->IsAnti = 0; - if (*emptyStreamVector == 0) - file->HasStream = 1; - else - file->HasStream = (uint8_t)((*emptyStreamVector)[i] ? 0 : 1); - if (file->HasStream) - { - file->IsDir = 0; - file->Size = (*unpackSizes)[sizeIndex]; - file->Crc = (*digests)[sizeIndex]; - file->CrcDefined = (uint8_t)(*digestsDefined)[sizeIndex]; - sizeIndex++; - } - else - { - if (*emptyFileVector == 0) - file->IsDir = 1; - else - file->IsDir = (uint8_t)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); - emptyFileIndex++; - file->Size = 0; - file->Crc = 0; - file->CrcDefined = 0; - } - } - } - return SzArEx_Fill(p, allocMain); -} - -static SRes SzReadHeader( - CSzArEx *p, - CSzData *sd, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - uint64_t *unpackSizes = 0; - uint8_t *digestsDefined = 0; - uint32_t *digests = 0; - uint8_t *emptyStreamVector = 0; - uint8_t *emptyFileVector = 0; - uint8_t *lwtVector = 0; - SRes res = SzReadHeader2(p, sd, - &unpackSizes, &digestsDefined, &digests, - &emptyStreamVector, &emptyFileVector, &lwtVector, - allocMain, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - IAlloc_Free(allocTemp, emptyStreamVector); - IAlloc_Free(allocTemp, emptyFileVector); - IAlloc_Free(allocTemp, lwtVector); - return res; -} - -static SRes SzReadAndDecodePackedStreams2( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - uint64_t baseOffset, - CSzAr *p, - uint64_t **unpackSizes, - uint8_t **digestsDefined, - uint32_t **digests, - ISzAlloc *allocTemp) -{ - - uint32_t numUnpackStreams = 0; - uint64_t dataStartPos; - CSzFolder *folder; - uint64_t unpackSize; - SRes res; - - RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, - &numUnpackStreams, unpackSizes, digestsDefined, digests, - allocTemp, allocTemp)); - - dataStartPos += baseOffset; - if (p->NumFolders != 1) - return SZ_ERROR_ARCHIVE; - - folder = p->Folders; - unpackSize = SzFolder_GetUnpackSize(folder); - - RINOK(LookInStream_SeekTo(inStream, dataStartPos)); - - if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) - return SZ_ERROR_MEM; - - res = SzFolder_Decode(folder, p->PackSizes, - inStream, dataStartPos, - outBuffer->data, (size_t)unpackSize, allocTemp); - RINOK(res); - if (folder->UnpackCRCDefined) - if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) - return SZ_ERROR_CRC; - return SZ_OK; -} - -static SRes SzReadAndDecodePackedStreams( - ILookInStream *inStream, - CSzData *sd, - CBuf *outBuffer, - uint64_t baseOffset, - ISzAlloc *allocTemp) -{ - CSzAr p; - uint64_t *unpackSizes = 0; - uint8_t *digestsDefined = 0; - uint32_t *digests = 0; - SRes res; - SzAr_Init(&p); - res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, - &p, &unpackSizes, &digestsDefined, &digests, - allocTemp); - SzAr_Free(&p, allocTemp); - IAlloc_Free(allocTemp, unpackSizes); - IAlloc_Free(allocTemp, digestsDefined); - IAlloc_Free(allocTemp, digests); - return res; -} - -static SRes SzArEx_Open2( - CSzArEx *p, - ILookInStream *inStream, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - uint8_t header[k7zStartHeaderSize]; - int64_t startArcPos; - uint64_t nextHeaderOffset, nextHeaderSize; - size_t nextHeaderSizeT; - uint32_t nextHeaderCRC; - CBuf buffer; - SRes res; - - startArcPos = 0; - RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); - - RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); - - if (!TestSignatureCandidate(header)) - return SZ_ERROR_NO_ARCHIVE; - if (header[6] != k7zMajorVersion) - return SZ_ERROR_UNSUPPORTED; - - nextHeaderOffset = GetUi64(header + 12); - nextHeaderSize = GetUi64(header + 20); - nextHeaderCRC = GetUi32(header + 28); - - p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; - - if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) - return SZ_ERROR_CRC; - - nextHeaderSizeT = (size_t)nextHeaderSize; - if (nextHeaderSizeT != nextHeaderSize) - return SZ_ERROR_MEM; - if (nextHeaderSizeT == 0) - return SZ_OK; - if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || - nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) - return SZ_ERROR_NO_ARCHIVE; - - { - int64_t pos = 0; - RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); - if ((uint64_t)pos < startArcPos + nextHeaderOffset || - (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || - (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) - return SZ_ERROR_INPUT_EOF; - } - - RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); - - if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) - return SZ_ERROR_MEM; - - res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); - if (res == SZ_OK) - { - res = SZ_ERROR_ARCHIVE; - if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) - { - CSzData sd; - uint64_t type; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - if (res == SZ_OK) - { - if (type == k7zIdEncodedHeader) - { - CBuf outBuffer; - Buf_Init(&outBuffer); - res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); - if (res != SZ_OK) - Buf_Free(&outBuffer, allocTemp); - else - { - Buf_Free(&buffer, allocTemp); - buffer.data = outBuffer.data; - buffer.size = outBuffer.size; - sd.Data = buffer.data; - sd.Size = buffer.size; - res = SzReadID(&sd, &type); - } - } - } - if (res == SZ_OK) - { - if (type == k7zIdHeader) - res = SzReadHeader(p, &sd, allocMain, allocTemp); - else - res = SZ_ERROR_UNSUPPORTED; - } - } - } - Buf_Free(&buffer, allocTemp); - return res; -} - -SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) -{ - SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); - if (res != SZ_OK) - SzArEx_Free(p, allocMain); - return res; -} - -SRes SzArEx_Extract( - const CSzArEx *p, - ILookInStream *inStream, - uint32_t fileIndex, - uint32_t *blockIndex, - uint8_t **outBuffer, - size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, - ISzAlloc *allocMain, - ISzAlloc *allocTemp) -{ - uint32_t folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; - SRes res = SZ_OK; - *offset = 0; - *outSizeProcessed = 0; - if (folderIndex == (uint32_t)-1) - { - IAlloc_Free(allocMain, *outBuffer); - *blockIndex = folderIndex; - *outBuffer = 0; - *outBufferSize = 0; - return SZ_OK; - } - - if (*outBuffer == 0 || *blockIndex != folderIndex) - { - CSzFolder *folder = p->db.Folders + folderIndex; - uint64_t unpackSizeSpec = SzFolder_GetUnpackSize(folder); - size_t unpackSize = (size_t)unpackSizeSpec; - uint64_t startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); - - if (unpackSize != unpackSizeSpec) - return SZ_ERROR_MEM; - *blockIndex = folderIndex; - IAlloc_Free(allocMain, *outBuffer); - *outBuffer = 0; - - RINOK(LookInStream_SeekTo(inStream, startOffset)); - - if (res == SZ_OK) - { - *outBufferSize = unpackSize; - if (unpackSize != 0) - { - *outBuffer = (uint8_t *)IAlloc_Alloc(allocMain, unpackSize); - if (*outBuffer == 0) - res = SZ_ERROR_MEM; - } - if (res == SZ_OK) - { - res = SzFolder_Decode(folder, - p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], - inStream, startOffset, - *outBuffer, unpackSize, allocTemp); - if (res == SZ_OK) - { - if (folder->UnpackCRCDefined) - { - if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) - res = SZ_ERROR_CRC; - } - } - } - } - } - if (res == SZ_OK) - { - uint32_t i; - CSzFileItem *fileItem = p->db.Files + fileIndex; - *offset = 0; - for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) - *offset += (uint32_t)p->db.Files[i].Size; - *outSizeProcessed = (size_t)fileItem->Size; - if (*offset + *outSizeProcessed > *outBufferSize) - return SZ_ERROR_FAIL; - if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) - res = SZ_ERROR_CRC; - } - return res; -} +/* 7zIn.c -- 7z Input functions + 2010-10-29 : Igor Pavlov : Public domain */ + +#include +#include + +#include "7z.h" +#include "7zCrc.h" +#include "CpuArch.h" + +uint8_t k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + +#define RINOM(x) { if ((x) == 0) return SZ_ERROR_MEM; } + +#define NUM_FOLDER_CODERS_MAX 32 +#define NUM_CODER_STREAMS_MAX 32 + +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc); +int SzFolder_FindBindPairForOutStream(CSzFolder *p, uint32_t outStreamIndex); + +void SzCoderInfo_Init(CSzCoderInfo *p) +{ + Buf_Init(&p->Props); +} + +void SzCoderInfo_Free(CSzCoderInfo *p, ISzAlloc *alloc) +{ + Buf_Free(&p->Props, alloc); + SzCoderInfo_Init(p); +} + +void SzFolder_Init(CSzFolder *p) +{ + p->Coders = 0; + p->BindPairs = 0; + p->PackStreams = 0; + p->UnpackSizes = 0; + p->NumCoders = 0; + p->NumBindPairs = 0; + p->NumPackStreams = 0; + p->UnpackCRCDefined = 0; + p->UnpackCRC = 0; + p->NumUnpackStreams = 0; +} + +void SzFolder_Free(CSzFolder *p, ISzAlloc *alloc) +{ + uint32_t i; + if (p->Coders) + for (i = 0; i < p->NumCoders; i++) + SzCoderInfo_Free(&p->Coders[i], alloc); + IAlloc_Free(alloc, p->Coders); + IAlloc_Free(alloc, p->BindPairs); + IAlloc_Free(alloc, p->PackStreams); + IAlloc_Free(alloc, p->UnpackSizes); + SzFolder_Init(p); +} + +uint32_t SzFolder_GetNumOutStreams(CSzFolder *p) +{ + uint32_t result = 0; + uint32_t i; + for (i = 0; i < p->NumCoders; i++) + result += p->Coders[i].NumOutStreams; + return result; +} + +int SzFolder_FindBindPairForInStream(CSzFolder *p, uint32_t inStreamIndex) +{ + uint32_t i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].InIndex == inStreamIndex) + return i; + return -1; +} + + +int SzFolder_FindBindPairForOutStream(CSzFolder *p, uint32_t outStreamIndex) +{ + uint32_t i; + for (i = 0; i < p->NumBindPairs; i++) + if (p->BindPairs[i].OutIndex == outStreamIndex) + return i; + return -1; +} + +uint64_t SzFolder_GetUnpackSize(CSzFolder *p) +{ + int i = (int)SzFolder_GetNumOutStreams(p); + if (i == 0) + return 0; + for (i--; i >= 0; i--) + if (SzFolder_FindBindPairForOutStream(p, i) < 0) + return p->UnpackSizes[i]; + /* throw 1; */ + return 0; +} + +void SzFile_Init(CSzFileItem *p) +{ + p->HasStream = 1; + p->IsDir = 0; + p->IsAnti = 0; + p->CrcDefined = 0; + p->MTimeDefined = 0; +} + +void SzAr_Init(CSzAr *p) +{ + p->PackSizes = 0; + p->PackCRCsDefined = 0; + p->PackCRCs = 0; + p->Folders = 0; + p->Files = 0; + p->NumPackStreams = 0; + p->NumFolders = 0; + p->NumFiles = 0; +} + +void SzAr_Free(CSzAr *p, ISzAlloc *alloc) +{ + uint32_t i; + if (p->Folders) + for (i = 0; i < p->NumFolders; i++) + SzFolder_Free(&p->Folders[i], alloc); + + IAlloc_Free(alloc, p->PackSizes); + IAlloc_Free(alloc, p->PackCRCsDefined); + IAlloc_Free(alloc, p->PackCRCs); + IAlloc_Free(alloc, p->Folders); + IAlloc_Free(alloc, p->Files); + SzAr_Init(p); +} + + +void SzArEx_Init(CSzArEx *p) +{ + SzAr_Init(&p->db); + p->FolderStartPackStreamIndex = 0; + p->PackStreamStartPositions = 0; + p->FolderStartFileIndex = 0; + p->FileIndexToFolderIndexMap = 0; + p->FileNameOffsets = 0; + Buf_Init(&p->FileNames); +} + +void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc) +{ + IAlloc_Free(alloc, p->FolderStartPackStreamIndex); + IAlloc_Free(alloc, p->PackStreamStartPositions); + IAlloc_Free(alloc, p->FolderStartFileIndex); + IAlloc_Free(alloc, p->FileIndexToFolderIndexMap); + + IAlloc_Free(alloc, p->FileNameOffsets); + Buf_Free(&p->FileNames, alloc); + + SzAr_Free(&p->db, alloc); + SzArEx_Init(p); +} + +/* + uint64_t GetFolderPackStreamSize(int folderIndex, int streamIndex) const + { + return PackSizes[FolderStartPackStreamIndex[folderIndex] + streamIndex]; + } + + uint64_t GetFilePackSize(int fileIndex) const + { + int folderIndex = FileIndexToFolderIndexMap[fileIndex]; + if (folderIndex >= 0) + { + const CSzFolder &folderInfo = Folders[folderIndex]; + if (FolderStartFileIndex[folderIndex] == fileIndex) + return GetFolderFullPackSize(folderIndex); + } + return 0; + } + */ + +#define MY_ALLOC(T, p, size, alloc) { if ((size) == 0) p = 0; else \ + if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == 0) return SZ_ERROR_MEM; } + +static SRes SzArEx_Fill(CSzArEx *p, ISzAlloc *alloc) +{ + uint32_t startPos = 0; + uint64_t startPosSize = 0; + uint32_t i; + uint32_t folderIndex = 0; + uint32_t indexInFolder = 0; + MY_ALLOC(uint32_t, p->FolderStartPackStreamIndex, p->db.NumFolders, alloc); + for (i = 0; i < p->db.NumFolders; i++) + { + p->FolderStartPackStreamIndex[i] = startPos; + startPos += p->db.Folders[i].NumPackStreams; + } + + MY_ALLOC(uint64_t, p->PackStreamStartPositions, p->db.NumPackStreams, alloc); + + for (i = 0; i < p->db.NumPackStreams; i++) + { + p->PackStreamStartPositions[i] = startPosSize; + startPosSize += p->db.PackSizes[i]; + } + + MY_ALLOC(uint32_t, p->FolderStartFileIndex, p->db.NumFolders, alloc); + MY_ALLOC(uint32_t, p->FileIndexToFolderIndexMap, p->db.NumFiles, alloc); + + for (i = 0; i < p->db.NumFiles; i++) + { + CSzFileItem *file = p->db.Files + i; + int emptyStream = !file->HasStream; + if (emptyStream && indexInFolder == 0) + { + p->FileIndexToFolderIndexMap[i] = (uint32_t)-1; + continue; + } + if (indexInFolder == 0) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: Loop for skipping empty folders + */ + for (;;) + { + if (folderIndex >= p->db.NumFolders) + return SZ_ERROR_ARCHIVE; + p->FolderStartFileIndex[folderIndex] = i; + if (p->db.Folders[folderIndex].NumUnpackStreams != 0) + break; + folderIndex++; + } + } + p->FileIndexToFolderIndexMap[i] = folderIndex; + if (emptyStream) + continue; + indexInFolder++; + if (indexInFolder >= p->db.Folders[folderIndex].NumUnpackStreams) + { + folderIndex++; + indexInFolder = 0; + } + } + return SZ_OK; +} + + +uint64_t SzArEx_GetFolderStreamPos(const CSzArEx *p, uint32_t folderIndex, uint32_t indexInFolder) +{ + return p->dataPos + + p->PackStreamStartPositions[p->FolderStartPackStreamIndex[folderIndex] + indexInFolder]; +} + +int SzArEx_GetFolderFullPackSize(const CSzArEx *p, uint32_t folderIndex, uint64_t *resSize) +{ + uint32_t packStreamIndex = p->FolderStartPackStreamIndex[folderIndex]; + CSzFolder *folder = p->db.Folders + folderIndex; + uint64_t size = 0; + uint32_t i; + for (i = 0; i < folder->NumPackStreams; i++) + { + uint64_t t = size + p->db.PackSizes[packStreamIndex + i]; + if (t < size) /* check it */ + return SZ_ERROR_FAIL; + size = t; + } + *resSize = size; + return SZ_OK; +} + + +static int TestSignatureCandidate(uint8_t *testuint8_ts) +{ + size_t i; + for (i = 0; i < k7zSignatureSize; i++) + if (testuint8_ts[i] != k7zSignature[i]) + return 0; + return 1; +} + +typedef struct _CSzState +{ + uint8_t *Data; + size_t Size; +}CSzData; + +static SRes SzReaduint8_t(CSzData *sd, uint8_t *b) +{ + if (sd->Size == 0) + return SZ_ERROR_ARCHIVE; + sd->Size--; + *b = *sd->Data++; + return SZ_OK; +} + +static SRes SzReaduint8_ts(CSzData *sd, uint8_t *data, size_t size) +{ + size_t i; + for (i = 0; i < size; i++) + { + RINOK(SzReaduint8_t(sd, data + i)); + } + return SZ_OK; +} + +static SRes SzReaduint32_t(CSzData *sd, uint32_t *value) +{ + int i; + *value = 0; + for (i = 0; i < 4; i++) + { + uint8_t b; + RINOK(SzReaduint8_t(sd, &b)); + *value |= ((uint32_t)(b) << (8 * i)); + } + return SZ_OK; +} + +static SRes SzReadNumber(CSzData *sd, uint64_t *value) +{ + uint8_t firstuint8_t; + uint8_t mask = 0x80; + int i; + RINOK(SzReaduint8_t(sd, &firstuint8_t)); + *value = 0; + for (i = 0; i < 8; i++) + { + uint8_t b; + if ((firstuint8_t & mask) == 0) + { + uint64_t highPart = firstuint8_t & (mask - 1); + *value += (highPart << (8 * i)); + return SZ_OK; + } + RINOK(SzReaduint8_t(sd, &b)); + *value |= ((uint64_t)b << (8 * i)); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadNumber32(CSzData *sd, uint32_t *value) +{ + uint64_t value64; + RINOK(SzReadNumber(sd, &value64)); + if (value64 >= 0x80000000) + return SZ_ERROR_UNSUPPORTED; + if (value64 >= ((uint64_t)(1) << ((sizeof(size_t) - 1) * 8 + 2))) + return SZ_ERROR_UNSUPPORTED; + *value = (uint32_t)value64; + return SZ_OK; +} + +static SRes SzReadID(CSzData *sd, uint64_t *value) +{ + return SzReadNumber(sd, value); +} + +static SRes SzSkeepDataSize(CSzData *sd, uint64_t size) +{ + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + sd->Size -= (size_t)size; + sd->Data += (size_t)size; + return SZ_OK; +} + +static SRes SzSkeepData(CSzData *sd) +{ + uint64_t size; + RINOK(SzReadNumber(sd, &size)); + return SzSkeepDataSize(sd, size); +} + +static SRes SzReadArchiveProperties(CSzData *sd) +{ + for (;;) + { + uint64_t type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + SzSkeepData(sd); + } + return SZ_OK; +} + +static SRes SzWaitAttribute(CSzData *sd, uint64_t attribute) +{ + for (;;) + { + uint64_t type; + RINOK(SzReadID(sd, &type)); + if (type == attribute) + return SZ_OK; + if (type == k7zIdEnd) + return SZ_ERROR_ARCHIVE; + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadBoolVector(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc) +{ + uint8_t b = 0; + uint8_t mask = 0; + size_t i; + MY_ALLOC(uint8_t, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + { + if (mask == 0) + { + RINOK(SzReaduint8_t(sd, &b)); + mask = 0x80; + } + (*v)[i] = (uint8_t)(((b & mask) != 0) ? 1 : 0); + mask >>= 1; + } + return SZ_OK; +} + +static SRes SzReadBoolVector2(CSzData *sd, size_t numItems, uint8_t **v, ISzAlloc *alloc) +{ + uint8_t allAreDefined; + size_t i; + RINOK(SzReaduint8_t(sd, &allAreDefined)); + if (allAreDefined == 0) + return SzReadBoolVector(sd, numItems, v, alloc); + MY_ALLOC(uint8_t, *v, numItems, alloc); + for (i = 0; i < numItems; i++) + (*v)[i] = 1; + return SZ_OK; +} + +static SRes SzReadHashDigests( + CSzData *sd, + size_t numItems, + uint8_t **digestsDefined, + uint32_t **digests, + ISzAlloc *alloc) +{ + size_t i; + RINOK(SzReadBoolVector2(sd, numItems, digestsDefined, alloc)); + MY_ALLOC(uint32_t, *digests, numItems, alloc); + for (i = 0; i < numItems; i++) + if ((*digestsDefined)[i]) + { + RINOK(SzReaduint32_t(sd, (*digests) + i)); + } + return SZ_OK; +} + +static SRes SzReadPackInfo( + CSzData *sd, + uint64_t *dataOffset, + uint32_t *numPackStreams, + uint64_t **packSizes, + uint8_t **packCRCsDefined, + uint32_t **packCRCs, + ISzAlloc *alloc) +{ + uint32_t i; + RINOK(SzReadNumber(sd, dataOffset)); + RINOK(SzReadNumber32(sd, numPackStreams)); + + RINOK(SzWaitAttribute(sd, k7zIdSize)); + + MY_ALLOC(uint64_t, *packSizes, (size_t)*numPackStreams, alloc); + + for (i = 0; i < *numPackStreams; i++) + { + RINOK(SzReadNumber(sd, (*packSizes) + i)); + } + + for (;;) + { + uint64_t type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + if (type == k7zIdCRC) + { + RINOK(SzReadHashDigests(sd, (size_t)*numPackStreams, packCRCsDefined, packCRCs, alloc)); + continue; + } + RINOK(SzSkeepData(sd)); + } + if (*packCRCsDefined == 0) + { + MY_ALLOC(uint8_t, *packCRCsDefined, (size_t)*numPackStreams, alloc); + MY_ALLOC(uint32_t, *packCRCs, (size_t)*numPackStreams, alloc); + for (i = 0; i < *numPackStreams; i++) + { + (*packCRCsDefined)[i] = 0; + (*packCRCs)[i] = 0; + } + } + return SZ_OK; +} + +static SRes SzReadSwitch(CSzData *sd) +{ + uint8_t external; + RINOK(SzReaduint8_t(sd, &external)); + return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED; +} + +static SRes SzGetNextFolderItem(CSzData *sd, CSzFolder *folder, ISzAlloc *alloc) +{ + uint32_t numCoders, numBindPairs, numPackStreams, i; + uint32_t numInStreams = 0, numOutStreams = 0; + + RINOK(SzReadNumber32(sd, &numCoders)); + if (numCoders > NUM_FOLDER_CODERS_MAX) + return SZ_ERROR_UNSUPPORTED; + folder->NumCoders = numCoders; + + MY_ALLOC(CSzCoderInfo, folder->Coders, (size_t)numCoders, alloc); + + for (i = 0; i < numCoders; i++) + SzCoderInfo_Init(folder->Coders + i); + + for (i = 0; i < numCoders; i++) + { + uint8_t mainuint8_t; + CSzCoderInfo *coder = folder->Coders + i; + { + unsigned idSize, j; + uint8_t longID[15]; + RINOK(SzReaduint8_t(sd, &mainuint8_t)); + idSize = (unsigned)(mainuint8_t & 0xF); + RINOK(SzReaduint8_ts(sd, longID, idSize)); + if (idSize > sizeof(coder->MethodID)) + return SZ_ERROR_UNSUPPORTED; + coder->MethodID = 0; + for (j = 0; j < idSize; j++) + coder->MethodID |= (uint64_t)longID[idSize - 1 - j] << (8 * j); + + if ((mainuint8_t & 0x10) != 0) + { + RINOK(SzReadNumber32(sd, &coder->NumInStreams)); + RINOK(SzReadNumber32(sd, &coder->NumOutStreams)); + if (coder->NumInStreams > NUM_CODER_STREAMS_MAX || + coder->NumOutStreams > NUM_CODER_STREAMS_MAX) + return SZ_ERROR_UNSUPPORTED; + } + else + { + coder->NumInStreams = 1; + coder->NumOutStreams = 1; + } + if ((mainuint8_t & 0x20) != 0) + { + uint64_t propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + if (!Buf_Create(&coder->Props, (size_t)propertiesSize, alloc)) + return SZ_ERROR_MEM; + RINOK(SzReaduint8_ts(sd, coder->Props.data, (size_t)propertiesSize)); + } + } + while ((mainuint8_t & 0x80) != 0) + { + RINOK(SzReaduint8_t(sd, &mainuint8_t)); + RINOK(SzSkeepDataSize(sd, (mainuint8_t & 0xF))); + if ((mainuint8_t & 0x10) != 0) + { + uint32_t n; + RINOK(SzReadNumber32(sd, &n)); + RINOK(SzReadNumber32(sd, &n)); + } + if ((mainuint8_t & 0x20) != 0) + { + uint64_t propertiesSize = 0; + RINOK(SzReadNumber(sd, &propertiesSize)); + RINOK(SzSkeepDataSize(sd, propertiesSize)); + } + } + numInStreams += coder->NumInStreams; + numOutStreams += coder->NumOutStreams; + } + + if (numOutStreams == 0) + return SZ_ERROR_UNSUPPORTED; + + folder->NumBindPairs = numBindPairs = numOutStreams - 1; + MY_ALLOC(CSzBindPair, folder->BindPairs, (size_t)numBindPairs, alloc); + + for (i = 0; i < numBindPairs; i++) + { + CSzBindPair *bp = folder->BindPairs + i; + RINOK(SzReadNumber32(sd, &bp->InIndex)); + RINOK(SzReadNumber32(sd, &bp->OutIndex)); + } + + if (numInStreams < numBindPairs) + return SZ_ERROR_UNSUPPORTED; + + folder->NumPackStreams = numPackStreams = numInStreams - numBindPairs; + MY_ALLOC(uint32_t, folder->PackStreams, (size_t)numPackStreams, alloc); + + if (numPackStreams == 1) + { + for (i = 0; i < numInStreams ; i++) + if (SzFolder_FindBindPairForInStream(folder, i) < 0) + break; + if (i == numInStreams) + return SZ_ERROR_UNSUPPORTED; + folder->PackStreams[0] = i; + } + else + for (i = 0; i < numPackStreams; i++) + { + RINOK(SzReadNumber32(sd, folder->PackStreams + i)); + } + return SZ_OK; +} + +static SRes SzReadUnpackInfo( + CSzData *sd, + uint32_t *numFolders, + CSzFolder **folders, /* for alloc */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + uint32_t i; + RINOK(SzWaitAttribute(sd, k7zIdFolder)); + RINOK(SzReadNumber32(sd, numFolders)); + { + RINOK(SzReadSwitch(sd)); + + MY_ALLOC(CSzFolder, *folders, (size_t)*numFolders, alloc); + + for (i = 0; i < *numFolders; i++) + SzFolder_Init((*folders) + i); + + for (i = 0; i < *numFolders; i++) + { + RINOK(SzGetNextFolderItem(sd, (*folders) + i, alloc)); + } + } + + RINOK(SzWaitAttribute(sd, k7zIdCodersUnpackSize)); + + for (i = 0; i < *numFolders; i++) + { + uint32_t j; + CSzFolder *folder = (*folders) + i; + uint32_t numOutStreams = SzFolder_GetNumOutStreams(folder); + + MY_ALLOC(uint64_t, folder->UnpackSizes, (size_t)numOutStreams, alloc); + + for (j = 0; j < numOutStreams; j++) + { + RINOK(SzReadNumber(sd, folder->UnpackSizes + j)); + } + } + + for (;;) + { + uint64_t type; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + return SZ_OK; + if (type == k7zIdCRC) + { + SRes res; + uint8_t *crcsDefined = 0; + uint32_t *crcs = 0; + res = SzReadHashDigests(sd, *numFolders, &crcsDefined, &crcs, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < *numFolders; i++) + { + CSzFolder *folder = (*folders) + i; + folder->UnpackCRCDefined = crcsDefined[i]; + folder->UnpackCRC = crcs[i]; + } + } + IAlloc_Free(allocTemp, crcs); + IAlloc_Free(allocTemp, crcsDefined); + RINOK(res); + continue; + } + RINOK(SzSkeepData(sd)); + } +} + +static SRes SzReadSubStreamsInfo( + CSzData *sd, + uint32_t numFolders, + CSzFolder *folders, + uint32_t *numUnpackStreams, + uint64_t **unpackSizes, + uint8_t **digestsDefined, + uint32_t **digests, + ISzAlloc *allocTemp) +{ + uint64_t type = 0; + uint32_t i; + uint32_t si = 0; + uint32_t numDigests = 0; + + for (i = 0; i < numFolders; i++) + folders[i].NumUnpackStreams = 1; + *numUnpackStreams = numFolders; + + for (;;) + { + RINOK(SzReadID(sd, &type)); + if (type == k7zIdNumUnpackStream) + { + *numUnpackStreams = 0; + for (i = 0; i < numFolders; i++) + { + uint32_t numStreams; + RINOK(SzReadNumber32(sd, &numStreams)); + folders[i].NumUnpackStreams = numStreams; + *numUnpackStreams += numStreams; + } + continue; + } + if (type == k7zIdCRC || type == k7zIdSize) + break; + if (type == k7zIdEnd) + break; + RINOK(SzSkeepData(sd)); + } + + if (*numUnpackStreams == 0) + { + *unpackSizes = 0; + *digestsDefined = 0; + *digests = 0; + } + else + { + *unpackSizes = (uint64_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint64_t)); + RINOM(*unpackSizes); + *digestsDefined = (uint8_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint8_t)); + RINOM(*digestsDefined); + *digests = (uint32_t *)IAlloc_Alloc(allocTemp, (size_t)*numUnpackStreams * sizeof(uint32_t)); + RINOM(*digests); + } + + for (i = 0; i < numFolders; i++) + { + /* + v3.13 incorrectly worked with empty folders + v4.07: we check that folder is empty + */ + uint64_t sum = 0; + uint32_t j; + uint32_t numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams == 0) + continue; + if (type == k7zIdSize) + for (j = 1; j < numSubstreams; j++) + { + uint64_t size; + RINOK(SzReadNumber(sd, &size)); + (*unpackSizes)[si++] = size; + sum += size; + } + (*unpackSizes)[si++] = SzFolder_GetUnpackSize(folders + i) - sum; + } + if (type == k7zIdSize) + { + RINOK(SzReadID(sd, &type)); + } + + for (i = 0; i < *numUnpackStreams; i++) + { + (*digestsDefined)[i] = 0; + (*digests)[i] = 0; + } + + + for (i = 0; i < numFolders; i++) + { + uint32_t numSubstreams = folders[i].NumUnpackStreams; + if (numSubstreams != 1 || !folders[i].UnpackCRCDefined) + numDigests += numSubstreams; + } + + + si = 0; + for (;;) + { + if (type == k7zIdCRC) + { + int digestIndex = 0; + uint8_t *digestsDefined2 = 0; + uint32_t *digests2 = 0; + SRes res = SzReadHashDigests(sd, numDigests, &digestsDefined2, &digests2, allocTemp); + if (res == SZ_OK) + { + for (i = 0; i < numFolders; i++) + { + CSzFolder *folder = folders + i; + uint32_t numSubstreams = folder->NumUnpackStreams; + if (numSubstreams == 1 && folder->UnpackCRCDefined) + { + (*digestsDefined)[si] = 1; + (*digests)[si] = folder->UnpackCRC; + si++; + } + else + { + uint32_t j; + for (j = 0; j < numSubstreams; j++, digestIndex++) + { + (*digestsDefined)[si] = digestsDefined2[digestIndex]; + (*digests)[si] = digests2[digestIndex]; + si++; + } + } + } + } + IAlloc_Free(allocTemp, digestsDefined2); + IAlloc_Free(allocTemp, digests2); + RINOK(res); + } + else if (type == k7zIdEnd) + return SZ_OK; + else + { + RINOK(SzSkeepData(sd)); + } + RINOK(SzReadID(sd, &type)); + } +} + + +static SRes SzReadStreamsInfo( + CSzData *sd, + uint64_t *dataOffset, + CSzAr *p, + uint32_t *numUnpackStreams, + uint64_t **unpackSizes, /* allocTemp */ + uint8_t **digestsDefined, /* allocTemp */ + uint32_t **digests, /* allocTemp */ + ISzAlloc *alloc, + ISzAlloc *allocTemp) +{ + for (;;) + { + uint64_t type; + RINOK(SzReadID(sd, &type)); + if ((uint64_t)(int)type != type) + return SZ_ERROR_UNSUPPORTED; + switch((int)type) + { + case k7zIdEnd: + return SZ_OK; + case k7zIdPackInfo: + { + RINOK(SzReadPackInfo(sd, dataOffset, &p->NumPackStreams, + &p->PackSizes, &p->PackCRCsDefined, &p->PackCRCs, alloc)); + break; + } + case k7zIdUnpackInfo: + { + RINOK(SzReadUnpackInfo(sd, &p->NumFolders, &p->Folders, alloc, allocTemp)); + break; + } + case k7zIdSubStreamsInfo: + { + RINOK(SzReadSubStreamsInfo(sd, p->NumFolders, p->Folders, + numUnpackStreams, unpackSizes, digestsDefined, digests, allocTemp)); + break; + } + default: + return SZ_ERROR_UNSUPPORTED; + } + } +} + +size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, uint16_t *dest) +{ + size_t len = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; + if (dest != 0) + { + size_t i; + const uint8_t *src = p->FileNames.data + (p->FileNameOffsets[fileIndex] * 2); + for (i = 0; i < len; i++) + dest[i] = GetUi16(src + i * 2); + } + return len; +} + +static SRes SzReadFileNames(const uint8_t *p, size_t size, uint32_t numFiles, size_t *sizes) +{ + uint32_t i; + size_t pos = 0; + for (i = 0; i < numFiles; i++) + { + sizes[i] = pos; + for (;;) + { + if (pos >= size) + return SZ_ERROR_ARCHIVE; + if (p[pos * 2] == 0 && p[pos * 2 + 1] == 0) + break; + pos++; + } + pos++; + } + sizes[i] = pos; + return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE; +} + +static SRes SzReadHeader2( + CSzArEx *p, /* allocMain */ + CSzData *sd, + uint64_t **unpackSizes, /* allocTemp */ + uint8_t **digestsDefined, /* allocTemp */ + uint32_t **digests, /* allocTemp */ + uint8_t **emptyStreamVector, /* allocTemp */ + uint8_t **emptyFileVector, /* allocTemp */ + uint8_t **lwtVector, /* allocTemp */ + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + uint64_t type; + uint32_t numUnpackStreams = 0; + uint32_t numFiles = 0; + CSzFileItem *files = 0; + uint32_t numEmptyStreams = 0; + uint32_t i; + + RINOK(SzReadID(sd, &type)); + + if (type == k7zIdArchiveProperties) + { + RINOK(SzReadArchiveProperties(sd)); + RINOK(SzReadID(sd, &type)); + } + + + if (type == k7zIdMainStreamsInfo) + { + RINOK(SzReadStreamsInfo(sd, + &p->dataPos, + &p->db, + &numUnpackStreams, + unpackSizes, + digestsDefined, + digests, allocMain, allocTemp)); + p->dataPos += p->startPosAfterHeader; + RINOK(SzReadID(sd, &type)); + } + + if (type == k7zIdEnd) + return SZ_OK; + if (type != k7zIdFilesInfo) + return SZ_ERROR_ARCHIVE; + + RINOK(SzReadNumber32(sd, &numFiles)); + p->db.NumFiles = numFiles; + + MY_ALLOC(CSzFileItem, files, (size_t)numFiles, allocMain); + + p->db.Files = files; + for (i = 0; i < numFiles; i++) + SzFile_Init(files + i); + + for (;;) + { + uint64_t size; + RINOK(SzReadID(sd, &type)); + if (type == k7zIdEnd) + break; + RINOK(SzReadNumber(sd, &size)); + if (size > sd->Size) + return SZ_ERROR_ARCHIVE; + if ((uint64_t)(int)type != type) + { + RINOK(SzSkeepDataSize(sd, size)); + } + else + switch((int)type) + { + case k7zIdName: + { + size_t namesSize; + RINOK(SzReadSwitch(sd)); + namesSize = (size_t)size - 1; + if ((namesSize & 1) != 0) + return SZ_ERROR_ARCHIVE; + if (!Buf_Create(&p->FileNames, namesSize, allocMain)) + return SZ_ERROR_MEM; + MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain); + memcpy(p->FileNames.data, sd->Data, namesSize); + RINOK(SzReadFileNames(sd->Data, namesSize >> 1, numFiles, p->FileNameOffsets)) + RINOK(SzSkeepDataSize(sd, namesSize)); + break; + } + case k7zIdEmptyStream: + { + RINOK(SzReadBoolVector(sd, numFiles, emptyStreamVector, allocTemp)); + numEmptyStreams = 0; + for (i = 0; i < numFiles; i++) + if ((*emptyStreamVector)[i]) + numEmptyStreams++; + break; + } + case k7zIdEmptyFile: + { + RINOK(SzReadBoolVector(sd, numEmptyStreams, emptyFileVector, allocTemp)); + break; + } + case k7zIdWinAttributes: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + uint8_t defined = (*lwtVector)[i]; + f->AttribDefined = defined; + f->Attrib = 0; + if (defined) + { + RINOK(SzReaduint32_t(sd, &f->Attrib)); + } + } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; + break; + } + case k7zIdMTime: + { + RINOK(SzReadBoolVector2(sd, numFiles, lwtVector, allocTemp)); + RINOK(SzReadSwitch(sd)); + for (i = 0; i < numFiles; i++) + { + CSzFileItem *f = &files[i]; + uint8_t defined = (*lwtVector)[i]; + f->MTimeDefined = defined; + f->MTime.Low = f->MTime.High = 0; + if (defined) + { + RINOK(SzReaduint32_t(sd, &f->MTime.Low)); + RINOK(SzReaduint32_t(sd, &f->MTime.High)); + } + } + IAlloc_Free(allocTemp, *lwtVector); + *lwtVector = NULL; + break; + } + default: + { + RINOK(SzSkeepDataSize(sd, size)); + } + } + } + + { + uint32_t emptyFileIndex = 0; + uint32_t sizeIndex = 0; + for (i = 0; i < numFiles; i++) + { + CSzFileItem *file = files + i; + file->IsAnti = 0; + if (*emptyStreamVector == 0) + file->HasStream = 1; + else + file->HasStream = (uint8_t)((*emptyStreamVector)[i] ? 0 : 1); + if (file->HasStream) + { + file->IsDir = 0; + file->Size = (*unpackSizes)[sizeIndex]; + file->Crc = (*digests)[sizeIndex]; + file->CrcDefined = (uint8_t)(*digestsDefined)[sizeIndex]; + sizeIndex++; + } + else + { + if (*emptyFileVector == 0) + file->IsDir = 1; + else + file->IsDir = (uint8_t)((*emptyFileVector)[emptyFileIndex] ? 0 : 1); + emptyFileIndex++; + file->Size = 0; + file->Crc = 0; + file->CrcDefined = 0; + } + } + } + return SzArEx_Fill(p, allocMain); +} + +static SRes SzReadHeader( + CSzArEx *p, + CSzData *sd, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + uint64_t *unpackSizes = 0; + uint8_t *digestsDefined = 0; + uint32_t *digests = 0; + uint8_t *emptyStreamVector = 0; + uint8_t *emptyFileVector = 0; + uint8_t *lwtVector = 0; + SRes res = SzReadHeader2(p, sd, + &unpackSizes, &digestsDefined, &digests, + &emptyStreamVector, &emptyFileVector, &lwtVector, + allocMain, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + IAlloc_Free(allocTemp, emptyStreamVector); + IAlloc_Free(allocTemp, emptyFileVector); + IAlloc_Free(allocTemp, lwtVector); + return res; +} + +static SRes SzReadAndDecodePackedStreams2( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + uint64_t baseOffset, + CSzAr *p, + uint64_t **unpackSizes, + uint8_t **digestsDefined, + uint32_t **digests, + ISzAlloc *allocTemp) +{ + + uint32_t numUnpackStreams = 0; + uint64_t dataStartPos; + CSzFolder *folder; + uint64_t unpackSize; + SRes res; + + RINOK(SzReadStreamsInfo(sd, &dataStartPos, p, + &numUnpackStreams, unpackSizes, digestsDefined, digests, + allocTemp, allocTemp)); + + dataStartPos += baseOffset; + if (p->NumFolders != 1) + return SZ_ERROR_ARCHIVE; + + folder = p->Folders; + unpackSize = SzFolder_GetUnpackSize(folder); + + RINOK(LookInStream_SeekTo(inStream, dataStartPos)); + + if (!Buf_Create(outBuffer, (size_t)unpackSize, allocTemp)) + return SZ_ERROR_MEM; + + res = SzFolder_Decode(folder, p->PackSizes, + inStream, dataStartPos, + outBuffer->data, (size_t)unpackSize, allocTemp); + RINOK(res); + if (folder->UnpackCRCDefined) + if (CrcCalc(outBuffer->data, (size_t)unpackSize) != folder->UnpackCRC) + return SZ_ERROR_CRC; + return SZ_OK; +} + +static SRes SzReadAndDecodePackedStreams( + ILookInStream *inStream, + CSzData *sd, + CBuf *outBuffer, + uint64_t baseOffset, + ISzAlloc *allocTemp) +{ + CSzAr p; + uint64_t *unpackSizes = 0; + uint8_t *digestsDefined = 0; + uint32_t *digests = 0; + SRes res; + SzAr_Init(&p); + res = SzReadAndDecodePackedStreams2(inStream, sd, outBuffer, baseOffset, + &p, &unpackSizes, &digestsDefined, &digests, + allocTemp); + SzAr_Free(&p, allocTemp); + IAlloc_Free(allocTemp, unpackSizes); + IAlloc_Free(allocTemp, digestsDefined); + IAlloc_Free(allocTemp, digests); + return res; +} + +static SRes SzArEx_Open2( + CSzArEx *p, + ILookInStream *inStream, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + uint8_t header[k7zStartHeaderSize]; + int64_t startArcPos; + uint64_t nextHeaderOffset, nextHeaderSize; + size_t nextHeaderSizeT; + uint32_t nextHeaderCRC; + CBuf buffer; + SRes res; + + startArcPos = 0; + RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR)); + + RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)); + + if (!TestSignatureCandidate(header)) + return SZ_ERROR_NO_ARCHIVE; + if (header[6] != k7zMajorVersion) + return SZ_ERROR_UNSUPPORTED; + + nextHeaderOffset = GetUi64(header + 12); + nextHeaderSize = GetUi64(header + 20); + nextHeaderCRC = GetUi32(header + 28); + + p->startPosAfterHeader = startArcPos + k7zStartHeaderSize; + + if (CrcCalc(header + 12, 20) != GetUi32(header + 8)) + return SZ_ERROR_CRC; + + nextHeaderSizeT = (size_t)nextHeaderSize; + if (nextHeaderSizeT != nextHeaderSize) + return SZ_ERROR_MEM; + if (nextHeaderSizeT == 0) + return SZ_OK; + if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || + nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize) + return SZ_ERROR_NO_ARCHIVE; + + { + int64_t pos = 0; + RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END)); + if ((uint64_t)pos < startArcPos + nextHeaderOffset || + (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset || + (uint64_t)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize) + return SZ_ERROR_INPUT_EOF; + } + + RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset)); + + if (!Buf_Create(&buffer, nextHeaderSizeT, allocTemp)) + return SZ_ERROR_MEM; + + res = LookInStream_Read(inStream, buffer.data, nextHeaderSizeT); + if (res == SZ_OK) + { + res = SZ_ERROR_ARCHIVE; + if (CrcCalc(buffer.data, nextHeaderSizeT) == nextHeaderCRC) + { + CSzData sd; + uint64_t type; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + if (res == SZ_OK) + { + if (type == k7zIdEncodedHeader) + { + CBuf outBuffer; + Buf_Init(&outBuffer); + res = SzReadAndDecodePackedStreams(inStream, &sd, &outBuffer, p->startPosAfterHeader, allocTemp); + if (res != SZ_OK) + Buf_Free(&outBuffer, allocTemp); + else + { + Buf_Free(&buffer, allocTemp); + buffer.data = outBuffer.data; + buffer.size = outBuffer.size; + sd.Data = buffer.data; + sd.Size = buffer.size; + res = SzReadID(&sd, &type); + } + } + } + if (res == SZ_OK) + { + if (type == k7zIdHeader) + res = SzReadHeader(p, &sd, allocMain, allocTemp); + else + res = SZ_ERROR_UNSUPPORTED; + } + } + } + Buf_Free(&buffer, allocTemp); + return res; +} + +SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream, ISzAlloc *allocMain, ISzAlloc *allocTemp) +{ + SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp); + if (res != SZ_OK) + SzArEx_Free(p, allocMain); + return res; +} + +SRes SzArEx_Extract( + const CSzArEx *p, + ILookInStream *inStream, + uint32_t fileIndex, + uint32_t *blockIndex, + uint8_t **outBuffer, + size_t *outBufferSize, + size_t *offset, + size_t *outSizeProcessed, + ISzAlloc *allocMain, + ISzAlloc *allocTemp) +{ + uint32_t folderIndex = p->FileIndexToFolderIndexMap[fileIndex]; + SRes res = SZ_OK; + *offset = 0; + *outSizeProcessed = 0; + if (folderIndex == (uint32_t)-1) + { + IAlloc_Free(allocMain, *outBuffer); + *blockIndex = folderIndex; + *outBuffer = 0; + *outBufferSize = 0; + return SZ_OK; + } + + if (*outBuffer == 0 || *blockIndex != folderIndex) + { + CSzFolder *folder = p->db.Folders + folderIndex; + uint64_t unpackSizeSpec = SzFolder_GetUnpackSize(folder); + size_t unpackSize = (size_t)unpackSizeSpec; + uint64_t startOffset = SzArEx_GetFolderStreamPos(p, folderIndex, 0); + + if (unpackSize != unpackSizeSpec) + return SZ_ERROR_MEM; + *blockIndex = folderIndex; + IAlloc_Free(allocMain, *outBuffer); + *outBuffer = 0; + + RINOK(LookInStream_SeekTo(inStream, startOffset)); + + if (res == SZ_OK) + { + *outBufferSize = unpackSize; + if (unpackSize != 0) + { + *outBuffer = (uint8_t *)IAlloc_Alloc(allocMain, unpackSize); + if (*outBuffer == 0) + res = SZ_ERROR_MEM; + } + if (res == SZ_OK) + { + res = SzFolder_Decode(folder, + p->db.PackSizes + p->FolderStartPackStreamIndex[folderIndex], + inStream, startOffset, + *outBuffer, unpackSize, allocTemp); + if (res == SZ_OK) + { + if (folder->UnpackCRCDefined) + { + if (CrcCalc(*outBuffer, unpackSize) != folder->UnpackCRC) + res = SZ_ERROR_CRC; + } + } + } + } + } + if (res == SZ_OK) + { + uint32_t i; + CSzFileItem *fileItem = p->db.Files + fileIndex; + *offset = 0; + for (i = p->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) + *offset += (uint32_t)p->db.Files[i].Size; + *outSizeProcessed = (size_t)fileItem->Size; + if (*offset + *outSizeProcessed > *outBufferSize) + return SZ_ERROR_FAIL; + if (fileItem->CrcDefined && CrcCalc(*outBuffer + *offset, *outSizeProcessed) != fileItem->Crc) + res = SZ_ERROR_CRC; + } + return res; +} diff --git a/deps/7zip/7zStream.c b/deps/7zip/7zStream.c index c205fbe200..1fc86d064c 100644 --- a/deps/7zip/7zStream.c +++ b/deps/7zip/7zStream.c @@ -1,173 +1,173 @@ -/* 7zStream.c -- 7z Stream functions - 2010-03-11 : Igor Pavlov : Public domain */ - -#include -#include -#include - -#include "7zTypes.h" - -SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf); - -SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((uint8_t *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) -{ - return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf) -{ - size_t processed = 1; - RINOK(stream->Read(stream, buf, &processed)); - return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; -} - -SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset) -{ - int64_t t = offset; - return stream->Seek(stream, &t, SZ_SEEK_SET); -} - -SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) -{ - const void *lookBuf; - if (*size == 0) - return SZ_OK; - RINOK(stream->Look(stream, &lookBuf, size)); - memcpy(buf, lookBuf, *size); - return stream->Skip(stream, *size); -} - -SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) -{ - while (size != 0) - { - size_t processed = size; - RINOK(stream->Read(stream, buf, &processed)); - if (processed == 0) - return errorType; - buf = (void *)((uint8_t *)buf + processed); - size -= processed; - } - return SZ_OK; -} - -SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) -{ - return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); -} - -static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - size2 = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, &size2); - p->size = size2; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) -{ - SRes res = SZ_OK; - CLookToRead *p = (CLookToRead *)pp; - size_t size2 = p->size - p->pos; - if (size2 == 0 && *size > 0) - { - p->pos = 0; - if (*size > LookToRead_BUF_SIZE) - *size = LookToRead_BUF_SIZE; - res = p->realStream->Read(p->realStream, p->buf, size); - size2 = p->size = *size; - } - if (size2 < *size) - *size = size2; - *buf = p->buf + p->pos; - return res; -} - -static SRes LookToRead_Skip(void *pp, size_t offset) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos += offset; - return SZ_OK; -} - -static SRes LookToRead_Read(void *pp, void *buf, size_t *size) -{ - CLookToRead *p = (CLookToRead *)pp; - size_t rem = p->size - p->pos; - if (rem == 0) - return p->realStream->Read(p->realStream, buf, size); - if (rem > *size) - rem = *size; - memcpy(buf, p->buf + p->pos, rem); - p->pos += rem; - *size = rem; - return SZ_OK; -} - -static SRes LookToRead_Seek(void *pp, int64_t *pos, ESzSeek origin) -{ - CLookToRead *p = (CLookToRead *)pp; - p->pos = p->size = 0; - return p->realStream->Seek(p->realStream, pos, origin); -} - -void LookToRead_CreateVTable(CLookToRead *p, int lookahead) -{ - p->s.Look = lookahead ? - LookToRead_Look_Lookahead : - LookToRead_Look_Exact; - p->s.Skip = LookToRead_Skip; - p->s.Read = LookToRead_Read; - p->s.Seek = LookToRead_Seek; -} - -void LookToRead_Init(CLookToRead *p) -{ - p->pos = p->size = 0; -} - -static SRes SecToLook_Read(void *pp, void *buf, size_t *size) -{ - CSecToLook *p = (CSecToLook *)pp; - return LookInStream_LookRead(p->realStream, buf, size); -} - -void SecToLook_CreateVTable(CSecToLook *p) -{ - p->s.Read = SecToLook_Read; -} - -static SRes SecToRead_Read(void *pp, void *buf, size_t *size) -{ - CSecToRead *p = (CSecToRead *)pp; - return p->realStream->Read(p->realStream, buf, size); -} - -void SecToRead_CreateVTable(CSecToRead *p) -{ - p->s.Read = SecToRead_Read; -} +/* 7zStream.c -- 7z Stream functions + 2010-03-11 : Igor Pavlov : Public domain */ + +#include +#include +#include + +#include "7zTypes.h" + +SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf); + +SRes SeqInStream_Read2(ISeqInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((uint8_t *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes SeqInStream_Read(ISeqInStream *stream, void *buf, size_t size) +{ + return SeqInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +SRes SeqInStream_Readuint8_t(ISeqInStream *stream, uint8_t *buf) +{ + size_t processed = 1; + RINOK(stream->Read(stream, buf, &processed)); + return (processed == 1) ? SZ_OK : SZ_ERROR_INPUT_EOF; +} + +SRes LookInStream_SeekTo(ILookInStream *stream, uint64_t offset) +{ + int64_t t = offset; + return stream->Seek(stream, &t, SZ_SEEK_SET); +} + +SRes LookInStream_LookRead(ILookInStream *stream, void *buf, size_t *size) +{ + const void *lookBuf; + if (*size == 0) + return SZ_OK; + RINOK(stream->Look(stream, &lookBuf, size)); + memcpy(buf, lookBuf, *size); + return stream->Skip(stream, *size); +} + +SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType) +{ + while (size != 0) + { + size_t processed = size; + RINOK(stream->Read(stream, buf, &processed)); + if (processed == 0) + return errorType; + buf = (void *)((uint8_t *)buf + processed); + size -= processed; + } + return SZ_OK; +} + +SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size) +{ + return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF); +} + +static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + size2 = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, &size2); + p->size = size2; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size) +{ + SRes res = SZ_OK; + CLookToRead *p = (CLookToRead *)pp; + size_t size2 = p->size - p->pos; + if (size2 == 0 && *size > 0) + { + p->pos = 0; + if (*size > LookToRead_BUF_SIZE) + *size = LookToRead_BUF_SIZE; + res = p->realStream->Read(p->realStream, p->buf, size); + size2 = p->size = *size; + } + if (size2 < *size) + *size = size2; + *buf = p->buf + p->pos; + return res; +} + +static SRes LookToRead_Skip(void *pp, size_t offset) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos += offset; + return SZ_OK; +} + +static SRes LookToRead_Read(void *pp, void *buf, size_t *size) +{ + CLookToRead *p = (CLookToRead *)pp; + size_t rem = p->size - p->pos; + if (rem == 0) + return p->realStream->Read(p->realStream, buf, size); + if (rem > *size) + rem = *size; + memcpy(buf, p->buf + p->pos, rem); + p->pos += rem; + *size = rem; + return SZ_OK; +} + +static SRes LookToRead_Seek(void *pp, int64_t *pos, ESzSeek origin) +{ + CLookToRead *p = (CLookToRead *)pp; + p->pos = p->size = 0; + return p->realStream->Seek(p->realStream, pos, origin); +} + +void LookToRead_CreateVTable(CLookToRead *p, int lookahead) +{ + p->s.Look = lookahead ? + LookToRead_Look_Lookahead : + LookToRead_Look_Exact; + p->s.Skip = LookToRead_Skip; + p->s.Read = LookToRead_Read; + p->s.Seek = LookToRead_Seek; +} + +void LookToRead_Init(CLookToRead *p) +{ + p->pos = p->size = 0; +} + +static SRes SecToLook_Read(void *pp, void *buf, size_t *size) +{ + CSecToLook *p = (CSecToLook *)pp; + return LookInStream_LookRead(p->realStream, buf, size); +} + +void SecToLook_CreateVTable(CSecToLook *p) +{ + p->s.Read = SecToLook_Read; +} + +static SRes SecToRead_Read(void *pp, void *buf, size_t *size) +{ + CSecToRead *p = (CSecToRead *)pp; + return p->realStream->Read(p->realStream, buf, size); +} + +void SecToRead_CreateVTable(CSecToRead *p) +{ + p->s.Read = SecToRead_Read; +} diff --git a/deps/7zip/7zVersion.h b/deps/7zip/7zVersion.h index d4ac470e23..9d99c5dff2 100644 --- a/deps/7zip/7zVersion.h +++ b/deps/7zip/7zVersion.h @@ -1,7 +1,7 @@ -#define MY_VER_MAJOR 9 -#define MY_VER_MINOR 20 -#define MY_VER_BUILD 0 -#define MY_VERSION "9.20" -#define MY_DATE "2010-11-18" -#define MY_COPYRIGHT ": Igor Pavlov : Public domain" -#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE +#define MY_VER_MAJOR 9 +#define MY_VER_MINOR 20 +#define MY_VER_BUILD 0 +#define MY_VERSION "9.20" +#define MY_DATE "2010-11-18" +#define MY_COPYRIGHT ": Igor Pavlov : Public domain" +#define MY_VERSION_COPYRIGHT_DATE MY_VERSION " " MY_COPYRIGHT " : " MY_DATE diff --git a/deps/7zip/Bcj2.c b/deps/7zip/Bcj2.c index 7c55cae3d1..13991b7698 100644 --- a/deps/7zip/Bcj2.c +++ b/deps/7zip/Bcj2.c @@ -1,149 +1,149 @@ -/* Bcj2.c -- Converter for x86 code (BCJ2) - 2008-10-04 : Igor Pavlov : Public domain */ - -#include -#include "Bcj2.h" - -#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) -#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) - -#define kNumTopBits 24 -#define kTopValue ((uint32_t)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_READ_BYTE (*buffer++) - -int Bcj2_Decode( - const uint8_t *buf0, size_t size0, - const uint8_t *buf1, size_t size1, - const uint8_t *buf2, size_t size2, - const uint8_t *buf3, size_t size3, - uint8_t *outBuf, size_t outSize) -{ - uint16_t p[256 + 2]; - size_t inPos = 0, outPos = 0; - - const uint8_t *buffer, *bufferLim; - uint32_t range, codes = 0; - uint8_t prevuint8_t = 0; - - unsigned int i; - for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) - p[i] = kBitModelTotal >> 1; - - buffer = buf3; - bufferLim = buffer + size3; - range = 0xFFFFFFFF; - - for (i = 0; i < 5; i++) - { - if (buffer == bufferLim) - return SZ_ERROR_DATA; - codes = (codes << 8) | RC_READ_BYTE; - } - - if (outSize == 0) - return SZ_OK; - - for (;;) - { - uint8_t b; - uint16_t *prob; - uint32_t bound; - uint32_t ttt; - - size_t limit = size0 - inPos; - if (outSize - outPos < limit) - limit = outSize - outPos; - while (limit != 0) - { - b = buf0[inPos]; - outBuf[outPos++] = b; - if (IsJ(prevuint8_t, b)) - break; - inPos++; - prevuint8_t = b; - limit--; - } - - if (limit == 0 || outPos == outSize) - break; - - b = buf0[inPos++]; - - if (b == 0xE8) - prob = p + prevuint8_t; - else if (b == 0xE9) - prob = p + 256; - else - prob = p + 257; - - ttt = *(prob); - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - range = bound; - *(prob) = (uint16_t)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); - - if (range < kTopValue) - { - if (buffer == bufferLim) - return SZ_ERROR_DATA; - range <<= 8; - codes = (codes << 8) | RC_READ_BYTE; - } - prevuint8_t = b; - } - else - { - uint32_t dest; - const uint8_t *v; - - range -= bound; - codes -= bound; - *(prob) = (uint16_t)(ttt - (ttt >> kNumMoveBits)); - - if (range < kTopValue) - { - if (buffer == bufferLim) - return SZ_ERROR_DATA; - range <<= 8; - codes = (codes << 8) | RC_READ_BYTE; - } - - if (b == 0xE8) - { - v = buf1; - if (size1 < 4) - return SZ_ERROR_DATA; - buf1 += 4; - size1 -= 4; - } - else - { - v = buf2; - if (size2 < 4) - return SZ_ERROR_DATA; - buf2 += 4; - size2 -= 4; - } - dest = (((uint32_t)v[0] << 24) | ((uint32_t)v[1] << 16) | - ((uint32_t)v[2] << 8) | ((uint32_t)v[3])) - ((uint32_t)outPos + 4); - outBuf[outPos++] = (uint8_t)dest; - if (outPos == outSize) - break; - outBuf[outPos++] = (uint8_t)(dest >> 8); - if (outPos == outSize) - break; - outBuf[outPos++] = (uint8_t)(dest >> 16); - if (outPos == outSize) - break; - outBuf[outPos++] = prevuint8_t = (uint8_t)(dest >> 24); - } - } - return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; -} +/* Bcj2.c -- Converter for x86 code (BCJ2) + 2008-10-04 : Igor Pavlov : Public domain */ + +#include +#include "Bcj2.h" + +#define IsJcc(b0, b1) ((b0) == 0x0F && ((b1) & 0xF0) == 0x80) +#define IsJ(b0, b1) ((b1 & 0xFE) == 0xE8 || IsJcc(b0, b1)) + +#define kNumTopBits 24 +#define kTopValue ((uint32_t)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_READ_BYTE (*buffer++) + +int Bcj2_Decode( + const uint8_t *buf0, size_t size0, + const uint8_t *buf1, size_t size1, + const uint8_t *buf2, size_t size2, + const uint8_t *buf3, size_t size3, + uint8_t *outBuf, size_t outSize) +{ + uint16_t p[256 + 2]; + size_t inPos = 0, outPos = 0; + + const uint8_t *buffer, *bufferLim; + uint32_t range, codes = 0; + uint8_t prevuint8_t = 0; + + unsigned int i; + for (i = 0; i < sizeof(p) / sizeof(p[0]); i++) + p[i] = kBitModelTotal >> 1; + + buffer = buf3; + bufferLim = buffer + size3; + range = 0xFFFFFFFF; + + for (i = 0; i < 5; i++) + { + if (buffer == bufferLim) + return SZ_ERROR_DATA; + codes = (codes << 8) | RC_READ_BYTE; + } + + if (outSize == 0) + return SZ_OK; + + for (;;) + { + uint8_t b; + uint16_t *prob; + uint32_t bound; + uint32_t ttt; + + size_t limit = size0 - inPos; + if (outSize - outPos < limit) + limit = outSize - outPos; + while (limit != 0) + { + b = buf0[inPos]; + outBuf[outPos++] = b; + if (IsJ(prevuint8_t, b)) + break; + inPos++; + prevuint8_t = b; + limit--; + } + + if (limit == 0 || outPos == outSize) + break; + + b = buf0[inPos++]; + + if (b == 0xE8) + prob = p + prevuint8_t; + else if (b == 0xE9) + prob = p + 256; + else + prob = p + 257; + + ttt = *(prob); + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + range = bound; + *(prob) = (uint16_t)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); + + if (range < kTopValue) + { + if (buffer == bufferLim) + return SZ_ERROR_DATA; + range <<= 8; + codes = (codes << 8) | RC_READ_BYTE; + } + prevuint8_t = b; + } + else + { + uint32_t dest; + const uint8_t *v; + + range -= bound; + codes -= bound; + *(prob) = (uint16_t)(ttt - (ttt >> kNumMoveBits)); + + if (range < kTopValue) + { + if (buffer == bufferLim) + return SZ_ERROR_DATA; + range <<= 8; + codes = (codes << 8) | RC_READ_BYTE; + } + + if (b == 0xE8) + { + v = buf1; + if (size1 < 4) + return SZ_ERROR_DATA; + buf1 += 4; + size1 -= 4; + } + else + { + v = buf2; + if (size2 < 4) + return SZ_ERROR_DATA; + buf2 += 4; + size2 -= 4; + } + dest = (((uint32_t)v[0] << 24) | ((uint32_t)v[1] << 16) | + ((uint32_t)v[2] << 8) | ((uint32_t)v[3])) - ((uint32_t)outPos + 4); + outBuf[outPos++] = (uint8_t)dest; + if (outPos == outSize) + break; + outBuf[outPos++] = (uint8_t)(dest >> 8); + if (outPos == outSize) + break; + outBuf[outPos++] = (uint8_t)(dest >> 16); + if (outPos == outSize) + break; + outBuf[outPos++] = prevuint8_t = (uint8_t)(dest >> 24); + } + } + return (outPos == outSize) ? SZ_OK : SZ_ERROR_DATA; +} diff --git a/deps/7zip/Bcj2.h b/deps/7zip/Bcj2.h index a7651499f7..edca41e0a9 100644 --- a/deps/7zip/Bcj2.h +++ b/deps/7zip/Bcj2.h @@ -1,38 +1,38 @@ -/* Bcj2.h -- Converter for x86 code (BCJ2) -2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __BCJ2_H -#define __BCJ2_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* -Conditions: - outSize <= FullOutputSize, - where FullOutputSize is full size of output stream of x86_2 filter. - -If buf0 overlaps outBuf, there are two required conditions: - 1) (buf0 >= outBuf) - 2) (buf0 + size0 >= outBuf + FullOutputSize). - -Returns: - SZ_OK - SZ_ERROR_DATA - Data error -*/ - -int Bcj2_Decode( - const uint8_t *buf0, size_t size0, - const uint8_t *buf1, size_t size1, - const uint8_t *buf2, size_t size2, - const uint8_t *buf3, size_t size3, - uint8_t *outBuf, size_t outSize); - -#ifdef __cplusplus -} -#endif - -#endif +/* Bcj2.h -- Converter for x86 code (BCJ2) +2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __BCJ2_H +#define __BCJ2_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +Conditions: + outSize <= FullOutputSize, + where FullOutputSize is full size of output stream of x86_2 filter. + +If buf0 overlaps outBuf, there are two required conditions: + 1) (buf0 >= outBuf) + 2) (buf0 + size0 >= outBuf + FullOutputSize). + +Returns: + SZ_OK + SZ_ERROR_DATA - Data error +*/ + +int Bcj2_Decode( + const uint8_t *buf0, size_t size0, + const uint8_t *buf1, size_t size1, + const uint8_t *buf2, size_t size2, + const uint8_t *buf3, size_t size3, + uint8_t *outBuf, size_t outSize); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/Bra.c b/deps/7zip/Bra.c index 40a0e5f9ed..49df0831b3 100644 --- a/deps/7zip/Bra.c +++ b/deps/7zip/Bra.c @@ -1,134 +1,134 @@ -/* Bra.c -- Converters for RISC code - 2010-04-16 : Igor Pavlov : Public domain */ - -#include -#include "Bra.h" - -size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) -{ - size_t i; - if (size < 4) - return 0; - size -= 4; - ip += 8; - for (i = 0; i <= size; i += 4) - { - if (data[i + 3] == 0xEB) - { - uint32_t dest; - uint32_t src = ((uint32_t)data[i + 2] << 16) | ((uint32_t)data[i + 1] << 8) | (data[i + 0]); - src <<= 2; - if (encoding) - dest = ip + (uint32_t)i + src; - else - dest = src - (ip + (uint32_t)i); - dest >>= 2; - data[i + 2] = (uint8_t)(dest >> 16); - data[i + 1] = (uint8_t)(dest >> 8); - data[i + 0] = (uint8_t)dest; - } - } - return i; -} - -size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) -{ - size_t i; - if (size < 4) - return 0; - size -= 4; - ip += 4; - for (i = 0; i <= size; i += 2) - { - if ((data[i + 1] & 0xF8) == 0xF0 && - (data[i + 3] & 0xF8) == 0xF8) - { - uint32_t dest; - uint32_t src = - (((uint32_t)data[i + 1] & 0x7) << 19) | - ((uint32_t)data[i + 0] << 11) | - (((uint32_t)data[i + 3] & 0x7) << 8) | - (data[i + 2]); - - src <<= 1; - if (encoding) - dest = ip + (uint32_t)i + src; - else - dest = src - (ip + (uint32_t)i); - dest >>= 1; - - data[i + 1] = (uint8_t)(0xF0 | ((dest >> 19) & 0x7)); - data[i + 0] = (uint8_t)(dest >> 11); - data[i + 3] = (uint8_t)(0xF8 | ((dest >> 8) & 0x7)); - data[i + 2] = (uint8_t)dest; - i += 2; - } - } - return i; -} - -size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) -{ - size_t i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) - { - uint32_t src = ((uint32_t)(data[i + 0] & 3) << 24) | - ((uint32_t)data[i + 1] << 16) | - ((uint32_t)data[i + 2] << 8) | - ((uint32_t)data[i + 3] & (~3)); - - uint32_t dest; - if (encoding) - dest = ip + (uint32_t)i + src; - else - dest = src - (ip + (uint32_t)i); - data[i + 0] = (uint8_t)(0x48 | ((dest >> 24) & 0x3)); - data[i + 1] = (uint8_t)(dest >> 16); - data[i + 2] = (uint8_t)(dest >> 8); - data[i + 3] &= 0x3; - data[i + 3] |= dest; - } - } - return i; -} - -size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) -{ - uint32_t i; - if (size < 4) - return 0; - size -= 4; - for (i = 0; i <= size; i += 4) - { - if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || - (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) - { - uint32_t src = - ((uint32_t)data[i + 0] << 24) | - ((uint32_t)data[i + 1] << 16) | - ((uint32_t)data[i + 2] << 8) | - ((uint32_t)data[i + 3]); - uint32_t dest; - - src <<= 2; - if (encoding) - dest = ip + i + src; - else - dest = src - (ip + i); - dest >>= 2; - - dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; - - data[i + 0] = (uint8_t)(dest >> 24); - data[i + 1] = (uint8_t)(dest >> 16); - data[i + 2] = (uint8_t)(dest >> 8); - data[i + 3] = (uint8_t)dest; - } - } - return i; -} +/* Bra.c -- Converters for RISC code + 2010-04-16 : Igor Pavlov : Public domain */ + +#include +#include "Bra.h" + +size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) +{ + size_t i; + if (size < 4) + return 0; + size -= 4; + ip += 8; + for (i = 0; i <= size; i += 4) + { + if (data[i + 3] == 0xEB) + { + uint32_t dest; + uint32_t src = ((uint32_t)data[i + 2] << 16) | ((uint32_t)data[i + 1] << 8) | (data[i + 0]); + src <<= 2; + if (encoding) + dest = ip + (uint32_t)i + src; + else + dest = src - (ip + (uint32_t)i); + dest >>= 2; + data[i + 2] = (uint8_t)(dest >> 16); + data[i + 1] = (uint8_t)(dest >> 8); + data[i + 0] = (uint8_t)dest; + } + } + return i; +} + +size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) +{ + size_t i; + if (size < 4) + return 0; + size -= 4; + ip += 4; + for (i = 0; i <= size; i += 2) + { + if ((data[i + 1] & 0xF8) == 0xF0 && + (data[i + 3] & 0xF8) == 0xF8) + { + uint32_t dest; + uint32_t src = + (((uint32_t)data[i + 1] & 0x7) << 19) | + ((uint32_t)data[i + 0] << 11) | + (((uint32_t)data[i + 3] & 0x7) << 8) | + (data[i + 2]); + + src <<= 1; + if (encoding) + dest = ip + (uint32_t)i + src; + else + dest = src - (ip + (uint32_t)i); + dest >>= 1; + + data[i + 1] = (uint8_t)(0xF0 | ((dest >> 19) & 0x7)); + data[i + 0] = (uint8_t)(dest >> 11); + data[i + 3] = (uint8_t)(0xF8 | ((dest >> 8) & 0x7)); + data[i + 2] = (uint8_t)dest; + i += 2; + } + } + return i; +} + +size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) +{ + size_t i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1) + { + uint32_t src = ((uint32_t)(data[i + 0] & 3) << 24) | + ((uint32_t)data[i + 1] << 16) | + ((uint32_t)data[i + 2] << 8) | + ((uint32_t)data[i + 3] & (~3)); + + uint32_t dest; + if (encoding) + dest = ip + (uint32_t)i + src; + else + dest = src - (ip + (uint32_t)i); + data[i + 0] = (uint8_t)(0x48 | ((dest >> 24) & 0x3)); + data[i + 1] = (uint8_t)(dest >> 16); + data[i + 2] = (uint8_t)(dest >> 8); + data[i + 3] &= 0x3; + data[i + 3] |= dest; + } + } + return i; +} + +size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding) +{ + uint32_t i; + if (size < 4) + return 0; + size -= 4; + for (i = 0; i <= size; i += 4) + { + if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) || + (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0)) + { + uint32_t src = + ((uint32_t)data[i + 0] << 24) | + ((uint32_t)data[i + 1] << 16) | + ((uint32_t)data[i + 2] << 8) | + ((uint32_t)data[i + 3]); + uint32_t dest; + + src <<= 2; + if (encoding) + dest = ip + i + src; + else + dest = src - (ip + i); + dest >>= 2; + + dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000; + + data[i + 0] = (uint8_t)(dest >> 24); + data[i + 1] = (uint8_t)(dest >> 16); + data[i + 2] = (uint8_t)(dest >> 8); + data[i + 3] = (uint8_t)dest; + } + } + return i; +} diff --git a/deps/7zip/Bra.h b/deps/7zip/Bra.h index 3e9d9d9a30..52fa0b30b1 100644 --- a/deps/7zip/Bra.h +++ b/deps/7zip/Bra.h @@ -1,68 +1,68 @@ -/* Bra.h -- Branch converters for executables - 2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __BRA_H -#define __BRA_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - - /* - These functions convert relative addresses to absolute addresses - in CALL instructions to increase the compression ratio. - -In: -data - data buffer -size - size of data -ip - current virtual Instruction Pinter (IP) value -state - state variable for x86 converter -encoding - 0 (for decoding), 1 (for encoding) - -Out: -state - state variable for x86 converter - -Returns: -The number of processed bytes. If you call these functions with multiple calls, -you must start next call with first byte after block of processed bytes. - -Type Endian Alignment LookAhead - -x86 little 1 4 -ARMT little 2 2 -ARM little 4 0 -PPC big 4 0 -SPARC big 4 0 -IA64 little 16 0 - -size must be >= Alignment + LookAhead, if it's not last block. -If (size < Alignment + LookAhead), converter returns 0. - -Example: - -uint32_t ip = 0; -for () -{ -; size must be >= Alignment + LookAhead, if it's not last block -size_t processed = Convert(data, size, ip, 1); -data += processed; -size -= processed; -ip += processed; -} -*/ - -#define x86_Convert_Init(state) { state = 0; } -size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding); -size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); -size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); -size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); -size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); -size_t IA64_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); - -#ifdef __cplusplus -} -#endif - -#endif +/* Bra.h -- Branch converters for executables + 2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __BRA_H +#define __BRA_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + + /* + These functions convert relative addresses to absolute addresses + in CALL instructions to increase the compression ratio. + +In: +data - data buffer +size - size of data +ip - current virtual Instruction Pinter (IP) value +state - state variable for x86 converter +encoding - 0 (for decoding), 1 (for encoding) + +Out: +state - state variable for x86 converter + +Returns: +The number of processed bytes. If you call these functions with multiple calls, +you must start next call with first byte after block of processed bytes. + +Type Endian Alignment LookAhead + +x86 little 1 4 +ARMT little 2 2 +ARM little 4 0 +PPC big 4 0 +SPARC big 4 0 +IA64 little 16 0 + +size must be >= Alignment + LookAhead, if it's not last block. +If (size < Alignment + LookAhead), converter returns 0. + +Example: + +uint32_t ip = 0; +for () +{ +; size must be >= Alignment + LookAhead, if it's not last block +size_t processed = Convert(data, size, ip, 1); +data += processed; +size -= processed; +ip += processed; +} +*/ + +#define x86_Convert_Init(state) { state = 0; } +size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding); +size_t ARM_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); +size_t ARMT_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); +size_t PPC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); +size_t SPARC_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); +size_t IA64_Convert(uint8_t *data, size_t size, uint32_t ip, int encoding); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/Bra86.c b/deps/7zip/Bra86.c index 6cb7bb17f5..d404527199 100644 --- a/deps/7zip/Bra86.c +++ b/deps/7zip/Bra86.c @@ -1,86 +1,86 @@ -/* Bra86.c -- Converter for x86 code (BCJ) - 2008-10-04 : Igor Pavlov : Public domain */ - -#include -#include "Bra.h" - -#define Test86MSuint8_t(b) ((b) == 0 || (b) == 0xFF) - -const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; -const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; - -size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding) -{ - size_t bufferPos = 0, prevPosT; - uint32_t prevMask = *state & 0x7; - if (size < 5) - return 0; - ip += 5; - prevPosT = (size_t)0 - 1; - - for (;;) - { - uint8_t *p = data + bufferPos; - uint8_t *limit = data + size - 4; - for (; p < limit; p++) - if ((*p & 0xFE) == 0xE8) - break; - bufferPos = (size_t)(p - data); - if (p >= limit) - break; - prevPosT = bufferPos - prevPosT; - if (prevPosT > 3) - prevMask = 0; - else - { - prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; - if (prevMask != 0) - { - uint8_t b = p[4 - kMaskToBitNumber[prevMask]]; - if (!kMaskToAllowedStatus[prevMask] || Test86MSuint8_t(b)) - { - prevPosT = bufferPos; - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; - continue; - } - } - } - prevPosT = bufferPos; - - if (Test86MSuint8_t(p[4])) - { - uint32_t src = ((uint32_t)p[4] << 24) | ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) | ((uint32_t)p[1]); - uint32_t dest; - for (;;) - { - uint8_t b; - int idx; - if (encoding) - dest = (ip + (uint32_t)bufferPos) + src; - else - dest = src - (ip + (uint32_t)bufferPos); - if (prevMask == 0) - break; - idx = kMaskToBitNumber[prevMask] * 8; - b = (uint8_t)(dest >> (24 - idx)); - if (!Test86MSuint8_t(b)) - break; - src = dest ^ ((1 << (32 - idx)) - 1); - } - p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1)); - p[3] = (uint8_t)(dest >> 16); - p[2] = (uint8_t)(dest >> 8); - p[1] = (uint8_t)dest; - bufferPos += 5; - } - else - { - prevMask = ((prevMask << 1) & 0x7) | 1; - bufferPos++; - } - } - prevPosT = bufferPos - prevPosT; - *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); - return bufferPos; -} +/* Bra86.c -- Converter for x86 code (BCJ) + 2008-10-04 : Igor Pavlov : Public domain */ + +#include +#include "Bra.h" + +#define Test86MSuint8_t(b) ((b) == 0 || (b) == 0xFF) + +const uint8_t kMaskToAllowedStatus[8] = {1, 1, 1, 0, 1, 0, 0, 0}; +const uint8_t kMaskToBitNumber[8] = {0, 1, 2, 2, 3, 3, 3, 3}; + +size_t x86_Convert(uint8_t *data, size_t size, uint32_t ip, uint32_t *state, int encoding) +{ + size_t bufferPos = 0, prevPosT; + uint32_t prevMask = *state & 0x7; + if (size < 5) + return 0; + ip += 5; + prevPosT = (size_t)0 - 1; + + for (;;) + { + uint8_t *p = data + bufferPos; + uint8_t *limit = data + size - 4; + for (; p < limit; p++) + if ((*p & 0xFE) == 0xE8) + break; + bufferPos = (size_t)(p - data); + if (p >= limit) + break; + prevPosT = bufferPos - prevPosT; + if (prevPosT > 3) + prevMask = 0; + else + { + prevMask = (prevMask << ((int)prevPosT - 1)) & 0x7; + if (prevMask != 0) + { + uint8_t b = p[4 - kMaskToBitNumber[prevMask]]; + if (!kMaskToAllowedStatus[prevMask] || Test86MSuint8_t(b)) + { + prevPosT = bufferPos; + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + continue; + } + } + } + prevPosT = bufferPos; + + if (Test86MSuint8_t(p[4])) + { + uint32_t src = ((uint32_t)p[4] << 24) | ((uint32_t)p[3] << 16) | ((uint32_t)p[2] << 8) | ((uint32_t)p[1]); + uint32_t dest; + for (;;) + { + uint8_t b; + int idx; + if (encoding) + dest = (ip + (uint32_t)bufferPos) + src; + else + dest = src - (ip + (uint32_t)bufferPos); + if (prevMask == 0) + break; + idx = kMaskToBitNumber[prevMask] * 8; + b = (uint8_t)(dest >> (24 - idx)); + if (!Test86MSuint8_t(b)) + break; + src = dest ^ ((1 << (32 - idx)) - 1); + } + p[4] = (uint8_t)(~(((dest >> 24) & 1) - 1)); + p[3] = (uint8_t)(dest >> 16); + p[2] = (uint8_t)(dest >> 8); + p[1] = (uint8_t)dest; + bufferPos += 5; + } + else + { + prevMask = ((prevMask << 1) & 0x7) | 1; + bufferPos++; + } + } + prevPosT = bufferPos - prevPosT; + *state = ((prevPosT > 3) ? 0 : ((prevMask << ((int)prevPosT - 1)) & 0x7)); + return bufferPos; +} diff --git a/deps/7zip/CpuArch.h b/deps/7zip/CpuArch.h index 700945f617..b223f1a7cb 100644 --- a/deps/7zip/CpuArch.h +++ b/deps/7zip/CpuArch.h @@ -1,71 +1,71 @@ -/* CpuArch.h -- CPU specific code -2010-10-26: Igor Pavlov : Public domain */ - -#ifndef __CPU_ARCH_H -#define __CPU_ARCH_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* -MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. -If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. -*/ - -#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) -#define MY_CPU_AMD64 -#endif - -#if defined(MY_CPU_AMD64) || defined(_M_IA64) -#define MY_CPU_64BIT -#endif - -#if defined(_M_IX86) || defined(__i386__) -#define MY_CPU_X86 -#endif - -#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) -#define MY_CPU_X86_OR_AMD64 -#endif - -#if defined(MY_CPU_X86) || defined(_M_ARM) -#define MY_CPU_32BIT -#endif - -#if defined(_WIN32) && defined(_M_ARM) -#define MY_CPU_ARM_LE -#endif - -#if defined(_WIN32) && defined(_M_IA64) -#define MY_CPU_IA64_LE -#endif - -#if defined(MY_CPU_X86_OR_AMD64) -#define MY_CPU_LE_UNALIGN -#endif - -#ifdef MY_CPU_LE_UNALIGN - -#define GetUi16(p) (*(const uint16_t *)(p)) -#define GetUi32(p) (*(const uint32_t *)(p)) -#define GetUi64(p) (*(const uint64_t *)(p)) -#else -#define GetUi16(p) (((const uint8_t *)(p))[0] | ((uint16_t)((const uint8_t *)(p))[1] << 8)) - -#define GetUi32(p) ( \ - ((const uint8_t *)(p))[0] | \ - ((uint32_t)((const uint8_t *)(p))[1] << 8) | \ - ((uint32_t)((const uint8_t *)(p))[2] << 16) | \ - ((uint32_t)((const uint8_t *)(p))[3] << 24)) - -#define GetUi64(p) (GetUi32(p) | ((uint64_t)GetUi32(((const uint8_t *)(p)) + 4) << 32)) -#endif - -#ifdef __cplusplus -} -#endif - -#endif +/* CpuArch.h -- CPU specific code +2010-10-26: Igor Pavlov : Public domain */ + +#ifndef __CPU_ARCH_H +#define __CPU_ARCH_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses. +If MY_CPU_LE_UNALIGN is not defined, we don't know about these properties of platform. +*/ + +#if defined(_M_X64) || defined(_M_AMD64) || defined(__x86_64__) +#define MY_CPU_AMD64 +#endif + +#if defined(MY_CPU_AMD64) || defined(_M_IA64) +#define MY_CPU_64BIT +#endif + +#if defined(_M_IX86) || defined(__i386__) +#define MY_CPU_X86 +#endif + +#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64) +#define MY_CPU_X86_OR_AMD64 +#endif + +#if defined(MY_CPU_X86) || defined(_M_ARM) +#define MY_CPU_32BIT +#endif + +#if defined(_WIN32) && defined(_M_ARM) +#define MY_CPU_ARM_LE +#endif + +#if defined(_WIN32) && defined(_M_IA64) +#define MY_CPU_IA64_LE +#endif + +#if defined(MY_CPU_X86_OR_AMD64) +#define MY_CPU_LE_UNALIGN +#endif + +#ifdef MY_CPU_LE_UNALIGN + +#define GetUi16(p) (*(const uint16_t *)(p)) +#define GetUi32(p) (*(const uint32_t *)(p)) +#define GetUi64(p) (*(const uint64_t *)(p)) +#else +#define GetUi16(p) (((const uint8_t *)(p))[0] | ((uint16_t)((const uint8_t *)(p))[1] << 8)) + +#define GetUi32(p) ( \ + ((const uint8_t *)(p))[0] | \ + ((uint32_t)((const uint8_t *)(p))[1] << 8) | \ + ((uint32_t)((const uint8_t *)(p))[2] << 16) | \ + ((uint32_t)((const uint8_t *)(p))[3] << 24)) + +#define GetUi64(p) (GetUi32(p) | ((uint64_t)GetUi32(((const uint8_t *)(p)) + 4) << 32)) +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/LzFind.c b/deps/7zip/LzFind.c index e41014e65f..0ad8c2c733 100644 --- a/deps/7zip/LzFind.c +++ b/deps/7zip/LzFind.c @@ -73,7 +73,7 @@ static void MatchFinder_ReadBlock(CMatchFinder *p) p->streamEndWasReached = 1; return; } - + for (;;) { unsigned char *dest = p->buffer + (p->streamPos - p->pos); @@ -179,24 +179,24 @@ int MatchFinder_Create(CMatchFinder *p, uint32_t historySize, ISzAlloc *alloc) { uint32_t sizeReserv; - + if (historySize > LzFindkMaxHistorySize) { MatchFinder_Free(p, alloc); return 0; } - + sizeReserv = historySize >> 1; if (historySize >= ((uint32_t)3 << 30)) sizeReserv = historySize >> 3; else if (historySize >= ((uint32_t)2 << 30)) sizeReserv = historySize >> 2; - + sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19); p->keepSizeBefore = historySize + keepAddBufferBefore + 1; p->keepSizeAfter = matchMaxLen + keepAddBufferAfter; - + /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */ - + if (LzInWindow_Create(p, sizeReserv, alloc)) { uint32_t newCyclicBufferSize = historySize + 1; @@ -238,7 +238,7 @@ int MatchFinder_Create(CMatchFinder *p, uint32_t historySize, p->historySize = historySize; p->hashSizeSum = hs; p->cyclicBufferSize = newCyclicBufferSize; - + numSons = newCyclicBufferSize; if (p->btMode) numSons <<= 1; @@ -246,11 +246,11 @@ int MatchFinder_Create(CMatchFinder *p, uint32_t historySize, if (p->hash && p->numRefs == newSize) return 1; - + MatchFinder_FreeThisClassMemory(p, alloc); p->numRefs = newSize; p->hash = AllocRefs(newSize, alloc); - + if (p->hash) { p->son = p->hash + p->hashSizeSum; @@ -267,11 +267,11 @@ static void MatchFinder_SetLimits(CMatchFinder *p) { uint32_t limit = kMaxValForNormalize - p->pos; uint32_t limit2 = p->cyclicBufferSize - p->cyclicBufferPos; - + if (limit2 < limit) limit = limit2; limit2 = p->streamPos - p->pos; - + if (limit2 <= p->keepSizeAfter) { if (limit2 > 0) @@ -279,10 +279,10 @@ static void MatchFinder_SetLimits(CMatchFinder *p) } else limit2 -= p->keepSizeAfter; - + if (limit2 < limit) limit = limit2; - + { uint32_t lenLimit = p->streamPos - p->pos; if (lenLimit > p->matchMaxLen) @@ -299,16 +299,16 @@ void MatchFinder_Init_2(CMatchFinder *p, int readData) uint32_t num = p->hashSizeSum; for (i = 0; i < num; i++) hash[i] = kEmptyHashValue; - + p->cyclicBufferPos = 0; p->buffer = p->bufferBase; p->pos = p->streamPos = p->cyclicBufferSize; p->result = SZ_OK; p->streamEndWasReached = 0; - + if (readData) MatchFinder_ReadBlock(p); - + MatchFinder_SetLimits(p); } @@ -316,7 +316,7 @@ void MatchFinder_Init(CMatchFinder *p) { MatchFinder_Init_2(p, true); } - + static uint32_t MatchFinder_GetSubValue(CMatchFinder *p) { return (p->pos - p->historySize - 1) & kNormalizeMask; @@ -559,7 +559,7 @@ static uint32_t Bt3_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) d2 = pos - hash[h2]; curMatch = hash[kFix3HashSize + hv]; - + hash[h2] = pos; hash[kFix3HashSize + hv] = pos; @@ -578,7 +578,7 @@ static uint32_t Bt3_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) MOVE_POS_RET; } } - + GET_MATCHES_FOOTER(offset, maxLen) } @@ -604,14 +604,14 @@ static uint32_t Bt4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) maxLen = 0; offset = 0; - + if (d2 < p->cyclicBufferSize && *(cur - d2) == *cur) { distances[0] = maxLen = 2; distances[1] = d2 - 1; offset = 2; } - + if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) { maxLen = 3; @@ -619,7 +619,7 @@ static uint32_t Bt4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) offset += 2; d2 = d3; } - + if (offset != 0) { UPDATE_maxLen @@ -630,10 +630,10 @@ static uint32_t Bt4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) MOVE_POS_RET; } } - + if (maxLen < 3) maxLen = 3; - + GET_MATCHES_FOOTER(offset, maxLen) } @@ -647,10 +647,10 @@ static uint32_t Hc4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) hash = p->hash; pos = p->pos; - + d2 = pos - hash[ h2]; d3 = pos - hash[kFix3HashSize + h3]; - + curMatch = hash[kFix4HashSize + hv]; hash[ h2] = pos; @@ -666,7 +666,7 @@ static uint32_t Hc4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) distances[1] = d2 - 1; offset = 2; } - + if (d2 != d3 && d3 < p->cyclicBufferSize && *(cur - d3) == *cur) { maxLen = 3; @@ -674,7 +674,7 @@ static uint32_t Hc4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) offset += 2; d2 = d3; } - + if (offset != 0) { UPDATE_maxLen @@ -685,7 +685,7 @@ static uint32_t Hc4_MatchFinder_GetMatches(CMatchFinder *p, uint32_t *distances) MOVE_POS_RET; } } - + if (maxLen < 3) maxLen = 3; diff --git a/deps/7zip/LzFind.h b/deps/7zip/LzFind.h index a7fc117536..063eceb5e4 100644 --- a/deps/7zip/LzFind.h +++ b/deps/7zip/LzFind.h @@ -34,7 +34,7 @@ typedef struct _CMatchFinder unsigned char *bufferBase; ISeqInStream *stream; - + uint32_t blockSize; uint32_t keepSizeBefore; uint32_t keepSizeAfter; @@ -57,7 +57,7 @@ typedef struct _CMatchFinder ((p)->streamEndWasReached \ && (p)->streamPos == (p)->pos \ && (!(p)->directInput || (p)->directInputRem == 0)) - + int MatchFinder_NeedMove(CMatchFinder *p); unsigned char *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p); void MatchFinder_MoveBlock(CMatchFinder *p); diff --git a/deps/7zip/Lzma2Dec.c b/deps/7zip/Lzma2Dec.c index a99b1f91b3..5b8a61c7d5 100644 --- a/deps/7zip/Lzma2Dec.c +++ b/deps/7zip/Lzma2Dec.c @@ -1,347 +1,347 @@ -/* Lzma2Dec.c -- LZMA2 Decoder - 2009-05-03 : Igor Pavlov : Public domain */ - -#include -#include - -#include "Lzma2Dec.h" - -/* - 00000000 - EOS - 00000001 U U - Uncompressed Reset Dic - 00000010 U U - Uncompressed No Reset - 100uuuuu U U P P - LZMA no reset - 101uuuuu U U P P - LZMA reset state - 110uuuuu U U P P S - LZMA reset state + new prop - 111uuuuu U U P P S - LZMA reset state + new prop + reset dic - - u, U - Unpack Size - P - Pack Size - S - Props - */ - -#define LZMA2_CONTROL_LZMA (1 << 7) -#define LZMA2_CONTROL_COPY_NO_RESET 2 -#define LZMA2_CONTROL_COPY_RESET_DIC 1 -#define LZMA2_CONTROL_EOF 0 - -#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) - -#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) -#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) - -#define LZMA2_LCLP_MAX 4 -#define LZMA2_DIC_SIZE_FROM_PROP(p) (((uint32_t)2 | ((p) & 1)) << ((p) / 2 + 11)) - -#define PRF(x) - -typedef enum -{ - LZMA2_STATE_CONTROL, - LZMA2_STATE_UNPACK0, - LZMA2_STATE_UNPACK1, - LZMA2_STATE_PACK0, - LZMA2_STATE_PACK1, - LZMA2_STATE_PROP, - LZMA2_STATE_DATA, - LZMA2_STATE_DATA_CONT, - LZMA2_STATE_FINISHED, - LZMA2_STATE_ERROR -} ELzma2State; - -static SRes Lzma2Dec_GetOldProps(uint8_t prop, uint8_t *props) -{ - uint32_t dicSize; - if (prop > 40) - return SZ_ERROR_UNSUPPORTED; - dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); - props[0] = (uint8_t)LZMA2_LCLP_MAX; - props[1] = (uint8_t)(dicSize); - props[2] = (uint8_t)(dicSize >> 8); - props[3] = (uint8_t)(dicSize >> 16); - props[4] = (uint8_t)(dicSize >> 24); - return SZ_OK; -} - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) -{ - uint8_t props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) -{ - uint8_t props[LZMA_PROPS_SIZE]; - RINOK(Lzma2Dec_GetOldProps(prop, props)); - return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); -} - -void Lzma2Dec_Init(CLzma2Dec *p) -{ - p->state = LZMA2_STATE_CONTROL; - p->needInitDic = true; - p->needInitState = true; - p->needInitProp = true; - LzmaDec_Init(&p->decoder); -} - -static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, uint8_t b) -{ - switch(p->state) - { - case LZMA2_STATE_CONTROL: - p->control = b; - PRF(printf("\n %4X ", p->decoder.dicPos)); - PRF(printf(" %2X", b)); - if (p->control == 0) - return LZMA2_STATE_FINISHED; - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if ((p->control & 0x7F) > 2) - return LZMA2_STATE_ERROR; - p->unpackSize = 0; - } - else - p->unpackSize = (uint32_t)(p->control & 0x1F) << 16; - return LZMA2_STATE_UNPACK0; - - case LZMA2_STATE_UNPACK0: - p->unpackSize |= (uint32_t)b << 8; - return LZMA2_STATE_UNPACK1; - - case LZMA2_STATE_UNPACK1: - p->unpackSize |= (uint32_t)b; - p->unpackSize++; - PRF(printf(" %8d", p->unpackSize)); - return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; - - case LZMA2_STATE_PACK0: - p->packSize = (uint32_t)b << 8; - return LZMA2_STATE_PACK1; - - case LZMA2_STATE_PACK1: - p->packSize |= (uint32_t)b; - p->packSize++; - PRF(printf(" %8d", p->packSize)); - return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: - (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); - - case LZMA2_STATE_PROP: - { - int lc, lp; - if (b >= (9 * 5 * 5)) - return LZMA2_STATE_ERROR; - lc = b % 9; - b /= 9; - p->decoder.prop.pb = b / 5; - lp = b % 5; - if (lc + lp > LZMA2_LCLP_MAX) - return LZMA2_STATE_ERROR; - p->decoder.prop.lc = lc; - p->decoder.prop.lp = lp; - p->needInitProp = false; - return LZMA2_STATE_DATA; - } - } - return LZMA2_STATE_ERROR; -} - -static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const uint8_t *src, size_t size) -{ - memcpy(p->dic + p->dicPos, src, size); - p->dicPos += size; - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) - p->checkDicSize = p->prop.dicSize; - p->processedPos += (uint32_t)size; -} - -void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState); - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit, - const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - size_t inSize = *srcLen; - *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->state != LZMA2_STATE_FINISHED) - { - size_t dicPos = p->decoder.dicPos; - if (p->state == LZMA2_STATE_ERROR) - return SZ_ERROR_DATA; - if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - (*srcLen)++; - p->state = Lzma2Dec_UpdateState(p, *src++); - continue; - } - { - size_t destSizeCur = dicLimit - dicPos; - size_t srcSizeCur = inSize - *srcLen; - ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; - - if (p->unpackSize <= destSizeCur) - { - destSizeCur = (size_t)p->unpackSize; - curFinishMode = LZMA_FINISH_END; - } - - if (LZMA2_IS_UNCOMPRESSED_STATE(p)) - { - if (*srcLen == inSize) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - - if (p->state == LZMA2_STATE_DATA) - { - bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); - if (initDic) - p->needInitProp = p->needInitState = true; - else if (p->needInitDic) - return SZ_ERROR_DATA; - p->needInitDic = false; - LzmaDec_InitDicAndState(&p->decoder, initDic, false); - } - - if (srcSizeCur > destSizeCur) - srcSizeCur = destSizeCur; - - if (srcSizeCur == 0) - return SZ_ERROR_DATA; - - LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->unpackSize -= (uint32_t)srcSizeCur; - p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; - } - else - { - size_t outSizeProcessed; - SRes res; - - if (p->state == LZMA2_STATE_DATA) - { - int mode = LZMA2_GET_LZMA_MODE(p); - bool initDic = (mode == 3); - bool initState = (mode > 0); - if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) - return SZ_ERROR_DATA; - - LzmaDec_InitDicAndState(&p->decoder, initDic, initState); - p->needInitDic = false; - p->needInitState = false; - p->state = LZMA2_STATE_DATA_CONT; - } - if (srcSizeCur > p->packSize) - srcSizeCur = (size_t)p->packSize; - - res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); - - src += srcSizeCur; - *srcLen += srcSizeCur; - p->packSize -= (uint32_t)srcSizeCur; - - outSizeProcessed = p->decoder.dicPos - dicPos; - p->unpackSize -= (uint32_t)outSizeProcessed; - - RINOK(res); - if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) - return res; - - if (srcSizeCur == 0 && outSizeProcessed == 0) - { - if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || - p->unpackSize != 0 || p->packSize != 0) - return SZ_ERROR_DATA; - p->state = LZMA2_STATE_CONTROL; - } - if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) - *status = LZMA_STATUS_NOT_FINISHED; - } - } - } - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return SZ_OK; -} - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - size_t outSize = *destLen, inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - size_t srcSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->decoder.dicPos == p->decoder.dicBufSize) - p->decoder.dicPos = 0; - dicPos = p->decoder.dicPos; - if (outSize > p->decoder.dicBufSize - dicPos) - { - outSizeCur = p->decoder.dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); - src += srcSizeCur; - inSize -= srcSizeCur; - *srcLen += srcSizeCur; - outSizeCur = p->decoder.dicPos - dicPos; - memcpy(dest, p->decoder.dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, - uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzma2Dec decoder; - SRes res; - size_t outSize = *destLen, inSize = *srcLen; - uint8_t props[LZMA_PROPS_SIZE]; - - Lzma2Dec_Construct(&decoder); - - *destLen = *srcLen = 0; - *status = LZMA_STATUS_NOT_SPECIFIED; - decoder.decoder.dic = dest; - decoder.decoder.dicBufSize = outSize; - - RINOK(Lzma2Dec_GetOldProps(prop, props)); - RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); - - *srcLen = inSize; - res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); - *destLen = decoder.decoder.dicPos; - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - - LzmaDec_FreeProbs(&decoder.decoder, alloc); - return res; -} +/* Lzma2Dec.c -- LZMA2 Decoder + 2009-05-03 : Igor Pavlov : Public domain */ + +#include +#include + +#include "Lzma2Dec.h" + +/* + 00000000 - EOS + 00000001 U U - Uncompressed Reset Dic + 00000010 U U - Uncompressed No Reset + 100uuuuu U U P P - LZMA no reset + 101uuuuu U U P P - LZMA reset state + 110uuuuu U U P P S - LZMA reset state + new prop + 111uuuuu U U P P S - LZMA reset state + new prop + reset dic + + u, U - Unpack Size + P - Pack Size + S - Props + */ + +#define LZMA2_CONTROL_LZMA (1 << 7) +#define LZMA2_CONTROL_COPY_NO_RESET 2 +#define LZMA2_CONTROL_COPY_RESET_DIC 1 +#define LZMA2_CONTROL_EOF 0 + +#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0) + +#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3) +#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2) + +#define LZMA2_LCLP_MAX 4 +#define LZMA2_DIC_SIZE_FROM_PROP(p) (((uint32_t)2 | ((p) & 1)) << ((p) / 2 + 11)) + +#define PRF(x) + +typedef enum +{ + LZMA2_STATE_CONTROL, + LZMA2_STATE_UNPACK0, + LZMA2_STATE_UNPACK1, + LZMA2_STATE_PACK0, + LZMA2_STATE_PACK1, + LZMA2_STATE_PROP, + LZMA2_STATE_DATA, + LZMA2_STATE_DATA_CONT, + LZMA2_STATE_FINISHED, + LZMA2_STATE_ERROR +} ELzma2State; + +static SRes Lzma2Dec_GetOldProps(uint8_t prop, uint8_t *props) +{ + uint32_t dicSize; + if (prop > 40) + return SZ_ERROR_UNSUPPORTED; + dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop); + props[0] = (uint8_t)LZMA2_LCLP_MAX; + props[1] = (uint8_t)(dicSize); + props[2] = (uint8_t)(dicSize >> 8); + props[3] = (uint8_t)(dicSize >> 16); + props[4] = (uint8_t)(dicSize >> 24); + return SZ_OK; +} + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) +{ + uint8_t props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc) +{ + uint8_t props[LZMA_PROPS_SIZE]; + RINOK(Lzma2Dec_GetOldProps(prop, props)); + return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc); +} + +void Lzma2Dec_Init(CLzma2Dec *p) +{ + p->state = LZMA2_STATE_CONTROL; + p->needInitDic = true; + p->needInitState = true; + p->needInitProp = true; + LzmaDec_Init(&p->decoder); +} + +static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, uint8_t b) +{ + switch(p->state) + { + case LZMA2_STATE_CONTROL: + p->control = b; + PRF(printf("\n %4X ", p->decoder.dicPos)); + PRF(printf(" %2X", b)); + if (p->control == 0) + return LZMA2_STATE_FINISHED; + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if ((p->control & 0x7F) > 2) + return LZMA2_STATE_ERROR; + p->unpackSize = 0; + } + else + p->unpackSize = (uint32_t)(p->control & 0x1F) << 16; + return LZMA2_STATE_UNPACK0; + + case LZMA2_STATE_UNPACK0: + p->unpackSize |= (uint32_t)b << 8; + return LZMA2_STATE_UNPACK1; + + case LZMA2_STATE_UNPACK1: + p->unpackSize |= (uint32_t)b; + p->unpackSize++; + PRF(printf(" %8d", p->unpackSize)); + return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; + + case LZMA2_STATE_PACK0: + p->packSize = (uint32_t)b << 8; + return LZMA2_STATE_PACK1; + + case LZMA2_STATE_PACK1: + p->packSize |= (uint32_t)b; + p->packSize++; + PRF(printf(" %8d", p->packSize)); + return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: + (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); + + case LZMA2_STATE_PROP: + { + int lc, lp; + if (b >= (9 * 5 * 5)) + return LZMA2_STATE_ERROR; + lc = b % 9; + b /= 9; + p->decoder.prop.pb = b / 5; + lp = b % 5; + if (lc + lp > LZMA2_LCLP_MAX) + return LZMA2_STATE_ERROR; + p->decoder.prop.lc = lc; + p->decoder.prop.lp = lp; + p->needInitProp = false; + return LZMA2_STATE_DATA; + } + } + return LZMA2_STATE_ERROR; +} + +static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const uint8_t *src, size_t size) +{ + memcpy(p->dic + p->dicPos, src, size); + p->dicPos += size; + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size) + p->checkDicSize = p->prop.dicSize; + p->processedPos += (uint32_t)size; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState); + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit, + const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + size_t inSize = *srcLen; + *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->state != LZMA2_STATE_FINISHED) + { + size_t dicPos = p->decoder.dicPos; + if (p->state == LZMA2_STATE_ERROR) + return SZ_ERROR_DATA; + if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + (*srcLen)++; + p->state = Lzma2Dec_UpdateState(p, *src++); + continue; + } + { + size_t destSizeCur = dicLimit - dicPos; + size_t srcSizeCur = inSize - *srcLen; + ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY; + + if (p->unpackSize <= destSizeCur) + { + destSizeCur = (size_t)p->unpackSize; + curFinishMode = LZMA_FINISH_END; + } + + if (LZMA2_IS_UNCOMPRESSED_STATE(p)) + { + if (*srcLen == inSize) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + + if (p->state == LZMA2_STATE_DATA) + { + bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC); + if (initDic) + p->needInitProp = p->needInitState = true; + else if (p->needInitDic) + return SZ_ERROR_DATA; + p->needInitDic = false; + LzmaDec_InitDicAndState(&p->decoder, initDic, false); + } + + if (srcSizeCur > destSizeCur) + srcSizeCur = destSizeCur; + + if (srcSizeCur == 0) + return SZ_ERROR_DATA; + + LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->unpackSize -= (uint32_t)srcSizeCur; + p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT; + } + else + { + size_t outSizeProcessed; + SRes res; + + if (p->state == LZMA2_STATE_DATA) + { + int mode = LZMA2_GET_LZMA_MODE(p); + bool initDic = (mode == 3); + bool initState = (mode > 0); + if ((!initDic && p->needInitDic) || (!initState && p->needInitState)) + return SZ_ERROR_DATA; + + LzmaDec_InitDicAndState(&p->decoder, initDic, initState); + p->needInitDic = false; + p->needInitState = false; + p->state = LZMA2_STATE_DATA_CONT; + } + if (srcSizeCur > p->packSize) + srcSizeCur = (size_t)p->packSize; + + res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status); + + src += srcSizeCur; + *srcLen += srcSizeCur; + p->packSize -= (uint32_t)srcSizeCur; + + outSizeProcessed = p->decoder.dicPos - dicPos; + p->unpackSize -= (uint32_t)outSizeProcessed; + + RINOK(res); + if (*status == LZMA_STATUS_NEEDS_MORE_INPUT) + return res; + + if (srcSizeCur == 0 && outSizeProcessed == 0) + { + if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK || + p->unpackSize != 0 || p->packSize != 0) + return SZ_ERROR_DATA; + p->state = LZMA2_STATE_CONTROL; + } + if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK) + *status = LZMA_STATUS_NOT_FINISHED; + } + } + } + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return SZ_OK; +} + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + size_t outSize = *destLen, inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + size_t srcSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->decoder.dicPos == p->decoder.dicBufSize) + p->decoder.dicPos = 0; + dicPos = p->decoder.dicPos; + if (outSize > p->decoder.dicBufSize - dicPos) + { + outSizeCur = p->decoder.dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = Lzma2Dec_DecodeToDic(p, outSizeCur, src, &srcSizeCur, curFinishMode, status); + src += srcSizeCur; + inSize -= srcSizeCur; + *srcLen += srcSizeCur; + outSizeCur = p->decoder.dicPos - dicPos; + memcpy(dest, p->decoder.dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, + uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzma2Dec decoder; + SRes res; + size_t outSize = *destLen, inSize = *srcLen; + uint8_t props[LZMA_PROPS_SIZE]; + + Lzma2Dec_Construct(&decoder); + + *destLen = *srcLen = 0; + *status = LZMA_STATUS_NOT_SPECIFIED; + decoder.decoder.dic = dest; + decoder.decoder.dicBufSize = outSize; + + RINOK(Lzma2Dec_GetOldProps(prop, props)); + RINOK(LzmaDec_AllocateProbs(&decoder.decoder, props, LZMA_PROPS_SIZE, alloc)); + + *srcLen = inSize; + res = Lzma2Dec_DecodeToDic(&decoder, outSize, src, srcLen, finishMode, status); + *destLen = decoder.decoder.dicPos; + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + LzmaDec_FreeProbs(&decoder.decoder, alloc); + return res; +} diff --git a/deps/7zip/Lzma2Dec.h b/deps/7zip/Lzma2Dec.h index 53797ae049..5ab3706b49 100644 --- a/deps/7zip/Lzma2Dec.h +++ b/deps/7zip/Lzma2Dec.h @@ -1,85 +1,85 @@ -/* Lzma2Dec.h -- LZMA2 Decoder -2009-05-03 : Igor Pavlov : Public domain */ - -#ifndef __LZMA2_DEC_H -#define __LZMA2_DEC_H - -#include -#include "LzmaDec.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------- State Interface ---------- */ - -typedef struct -{ - CLzmaDec decoder; - uint32_t packSize; - uint32_t unpackSize; - int state; - uint8_t control; - bool needInitDic; - bool needInitState; - bool needInitProp; -} CLzma2Dec; - -#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) -#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); -#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); - -SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc); -SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc); -void Lzma2Dec_Init(CLzma2Dec *p); - - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen or dicLimit). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - LZMA_STATUS_NEEDS_MORE_INPUT - SZ_ERROR_DATA - Data error -*/ - -SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit, - const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - -SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, - const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* -finishMode: - It has meaning only if the decoding reaches output limit (*destLen). - LZMA_FINISH_ANY - use smallest number of input bytes - LZMA_FINISH_END - read EndOfStream marker after decoding - -Returns: - SZ_OK - status: - LZMA_STATUS_FINISHED_WITH_MARK - LZMA_STATUS_NOT_FINISHED - SZ_ERROR_DATA - Data error - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, - uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); - -#ifdef __cplusplus -} -#endif - -#endif +/* Lzma2Dec.h -- LZMA2 Decoder +2009-05-03 : Igor Pavlov : Public domain */ + +#ifndef __LZMA2_DEC_H +#define __LZMA2_DEC_H + +#include +#include "LzmaDec.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- State Interface ---------- */ + +typedef struct +{ + CLzmaDec decoder; + uint32_t packSize; + uint32_t unpackSize; + int state; + uint8_t control; + bool needInitDic; + bool needInitState; + bool needInitProp; +} CLzma2Dec; + +#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder) +#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc); +#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc); + +SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc); +SRes Lzma2Dec_Allocate(CLzma2Dec *p, uint8_t prop, ISzAlloc *alloc); +void Lzma2Dec_Init(CLzma2Dec *p); + + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen or dicLimit). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + LZMA_STATUS_NEEDS_MORE_INPUT + SZ_ERROR_DATA - Data error +*/ + +SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, size_t dicLimit, + const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + +SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, uint8_t *dest, size_t *destLen, + const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* +finishMode: + It has meaning only if the decoding reaches output limit (*destLen). + LZMA_FINISH_ANY - use smallest number of input bytes + LZMA_FINISH_END - read EndOfStream marker after decoding + +Returns: + SZ_OK + status: + LZMA_STATUS_FINISHED_WITH_MARK + LZMA_STATUS_NOT_FINISHED + SZ_ERROR_DATA - Data error + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes Lzma2Decode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, + uint8_t prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/LzmaDec.c b/deps/7zip/LzmaDec.c index 4a0a5a5faf..5325053939 100644 --- a/deps/7zip/LzmaDec.c +++ b/deps/7zip/LzmaDec.c @@ -1,1040 +1,1040 @@ -/* LzmaDec.c -- LZMA Decoder - 2009-09-20 : Igor Pavlov : Public domain */ -#include -#include -#include - -#include "LzmaDec.h" - -#define kNumTopBits 24 -#define kTopValue ((uint32_t)1 << kNumTopBits) - -#define kNumBitModelTotalBits 11 -#define kBitModelTotal (1 << kNumBitModelTotalBits) -#define kNumMoveBits 5 - -#define RC_INIT_SIZE 5 - -#define LZMADEC_NORMALIZE if (range < kTopValue) { range <<= 8; codes = (codes << 8) | (*buf++); } - -#define LZMADEC_IF_BIT_0(prob) ttt = *(prob); LZMADEC_NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (codes < bound) -#define UPDATE_0(p) range = bound; *(p) = (uint16_t)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); -#define LZMADEC_UPDATE_1(p) range -= bound; codes -= bound; *(p) = (uint16_t)(ttt - (ttt >> kNumMoveBits)); -#define GET_BIT2(p, i, A0, A1) LZMADEC_IF_BIT_0(p) \ -{ UPDATE_0(p); i = (i + i); A0; } else \ -{ LZMADEC_UPDATE_1(p); i = (i + i) + 1; A1; } -#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) - -#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } -#define TREE_DECODE(probs, limit, i) \ -{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } - -/* #define _LZMA_SIZE_OPT */ - -#ifdef _LZMA_SIZE_OPT -#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) -#else -#define TREE_6_DECODE(probs, i) \ -{ i = 1; \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - TREE_GET_BIT(probs, i); \ - i -= 0x40; } -#endif - -#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; codes = (codes << 8) | (*buf++); } - -#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (codes < bound) -#define UPDATE_0_CHECK range = bound; -#define UPDATE_1_CHECK range -= bound; codes -= bound; -#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ -{ UPDATE_0_CHECK; i = (i + i); A0; } else \ -{ UPDATE_1_CHECK; i = (i + i) + 1; A1; } -#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) -#define TREE_DECODE_CHECK(probs, limit, i) \ -{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } - - -#define kNumPosBitsMax 4 -#define kNumPosStatesMax (1 << kNumPosBitsMax) - -#define kLenNumLowBits 3 -#define kLenNumLowSymbols (1 << kLenNumLowBits) -#define kLenNumMidBits 3 -#define kLenNumMidSymbols (1 << kLenNumMidBits) -#define kLenNumHighBits 8 -#define kLenNumHighSymbols (1 << kLenNumHighBits) - -#define LenChoice 0 -#define LenChoice2 (LenChoice + 1) -#define LenLow (LenChoice2 + 1) -#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) -#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) -#define kNumLenProbs (LenHigh + kLenNumHighSymbols) - - -#define kNumStates 12 -#define kNumLitStates 7 - -#define kStartPosModelIndex 4 -#define kEndPosModelIndex 14 -#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) - -#define kNumPosSlotBits 6 -#define kNumLenToPosStates 4 - -#define kNumAlignBits 4 -#define kAlignTableSize (1 << kNumAlignBits) - -#define kMatchMinLen 2 -#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) - -#define IsMatch 0 -#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) -#define IsRepG0 (IsRep + kNumStates) -#define IsRepG1 (IsRepG0 + kNumStates) -#define IsRepG2 (IsRepG1 + kNumStates) -#define IsRep0Long (IsRepG2 + kNumStates) -#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) -#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) -#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) -#define LenCoder (Align + kAlignTableSize) -#define RepLenCoder (LenCoder + kNumLenProbs) -#define Literal (RepLenCoder + kNumLenProbs) - -#define LZMA_BASE_SIZE 1846 -#define LZMA_LIT_SIZE 768 - -#define LzmaProps_GetNumProbs(p) ((uint32_t)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) - -#if Literal != LZMA_BASE_SIZE -StopCompilingDueBUG -#endif - -#define LZMA_DIC_MIN (1 << 12) - -/* First LZMA-symbol is always decoded. - And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization - Out: - Result: - SZ_OK - OK - SZ_ERROR_DATA - Error - p->remainLen: - < kMatchSpecLenStart : normal remain - = kMatchSpecLenStart : finished - = kMatchSpecLenStart + 1 : Flush marker - = kMatchSpecLenStart + 2 : State Init Marker - */ - -static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, size_t limit, const uint8_t *bufLimit) -{ - uint16_t *probs = p->probs; - - unsigned state = p->state; - uint32_t rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; - unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; - unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; - unsigned lc = p->prop.lc; - - uint8_t *dic = p->dic; - size_t dicBufSize = p->dicBufSize; - size_t dicPos = p->dicPos; - - uint32_t processedPos = p->processedPos; - uint32_t checkDicSize = p->checkDicSize; - unsigned len = 0; - - const uint8_t *buf = p->buf; - uint32_t range = p->range; - uint32_t codes = p->code; - - do - { - uint16_t *prob; - uint32_t bound; - unsigned ttt; - unsigned posState = processedPos & pbMask; - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - unsigned symbol; - UPDATE_0(prob); - prob = probs + Literal; - if (checkDicSize != 0 || processedPos != 0) - prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + - (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); - - if (state < kNumLitStates) - { - state -= (state < 4) ? state : 3; - symbol = 1; - do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchuint8_t = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - unsigned offs = 0x100; - state -= (state < 10) ? 3 : 6; - symbol = 1; - do - { - unsigned bit; - uint16_t *probLit; - matchuint8_t <<= 1; - bit = (matchuint8_t & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - dic[dicPos++] = (uint8_t)symbol; - processedPos++; - continue; - } - else - { - LZMADEC_UPDATE_1(prob); - prob = probs + IsRep + state; - - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - UPDATE_0(prob); - state += kNumStates; - prob = probs + LenCoder; - } - else - { - LZMADEC_UPDATE_1(prob); - if (checkDicSize == 0 && processedPos == 0) - return SZ_ERROR_DATA; - prob = probs + IsRepG0 + state; - - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - UPDATE_0(prob); - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - UPDATE_0(prob); - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - processedPos++; - state = state < kNumLitStates ? 9 : 11; - continue; - } - LZMADEC_UPDATE_1(prob); - } - else - { - uint32_t distance; - LZMADEC_UPDATE_1(prob); - prob = probs + IsRepG1 + state; - - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - UPDATE_0(prob); - distance = rep1; - } - else - { - LZMADEC_UPDATE_1(prob); - prob = probs + IsRepG2 + state; - - ttt = *(prob); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - - if (codes < bound) - { - UPDATE_0(prob); - distance = rep2; - } - else - { - LZMADEC_UPDATE_1(prob); - distance = rep3; - rep3 = rep2; - } - rep2 = rep1; - } - rep1 = rep0; - rep0 = distance; - } - state = state < kNumLitStates ? 8 : 11; - prob = probs + RepLenCoder; - } - { - unsigned _limit, offset; - uint16_t *probLen = prob + LenChoice; - - ttt = *(probLen); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - if (codes < bound) - { - UPDATE_0(probLen); - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - _limit = (1 << kLenNumLowBits); - } - else - { - LZMADEC_UPDATE_1(probLen); - probLen = prob + LenChoice2; - - ttt = *(probLen); - LZMADEC_NORMALIZE; - bound = (range >> kNumBitModelTotalBits) * ttt; - if (codes < bound) - { - UPDATE_0(probLen); - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - _limit = (1 << kLenNumMidBits); - } - else - { - LZMADEC_UPDATE_1(probLen); - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - _limit = (1 << kLenNumHighBits); - } - } - TREE_DECODE(probLen, _limit, len); - len += offset; - } - - if (state >= kNumStates) - { - uint32_t distance; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); - TREE_6_DECODE(prob, distance); - if (distance >= kStartPosModelIndex) - { - unsigned posSlot = (unsigned)distance; - int numDirectBits = (int)(((distance >> 1) - 1)); - distance = (2 | (distance & 1)); - if (posSlot < kEndPosModelIndex) - { - distance <<= numDirectBits; - prob = probs + SpecPos + distance - posSlot - 1; - { - uint32_t mask = 1; - unsigned i = 1; - do - { - GET_BIT2(prob + i, i, ; , distance |= mask); - mask <<= 1; - } - while (--numDirectBits != 0); - } - } - else - { - numDirectBits -= kNumAlignBits; - do - { - LZMADEC_NORMALIZE - range >>= 1; - - { - uint32_t t; - codes -= range; - t = (0 - ((uint32_t)codes >> 31)); /* (uint32_t)((Int32)codes >> 31) */ - distance = (distance << 1) + (t + 1); - codes += range & t; - } - /* - distance <<= 1; - if (codes >= range) - { - codes -= range; - distance |= 1; - } - */ - } - while (--numDirectBits != 0); - prob = probs + Align; - distance <<= kNumAlignBits; - { - unsigned i = 1; - GET_BIT2(prob + i, i, ; , distance |= 1); - GET_BIT2(prob + i, i, ; , distance |= 2); - GET_BIT2(prob + i, i, ; , distance |= 4); - GET_BIT2(prob + i, i, ; , distance |= 8); - } - if (distance == (uint32_t)0xFFFFFFFF) - { - len += kMatchSpecLenStart; - state -= kNumStates; - break; - } - } - } - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance + 1; - if (checkDicSize == 0) - { - if (distance >= processedPos) - return SZ_ERROR_DATA; - } - else if (distance >= checkDicSize) - return SZ_ERROR_DATA; - state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; - } - - len += kMatchMinLen; - - if (limit == dicPos) - return SZ_ERROR_DATA; - { - size_t rem = limit - dicPos; - unsigned curLen = ((rem < len) ? (unsigned)rem : len); - size_t pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); - - processedPos += curLen; - - len -= curLen; - if (pos + curLen <= dicBufSize) - { - uint8_t *dest = dic + dicPos; - ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; - const uint8_t *lim = dest + curLen; - dicPos += curLen; - do - *(dest) = (uint8_t)*(dest + src); - while (++dest != lim); - } - else - { - do - { - dic[dicPos++] = dic[pos]; - if (++pos == dicBufSize) - pos = 0; - } - while (--curLen != 0); - } - } - } - }while (dicPos < limit && buf < bufLimit); - - LZMADEC_NORMALIZE; - - p->buf = buf; - p->range = range; - p->code = codes; - p->remainLen = len; - p->dicPos = dicPos; - p->processedPos = processedPos; - p->reps[0] = rep0; - p->reps[1] = rep1; - p->reps[2] = rep2; - p->reps[3] = rep3; - p->state = state; - - return SZ_OK; -} - -static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, size_t limit) -{ - if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) - { - uint8_t *dic = p->dic; - size_t dicPos = p->dicPos; - size_t dicBufSize = p->dicBufSize; - unsigned len = p->remainLen; - uint32_t rep0 = p->reps[0]; - if (limit - dicPos < len) - len = (unsigned)(limit - dicPos); - - if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) - p->checkDicSize = p->prop.dicSize; - - p->processedPos += len; - p->remainLen -= len; - while (len-- != 0) - { - dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; - dicPos++; - } - p->dicPos = dicPos; - } -} - -static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, size_t limit, const uint8_t *bufLimit) -{ - do - { - size_t limit2 = limit; - if (p->checkDicSize == 0) - { - uint32_t rem = p->prop.dicSize - p->processedPos; - if (limit - p->dicPos > rem) - limit2 = p->dicPos + rem; - } - RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); - if (p->processedPos >= p->prop.dicSize) - p->checkDicSize = p->prop.dicSize; - LzmaDec_WriteRem(p, limit); - } - while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); - - if (p->remainLen > kMatchSpecLenStart) - { - p->remainLen = kMatchSpecLenStart; - } - return 0; -} - -typedef enum -{ - DUMMY_ERROR, /* unexpected end of input stream */ - DUMMY_LIT, - DUMMY_MATCH, - DUMMY_REP -} ELzmaDummy; - -static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, size_t inSize) -{ - uint32_t range = p->range; - uint32_t codes = p->code; - const uint8_t *bufLimit = buf + inSize; - uint16_t *probs = p->probs; - unsigned state = p->state; - ELzmaDummy res; - - { - uint16_t *prob; - uint32_t bound; - unsigned ttt; - unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); - - prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK - - /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ - - prob = probs + Literal; - if (p->checkDicSize != 0 || p->processedPos != 0) - prob += (LZMA_LIT_SIZE * - ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + - (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); - - if (state < kNumLitStates) - { - unsigned symbol = 1; - do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); - } - else - { - unsigned matchuint8_t = p->dic[p->dicPos - p->reps[0] + - ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; - unsigned offs = 0x100; - unsigned symbol = 1; - do - { - unsigned bit; - uint16_t *probLit; - matchuint8_t <<= 1; - bit = (matchuint8_t & offs); - probLit = prob + offs + bit + symbol; - GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) - } - while (symbol < 0x100); - } - res = DUMMY_LIT; - } - else - { - unsigned len; - UPDATE_1_CHECK; - - prob = probs + IsRep + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - state = 0; - prob = probs + LenCoder; - res = DUMMY_MATCH; - } - else - { - UPDATE_1_CHECK; - res = DUMMY_REP; - prob = probs + IsRepG0 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - NORMALIZE_CHECK; - return DUMMY_REP; - } - else - { - UPDATE_1_CHECK; - } - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG1 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - prob = probs + IsRepG2 + state; - IF_BIT_0_CHECK(prob) - { - UPDATE_0_CHECK; - } - else - { - UPDATE_1_CHECK; - } - } - } - state = kNumStates; - prob = probs + RepLenCoder; - } - { - unsigned limit, offset; - uint16_t *probLen = prob + LenChoice; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenLow + (posState << kLenNumLowBits); - offset = 0; - limit = 1 << kLenNumLowBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenChoice2; - IF_BIT_0_CHECK(probLen) - { - UPDATE_0_CHECK; - probLen = prob + LenMid + (posState << kLenNumMidBits); - offset = kLenNumLowSymbols; - limit = 1 << kLenNumMidBits; - } - else - { - UPDATE_1_CHECK; - probLen = prob + LenHigh; - offset = kLenNumLowSymbols + kLenNumMidSymbols; - limit = 1 << kLenNumHighBits; - } - } - TREE_DECODE_CHECK(probLen, limit, len); - len += offset; - } - - if (state < 4) - { - unsigned posSlot; - prob = probs + PosSlot + - ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << - kNumPosSlotBits); - TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); - if (posSlot >= kStartPosModelIndex) - { - int numDirectBits = ((posSlot >> 1) - 1); - - /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ - - if (posSlot < kEndPosModelIndex) - { - prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; - } - else - { - numDirectBits -= kNumAlignBits; - do - { - NORMALIZE_CHECK - range >>= 1; - codes -= range & (((codes - range) >> 31) - 1); - /* if (codes >= range) codes -= range; */ - } - while (--numDirectBits != 0); - prob = probs + Align; - numDirectBits = kNumAlignBits; - } - { - unsigned i = 1; - do - { - GET_BIT_CHECK(prob + i, i); - } - while (--numDirectBits != 0); - } - } - } - } - } - NORMALIZE_CHECK; - return res; -} - - -static void LzmaDec_InitRc(CLzmaDec *p, const uint8_t *data) -{ - p->code = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]); - p->range = 0xFFFFFFFF; - p->needFlush = 0; -} - -void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState); - -void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState) -{ - p->needFlush = 1; - p->remainLen = 0; - p->tempBufSize = 0; - - if (initDic) - { - p->processedPos = 0; - p->checkDicSize = 0; - p->needInitState = 1; - } - if (initState) - p->needInitState = 1; -} - -void LzmaDec_Init(CLzmaDec *p) -{ - p->dicPos = 0; - LzmaDec_InitDicAndState(p, true, true); -} - -static void LzmaDec_InitStateReal(CLzmaDec *p) -{ - uint32_t numProbs = Literal + ((uint32_t)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); - uint32_t i; - uint16_t *probs = p->probs; - for (i = 0; i < numProbs; i++) - probs[i] = kBitModelTotal >> 1; - p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; - p->state = 0; - p->needInitState = 0; -} - -SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, const uint8_t *src, size_t *srcLen, - ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - size_t inSize = *srcLen; - (*srcLen) = 0; - LzmaDec_WriteRem(p, dicLimit); - - *status = LZMA_STATUS_NOT_SPECIFIED; - - while (p->remainLen != kMatchSpecLenStart) - { - int checkEndMarkNow; - - if (p->needFlush != 0) - { - for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) - p->tempBuf[p->tempBufSize++] = *src++; - if (p->tempBufSize < RC_INIT_SIZE) - { - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (p->tempBuf[0] != 0) - return SZ_ERROR_DATA; - - LzmaDec_InitRc(p, p->tempBuf); - p->tempBufSize = 0; - } - - checkEndMarkNow = 0; - if (p->dicPos >= dicLimit) - { - if (p->remainLen == 0 && p->code == 0) - { - *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; - return SZ_OK; - } - if (finishMode == LZMA_FINISH_ANY) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_OK; - } - if (p->remainLen != 0) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - checkEndMarkNow = 1; - } - - if (p->needInitState) - LzmaDec_InitStateReal(p); - - if (p->tempBufSize == 0) - { - size_t processed; - const uint8_t *bufLimit; - if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, src, inSize); - if (dummyRes == DUMMY_ERROR) - { - memcpy(p->tempBuf, src, inSize); - p->tempBufSize = (unsigned)inSize; - (*srcLen) += inSize; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - bufLimit = src; - } - else - bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; - p->buf = src; - if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) - return SZ_ERROR_DATA; - processed = (size_t)(p->buf - src); - (*srcLen) += processed; - src += processed; - inSize -= processed; - } - else - { - unsigned rem = p->tempBufSize, lookAhead = 0; - while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) - p->tempBuf[rem++] = src[lookAhead++]; - p->tempBufSize = rem; - if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) - { - int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); - if (dummyRes == DUMMY_ERROR) - { - (*srcLen) += lookAhead; - *status = LZMA_STATUS_NEEDS_MORE_INPUT; - return SZ_OK; - } - if (checkEndMarkNow && dummyRes != DUMMY_MATCH) - { - *status = LZMA_STATUS_NOT_FINISHED; - return SZ_ERROR_DATA; - } - } - p->buf = p->tempBuf; - if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) - return SZ_ERROR_DATA; - lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); - (*srcLen) += lookAhead; - src += lookAhead; - inSize -= lookAhead; - p->tempBufSize = 0; - } - } - if (p->code == 0) - *status = LZMA_STATUS_FINISHED_WITH_MARK; - return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; -} - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) -{ - size_t outSize = *destLen; - size_t inSize = *srcLen; - *srcLen = *destLen = 0; - for (;;) - { - size_t inSizeCur = inSize, outSizeCur, dicPos; - ELzmaFinishMode curFinishMode; - SRes res; - if (p->dicPos == p->dicBufSize) - p->dicPos = 0; - dicPos = p->dicPos; - if (outSize > p->dicBufSize - dicPos) - { - outSizeCur = p->dicBufSize; - curFinishMode = LZMA_FINISH_ANY; - } - else - { - outSizeCur = dicPos + outSize; - curFinishMode = finishMode; - } - - res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); - src += inSizeCur; - inSize -= inSizeCur; - *srcLen += inSizeCur; - outSizeCur = p->dicPos - dicPos; - memcpy(dest, p->dic + dicPos, outSizeCur); - dest += outSizeCur; - outSize -= outSizeCur; - *destLen += outSizeCur; - if (res != 0) - return res; - if (outSizeCur == 0 || outSize == 0) - return SZ_OK; - } -} - -void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->probs); - p->probs = 0; -} - -static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) -{ - alloc->Free(alloc, p->dic); - p->dic = 0; -} - -void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) -{ - LzmaDec_FreeProbs(p, alloc); - LzmaDec_FreeDict(p, alloc); -} - -SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size) -{ - uint32_t dicSize; - uint8_t d; - - if (size < LZMA_PROPS_SIZE) - return SZ_ERROR_UNSUPPORTED; - else - dicSize = data[1] | ((uint32_t)data[2] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[4] << 24); - - if (dicSize < LZMA_DIC_MIN) - dicSize = LZMA_DIC_MIN; - p->dicSize = dicSize; - - d = data[0]; - if (d >= (9 * 5 * 5)) - return SZ_ERROR_UNSUPPORTED; - - p->lc = d % 9; - d /= 9; - p->pb = d / 5; - p->lp = d % 5; - - return SZ_OK; -} - -static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) -{ - uint32_t numProbs = LzmaProps_GetNumProbs(propNew); - if (p->probs == 0 || numProbs != p->numProbs) - { - LzmaDec_FreeProbs(p, alloc); - p->probs = (uint16_t *)alloc->Alloc(alloc, numProbs * sizeof(uint16_t)); - p->numProbs = numProbs; - if (p->probs == 0) - return SZ_ERROR_MEM; - } - return SZ_OK; -} - -SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDec_Allocate(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) -{ - CLzmaProps propNew; - size_t dicBufSize; - RINOK(LzmaProps_Decode(&propNew, props, propsSize)); - RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); - dicBufSize = propNew.dicSize; - if (p->dic == 0 || dicBufSize != p->dicBufSize) - { - LzmaDec_FreeDict(p, alloc); - p->dic = (uint8_t *)alloc->Alloc(alloc, dicBufSize); - if (p->dic == 0) - { - LzmaDec_FreeProbs(p, alloc); - return SZ_ERROR_MEM; - } - } - p->dicBufSize = dicBufSize; - p->prop = propNew; - return SZ_OK; -} - -SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, - const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc) -{ - CLzmaDec p; - SRes res; - size_t inSize = *srcLen; - size_t outSize = *destLen; - *srcLen = *destLen = 0; - if (inSize < RC_INIT_SIZE) - return SZ_ERROR_INPUT_EOF; - - LzmaDec_Construct(&p); - res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); - if (res != 0) - return res; - p.dic = dest; - p.dicBufSize = outSize; - - LzmaDec_Init(&p); - - *srcLen = inSize; - res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); - - if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) - res = SZ_ERROR_INPUT_EOF; - - (*destLen) = p.dicPos; - LzmaDec_FreeProbs(&p, alloc); - return res; -} +/* LzmaDec.c -- LZMA Decoder + 2009-09-20 : Igor Pavlov : Public domain */ +#include +#include +#include + +#include "LzmaDec.h" + +#define kNumTopBits 24 +#define kTopValue ((uint32_t)1 << kNumTopBits) + +#define kNumBitModelTotalBits 11 +#define kBitModelTotal (1 << kNumBitModelTotalBits) +#define kNumMoveBits 5 + +#define RC_INIT_SIZE 5 + +#define LZMADEC_NORMALIZE if (range < kTopValue) { range <<= 8; codes = (codes << 8) | (*buf++); } + +#define LZMADEC_IF_BIT_0(prob) ttt = *(prob); LZMADEC_NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (codes < bound) +#define UPDATE_0(p) range = bound; *(p) = (uint16_t)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits)); +#define LZMADEC_UPDATE_1(p) range -= bound; codes -= bound; *(p) = (uint16_t)(ttt - (ttt >> kNumMoveBits)); +#define GET_BIT2(p, i, A0, A1) LZMADEC_IF_BIT_0(p) \ +{ UPDATE_0(p); i = (i + i); A0; } else \ +{ LZMADEC_UPDATE_1(p); i = (i + i) + 1; A1; } +#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;) + +#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); } +#define TREE_DECODE(probs, limit, i) \ +{ i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; } + +/* #define _LZMA_SIZE_OPT */ + +#ifdef _LZMA_SIZE_OPT +#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i) +#else +#define TREE_6_DECODE(probs, i) \ +{ i = 1; \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + TREE_GET_BIT(probs, i); \ + i -= 0x40; } +#endif + +#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; codes = (codes << 8) | (*buf++); } + +#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (codes < bound) +#define UPDATE_0_CHECK range = bound; +#define UPDATE_1_CHECK range -= bound; codes -= bound; +#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \ +{ UPDATE_0_CHECK; i = (i + i); A0; } else \ +{ UPDATE_1_CHECK; i = (i + i) + 1; A1; } +#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;) +#define TREE_DECODE_CHECK(probs, limit, i) \ +{ i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; } + + +#define kNumPosBitsMax 4 +#define kNumPosStatesMax (1 << kNumPosBitsMax) + +#define kLenNumLowBits 3 +#define kLenNumLowSymbols (1 << kLenNumLowBits) +#define kLenNumMidBits 3 +#define kLenNumMidSymbols (1 << kLenNumMidBits) +#define kLenNumHighBits 8 +#define kLenNumHighSymbols (1 << kLenNumHighBits) + +#define LenChoice 0 +#define LenChoice2 (LenChoice + 1) +#define LenLow (LenChoice2 + 1) +#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits)) +#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits)) +#define kNumLenProbs (LenHigh + kLenNumHighSymbols) + + +#define kNumStates 12 +#define kNumLitStates 7 + +#define kStartPosModelIndex 4 +#define kEndPosModelIndex 14 +#define kNumFullDistances (1 << (kEndPosModelIndex >> 1)) + +#define kNumPosSlotBits 6 +#define kNumLenToPosStates 4 + +#define kNumAlignBits 4 +#define kAlignTableSize (1 << kNumAlignBits) + +#define kMatchMinLen 2 +#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols) + +#define IsMatch 0 +#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax)) +#define IsRepG0 (IsRep + kNumStates) +#define IsRepG1 (IsRepG0 + kNumStates) +#define IsRepG2 (IsRepG1 + kNumStates) +#define IsRep0Long (IsRepG2 + kNumStates) +#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax)) +#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits)) +#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex) +#define LenCoder (Align + kAlignTableSize) +#define RepLenCoder (LenCoder + kNumLenProbs) +#define Literal (RepLenCoder + kNumLenProbs) + +#define LZMA_BASE_SIZE 1846 +#define LZMA_LIT_SIZE 768 + +#define LzmaProps_GetNumProbs(p) ((uint32_t)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp))) + +#if Literal != LZMA_BASE_SIZE +StopCompilingDueBUG +#endif + +#define LZMA_DIC_MIN (1 << 12) + +/* First LZMA-symbol is always decoded. + And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization + Out: + Result: + SZ_OK - OK + SZ_ERROR_DATA - Error + p->remainLen: + < kMatchSpecLenStart : normal remain + = kMatchSpecLenStart : finished + = kMatchSpecLenStart + 1 : Flush marker + = kMatchSpecLenStart + 2 : State Init Marker + */ + +static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, size_t limit, const uint8_t *bufLimit) +{ + uint16_t *probs = p->probs; + + unsigned state = p->state; + uint32_t rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3]; + unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1; + unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1; + unsigned lc = p->prop.lc; + + uint8_t *dic = p->dic; + size_t dicBufSize = p->dicBufSize; + size_t dicPos = p->dicPos; + + uint32_t processedPos = p->processedPos; + uint32_t checkDicSize = p->checkDicSize; + unsigned len = 0; + + const uint8_t *buf = p->buf; + uint32_t range = p->range; + uint32_t codes = p->code; + + do + { + uint16_t *prob; + uint32_t bound; + unsigned ttt; + unsigned posState = processedPos & pbMask; + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + unsigned symbol; + UPDATE_0(prob); + prob = probs + Literal; + if (checkDicSize != 0 || processedPos != 0) + prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) + + (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc)))); + + if (state < kNumLitStates) + { + state -= (state < 4) ? state : 3; + symbol = 1; + do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchuint8_t = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + unsigned offs = 0x100; + state -= (state < 10) ? 3 : 6; + symbol = 1; + do + { + unsigned bit; + uint16_t *probLit; + matchuint8_t <<= 1; + bit = (matchuint8_t & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + dic[dicPos++] = (uint8_t)symbol; + processedPos++; + continue; + } + else + { + LZMADEC_UPDATE_1(prob); + prob = probs + IsRep + state; + + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + UPDATE_0(prob); + state += kNumStates; + prob = probs + LenCoder; + } + else + { + LZMADEC_UPDATE_1(prob); + if (checkDicSize == 0 && processedPos == 0) + return SZ_ERROR_DATA; + prob = probs + IsRepG0 + state; + + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + UPDATE_0(prob); + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + UPDATE_0(prob); + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + processedPos++; + state = state < kNumLitStates ? 9 : 11; + continue; + } + LZMADEC_UPDATE_1(prob); + } + else + { + uint32_t distance; + LZMADEC_UPDATE_1(prob); + prob = probs + IsRepG1 + state; + + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + UPDATE_0(prob); + distance = rep1; + } + else + { + LZMADEC_UPDATE_1(prob); + prob = probs + IsRepG2 + state; + + ttt = *(prob); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + + if (codes < bound) + { + UPDATE_0(prob); + distance = rep2; + } + else + { + LZMADEC_UPDATE_1(prob); + distance = rep3; + rep3 = rep2; + } + rep2 = rep1; + } + rep1 = rep0; + rep0 = distance; + } + state = state < kNumLitStates ? 8 : 11; + prob = probs + RepLenCoder; + } + { + unsigned _limit, offset; + uint16_t *probLen = prob + LenChoice; + + ttt = *(probLen); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + if (codes < bound) + { + UPDATE_0(probLen); + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + _limit = (1 << kLenNumLowBits); + } + else + { + LZMADEC_UPDATE_1(probLen); + probLen = prob + LenChoice2; + + ttt = *(probLen); + LZMADEC_NORMALIZE; + bound = (range >> kNumBitModelTotalBits) * ttt; + if (codes < bound) + { + UPDATE_0(probLen); + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + _limit = (1 << kLenNumMidBits); + } + else + { + LZMADEC_UPDATE_1(probLen); + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + _limit = (1 << kLenNumHighBits); + } + } + TREE_DECODE(probLen, _limit, len); + len += offset; + } + + if (state >= kNumStates) + { + uint32_t distance; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits); + TREE_6_DECODE(prob, distance); + if (distance >= kStartPosModelIndex) + { + unsigned posSlot = (unsigned)distance; + int numDirectBits = (int)(((distance >> 1) - 1)); + distance = (2 | (distance & 1)); + if (posSlot < kEndPosModelIndex) + { + distance <<= numDirectBits; + prob = probs + SpecPos + distance - posSlot - 1; + { + uint32_t mask = 1; + unsigned i = 1; + do + { + GET_BIT2(prob + i, i, ; , distance |= mask); + mask <<= 1; + } + while (--numDirectBits != 0); + } + } + else + { + numDirectBits -= kNumAlignBits; + do + { + LZMADEC_NORMALIZE + range >>= 1; + + { + uint32_t t; + codes -= range; + t = (0 - ((uint32_t)codes >> 31)); /* (uint32_t)((Int32)codes >> 31) */ + distance = (distance << 1) + (t + 1); + codes += range & t; + } + /* + distance <<= 1; + if (codes >= range) + { + codes -= range; + distance |= 1; + } + */ + } + while (--numDirectBits != 0); + prob = probs + Align; + distance <<= kNumAlignBits; + { + unsigned i = 1; + GET_BIT2(prob + i, i, ; , distance |= 1); + GET_BIT2(prob + i, i, ; , distance |= 2); + GET_BIT2(prob + i, i, ; , distance |= 4); + GET_BIT2(prob + i, i, ; , distance |= 8); + } + if (distance == (uint32_t)0xFFFFFFFF) + { + len += kMatchSpecLenStart; + state -= kNumStates; + break; + } + } + } + rep3 = rep2; + rep2 = rep1; + rep1 = rep0; + rep0 = distance + 1; + if (checkDicSize == 0) + { + if (distance >= processedPos) + return SZ_ERROR_DATA; + } + else if (distance >= checkDicSize) + return SZ_ERROR_DATA; + state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3; + } + + len += kMatchMinLen; + + if (limit == dicPos) + return SZ_ERROR_DATA; + { + size_t rem = limit - dicPos; + unsigned curLen = ((rem < len) ? (unsigned)rem : len); + size_t pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0); + + processedPos += curLen; + + len -= curLen; + if (pos + curLen <= dicBufSize) + { + uint8_t *dest = dic + dicPos; + ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos; + const uint8_t *lim = dest + curLen; + dicPos += curLen; + do + *(dest) = (uint8_t)*(dest + src); + while (++dest != lim); + } + else + { + do + { + dic[dicPos++] = dic[pos]; + if (++pos == dicBufSize) + pos = 0; + } + while (--curLen != 0); + } + } + } + }while (dicPos < limit && buf < bufLimit); + + LZMADEC_NORMALIZE; + + p->buf = buf; + p->range = range; + p->code = codes; + p->remainLen = len; + p->dicPos = dicPos; + p->processedPos = processedPos; + p->reps[0] = rep0; + p->reps[1] = rep1; + p->reps[2] = rep2; + p->reps[3] = rep3; + p->state = state; + + return SZ_OK; +} + +static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, size_t limit) +{ + if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart) + { + uint8_t *dic = p->dic; + size_t dicPos = p->dicPos; + size_t dicBufSize = p->dicBufSize; + unsigned len = p->remainLen; + uint32_t rep0 = p->reps[0]; + if (limit - dicPos < len) + len = (unsigned)(limit - dicPos); + + if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len) + p->checkDicSize = p->prop.dicSize; + + p->processedPos += len; + p->remainLen -= len; + while (len-- != 0) + { + dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)]; + dicPos++; + } + p->dicPos = dicPos; + } +} + +static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, size_t limit, const uint8_t *bufLimit) +{ + do + { + size_t limit2 = limit; + if (p->checkDicSize == 0) + { + uint32_t rem = p->prop.dicSize - p->processedPos; + if (limit - p->dicPos > rem) + limit2 = p->dicPos + rem; + } + RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit)); + if (p->processedPos >= p->prop.dicSize) + p->checkDicSize = p->prop.dicSize; + LzmaDec_WriteRem(p, limit); + } + while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart); + + if (p->remainLen > kMatchSpecLenStart) + { + p->remainLen = kMatchSpecLenStart; + } + return 0; +} + +typedef enum +{ + DUMMY_ERROR, /* unexpected end of input stream */ + DUMMY_LIT, + DUMMY_MATCH, + DUMMY_REP +} ELzmaDummy; + +static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const uint8_t *buf, size_t inSize) +{ + uint32_t range = p->range; + uint32_t codes = p->code; + const uint8_t *bufLimit = buf + inSize; + uint16_t *probs = p->probs; + unsigned state = p->state; + ELzmaDummy res; + + { + uint16_t *prob; + uint32_t bound; + unsigned ttt; + unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1); + + prob = probs + IsMatch + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK + + /* if (bufLimit - buf >= 7) return DUMMY_LIT; */ + + prob = probs + Literal; + if (p->checkDicSize != 0 || p->processedPos != 0) + prob += (LZMA_LIT_SIZE * + ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) + + (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc)))); + + if (state < kNumLitStates) + { + unsigned symbol = 1; + do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100); + } + else + { + unsigned matchuint8_t = p->dic[p->dicPos - p->reps[0] + + ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)]; + unsigned offs = 0x100; + unsigned symbol = 1; + do + { + unsigned bit; + uint16_t *probLit; + matchuint8_t <<= 1; + bit = (matchuint8_t & offs); + probLit = prob + offs + bit + symbol; + GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit) + } + while (symbol < 0x100); + } + res = DUMMY_LIT; + } + else + { + unsigned len; + UPDATE_1_CHECK; + + prob = probs + IsRep + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + state = 0; + prob = probs + LenCoder; + res = DUMMY_MATCH; + } + else + { + UPDATE_1_CHECK; + res = DUMMY_REP; + prob = probs + IsRepG0 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + NORMALIZE_CHECK; + return DUMMY_REP; + } + else + { + UPDATE_1_CHECK; + } + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG1 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + prob = probs + IsRepG2 + state; + IF_BIT_0_CHECK(prob) + { + UPDATE_0_CHECK; + } + else + { + UPDATE_1_CHECK; + } + } + } + state = kNumStates; + prob = probs + RepLenCoder; + } + { + unsigned limit, offset; + uint16_t *probLen = prob + LenChoice; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenLow + (posState << kLenNumLowBits); + offset = 0; + limit = 1 << kLenNumLowBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenChoice2; + IF_BIT_0_CHECK(probLen) + { + UPDATE_0_CHECK; + probLen = prob + LenMid + (posState << kLenNumMidBits); + offset = kLenNumLowSymbols; + limit = 1 << kLenNumMidBits; + } + else + { + UPDATE_1_CHECK; + probLen = prob + LenHigh; + offset = kLenNumLowSymbols + kLenNumMidSymbols; + limit = 1 << kLenNumHighBits; + } + } + TREE_DECODE_CHECK(probLen, limit, len); + len += offset; + } + + if (state < 4) + { + unsigned posSlot; + prob = probs + PosSlot + + ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << + kNumPosSlotBits); + TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot); + if (posSlot >= kStartPosModelIndex) + { + int numDirectBits = ((posSlot >> 1) - 1); + + /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */ + + if (posSlot < kEndPosModelIndex) + { + prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1; + } + else + { + numDirectBits -= kNumAlignBits; + do + { + NORMALIZE_CHECK + range >>= 1; + codes -= range & (((codes - range) >> 31) - 1); + /* if (codes >= range) codes -= range; */ + } + while (--numDirectBits != 0); + prob = probs + Align; + numDirectBits = kNumAlignBits; + } + { + unsigned i = 1; + do + { + GET_BIT_CHECK(prob + i, i); + } + while (--numDirectBits != 0); + } + } + } + } + } + NORMALIZE_CHECK; + return res; +} + + +static void LzmaDec_InitRc(CLzmaDec *p, const uint8_t *data) +{ + p->code = ((uint32_t)data[1] << 24) | ((uint32_t)data[2] << 16) | ((uint32_t)data[3] << 8) | ((uint32_t)data[4]); + p->range = 0xFFFFFFFF; + p->needFlush = 0; +} + +void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState); + +void LzmaDec_InitDicAndState(CLzmaDec *p, bool initDic, bool initState) +{ + p->needFlush = 1; + p->remainLen = 0; + p->tempBufSize = 0; + + if (initDic) + { + p->processedPos = 0; + p->checkDicSize = 0; + p->needInitState = 1; + } + if (initState) + p->needInitState = 1; +} + +void LzmaDec_Init(CLzmaDec *p) +{ + p->dicPos = 0; + LzmaDec_InitDicAndState(p, true, true); +} + +static void LzmaDec_InitStateReal(CLzmaDec *p) +{ + uint32_t numProbs = Literal + ((uint32_t)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp)); + uint32_t i; + uint16_t *probs = p->probs; + for (i = 0; i < numProbs; i++) + probs[i] = kBitModelTotal >> 1; + p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1; + p->state = 0; + p->needInitState = 0; +} + +SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, const uint8_t *src, size_t *srcLen, + ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + size_t inSize = *srcLen; + (*srcLen) = 0; + LzmaDec_WriteRem(p, dicLimit); + + *status = LZMA_STATUS_NOT_SPECIFIED; + + while (p->remainLen != kMatchSpecLenStart) + { + int checkEndMarkNow; + + if (p->needFlush != 0) + { + for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--) + p->tempBuf[p->tempBufSize++] = *src++; + if (p->tempBufSize < RC_INIT_SIZE) + { + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (p->tempBuf[0] != 0) + return SZ_ERROR_DATA; + + LzmaDec_InitRc(p, p->tempBuf); + p->tempBufSize = 0; + } + + checkEndMarkNow = 0; + if (p->dicPos >= dicLimit) + { + if (p->remainLen == 0 && p->code == 0) + { + *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK; + return SZ_OK; + } + if (finishMode == LZMA_FINISH_ANY) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_OK; + } + if (p->remainLen != 0) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + checkEndMarkNow = 1; + } + + if (p->needInitState) + LzmaDec_InitStateReal(p); + + if (p->tempBufSize == 0) + { + size_t processed; + const uint8_t *bufLimit; + if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, src, inSize); + if (dummyRes == DUMMY_ERROR) + { + memcpy(p->tempBuf, src, inSize); + p->tempBufSize = (unsigned)inSize; + (*srcLen) += inSize; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + bufLimit = src; + } + else + bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX; + p->buf = src; + if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0) + return SZ_ERROR_DATA; + processed = (size_t)(p->buf - src); + (*srcLen) += processed; + src += processed; + inSize -= processed; + } + else + { + unsigned rem = p->tempBufSize, lookAhead = 0; + while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize) + p->tempBuf[rem++] = src[lookAhead++]; + p->tempBufSize = rem; + if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow) + { + int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem); + if (dummyRes == DUMMY_ERROR) + { + (*srcLen) += lookAhead; + *status = LZMA_STATUS_NEEDS_MORE_INPUT; + return SZ_OK; + } + if (checkEndMarkNow && dummyRes != DUMMY_MATCH) + { + *status = LZMA_STATUS_NOT_FINISHED; + return SZ_ERROR_DATA; + } + } + p->buf = p->tempBuf; + if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0) + return SZ_ERROR_DATA; + lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf)); + (*srcLen) += lookAhead; + src += lookAhead; + inSize -= lookAhead; + p->tempBufSize = 0; + } + } + if (p->code == 0) + *status = LZMA_STATUS_FINISHED_WITH_MARK; + return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA; +} + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status) +{ + size_t outSize = *destLen; + size_t inSize = *srcLen; + *srcLen = *destLen = 0; + for (;;) + { + size_t inSizeCur = inSize, outSizeCur, dicPos; + ELzmaFinishMode curFinishMode; + SRes res; + if (p->dicPos == p->dicBufSize) + p->dicPos = 0; + dicPos = p->dicPos; + if (outSize > p->dicBufSize - dicPos) + { + outSizeCur = p->dicBufSize; + curFinishMode = LZMA_FINISH_ANY; + } + else + { + outSizeCur = dicPos + outSize; + curFinishMode = finishMode; + } + + res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status); + src += inSizeCur; + inSize -= inSizeCur; + *srcLen += inSizeCur; + outSizeCur = p->dicPos - dicPos; + memcpy(dest, p->dic + dicPos, outSizeCur); + dest += outSizeCur; + outSize -= outSizeCur; + *destLen += outSizeCur; + if (res != 0) + return res; + if (outSizeCur == 0 || outSize == 0) + return SZ_OK; + } +} + +void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->probs); + p->probs = 0; +} + +static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc) +{ + alloc->Free(alloc, p->dic); + p->dic = 0; +} + +void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc) +{ + LzmaDec_FreeProbs(p, alloc); + LzmaDec_FreeDict(p, alloc); +} + +SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size) +{ + uint32_t dicSize; + uint8_t d; + + if (size < LZMA_PROPS_SIZE) + return SZ_ERROR_UNSUPPORTED; + else + dicSize = data[1] | ((uint32_t)data[2] << 8) | ((uint32_t)data[3] << 16) | ((uint32_t)data[4] << 24); + + if (dicSize < LZMA_DIC_MIN) + dicSize = LZMA_DIC_MIN; + p->dicSize = dicSize; + + d = data[0]; + if (d >= (9 * 5 * 5)) + return SZ_ERROR_UNSUPPORTED; + + p->lc = d % 9; + d /= 9; + p->pb = d / 5; + p->lp = d % 5; + + return SZ_OK; +} + +static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc) +{ + uint32_t numProbs = LzmaProps_GetNumProbs(propNew); + if (p->probs == 0 || numProbs != p->numProbs) + { + LzmaDec_FreeProbs(p, alloc); + p->probs = (uint16_t *)alloc->Alloc(alloc, numProbs * sizeof(uint16_t)); + p->numProbs = numProbs; + if (p->probs == 0) + return SZ_ERROR_MEM; + } + return SZ_OK; +} + +SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDec_Allocate(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc) +{ + CLzmaProps propNew; + size_t dicBufSize; + RINOK(LzmaProps_Decode(&propNew, props, propsSize)); + RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc)); + dicBufSize = propNew.dicSize; + if (p->dic == 0 || dicBufSize != p->dicBufSize) + { + LzmaDec_FreeDict(p, alloc); + p->dic = (uint8_t *)alloc->Alloc(alloc, dicBufSize); + if (p->dic == 0) + { + LzmaDec_FreeProbs(p, alloc); + return SZ_ERROR_MEM; + } + } + p->dicBufSize = dicBufSize; + p->prop = propNew; + return SZ_OK; +} + +SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, + const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc) +{ + CLzmaDec p; + SRes res; + size_t inSize = *srcLen; + size_t outSize = *destLen; + *srcLen = *destLen = 0; + if (inSize < RC_INIT_SIZE) + return SZ_ERROR_INPUT_EOF; + + LzmaDec_Construct(&p); + res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc); + if (res != 0) + return res; + p.dic = dest; + p.dicBufSize = outSize; + + LzmaDec_Init(&p); + + *srcLen = inSize; + res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status); + + if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT) + res = SZ_ERROR_INPUT_EOF; + + (*destLen) = p.dicPos; + LzmaDec_FreeProbs(&p, alloc); + return res; +} diff --git a/deps/7zip/LzmaDec.h b/deps/7zip/LzmaDec.h index b10837ce99..a7cf98d971 100644 --- a/deps/7zip/LzmaDec.h +++ b/deps/7zip/LzmaDec.h @@ -1,220 +1,220 @@ -/* LzmaDec.h -- LZMA Decoder - 2009-02-07 : Igor Pavlov : Public domain */ - -#ifndef __LZMA_DEC_H -#define __LZMA_DEC_H - -#include "7zTypes.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ---------- LZMA Properties ---------- */ - -#define LZMA_PROPS_SIZE 5 - - typedef struct _CLzmaProps - { - unsigned lc, lp, pb; - uint32_t dicSize; - } CLzmaProps; - - /* LzmaProps_Decode - decodes properties -Returns: -SZ_OK -SZ_ERROR_UNSUPPORTED - Unsupported properties -*/ - - SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size); - - - /* ---------- LZMA Decoder state ---------- */ - - /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. - Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ - -#define LZMA_REQUIRED_INPUT_MAX 20 - - typedef struct - { - CLzmaProps prop; - uint16_t *probs; - uint8_t *dic; - const uint8_t *buf; - uint32_t range, code; - size_t dicPos; - size_t dicBufSize; - uint32_t processedPos; - uint32_t checkDicSize; - unsigned state; - uint32_t reps[4]; - unsigned remainLen; - int needFlush; - int needInitState; - uint32_t numProbs; - unsigned tempBufSize; - uint8_t tempBuf[LZMA_REQUIRED_INPUT_MAX]; - } CLzmaDec; - -#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } - - void LzmaDec_Init(CLzmaDec *p); - - /* There are two types of LZMA streams: - 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. - 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ - - typedef enum - { - LZMA_FINISH_ANY, /* finish at any point */ - LZMA_FINISH_END /* block must be finished at the end */ - } ELzmaFinishMode; - - /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! - - You must use LZMA_FINISH_END, when you know that current output buffer - covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. - - If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, - and output value of destLen will be less than output buffer size limit. - You can check status result also. - - You can use multiple checks to test data integrity after full decompression: - 1) Check Result and "status" variable. - 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. - 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. - You must use correct finish mode in that case. */ - - typedef enum - { - LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ - LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ - LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ - LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ - LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ - } ELzmaStatus; - - /* ELzmaStatus is used only as output value for function call */ - - - /* ---------- Interfaces ---------- */ - - /* There are 3 levels of interfaces: - 1) Dictionary Interface - 2) Buffer Interface - 3) One Call Interface - You can select any of these interfaces, but don't mix functions from different - groups for same object. */ - - - /* There are two variants to allocate state for Dictionary Interface: - 1) LzmaDec_Allocate / LzmaDec_Free - 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs - You can use variant 2, if you set dictionary buffer manually. - For Buffer Interface you must always use variant 1. - - LzmaDec_Allocate* can return: - SZ_OK - SZ_ERROR_MEM - Memory allocation error - SZ_ERROR_UNSUPPORTED - Unsupported properties - */ - - SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc); - void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); - - SRes LzmaDec_Allocate(CLzmaDec *state, const uint8_t *prop, unsigned propsSize, ISzAlloc *alloc); - void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); - - /* ---------- Dictionary Interface ---------- */ - - /* You can use it, if you want to eliminate the overhead for data copying from - dictionary to some other external buffer. - You must work with CLzmaDec variables directly in this interface. - -STEPS: -LzmaDec_Constr() -LzmaDec_Allocate() -for (each new stream) -{ -LzmaDec_Init() -while (it needs more decompression) -{ -LzmaDec_DecodeToDic() -use data from CLzmaDec::dic and update CLzmaDec::dicPos -} -} -LzmaDec_Free() -*/ - - /* LzmaDec_DecodeToDic - - The decoding to internal dictionary buffer (CLzmaDec::dic). - You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! - -finishMode: -It has meaning only if the decoding reaches output limit (dicLimit). -LZMA_FINISH_ANY - Decode just dicLimit bytes. -LZMA_FINISH_END - Stream must be finished after dicLimit. - -Returns: -SZ_OK -status: -LZMA_STATUS_FINISHED_WITH_MARK -LZMA_STATUS_NOT_FINISHED -LZMA_STATUS_NEEDS_MORE_INPUT -LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -SZ_ERROR_DATA - Data error -*/ - - SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, - const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- Buffer Interface ---------- */ - -/* It's zlib-like interface. - See LzmaDec_DecodeToDic description for information about STEPS and return results, - but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need - to work with CLzmaDec variables manually. - -finishMode: -It has meaning only if the decoding reaches output limit (*destLen). -LZMA_FINISH_ANY - Decode just destLen bytes. -LZMA_FINISH_END - Stream must be finished after (*destLen). -*/ - -SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, - const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); - - -/* ---------- One Call Interface ---------- */ - -/* LzmaDecode - -finishMode: -It has meaning only if the decoding reaches output limit (*destLen). -LZMA_FINISH_ANY - Decode just destLen bytes. -LZMA_FINISH_END - Stream must be finished after (*destLen). - -Returns: -SZ_OK -status: -LZMA_STATUS_FINISHED_WITH_MARK -LZMA_STATUS_NOT_FINISHED -LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK -SZ_ERROR_DATA - Data error -SZ_ERROR_MEM - Memory allocation error -SZ_ERROR_UNSUPPORTED - Unsupported properties -SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). -*/ - -SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, - const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode, - ELzmaStatus *status, ISzAlloc *alloc); - -#ifdef __cplusplus -} -#endif - -#endif +/* LzmaDec.h -- LZMA Decoder + 2009-02-07 : Igor Pavlov : Public domain */ + +#ifndef __LZMA_DEC_H +#define __LZMA_DEC_H + +#include "7zTypes.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* ---------- LZMA Properties ---------- */ + +#define LZMA_PROPS_SIZE 5 + + typedef struct _CLzmaProps + { + unsigned lc, lp, pb; + uint32_t dicSize; + } CLzmaProps; + + /* LzmaProps_Decode - decodes properties +Returns: +SZ_OK +SZ_ERROR_UNSUPPORTED - Unsupported properties +*/ + + SRes LzmaProps_Decode(CLzmaProps *p, const uint8_t *data, unsigned size); + + + /* ---------- LZMA Decoder state ---------- */ + + /* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case. + Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */ + +#define LZMA_REQUIRED_INPUT_MAX 20 + + typedef struct + { + CLzmaProps prop; + uint16_t *probs; + uint8_t *dic; + const uint8_t *buf; + uint32_t range, code; + size_t dicPos; + size_t dicBufSize; + uint32_t processedPos; + uint32_t checkDicSize; + unsigned state; + uint32_t reps[4]; + unsigned remainLen; + int needFlush; + int needInitState; + uint32_t numProbs; + unsigned tempBufSize; + uint8_t tempBuf[LZMA_REQUIRED_INPUT_MAX]; + } CLzmaDec; + +#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; } + + void LzmaDec_Init(CLzmaDec *p); + + /* There are two types of LZMA streams: + 0) Stream with end mark. That end mark adds about 6 bytes to compressed size. + 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */ + + typedef enum + { + LZMA_FINISH_ANY, /* finish at any point */ + LZMA_FINISH_END /* block must be finished at the end */ + } ELzmaFinishMode; + + /* ELzmaFinishMode has meaning only if the decoding reaches output limit !!! + + You must use LZMA_FINISH_END, when you know that current output buffer + covers last bytes of block. In other cases you must use LZMA_FINISH_ANY. + + If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK, + and output value of destLen will be less than output buffer size limit. + You can check status result also. + + You can use multiple checks to test data integrity after full decompression: + 1) Check Result and "status" variable. + 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize. + 3) Check that output(srcLen) = compressedSize, if you know real compressedSize. + You must use correct finish mode in that case. */ + + typedef enum + { + LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */ + LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */ + LZMA_STATUS_NOT_FINISHED, /* stream was not finished */ + LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */ + LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */ + } ELzmaStatus; + + /* ELzmaStatus is used only as output value for function call */ + + + /* ---------- Interfaces ---------- */ + + /* There are 3 levels of interfaces: + 1) Dictionary Interface + 2) Buffer Interface + 3) One Call Interface + You can select any of these interfaces, but don't mix functions from different + groups for same object. */ + + + /* There are two variants to allocate state for Dictionary Interface: + 1) LzmaDec_Allocate / LzmaDec_Free + 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs + You can use variant 2, if you set dictionary buffer manually. + For Buffer Interface you must always use variant 1. + + LzmaDec_Allocate* can return: + SZ_OK + SZ_ERROR_MEM - Memory allocation error + SZ_ERROR_UNSUPPORTED - Unsupported properties + */ + + SRes LzmaDec_AllocateProbs(CLzmaDec *p, const uint8_t *props, unsigned propsSize, ISzAlloc *alloc); + void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc); + + SRes LzmaDec_Allocate(CLzmaDec *state, const uint8_t *prop, unsigned propsSize, ISzAlloc *alloc); + void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc); + + /* ---------- Dictionary Interface ---------- */ + + /* You can use it, if you want to eliminate the overhead for data copying from + dictionary to some other external buffer. + You must work with CLzmaDec variables directly in this interface. + +STEPS: +LzmaDec_Constr() +LzmaDec_Allocate() +for (each new stream) +{ +LzmaDec_Init() +while (it needs more decompression) +{ +LzmaDec_DecodeToDic() +use data from CLzmaDec::dic and update CLzmaDec::dicPos +} +} +LzmaDec_Free() +*/ + + /* LzmaDec_DecodeToDic + + The decoding to internal dictionary buffer (CLzmaDec::dic). + You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!! + +finishMode: +It has meaning only if the decoding reaches output limit (dicLimit). +LZMA_FINISH_ANY - Decode just dicLimit bytes. +LZMA_FINISH_END - Stream must be finished after dicLimit. + +Returns: +SZ_OK +status: +LZMA_STATUS_FINISHED_WITH_MARK +LZMA_STATUS_NOT_FINISHED +LZMA_STATUS_NEEDS_MORE_INPUT +LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK +SZ_ERROR_DATA - Data error +*/ + + SRes LzmaDec_DecodeToDic(CLzmaDec *p, size_t dicLimit, + const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- Buffer Interface ---------- */ + +/* It's zlib-like interface. + See LzmaDec_DecodeToDic description for information about STEPS and return results, + but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need + to work with CLzmaDec variables manually. + +finishMode: +It has meaning only if the decoding reaches output limit (*destLen). +LZMA_FINISH_ANY - Decode just destLen bytes. +LZMA_FINISH_END - Stream must be finished after (*destLen). +*/ + +SRes LzmaDec_DecodeToBuf(CLzmaDec *p, uint8_t *dest, size_t *destLen, + const uint8_t *src, size_t *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status); + + +/* ---------- One Call Interface ---------- */ + +/* LzmaDecode + +finishMode: +It has meaning only if the decoding reaches output limit (*destLen). +LZMA_FINISH_ANY - Decode just destLen bytes. +LZMA_FINISH_END - Stream must be finished after (*destLen). + +Returns: +SZ_OK +status: +LZMA_STATUS_FINISHED_WITH_MARK +LZMA_STATUS_NOT_FINISHED +LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK +SZ_ERROR_DATA - Data error +SZ_ERROR_MEM - Memory allocation error +SZ_ERROR_UNSUPPORTED - Unsupported properties +SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src). +*/ + +SRes LzmaDecode(uint8_t *dest, size_t *destLen, const uint8_t *src, size_t *srcLen, + const uint8_t *propData, unsigned propSize, ELzmaFinishMode finishMode, + ELzmaStatus *status, ISzAlloc *alloc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/deps/7zip/LzmaEnc.c b/deps/7zip/LzmaEnc.c index 6ea4395a3b..d66c0acb08 100644 --- a/deps/7zip/LzmaEnc.c +++ b/deps/7zip/LzmaEnc.c @@ -50,7 +50,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) int level = p->level; if (level < 0) level = 5; p->level = level; - + if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26))); if (p->dictSize > p->reduceSize) { @@ -71,7 +71,7 @@ void LzmaEncProps_Normalize(CLzmaEncProps *p) if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1); if (p->numHashBytes < 0) p->numHashBytes = 4; if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1); - + if (p->numThreads < 0) p->numThreads = #ifndef _7ZIP_ST @@ -99,7 +99,7 @@ static void LzmaEnc_FastPosInit(unsigned char *g_FastPos) g_FastPos[0] = 0; g_FastPos[1] = 1; g_FastPos += 2; - + for (slot = 2; slot < kNumLogBits * 2; slot++) { size_t k = ((size_t)1 << ((slot >> 1) - 1)); @@ -236,7 +236,7 @@ typedef struct CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - + CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; } CSaveState; @@ -272,7 +272,7 @@ typedef struct bool needInit; uint64_t nowPos64; - + uint32_t matchPriceCount; uint32_t alignPriceCount; @@ -293,9 +293,9 @@ typedef struct #ifndef _7ZIP_ST unsigned char pad[128]; #endif - + COptimal opt[kNumOpts]; - + unsigned char g_FastPos[1 << kNumLogBits]; uint32_t ProbPrices[kBitModelTotal >> kNumMoveReducingBits]; @@ -315,7 +315,7 @@ typedef struct CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits]; CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex]; CLzmaProb posAlignEncoder[1 << kNumAlignBits]; - + CLenPriceEnc lenEnc; CLenPriceEnc repLenEnc; @@ -808,7 +808,7 @@ static uint32_t ReadMatchDistances(CLzmaEnc *p, uint32_t *numDistancePairsRes) uint32_t lenRes = 0, numPairs; p->numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj); numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); - + if (numPairs > 0) { lenRes = p->matches[numPairs - 2]; @@ -893,10 +893,10 @@ static uint32_t Backward(CLzmaEnc *p, uint32_t *backRes, uint32_t cur) { uint32_t posPrev = posMem; uint32_t backCur = backMem; - + backMem = p->opt[posPrev].backPrev; posMem = p->opt[posPrev].posPrev; - + p->opt[posPrev].backPrev = backCur; p->opt[posPrev].posPrev = cur; cur = posPrev; @@ -932,7 +932,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) return lenRes; } p->optimumCurrentIndex = p->optimumEndIndex = 0; - + if (p->additionalOffset == 0) mainLen = ReadMatchDistances(p, &numPairs); else @@ -1223,7 +1223,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]); repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]); - + if (matchByte == curByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0)) { uint32_t shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState); @@ -1285,7 +1285,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) } } } - + startLen = 2; /* speed optimization */ { uint32_t repIndex; @@ -1316,10 +1316,10 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) } while (--lenTest >= 2); lenTest = lenTestTemp; - + if (repIndex == 0) startLen = lenTest + 1; - + /* if (_maxMode) */ { uint32_t lenTest2 = lenTest + 1; @@ -1343,7 +1343,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) nextRepMatchPrice = curAndLenCharPrice + GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isRep[state2]); - + /* for (; lenTest2 >= 2; lenTest2--) */ { uint32_t curAndLenPrice; @@ -1399,7 +1399,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) curAndLenPrice += p->distancesPrices[lenToPosState][curBack]; else curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask]; - + opt = &p->opt[cur + lenTest]; if (curAndLenPrice < opt->price) { @@ -1434,7 +1434,7 @@ static uint32_t GetOptimum(CLzmaEnc *p, uint32_t position, uint32_t *backRes) nextRepMatchPrice = curAndLenCharPrice + GET_PRICE_1(p->isMatch[state2][posStateNext]) + GET_PRICE_1(p->isRep[state2]); - + /* for (; lenTest2 >= 2; lenTest2--) */ { uint32_t offset = cur + lenTest + 1 + lenTest2; @@ -1546,7 +1546,7 @@ static uint32_t GetOptimumFast(CLzmaEnc *p, uint32_t *backRes) MovePos(p, repLen - 1); return repLen; } - + if (mainLen < 2 || numAvail <= 2) return 1; @@ -1560,7 +1560,7 @@ static uint32_t GetOptimumFast(CLzmaEnc *p, uint32_t *backRes) (p->longestMatchLength + 1 >= mainLen && mainLen >= 3 && ChangePair(newDistance, mainDist))) return 1; } - + data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1; for (i = 0; i < LZMA_NUM_REPS; i++) { @@ -1660,7 +1660,7 @@ void LzmaEnc_Construct(CLzmaEnc *p) { RangeEnc_Construct(&p->rc); MatchFinder_Construct(&p->matchFinderBase); - + #ifndef _7ZIP_ST MatchFinderMt_Construct(&p->matchFinderMt); p->matchFinderMt.MatchFinder = &p->matchFinderBase; @@ -1701,7 +1701,7 @@ void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig) #ifndef _7ZIP_ST MatchFinderMt_Destruct(&p->matchFinderMt, allocBig); #endif - + MatchFinder_Free(&p->matchFinderBase, allocBig); LzmaEnc_FreeLits(p, alloc); RangeEnc_Free(&p->rc, alloc); @@ -1816,7 +1816,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, bool useLimits, uint32_t maxPackSi pos -= LZMA_NUM_REPS; GetPosSlot(pos, posSlot); RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot); - + if (posSlot >= kStartPosModelIndex) { uint32_t footerBits = ((posSlot >> 1) - 1); @@ -1919,7 +1919,7 @@ static SRes LzmaEnc_Alloc(CLzmaEnc *p, uint32_t keepWindowSize, ISzAlloc *alloc, p->matchFinderObj = &p->matchFinderBase; MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder); } - + return SZ_OK; } @@ -2123,7 +2123,7 @@ SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, bool reInit, p->rc.outStream = &outStream.funcTable; res = LzmaEnc_CodeOneBlock(p, true, desiredPackSize, *unpackSize); - + *unpackSize = (uint32_t)(p->nowPos64 - nowPos64); *destLen -= outStream.rem; if (outStream.overflow) @@ -2158,7 +2158,7 @@ static SRes LzmaEnc_Encode2(CLzmaEnc *p, ICompressProgress *progress) } } } - + LzmaEnc_Finish(p); return res; @@ -2218,7 +2218,7 @@ SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, unsigned char *dest, size_t *destLen, p->rc.outStream = &outStream.funcTable; res = LzmaEnc_MemPrepare(pp, src, srcLen, 0, alloc, allocBig); - + if (res == SZ_OK) { res = LzmaEnc_Encode2(p, progress); diff --git a/deps/SPIRV-Cross/GLSL.std.450.h b/deps/SPIRV-Cross/GLSL.std.450.h index 54cc00e9a8..943fd8650f 100644 --- a/deps/SPIRV-Cross/GLSL.std.450.h +++ b/deps/SPIRV-Cross/GLSL.std.450.h @@ -13,7 +13,7 @@ ** ** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS ** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/deps/glslang/glslang/SPIRV/GLSL.std.450.h b/deps/glslang/glslang/SPIRV/GLSL.std.450.h index df31092bec..86d3da8065 100755 --- a/deps/glslang/glslang/SPIRV/GLSL.std.450.h +++ b/deps/glslang/glslang/SPIRV/GLSL.std.450.h @@ -13,7 +13,7 @@ ** ** MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS KHRONOS ** STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS SPECIFICATIONS AND -** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ +** HEADER INFORMATION ARE LOCATED AT https://www.khronos.org/registry/ ** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ** OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, diff --git a/deps/glslang/glslang/SPIRV/SPVRemapper.h b/deps/glslang/glslang/SPIRV/SPVRemapper.h index b3c686aae5..ee5f63c653 100755 --- a/deps/glslang/glslang/SPIRV/SPVRemapper.h +++ b/deps/glslang/glslang/SPIRV/SPVRemapper.h @@ -112,7 +112,7 @@ class spirvbin_t : public spirvbin_base_t { public: spirvbin_t(int verbose = 0) : entryPoint(spv::NoResult), largestNewId(0), verbose(verbose) { } - + // remap on an existing binary in memory void remap(std::vector& spv, std::uint32_t opts = DO_EVERYTHING); @@ -175,7 +175,7 @@ private: range_t constRange(spv::Op opCode) const; unsigned typeSizeInWords(spv::Id id) const; unsigned idTypeSizeInWords(spv::Id id) const; - + spv::Id& asId(unsigned word) { return spv[word]; } const spv::Id& asId(unsigned word) const { return spv[word]; } spv::Op asOpCode(unsigned word) const { return opOpCode(spv[word]); } @@ -241,7 +241,7 @@ private: void mapRemainder(); // map any IDs we haven't touched yet void stripDebug(); // strip debug info void strip(); // remove debug symbols - + std::vector spv; // SPIR words namemap_t nameMap; // ID names from OpName @@ -268,11 +268,11 @@ private: // Which functions are called, anywhere in the module, with a call count std::unordered_map fnCalls; - + posmap_t typeConstPos; // word positions that define types & consts (ordered) posmap_rev_t idPosR; // reverse map from IDs to positions typesize_map_t idTypeSizeMap; // maps each ID to its type size, if known. - + std::vector idMapL; // ID {M}ap from {L}ocal to {G}lobal IDs spv::Id entryPoint; // module entry point diff --git a/deps/glslang/glslang/SPIRV/SpvBuilder.h b/deps/glslang/glslang/SPIRV/SpvBuilder.h index e8524b2b1b..ad5da5ffde 100755 --- a/deps/glslang/glslang/SPIRV/SpvBuilder.h +++ b/deps/glslang/glslang/SPIRV/SpvBuilder.h @@ -301,7 +301,7 @@ public: // Generally, the type of 'scalar' does not need to be the same type as the components in 'vector'. // The type of the created vector is a vector of components of the same type as the scalar. // - // Note: One of the arguments will change, with the result coming back that way rather than + // Note: One of the arguments will change, with the result coming back that way rather than // through the return value. void promoteScalar(Decoration precision, Id& left, Id& right); diff --git a/deps/glslang/glslang/SPIRV/doc.h b/deps/glslang/glslang/SPIRV/doc.h index 743896ff4a..dfc5662667 100644 --- a/deps/glslang/glslang/SPIRV/doc.h +++ b/deps/glslang/glslang/SPIRV/doc.h @@ -195,7 +195,7 @@ public: // Parameterize a set of enumerants that form an enum class EnumDefinition : public EnumParameters { public: - EnumDefinition() : + EnumDefinition() : ceiling(0), bitmask(false), getName(0), enumParams(0), operandParams(0) { } void set(int ceil, const char* (*name)(int), EnumParameters* ep, bool mask = false) { diff --git a/deps/glslang/glslang/SPIRV/spvIR.h b/deps/glslang/glslang/SPIRV/spvIR.h index c584c9dcb4..88630f899c 100755 --- a/deps/glslang/glslang/SPIRV/spvIR.h +++ b/deps/glslang/glslang/SPIRV/spvIR.h @@ -36,9 +36,9 @@ // // Simple in-memory representation (IR) of SPIRV. Just for holding // Each function's CFG of blocks. Has this hierarchy: -// - Module, which is a list of -// - Function, which is a list of -// - Block, which is a list of +// - Module, which is a list of +// - Function, which is a list of +// - Block, which is a list of // - Instruction // @@ -65,7 +65,7 @@ const Id NoResult = 0; const Id NoType = 0; const Decoration NoPrecision = DecorationMax; -const MemorySemanticsMask MemorySemanticsAllMemory = +const MemorySemanticsMask MemorySemanticsAllMemory = (MemorySemanticsMask)(MemorySemanticsSequentiallyConsistentMask | MemorySemanticsUniformMemoryMask | MemorySemanticsSubgroupMemoryMask | @@ -229,7 +229,7 @@ protected: std::vector > localVariables; Function& parent; - // track whether this block is known to be uncreachable (not necessarily + // track whether this block is known to be uncreachable (not necessarily // true for all unreachable blocks, but should be set at least // for the extraneous ones introduced by the builder). bool unreachable; diff --git a/deps/glslang/glslang/StandAlone/Worklist.h b/deps/glslang/glslang/StandAlone/Worklist.h index 57dc0db7b2..cfa80a8321 100644 --- a/deps/glslang/glslang/StandAlone/Worklist.h +++ b/deps/glslang/glslang/StandAlone/Worklist.h @@ -59,21 +59,21 @@ namespace glslang { void add(TWorkItem* item) { GetGlobalLock(); - + worklist.push_back(item); - + ReleaseGlobalLock(); } - + bool remove(TWorkItem*& item) { GetGlobalLock(); - + if (worklist.empty()) return false; item = worklist.front(); worklist.pop_front(); - + ReleaseGlobalLock(); return true; diff --git a/deps/glslang/glslang/glslang/Include/BaseTypes.h b/deps/glslang/glslang/glslang/Include/BaseTypes.h index f707440672..38719306d0 100644 --- a/deps/glslang/glslang/glslang/Include/BaseTypes.h +++ b/deps/glslang/glslang/glslang/Include/BaseTypes.h @@ -84,7 +84,7 @@ enum TStorageQualifier { EvqUniform, // read only, shared with app EvqBuffer, // read/write, shared with app EvqShared, // compute shader's read/write 'shared' qualifier - + // parameters EvqIn, // also, for 'in' in the grammar before we know if it's a pipeline input or an 'in' parameter EvqOut, // also, for 'out' in the grammar before we know if it's a pipeline output or an 'out' parameter @@ -212,7 +212,7 @@ enum TBuiltInVariable { }; // These will show up in error messages -__inline const char* GetStorageQualifierString(TStorageQualifier q) +__inline const char* GetStorageQualifierString(TStorageQualifier q) { switch (q) { case EvqTemporary: return "temp"; break; diff --git a/deps/glslang/glslang/glslang/Include/Common.h b/deps/glslang/glslang/glslang/Include/Common.h index a779c83e6a..e0af6b1ff1 100644 --- a/deps/glslang/glslang/glslang/Include/Common.h +++ b/deps/glslang/glslang/glslang/Include/Common.h @@ -56,7 +56,7 @@ std::string to_string(const T& val) { #if defined(_MSC_VER) && _MSC_VER < 1700 inline long long int strtoll (const char* str, char** endptr, int base) { - return _strtoi64(str, endptr, base); + return _strtoi64(str, endptr, base); } inline unsigned long long int strtoull (const char* str, char** endptr, int base) { @@ -168,7 +168,7 @@ public: template class TList : public std::list > { }; -template > +template > class TMap : public std::map > > { }; @@ -194,13 +194,13 @@ template T Max(const T a, const T b) { return a > b ? a : b; } inline const TString String(const int i, const int /*base*/ = 10) { char text[16]; // 32 bit ints are at most 10 digits in base 10 - + // we assume base 10 for all cases snprintf(text, sizeof(text), "%d", i); return text; } - + struct TSourceLoc { void init() { name = nullptr; string = 0; line = 0; column = 0; } // Returns the name if it exists. Otherwise, returns the string number. diff --git a/deps/glslang/glslang/glslang/Include/ConstantUnion.h b/deps/glslang/glslang/glslang/Include/ConstantUnion.h index ec6aff1171..18756f5ce0 100644 --- a/deps/glslang/glslang/glslang/Include/ConstantUnion.h +++ b/deps/glslang/glslang/glslang/Include/ConstantUnion.h @@ -46,14 +46,14 @@ public: TConstUnion() : iConst(0), type(EbtInt) { } void setIConst(int i) - { - iConst = i; + { + iConst = i; type = EbtInt; } void setUConst(unsigned int u) { - uConst = u; + uConst = u; type = EbtUint; } @@ -71,13 +71,13 @@ public: void setDConst(double d) { - dConst = d; + dConst = d; type = EbtDouble; } void setBConst(bool b) { - bConst = b; + bConst = b; type = EbtBool; } @@ -215,7 +215,7 @@ public: } bool operator>(const TConstUnion& constant) const - { + { assert(type == constant.type); switch (type) { case EbtInt: @@ -250,7 +250,7 @@ public: } bool operator<(const TConstUnion& constant) const - { + { assert(type == constant.type); switch (type) { case EbtInt: @@ -285,7 +285,7 @@ public: } TConstUnion operator+(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -301,7 +301,7 @@ public: } TConstUnion operator-(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -317,7 +317,7 @@ public: } TConstUnion operator*(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -325,7 +325,7 @@ public: case EbtInt64: returnValue.setI64Const(i64Const * constant.i64Const); break; case EbtUint: returnValue.setUConst(uConst * constant.uConst); break; case EbtUint64: returnValue.setU64Const(u64Const * constant.u64Const); break; - case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; + case EbtDouble: returnValue.setDConst(dConst * constant.dConst); break; default: assert(false && "Default missing"); } @@ -333,7 +333,7 @@ public: } TConstUnion operator%(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -348,7 +348,7 @@ public: } TConstUnion operator>>(const TConstUnion& constant) const - { + { TConstUnion returnValue; switch (type) { case EbtInt: @@ -394,7 +394,7 @@ public: } TConstUnion operator<<(const TConstUnion& constant) const - { + { TConstUnion returnValue; switch (type) { case EbtInt: @@ -440,7 +440,7 @@ public: } TConstUnion operator&(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -455,7 +455,7 @@ public: } TConstUnion operator|(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -470,7 +470,7 @@ public: } TConstUnion operator^(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -485,7 +485,7 @@ public: } TConstUnion operator~() const - { + { TConstUnion returnValue; switch (type) { case EbtInt: returnValue.setIConst(~iConst); break; @@ -499,7 +499,7 @@ public: } TConstUnion operator&&(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -511,7 +511,7 @@ public: } TConstUnion operator||(const TConstUnion& constant) const - { + { TConstUnion returnValue; assert(type == constant.type); switch (type) { @@ -544,7 +544,7 @@ private: // One convenience is being able to use [] to go inside the array, instead // of C++ assuming it as an array of pointers to vectors. // -// General usage is that the size is known up front, and it is +// General usage is that the size is known up front, and it is // created once with the proper size. // class TConstUnionArray { diff --git a/deps/glslang/glslang/glslang/Include/InfoSink.h b/deps/glslang/glslang/glslang/Include/InfoSink.h index 0cbd99bdaa..54f1f3393c 100644 --- a/deps/glslang/glslang/glslang/Include/InfoSink.h +++ b/deps/glslang/glslang/glslang/Include/InfoSink.h @@ -74,9 +74,9 @@ public: TInfoSinkBase& operator<<(const char* s) { append(s); return *this; } TInfoSinkBase& operator<<(int n) { append(String(n)); return *this; } TInfoSinkBase& operator<<(unsigned int n) { append(String(n)); return *this; } - TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; + TInfoSinkBase& operator<<(float n) { const int size = 40; char buf[size]; snprintf(buf, size, (fabs(n) > 1e-8 && fabs(n) < 1e8) || n == 0.0f ? "%f" : "%g", n); - append(buf); + append(buf); return *this; } TInfoSinkBase& operator+(const TPersistString& t) { append(t); return *this; } TInfoSinkBase& operator+(const TString& t) { append(t); return *this; } @@ -113,20 +113,20 @@ public: append(s); append("\n"); } - + void setOutputStream(int output = 4) { outputStream = output; } protected: - void append(const char* s); + void append(const char* s); void append(int count, char c); void append(const TPersistString& t); void append(const TString& t); - void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) + void checkMem(size_t growth) { if (sink.capacity() < sink.size() + growth + 2) sink.reserve(sink.capacity() + sink.capacity() / 2); } void appendToStream(const char* s); TPersistString sink; diff --git a/deps/glslang/glslang/glslang/Include/PoolAlloc.h b/deps/glslang/glslang/glslang/Include/PoolAlloc.h index 635be79ef9..0aa2ab2c11 100644 --- a/deps/glslang/glslang/glslang/Include/PoolAlloc.h +++ b/deps/glslang/glslang/glslang/Include/PoolAlloc.h @@ -43,8 +43,8 @@ // // This header defines an allocator that can be used to efficiently -// allocate a large number of small requests for heap memory, with the -// intention that they are not individually deallocated, but rather +// allocate a large number of small requests for heap memory, with the +// intention that they are not individually deallocated, but rather // collectively deallocated at one time. // // This simultaneously @@ -70,7 +70,7 @@ namespace glslang { // If we are using guard blocks, we must track each individual // allocation. If we aren't using guard blocks, these // never get instantiated, so won't have any impact. -// +// class TAllocation { public: @@ -87,7 +87,7 @@ public: memset(postGuard(), guardBlockEndVal, guardBlockSize); # endif } - + void check() const { checkGuardBlock(preGuard(), guardBlockBeginVal, "before"); checkGuardBlock(postGuard(), guardBlockEndVal, "after"); @@ -100,7 +100,7 @@ public: inline static size_t allocationSize(size_t size) { return size + 2 * guardBlockSize + headerSize(); } - + // Offset from surrounding buffer to get to user data buffer. inline static unsigned char* offsetAllocation(unsigned char* m) { return m + guardBlockSize + headerSize(); @@ -123,16 +123,16 @@ private: const static unsigned char userDataFill; const static size_t guardBlockSize; -# ifdef GUARD_BLOCKS +# ifdef GUARD_BLOCKS inline static size_t headerSize() { return sizeof(TAllocation); } # else inline static size_t headerSize() { return 0; } # endif }; - + // // There are several stacks. One is to track the pushing and popping -// of the user, and not yet implemented. The others are simply a +// of the user, and not yet implemented. The others are simply a // repositories of free pages or used pages. // // Page stacks are linked together with a simple header at the beginning @@ -141,7 +141,7 @@ private: // re-use. // // The "page size" used is not, nor must it match, the underlying OS -// page size. But, having it be about that size or equal to a set of +// page size. But, having it be about that size or equal to a set of // pages is likely most optimal. // class TPoolAllocator { @@ -185,7 +185,7 @@ public: protected: friend struct tHeader; - + struct tHeader { tHeader(tHeader* nextPage, size_t pageCount) : #ifdef GUARD_BLOCKS @@ -227,7 +227,7 @@ protected: } size_t pageSize; // granularity of allocation from the OS - size_t alignment; // all returned allocations will be aligned at + size_t alignment; // all returned allocations will be aligned at // this granularity, which will be a power of 2 size_t alignmentMask; size_t headerSkip; // amount of memory to skip to make room for the @@ -278,7 +278,7 @@ public: typedef T& reference; typedef const T& const_reference; typedef T value_type; - template + template struct rebind { typedef pool_allocator other; }; @@ -292,9 +292,9 @@ public: template pool_allocator(const pool_allocator& p) : allocator(p.getAllocator()) { } - pointer allocate(size_type n) { + pointer allocate(size_type n) { return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } - pointer allocate(size_type n, const void*) { + pointer allocate(size_type n, const void*) { return reinterpret_cast(getAllocator().allocate(n * sizeof(T))); } void deallocate(void*, size_type) { } diff --git a/deps/glslang/glslang/glslang/Include/ResourceLimits.h b/deps/glslang/glslang/glslang/Include/ResourceLimits.h index e8c743d6b7..b9cadb9faf 100644 --- a/deps/glslang/glslang/glslang/Include/ResourceLimits.h +++ b/deps/glslang/glslang/glslang/Include/ResourceLimits.h @@ -81,7 +81,7 @@ struct TBuiltInResource { int maxComputeImageUniforms; int maxComputeAtomicCounters; int maxComputeAtomicCounterBuffers; - int maxVaryingComponents; + int maxVaryingComponents; int maxVertexOutputComponents; int maxGeometryInputComponents; int maxGeometryOutputComponents; diff --git a/deps/glslang/glslang/glslang/Include/ShHandle.h b/deps/glslang/glslang/glslang/Include/ShHandle.h index bfc97db8b2..1e24fdd933 100644 --- a/deps/glslang/glslang/glslang/Include/ShHandle.h +++ b/deps/glslang/glslang/glslang/Include/ShHandle.h @@ -43,7 +43,7 @@ // -#define SH_EXPORTING +#define SH_EXPORTING #include "../Public/ShaderLang.h" #include "../MachineIndependent/Versions.h" #include "InfoSink.h" @@ -73,7 +73,7 @@ public: TUniformMap() { } virtual ~TUniformMap() { } virtual TUniformMap* getAsUniformMap() { return this; } - virtual int getLocation(const char* name) = 0; + virtual int getLocation(const char* name) = 0; virtual TInfoSink& getInfoSink() { return infoSink; } TInfoSink infoSink; }; @@ -95,7 +95,7 @@ public: virtual TCompiler* getAsCompiler() { return this; } virtual bool linkable() { return haveValidObjectCode; } - + TInfoSink& infoSink; protected: TCompiler& operator=(TCompiler&); @@ -117,9 +117,9 @@ typedef glslang::TVector THandleList; class TLinker : public TShHandleBase { public: - TLinker(EShExecutable e, TInfoSink& iSink) : + TLinker(EShExecutable e, TInfoSink& iSink) : infoSink(iSink), - executable(e), + executable(e), haveReturnableObjectCode(false), appAttributeBindings(0), fixedAttributeBindings(0), @@ -147,7 +147,7 @@ protected: const ShBindingTable* fixedAttributeBindings; const int* excludedAttributes; int excludedCount; - ShBindingTable* uniformBindings; // created by the linker + ShBindingTable* uniformBindings; // created by the linker }; // @@ -155,7 +155,7 @@ protected: // and the machine dependent code. // // The machine dependent code should derive from the classes -// above. Then Construct*() and Delete*() will create and +// above. Then Construct*() and Delete*() will create and // destroy the machine dependent objects, which contain the // above machine independent information. // @@ -165,7 +165,7 @@ TShHandleBase* ConstructLinker(EShExecutable, int); TShHandleBase* ConstructBindings(); void DeleteLinker(TShHandleBase*); void DeleteBindingList(TShHandleBase* bindingList); - + TUniformMap* ConstructUniformMap(); void DeleteCompiler(TCompiler*); diff --git a/deps/glslang/glslang/glslang/Include/Types.h b/deps/glslang/glslang/glslang/Include/Types.h index 8745c7a942..7642df9be1 100644 --- a/deps/glslang/glslang/glslang/Include/Types.h +++ b/deps/glslang/glslang/glslang/Include/Types.h @@ -421,7 +421,7 @@ public: clearLayout(); } - // Drop just the storage qualification, which perhaps should + // Drop just the storage qualification, which perhaps should // never be done, as it is fundamentally inconsistent, but need to // explore what downstream consumers need. // E.g., in a deference, it is an inconsistency between: @@ -1067,7 +1067,7 @@ public: qualifier.storage = q; } // for explicit precision qualifier - TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, + TType(TBasicType t, TStorageQualifier q, TPrecisionQualifier p, int vs = 1, int mc = 0, int mr = 0, bool isVector = false) : basicType(t), vectorSize(vs), matrixCols(mc), matrixRows(mr), vector1(isVector && vs == 1), arraySizes(nullptr), structure(nullptr), fieldName(nullptr), typeName(nullptr) diff --git a/deps/glslang/glslang/glslang/Include/intermediate.h b/deps/glslang/glslang/glslang/Include/intermediate.h index 8f7ffcc0da..ffdc82b003 100644 --- a/deps/glslang/glslang/glslang/Include/intermediate.h +++ b/deps/glslang/glslang/glslang/Include/intermediate.h @@ -38,7 +38,7 @@ // Definition of the in-memory high-level intermediate representation // of shaders. This is a tree that parser creates. // -// Nodes in the tree are defined as a hierarchy of classes derived from +// Nodes in the tree are defined as a hierarchy of classes derived from // TIntermNode. Each is a node in a tree. There is no preset branching factor; // each node can have it's own type of list of children. // @@ -66,14 +66,14 @@ enum TOperator { EOpNull, // if in a node, should only mean a node is still being built EOpSequence, // denotes a list of statements, or parameters, etc. EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST - EOpFunctionCall, + EOpFunctionCall, EOpFunction, // For function definition EOpParameters, // an aggregate listing the parameters to a function // // Unary operators // - + EOpNegative, EOpLogicalNot, EOpVectorLogicalNot, @@ -445,7 +445,7 @@ enum TOperator { // // moves // - + EOpAssign, EOpAddAssign, EOpSubAssign, @@ -708,7 +708,7 @@ public: virtual void setType(const TType& t) { type.shallowCopy(t); } virtual const TType& getType() const { return type; } virtual TType& getWritableType() { return type; } - + virtual TBasicType getBasicType() const { return type.getBasicType(); } virtual TQualifier& getQualifier() { return type.getQualifier(); } virtual const TQualifier& getQualifier() const { return type.getQualifier(); } @@ -733,7 +733,7 @@ protected: // class TIntermLoop : public TIntermNode { public: - TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : + TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : body(aBody), test(aTest), terminal(aTerminal), @@ -1147,7 +1147,7 @@ enum TVisit }; // -// For traversing the tree. User should derive from this, +// For traversing the tree. User should derive from this, // put their traversal specific data in it, and then pass // it to a Traverse method. // @@ -1159,10 +1159,10 @@ enum TVisit // the subtree). Similarly for inVisit for in-order visiting of nodes with // multiple children. // -// If you only want post-visits, explicitly turn off preVisit (and inVisit) +// If you only want post-visits, explicitly turn off preVisit (and inVisit) // and turn on postVisit. // -// In general, for the visit*() methods, return true from interior nodes +// In general, for the visit*() methods, return true from interior nodes // to have the traversal continue on to children. // // If you process children yourself, or don't want them processed, return false. diff --git a/deps/glslang/glslang/glslang/MachineIndependent/Initialize.h b/deps/glslang/glslang/glslang/MachineIndependent/Initialize.h index 23f57acc17..a61c6b408a 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/Initialize.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/Initialize.h @@ -67,7 +67,7 @@ public: virtual const TString& getStageString(EShLanguage language) const { return stageBuiltins[language]; } virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable) = 0; - + virtual void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources) = 0; protected: @@ -89,7 +89,7 @@ public: void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage); void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable); - + void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); protected: diff --git a/deps/glslang/glslang/glslang/MachineIndependent/ParseHelper.h b/deps/glslang/glslang/glslang/MachineIndependent/ParseHelper.h index 6234db6095..30f2d9a822 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/ParseHelper.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/ParseHelper.h @@ -449,7 +449,7 @@ protected: // * note, that appropriately gives an error if redeclaring a block that // was already used and hence already copied-up // - // - on seeing a layout declaration that sizes the array, fix everything in the + // - on seeing a layout declaration that sizes the array, fix everything in the // resize-list, giving errors for mismatch // // - on seeing an array size declaration, give errors on mismatch between it and previous diff --git a/deps/glslang/glslang/glslang/MachineIndependent/Scan.h b/deps/glslang/glslang/glslang/MachineIndependent/Scan.h index 67c86d2efe..fe747ef431 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/Scan.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/Scan.h @@ -254,7 +254,7 @@ protected: size_t currentChar; // This is for reporting what string/line an error occurred on, and can be overridden by #line. - // It remembers the last state of each source string as it is left for the next one, so unget() + // It remembers the last state of each source string as it is left for the next one, so unget() // can restore that state. TSourceLoc* loc; // an array diff --git a/deps/glslang/glslang/glslang/MachineIndependent/SymbolTable.h b/deps/glslang/glslang/glslang/MachineIndependent/SymbolTable.h index aeec34fc02..9f5a2e69f5 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/SymbolTable.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/SymbolTable.h @@ -120,7 +120,7 @@ protected: const TString *name; unsigned int uniqueId; // For cross-scope comparing during code generation - // For tracking what extensions must be present + // For tracking what extensions must be present // (don't use if correct version/profile is present). int numExtensions; const char** extensions; // an array of pointers to existing constant char strings @@ -145,7 +145,7 @@ protected: class TVariable : public TSymbol { public: TVariable(const TString *name, const TType& t, bool uT = false ) - : TSymbol(name), + : TSymbol(name), userType(uT), constSubtree(nullptr), anonId(-1) { type.shallowCopy(t); } @@ -191,7 +191,7 @@ protected: struct TParameter { TString *name; TType* type; - void copyParam(const TParameter& param) + void copyParam(const TParameter& param) { if (param.name) name = NewPoolTString(param.name->c_str()); @@ -272,7 +272,7 @@ public: virtual const TAnonMember* getAsAnonMember() const { return this; } virtual const TVariable& getAnonContainer() const { return anonContainer; } virtual unsigned int getMemberNumber() const { return memberNumber; } - + virtual const TType& getType() const { const TTypeList& types = *anonContainer.getType().getStruct(); @@ -285,7 +285,7 @@ public: const TTypeList& types = *anonContainer.getType().getStruct(); return *types[memberNumber].type; } - + virtual int getAnonId() const { return anonId; } virtual void dump(TInfoSink &infoSink) const; @@ -365,7 +365,7 @@ public: TSymbol* find(const TString& name) const { tLevel::const_iterator it = level.find(name); - if (it == level.end()) + if (it == level.end()) return 0; else return (*it).second; @@ -488,7 +488,7 @@ public: while (table.size() > adoptedLevels) pop(0); } - + void adoptLevels(TSymbolTable& symTable) { for (unsigned int level = 0; level < symTable.table.size(); ++level) { @@ -520,7 +520,7 @@ public: void setNoBuiltInRedeclarations() { noBuiltInRedeclarations = true; } void setSeparateNameSpaces() { separateNameSpaces = true; } - + void push() { table.push_back(new TSymbolTableLevel); @@ -546,7 +546,7 @@ public: // make sure there isn't a function of this variable name if (! separateNameSpaces && ! symbol.getAsFunction() && table[currentLevel()]->hasFunctionName(symbol.getName())) return false; - + // check for not overloading or redefining a built-in function if (noBuiltInRedeclarations) { if (atGlobalLevel() && currentLevel() > 0) { @@ -570,7 +570,7 @@ public: // // To allocate an internal temporary, which will need to be uniquely - // identified by the consumer of the AST, but never need to + // identified by the consumer of the AST, but never need to // found by doing a symbol table search by name, hence allowed an // arbitrary name in the symbol with no worry of collision. // @@ -672,7 +672,7 @@ public: for (unsigned int level = 0; level < table.size(); ++level) table[level]->relateToOperator(name, op); } - + void setFunctionExtensions(const char* name, int num, const char* const extensions[]) { for (unsigned int level = 0; level < table.size(); ++level) diff --git a/deps/glslang/glslang/glslang/MachineIndependent/glslang_tab.cpp.h b/deps/glslang/glslang/glslang/MachineIndependent/glslang_tab.cpp.h index b6d27993c9..a3a458bb77 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/glslang_tab.cpp.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/glslang_tab.cpp.h @@ -1,19 +1,19 @@ /* A Bison parser, made by GNU Bison 2.7. */ /* Bison interface for Yacc-like parsers in C - + Copyright (C) 1984, 1989-1990, 2000-2012 Free Software Foundation, Inc. - + 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 3 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, see . */ @@ -26,7 +26,7 @@ special exception, which will cause the skeleton and the resulting Bison output files to be licensed under the GNU General Public License without this special exception. - + This special exception was added by the Free Software Foundation in version 2.2 of Bison. */ diff --git a/deps/glslang/glslang/glslang/MachineIndependent/localintermediate.h b/deps/glslang/glslang/glslang/MachineIndependent/localintermediate.h index 6f6db92d5f..57a2a70353 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/localintermediate.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/localintermediate.h @@ -83,7 +83,7 @@ struct TCall { // A generic 1-D range. struct TRange { TRange(int start, int last) : start(start), last(last) { } - bool overlap(const TRange& rhs) const + bool overlap(const TRange& rhs) const { return last >= rhs.start && start <= rhs.last; } @@ -188,7 +188,7 @@ public: bool getFlattenUniformArrays() const { return flattenUniformArrays; } void setNoStorageFormat(bool b) { useUnknownFormat = b; } bool getNoStorageFormat() const { return useUnknownFormat; } - + void setVersion(int v) { version = v; } int getVersion() const { return version; } void setProfile(EProfile p) { profile = p; } @@ -269,7 +269,7 @@ public: void addSymbolLinkageNodes(TIntermAggregate*& linkage, EShLanguage, TSymbolTable&); void addSymbolLinkageNode(TIntermAggregate*& linkage, const TSymbol&); - bool setInvocations(int i) + bool setInvocations(int i) { if (invocations != TQualifier::layoutNotSet) return invocations == i; @@ -311,7 +311,7 @@ public: TVertexOrder getVertexOrder() const { return vertexOrder; } void setPointMode() { pointMode = true; } bool getPointMode() const { return pointMode; } - + bool setLocalSize(int dim, int size) { if (localSize[dim] > 1) @@ -406,7 +406,7 @@ protected: bool promoteBinary(TIntermBinary&); void addSymbolLinkageNode(TIntermAggregate*& linkage, TSymbolTable&, const TString&); bool promoteAggregate(TIntermAggregate&); - + const EShLanguage language; // stage, known at construction time EShSource source; // source language, known a bit later std::string entryPointName; diff --git a/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpContext.h b/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpContext.h index 013c90e567..f1c2f31108 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpContext.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpContext.h @@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses express or implied, are granted by NVIDIA herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the NVIDIA Software may be -incorporated. No hardware is licensed hereunder. +incorporated. No hardware is licensed hereunder. THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, @@ -94,7 +94,7 @@ class TPpToken { public: TPpToken() : token(0), space(false), ival(0), dval(0.0), atom(0) { - loc.init(); + loc.init(); name[0] = 0; } @@ -239,7 +239,7 @@ protected: static const int maxMacroArgs = 64; static const int maxIfNesting = 64; - int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor) + int ifdepth; // current #if-#else-#endif nesting in the cpp.c file (pre-processor) bool elseSeen[maxIfNesting]; // Keep a track of whether an else has been seen at a particular depth int elsetracker; // #if-#else and #endif constructs...Counter. @@ -301,11 +301,11 @@ protected: int extraTokenCheck(int atom, TPpToken* ppToken, int token); int eval(int token, int precedence, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); int evalToToken(int token, bool shortCircuit, int& res, bool& err, TPpToken * ppToken); - int CPPif (TPpToken * ppToken); + int CPPif (TPpToken * ppToken); int CPPifdef(int defined, TPpToken * ppToken); int CPPinclude(TPpToken * ppToken); - int CPPline(TPpToken * ppToken); - int CPPerror(TPpToken * ppToken); + int CPPline(TPpToken * ppToken); + int CPPerror(TPpToken * ppToken); int CPPpragma(TPpToken * ppToken); int CPPversion(TPpToken * ppToken); int CPPextension(TPpToken * ppToken); @@ -331,7 +331,7 @@ protected: int ReadToken(TokenStream* pTok, TPpToken* ppToken); void pushTokenStreamInput(TokenStream *ts); void UngetToken(int token, TPpToken* ppToken); - + class tTokenInput : public tInput { public: tTokenInput(TPpContext* pp, TokenStream* t) : tInput(pp), tokens(t) { } @@ -387,7 +387,7 @@ protected: return '\\'; } while (ch == '\\'); } - + // handle any non-escaped newline if (ch == '\r' || ch == '\n') { if (ch == '\r' && input->peek() == '\n') @@ -432,7 +432,7 @@ protected: TInputScanner* input; }; - // Holds a reference to included file data, as well as a + // Holds a reference to included file data, as well as a // prologue and an epilogue string. This can be scanned using the tInput // interface and acts as a single source string. class TokenizableIncludeFile : public tInput { diff --git a/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h b/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h index c84431d368..2d231e1d2d 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/preprocessor/PpTokens.h @@ -56,7 +56,7 @@ Except as expressly stated in this notice, no other rights or licenses express or implied, are granted by NVIDIA herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the NVIDIA Software may be -incorporated. No hardware is licensed hereunder. +incorporated. No hardware is licensed hereunder. THE NVIDIA SOFTWARE IS BEING PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, @@ -128,7 +128,7 @@ enum EFixedAtoms { #endif PpAtomConstString, - // Identifiers + // Identifiers PpAtomIdentifier, // preprocessor "keywords" diff --git a/deps/glslang/glslang/glslang/MachineIndependent/reflection.h b/deps/glslang/glslang/glslang/MachineIndependent/reflection.h index 13f5177c0f..b6bf4a9b02 100644 --- a/deps/glslang/glslang/glslang/MachineIndependent/reflection.h +++ b/deps/glslang/glslang/glslang/MachineIndependent/reflection.h @@ -55,7 +55,7 @@ class TReflectionTraverser; // Data needed for just a single object at the granularity exchanged by the reflection API class TObjectReflection { public: - TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : + TObjectReflection(const TString& pName, const TType& pType, int pOffset, int pGLDefineType, int pSize, int pIndex) : name(pName), type(pType.clone()), offset(pOffset), glDefineType(pGLDefineType), size(pSize), index(pIndex) { } @@ -107,7 +107,7 @@ public: // for mapping a block index to the block's description int getNumUniformBlocks() const { return (int)indexToUniformBlock.size(); } - const TObjectReflection& getUniformBlock(int i) const + const TObjectReflection& getUniformBlock(int i) const { if (i >= 0 && i < (int)indexToUniformBlock.size()) return indexToUniformBlock[i]; @@ -126,7 +126,7 @@ public: } // for mapping any name to its index (block names, uniform names and attribute names) - int getIndex(const char* name) const + int getIndex(const char* name) const { TNameToIndex::const_iterator it = nameToIndex.find(name); if (it == nameToIndex.end()) diff --git a/deps/glslang/glslang/glslang/Public/ShaderLang.h b/deps/glslang/glslang/glslang/Public/ShaderLang.h index afdc7d1eb2..4e4d695c69 100644 --- a/deps/glslang/glslang/glslang/Public/ShaderLang.h +++ b/deps/glslang/glslang/glslang/Public/ShaderLang.h @@ -165,9 +165,9 @@ typedef struct { // // ShHandle held by but opaque to the driver. It is allocated, -// managed, and de-allocated by the compiler/linker. It's contents +// managed, and de-allocated by the compiler/linker. It's contents // are defined by and used by the compiler and linker. For example, -// symbol table information and object code passed from the compiler +// symbol table information and object code passed from the compiler // to the linker can be stored where ShHandle points. // // If handle creation fails, 0 will be returned. @@ -187,7 +187,7 @@ SH_IMPORT_EXPORT void ShDestruct(ShHandle); // The return value of ShCompile is boolean, non-zero indicating // success. // -// The info-log should be written by ShCompile into +// The info-log should be written by ShCompile into // ShHandle, so it can answer future queries. // SH_IMPORT_EXPORT int ShCompile( @@ -251,8 +251,8 @@ SH_IMPORT_EXPORT int ShGetUniformLocation(const ShHandle uniformMap, const char* // ----------------------------------- // // Below is a new alternate C++ interface that might potentially replace the above -// opaque handle-based interface. -// +// opaque handle-based interface. +// // The below is further designed to handle multiple compilation units per stage, where // the intermediate results, including the parse tree, are preserved until link time, // rather than the above interface which is designed to have each compilation unit @@ -513,7 +513,7 @@ public: const char *getAttributeName(int index) const; // can be used for glGetActiveAttrib() int getAttributeType(int index) const; // can be used for glGetActiveAttrib() const TType* getUniformTType(int index) const; // returns a TType* - const TType* getUniformBlockTType(int index) const; // returns a TType* + const TType* getUniformBlockTType(int index) const; // returns a TType* const TType* getAttributeTType(int index) const; // returns a TType* void dumpReflection(); diff --git a/deps/glslang/glslang/gtests/TestFixture.h b/deps/glslang/glslang/gtests/TestFixture.h index e795e8dc90..8aee0cf88e 100644 --- a/deps/glslang/glslang/gtests/TestFixture.h +++ b/deps/glslang/glslang/gtests/TestFixture.h @@ -258,7 +258,7 @@ public: glslang::TProgram program; program.addShader(&shader); - + success &= program.link(controls); success &= program.mapIO(); @@ -330,7 +330,7 @@ public: std::vector spirv_binary(code); // scratch copy spv::spirvbin_t(0 /*verbosity*/).remap(spirv_binary, remapOptions); - + std::ostringstream disassembly_stream; spv::Parameterize(); spv::Disassemble(disassembly_stream, spirv_binary); diff --git a/deps/glslang/glslang/hlsl/hlslGrammar.h b/deps/glslang/glslang/hlsl/hlslGrammar.h index 8804b217ec..ad124cb755 100755 --- a/deps/glslang/glslang/hlsl/hlslGrammar.h +++ b/deps/glslang/glslang/hlsl/hlslGrammar.h @@ -44,7 +44,7 @@ namespace glslang { class TAttributeMap; // forward declare - + // Should just be the grammar aspect of HLSL. // Described in more detail in hlslGrammar.cpp. diff --git a/deps/glslang/glslang/hlsl/hlslParseHelper.h b/deps/glslang/glslang/hlsl/hlslParseHelper.h index 206df9b887..1de4f36d03 100755 --- a/deps/glslang/glslang/hlsl/hlslParseHelper.h +++ b/deps/glslang/glslang/hlsl/hlslParseHelper.h @@ -263,7 +263,7 @@ protected: // * note, that appropriately gives an error if redeclaring a block that // was already used and hence already copied-up // - // - on seeing a layout declaration that sizes the array, fix everything in the + // - on seeing a layout declaration that sizes the array, fix everything in the // resize-list, giving errors for mismatch // // - on seeing an array size declaration, give errors on mismatch between it and previous diff --git a/deps/glslang/glslang/hlsl/hlslParseables.h b/deps/glslang/glslang/hlsl/hlslParseables.h index c837590030..3c93b178e6 100755 --- a/deps/glslang/glslang/hlsl/hlslParseables.h +++ b/deps/glslang/glslang/hlsl/hlslParseables.h @@ -52,7 +52,7 @@ public: void initialize(const TBuiltInResource& resources, int version, EProfile, const SpvVersion& spvVersion, EShLanguage); void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable); - + void identifyBuiltIns(int version, EProfile profile, const SpvVersion& spvVersion, EShLanguage language, TSymbolTable& symbolTable, const TBuiltInResource &resources); private: diff --git a/deps/glslang/glslang/hlsl/hlslTokens.h b/deps/glslang/glslang/hlsl/hlslTokens.h index 6902070cbe..cfa63b7cfe 100755 --- a/deps/glslang/glslang/hlsl/hlslTokens.h +++ b/deps/glslang/glslang/hlsl/hlslTokens.h @@ -247,7 +247,7 @@ enum EHlslTokenClass { EHTokRWTexture2darray, EHTokRWTexture3d, EHTokRWBuffer, - + // variable, user type, ... EHTokIdentifier, diff --git a/deps/ibxm/ibxm.c b/deps/ibxm/ibxm.c index 526cfd6875..2097cedc12 100644 --- a/deps/ibxm/ibxm.c +++ b/deps/ibxm/ibxm.c @@ -1,1922 +1,1922 @@ - -#include "stdlib.h" -#include "string.h" - -#include "ibxm.h" - -const char *IBXM_VERSION = "ibxm/ac mod/xm/s3m replay 20170901 (c)mumart@gmail.com"; - -static const int FP_SHIFT = 15, FP_ONE = 32768, FP_MASK = 32767; - -static const int exp2_table[] = { - 32768, 32946, 33125, 33305, 33486, 33667, 33850, 34034, - 34219, 34405, 34591, 34779, 34968, 35158, 35349, 35541, - 35734, 35928, 36123, 36319, 36516, 36715, 36914, 37114, - 37316, 37518, 37722, 37927, 38133, 38340, 38548, 38757, - 38968, 39180, 39392, 39606, 39821, 40037, 40255, 40473, - 40693, 40914, 41136, 41360, 41584, 41810, 42037, 42265, - 42495, 42726, 42958, 43191, 43425, 43661, 43898, 44137, - 44376, 44617, 44859, 45103, 45348, 45594, 45842, 46091, - 46341, 46593, 46846, 47100, 47356, 47613, 47871, 48131, - 48393, 48655, 48920, 49185, 49452, 49721, 49991, 50262, - 50535, 50810, 51085, 51363, 51642, 51922, 52204, 52488, - 52773, 53059, 53347, 53637, 53928, 54221, 54515, 54811, - 55109, 55408, 55709, 56012, 56316, 56622, 56929, 57238, - 57549, 57861, 58176, 58491, 58809, 59128, 59449, 59772, - 60097, 60423, 60751, 61081, 61413, 61746, 62081, 62419, - 62757, 63098, 63441, 63785, 64132, 64480, 64830, 65182, - 65536 -}; - -static const short sine_table[] = { - 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, - 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24 -}; - -struct note { - unsigned char key, instrument, volume, effect, param; -}; - -struct channel { - struct replay *replay; - struct instrument *instrument; - struct sample *sample; - struct note note; - int id, key_on, random_seed, pl_row; - int sample_off, sample_idx, sample_fra, freq, ampl, pann; - int volume, panning, fadeout_vol, vol_env_tick, pan_env_tick; - int period, porta_period, retrig_count, fx_count, av_count; - int porta_up_param, porta_down_param, tone_porta_param, offset_param; - int fine_porta_up_param, fine_porta_down_param, xfine_porta_param; - int arpeggio_param, vol_slide_param, gvol_slide_param, pan_slide_param; - int fine_vslide_up_param, fine_vslide_down_param; - int retrig_volume, retrig_ticks, tremor_on_ticks, tremor_off_ticks; - int vibrato_type, vibrato_phase, vibrato_speed, vibrato_depth; - int tremolo_type, tremolo_phase, tremolo_speed, tremolo_depth; - int tremolo_add, vibrato_add, arpeggio_add; -}; - -struct replay { - int sample_rate, interpolation, global_vol; - int seq_pos, break_pos, row, next_row, tick; - int speed, tempo, pl_count, pl_chan; - int *ramp_buf; - char **play_count; - struct channel *channels; - struct module *module; -}; - -static int exp_2( int x ) { - int c, m, y; - int x0 = ( x & FP_MASK ) >> ( FP_SHIFT - 7 ); - c = exp2_table[ x0 ]; - m = exp2_table[ x0 + 1 ] - c; - y = ( m * ( x & ( FP_MASK >> 7 ) ) >> 8 ) + c; - return ( y << FP_SHIFT ) >> ( FP_SHIFT - ( x >> FP_SHIFT ) ); -} - -static int log_2( int x ) { - int step; - int y = 16 << FP_SHIFT; - for( step = y; step > 0; step >>= 1 ) { - if( exp_2( y - step ) >= x ) { - y -= step; - } - } - return y; -} - -static char* data_ascii( struct data *data, int offset, int length, char *dest ) { - int idx, chr; - memset( dest, 32, length ); - if( offset > data->length ) { - offset = data->length; - } - if( ( unsigned int ) offset + length > ( unsigned int ) data->length ) { - length = data->length - offset; - } - for( idx = 0; idx < length; idx++ ) { - chr = data->buffer[ offset + idx ] & 0xFF; - if( chr > 32 ) { - dest[ idx ] = chr; - } - } - return dest; -} - -static int data_s8( struct data *data, int offset ) { - int value = 0; - if( offset < data->length ) { - value = data->buffer[ offset ]; - value = ( value & 0x7F ) - ( value & 0x80 ); - } - return value; -} - -static int data_u8( struct data *data, int offset ) { - int value = 0; - if( offset < data->length ) { - value = data->buffer[ offset ] & 0xFF; - } - return value; -} - -static int data_u16be( struct data *data, int offset ) { - int value = 0; - if( offset + 1 < data->length ) { - value = ( ( data->buffer[ offset ] & 0xFF ) << 8 ) - | ( data->buffer[ offset + 1 ] & 0xFF ); - } - return value; -} - -static int data_u16le( struct data *data, int offset ) { - int value = 0; - if( offset + 1 < data->length ) { - value = ( data->buffer[ offset ] & 0xFF ) - | ( ( data->buffer[ offset + 1 ] & 0xFF ) << 8 ); - } - return value; -} - -static unsigned int data_u32le( struct data *data, int offset ) { - unsigned int value = 0; - if( offset + 3 < data->length ) { - value = ( data->buffer[ offset ] & 0xFF ) - | ( ( data->buffer[ offset + 1 ] & 0xFF ) << 8 ) - | ( ( data->buffer[ offset + 2 ] & 0xFF ) << 16 ) - | ( ( data->buffer[ offset + 3 ] & 0xFF ) << 24 ); - } - return value; -} - -static void data_sam_s8( struct data *data, int offset, int count, short *dest ) { - int idx, amp, length = data->length; - char *buffer = data->buffer; - if( offset > length ) { - offset = length; - } - if( offset + count > length ) { - count = length - offset; - } - for( idx = 0; idx < count; idx++ ) { - amp = ( buffer[ offset + idx ] & 0xFF ) << 8; - dest[ idx ] = ( amp & 0x7FFF ) - ( amp & 0x8000 ); - } -} - -static void data_sam_s16le( struct data *data, int offset, int count, short *dest ) { - int idx, amp, length = data->length; - char *buffer = data->buffer; - if( offset > length ) { - offset = length; - } - if( offset + count * 2 > length ) { - count = ( length - offset ) / 2; - } - for( idx = 0; idx < count; idx++ ) { - amp = ( buffer[ offset + idx * 2 ] & 0xFF ) | ( buffer[ offset + idx * 2 + 1 ] << 8 ); - dest[ idx ] = ( amp & 0x7FFF ) - ( amp & 0x8000 ); - } -} - -static int envelope_next_tick( struct envelope *envelope, int tick, int key_on ) { - tick++; - if( envelope->looped && tick >= envelope->loop_end_tick ) { - tick = envelope->loop_start_tick; - } - if( envelope->sustain && key_on && tick >= envelope->sustain_tick ) { - tick = envelope->sustain_tick; - } - return tick; -} - -static int envelope_calculate_ampl( struct envelope *envelope, int tick ) { - int idx, point, dt, da; - int ampl = envelope->points_ampl[ envelope->num_points - 1 ]; - if( tick < envelope->points_tick[ envelope->num_points - 1 ] ) { - point = 0; - for( idx = 1; idx < envelope->num_points; idx++ ) { - if( envelope->points_tick[ idx ] <= tick ) { - point = idx; - } - } - dt = envelope->points_tick[ point + 1 ] - envelope->points_tick[ point ]; - da = envelope->points_ampl[ point + 1 ] - envelope->points_ampl[ point ]; - ampl = envelope->points_ampl[ point ]; - ampl += ( ( da << 24 ) / dt ) * ( tick - envelope->points_tick[ point ] ) >> 24; - } - return ampl; -} - -static void sample_ping_pong( struct sample *sample ) { - int idx; - int loop_start = sample->loop_start; - int loop_length = sample->loop_length; - int loop_end = loop_start + loop_length; - short *sample_data = sample->data; - short *new_data = (short*)calloc( loop_end + loop_length + 1, sizeof( short ) ); - if( new_data ) { - memcpy( new_data, sample_data, loop_end * sizeof( short ) ); - for( idx = 0; idx < loop_length; idx++ ) { - new_data[ loop_end + idx ] = sample_data[ loop_end - idx - 1 ]; - } - free( sample->data ); - sample->data = new_data; - sample->loop_length *= 2; - sample->data[ loop_start + sample->loop_length ] = sample->data[ loop_start ]; - } -} - -/* Deallocate the specified module. */ -void dispose_module( struct module *module ) { - int idx, sam; - struct instrument *instrument; - free( module->default_panning ); - free( module->sequence ); - if( module->patterns ) { - for( idx = 0; idx < module->num_patterns; idx++ ) { - free( module->patterns[ idx ].data ); - } - free( module->patterns ); - } - if( module->instruments ) { - for( idx = 0; idx <= module->num_instruments; idx++ ) { - instrument = &module->instruments[ idx ]; - if( instrument->samples ) { - for( sam = 0; sam < instrument->num_samples; sam++ ) { - free( instrument->samples[ sam ].data ); - } - free( instrument->samples ); - } - } - free( module->instruments ); - } - free( module ); -} - -static struct module* module_load_xm( struct data *data, char *message ) { - int delta_env, offset, next_offset, idx, entry; - int num_rows, num_notes, pat_data_len, pat_data_offset; - int sam, sam_head_offset, sam_data_bytes, sam_data_samples; - int num_samples, sam_loop_start, sam_loop_length, amp; - int note, flags, key, ins, vol, fxc, fxp; - int point, point_tick, point_offset; - int looped, ping_pong, sixteen_bit; - char ascii[ 16 ], *pattern_data; - struct instrument *instrument; - struct sample *sample; - struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); - if( module ) { - if( data_u16le( data, 58 ) != 0x0104 ) { - strcpy( message, "XM format version must be 0x0104!" ); - dispose_module( module ); - return NULL; - } - data_ascii( data, 17, 20, module->name ); - delta_env = !memcmp( data_ascii( data, 38, 15, ascii ), "DigiBooster Pro", 15 ); - offset = 60 + data_u32le( data, 60 ); - module->sequence_len = data_u16le( data, 64 ); - module->restart_pos = data_u16le( data, 66 ); - module->num_channels = data_u16le( data, 68 ); - module->num_patterns = data_u16le( data, 70 ); - module->num_instruments = data_u16le( data, 72 ); - module->linear_periods = data_u16le( data, 74 ) & 0x1; - module->default_gvol = 64; - module->default_speed = data_u16le( data, 76 ); - module->default_tempo = data_u16le( data, 78 ); - module->c2_rate = 8363; - module->gain = 64; - module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); - if( !module->default_panning ) { - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->num_channels; idx++ ) { - module->default_panning[ idx ] = 128; - } - module->sequence = (unsigned char*)calloc( module->sequence_len, sizeof( unsigned char ) ); - if( !module->sequence ) { - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->sequence_len; idx++ ) { - entry = data_u8( data, 80 + idx ); - module->sequence[ idx ] = entry < module->num_patterns ? entry : 0; - } - module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); - if( !module->patterns ) { - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->num_patterns; idx++ ) { - if( data_u8( data, offset + 4 ) ) { - strcpy( message, "Unknown pattern packing type!" ); - dispose_module( module ); - return NULL; - } - num_rows = data_u16le( data, offset + 5 ); - if( num_rows < 1 ) { - num_rows = 1; - } - pat_data_len = data_u16le( data, offset + 7 ); - offset += data_u32le( data, offset ); - next_offset = offset + pat_data_len; - num_notes = num_rows * module->num_channels; - pattern_data = (char*)calloc( num_notes, 5 ); - if( !pattern_data ) { - dispose_module( module ); - return NULL; - } - module->patterns[ idx ].num_channels = module->num_channels; - module->patterns[ idx ].num_rows = num_rows; - module->patterns[ idx ].data = pattern_data; - if( pat_data_len > 0 ) { - pat_data_offset = 0; - for( note = 0; note < num_notes; note++ ) { - flags = data_u8( data, offset ); - if( ( flags & 0x80 ) == 0 ) { - flags = 0x1F; - } else { - offset++; - } - key = ( flags & 0x01 ) > 0 ? data_u8( data, offset++ ) : 0; - pattern_data[ pat_data_offset++ ] = key; - ins = ( flags & 0x02 ) > 0 ? data_u8( data, offset++ ) : 0; - pattern_data[ pat_data_offset++ ] = ins; - vol = ( flags & 0x04 ) > 0 ? data_u8( data, offset++ ) : 0; - pattern_data[ pat_data_offset++ ] = vol; - fxc = ( flags & 0x08 ) > 0 ? data_u8( data, offset++ ) : 0; - fxp = ( flags & 0x10 ) > 0 ? data_u8( data, offset++ ) : 0; - if( fxc >= 0x40 ) { - fxc = fxp = 0; - } - pattern_data[ pat_data_offset++ ] = fxc; - pattern_data[ pat_data_offset++ ] = fxp; - } - } - offset = next_offset; - } - module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); - if( !module->instruments ) { - dispose_module( module ); - return NULL; - } - instrument = &module->instruments[ 0 ]; - instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - for( ins = 1; ins <= module->num_instruments; ins++ ) { - instrument = &module->instruments[ ins ]; - data_ascii( data, offset + 4, 22, instrument->name ); - num_samples = data_u16le( data, offset + 27 ); - instrument->num_samples = ( num_samples > 0 ) ? num_samples : 1; - instrument->samples = (struct sample*)calloc( instrument->num_samples, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - if( num_samples > 0 ) { - for( key = 0; key < 96; key++ ) { - instrument->key_to_sample[ key + 1 ] = data_u8( data, offset + 33 + key ); - } - point_tick = 0; - for( point = 0; point < 12; point++ ) { - point_offset = offset + 129 + ( point * 4 ); - point_tick = ( delta_env ? point_tick : 0 ) + data_u16le( data, point_offset ); - instrument->vol_env.points_tick[ point ] = point_tick; - instrument->vol_env.points_ampl[ point ] = data_u16le( data, point_offset + 2 ); - } - point_tick = 0; - for( point = 0; point < 12; point++ ) { - point_offset = offset + 177 + ( point * 4 ); - point_tick = ( delta_env ? point_tick : 0 ) + data_u16le( data, point_offset ); - instrument->pan_env.points_tick[ point ] = point_tick; - instrument->pan_env.points_ampl[ point ] = data_u16le( data, point_offset + 2 ); - } - instrument->vol_env.num_points = data_u8( data, offset + 225 ); - if( instrument->vol_env.num_points > 12 ) { - instrument->vol_env.num_points = 0; - } - instrument->pan_env.num_points = data_u8( data, offset + 226 ); - if( instrument->pan_env.num_points > 12 ) { - instrument->pan_env.num_points = 0; - } - instrument->vol_env.sustain_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 227 ) & 0xF ]; - instrument->vol_env.loop_start_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 228 ) & 0xF ]; - instrument->vol_env.loop_end_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 229 ) & 0xF ]; - instrument->pan_env.sustain_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 230 ) & 0xF ]; - instrument->pan_env.loop_start_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 231 ) & 0xF ]; - instrument->pan_env.loop_end_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 232 ) & 0xF ]; - instrument->vol_env.enabled = instrument->vol_env.num_points > 0 && ( data_u8( data, offset + 233 ) & 0x1 ); - instrument->vol_env.sustain = ( data_u8( data, offset + 233 ) & 0x2 ) > 0; - instrument->vol_env.looped = ( data_u8( data, offset + 233 ) & 0x4 ) > 0; - instrument->pan_env.enabled = instrument->pan_env.num_points > 0 && ( data_u8( data, offset + 234 ) & 0x1 ); - instrument->pan_env.sustain = ( data_u8( data, offset + 234 ) & 0x2 ) > 0; - instrument->pan_env.looped = ( data_u8( data, offset + 234 ) & 0x4 ) > 0; - instrument->vib_type = data_u8( data, offset + 235 ); - instrument->vib_sweep = data_u8( data, offset + 236 ); - instrument->vib_depth = data_u8( data, offset + 237 ); - instrument->vib_rate = data_u8( data, offset + 238 ); - instrument->vol_fadeout = data_u16le( data, offset + 239 ); - } - offset += data_u32le( data, offset ); - sam_head_offset = offset; - offset += num_samples * 40; - for( sam = 0; sam < num_samples; sam++ ) { - sample = &instrument->samples[ sam ]; - sam_data_bytes = data_u32le( data, sam_head_offset ); - sam_loop_start = data_u32le( data, sam_head_offset + 4 ); - sam_loop_length = data_u32le( data, sam_head_offset + 8 ); - sample->volume = data_u8( data, sam_head_offset + 12 ); - sample->fine_tune = data_s8( data, sam_head_offset + 13 ); - looped = ( data_u8( data, sam_head_offset + 14 ) & 0x3 ) > 0; - ping_pong = ( data_u8( data, sam_head_offset + 14 ) & 0x2 ) > 0; - sixteen_bit = ( data_u8( data, sam_head_offset + 14 ) & 0x10 ) > 0; - sample->panning = data_u8( data, sam_head_offset + 15 ) + 1; - sample->rel_note = data_s8( data, sam_head_offset + 16 ); - data_ascii( data, sam_head_offset + 18, 22, sample->name ); - sam_head_offset += 40; - sam_data_samples = sam_data_bytes; - if( sixteen_bit ) { - sam_data_samples = sam_data_samples >> 1; - sam_loop_start = sam_loop_start >> 1; - sam_loop_length = sam_loop_length >> 1; - } - if( !looped || ( sam_loop_start + sam_loop_length ) > sam_data_samples ) { - sam_loop_start = sam_data_samples; - sam_loop_length = 0; - } - sample->loop_start = sam_loop_start; - sample->loop_length = sam_loop_length; - sample->data = (short*)calloc( sam_data_samples + 1, sizeof( short ) ); - if( sample->data ) { - if( sixteen_bit ) { - data_sam_s16le( data, offset, sam_data_samples, sample->data ); - } else { - data_sam_s8( data, offset, sam_data_samples, sample->data ); - } - amp = 0; - for( idx = 0; idx < sam_data_samples; idx++ ) { - amp = amp + sample->data[ idx ]; - amp = ( amp & 0x7FFF ) - ( amp & 0x8000 ); - sample->data[ idx ] = amp; - } - sample->data[ sam_loop_start + sam_loop_length ] = sample->data[ sam_loop_start ]; - if( ping_pong ) { - sample_ping_pong( sample ); - } - } else { - dispose_module( module ); - return NULL; - } - offset += sam_data_bytes; - } - } - } - return module; -} - -static struct module* module_load_s3m( struct data *data, char *message ) { - int idx, module_data_idx, inst_offset, flags; - int version, sixteen_bit, tune, signed_samples; - int stereo_mode, default_pan, channel_map[ 32 ]; - int sample_offset, sample_length, loop_start, loop_length; - int pat_offset, note_offset, row, chan, token; - int key, ins, volume, effect, param, panning; - char *pattern_data; - struct instrument *instrument; - struct sample *sample; - struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); - if( module ) { - data_ascii( data, 0, 28, module->name ); - module->sequence_len = data_u16le( data, 32 ); - module->num_instruments = data_u16le( data, 34 ); - module->num_patterns = data_u16le( data, 36 ); - flags = data_u16le( data, 38 ); - version = data_u16le( data, 40 ); - module->fast_vol_slides = ( ( flags & 0x40 ) == 0x40 ) || version == 0x1300; - signed_samples = data_u16le( data, 42 ) == 1; - if( data_u32le( data, 44 ) != 0x4d524353 ) { - strcpy( message, "Not an S3M file!" ); - dispose_module( module ); - return NULL; - } - module->default_gvol = data_u8( data, 48 ); - module->default_speed = data_u8( data, 49 ); - module->default_tempo = data_u8( data, 50 ); - module->c2_rate = 8363; - module->gain = data_u8( data, 51 ) & 0x7F; - stereo_mode = ( data_u8( data, 51 ) & 0x80 ) == 0x80; - default_pan = data_u8( data, 53 ) == 0xFC; - for( idx = 0; idx < 32; idx++ ) { - channel_map[ idx ] = -1; - if( data_u8( data, 64 + idx ) < 16 ) { - channel_map[ idx ] = module->num_channels++; - } - } - module->sequence = (unsigned char*)calloc( module->sequence_len, sizeof( unsigned char ) ); - if( !module->sequence ){ - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->sequence_len; idx++ ) { - module->sequence[ idx ] = data_u8( data, 96 + idx ); - } - module_data_idx = 96 + module->sequence_len; - module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); - if( !module->instruments ) { - dispose_module( module ); - return NULL; - } - instrument = &module->instruments[ 0 ]; - instrument->num_samples = 1; - instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - for( ins = 1; ins <= module->num_instruments; ins++ ) { - instrument = &module->instruments[ ins ]; - instrument->num_samples = 1; - instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - sample = &instrument->samples[ 0 ]; - inst_offset = data_u16le( data, module_data_idx ) << 4; - module_data_idx += 2; - data_ascii( data, inst_offset + 48, 28, instrument->name ); - if( data_u8( data, inst_offset ) == 1 && data_u16le( data, inst_offset + 76 ) == 0x4353 ) { - sample_offset = ( data_u8( data, inst_offset + 13 ) << 20 ) - + ( data_u16le( data, inst_offset + 14 ) << 4 ); - sample_length = data_u32le( data, inst_offset + 16 ); - loop_start = data_u32le( data, inst_offset + 20 ); - loop_length = data_u32le( data, inst_offset + 24 ) - loop_start; - sample->volume = data_u8( data, inst_offset + 28 ); - if( data_u8( data, inst_offset + 30 ) != 0 ) { - strcpy( message, "Packed samples not supported!" ); - dispose_module( module ); - return NULL; - } - if( loop_start + loop_length > sample_length ) { - loop_length = sample_length - loop_start; - } - if( loop_length < 1 || !( data_u8( data, inst_offset + 31 ) & 0x1 ) ) { - loop_start = sample_length; - loop_length = 0; - } - sample->loop_start = loop_start; - sample->loop_length = loop_length; - /* stereo = data_u8( data, inst_offset + 31 ) & 0x2; */ - sixteen_bit = data_u8( data, inst_offset + 31 ) & 0x4; - tune = ( log_2( data_u32le( data, inst_offset + 32 ) ) - log_2( module->c2_rate ) ) * 12; - sample->rel_note = tune >> FP_SHIFT; - sample->fine_tune = ( tune & FP_MASK ) >> ( FP_SHIFT - 7 ); - sample->data = (short*)calloc( sample_length + 1, sizeof( short ) ); - if( sample->data ) { - if( sixteen_bit ) { - data_sam_s16le( data, sample_offset, sample_length, sample->data ); - } else { - data_sam_s8( data, sample_offset, sample_length, sample->data ); - } - if( !signed_samples ) { - for( idx = 0; idx < sample_length; idx++ ) { - sample->data[ idx ] = ( sample->data[ idx ] & 0xFFFF ) - 32768; - } - } - sample->data[ loop_start + loop_length ] = sample->data[ loop_start ]; - } else { - dispose_module( module ); - return NULL; - } - } - } - module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); - if( !module->patterns ) { - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->num_patterns; idx++ ) { - module->patterns[ idx ].num_channels = module->num_channels; - module->patterns[ idx ].num_rows = 64; - pattern_data = (char*)calloc( module->num_channels * 64, 5 ); - if( !pattern_data ) { - dispose_module( module ); - return NULL; - } - module->patterns[ idx ].data = pattern_data; - pat_offset = ( data_u16le( data, module_data_idx ) << 4 ) + 2; - row = 0; - while( row < 64 ) { - token = data_u8( data, pat_offset++ ); - if( token ) { - key = ins = 0; - if( ( token & 0x20 ) == 0x20 ) { - /* Key + Instrument.*/ - key = data_u8( data, pat_offset++ ); - ins = data_u8( data, pat_offset++ ); - if( key < 0xFE ) { - key = ( key >> 4 ) * 12 + ( key & 0xF ) + 1; - } else if( key == 0xFF ) { - key = 0; - } - } - volume = 0; - if( ( token & 0x40 ) == 0x40 ) { - /* Volume Column.*/ - volume = ( data_u8( data, pat_offset++ ) & 0x7F ) + 0x10; - if( volume > 0x50 ) { - volume = 0; - } - } - effect = param = 0; - if( ( token & 0x80 ) == 0x80 ) { - /* Effect + Param.*/ - effect = data_u8( data, pat_offset++ ); - param = data_u8( data, pat_offset++ ); - if( effect < 1 || effect >= 0x40 ) { - effect = param = 0; - } else if( effect > 0 ) { - effect += 0x80; - } - } - chan = channel_map[ token & 0x1F ]; - if( chan >= 0 ) { - note_offset = ( row * module->num_channels + chan ) * 5; - pattern_data[ note_offset ] = key; - pattern_data[ note_offset + 1 ] = ins; - pattern_data[ note_offset + 2 ] = volume; - pattern_data[ note_offset + 3 ] = effect; - pattern_data[ note_offset + 4 ] = param; - } - } else { - row++; - } - } - module_data_idx += 2; - } - module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); - if( module->default_panning ) { - for( chan = 0; chan < 32; chan++ ) { - if( channel_map[ chan ] >= 0 ) { - panning = 7; - if( stereo_mode ) { - panning = 12; - if( data_u8( data, 64 + chan ) < 8 ) { - panning = 3; - } - } - if( default_pan ) { - flags = data_u8( data, module_data_idx + chan ); - if( ( flags & 0x20 ) == 0x20 ) { - panning = flags & 0xF; - } - } - module->default_panning[ channel_map[ chan ] ] = panning * 17; - } - } - } else { - dispose_module( module ); - return NULL; - } - } - return module; -} - -static struct module* module_load_mod( struct data *data, char *message ) { - int idx, pat, module_data_idx, pat_data_len, pat_data_idx; - int period, key, ins, effect, param, fine_tune; - int sample_length, loop_start, loop_length; - char *pattern_data; - struct instrument *instrument; - struct sample *sample; - struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); - if( module ) { - data_ascii( data, 0, 20, module->name ); - module->sequence_len = data_u8( data, 950 ) & 0x7F; - module->restart_pos = data_u8( data, 951 ) & 0x7F; - if( module->restart_pos >= module->sequence_len ) { - module->restart_pos = 0; - } - module->sequence = (unsigned char*)calloc( 128, sizeof( unsigned char ) ); - if( !module->sequence ){ - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < 128; idx++ ) { - pat = data_u8( data, 952 + idx ) & 0x7F; - module->sequence[ idx ] = pat; - if( pat >= module->num_patterns ) { - module->num_patterns = pat + 1; - } - } - switch( data_u16be( data, 1082 ) ) { - case 0x4b2e: /* M.K. */ - case 0x4b21: /* M!K! */ - case 0x5434: /* FLT4 */ - module->num_channels = 4; - module->c2_rate = 8287; - module->gain = 64; - break; - case 0x484e: /* xCHN */ - module->num_channels = data_u8( data, 1080 ) - 48; - module->c2_rate = 8363; - module->gain = 32; - break; - case 0x4348: /* xxCH */ - module->num_channels = ( data_u8( data, 1080 ) - 48 ) * 10; - module->num_channels += data_u8( data, 1081 ) - 48; - module->c2_rate = 8363; - module->gain = 32; - break; - default: - strcpy( message, "MOD Format not recognised!" ); - dispose_module( module ); - return NULL; - } - module->default_gvol = 64; - module->default_speed = 6; - module->default_tempo = 125; - module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); - if( !module->default_panning ) { - dispose_module( module ); - return NULL; - } - for( idx = 0; idx < module->num_channels; idx++ ) { - module->default_panning[ idx ] = 51; - if( ( idx & 3 ) == 1 || ( idx & 3 ) == 2 ) { - module->default_panning[ idx ] = 204; - } - } - module_data_idx = 1084; - module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); - if( !module->patterns ) { - dispose_module( module ); - return NULL; - } - pat_data_len = module->num_channels * 64 * 5; - for( pat = 0; pat < module->num_patterns; pat++ ) { - module->patterns[ pat ].num_channels = module->num_channels; - module->patterns[ pat ].num_rows = 64; - pattern_data = (char*)calloc( 1, pat_data_len ); - if( !pattern_data ) { - dispose_module( module ); - return NULL; - } - module->patterns[ pat ].data = pattern_data; - for( pat_data_idx = 0; pat_data_idx < pat_data_len; pat_data_idx += 5 ) { - period = ( data_u8( data, module_data_idx ) & 0xF ) << 8; - period = ( period | data_u8( data, module_data_idx + 1 ) ) * 4; - if( period >= 112 && period <= 6848 ) { - key = -12 * log_2( ( period << FP_SHIFT ) / 29021 ); - key = ( key + ( key & ( FP_ONE >> 1 ) ) ) >> FP_SHIFT; - pattern_data[ pat_data_idx ] = key; - } - ins = ( data_u8( data, module_data_idx + 2 ) & 0xF0 ) >> 4; - ins = ins | ( data_u8( data, module_data_idx ) & 0x10 ); - pattern_data[ pat_data_idx + 1 ] = ins; - effect = data_u8( data, module_data_idx + 2 ) & 0x0F; - param = data_u8( data, module_data_idx + 3 ); - if( param == 0 && ( effect < 3 || effect == 0xA ) ) { - effect = 0; - } - if( param == 0 && ( effect == 5 || effect == 6 ) ) { - effect -= 2; - } - if( effect == 8 && module->num_channels == 4 ) { - effect = param = 0; - } - pattern_data[ pat_data_idx + 3 ] = effect; - pattern_data[ pat_data_idx + 4 ] = param; - module_data_idx += 4; - } - } - module->num_instruments = 31; - module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); - if( !module->instruments ) { - dispose_module( module ); - return NULL; - } - instrument = &module->instruments[ 0 ]; - instrument->num_samples = 1; - instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - for( ins = 1; ins <= module->num_instruments; ins++ ) { - instrument = &module->instruments[ ins ]; - instrument->num_samples = 1; - instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); - if( !instrument->samples ) { - dispose_module( module ); - return NULL; - } - sample = &instrument->samples[ 0 ]; - data_ascii( data, ins * 30 - 10, 22, instrument->name ); - sample_length = data_u16be( data, ins * 30 + 12 ) * 2; - fine_tune = ( data_u8( data, ins * 30 + 14 ) & 0xF ) << 4; - sample->fine_tune = ( fine_tune & 0x7F ) - ( fine_tune & 0x80 ); - sample->volume = data_u8( data, ins * 30 + 15 ) & 0x7F; - if( sample->volume > 64 ) { - sample->volume = 64; - } - loop_start = data_u16be( data, ins * 30 + 16 ) * 2; - loop_length = data_u16be( data, ins * 30 + 18 ) * 2; - if( loop_start + loop_length > sample_length ) { - loop_length = sample_length - loop_start; - } - if( loop_length < 4 ) { - loop_start = sample_length; - loop_length = 0; - } - sample->loop_start = loop_start; - sample->loop_length = loop_length; - sample->data = (short*)calloc( sample_length + 1, sizeof( short ) ); - if( sample->data ) { - data_sam_s8( data, module_data_idx, sample_length, sample->data ); - sample->data[ loop_start + loop_length ] = sample->data[ loop_start ]; - } else { - dispose_module( module ); - return NULL; - } - module_data_idx += sample_length; - } - } - return module; -} - -/* Allocate and initialize a module from the specified data, returns NULL on error. - Message should point to a 64-character buffer to receive error messages. */ -struct module* module_load( struct data *data, char *message ) { - char ascii[ 16 ]; - struct module* module; - if( !memcmp( data_ascii( data, 0, 16, ascii ), "Extended Module:", 16 ) ) { - module = module_load_xm( data, message ); - } else if( !memcmp( data_ascii( data, 44, 4, ascii ), "SCRM", 4 ) ) { - module = module_load_s3m( data, message ); - } else { - module = module_load_mod( data, message ); - } - return module; -} - -static void pattern_get_note( struct pattern *pattern, int row, int chan, struct note *dest ) { - int offset = ( row * pattern->num_channels + chan ) * 5; - if( offset >= 0 && row < pattern->num_rows && chan < pattern->num_channels ) { - dest->key = pattern->data[ offset ]; - dest->instrument = pattern->data[ offset + 1 ]; - dest->volume = pattern->data[ offset + 2 ]; - dest->effect = pattern->data[ offset + 3 ]; - dest->param = pattern->data[ offset + 4 ]; - } else { - memset( dest, 0, sizeof( struct note ) ); - } -} - -static void channel_init( struct channel *channel, struct replay *replay, int idx ) { - memset( channel, 0, sizeof( struct channel ) ); - channel->replay = replay; - channel->id = idx; - channel->panning = replay->module->default_panning[ idx ]; - channel->instrument = &replay->module->instruments[ 0 ]; - channel->sample = &channel->instrument->samples[ 0 ]; - channel->random_seed = ( idx + 1 ) * 0xABCDEF; -} - -static void channel_volume_slide( struct channel *channel ) { - int up = channel->vol_slide_param >> 4; - int down = channel->vol_slide_param & 0xF; - if( down == 0xF && up > 0 ) { - /* Fine slide up.*/ - if( channel->fx_count == 0 ) { - channel->volume += up; - } - } else if( up == 0xF && down > 0 ) { - /* Fine slide down.*/ - if( channel->fx_count == 0 ) { - channel->volume -= down; - } - } else if( channel->fx_count > 0 || channel->replay->module->fast_vol_slides ) { - /* Normal.*/ - channel->volume += up - down; - } - if( channel->volume > 64 ) { - channel->volume = 64; - } - if( channel->volume < 0 ) { - channel->volume = 0; - } -} - -static void channel_porta_up( struct channel *channel, int param ) { - switch( param & 0xF0 ) { - case 0xE0: /* Extra-fine porta.*/ - if( channel->fx_count == 0 ) { - channel->period -= param & 0xF; - } - break; - case 0xF0: /* Fine porta.*/ - if( channel->fx_count == 0 ) { - channel->period -= ( param & 0xF ) << 2; - } - break; - default:/* Normal porta.*/ - if( channel->fx_count > 0 ) { - channel->period -= param << 2; - } - break; - } - if( channel->period < 0 ) { - channel->period = 0; - } -} - -static void channel_porta_down( struct channel *channel, int param ) { - if( channel->period > 0 ) { - switch( param & 0xF0 ) { - case 0xE0: /* Extra-fine porta.*/ - if( channel->fx_count == 0 ) { - channel->period += param & 0xF; - } - break; - case 0xF0: /* Fine porta.*/ - if( channel->fx_count == 0 ) { - channel->period += ( param & 0xF ) << 2; - } - break; - default:/* Normal porta.*/ - if( channel->fx_count > 0 ) { - channel->period += param << 2; - } - break; - } - if( channel->period > 65535 ) { - channel->period = 65535; - } - } -} - -static void channel_tone_porta( struct channel *channel ) { - if( channel->period > 0 ) { - if( channel->period < channel->porta_period ) { - channel->period += channel->tone_porta_param << 2; - if( channel->period > channel->porta_period ) { - channel->period = channel->porta_period; - } - } else { - channel->period -= channel->tone_porta_param << 2; - if( channel->period < channel->porta_period ) { - channel->period = channel->porta_period; - } - } - } -} - -static int channel_waveform( struct channel *channel, int phase, int type ) { - int amplitude = 0; - switch( type ) { - default: /* Sine. */ - amplitude = sine_table[ phase & 0x1F ]; - if( ( phase & 0x20 ) > 0 ) { - amplitude = -amplitude; - } - break; - case 6: /* Saw Up.*/ - amplitude = ( ( ( phase + 0x20 ) & 0x3F ) << 3 ) - 255; - break; - case 1: case 7: /* Saw Down. */ - amplitude = 255 - ( ( ( phase + 0x20 ) & 0x3F ) << 3 ); - break; - case 2: case 5: /* Square. */ - amplitude = ( phase & 0x20 ) > 0 ? 255 : -255; - break; - case 3: case 8: /* Random. */ - amplitude = ( channel->random_seed >> 20 ) - 255; - channel->random_seed = ( channel->random_seed * 65 + 17 ) & 0x1FFFFFFF; - break; - } - return amplitude; -} - -static void channel_vibrato( struct channel *channel, int fine ) { - int wave = channel_waveform( channel, channel->vibrato_phase, channel->vibrato_type & 0x3 ); - channel->vibrato_add = wave * channel->vibrato_depth >> ( fine ? 7 : 5 ); -} - -static void channel_tremolo( struct channel *channel ) { - int wave = channel_waveform( channel, channel->tremolo_phase, channel->tremolo_type & 0x3 ); - channel->tremolo_add = wave * channel->tremolo_depth >> 6; -} - -static void channel_tremor( struct channel *channel ) { - if( channel->retrig_count >= channel->tremor_on_ticks ) { - channel->tremolo_add = -64; - } - if( channel->retrig_count >= ( channel->tremor_on_ticks + channel->tremor_off_ticks ) ) { - channel->tremolo_add = channel->retrig_count = 0; - } -} - -static void channel_retrig_vol_slide( struct channel *channel ) { - if( channel->retrig_count >= channel->retrig_ticks ) { - channel->retrig_count = channel->sample_idx = channel->sample_fra = 0; - switch( channel->retrig_volume ) { - case 0x1: channel->volume = channel->volume - 1; break; - case 0x2: channel->volume = channel->volume - 2; break; - case 0x3: channel->volume = channel->volume - 4; break; - case 0x4: channel->volume = channel->volume - 8; break; - case 0x5: channel->volume = channel->volume - 16; break; - case 0x6: channel->volume = channel->volume * 2 / 3; break; - case 0x7: channel->volume = channel->volume >> 1; break; - case 0x8: /* ? */ break; - case 0x9: channel->volume = channel->volume + 1; break; - case 0xA: channel->volume = channel->volume + 2; break; - case 0xB: channel->volume = channel->volume + 4; break; - case 0xC: channel->volume = channel->volume + 8; break; - case 0xD: channel->volume = channel->volume + 16; break; - case 0xE: channel->volume = channel->volume * 3 / 2; break; - case 0xF: channel->volume = channel->volume << 1; break; - } - if( channel->volume < 0 ) { - channel->volume = 0; - } - if( channel->volume > 64 ) { - channel->volume = 64; - } - } -} - -static void channel_trigger( struct channel *channel ) { - int key, sam, porta, period, fine_tune, ins = channel->note.instrument; - struct sample *sample; - if( ins > 0 && ins <= channel->replay->module->num_instruments ) { - channel->instrument = &channel->replay->module->instruments[ ins ]; - key = channel->note.key < 97 ? channel->note.key : 0; - sam = channel->instrument->key_to_sample[ key ]; - sample = &channel->instrument->samples[ sam ]; - channel->volume = sample->volume >= 64 ? 64 : sample->volume & 0x3F; - if( sample->panning > 0 ) { - channel->panning = ( sample->panning - 1 ) & 0xFF; - } - if( channel->period > 0 && sample->loop_length > 1 ) { - /* Amiga trigger.*/ - channel->sample = sample; - } - channel->sample_off = 0; - channel->vol_env_tick = channel->pan_env_tick = 0; - channel->fadeout_vol = 32768; - channel->key_on = 1; - } - if( channel->note.effect == 0x09 || channel->note.effect == 0x8F ) { - /* Set Sample Offset. */ - if( channel->note.param > 0 ) { - channel->offset_param = channel->note.param; - } - channel->sample_off = channel->offset_param << 8; - } - if( channel->note.volume >= 0x10 && channel->note.volume < 0x60 ) { - channel->volume = channel->note.volume < 0x50 ? channel->note.volume - 0x10 : 64; - } - switch( channel->note.volume & 0xF0 ) { - case 0x80: /* Fine Vol Down.*/ - channel->volume -= channel->note.volume & 0xF; - if( channel->volume < 0 ) { - channel->volume = 0; - } - break; - case 0x90: /* Fine Vol Up.*/ - channel->volume += channel->note.volume & 0xF; - if( channel->volume > 64 ) { - channel->volume = 64; - } - break; - case 0xA0: /* Set Vibrato Speed.*/ - if( ( channel->note.volume & 0xF ) > 0 ) { - channel->vibrato_speed = channel->note.volume & 0xF; - } - break; - case 0xB0: /* Vibrato.*/ - if( ( channel->note.volume & 0xF ) > 0 ) { - channel->vibrato_depth = channel->note.volume & 0xF; - } - channel_vibrato( channel, 0 ); - break; - case 0xC0: /* Set Panning.*/ - channel->panning = ( channel->note.volume & 0xF ) * 17; - break; - case 0xF0: /* Tone Porta.*/ - if( ( channel->note.volume & 0xF ) > 0 ) { - channel->tone_porta_param = channel->note.volume & 0xF; - } - break; - } - if( channel->note.key > 0 ) { - if( channel->note.key > 96 ) { - channel->key_on = 0; - } else { - porta = ( channel->note.volume & 0xF0 ) == 0xF0 || - channel->note.effect == 0x03 || channel->note.effect == 0x05 || - channel->note.effect == 0x87 || channel->note.effect == 0x8C; - if( !porta ) { - ins = channel->instrument->key_to_sample[ channel->note.key ]; - channel->sample = &channel->instrument->samples[ ins ]; - } - fine_tune = channel->sample->fine_tune; - if( channel->note.effect == 0x75 || channel->note.effect == 0xF2 ) { - /* Set Fine Tune. */ - fine_tune = ( ( channel->note.param & 0xF ) << 4 ) - 128; - } - key = channel->note.key + channel->sample->rel_note; - if( key < 1 ) { - key = 1; - } - if( key > 120 ) { - key = 120; - } - period = ( key << 6 ) + ( fine_tune >> 1 ); - if( channel->replay->module->linear_periods ) { - channel->porta_period = 7744 - period; - } else { - channel->porta_period = 29021 * exp_2( ( period << FP_SHIFT ) / -768 ) >> FP_SHIFT; - } - if( !porta ) { - channel->period = channel->porta_period; - channel->sample_idx = channel->sample_off; - channel->sample_fra = 0; - if( channel->vibrato_type < 4 ) { - channel->vibrato_phase = 0; - } - if( channel->tremolo_type < 4 ) { - channel->tremolo_phase = 0; - } - channel->retrig_count = channel->av_count = 0; - } - } - } -} - -static void channel_update_envelopes( struct channel *channel ) { - if( channel->instrument->vol_env.enabled ) { - if( !channel->key_on ) { - channel->fadeout_vol -= channel->instrument->vol_fadeout; - if( channel->fadeout_vol < 0 ) { - channel->fadeout_vol = 0; - } - } - channel->vol_env_tick = envelope_next_tick( &channel->instrument->vol_env, - channel->vol_env_tick, channel->key_on ); - } - if( channel->instrument->pan_env.enabled ) { - channel->pan_env_tick = envelope_next_tick( &channel->instrument->pan_env, - channel->pan_env_tick, channel->key_on ); - } -} - -static void channel_auto_vibrato( struct channel *channel ) { - int sweep, rate, type, wave; - int depth = channel->instrument->vib_depth & 0x7F; - if( depth > 0 ) { - sweep = channel->instrument->vib_sweep & 0x7F; - rate = channel->instrument->vib_rate & 0x7F; - type = channel->instrument->vib_type; - if( channel->av_count < sweep ) { - depth = depth * channel->av_count / sweep; - } - wave = channel_waveform( channel, channel->av_count * rate >> 2, type + 4 ); - channel->vibrato_add += wave * depth >> 8; - channel->av_count++; - } -} - -static void channel_calculate_freq( struct channel *channel ) { - int per = channel->period + channel->vibrato_add; - if( channel->replay->module->linear_periods ) { - per = per - ( channel->arpeggio_add << 6 ); - if( per < 28 || per > 7680 ) { - per = 7680; - } - channel->freq = ( ( channel->replay->module->c2_rate >> 4 ) - * exp_2( ( ( 4608 - per ) << FP_SHIFT ) / 768 ) ) >> ( FP_SHIFT - 4 ); - } else { - if( per > 29021 ) { - per = 29021; - } - per = ( per << FP_SHIFT ) / exp_2( ( channel->arpeggio_add << FP_SHIFT ) / 12 ); - if( per < 28 ) { - per = 29021; - } - channel->freq = channel->replay->module->c2_rate * 1712 / per; - } -} - -static void channel_calculate_ampl( struct channel *channel ) { - int vol, range, env_pan = 32, env_vol = channel->key_on ? 64 : 0; - if( channel->instrument->vol_env.enabled ) { - env_vol = envelope_calculate_ampl( &channel->instrument->vol_env, channel->vol_env_tick ); - } - vol = channel->volume + channel->tremolo_add; - if( vol > 64 ) { - vol = 64; - } - if( vol < 0 ) { - vol = 0; - } - vol = ( vol * channel->replay->module->gain * FP_ONE ) >> 13; - vol = ( vol * channel->fadeout_vol ) >> 15; - channel->ampl = ( vol * channel->replay->global_vol * env_vol ) >> 12; - if( channel->instrument->pan_env.enabled ) { - env_pan = envelope_calculate_ampl( &channel->instrument->pan_env, channel->pan_env_tick ); - } - range = ( channel->panning < 128 ) ? channel->panning : ( 255 - channel->panning ); - channel->pann = channel->panning + ( range * ( env_pan - 32 ) >> 5 ); -} - -static void channel_tick( struct channel *channel ) { - channel->vibrato_add = 0; - channel->fx_count++; - channel->retrig_count++; - if( !( channel->note.effect == 0x7D && channel->fx_count <= channel->note.param ) ) { - switch( channel->note.volume & 0xF0 ) { - case 0x60: /* Vol Slide Down.*/ - channel->volume -= channel->note.volume & 0xF; - if( channel->volume < 0 ) { - channel->volume = 0; - } - break; - case 0x70: /* Vol Slide Up.*/ - channel->volume += channel->note.volume & 0xF; - if( channel->volume > 64 ) { - channel->volume = 64; - } - break; - case 0xB0: /* Vibrato.*/ - channel->vibrato_phase += channel->vibrato_speed; - channel_vibrato( channel, 0 ); - break; - case 0xD0: /* Pan Slide Left.*/ - channel->panning -= channel->note.volume & 0xF; - if( channel->panning < 0 ) { - channel->panning = 0; - } - break; - case 0xE0: /* Pan Slide Right.*/ - channel->panning += channel->note.volume & 0xF; - if( channel->panning > 255 ) { - channel->panning = 255; - } - break; - case 0xF0: /* Tone Porta.*/ - channel_tone_porta( channel ); - break; - } - } - switch( channel->note.effect ) { - case 0x01: case 0x86: /* Porta Up. */ - channel_porta_up( channel, channel->porta_up_param ); - break; - case 0x02: case 0x85: /* Porta Down. */ - channel_porta_down( channel, channel->porta_down_param ); - break; - case 0x03: case 0x87: /* Tone Porta. */ - channel_tone_porta( channel ); - break; - case 0x04: case 0x88: /* Vibrato. */ - channel->vibrato_phase += channel->vibrato_speed; - channel_vibrato( channel, 0 ); - break; - case 0x05: case 0x8C: /* Tone Porta + Vol Slide. */ - channel_tone_porta( channel ); - channel_volume_slide( channel ); - break; - case 0x06: case 0x8B: /* Vibrato + Vol Slide. */ - channel->vibrato_phase += channel->vibrato_speed; - channel_vibrato( channel, 0 ); - channel_volume_slide( channel ); - break; - case 0x07: case 0x92: /* Tremolo. */ - channel->tremolo_phase += channel->tremolo_speed; - channel_tremolo( channel ); - break; - case 0x0A: case 0x84: /* Vol Slide. */ - channel_volume_slide( channel ); - break; - case 0x11: /* Global Volume Slide. */ - channel->replay->global_vol = channel->replay->global_vol - + ( channel->gvol_slide_param >> 4 ) - - ( channel->gvol_slide_param & 0xF ); - if( channel->replay->global_vol < 0 ) { - channel->replay->global_vol = 0; - } - if( channel->replay->global_vol > 64 ) { - channel->replay->global_vol = 64; - } - break; - case 0x19: /* Panning Slide. */ - channel->panning = channel->panning - + ( channel->pan_slide_param >> 4 ) - - ( channel->pan_slide_param & 0xF ); - if( channel->panning < 0 ) { - channel->panning = 0; - } - if( channel->panning > 255 ) { - channel->panning = 255; - } - break; - case 0x1B: case 0x91: /* Retrig + Vol Slide. */ - channel_retrig_vol_slide( channel ); - break; - case 0x1D: case 0x89: /* Tremor. */ - channel_tremor( channel ); - break; - case 0x79: /* Retrig. */ - if( channel->fx_count >= channel->note.param ) { - channel->fx_count = 0; - channel->sample_idx = channel->sample_fra = 0; - } - break; - case 0x7C: case 0xFC: /* Note Cut. */ - if( channel->note.param == channel->fx_count ) { - channel->volume = 0; - } - break; - case 0x7D: case 0xFD: /* Note Delay. */ - if( channel->note.param == channel->fx_count ) { - channel_trigger( channel ); - } - break; - case 0x8A: /* Arpeggio. */ - if( channel->fx_count == 1 ) { - channel->arpeggio_add = channel->arpeggio_param >> 4; - } else if( channel->fx_count == 2 ) { - channel->arpeggio_add = channel->arpeggio_param & 0xF; - } else { - channel->arpeggio_add = channel->fx_count = 0; - } - break; - case 0x95: /* Fine Vibrato. */ - channel->vibrato_phase += channel->vibrato_speed; - channel_vibrato( channel, 1 ); - break; - } - channel_auto_vibrato( channel ); - channel_calculate_freq( channel ); - channel_calculate_ampl( channel ); - channel_update_envelopes( channel ); -} - -static void channel_row( struct channel *channel, struct note *note ) { - channel->note = *note; - channel->retrig_count++; - channel->vibrato_add = channel->tremolo_add = channel->arpeggio_add = channel->fx_count = 0; - if( !( ( note->effect == 0x7D || note->effect == 0xFD ) && note->param > 0 ) ) { - /* Not note delay.*/ - channel_trigger( channel ); - } - switch( channel->note.effect ) { - case 0x01: case 0x86: /* Porta Up. */ - if( channel->note.param > 0 ) { - channel->porta_up_param = channel->note.param; - } - channel_porta_up( channel, channel->porta_up_param ); - break; - case 0x02: case 0x85: /* Porta Down. */ - if( channel->note.param > 0 ) { - channel->porta_down_param = channel->note.param; - } - channel_porta_down( channel, channel->porta_down_param ); - break; - case 0x03: case 0x87: /* Tone Porta. */ - if( channel->note.param > 0 ) { - channel->tone_porta_param = channel->note.param; - } - break; - case 0x04: case 0x88: /* Vibrato. */ - if( ( channel->note.param >> 4 ) > 0 ) { - channel->vibrato_speed = channel->note.param >> 4; - } - if( ( channel->note.param & 0xF ) > 0 ) { - channel->vibrato_depth = channel->note.param & 0xF; - } - channel_vibrato( channel, 0 ); - break; - case 0x05: case 0x8C: /* Tone Porta + Vol Slide. */ - if( channel->note.param > 0 ) { - channel->vol_slide_param = channel->note.param; - } - channel_volume_slide( channel ); - break; - case 0x06: case 0x8B: /* Vibrato + Vol Slide. */ - if( channel->note.param > 0 ) { - channel->vol_slide_param = channel->note.param; - } - channel_vibrato( channel, 0 ); - channel_volume_slide( channel ); - break; - case 0x07: case 0x92: /* Tremolo. */ - if( ( channel->note.param >> 4 ) > 0 ) { - channel->tremolo_speed = channel->note.param >> 4; - } - if( ( channel->note.param & 0xF ) > 0 ) { - channel->tremolo_depth = channel->note.param & 0xF; - } - channel_tremolo( channel ); - break; - case 0x08: /* Set Panning.*/ - channel->panning = ( channel->note.param < 128 ) ? ( channel->note.param << 1 ) : 255; - break; - case 0x0A: case 0x84: /* Vol Slide. */ - if( channel->note.param > 0 ) { - channel->vol_slide_param = channel->note.param; - } - channel_volume_slide( channel ); - break; - case 0x0C: /* Set Volume. */ - channel->volume = channel->note.param >= 64 ? 64 : channel->note.param & 0x3F; - break; - case 0x10: case 0x96: /* Set Global Volume. */ - channel->replay->global_vol = channel->note.param >= 64 ? 64 : channel->note.param & 0x3F; - break; - case 0x11: /* Global Volume Slide. */ - if( channel->note.param > 0 ) { - channel->gvol_slide_param = channel->note.param; - } - break; - case 0x14: /* Key Off. */ - channel->key_on = 0; - break; - case 0x15: /* Set Envelope Tick. */ - channel->vol_env_tick = channel->pan_env_tick = channel->note.param & 0xFF; - break; - case 0x19: /* Panning Slide. */ - if( channel->note.param > 0 ) { - channel->pan_slide_param = channel->note.param; - } - break; - case 0x1B: case 0x91: /* Retrig + Vol Slide. */ - if( ( channel->note.param >> 4 ) > 0 ) { - channel->retrig_volume = channel->note.param >> 4; - } - if( ( channel->note.param & 0xF ) > 0 ) { - channel->retrig_ticks = channel->note.param & 0xF; - } - channel_retrig_vol_slide( channel ); - break; - case 0x1D: case 0x89: /* Tremor. */ - if( ( channel->note.param >> 4 ) > 0 ) { - channel->tremor_on_ticks = channel->note.param >> 4; - } - if( ( channel->note.param & 0xF ) > 0 ) { - channel->tremor_off_ticks = channel->note.param & 0xF; - } - channel_tremor( channel ); - break; - case 0x21: /* Extra Fine Porta. */ - if( channel->note.param > 0 ) { - channel->xfine_porta_param = channel->note.param; - } - switch( channel->xfine_porta_param & 0xF0 ) { - case 0x10: - channel_porta_up( channel, 0xE0 | ( channel->xfine_porta_param & 0xF ) ); - break; - case 0x20: - channel_porta_down( channel, 0xE0 | ( channel->xfine_porta_param & 0xF ) ); - break; - } - break; - case 0x71: /* Fine Porta Up. */ - if( channel->note.param > 0 ) { - channel->fine_porta_up_param = channel->note.param; - } - channel_porta_up( channel, 0xF0 | ( channel->fine_porta_up_param & 0xF ) ); - break; - case 0x72: /* Fine Porta Down. */ - if( channel->note.param > 0 ) { - channel->fine_porta_down_param = channel->note.param; - } - channel_porta_down( channel, 0xF0 | ( channel->fine_porta_down_param & 0xF ) ); - break; - case 0x74: case 0xF3: /* Set Vibrato Waveform. */ - if( channel->note.param < 8 ) { - channel->vibrato_type = channel->note.param; - } - break; - case 0x77: case 0xF4: /* Set Tremolo Waveform. */ - if( channel->note.param < 8 ) { - channel->tremolo_type = channel->note.param; - } - break; - case 0x7A: /* Fine Vol Slide Up. */ - if( channel->note.param > 0 ) { - channel->fine_vslide_up_param = channel->note.param; - } - channel->volume += channel->fine_vslide_up_param; - if( channel->volume > 64 ) { - channel->volume = 64; - } - break; - case 0x7B: /* Fine Vol Slide Down. */ - if( channel->note.param > 0 ) { - channel->fine_vslide_down_param = channel->note.param; - } - channel->volume -= channel->fine_vslide_down_param; - if( channel->volume < 0 ) { - channel->volume = 0; - } - break; - case 0x7C: case 0xFC: /* Note Cut. */ - if( channel->note.param <= 0 ) { - channel->volume = 0; - } - break; - case 0x8A: /* Arpeggio. */ - if( channel->note.param > 0 ) { - channel->arpeggio_param = channel->note.param; - } - break; - case 0x95: /* Fine Vibrato.*/ - if( ( channel->note.param >> 4 ) > 0 ) { - channel->vibrato_speed = channel->note.param >> 4; - } - if( ( channel->note.param & 0xF ) > 0 ) { - channel->vibrato_depth = channel->note.param & 0xF; - } - channel_vibrato( channel, 1 ); - break; - case 0xF8: /* Set Panning. */ - channel->panning = channel->note.param * 17; - break; - } - channel_auto_vibrato( channel ); - channel_calculate_freq( channel ); - channel_calculate_ampl( channel ); - channel_update_envelopes( channel ); -} - -static void channel_resample( struct channel *channel, int *mix_buf, - int offset, int count, int sample_rate, int interpolate ) { - struct sample *sample = channel->sample; - int l_gain, r_gain, sam_idx, sam_fra, step; - int loop_len, loop_end, out_idx, out_end, y, m, c; - short *sample_data = channel->sample->data; - if( channel->ampl > 0 ) { - l_gain = channel->ampl * ( 255 - channel->pann ) >> 8; - r_gain = channel->ampl * channel->pann >> 8; - sam_idx = channel->sample_idx; - sam_fra = channel->sample_fra; - step = ( channel->freq << ( FP_SHIFT - 3 ) ) / ( sample_rate >> 3 ); - loop_len = sample->loop_length; - loop_end = sample->loop_start + loop_len; - out_idx = offset * 2; - out_end = ( offset + count ) * 2; - if( interpolate ) { - while( out_idx < out_end ) { - if( sam_idx >= loop_end ) { - if( loop_len > 1 ) { - while( sam_idx >= loop_end ) { - sam_idx -= loop_len; - } - } else { - break; - } - } - c = sample_data[ sam_idx ]; - m = sample_data[ sam_idx + 1 ] - c; - y = ( ( m * sam_fra ) >> FP_SHIFT ) + c; - mix_buf[ out_idx++ ] += ( y * l_gain ) >> FP_SHIFT; - mix_buf[ out_idx++ ] += ( y * r_gain ) >> FP_SHIFT; - sam_fra += step; - sam_idx += sam_fra >> FP_SHIFT; - sam_fra &= FP_MASK; - } - } else { - while( out_idx < out_end ) { - if( sam_idx >= loop_end ) { - if( loop_len > 1 ) { - while( sam_idx >= loop_end ) { - sam_idx -= loop_len; - } - } else { - break; - } - } - y = sample_data[ sam_idx ]; - mix_buf[ out_idx++ ] += ( y * l_gain ) >> FP_SHIFT; - mix_buf[ out_idx++ ] += ( y * r_gain ) >> FP_SHIFT; - sam_fra += step; - sam_idx += sam_fra >> FP_SHIFT; - sam_fra &= FP_MASK; - } - } - } -} - -static void channel_update_sample_idx( struct channel *channel, int count, int sample_rate ) { - struct sample *sample = channel->sample; - int step = ( channel->freq << ( FP_SHIFT - 3 ) ) / ( sample_rate >> 3 ); - channel->sample_fra += step * count; - channel->sample_idx += channel->sample_fra >> FP_SHIFT; - if( channel->sample_idx > sample->loop_start ) { - if( sample->loop_length > 1 ) { - channel->sample_idx = sample->loop_start - + ( channel->sample_idx - sample->loop_start ) % sample->loop_length; - } else { - channel->sample_idx = sample->loop_start; - } - } - channel->sample_fra &= FP_MASK; -} - -static void replay_row( struct replay *replay ) { - int idx, count; - struct note note; - struct pattern *pattern; - struct channel *channel; - struct module *module = replay->module; - if( replay->next_row < 0 ) { - replay->break_pos = replay->seq_pos + 1; - replay->next_row = 0; - } - if( replay->break_pos >= 0 ) { - if( replay->break_pos >= module->sequence_len ) { - replay->break_pos = replay->next_row = 0; - } - while( module->sequence[ replay->break_pos ] >= module->num_patterns ) { - replay->break_pos++; - if( replay->break_pos >= module->sequence_len ) { - replay->break_pos = replay->next_row = 0; - } - } - replay->seq_pos = replay->break_pos; - for( idx = 0; idx < module->num_channels; idx++ ) { - replay->channels[ idx ].pl_row = 0; - } - replay->break_pos = -1; - } - pattern = &module->patterns[ module->sequence[ replay->seq_pos ] ]; - replay->row = replay->next_row; - if( replay->row >= pattern->num_rows ) { - replay->row = 0; - } - if( replay->play_count && replay->play_count[ 0 ] ) { - count = replay->play_count[ replay->seq_pos ][ replay->row ]; - if( replay->pl_count < 0 && count < 127 ) { - replay->play_count[ replay->seq_pos ][ replay->row ] = count + 1; - } - } - replay->next_row = replay->row + 1; - if( replay->next_row >= pattern->num_rows ) { - replay->next_row = -1; - } - for( idx = 0; idx < module->num_channels; idx++ ) { - channel = &replay->channels[ idx ]; - pattern_get_note( pattern, replay->row, idx, ¬e ); - if( note.effect == 0xE ) { - note.effect = 0x70 | ( note.param >> 4 ); - note.param &= 0xF; - } - if( note.effect == 0x93 ) { - note.effect = 0xF0 | ( note.param >> 4 ); - note.param &= 0xF; - } - if( note.effect == 0 && note.param > 0 ) { - note.effect = 0x8A; - } - channel_row( channel, ¬e ); - switch( note.effect ) { - case 0x81: /* Set Speed. */ - if( note.param > 0 ) { - replay->tick = replay->speed = note.param; - } - break; - case 0xB: case 0x82: /* Pattern Jump.*/ - if( replay->pl_count < 0 ) { - replay->break_pos = note.param; - replay->next_row = 0; - } - break; - case 0xD: case 0x83: /* Pattern Break.*/ - if( replay->pl_count < 0 ) { - if( replay->break_pos < 0 ) { - replay->break_pos = replay->seq_pos + 1; - } - replay->next_row = ( note.param >> 4 ) * 10 + ( note.param & 0xF ); - } - break; - case 0xF: /* Set Speed/Tempo.*/ - if( note.param > 0 ) { - if( note.param < 32 ) { - replay->tick = replay->speed = note.param; - } else { - replay->tempo = note.param; - } - } - break; - case 0x94: /* Set Tempo.*/ - if( note.param > 32 ) { - replay->tempo = note.param; - } - break; - case 0x76: case 0xFB : /* Pattern Loop.*/ - if( note.param == 0 ) { - /* Set loop marker on this channel. */ - channel->pl_row = replay->row; - } - if( channel->pl_row < replay->row && replay->break_pos < 0 ) { - /* Marker valid. */ - if( replay->pl_count < 0 ) { - /* Not already looping, begin. */ - replay->pl_count = note.param; - replay->pl_chan = idx; - } - if( replay->pl_chan == idx ) { - /* Next Loop.*/ - if( replay->pl_count == 0 ) { - /* Loop finished. Invalidate current marker. */ - channel->pl_row = replay->row + 1; - } else { - /* Loop. */ - replay->next_row = channel->pl_row; - } - replay->pl_count--; - } - } - break; - case 0x7E: case 0xFE: /* Pattern Delay.*/ - replay->tick = replay->speed + replay->speed * note.param; - break; - } - } -} - -static int replay_tick( struct replay *replay ) { - int idx, num_channels, count = 1; - if( --replay->tick <= 0 ) { - replay->tick = replay->speed; - replay_row( replay ); - } else { - num_channels = replay->module->num_channels; - for( idx = 0; idx < num_channels; idx++ ) { - channel_tick( &replay->channels[ idx ] ); - } - } - if( replay->play_count && replay->play_count[ 0 ] ) { - count = replay->play_count[ replay->seq_pos ][ replay->row ] - 1; - } - return count; -} - -static int module_init_play_count( struct module *module, char **play_count ) { - int idx, pat, rows, len = 0; - for( idx = 0; idx < module->sequence_len; idx++ ) { - pat = module->sequence[ idx ]; - rows = ( pat < module->num_patterns ) ? module->patterns[ pat ].num_rows : 0; - if( play_count ) { - play_count[ idx ] = play_count[ 0 ] ? &play_count[ 0 ][ len ] : NULL; - } - len += rows; - } - return len; -} - -/* Set the pattern in the sequence to play. The tempo is reset to the default. */ -void replay_set_sequence_pos( struct replay *replay, int pos ) { - int idx; - struct module *module = replay->module; - if( pos >= module->sequence_len ) { - pos = 0; - } - replay->break_pos = pos; - replay->next_row = 0; - replay->tick = 1; - replay->global_vol = module->default_gvol; - replay->speed = module->default_speed > 0 ? module->default_speed : 6; - replay->tempo = module->default_tempo > 0 ? module->default_tempo : 125; - replay->pl_count = replay->pl_chan = -1; - if( replay->play_count ) { - free( replay->play_count[ 0 ] ); - free( replay->play_count ); - } - replay->play_count = (char**)calloc( module->sequence_len, sizeof( char * ) ); - if( replay->play_count ) { - replay->play_count[ 0 ] = (char*)calloc( module_init_play_count( module, NULL ), sizeof( char ) ); - module_init_play_count( module, replay->play_count ); - } - for( idx = 0; idx < module->num_channels; idx++ ) { - channel_init( &replay->channels[ idx ], replay, idx ); - } - memset( replay->ramp_buf, 0, 128 * sizeof( int ) ); - replay_tick( replay ); -} - -/* Deallocate the specified replay. */ -void dispose_replay( struct replay *replay ) { - if( replay->play_count ) { - free( replay->play_count[ 0 ] ); - free( replay->play_count ); - } - free( replay->ramp_buf ); - free( replay->channels ); - free( replay ); -} - -/* Allocate and initialize a replay with the specified sampling rate and interpolation. */ -struct replay* new_replay( struct module *module, int sample_rate, int interpolation ) { - struct replay *replay = (struct replay*)calloc( 1, sizeof( struct replay ) ); - if( replay ) { - replay->module = module; - replay->sample_rate = sample_rate; - replay->interpolation = interpolation; - replay->ramp_buf = (int*)calloc( 128, sizeof( int ) ); - replay->channels = (struct channel*)calloc( module->num_channels, sizeof( struct channel ) ); - if( replay->ramp_buf && replay->channels ) { - replay_set_sequence_pos( replay, 0 ); - } else { - dispose_replay( replay ); - replay = NULL; - } - } - return replay; -} - -static int calculate_tick_len( int tempo, int sample_rate ) { - return ( sample_rate * 5 ) / ( tempo * 2 ); -} - -/* Returns the length of the output buffer required by replay_get_audio(). */ -int calculate_mix_buf_len( int sample_rate ) { - return ( calculate_tick_len( 32, sample_rate ) + 65 ) * 4; -} - -/* Returns the song duration in samples at the current sampling rate. */ -int replay_calculate_duration( struct replay *replay ) { - int count = 0, duration = 0; - replay_set_sequence_pos( replay, 0 ); - while( count < 1 ) { - duration += calculate_tick_len( replay->tempo, replay->sample_rate ); - count = replay_tick( replay ); - } - replay_set_sequence_pos( replay, 0 ); - return duration; -} - -/* Seek to approximately the specified sample position. - The actual sample position reached is returned. */ -int replay_seek( struct replay *replay, int sample_pos ) { - int idx, tick_len, current_pos = 0; - replay_set_sequence_pos( replay, 0 ); - tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); - while( ( sample_pos - current_pos ) >= tick_len ) { - for( idx = 0; idx < replay->module->num_channels; idx++ ) { - channel_update_sample_idx( &replay->channels[ idx ], - tick_len * 2, replay->sample_rate * 2 ); - } - current_pos += tick_len; - replay_tick( replay ); - tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); - } - return current_pos; -} - -static void replay_volume_ramp( struct replay *replay, int *mix_buf, int tick_len ) { - int idx, a1, a2, ramp_rate = 256 * 2048 / replay->sample_rate; - for( idx = 0, a1 = 0; a1 < 256; idx += 2, a1 += ramp_rate ) { - a2 = 256 - a1; - mix_buf[ idx ] = ( mix_buf[ idx ] * a1 + replay->ramp_buf[ idx ] * a2 ) >> 8; - mix_buf[ idx + 1 ] = ( mix_buf[ idx + 1 ] * a1 + replay->ramp_buf[ idx + 1 ] * a2 ) >> 8; - } - memcpy( replay->ramp_buf, &mix_buf[ tick_len * 2 ], 128 * sizeof( int ) ); -} - -/* 2:1 downsampling with simple but effective anti-aliasing. Buf must contain count * 2 + 1 stereo samples. */ -static void downsample( int *buf, int count ) { - int idx, out_idx, out_len = count * 2; - for( idx = 0, out_idx = 0; out_idx < out_len; idx += 4, out_idx += 2 ) { - buf[ out_idx ] = ( buf[ idx ] >> 2 ) + ( buf[ idx + 2 ] >> 1 ) + ( buf[ idx + 4 ] >> 2 ); - buf[ out_idx + 1 ] = ( buf[ idx + 1 ] >> 2 ) + ( buf[ idx + 3 ] >> 1 ) + ( buf[ idx + 5 ] >> 2 ); - } -} - -/* Generates audio and returns the number of stereo samples written into mix_buf. */ -int replay_get_audio( struct replay *replay, int *mix_buf ) { - struct channel *channel; - int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); - /* Clear output buffer. */ - memset( mix_buf, 0, ( tick_len + 65 ) * 4 * sizeof( int ) ); - /* Resample. */ - num_channels = replay->module->num_channels; - for( idx = 0; idx < num_channels; idx++ ) { - channel = &replay->channels[ idx ]; - channel_resample( channel, mix_buf, 0, ( tick_len + 65 ) * 2, - replay->sample_rate * 2, replay->interpolation ); - channel_update_sample_idx( channel, tick_len * 2, replay->sample_rate * 2 ); - } - downsample( mix_buf, tick_len + 64 ); - replay_volume_ramp( replay, mix_buf, tick_len ); - replay_tick( replay ); - return tick_len; -} + +#include "stdlib.h" +#include "string.h" + +#include "ibxm.h" + +const char *IBXM_VERSION = "ibxm/ac mod/xm/s3m replay 20170901 (c)mumart@gmail.com"; + +static const int FP_SHIFT = 15, FP_ONE = 32768, FP_MASK = 32767; + +static const int exp2_table[] = { + 32768, 32946, 33125, 33305, 33486, 33667, 33850, 34034, + 34219, 34405, 34591, 34779, 34968, 35158, 35349, 35541, + 35734, 35928, 36123, 36319, 36516, 36715, 36914, 37114, + 37316, 37518, 37722, 37927, 38133, 38340, 38548, 38757, + 38968, 39180, 39392, 39606, 39821, 40037, 40255, 40473, + 40693, 40914, 41136, 41360, 41584, 41810, 42037, 42265, + 42495, 42726, 42958, 43191, 43425, 43661, 43898, 44137, + 44376, 44617, 44859, 45103, 45348, 45594, 45842, 46091, + 46341, 46593, 46846, 47100, 47356, 47613, 47871, 48131, + 48393, 48655, 48920, 49185, 49452, 49721, 49991, 50262, + 50535, 50810, 51085, 51363, 51642, 51922, 52204, 52488, + 52773, 53059, 53347, 53637, 53928, 54221, 54515, 54811, + 55109, 55408, 55709, 56012, 56316, 56622, 56929, 57238, + 57549, 57861, 58176, 58491, 58809, 59128, 59449, 59772, + 60097, 60423, 60751, 61081, 61413, 61746, 62081, 62419, + 62757, 63098, 63441, 63785, 64132, 64480, 64830, 65182, + 65536 +}; + +static const short sine_table[] = { + 0, 24, 49, 74, 97, 120, 141, 161, 180, 197, 212, 224, 235, 244, 250, 253, + 255, 253, 250, 244, 235, 224, 212, 197, 180, 161, 141, 120, 97, 74, 49, 24 +}; + +struct note { + unsigned char key, instrument, volume, effect, param; +}; + +struct channel { + struct replay *replay; + struct instrument *instrument; + struct sample *sample; + struct note note; + int id, key_on, random_seed, pl_row; + int sample_off, sample_idx, sample_fra, freq, ampl, pann; + int volume, panning, fadeout_vol, vol_env_tick, pan_env_tick; + int period, porta_period, retrig_count, fx_count, av_count; + int porta_up_param, porta_down_param, tone_porta_param, offset_param; + int fine_porta_up_param, fine_porta_down_param, xfine_porta_param; + int arpeggio_param, vol_slide_param, gvol_slide_param, pan_slide_param; + int fine_vslide_up_param, fine_vslide_down_param; + int retrig_volume, retrig_ticks, tremor_on_ticks, tremor_off_ticks; + int vibrato_type, vibrato_phase, vibrato_speed, vibrato_depth; + int tremolo_type, tremolo_phase, tremolo_speed, tremolo_depth; + int tremolo_add, vibrato_add, arpeggio_add; +}; + +struct replay { + int sample_rate, interpolation, global_vol; + int seq_pos, break_pos, row, next_row, tick; + int speed, tempo, pl_count, pl_chan; + int *ramp_buf; + char **play_count; + struct channel *channels; + struct module *module; +}; + +static int exp_2( int x ) { + int c, m, y; + int x0 = ( x & FP_MASK ) >> ( FP_SHIFT - 7 ); + c = exp2_table[ x0 ]; + m = exp2_table[ x0 + 1 ] - c; + y = ( m * ( x & ( FP_MASK >> 7 ) ) >> 8 ) + c; + return ( y << FP_SHIFT ) >> ( FP_SHIFT - ( x >> FP_SHIFT ) ); +} + +static int log_2( int x ) { + int step; + int y = 16 << FP_SHIFT; + for( step = y; step > 0; step >>= 1 ) { + if( exp_2( y - step ) >= x ) { + y -= step; + } + } + return y; +} + +static char* data_ascii( struct data *data, int offset, int length, char *dest ) { + int idx, chr; + memset( dest, 32, length ); + if( offset > data->length ) { + offset = data->length; + } + if( ( unsigned int ) offset + length > ( unsigned int ) data->length ) { + length = data->length - offset; + } + for( idx = 0; idx < length; idx++ ) { + chr = data->buffer[ offset + idx ] & 0xFF; + if( chr > 32 ) { + dest[ idx ] = chr; + } + } + return dest; +} + +static int data_s8( struct data *data, int offset ) { + int value = 0; + if( offset < data->length ) { + value = data->buffer[ offset ]; + value = ( value & 0x7F ) - ( value & 0x80 ); + } + return value; +} + +static int data_u8( struct data *data, int offset ) { + int value = 0; + if( offset < data->length ) { + value = data->buffer[ offset ] & 0xFF; + } + return value; +} + +static int data_u16be( struct data *data, int offset ) { + int value = 0; + if( offset + 1 < data->length ) { + value = ( ( data->buffer[ offset ] & 0xFF ) << 8 ) + | ( data->buffer[ offset + 1 ] & 0xFF ); + } + return value; +} + +static int data_u16le( struct data *data, int offset ) { + int value = 0; + if( offset + 1 < data->length ) { + value = ( data->buffer[ offset ] & 0xFF ) + | ( ( data->buffer[ offset + 1 ] & 0xFF ) << 8 ); + } + return value; +} + +static unsigned int data_u32le( struct data *data, int offset ) { + unsigned int value = 0; + if( offset + 3 < data->length ) { + value = ( data->buffer[ offset ] & 0xFF ) + | ( ( data->buffer[ offset + 1 ] & 0xFF ) << 8 ) + | ( ( data->buffer[ offset + 2 ] & 0xFF ) << 16 ) + | ( ( data->buffer[ offset + 3 ] & 0xFF ) << 24 ); + } + return value; +} + +static void data_sam_s8( struct data *data, int offset, int count, short *dest ) { + int idx, amp, length = data->length; + char *buffer = data->buffer; + if( offset > length ) { + offset = length; + } + if( offset + count > length ) { + count = length - offset; + } + for( idx = 0; idx < count; idx++ ) { + amp = ( buffer[ offset + idx ] & 0xFF ) << 8; + dest[ idx ] = ( amp & 0x7FFF ) - ( amp & 0x8000 ); + } +} + +static void data_sam_s16le( struct data *data, int offset, int count, short *dest ) { + int idx, amp, length = data->length; + char *buffer = data->buffer; + if( offset > length ) { + offset = length; + } + if( offset + count * 2 > length ) { + count = ( length - offset ) / 2; + } + for( idx = 0; idx < count; idx++ ) { + amp = ( buffer[ offset + idx * 2 ] & 0xFF ) | ( buffer[ offset + idx * 2 + 1 ] << 8 ); + dest[ idx ] = ( amp & 0x7FFF ) - ( amp & 0x8000 ); + } +} + +static int envelope_next_tick( struct envelope *envelope, int tick, int key_on ) { + tick++; + if( envelope->looped && tick >= envelope->loop_end_tick ) { + tick = envelope->loop_start_tick; + } + if( envelope->sustain && key_on && tick >= envelope->sustain_tick ) { + tick = envelope->sustain_tick; + } + return tick; +} + +static int envelope_calculate_ampl( struct envelope *envelope, int tick ) { + int idx, point, dt, da; + int ampl = envelope->points_ampl[ envelope->num_points - 1 ]; + if( tick < envelope->points_tick[ envelope->num_points - 1 ] ) { + point = 0; + for( idx = 1; idx < envelope->num_points; idx++ ) { + if( envelope->points_tick[ idx ] <= tick ) { + point = idx; + } + } + dt = envelope->points_tick[ point + 1 ] - envelope->points_tick[ point ]; + da = envelope->points_ampl[ point + 1 ] - envelope->points_ampl[ point ]; + ampl = envelope->points_ampl[ point ]; + ampl += ( ( da << 24 ) / dt ) * ( tick - envelope->points_tick[ point ] ) >> 24; + } + return ampl; +} + +static void sample_ping_pong( struct sample *sample ) { + int idx; + int loop_start = sample->loop_start; + int loop_length = sample->loop_length; + int loop_end = loop_start + loop_length; + short *sample_data = sample->data; + short *new_data = (short*)calloc( loop_end + loop_length + 1, sizeof( short ) ); + if( new_data ) { + memcpy( new_data, sample_data, loop_end * sizeof( short ) ); + for( idx = 0; idx < loop_length; idx++ ) { + new_data[ loop_end + idx ] = sample_data[ loop_end - idx - 1 ]; + } + free( sample->data ); + sample->data = new_data; + sample->loop_length *= 2; + sample->data[ loop_start + sample->loop_length ] = sample->data[ loop_start ]; + } +} + +/* Deallocate the specified module. */ +void dispose_module( struct module *module ) { + int idx, sam; + struct instrument *instrument; + free( module->default_panning ); + free( module->sequence ); + if( module->patterns ) { + for( idx = 0; idx < module->num_patterns; idx++ ) { + free( module->patterns[ idx ].data ); + } + free( module->patterns ); + } + if( module->instruments ) { + for( idx = 0; idx <= module->num_instruments; idx++ ) { + instrument = &module->instruments[ idx ]; + if( instrument->samples ) { + for( sam = 0; sam < instrument->num_samples; sam++ ) { + free( instrument->samples[ sam ].data ); + } + free( instrument->samples ); + } + } + free( module->instruments ); + } + free( module ); +} + +static struct module* module_load_xm( struct data *data, char *message ) { + int delta_env, offset, next_offset, idx, entry; + int num_rows, num_notes, pat_data_len, pat_data_offset; + int sam, sam_head_offset, sam_data_bytes, sam_data_samples; + int num_samples, sam_loop_start, sam_loop_length, amp; + int note, flags, key, ins, vol, fxc, fxp; + int point, point_tick, point_offset; + int looped, ping_pong, sixteen_bit; + char ascii[ 16 ], *pattern_data; + struct instrument *instrument; + struct sample *sample; + struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); + if( module ) { + if( data_u16le( data, 58 ) != 0x0104 ) { + strcpy( message, "XM format version must be 0x0104!" ); + dispose_module( module ); + return NULL; + } + data_ascii( data, 17, 20, module->name ); + delta_env = !memcmp( data_ascii( data, 38, 15, ascii ), "DigiBooster Pro", 15 ); + offset = 60 + data_u32le( data, 60 ); + module->sequence_len = data_u16le( data, 64 ); + module->restart_pos = data_u16le( data, 66 ); + module->num_channels = data_u16le( data, 68 ); + module->num_patterns = data_u16le( data, 70 ); + module->num_instruments = data_u16le( data, 72 ); + module->linear_periods = data_u16le( data, 74 ) & 0x1; + module->default_gvol = 64; + module->default_speed = data_u16le( data, 76 ); + module->default_tempo = data_u16le( data, 78 ); + module->c2_rate = 8363; + module->gain = 64; + module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); + if( !module->default_panning ) { + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->num_channels; idx++ ) { + module->default_panning[ idx ] = 128; + } + module->sequence = (unsigned char*)calloc( module->sequence_len, sizeof( unsigned char ) ); + if( !module->sequence ) { + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->sequence_len; idx++ ) { + entry = data_u8( data, 80 + idx ); + module->sequence[ idx ] = entry < module->num_patterns ? entry : 0; + } + module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); + if( !module->patterns ) { + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->num_patterns; idx++ ) { + if( data_u8( data, offset + 4 ) ) { + strcpy( message, "Unknown pattern packing type!" ); + dispose_module( module ); + return NULL; + } + num_rows = data_u16le( data, offset + 5 ); + if( num_rows < 1 ) { + num_rows = 1; + } + pat_data_len = data_u16le( data, offset + 7 ); + offset += data_u32le( data, offset ); + next_offset = offset + pat_data_len; + num_notes = num_rows * module->num_channels; + pattern_data = (char*)calloc( num_notes, 5 ); + if( !pattern_data ) { + dispose_module( module ); + return NULL; + } + module->patterns[ idx ].num_channels = module->num_channels; + module->patterns[ idx ].num_rows = num_rows; + module->patterns[ idx ].data = pattern_data; + if( pat_data_len > 0 ) { + pat_data_offset = 0; + for( note = 0; note < num_notes; note++ ) { + flags = data_u8( data, offset ); + if( ( flags & 0x80 ) == 0 ) { + flags = 0x1F; + } else { + offset++; + } + key = ( flags & 0x01 ) > 0 ? data_u8( data, offset++ ) : 0; + pattern_data[ pat_data_offset++ ] = key; + ins = ( flags & 0x02 ) > 0 ? data_u8( data, offset++ ) : 0; + pattern_data[ pat_data_offset++ ] = ins; + vol = ( flags & 0x04 ) > 0 ? data_u8( data, offset++ ) : 0; + pattern_data[ pat_data_offset++ ] = vol; + fxc = ( flags & 0x08 ) > 0 ? data_u8( data, offset++ ) : 0; + fxp = ( flags & 0x10 ) > 0 ? data_u8( data, offset++ ) : 0; + if( fxc >= 0x40 ) { + fxc = fxp = 0; + } + pattern_data[ pat_data_offset++ ] = fxc; + pattern_data[ pat_data_offset++ ] = fxp; + } + } + offset = next_offset; + } + module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); + if( !module->instruments ) { + dispose_module( module ); + return NULL; + } + instrument = &module->instruments[ 0 ]; + instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + for( ins = 1; ins <= module->num_instruments; ins++ ) { + instrument = &module->instruments[ ins ]; + data_ascii( data, offset + 4, 22, instrument->name ); + num_samples = data_u16le( data, offset + 27 ); + instrument->num_samples = ( num_samples > 0 ) ? num_samples : 1; + instrument->samples = (struct sample*)calloc( instrument->num_samples, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + if( num_samples > 0 ) { + for( key = 0; key < 96; key++ ) { + instrument->key_to_sample[ key + 1 ] = data_u8( data, offset + 33 + key ); + } + point_tick = 0; + for( point = 0; point < 12; point++ ) { + point_offset = offset + 129 + ( point * 4 ); + point_tick = ( delta_env ? point_tick : 0 ) + data_u16le( data, point_offset ); + instrument->vol_env.points_tick[ point ] = point_tick; + instrument->vol_env.points_ampl[ point ] = data_u16le( data, point_offset + 2 ); + } + point_tick = 0; + for( point = 0; point < 12; point++ ) { + point_offset = offset + 177 + ( point * 4 ); + point_tick = ( delta_env ? point_tick : 0 ) + data_u16le( data, point_offset ); + instrument->pan_env.points_tick[ point ] = point_tick; + instrument->pan_env.points_ampl[ point ] = data_u16le( data, point_offset + 2 ); + } + instrument->vol_env.num_points = data_u8( data, offset + 225 ); + if( instrument->vol_env.num_points > 12 ) { + instrument->vol_env.num_points = 0; + } + instrument->pan_env.num_points = data_u8( data, offset + 226 ); + if( instrument->pan_env.num_points > 12 ) { + instrument->pan_env.num_points = 0; + } + instrument->vol_env.sustain_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 227 ) & 0xF ]; + instrument->vol_env.loop_start_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 228 ) & 0xF ]; + instrument->vol_env.loop_end_tick = instrument->vol_env.points_tick[ data_u8( data, offset + 229 ) & 0xF ]; + instrument->pan_env.sustain_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 230 ) & 0xF ]; + instrument->pan_env.loop_start_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 231 ) & 0xF ]; + instrument->pan_env.loop_end_tick = instrument->pan_env.points_tick[ data_u8( data, offset + 232 ) & 0xF ]; + instrument->vol_env.enabled = instrument->vol_env.num_points > 0 && ( data_u8( data, offset + 233 ) & 0x1 ); + instrument->vol_env.sustain = ( data_u8( data, offset + 233 ) & 0x2 ) > 0; + instrument->vol_env.looped = ( data_u8( data, offset + 233 ) & 0x4 ) > 0; + instrument->pan_env.enabled = instrument->pan_env.num_points > 0 && ( data_u8( data, offset + 234 ) & 0x1 ); + instrument->pan_env.sustain = ( data_u8( data, offset + 234 ) & 0x2 ) > 0; + instrument->pan_env.looped = ( data_u8( data, offset + 234 ) & 0x4 ) > 0; + instrument->vib_type = data_u8( data, offset + 235 ); + instrument->vib_sweep = data_u8( data, offset + 236 ); + instrument->vib_depth = data_u8( data, offset + 237 ); + instrument->vib_rate = data_u8( data, offset + 238 ); + instrument->vol_fadeout = data_u16le( data, offset + 239 ); + } + offset += data_u32le( data, offset ); + sam_head_offset = offset; + offset += num_samples * 40; + for( sam = 0; sam < num_samples; sam++ ) { + sample = &instrument->samples[ sam ]; + sam_data_bytes = data_u32le( data, sam_head_offset ); + sam_loop_start = data_u32le( data, sam_head_offset + 4 ); + sam_loop_length = data_u32le( data, sam_head_offset + 8 ); + sample->volume = data_u8( data, sam_head_offset + 12 ); + sample->fine_tune = data_s8( data, sam_head_offset + 13 ); + looped = ( data_u8( data, sam_head_offset + 14 ) & 0x3 ) > 0; + ping_pong = ( data_u8( data, sam_head_offset + 14 ) & 0x2 ) > 0; + sixteen_bit = ( data_u8( data, sam_head_offset + 14 ) & 0x10 ) > 0; + sample->panning = data_u8( data, sam_head_offset + 15 ) + 1; + sample->rel_note = data_s8( data, sam_head_offset + 16 ); + data_ascii( data, sam_head_offset + 18, 22, sample->name ); + sam_head_offset += 40; + sam_data_samples = sam_data_bytes; + if( sixteen_bit ) { + sam_data_samples = sam_data_samples >> 1; + sam_loop_start = sam_loop_start >> 1; + sam_loop_length = sam_loop_length >> 1; + } + if( !looped || ( sam_loop_start + sam_loop_length ) > sam_data_samples ) { + sam_loop_start = sam_data_samples; + sam_loop_length = 0; + } + sample->loop_start = sam_loop_start; + sample->loop_length = sam_loop_length; + sample->data = (short*)calloc( sam_data_samples + 1, sizeof( short ) ); + if( sample->data ) { + if( sixteen_bit ) { + data_sam_s16le( data, offset, sam_data_samples, sample->data ); + } else { + data_sam_s8( data, offset, sam_data_samples, sample->data ); + } + amp = 0; + for( idx = 0; idx < sam_data_samples; idx++ ) { + amp = amp + sample->data[ idx ]; + amp = ( amp & 0x7FFF ) - ( amp & 0x8000 ); + sample->data[ idx ] = amp; + } + sample->data[ sam_loop_start + sam_loop_length ] = sample->data[ sam_loop_start ]; + if( ping_pong ) { + sample_ping_pong( sample ); + } + } else { + dispose_module( module ); + return NULL; + } + offset += sam_data_bytes; + } + } + } + return module; +} + +static struct module* module_load_s3m( struct data *data, char *message ) { + int idx, module_data_idx, inst_offset, flags; + int version, sixteen_bit, tune, signed_samples; + int stereo_mode, default_pan, channel_map[ 32 ]; + int sample_offset, sample_length, loop_start, loop_length; + int pat_offset, note_offset, row, chan, token; + int key, ins, volume, effect, param, panning; + char *pattern_data; + struct instrument *instrument; + struct sample *sample; + struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); + if( module ) { + data_ascii( data, 0, 28, module->name ); + module->sequence_len = data_u16le( data, 32 ); + module->num_instruments = data_u16le( data, 34 ); + module->num_patterns = data_u16le( data, 36 ); + flags = data_u16le( data, 38 ); + version = data_u16le( data, 40 ); + module->fast_vol_slides = ( ( flags & 0x40 ) == 0x40 ) || version == 0x1300; + signed_samples = data_u16le( data, 42 ) == 1; + if( data_u32le( data, 44 ) != 0x4d524353 ) { + strcpy( message, "Not an S3M file!" ); + dispose_module( module ); + return NULL; + } + module->default_gvol = data_u8( data, 48 ); + module->default_speed = data_u8( data, 49 ); + module->default_tempo = data_u8( data, 50 ); + module->c2_rate = 8363; + module->gain = data_u8( data, 51 ) & 0x7F; + stereo_mode = ( data_u8( data, 51 ) & 0x80 ) == 0x80; + default_pan = data_u8( data, 53 ) == 0xFC; + for( idx = 0; idx < 32; idx++ ) { + channel_map[ idx ] = -1; + if( data_u8( data, 64 + idx ) < 16 ) { + channel_map[ idx ] = module->num_channels++; + } + } + module->sequence = (unsigned char*)calloc( module->sequence_len, sizeof( unsigned char ) ); + if( !module->sequence ){ + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->sequence_len; idx++ ) { + module->sequence[ idx ] = data_u8( data, 96 + idx ); + } + module_data_idx = 96 + module->sequence_len; + module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); + if( !module->instruments ) { + dispose_module( module ); + return NULL; + } + instrument = &module->instruments[ 0 ]; + instrument->num_samples = 1; + instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + for( ins = 1; ins <= module->num_instruments; ins++ ) { + instrument = &module->instruments[ ins ]; + instrument->num_samples = 1; + instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + sample = &instrument->samples[ 0 ]; + inst_offset = data_u16le( data, module_data_idx ) << 4; + module_data_idx += 2; + data_ascii( data, inst_offset + 48, 28, instrument->name ); + if( data_u8( data, inst_offset ) == 1 && data_u16le( data, inst_offset + 76 ) == 0x4353 ) { + sample_offset = ( data_u8( data, inst_offset + 13 ) << 20 ) + + ( data_u16le( data, inst_offset + 14 ) << 4 ); + sample_length = data_u32le( data, inst_offset + 16 ); + loop_start = data_u32le( data, inst_offset + 20 ); + loop_length = data_u32le( data, inst_offset + 24 ) - loop_start; + sample->volume = data_u8( data, inst_offset + 28 ); + if( data_u8( data, inst_offset + 30 ) != 0 ) { + strcpy( message, "Packed samples not supported!" ); + dispose_module( module ); + return NULL; + } + if( loop_start + loop_length > sample_length ) { + loop_length = sample_length - loop_start; + } + if( loop_length < 1 || !( data_u8( data, inst_offset + 31 ) & 0x1 ) ) { + loop_start = sample_length; + loop_length = 0; + } + sample->loop_start = loop_start; + sample->loop_length = loop_length; + /* stereo = data_u8( data, inst_offset + 31 ) & 0x2; */ + sixteen_bit = data_u8( data, inst_offset + 31 ) & 0x4; + tune = ( log_2( data_u32le( data, inst_offset + 32 ) ) - log_2( module->c2_rate ) ) * 12; + sample->rel_note = tune >> FP_SHIFT; + sample->fine_tune = ( tune & FP_MASK ) >> ( FP_SHIFT - 7 ); + sample->data = (short*)calloc( sample_length + 1, sizeof( short ) ); + if( sample->data ) { + if( sixteen_bit ) { + data_sam_s16le( data, sample_offset, sample_length, sample->data ); + } else { + data_sam_s8( data, sample_offset, sample_length, sample->data ); + } + if( !signed_samples ) { + for( idx = 0; idx < sample_length; idx++ ) { + sample->data[ idx ] = ( sample->data[ idx ] & 0xFFFF ) - 32768; + } + } + sample->data[ loop_start + loop_length ] = sample->data[ loop_start ]; + } else { + dispose_module( module ); + return NULL; + } + } + } + module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); + if( !module->patterns ) { + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->num_patterns; idx++ ) { + module->patterns[ idx ].num_channels = module->num_channels; + module->patterns[ idx ].num_rows = 64; + pattern_data = (char*)calloc( module->num_channels * 64, 5 ); + if( !pattern_data ) { + dispose_module( module ); + return NULL; + } + module->patterns[ idx ].data = pattern_data; + pat_offset = ( data_u16le( data, module_data_idx ) << 4 ) + 2; + row = 0; + while( row < 64 ) { + token = data_u8( data, pat_offset++ ); + if( token ) { + key = ins = 0; + if( ( token & 0x20 ) == 0x20 ) { + /* Key + Instrument.*/ + key = data_u8( data, pat_offset++ ); + ins = data_u8( data, pat_offset++ ); + if( key < 0xFE ) { + key = ( key >> 4 ) * 12 + ( key & 0xF ) + 1; + } else if( key == 0xFF ) { + key = 0; + } + } + volume = 0; + if( ( token & 0x40 ) == 0x40 ) { + /* Volume Column.*/ + volume = ( data_u8( data, pat_offset++ ) & 0x7F ) + 0x10; + if( volume > 0x50 ) { + volume = 0; + } + } + effect = param = 0; + if( ( token & 0x80 ) == 0x80 ) { + /* Effect + Param.*/ + effect = data_u8( data, pat_offset++ ); + param = data_u8( data, pat_offset++ ); + if( effect < 1 || effect >= 0x40 ) { + effect = param = 0; + } else if( effect > 0 ) { + effect += 0x80; + } + } + chan = channel_map[ token & 0x1F ]; + if( chan >= 0 ) { + note_offset = ( row * module->num_channels + chan ) * 5; + pattern_data[ note_offset ] = key; + pattern_data[ note_offset + 1 ] = ins; + pattern_data[ note_offset + 2 ] = volume; + pattern_data[ note_offset + 3 ] = effect; + pattern_data[ note_offset + 4 ] = param; + } + } else { + row++; + } + } + module_data_idx += 2; + } + module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); + if( module->default_panning ) { + for( chan = 0; chan < 32; chan++ ) { + if( channel_map[ chan ] >= 0 ) { + panning = 7; + if( stereo_mode ) { + panning = 12; + if( data_u8( data, 64 + chan ) < 8 ) { + panning = 3; + } + } + if( default_pan ) { + flags = data_u8( data, module_data_idx + chan ); + if( ( flags & 0x20 ) == 0x20 ) { + panning = flags & 0xF; + } + } + module->default_panning[ channel_map[ chan ] ] = panning * 17; + } + } + } else { + dispose_module( module ); + return NULL; + } + } + return module; +} + +static struct module* module_load_mod( struct data *data, char *message ) { + int idx, pat, module_data_idx, pat_data_len, pat_data_idx; + int period, key, ins, effect, param, fine_tune; + int sample_length, loop_start, loop_length; + char *pattern_data; + struct instrument *instrument; + struct sample *sample; + struct module *module = (struct module*)calloc( 1, sizeof( struct module ) ); + if( module ) { + data_ascii( data, 0, 20, module->name ); + module->sequence_len = data_u8( data, 950 ) & 0x7F; + module->restart_pos = data_u8( data, 951 ) & 0x7F; + if( module->restart_pos >= module->sequence_len ) { + module->restart_pos = 0; + } + module->sequence = (unsigned char*)calloc( 128, sizeof( unsigned char ) ); + if( !module->sequence ){ + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < 128; idx++ ) { + pat = data_u8( data, 952 + idx ) & 0x7F; + module->sequence[ idx ] = pat; + if( pat >= module->num_patterns ) { + module->num_patterns = pat + 1; + } + } + switch( data_u16be( data, 1082 ) ) { + case 0x4b2e: /* M.K. */ + case 0x4b21: /* M!K! */ + case 0x5434: /* FLT4 */ + module->num_channels = 4; + module->c2_rate = 8287; + module->gain = 64; + break; + case 0x484e: /* xCHN */ + module->num_channels = data_u8( data, 1080 ) - 48; + module->c2_rate = 8363; + module->gain = 32; + break; + case 0x4348: /* xxCH */ + module->num_channels = ( data_u8( data, 1080 ) - 48 ) * 10; + module->num_channels += data_u8( data, 1081 ) - 48; + module->c2_rate = 8363; + module->gain = 32; + break; + default: + strcpy( message, "MOD Format not recognised!" ); + dispose_module( module ); + return NULL; + } + module->default_gvol = 64; + module->default_speed = 6; + module->default_tempo = 125; + module->default_panning = (unsigned char*)calloc( module->num_channels, sizeof( unsigned char ) ); + if( !module->default_panning ) { + dispose_module( module ); + return NULL; + } + for( idx = 0; idx < module->num_channels; idx++ ) { + module->default_panning[ idx ] = 51; + if( ( idx & 3 ) == 1 || ( idx & 3 ) == 2 ) { + module->default_panning[ idx ] = 204; + } + } + module_data_idx = 1084; + module->patterns = (struct pattern*)calloc( module->num_patterns, sizeof( struct pattern ) ); + if( !module->patterns ) { + dispose_module( module ); + return NULL; + } + pat_data_len = module->num_channels * 64 * 5; + for( pat = 0; pat < module->num_patterns; pat++ ) { + module->patterns[ pat ].num_channels = module->num_channels; + module->patterns[ pat ].num_rows = 64; + pattern_data = (char*)calloc( 1, pat_data_len ); + if( !pattern_data ) { + dispose_module( module ); + return NULL; + } + module->patterns[ pat ].data = pattern_data; + for( pat_data_idx = 0; pat_data_idx < pat_data_len; pat_data_idx += 5 ) { + period = ( data_u8( data, module_data_idx ) & 0xF ) << 8; + period = ( period | data_u8( data, module_data_idx + 1 ) ) * 4; + if( period >= 112 && period <= 6848 ) { + key = -12 * log_2( ( period << FP_SHIFT ) / 29021 ); + key = ( key + ( key & ( FP_ONE >> 1 ) ) ) >> FP_SHIFT; + pattern_data[ pat_data_idx ] = key; + } + ins = ( data_u8( data, module_data_idx + 2 ) & 0xF0 ) >> 4; + ins = ins | ( data_u8( data, module_data_idx ) & 0x10 ); + pattern_data[ pat_data_idx + 1 ] = ins; + effect = data_u8( data, module_data_idx + 2 ) & 0x0F; + param = data_u8( data, module_data_idx + 3 ); + if( param == 0 && ( effect < 3 || effect == 0xA ) ) { + effect = 0; + } + if( param == 0 && ( effect == 5 || effect == 6 ) ) { + effect -= 2; + } + if( effect == 8 && module->num_channels == 4 ) { + effect = param = 0; + } + pattern_data[ pat_data_idx + 3 ] = effect; + pattern_data[ pat_data_idx + 4 ] = param; + module_data_idx += 4; + } + } + module->num_instruments = 31; + module->instruments = (struct instrument*)calloc( module->num_instruments + 1, sizeof( struct instrument ) ); + if( !module->instruments ) { + dispose_module( module ); + return NULL; + } + instrument = &module->instruments[ 0 ]; + instrument->num_samples = 1; + instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + for( ins = 1; ins <= module->num_instruments; ins++ ) { + instrument = &module->instruments[ ins ]; + instrument->num_samples = 1; + instrument->samples = (struct sample*)calloc( 1, sizeof( struct sample ) ); + if( !instrument->samples ) { + dispose_module( module ); + return NULL; + } + sample = &instrument->samples[ 0 ]; + data_ascii( data, ins * 30 - 10, 22, instrument->name ); + sample_length = data_u16be( data, ins * 30 + 12 ) * 2; + fine_tune = ( data_u8( data, ins * 30 + 14 ) & 0xF ) << 4; + sample->fine_tune = ( fine_tune & 0x7F ) - ( fine_tune & 0x80 ); + sample->volume = data_u8( data, ins * 30 + 15 ) & 0x7F; + if( sample->volume > 64 ) { + sample->volume = 64; + } + loop_start = data_u16be( data, ins * 30 + 16 ) * 2; + loop_length = data_u16be( data, ins * 30 + 18 ) * 2; + if( loop_start + loop_length > sample_length ) { + loop_length = sample_length - loop_start; + } + if( loop_length < 4 ) { + loop_start = sample_length; + loop_length = 0; + } + sample->loop_start = loop_start; + sample->loop_length = loop_length; + sample->data = (short*)calloc( sample_length + 1, sizeof( short ) ); + if( sample->data ) { + data_sam_s8( data, module_data_idx, sample_length, sample->data ); + sample->data[ loop_start + loop_length ] = sample->data[ loop_start ]; + } else { + dispose_module( module ); + return NULL; + } + module_data_idx += sample_length; + } + } + return module; +} + +/* Allocate and initialize a module from the specified data, returns NULL on error. + Message should point to a 64-character buffer to receive error messages. */ +struct module* module_load( struct data *data, char *message ) { + char ascii[ 16 ]; + struct module* module; + if( !memcmp( data_ascii( data, 0, 16, ascii ), "Extended Module:", 16 ) ) { + module = module_load_xm( data, message ); + } else if( !memcmp( data_ascii( data, 44, 4, ascii ), "SCRM", 4 ) ) { + module = module_load_s3m( data, message ); + } else { + module = module_load_mod( data, message ); + } + return module; +} + +static void pattern_get_note( struct pattern *pattern, int row, int chan, struct note *dest ) { + int offset = ( row * pattern->num_channels + chan ) * 5; + if( offset >= 0 && row < pattern->num_rows && chan < pattern->num_channels ) { + dest->key = pattern->data[ offset ]; + dest->instrument = pattern->data[ offset + 1 ]; + dest->volume = pattern->data[ offset + 2 ]; + dest->effect = pattern->data[ offset + 3 ]; + dest->param = pattern->data[ offset + 4 ]; + } else { + memset( dest, 0, sizeof( struct note ) ); + } +} + +static void channel_init( struct channel *channel, struct replay *replay, int idx ) { + memset( channel, 0, sizeof( struct channel ) ); + channel->replay = replay; + channel->id = idx; + channel->panning = replay->module->default_panning[ idx ]; + channel->instrument = &replay->module->instruments[ 0 ]; + channel->sample = &channel->instrument->samples[ 0 ]; + channel->random_seed = ( idx + 1 ) * 0xABCDEF; +} + +static void channel_volume_slide( struct channel *channel ) { + int up = channel->vol_slide_param >> 4; + int down = channel->vol_slide_param & 0xF; + if( down == 0xF && up > 0 ) { + /* Fine slide up.*/ + if( channel->fx_count == 0 ) { + channel->volume += up; + } + } else if( up == 0xF && down > 0 ) { + /* Fine slide down.*/ + if( channel->fx_count == 0 ) { + channel->volume -= down; + } + } else if( channel->fx_count > 0 || channel->replay->module->fast_vol_slides ) { + /* Normal.*/ + channel->volume += up - down; + } + if( channel->volume > 64 ) { + channel->volume = 64; + } + if( channel->volume < 0 ) { + channel->volume = 0; + } +} + +static void channel_porta_up( struct channel *channel, int param ) { + switch( param & 0xF0 ) { + case 0xE0: /* Extra-fine porta.*/ + if( channel->fx_count == 0 ) { + channel->period -= param & 0xF; + } + break; + case 0xF0: /* Fine porta.*/ + if( channel->fx_count == 0 ) { + channel->period -= ( param & 0xF ) << 2; + } + break; + default:/* Normal porta.*/ + if( channel->fx_count > 0 ) { + channel->period -= param << 2; + } + break; + } + if( channel->period < 0 ) { + channel->period = 0; + } +} + +static void channel_porta_down( struct channel *channel, int param ) { + if( channel->period > 0 ) { + switch( param & 0xF0 ) { + case 0xE0: /* Extra-fine porta.*/ + if( channel->fx_count == 0 ) { + channel->period += param & 0xF; + } + break; + case 0xF0: /* Fine porta.*/ + if( channel->fx_count == 0 ) { + channel->period += ( param & 0xF ) << 2; + } + break; + default:/* Normal porta.*/ + if( channel->fx_count > 0 ) { + channel->period += param << 2; + } + break; + } + if( channel->period > 65535 ) { + channel->period = 65535; + } + } +} + +static void channel_tone_porta( struct channel *channel ) { + if( channel->period > 0 ) { + if( channel->period < channel->porta_period ) { + channel->period += channel->tone_porta_param << 2; + if( channel->period > channel->porta_period ) { + channel->period = channel->porta_period; + } + } else { + channel->period -= channel->tone_porta_param << 2; + if( channel->period < channel->porta_period ) { + channel->period = channel->porta_period; + } + } + } +} + +static int channel_waveform( struct channel *channel, int phase, int type ) { + int amplitude = 0; + switch( type ) { + default: /* Sine. */ + amplitude = sine_table[ phase & 0x1F ]; + if( ( phase & 0x20 ) > 0 ) { + amplitude = -amplitude; + } + break; + case 6: /* Saw Up.*/ + amplitude = ( ( ( phase + 0x20 ) & 0x3F ) << 3 ) - 255; + break; + case 1: case 7: /* Saw Down. */ + amplitude = 255 - ( ( ( phase + 0x20 ) & 0x3F ) << 3 ); + break; + case 2: case 5: /* Square. */ + amplitude = ( phase & 0x20 ) > 0 ? 255 : -255; + break; + case 3: case 8: /* Random. */ + amplitude = ( channel->random_seed >> 20 ) - 255; + channel->random_seed = ( channel->random_seed * 65 + 17 ) & 0x1FFFFFFF; + break; + } + return amplitude; +} + +static void channel_vibrato( struct channel *channel, int fine ) { + int wave = channel_waveform( channel, channel->vibrato_phase, channel->vibrato_type & 0x3 ); + channel->vibrato_add = wave * channel->vibrato_depth >> ( fine ? 7 : 5 ); +} + +static void channel_tremolo( struct channel *channel ) { + int wave = channel_waveform( channel, channel->tremolo_phase, channel->tremolo_type & 0x3 ); + channel->tremolo_add = wave * channel->tremolo_depth >> 6; +} + +static void channel_tremor( struct channel *channel ) { + if( channel->retrig_count >= channel->tremor_on_ticks ) { + channel->tremolo_add = -64; + } + if( channel->retrig_count >= ( channel->tremor_on_ticks + channel->tremor_off_ticks ) ) { + channel->tremolo_add = channel->retrig_count = 0; + } +} + +static void channel_retrig_vol_slide( struct channel *channel ) { + if( channel->retrig_count >= channel->retrig_ticks ) { + channel->retrig_count = channel->sample_idx = channel->sample_fra = 0; + switch( channel->retrig_volume ) { + case 0x1: channel->volume = channel->volume - 1; break; + case 0x2: channel->volume = channel->volume - 2; break; + case 0x3: channel->volume = channel->volume - 4; break; + case 0x4: channel->volume = channel->volume - 8; break; + case 0x5: channel->volume = channel->volume - 16; break; + case 0x6: channel->volume = channel->volume * 2 / 3; break; + case 0x7: channel->volume = channel->volume >> 1; break; + case 0x8: /* ? */ break; + case 0x9: channel->volume = channel->volume + 1; break; + case 0xA: channel->volume = channel->volume + 2; break; + case 0xB: channel->volume = channel->volume + 4; break; + case 0xC: channel->volume = channel->volume + 8; break; + case 0xD: channel->volume = channel->volume + 16; break; + case 0xE: channel->volume = channel->volume * 3 / 2; break; + case 0xF: channel->volume = channel->volume << 1; break; + } + if( channel->volume < 0 ) { + channel->volume = 0; + } + if( channel->volume > 64 ) { + channel->volume = 64; + } + } +} + +static void channel_trigger( struct channel *channel ) { + int key, sam, porta, period, fine_tune, ins = channel->note.instrument; + struct sample *sample; + if( ins > 0 && ins <= channel->replay->module->num_instruments ) { + channel->instrument = &channel->replay->module->instruments[ ins ]; + key = channel->note.key < 97 ? channel->note.key : 0; + sam = channel->instrument->key_to_sample[ key ]; + sample = &channel->instrument->samples[ sam ]; + channel->volume = sample->volume >= 64 ? 64 : sample->volume & 0x3F; + if( sample->panning > 0 ) { + channel->panning = ( sample->panning - 1 ) & 0xFF; + } + if( channel->period > 0 && sample->loop_length > 1 ) { + /* Amiga trigger.*/ + channel->sample = sample; + } + channel->sample_off = 0; + channel->vol_env_tick = channel->pan_env_tick = 0; + channel->fadeout_vol = 32768; + channel->key_on = 1; + } + if( channel->note.effect == 0x09 || channel->note.effect == 0x8F ) { + /* Set Sample Offset. */ + if( channel->note.param > 0 ) { + channel->offset_param = channel->note.param; + } + channel->sample_off = channel->offset_param << 8; + } + if( channel->note.volume >= 0x10 && channel->note.volume < 0x60 ) { + channel->volume = channel->note.volume < 0x50 ? channel->note.volume - 0x10 : 64; + } + switch( channel->note.volume & 0xF0 ) { + case 0x80: /* Fine Vol Down.*/ + channel->volume -= channel->note.volume & 0xF; + if( channel->volume < 0 ) { + channel->volume = 0; + } + break; + case 0x90: /* Fine Vol Up.*/ + channel->volume += channel->note.volume & 0xF; + if( channel->volume > 64 ) { + channel->volume = 64; + } + break; + case 0xA0: /* Set Vibrato Speed.*/ + if( ( channel->note.volume & 0xF ) > 0 ) { + channel->vibrato_speed = channel->note.volume & 0xF; + } + break; + case 0xB0: /* Vibrato.*/ + if( ( channel->note.volume & 0xF ) > 0 ) { + channel->vibrato_depth = channel->note.volume & 0xF; + } + channel_vibrato( channel, 0 ); + break; + case 0xC0: /* Set Panning.*/ + channel->panning = ( channel->note.volume & 0xF ) * 17; + break; + case 0xF0: /* Tone Porta.*/ + if( ( channel->note.volume & 0xF ) > 0 ) { + channel->tone_porta_param = channel->note.volume & 0xF; + } + break; + } + if( channel->note.key > 0 ) { + if( channel->note.key > 96 ) { + channel->key_on = 0; + } else { + porta = ( channel->note.volume & 0xF0 ) == 0xF0 || + channel->note.effect == 0x03 || channel->note.effect == 0x05 || + channel->note.effect == 0x87 || channel->note.effect == 0x8C; + if( !porta ) { + ins = channel->instrument->key_to_sample[ channel->note.key ]; + channel->sample = &channel->instrument->samples[ ins ]; + } + fine_tune = channel->sample->fine_tune; + if( channel->note.effect == 0x75 || channel->note.effect == 0xF2 ) { + /* Set Fine Tune. */ + fine_tune = ( ( channel->note.param & 0xF ) << 4 ) - 128; + } + key = channel->note.key + channel->sample->rel_note; + if( key < 1 ) { + key = 1; + } + if( key > 120 ) { + key = 120; + } + period = ( key << 6 ) + ( fine_tune >> 1 ); + if( channel->replay->module->linear_periods ) { + channel->porta_period = 7744 - period; + } else { + channel->porta_period = 29021 * exp_2( ( period << FP_SHIFT ) / -768 ) >> FP_SHIFT; + } + if( !porta ) { + channel->period = channel->porta_period; + channel->sample_idx = channel->sample_off; + channel->sample_fra = 0; + if( channel->vibrato_type < 4 ) { + channel->vibrato_phase = 0; + } + if( channel->tremolo_type < 4 ) { + channel->tremolo_phase = 0; + } + channel->retrig_count = channel->av_count = 0; + } + } + } +} + +static void channel_update_envelopes( struct channel *channel ) { + if( channel->instrument->vol_env.enabled ) { + if( !channel->key_on ) { + channel->fadeout_vol -= channel->instrument->vol_fadeout; + if( channel->fadeout_vol < 0 ) { + channel->fadeout_vol = 0; + } + } + channel->vol_env_tick = envelope_next_tick( &channel->instrument->vol_env, + channel->vol_env_tick, channel->key_on ); + } + if( channel->instrument->pan_env.enabled ) { + channel->pan_env_tick = envelope_next_tick( &channel->instrument->pan_env, + channel->pan_env_tick, channel->key_on ); + } +} + +static void channel_auto_vibrato( struct channel *channel ) { + int sweep, rate, type, wave; + int depth = channel->instrument->vib_depth & 0x7F; + if( depth > 0 ) { + sweep = channel->instrument->vib_sweep & 0x7F; + rate = channel->instrument->vib_rate & 0x7F; + type = channel->instrument->vib_type; + if( channel->av_count < sweep ) { + depth = depth * channel->av_count / sweep; + } + wave = channel_waveform( channel, channel->av_count * rate >> 2, type + 4 ); + channel->vibrato_add += wave * depth >> 8; + channel->av_count++; + } +} + +static void channel_calculate_freq( struct channel *channel ) { + int per = channel->period + channel->vibrato_add; + if( channel->replay->module->linear_periods ) { + per = per - ( channel->arpeggio_add << 6 ); + if( per < 28 || per > 7680 ) { + per = 7680; + } + channel->freq = ( ( channel->replay->module->c2_rate >> 4 ) + * exp_2( ( ( 4608 - per ) << FP_SHIFT ) / 768 ) ) >> ( FP_SHIFT - 4 ); + } else { + if( per > 29021 ) { + per = 29021; + } + per = ( per << FP_SHIFT ) / exp_2( ( channel->arpeggio_add << FP_SHIFT ) / 12 ); + if( per < 28 ) { + per = 29021; + } + channel->freq = channel->replay->module->c2_rate * 1712 / per; + } +} + +static void channel_calculate_ampl( struct channel *channel ) { + int vol, range, env_pan = 32, env_vol = channel->key_on ? 64 : 0; + if( channel->instrument->vol_env.enabled ) { + env_vol = envelope_calculate_ampl( &channel->instrument->vol_env, channel->vol_env_tick ); + } + vol = channel->volume + channel->tremolo_add; + if( vol > 64 ) { + vol = 64; + } + if( vol < 0 ) { + vol = 0; + } + vol = ( vol * channel->replay->module->gain * FP_ONE ) >> 13; + vol = ( vol * channel->fadeout_vol ) >> 15; + channel->ampl = ( vol * channel->replay->global_vol * env_vol ) >> 12; + if( channel->instrument->pan_env.enabled ) { + env_pan = envelope_calculate_ampl( &channel->instrument->pan_env, channel->pan_env_tick ); + } + range = ( channel->panning < 128 ) ? channel->panning : ( 255 - channel->panning ); + channel->pann = channel->panning + ( range * ( env_pan - 32 ) >> 5 ); +} + +static void channel_tick( struct channel *channel ) { + channel->vibrato_add = 0; + channel->fx_count++; + channel->retrig_count++; + if( !( channel->note.effect == 0x7D && channel->fx_count <= channel->note.param ) ) { + switch( channel->note.volume & 0xF0 ) { + case 0x60: /* Vol Slide Down.*/ + channel->volume -= channel->note.volume & 0xF; + if( channel->volume < 0 ) { + channel->volume = 0; + } + break; + case 0x70: /* Vol Slide Up.*/ + channel->volume += channel->note.volume & 0xF; + if( channel->volume > 64 ) { + channel->volume = 64; + } + break; + case 0xB0: /* Vibrato.*/ + channel->vibrato_phase += channel->vibrato_speed; + channel_vibrato( channel, 0 ); + break; + case 0xD0: /* Pan Slide Left.*/ + channel->panning -= channel->note.volume & 0xF; + if( channel->panning < 0 ) { + channel->panning = 0; + } + break; + case 0xE0: /* Pan Slide Right.*/ + channel->panning += channel->note.volume & 0xF; + if( channel->panning > 255 ) { + channel->panning = 255; + } + break; + case 0xF0: /* Tone Porta.*/ + channel_tone_porta( channel ); + break; + } + } + switch( channel->note.effect ) { + case 0x01: case 0x86: /* Porta Up. */ + channel_porta_up( channel, channel->porta_up_param ); + break; + case 0x02: case 0x85: /* Porta Down. */ + channel_porta_down( channel, channel->porta_down_param ); + break; + case 0x03: case 0x87: /* Tone Porta. */ + channel_tone_porta( channel ); + break; + case 0x04: case 0x88: /* Vibrato. */ + channel->vibrato_phase += channel->vibrato_speed; + channel_vibrato( channel, 0 ); + break; + case 0x05: case 0x8C: /* Tone Porta + Vol Slide. */ + channel_tone_porta( channel ); + channel_volume_slide( channel ); + break; + case 0x06: case 0x8B: /* Vibrato + Vol Slide. */ + channel->vibrato_phase += channel->vibrato_speed; + channel_vibrato( channel, 0 ); + channel_volume_slide( channel ); + break; + case 0x07: case 0x92: /* Tremolo. */ + channel->tremolo_phase += channel->tremolo_speed; + channel_tremolo( channel ); + break; + case 0x0A: case 0x84: /* Vol Slide. */ + channel_volume_slide( channel ); + break; + case 0x11: /* Global Volume Slide. */ + channel->replay->global_vol = channel->replay->global_vol + + ( channel->gvol_slide_param >> 4 ) + - ( channel->gvol_slide_param & 0xF ); + if( channel->replay->global_vol < 0 ) { + channel->replay->global_vol = 0; + } + if( channel->replay->global_vol > 64 ) { + channel->replay->global_vol = 64; + } + break; + case 0x19: /* Panning Slide. */ + channel->panning = channel->panning + + ( channel->pan_slide_param >> 4 ) + - ( channel->pan_slide_param & 0xF ); + if( channel->panning < 0 ) { + channel->panning = 0; + } + if( channel->panning > 255 ) { + channel->panning = 255; + } + break; + case 0x1B: case 0x91: /* Retrig + Vol Slide. */ + channel_retrig_vol_slide( channel ); + break; + case 0x1D: case 0x89: /* Tremor. */ + channel_tremor( channel ); + break; + case 0x79: /* Retrig. */ + if( channel->fx_count >= channel->note.param ) { + channel->fx_count = 0; + channel->sample_idx = channel->sample_fra = 0; + } + break; + case 0x7C: case 0xFC: /* Note Cut. */ + if( channel->note.param == channel->fx_count ) { + channel->volume = 0; + } + break; + case 0x7D: case 0xFD: /* Note Delay. */ + if( channel->note.param == channel->fx_count ) { + channel_trigger( channel ); + } + break; + case 0x8A: /* Arpeggio. */ + if( channel->fx_count == 1 ) { + channel->arpeggio_add = channel->arpeggio_param >> 4; + } else if( channel->fx_count == 2 ) { + channel->arpeggio_add = channel->arpeggio_param & 0xF; + } else { + channel->arpeggio_add = channel->fx_count = 0; + } + break; + case 0x95: /* Fine Vibrato. */ + channel->vibrato_phase += channel->vibrato_speed; + channel_vibrato( channel, 1 ); + break; + } + channel_auto_vibrato( channel ); + channel_calculate_freq( channel ); + channel_calculate_ampl( channel ); + channel_update_envelopes( channel ); +} + +static void channel_row( struct channel *channel, struct note *note ) { + channel->note = *note; + channel->retrig_count++; + channel->vibrato_add = channel->tremolo_add = channel->arpeggio_add = channel->fx_count = 0; + if( !( ( note->effect == 0x7D || note->effect == 0xFD ) && note->param > 0 ) ) { + /* Not note delay.*/ + channel_trigger( channel ); + } + switch( channel->note.effect ) { + case 0x01: case 0x86: /* Porta Up. */ + if( channel->note.param > 0 ) { + channel->porta_up_param = channel->note.param; + } + channel_porta_up( channel, channel->porta_up_param ); + break; + case 0x02: case 0x85: /* Porta Down. */ + if( channel->note.param > 0 ) { + channel->porta_down_param = channel->note.param; + } + channel_porta_down( channel, channel->porta_down_param ); + break; + case 0x03: case 0x87: /* Tone Porta. */ + if( channel->note.param > 0 ) { + channel->tone_porta_param = channel->note.param; + } + break; + case 0x04: case 0x88: /* Vibrato. */ + if( ( channel->note.param >> 4 ) > 0 ) { + channel->vibrato_speed = channel->note.param >> 4; + } + if( ( channel->note.param & 0xF ) > 0 ) { + channel->vibrato_depth = channel->note.param & 0xF; + } + channel_vibrato( channel, 0 ); + break; + case 0x05: case 0x8C: /* Tone Porta + Vol Slide. */ + if( channel->note.param > 0 ) { + channel->vol_slide_param = channel->note.param; + } + channel_volume_slide( channel ); + break; + case 0x06: case 0x8B: /* Vibrato + Vol Slide. */ + if( channel->note.param > 0 ) { + channel->vol_slide_param = channel->note.param; + } + channel_vibrato( channel, 0 ); + channel_volume_slide( channel ); + break; + case 0x07: case 0x92: /* Tremolo. */ + if( ( channel->note.param >> 4 ) > 0 ) { + channel->tremolo_speed = channel->note.param >> 4; + } + if( ( channel->note.param & 0xF ) > 0 ) { + channel->tremolo_depth = channel->note.param & 0xF; + } + channel_tremolo( channel ); + break; + case 0x08: /* Set Panning.*/ + channel->panning = ( channel->note.param < 128 ) ? ( channel->note.param << 1 ) : 255; + break; + case 0x0A: case 0x84: /* Vol Slide. */ + if( channel->note.param > 0 ) { + channel->vol_slide_param = channel->note.param; + } + channel_volume_slide( channel ); + break; + case 0x0C: /* Set Volume. */ + channel->volume = channel->note.param >= 64 ? 64 : channel->note.param & 0x3F; + break; + case 0x10: case 0x96: /* Set Global Volume. */ + channel->replay->global_vol = channel->note.param >= 64 ? 64 : channel->note.param & 0x3F; + break; + case 0x11: /* Global Volume Slide. */ + if( channel->note.param > 0 ) { + channel->gvol_slide_param = channel->note.param; + } + break; + case 0x14: /* Key Off. */ + channel->key_on = 0; + break; + case 0x15: /* Set Envelope Tick. */ + channel->vol_env_tick = channel->pan_env_tick = channel->note.param & 0xFF; + break; + case 0x19: /* Panning Slide. */ + if( channel->note.param > 0 ) { + channel->pan_slide_param = channel->note.param; + } + break; + case 0x1B: case 0x91: /* Retrig + Vol Slide. */ + if( ( channel->note.param >> 4 ) > 0 ) { + channel->retrig_volume = channel->note.param >> 4; + } + if( ( channel->note.param & 0xF ) > 0 ) { + channel->retrig_ticks = channel->note.param & 0xF; + } + channel_retrig_vol_slide( channel ); + break; + case 0x1D: case 0x89: /* Tremor. */ + if( ( channel->note.param >> 4 ) > 0 ) { + channel->tremor_on_ticks = channel->note.param >> 4; + } + if( ( channel->note.param & 0xF ) > 0 ) { + channel->tremor_off_ticks = channel->note.param & 0xF; + } + channel_tremor( channel ); + break; + case 0x21: /* Extra Fine Porta. */ + if( channel->note.param > 0 ) { + channel->xfine_porta_param = channel->note.param; + } + switch( channel->xfine_porta_param & 0xF0 ) { + case 0x10: + channel_porta_up( channel, 0xE0 | ( channel->xfine_porta_param & 0xF ) ); + break; + case 0x20: + channel_porta_down( channel, 0xE0 | ( channel->xfine_porta_param & 0xF ) ); + break; + } + break; + case 0x71: /* Fine Porta Up. */ + if( channel->note.param > 0 ) { + channel->fine_porta_up_param = channel->note.param; + } + channel_porta_up( channel, 0xF0 | ( channel->fine_porta_up_param & 0xF ) ); + break; + case 0x72: /* Fine Porta Down. */ + if( channel->note.param > 0 ) { + channel->fine_porta_down_param = channel->note.param; + } + channel_porta_down( channel, 0xF0 | ( channel->fine_porta_down_param & 0xF ) ); + break; + case 0x74: case 0xF3: /* Set Vibrato Waveform. */ + if( channel->note.param < 8 ) { + channel->vibrato_type = channel->note.param; + } + break; + case 0x77: case 0xF4: /* Set Tremolo Waveform. */ + if( channel->note.param < 8 ) { + channel->tremolo_type = channel->note.param; + } + break; + case 0x7A: /* Fine Vol Slide Up. */ + if( channel->note.param > 0 ) { + channel->fine_vslide_up_param = channel->note.param; + } + channel->volume += channel->fine_vslide_up_param; + if( channel->volume > 64 ) { + channel->volume = 64; + } + break; + case 0x7B: /* Fine Vol Slide Down. */ + if( channel->note.param > 0 ) { + channel->fine_vslide_down_param = channel->note.param; + } + channel->volume -= channel->fine_vslide_down_param; + if( channel->volume < 0 ) { + channel->volume = 0; + } + break; + case 0x7C: case 0xFC: /* Note Cut. */ + if( channel->note.param <= 0 ) { + channel->volume = 0; + } + break; + case 0x8A: /* Arpeggio. */ + if( channel->note.param > 0 ) { + channel->arpeggio_param = channel->note.param; + } + break; + case 0x95: /* Fine Vibrato.*/ + if( ( channel->note.param >> 4 ) > 0 ) { + channel->vibrato_speed = channel->note.param >> 4; + } + if( ( channel->note.param & 0xF ) > 0 ) { + channel->vibrato_depth = channel->note.param & 0xF; + } + channel_vibrato( channel, 1 ); + break; + case 0xF8: /* Set Panning. */ + channel->panning = channel->note.param * 17; + break; + } + channel_auto_vibrato( channel ); + channel_calculate_freq( channel ); + channel_calculate_ampl( channel ); + channel_update_envelopes( channel ); +} + +static void channel_resample( struct channel *channel, int *mix_buf, + int offset, int count, int sample_rate, int interpolate ) { + struct sample *sample = channel->sample; + int l_gain, r_gain, sam_idx, sam_fra, step; + int loop_len, loop_end, out_idx, out_end, y, m, c; + short *sample_data = channel->sample->data; + if( channel->ampl > 0 ) { + l_gain = channel->ampl * ( 255 - channel->pann ) >> 8; + r_gain = channel->ampl * channel->pann >> 8; + sam_idx = channel->sample_idx; + sam_fra = channel->sample_fra; + step = ( channel->freq << ( FP_SHIFT - 3 ) ) / ( sample_rate >> 3 ); + loop_len = sample->loop_length; + loop_end = sample->loop_start + loop_len; + out_idx = offset * 2; + out_end = ( offset + count ) * 2; + if( interpolate ) { + while( out_idx < out_end ) { + if( sam_idx >= loop_end ) { + if( loop_len > 1 ) { + while( sam_idx >= loop_end ) { + sam_idx -= loop_len; + } + } else { + break; + } + } + c = sample_data[ sam_idx ]; + m = sample_data[ sam_idx + 1 ] - c; + y = ( ( m * sam_fra ) >> FP_SHIFT ) + c; + mix_buf[ out_idx++ ] += ( y * l_gain ) >> FP_SHIFT; + mix_buf[ out_idx++ ] += ( y * r_gain ) >> FP_SHIFT; + sam_fra += step; + sam_idx += sam_fra >> FP_SHIFT; + sam_fra &= FP_MASK; + } + } else { + while( out_idx < out_end ) { + if( sam_idx >= loop_end ) { + if( loop_len > 1 ) { + while( sam_idx >= loop_end ) { + sam_idx -= loop_len; + } + } else { + break; + } + } + y = sample_data[ sam_idx ]; + mix_buf[ out_idx++ ] += ( y * l_gain ) >> FP_SHIFT; + mix_buf[ out_idx++ ] += ( y * r_gain ) >> FP_SHIFT; + sam_fra += step; + sam_idx += sam_fra >> FP_SHIFT; + sam_fra &= FP_MASK; + } + } + } +} + +static void channel_update_sample_idx( struct channel *channel, int count, int sample_rate ) { + struct sample *sample = channel->sample; + int step = ( channel->freq << ( FP_SHIFT - 3 ) ) / ( sample_rate >> 3 ); + channel->sample_fra += step * count; + channel->sample_idx += channel->sample_fra >> FP_SHIFT; + if( channel->sample_idx > sample->loop_start ) { + if( sample->loop_length > 1 ) { + channel->sample_idx = sample->loop_start + + ( channel->sample_idx - sample->loop_start ) % sample->loop_length; + } else { + channel->sample_idx = sample->loop_start; + } + } + channel->sample_fra &= FP_MASK; +} + +static void replay_row( struct replay *replay ) { + int idx, count; + struct note note; + struct pattern *pattern; + struct channel *channel; + struct module *module = replay->module; + if( replay->next_row < 0 ) { + replay->break_pos = replay->seq_pos + 1; + replay->next_row = 0; + } + if( replay->break_pos >= 0 ) { + if( replay->break_pos >= module->sequence_len ) { + replay->break_pos = replay->next_row = 0; + } + while( module->sequence[ replay->break_pos ] >= module->num_patterns ) { + replay->break_pos++; + if( replay->break_pos >= module->sequence_len ) { + replay->break_pos = replay->next_row = 0; + } + } + replay->seq_pos = replay->break_pos; + for( idx = 0; idx < module->num_channels; idx++ ) { + replay->channels[ idx ].pl_row = 0; + } + replay->break_pos = -1; + } + pattern = &module->patterns[ module->sequence[ replay->seq_pos ] ]; + replay->row = replay->next_row; + if( replay->row >= pattern->num_rows ) { + replay->row = 0; + } + if( replay->play_count && replay->play_count[ 0 ] ) { + count = replay->play_count[ replay->seq_pos ][ replay->row ]; + if( replay->pl_count < 0 && count < 127 ) { + replay->play_count[ replay->seq_pos ][ replay->row ] = count + 1; + } + } + replay->next_row = replay->row + 1; + if( replay->next_row >= pattern->num_rows ) { + replay->next_row = -1; + } + for( idx = 0; idx < module->num_channels; idx++ ) { + channel = &replay->channels[ idx ]; + pattern_get_note( pattern, replay->row, idx, ¬e ); + if( note.effect == 0xE ) { + note.effect = 0x70 | ( note.param >> 4 ); + note.param &= 0xF; + } + if( note.effect == 0x93 ) { + note.effect = 0xF0 | ( note.param >> 4 ); + note.param &= 0xF; + } + if( note.effect == 0 && note.param > 0 ) { + note.effect = 0x8A; + } + channel_row( channel, ¬e ); + switch( note.effect ) { + case 0x81: /* Set Speed. */ + if( note.param > 0 ) { + replay->tick = replay->speed = note.param; + } + break; + case 0xB: case 0x82: /* Pattern Jump.*/ + if( replay->pl_count < 0 ) { + replay->break_pos = note.param; + replay->next_row = 0; + } + break; + case 0xD: case 0x83: /* Pattern Break.*/ + if( replay->pl_count < 0 ) { + if( replay->break_pos < 0 ) { + replay->break_pos = replay->seq_pos + 1; + } + replay->next_row = ( note.param >> 4 ) * 10 + ( note.param & 0xF ); + } + break; + case 0xF: /* Set Speed/Tempo.*/ + if( note.param > 0 ) { + if( note.param < 32 ) { + replay->tick = replay->speed = note.param; + } else { + replay->tempo = note.param; + } + } + break; + case 0x94: /* Set Tempo.*/ + if( note.param > 32 ) { + replay->tempo = note.param; + } + break; + case 0x76: case 0xFB : /* Pattern Loop.*/ + if( note.param == 0 ) { + /* Set loop marker on this channel. */ + channel->pl_row = replay->row; + } + if( channel->pl_row < replay->row && replay->break_pos < 0 ) { + /* Marker valid. */ + if( replay->pl_count < 0 ) { + /* Not already looping, begin. */ + replay->pl_count = note.param; + replay->pl_chan = idx; + } + if( replay->pl_chan == idx ) { + /* Next Loop.*/ + if( replay->pl_count == 0 ) { + /* Loop finished. Invalidate current marker. */ + channel->pl_row = replay->row + 1; + } else { + /* Loop. */ + replay->next_row = channel->pl_row; + } + replay->pl_count--; + } + } + break; + case 0x7E: case 0xFE: /* Pattern Delay.*/ + replay->tick = replay->speed + replay->speed * note.param; + break; + } + } +} + +static int replay_tick( struct replay *replay ) { + int idx, num_channels, count = 1; + if( --replay->tick <= 0 ) { + replay->tick = replay->speed; + replay_row( replay ); + } else { + num_channels = replay->module->num_channels; + for( idx = 0; idx < num_channels; idx++ ) { + channel_tick( &replay->channels[ idx ] ); + } + } + if( replay->play_count && replay->play_count[ 0 ] ) { + count = replay->play_count[ replay->seq_pos ][ replay->row ] - 1; + } + return count; +} + +static int module_init_play_count( struct module *module, char **play_count ) { + int idx, pat, rows, len = 0; + for( idx = 0; idx < module->sequence_len; idx++ ) { + pat = module->sequence[ idx ]; + rows = ( pat < module->num_patterns ) ? module->patterns[ pat ].num_rows : 0; + if( play_count ) { + play_count[ idx ] = play_count[ 0 ] ? &play_count[ 0 ][ len ] : NULL; + } + len += rows; + } + return len; +} + +/* Set the pattern in the sequence to play. The tempo is reset to the default. */ +void replay_set_sequence_pos( struct replay *replay, int pos ) { + int idx; + struct module *module = replay->module; + if( pos >= module->sequence_len ) { + pos = 0; + } + replay->break_pos = pos; + replay->next_row = 0; + replay->tick = 1; + replay->global_vol = module->default_gvol; + replay->speed = module->default_speed > 0 ? module->default_speed : 6; + replay->tempo = module->default_tempo > 0 ? module->default_tempo : 125; + replay->pl_count = replay->pl_chan = -1; + if( replay->play_count ) { + free( replay->play_count[ 0 ] ); + free( replay->play_count ); + } + replay->play_count = (char**)calloc( module->sequence_len, sizeof( char * ) ); + if( replay->play_count ) { + replay->play_count[ 0 ] = (char*)calloc( module_init_play_count( module, NULL ), sizeof( char ) ); + module_init_play_count( module, replay->play_count ); + } + for( idx = 0; idx < module->num_channels; idx++ ) { + channel_init( &replay->channels[ idx ], replay, idx ); + } + memset( replay->ramp_buf, 0, 128 * sizeof( int ) ); + replay_tick( replay ); +} + +/* Deallocate the specified replay. */ +void dispose_replay( struct replay *replay ) { + if( replay->play_count ) { + free( replay->play_count[ 0 ] ); + free( replay->play_count ); + } + free( replay->ramp_buf ); + free( replay->channels ); + free( replay ); +} + +/* Allocate and initialize a replay with the specified sampling rate and interpolation. */ +struct replay* new_replay( struct module *module, int sample_rate, int interpolation ) { + struct replay *replay = (struct replay*)calloc( 1, sizeof( struct replay ) ); + if( replay ) { + replay->module = module; + replay->sample_rate = sample_rate; + replay->interpolation = interpolation; + replay->ramp_buf = (int*)calloc( 128, sizeof( int ) ); + replay->channels = (struct channel*)calloc( module->num_channels, sizeof( struct channel ) ); + if( replay->ramp_buf && replay->channels ) { + replay_set_sequence_pos( replay, 0 ); + } else { + dispose_replay( replay ); + replay = NULL; + } + } + return replay; +} + +static int calculate_tick_len( int tempo, int sample_rate ) { + return ( sample_rate * 5 ) / ( tempo * 2 ); +} + +/* Returns the length of the output buffer required by replay_get_audio(). */ +int calculate_mix_buf_len( int sample_rate ) { + return ( calculate_tick_len( 32, sample_rate ) + 65 ) * 4; +} + +/* Returns the song duration in samples at the current sampling rate. */ +int replay_calculate_duration( struct replay *replay ) { + int count = 0, duration = 0; + replay_set_sequence_pos( replay, 0 ); + while( count < 1 ) { + duration += calculate_tick_len( replay->tempo, replay->sample_rate ); + count = replay_tick( replay ); + } + replay_set_sequence_pos( replay, 0 ); + return duration; +} + +/* Seek to approximately the specified sample position. + The actual sample position reached is returned. */ +int replay_seek( struct replay *replay, int sample_pos ) { + int idx, tick_len, current_pos = 0; + replay_set_sequence_pos( replay, 0 ); + tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); + while( ( sample_pos - current_pos ) >= tick_len ) { + for( idx = 0; idx < replay->module->num_channels; idx++ ) { + channel_update_sample_idx( &replay->channels[ idx ], + tick_len * 2, replay->sample_rate * 2 ); + } + current_pos += tick_len; + replay_tick( replay ); + tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); + } + return current_pos; +} + +static void replay_volume_ramp( struct replay *replay, int *mix_buf, int tick_len ) { + int idx, a1, a2, ramp_rate = 256 * 2048 / replay->sample_rate; + for( idx = 0, a1 = 0; a1 < 256; idx += 2, a1 += ramp_rate ) { + a2 = 256 - a1; + mix_buf[ idx ] = ( mix_buf[ idx ] * a1 + replay->ramp_buf[ idx ] * a2 ) >> 8; + mix_buf[ idx + 1 ] = ( mix_buf[ idx + 1 ] * a1 + replay->ramp_buf[ idx + 1 ] * a2 ) >> 8; + } + memcpy( replay->ramp_buf, &mix_buf[ tick_len * 2 ], 128 * sizeof( int ) ); +} + +/* 2:1 downsampling with simple but effective anti-aliasing. Buf must contain count * 2 + 1 stereo samples. */ +static void downsample( int *buf, int count ) { + int idx, out_idx, out_len = count * 2; + for( idx = 0, out_idx = 0; out_idx < out_len; idx += 4, out_idx += 2 ) { + buf[ out_idx ] = ( buf[ idx ] >> 2 ) + ( buf[ idx + 2 ] >> 1 ) + ( buf[ idx + 4 ] >> 2 ); + buf[ out_idx + 1 ] = ( buf[ idx + 1 ] >> 2 ) + ( buf[ idx + 3 ] >> 1 ) + ( buf[ idx + 5 ] >> 2 ); + } +} + +/* Generates audio and returns the number of stereo samples written into mix_buf. */ +int replay_get_audio( struct replay *replay, int *mix_buf ) { + struct channel *channel; + int idx, num_channels, tick_len = calculate_tick_len( replay->tempo, replay->sample_rate ); + /* Clear output buffer. */ + memset( mix_buf, 0, ( tick_len + 65 ) * 4 * sizeof( int ) ); + /* Resample. */ + num_channels = replay->module->num_channels; + for( idx = 0; idx < num_channels; idx++ ) { + channel = &replay->channels[ idx ]; + channel_resample( channel, mix_buf, 0, ( tick_len + 65 ) * 2, + replay->sample_rate * 2, replay->interpolation ); + channel_update_sample_idx( channel, tick_len * 2, replay->sample_rate * 2 ); + } + downsample( mix_buf, tick_len + 64 ); + replay_volume_ramp( replay, mix_buf, tick_len ); + replay_tick( replay ); + return tick_len; +} diff --git a/deps/libvita2d/source/vita2d_texture.c b/deps/libvita2d/source/vita2d_texture.c index 9d43071fb2..452bd4e51e 100644 --- a/deps/libvita2d/source/vita2d_texture.c +++ b/deps/libvita2d/source/vita2d_texture.c @@ -673,7 +673,7 @@ void vita2d_texture_set_tint_color_uniform(unsigned int color){ void vita2d_draw_texture_part_generic(const vita2d_texture *texture, SceGxmPrimitiveType type, vita2d_texture_vertex *vertices, unsigned int num_vertices) { - + uint16_t *indices = (uint16_t *)vita2d_pool_memalign( num_vertices * sizeof(uint16_t), // 4 indices sizeof(uint16_t)); diff --git a/deps/mbedtls/ecjpake.c b/deps/mbedtls/ecjpake.c index 1fa1c2d801..9218c5d172 100644 --- a/deps/mbedtls/ecjpake.c +++ b/deps/mbedtls/ecjpake.c @@ -299,7 +299,7 @@ cleanup: */ static int ecjpake_zkp_write( const mbedtls_md_info_t *md_info, const mbedtls_ecp_group *grp, - const int pf, + const int pf, const mbedtls_ecp_point *G, const mbedtls_mpi *x, const mbedtls_ecp_point *X, diff --git a/deps/mbedtls/mbedtls/ecp_internal.h b/deps/mbedtls/mbedtls/ecp_internal.h index 2991e26dd9..1a0fcd688c 100644 --- a/deps/mbedtls/mbedtls/ecp_internal.h +++ b/deps/mbedtls/mbedtls/ecp_internal.h @@ -47,7 +47,7 @@ * [6] Digital Signature Standard (DSS), FIPS 186-4. * * - * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer + * [7] Elliptic Curve Cryptography (ECC) Cipher Suites for Transport Layer * Security (TLS), RFC 4492. * * diff --git a/deps/mbedtls/mbedtls/rsa.h b/deps/mbedtls/mbedtls/rsa.h index 7d7469d509..a1a804be4c 100644 --- a/deps/mbedtls/mbedtls/rsa.h +++ b/deps/mbedtls/mbedtls/rsa.h @@ -333,7 +333,7 @@ int mbedtls_rsa_rsaes_oaep_encrypt( mbedtls_rsa_context *ctx, * as large as the size ctx->len of ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold - * the decryption of the particular ciphertext provided, + * the decryption of the particular ciphertext provided, * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * * \note The input buffer must be as large as the size @@ -365,7 +365,7 @@ int mbedtls_rsa_pkcs1_decrypt( mbedtls_rsa_context *ctx, * as large as the size ctx->len of ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold - * the decryption of the particular ciphertext provided, + * the decryption of the particular ciphertext provided, * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * * \note The input buffer must be as large as the size @@ -399,10 +399,10 @@ int mbedtls_rsa_rsaes_pkcs1_v15_decrypt( mbedtls_rsa_context *ctx, * as large as the size ctx->len of ctx->N (eg. 128 bytes * if RSA-1024 is used) to be able to hold an arbitrary * decrypted message. If it is not large enough to hold - * the decryption of the particular ciphertext provided, + * the decryption of the particular ciphertext provided, * the function will return MBEDTLS_ERR_RSA_OUTPUT_TOO_LARGE. * - * \note The input buffer must be as large as the size + * \note The input buffer must be as large as the size * of ctx->N (eg. 128 bytes if RSA-1024 is used). */ int mbedtls_rsa_rsaes_oaep_decrypt( mbedtls_rsa_context *ctx, diff --git a/deps/mbedtls/mbedtls/ssl_ciphersuites.h b/deps/mbedtls/mbedtls/ssl_ciphersuites.h index 9101d9cc7c..8ef79fdad3 100644 --- a/deps/mbedtls/mbedtls/ssl_ciphersuites.h +++ b/deps/mbedtls/mbedtls/ssl_ciphersuites.h @@ -266,7 +266,7 @@ typedef enum { defined(MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED) || \ defined(MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED) || \ - defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) + defined(MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED) #define MBEDTLS_KEY_EXCHANGE__CERT_REQ_ALLOWED__ENABLED #endif diff --git a/deps/mbedtls/ssl_cli.c b/deps/mbedtls/ssl_cli.c index a2b9f8cfe1..b73e416458 100644 --- a/deps/mbedtls/ssl_cli.c +++ b/deps/mbedtls/ssl_cli.c @@ -344,7 +344,7 @@ static void ssl_write_supported_point_formats_ext( mbedtls_ssl_context *ssl, *olen = 6; } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) @@ -1247,7 +1247,7 @@ static int ssl_parse_supported_point_formats_ext( mbedtls_ssl_context *ssl, MBEDTLS_SSL_ALERT_MSG_HANDSHAKE_FAILURE ); return( MBEDTLS_ERR_SSL_BAD_HS_SERVER_HELLO ); } -#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || +#endif /* MBEDTLS_ECDH_C || MBEDTLS_ECDSA_C || MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED */ #if defined(MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED) diff --git a/deps/mbedtls/ssl_srv.c b/deps/mbedtls/ssl_srv.c index f137c3dce6..be961af710 100644 --- a/deps/mbedtls/ssl_srv.c +++ b/deps/mbedtls/ssl_srv.c @@ -785,7 +785,7 @@ static int ssl_ciphersuite_match( mbedtls_ssl_context *ssl, int suite_id, const mbedtls_ssl_ciphersuite_t *suite_info; #if defined(MBEDTLS_SSL_PROTO_TLS1_2) && \ - defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) + defined(MBEDTLS_KEY_EXCHANGE__WITH_CERT__ENABLED) mbedtls_pk_type_t sig_type; #endif @@ -2955,7 +2955,7 @@ static int ssl_write_server_key_exchange( mbedtls_ssl_context *ssl ) return( ret ); } -#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) +#if defined(MBEDTLS_KEY_EXCHANGE__WITH_SERVER_SIGNATURE__ENABLED) dig_signed = p; dig_signed_len = len; #endif @@ -3044,7 +3044,7 @@ curve_matching_done: /* * 3.1: Choose hash algorithm: - * A: For TLS 1.2, obey signature-hash-algorithm extension + * A: For TLS 1.2, obey signature-hash-algorithm extension * to choose appropriate hash. * B: For SSL3, TLS1.0, TLS1.1 and ECDHE_ECDSA, use SHA1 * (RFC 4492, Sec. 5.4) @@ -3065,7 +3065,7 @@ curve_matching_done: sig_alg ) ) == MBEDTLS_MD_NONE ) { MBEDTLS_SSL_DEBUG_MSG( 1, ( "should never happen" ) ); - /* (... because we choose a cipher suite + /* (... because we choose a cipher suite * only if there is a matching hash.) */ return( MBEDTLS_ERR_SSL_INTERNAL_ERROR ); } diff --git a/deps/mbedtls/x509_crt.c b/deps/mbedtls/x509_crt.c index a6dce95ba2..a2305beb2e 100644 --- a/deps/mbedtls/x509_crt.c +++ b/deps/mbedtls/x509_crt.c @@ -713,7 +713,7 @@ static int x509_crt_parse_der_core( mbedtls_x509_crt *crt, const unsigned char * memcpy( p, buf, crt->raw.len ); - // Direct pointers to the new buffer + // Direct pointers to the new buffer p += crt->raw.len - len; end = crt_end = p + len; diff --git a/deps/stb/stb_image.h b/deps/stb/stb_image.h index 3349700b81..323ce6df12 100644 --- a/deps/stb/stb_image.h +++ b/deps/stb/stb_image.h @@ -5158,7 +5158,7 @@ static stbi_uc *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int // Else if n is 128, noop. // Endloop - /* The RLE-compressed data is preceeded by a 2-byte data count + /* The RLE-compressed data is preceeded by a 2-byte data count * for each row in the data, which we're going to just skip. */ stbi__skip(s, h * channelCount * 2 ); @@ -5948,7 +5948,7 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re c2 = stbi__get8(s); len = stbi__get8(s); if (c1 != 2 || c2 != 2 || (len & 0x80)) { - /* not run-length encoded, so we have to + /* not run-length encoded, so we have to * actually use THIS data as a decoded * pixel (note this can't be a valid pixel * --one of RGB must be >= 128) */ diff --git a/deps/stb/stb_rect_pack.h b/deps/stb/stb_rect_pack.h index f31258adb9..6c658de33e 100644 --- a/deps/stb/stb_rect_pack.h +++ b/deps/stb/stb_rect_pack.h @@ -245,7 +245,7 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, context->num_nodes = num_nodes; stbrp_setup_allow_out_of_mem(context, 0); - /* node 0 is the full width, + /* node 0 is the full width, * node 1 is the sentinel (lets us not store width explicitly) */ context->extra[0].x = 0; context->extra[0].y = 0; @@ -268,7 +268,7 @@ static int stbrp__skyline_find_min_y(stbrp_context *c, int x1 = x0 + width; STBRP_ASSERT(first->x <= x0); - STBRP_ASSERT(node->next->x > x0); + STBRP_ASSERT(node->next->x > x0); STBRP_ASSERT(node->x <= x0); min_y = 0; @@ -417,7 +417,7 @@ static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int widt } } tail = tail->next; - } + } } fr.prev_link = best; diff --git a/deps/stb/stb_truetype.h b/deps/stb/stb_truetype.h index ba3dd5acc0..4e1b8a97e7 100644 --- a/deps/stb/stb_truetype.h +++ b/deps/stb/stb_truetype.h @@ -26,7 +26,7 @@ * "Zer" on mollyrocket (with fix) * Cass Everitt * stoiko (Haemimont Games) - * Brian Hook + * Brian Hook * Walter van Niftrik * David Gow * David Given @@ -230,7 +230,7 @@ * Curve tesselation 120 LOC \__ 550 LOC Bitmap creation * Bitmap management 100 LOC / * Baked bitmap interface 70 LOC / - * Font name matching & access 150 LOC ---- 150 + * Font name matching & access 150 LOC ---- 150 * C runtime library abstraction 60 LOC ---- 60 * * @@ -566,10 +566,10 @@ enum }; #endif -#ifndef stbtt_vertex +#ifndef stbtt_vertex /* can't use stbtt_int16 because that's not visible in the header file */ -#define stbtt_vertex_type short +#define stbtt_vertex_type short typedef struct { @@ -944,7 +944,7 @@ STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, i stbtt_uint32 encoding_record = cmap + 4 + 8 * i; /* find an encoding we understand: */ - + switch(ttUSHORT(data+encoding_record)) { case STBTT_PLATFORM_ID_MICROSOFT: @@ -1273,7 +1273,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s if (start_off) { - /* if we start off with an off-curve point, + /* if we start off with an off-curve point, * then when we need to find a point on the curve * where we can start, and we need to save some state for when we wraparound. */ scx = x; @@ -1555,7 +1555,7 @@ STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, } else { - /* move to integral bboxes + /* move to integral bboxes * (treating pixels as little squares, what pixels get touched)? */ if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); @@ -1667,7 +1667,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); if (!z) return z; - + /* round dx down to avoid overshooting */ if (dxdy < 0) z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); @@ -1750,7 +1750,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac } } } - + e = e->next; } } @@ -2092,7 +2092,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); /* update all active edges, - * remove all active edges that terminate + * remove all active edges that terminate * before the top of this scanline */ while (*step) { stbtt__active_edge * z = *step; @@ -2306,7 +2306,7 @@ static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcou /* now sort the edges by their highest point (should snap to integer, and then by x) */ stbtt__sort_edges(e, n); - /* now, traverse the scanlines and find the + /* now, traverse the scanlines and find the * intersections on each scanline, use XOR winding rule */ stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); @@ -2449,7 +2449,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info { int ix0,iy0,ix1,iy1; stbtt__bitmap gbm; - stbtt_vertex *vertices; + stbtt_vertex *vertices; int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); if (scale_x == 0) scale_x = scale_y; @@ -2471,7 +2471,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info if (height) *height = gbm.h; if (xoff ) *xoff = ix0; if (yoff ) *yoff = iy0; - + if (gbm.w && gbm.h) { gbm.pixels = (unsigned char *)malloc(gbm.w * gbm.h); @@ -2485,7 +2485,7 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info free(vertices); return gbm.pixels; -} +} STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) @@ -2500,7 +2500,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigne int ix0,iy0; stbtt_vertex *vertices; int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; + stbtt__bitmap gbm; stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); gbm.pixels = output; @@ -2526,7 +2526,7 @@ STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo * { return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); -} +} STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, @@ -2539,7 +2539,7 @@ STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, uns STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); -} +} STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, @@ -2667,7 +2667,7 @@ static void stbrp_init_target(stbrp_context *con, int pw, int ph, con->y = 0; con->bottom_y = 0; STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); + STBTT__NOTUSED(num_nodes); } static void stbrp_pack_rects(stbrp_context *con, @@ -2772,7 +2772,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, total = 0; - /* make kernel_width a constant in common cases + /* make kernel_width a constant in common cases * so compiler can optimize out the divide */ switch (kernel_width) { case 2: @@ -2912,7 +2912,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd n = 0; for (i=0; i < num_ranges; ++i) n += ranges[i].num_chars_in_range; - + rects = (stbrp_rect *)malloc(sizeof(*rects) * n); if (rects == NULL) return 0; @@ -3045,7 +3045,7 @@ STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, /* font name matching -- recommended not to use this */ /* check if a UTF8 string contains a prefix which is the UTF16 string; if so return length of matching UTF8 string */ -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) { stbtt_int32 i=0; @@ -3091,7 +3091,7 @@ static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 return i; } -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) { return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); } @@ -3150,8 +3150,8 @@ static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, if (matchlen >= 0) { /* check for target_id+1 immediately following, with same encoding & language */ - if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id - && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding + if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id + && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { slen = ttUSHORT(fc+loc+12+8); diff --git a/deps/stb/stb_vorbis.h b/deps/stb/stb_vorbis.h index f662695711..6adaff4940 100644 --- a/deps/stb/stb_vorbis.h +++ b/deps/stb/stb_vorbis.h @@ -426,7 +426,7 @@ struct stb_vorbis int current_loc_valid; /* per-blocksize precomputed data */ - + /* twiddle factors */ float *A[2],*B[2],*C[2]; float *window[2]; @@ -737,7 +737,7 @@ static void compute_sorted_huffman(Codebook *c, uint8_t *lengths, uint32_t *valu if (!c->sparse) { int k = 0; for (i=0; i < c->entries; ++i) - if (include_in_sort(c, lengths[i])) + if (include_in_sort(c, lengths[i])) c->sorted_codewords[k++] = bit_reverse(c->codewords[i]); assert(k == c->sorted_entries); } else { @@ -943,7 +943,7 @@ static int start_page_no_capturepattern(vorb *f) /* header flag */ f->page_flag = get8(f); /* absolute granule position */ - loc0 = get32(f); + loc0 = get32(f); loc1 = get32(f); /* @TODO: validate loc0,loc1 as valid positions? * stream serial number -- vorbis doesn't interleave, so discard */ @@ -1437,69 +1437,69 @@ static int predict_point(int x, int x0, int x1, int y0, int y1) /* the following table is block-copied from the specification */ static float inverse_db_table[256] = { - 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, - 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, - 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, - 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, - 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, - 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, - 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, - 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, - 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, - 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, - 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, - 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, - 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, - 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, - 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, - 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, - 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, - 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, - 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, - 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, - 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, - 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, - 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, - 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, - 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, - 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, - 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, - 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, - 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, - 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, - 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, - 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, - 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, - 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, - 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, - 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, - 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, - 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, - 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, - 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, - 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, - 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, - 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, - 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, - 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, - 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, - 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, - 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, - 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, - 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, - 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, - 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, - 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, - 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, - 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, - 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, - 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, - 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, - 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, - 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, - 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, - 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, - 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, + 1.0649863e-07f, 1.1341951e-07f, 1.2079015e-07f, 1.2863978e-07f, + 1.3699951e-07f, 1.4590251e-07f, 1.5538408e-07f, 1.6548181e-07f, + 1.7623575e-07f, 1.8768855e-07f, 1.9988561e-07f, 2.1287530e-07f, + 2.2670913e-07f, 2.4144197e-07f, 2.5713223e-07f, 2.7384213e-07f, + 2.9163793e-07f, 3.1059021e-07f, 3.3077411e-07f, 3.5226968e-07f, + 3.7516214e-07f, 3.9954229e-07f, 4.2550680e-07f, 4.5315863e-07f, + 4.8260743e-07f, 5.1396998e-07f, 5.4737065e-07f, 5.8294187e-07f, + 6.2082472e-07f, 6.6116941e-07f, 7.0413592e-07f, 7.4989464e-07f, + 7.9862701e-07f, 8.5052630e-07f, 9.0579828e-07f, 9.6466216e-07f, + 1.0273513e-06f, 1.0941144e-06f, 1.1652161e-06f, 1.2409384e-06f, + 1.3215816e-06f, 1.4074654e-06f, 1.4989305e-06f, 1.5963394e-06f, + 1.7000785e-06f, 1.8105592e-06f, 1.9282195e-06f, 2.0535261e-06f, + 2.1869758e-06f, 2.3290978e-06f, 2.4804557e-06f, 2.6416497e-06f, + 2.8133190e-06f, 2.9961443e-06f, 3.1908506e-06f, 3.3982101e-06f, + 3.6190449e-06f, 3.8542308e-06f, 4.1047004e-06f, 4.3714470e-06f, + 4.6555282e-06f, 4.9580707e-06f, 5.2802740e-06f, 5.6234160e-06f, + 5.9888572e-06f, 6.3780469e-06f, 6.7925283e-06f, 7.2339451e-06f, + 7.7040476e-06f, 8.2047000e-06f, 8.7378876e-06f, 9.3057248e-06f, + 9.9104632e-06f, 1.0554501e-05f, 1.1240392e-05f, 1.1970856e-05f, + 1.2748789e-05f, 1.3577278e-05f, 1.4459606e-05f, 1.5399272e-05f, + 1.6400004e-05f, 1.7465768e-05f, 1.8600792e-05f, 1.9809576e-05f, + 2.1096914e-05f, 2.2467911e-05f, 2.3928002e-05f, 2.5482978e-05f, + 2.7139006e-05f, 2.8902651e-05f, 3.0780908e-05f, 3.2781225e-05f, + 3.4911534e-05f, 3.7180282e-05f, 3.9596466e-05f, 4.2169667e-05f, + 4.4910090e-05f, 4.7828601e-05f, 5.0936773e-05f, 5.4246931e-05f, + 5.7772202e-05f, 6.1526565e-05f, 6.5524908e-05f, 6.9783085e-05f, + 7.4317983e-05f, 7.9147585e-05f, 8.4291040e-05f, 8.9768747e-05f, + 9.5602426e-05f, 0.00010181521f, 0.00010843174f, 0.00011547824f, + 0.00012298267f, 0.00013097477f, 0.00013948625f, 0.00014855085f, + 0.00015820453f, 0.00016848555f, 0.00017943469f, 0.00019109536f, + 0.00020351382f, 0.00021673929f, 0.00023082423f, 0.00024582449f, + 0.00026179955f, 0.00027881276f, 0.00029693158f, 0.00031622787f, + 0.00033677814f, 0.00035866388f, 0.00038197188f, 0.00040679456f, + 0.00043323036f, 0.00046138411f, 0.00049136745f, 0.00052329927f, + 0.00055730621f, 0.00059352311f, 0.00063209358f, 0.00067317058f, + 0.00071691700f, 0.00076350630f, 0.00081312324f, 0.00086596457f, + 0.00092223983f, 0.00098217216f, 0.0010459992f, 0.0011139742f, + 0.0011863665f, 0.0012634633f, 0.0013455702f, 0.0014330129f, + 0.0015261382f, 0.0016253153f, 0.0017309374f, 0.0018434235f, + 0.0019632195f, 0.0020908006f, 0.0022266726f, 0.0023713743f, + 0.0025254795f, 0.0026895994f, 0.0028643847f, 0.0030505286f, + 0.0032487691f, 0.0034598925f, 0.0036847358f, 0.0039241906f, + 0.0041792066f, 0.0044507950f, 0.0047400328f, 0.0050480668f, + 0.0053761186f, 0.0057254891f, 0.0060975636f, 0.0064938176f, + 0.0069158225f, 0.0073652516f, 0.0078438871f, 0.0083536271f, + 0.0088964928f, 0.009474637f, 0.010090352f, 0.010746080f, + 0.011444421f, 0.012188144f, 0.012980198f, 0.013823725f, + 0.014722068f, 0.015678791f, 0.016697687f, 0.017782797f, + 0.018938423f, 0.020169149f, 0.021479854f, 0.022875735f, + 0.024362330f, 0.025945531f, 0.027631618f, 0.029427276f, + 0.031339626f, 0.033376252f, 0.035545228f, 0.037855157f, + 0.040315199f, 0.042935108f, 0.045725273f, 0.048696758f, + 0.051861348f, 0.055231591f, 0.058820850f, 0.062643361f, + 0.066714279f, 0.071049749f, 0.075666962f, 0.080584227f, + 0.085821044f, 0.091398179f, 0.097337747f, 0.10366330f, + 0.11039993f, 0.11757434f, 0.12521498f, 0.13335215f, + 0.14201813f, 0.15124727f, 0.16107617f, 0.17154380f, + 0.18269168f, 0.19456402f, 0.20720788f, 0.22067342f, + 0.23501402f, 0.25028656f, 0.26655159f, 0.28387361f, + 0.30232132f, 0.32196786f, 0.34289114f, 0.36517414f, + 0.38890521f, 0.41417847f, 0.44109412f, 0.46975890f, + 0.50028648f, 0.53279791f, 0.56742212f, 0.60429640f, + 0.64356699f, 0.68538959f, 0.72993007f, 0.77736504f, 0.82788260f, 0.88168307f, 0.9389798f, 1.0f }; @@ -1719,11 +1719,11 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n, int #if LIBVORBIS_MDCT /* directly call the vorbis MDCT using an interface documented * by Jeff Roberts... useful for performance comparison */ -typedef struct +typedef struct { int n; int log2n; - + float *trig; int *bitrev; @@ -1742,7 +1742,7 @@ void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) if (M1.n == n) M = &M1; else if (M2.n == n) M = &M2; else if (M1.n == 0) { mdct_init(&M1, n); M = &M1; } - else { + else { if (M2.n) __asm int 3; mdct_init(&M2, n); M = &M2; @@ -2157,7 +2157,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d1[0] = u[k4+1]; d0[1] = u[k4+2]; d0[0] = u[k4+3]; - + d0 -= 4; d1 -= 4; bitrev += 2; @@ -2239,7 +2239,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) float p0,p1,p2,p3; p3 = e[6]*B[7] - e[7]*B[6]; - p2 = -e[6]*B[6] - e[7]*B[7]; + p2 = -e[6]*B[6] - e[7]*B[7]; d0[0] = p3; d1[3] = - p3; @@ -2247,7 +2247,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[3] = p2; p1 = e[4]*B[5] - e[5]*B[4]; - p0 = -e[4]*B[4] - e[5]*B[5]; + p0 = -e[4]*B[4] - e[5]*B[5]; d0[1] = p1; d1[2] = - p1; @@ -2255,7 +2255,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[2] = p0; p3 = e[2]*B[3] - e[3]*B[2]; - p2 = -e[2]*B[2] - e[3]*B[3]; + p2 = -e[2]*B[2] - e[3]*B[3]; d0[2] = p3; d1[1] = - p3; @@ -2263,7 +2263,7 @@ static void inverse_mdct(float *buffer, int n, vorb *f, int blocktype) d3[1] = p2; p1 = e[0]*B[1] - e[1]*B[0]; - p0 = -e[0]*B[0] - e[1]*B[1]; + p0 = -e[0]*B[0] - e[1]*B[1]; d0[3] = p1; d1[0] = - p1; @@ -2968,7 +2968,7 @@ static int start_decoder(vorb *f) } else { STBV_Point p[31*8+2]; Floor1 *g = &f->floor_config[i].floor1; - int max_class = -1; + int max_class = -1; g->partitions = get_bits(f, 5); for (j=0; j < g->partitions; ++j) { g->partition_class_list[j] = get_bits(f, 4); @@ -3072,7 +3072,7 @@ static int start_decoder(vorb *f) f->mapping_count = get_bits(f,6)+1; f->mapping = (Mapping *) setup_malloc(f, f->mapping_count * sizeof(*f->mapping)); for (i=0; i < f->mapping_count; ++i) { - Mapping *m = f->mapping + i; + Mapping *m = f->mapping + i; int mapping_type = get_bits(f,16); if (mapping_type != 0) return error(f, VORBIS_invalid_setup); m->chan = (MappingChannel *) setup_malloc(f, f->channels * sizeof(*m->chan)); @@ -3473,7 +3473,7 @@ static int vorbis_analyze_page(stb_vorbis *f, ProbedPage *z) * will then require us to NOT discard all of the first frame we * decode, in some cases, which means an even weirder frame size * and extra code. what a fucking pain. - + * we're going to discard the first packet if we * start the seek here, so we don't care about it. (we could actually * do better; if the first packet is long, and the previous packet @@ -3567,7 +3567,7 @@ static int vorbis_seek_frame_from_page(stb_vorbis *f, uint32_t page_start, uint3 * then leave frame pending */ frames_to_skip = frame - 1; assert(frames_to_skip >= 0); - data_to_skip = -1; + data_to_skip = -1; } set_file_offset(f, page_start); @@ -3645,7 +3645,7 @@ static int vorbis_seek_base(stb_vorbis *f, unsigned int sample_number, int fine) return error(f, VORBIS_seek_failed); /* now we want to lerp between these for the target samples... */ - + /* step 1: we need to bias towards the page start... */ if (start_offset + 4000 < end_offset) end_offset -= 4000; @@ -3725,7 +3725,7 @@ unsigned int stb_vorbis_stream_length_in_samples(stb_vorbis *f) /* first, store the current decode position so we can restore it */ restore_offset = stb_vorbis_get_file_offset(f); - /* now we want to seek back 64K from the end (the last page must + /* now we want to seek back 64K from the end (the last page must * be at most a little less than 64K, but let's allow a little slop) */ if (f->stream_len >= 65536 && f->stream_len-65536 >= f->first_audio_page_offset) previous_safe = f->stream_len - 65536; diff --git a/dirs.c b/dirs.c index 486e9dcc2c..35b7ad5413 100644 --- a/dirs.c +++ b/dirs.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -82,7 +82,7 @@ bool dir_init_shader(void) bool dir_free_shader(void) { - struct rarch_dir_list *dir_list = + struct rarch_dir_list *dir_list = (struct rarch_dir_list*)&dir_shader_list; dir_list_free(dir_list->list); diff --git a/dirs.h b/dirs.h index f69bb06715..e9bc186c69 100644 --- a/dirs.h +++ b/dirs.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/driver.c b/driver.c index fbee1c29f1..7cadd24508 100644 --- a/driver.c +++ b/driver.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -145,7 +145,7 @@ static int driver_find_index(const char * label, const char *drv) str[0] = '\0'; - for (i = 0; + for (i = 0; find_driver_nonempty(label, i, str, sizeof(str)) != NULL; i++) { if (string_is_empty(str)) @@ -253,7 +253,7 @@ static void driver_adjust_system_rates(void) * * Sets audio and video drivers to nonblock state (if enabled). * - * If nonblock state is false, sets + * If nonblock state is false, sets * blocking state for both audio and video drivers instead. **/ void driver_set_nonblock_state(void) @@ -266,7 +266,7 @@ void driver_set_nonblock_state(void) settings_t *settings = config_get_ptr(); bool video_nonblock = enable; - if ( !settings->bools.video_vsync + if ( !settings->bools.video_vsync || rarch_ctl(RARCH_CTL_IS_NONBLOCK_FORCED, NULL)) video_nonblock = true; video_driver_set_nonblock_state(video_nonblock); @@ -279,7 +279,7 @@ void driver_set_nonblock_state(void) * driver_update_system_av_info: * @data : pointer to new A/V info * - * Update the system Audio/Video information. + * Update the system Audio/Video information. * Will reinitialize audio/video drivers. * Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO. * @@ -397,17 +397,17 @@ void drivers_init(int flags) **/ /** - * Driver ownership - set this to true if the platform in question needs to 'own' - * the respective handle and therefore skip regular RetroArch + * Driver ownership - set this to true if the platform in question needs to 'own' + * the respective handle and therefore skip regular RetroArch * driver teardown/reiniting procedure. * - * If to true, the 'free' function will get skipped. It is - * then up to the driver implementation to properly handle - * 'reiniting' inside the 'init' function and make sure it - * returns the existing handle instead of allocating and + * If to true, the 'free' function will get skipped. It is + * then up to the driver implementation to properly handle + * 'reiniting' inside the 'init' function and make sure it + * returns the existing handle instead of allocating and * returning a pointer to a new handle. * - * Typically, if a driver intends to make use of this, it should + * Typically, if a driver intends to make use of this, it should * set this to true at the end of its 'init' function. **/ void driver_uninit(int flags) diff --git a/driver.h b/driver.h index 1120253e65..49d61bbf07 100644 --- a/driver.h +++ b/driver.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -74,7 +74,7 @@ enum driver_ctl_state RARCH_DRIVER_CTL_NONE = 0, RARCH_DRIVER_CTL_DEINIT, - /* Attempts to find a default driver for + /* Attempts to find a default driver for * all driver types. * * Should be run before RARCH_DRIVER_CTL_INIT. @@ -86,7 +86,7 @@ enum driver_ctl_state * calls audio_monitor_set_refresh_rate(). */ RARCH_DRIVER_CTL_SET_REFRESH_RATE, - /* Update the system Audio/Video information. + /* Update the system Audio/Video information. * Will reinitialize audio/video drivers. * Used by RETRO_ENVIRONMENT_SET_SYSTEM_AV_INFO. */ RARCH_DRIVER_CTL_UPDATE_SYSTEM_AV_INFO, diff --git a/dynamic.c b/dynamic.c index 7661316f22..5e9bce61cb 100644 --- a/dynamic.c +++ b/dynamic.c @@ -199,11 +199,11 @@ static void libretro_get_environment_info(void (*func)(retro_environment_t), /* load_no_content gets set in this callback. */ func(environ_cb_get_system_info); - /* It's possible that we just set get_system_info callback + /* It's possible that we just set get_system_info callback * to the currently running core. * * Make sure we reset it to the actual environment callback. - * Ignore any environment callbacks here in case we're running + * Ignore any environment callbacks here in case we're running * on the non-current core. */ ignore_environment_cb = true; func(rarch_environment_cb); @@ -339,11 +339,11 @@ bool libretro_get_system_info(const char *path, /* load_no_content gets set in this callback. */ retro_set_environment(environ_cb_get_system_info); - /* It's possible that we just set get_system_info callback + /* It's possible that we just set get_system_info callback * to the currently running core. * * Make sure we reset it to the actual environment callback. - * Ignore any environment callbacks here in case we're running + * Ignore any environment callbacks here in case we're running * on the non-current core. */ ignore_environment_cb = true; retro_set_environment(rarch_environment_cb); @@ -712,11 +712,11 @@ static size_t mmap_add_bits_down(size_t n) n |= n >> 4; n |= n >> 8; n |= n >> 16; - + /* double shift to avoid warnings on 32bit (it's dead code, but compilers suck) */ if (sizeof(size_t) > 4) n |= n >> 16 >> 16; - + return n; } @@ -730,7 +730,7 @@ static size_t mmap_inflate(size_t addr, size_t mask) addr = ((addr & ~tmp) << 1) | (addr & tmp); mask = mask & (mask - 1); } - + return addr; } @@ -742,7 +742,7 @@ static size_t mmap_reduce(size_t addr, size_t mask) addr = (addr & tmp) | ((addr >> 1) & ~tmp); mask = (mask & (mask - 1)) >> 1; } - + return addr; } @@ -757,7 +757,7 @@ static bool mmap_preprocess_descriptors(rarch_memory_descriptor_t *first, unsign size_t top_addr = 1; rarch_memory_descriptor_t *desc = NULL; const rarch_memory_descriptor_t *end = first + count; - + for (desc = first; desc < end; desc++) { if (desc->core.select != 0) @@ -765,43 +765,43 @@ static bool mmap_preprocess_descriptors(rarch_memory_descriptor_t *first, unsign else top_addr |= desc->core.start + desc->core.len - 1; } - + top_addr = mmap_add_bits_down(top_addr); - + for (desc = first; desc < end; desc++) { if (desc->core.select == 0) { if (desc->core.len == 0) return false; - + if ((desc->core.len & (desc->core.len - 1)) != 0) return false; - + desc->core.select = top_addr & ~mmap_inflate(mmap_add_bits_down(desc->core.len - 1), desc->core.disconnect); } - + if (desc->core.len == 0) desc->core.len = mmap_add_bits_down(mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect)) + 1; - + if (desc->core.start & ~desc->core.select) return false; - + while (mmap_reduce(top_addr & ~desc->core.select, desc->core.disconnect) >> 1 > desc->core.len - 1) desc->core.disconnect |= mmap_highest_bit(top_addr & ~desc->core.select & ~desc->core.disconnect); - + desc->disconnect_mask = mmap_add_bits_down(desc->core.len - 1); desc->core.disconnect &= desc->disconnect_mask; - + while ((~desc->disconnect_mask) >> 1 & desc->core.disconnect) { desc->disconnect_mask >>= 1; desc->core.disconnect &= desc->disconnect_mask; } } - + return true; } @@ -942,7 +942,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) unsigned p; settings_t *settings = config_get_ptr(); rarch_system_info_t *system = runloop_get_system_info(); - + if (ignore_environment_cb) return false; @@ -1238,7 +1238,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) { struct retro_hw_render_callback *cb = (struct retro_hw_render_callback*)data; - struct retro_hw_render_callback *hwr = + struct retro_hw_render_callback *hwr = video_driver_get_hw_context(); RARCH_LOG("Environ SET_HW_RENDER.\n"); @@ -1253,7 +1253,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) cb->get_proc_address = video_driver_get_proc_address; /* Old ABI. Don't copy garbage. */ - if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) + if (cmd & RETRO_ENVIRONMENT_EXPERIMENTAL) memcpy(hwr, cb, offsetof(struct retro_hw_render_callback, stencil)); else @@ -1392,7 +1392,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) cb->get_cpu_features = cpu_features_get; cb->get_perf_counter = cpu_features_get_perf_counter; - cb->perf_register = performance_counter_register; + cb->perf_register = performance_counter_register; cb->perf_start = core_performance_counter_start; cb->perf_stop = core_performance_counter_stop; cb->perf_log = retro_perf_log; @@ -1494,7 +1494,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) } break; } - + case RETRO_ENVIRONMENT_SET_MEMORY_MAPS: { if (system) @@ -1575,9 +1575,9 @@ bool rarch_environment_cb(unsigned cmd, void *data) { const struct retro_game_geometry *in_geom = NULL; struct retro_game_geometry *geom = NULL; - struct retro_system_av_info *av_info = + struct retro_system_av_info *av_info = video_viewport_get_system_av_info(); - + if (av_info) geom = (struct retro_game_geometry*)&av_info->geometry; @@ -1617,7 +1617,7 @@ bool rarch_environment_cb(unsigned cmd, void *data) case RETRO_ENVIRONMENT_GET_HW_RENDER_INTERFACE: return video_driver_get_hw_render_interface( (const struct retro_hw_render_interface**)data); - + case RETRO_ENVIRONMENT_SET_SUPPORT_ACHIEVEMENTS: #ifdef HAVE_CHEEVOS { diff --git a/dynamic.h b/dynamic.h index d2b529520b..2432704e48 100644 --- a/dynamic.h +++ b/dynamic.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -93,7 +93,7 @@ struct retro_core_t void (*retro_set_input_poll)(retro_input_poll_t); void (*retro_set_input_state)(retro_input_state_t); void (*retro_set_controller_port_device)(unsigned, unsigned); - void (*retro_reset)(void); + void (*retro_reset)(void); void (*retro_run)(void); size_t (*retro_serialize_size)(void); bool (*retro_serialize)(void*, size_t); @@ -122,7 +122,7 @@ bool libretro_get_shared_context(void); /** * init_libretro_sym: * @type : Type of core to be loaded. - * If CORE_TYPE_DUMMY, will + * If CORE_TYPE_DUMMY, will * load dummy symbols. * * Initializes libretro symbols and diff --git a/file_path_str.c b/file_path_str.c index ce976bf261..219c719720 100644 --- a/file_path_str.c +++ b/file_path_str.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/frontend/drivers/platform_ctr.c b/frontend/drivers/platform_ctr.c index 7d3b7b6b28..015d7e0ae4 100644 --- a/frontend/drivers/platform_ctr.c +++ b/frontend/drivers/platform_ctr.c @@ -129,7 +129,7 @@ static void frontend_ctr_deinit(void *data) cfguExit(); ndspExit(); - csndExit(); + csndExit(); gfxTopRightFramebuffers[0] = NULL; gfxTopRightFramebuffers[1] = NULL; gfxExit(); @@ -322,7 +322,7 @@ static void frontend_ctr_init(void *data) verbosity_enable(); - gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); + gfxInit(GSP_BGR8_OES,GSP_RGB565_OES,false); u32 topSize = 400 * 240 * 3; u32 bottomSize = 320 * 240 * 2; diff --git a/frontend/drivers/platform_gx.c b/frontend/drivers/platform_gx.c index 8443348c63..541e1363bf 100644 --- a/frontend/drivers/platform_gx.c +++ b/frontend/drivers/platform_gx.c @@ -405,7 +405,7 @@ static void frontend_gx_exitspawn(char *s, size_t len) sizeof(salamander_basename)); /* FIXME/TODO - hack - * direct loading failed (out of memory), + * direct loading failed (out of memory), * try to jump to Salamander, * then load the correct core */ fill_pathname_join(s, g_defaults.dirs[DEFAULT_DIR_CORE], diff --git a/frontend/drivers/platform_ps3.c b/frontend/drivers/platform_ps3.c index 9360feef2d..e6d49fcf43 100644 --- a/frontend/drivers/platform_ps3.c +++ b/frontend/drivers/platform_ps3.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -56,7 +56,7 @@ SYS_PROCESS_PARAM(1001, 0x100000) #else SYS_PROCESS_PARAM(1001, 0x200000) #endif - + #ifdef HAVE_MULTIMAN #define MULTIMAN_SELF_FILE "/dev_hdd0/game/BLES80608/USRDIR/RELOAD.SELF" static bool multiman_detected = false; @@ -189,7 +189,7 @@ static void frontend_ps3_get_environment_settings(int *argc, char *argv[], break; } - if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) + if((get_attributes & CELL_GAME_ATTRIBUTE_APP_HOME) == CELL_GAME_ATTRIBUTE_APP_HOME) RARCH_LOG("RetroArch was launched from host machine (APP_HOME).\n"); diff --git a/frontend/drivers/platform_qnx.c b/frontend/drivers/platform_qnx.c index b115e22520..d9ec683b24 100644 --- a/frontend/drivers/platform_qnx.c +++ b/frontend/drivers/platform_qnx.c @@ -45,7 +45,7 @@ static void frontend_qnx_shutdown(bool unused) static int frontend_qnx_get_rating(void) { - /* TODO/FIXME - look at unique identifier per device and + /* TODO/FIXME - look at unique identifier per device and * determine rating for some */ return -1; } diff --git a/frontend/drivers/platform_unix.c b/frontend/drivers/platform_unix.c index 80bd183322..43847effee 100644 --- a/frontend/drivers/platform_unix.c +++ b/frontend/drivers/platform_unix.c @@ -1502,7 +1502,7 @@ static void frontend_unix_get_env(int *argc, __android_log_print(ANDROID_LOG_INFO, "RetroArch", "[ENV]: app dir: [%s]\n", app_dir); - /* set paths depending on the ability to write + /* set paths depending on the ability to write * to internal_storage_path */ if(!string_is_empty(internal_storage_path)) @@ -1592,7 +1592,7 @@ static void frontend_unix_get_env(int *argc, internal_storage_app_path, "cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); - if(!string_is_empty(screenshot_dir) + if(!string_is_empty(screenshot_dir) && test_permissions(screenshot_dir)) { fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT], @@ -1606,7 +1606,7 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); } - if(!string_is_empty(downloads_dir) + if(!string_is_empty(downloads_dir) && test_permissions(downloads_dir)) { fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], @@ -1621,7 +1621,7 @@ static void frontend_unix_get_env(int *argc, } break; - + /* only the internal app dir is writable, this should never happen*/ case INTERNAL_STORAGE_NOT_WRITABLE: fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SRAM], @@ -1650,7 +1650,7 @@ static void frontend_unix_get_env(int *argc, app_dir, "cheats", sizeof(g_defaults.dirs[DEFAULT_DIR_CHEATS])); - if( !string_is_empty(screenshot_dir) + if( !string_is_empty(screenshot_dir) && test_permissions(screenshot_dir)) { fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT], @@ -1664,7 +1664,7 @@ static void frontend_unix_get_env(int *argc, sizeof(g_defaults.dirs[DEFAULT_DIR_SCREENSHOT])); } - if(!string_is_empty(downloads_dir) + if(!string_is_empty(downloads_dir) && test_permissions(downloads_dir)) { fill_pathname_join(g_defaults.dirs[DEFAULT_DIR_CORE_ASSETS], @@ -1768,7 +1768,7 @@ static void frontend_unix_get_env(int *argc, #endif #if 0 - /* Set the OK/cancel menu buttons to the default + /* Set the OK/cancel menu buttons to the default * ones used for Shield */ g_defaults.menu.controls.set = true; g_defaults.menu.controls.menu_btn_ok = RETRO_DEVICE_ID_JOYPAD_B; @@ -2035,7 +2035,7 @@ static int frontend_unix_parse_drive_list(void *data, bool load_content) menu_entries_append_enum(list, "/storage", msg_hash_to_str(MSG_REMOVABLE_STORAGE), - enum_idx, + enum_idx, FILE_TYPE_DIRECTORY, 0, 0); #endif @@ -2175,7 +2175,7 @@ VALGRIND_PRINTF_BACKTRACE("SIGINT"); if (unix_sighandler_quit == 1) {} if (unix_sighandler_quit == 2) exit(1); /* in case there's a second deadlock in a C++ destructor or something */ - if (unix_sighandler_quit >= 3) abort(); + if (unix_sighandler_quit >= 3) abort(); } static void frontend_unix_install_signal_handlers(void) diff --git a/frontend/drivers/platform_unix.h b/frontend/drivers/platform_unix.h index db5eacceb3..c5a028ccc8 100644 --- a/frontend/drivers/platform_unix.h +++ b/frontend/drivers/platform_unix.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -244,7 +244,7 @@ enum /** * Command from main thread: the app should generate a new saved state - * for itself, to restore from later if needed. + * for itself, to restore from later if needed. */ APP_CMD_SAVE_STATE, diff --git a/frontend/drivers/platform_wii.c b/frontend/drivers/platform_wii.c index ac5ebfaea3..51b0d9c148 100644 --- a/frontend/drivers/platform_wii.c +++ b/frontend/drivers/platform_wii.c @@ -74,9 +74,9 @@ static void dol_copy_argv_path(const char *dolpath, const char *argpath) } /* a relative path */ else if ( - (strstr(dolpath, "sd:/") != dolpath) && + (strstr(dolpath, "sd:/") != dolpath) && (strstr(dolpath, "usb:/") != dolpath) && - (strstr(dolpath, "carda:/") != dolpath) && + (strstr(dolpath, "carda:/") != dolpath) && (strstr(dolpath, "cardb:/") != dolpath) ) { @@ -119,7 +119,7 @@ static void dol_copy_argv_path(const char *dolpath, const char *argpath) DCFlushRange(ARGS_ADDR, sizeof(struct __argv) + argv->length); } -/* WARNING: after we move any data +/* WARNING: after we move any data * into EXECUTE_ADDR, we can no longer use any * heap memory and are restricted to the stack only. */ void system_exec_wii(const char *_path, bool should_load_game) @@ -133,7 +133,7 @@ void system_exec_wii(const char *_path, bool should_load_game) bool original_verbose = verbosity_is_enabled(); #endif - /* copy heap info into stack so it survives + /* copy heap info into stack so it survives * us moving the .dol into MEM2. */ strlcpy(path, _path, sizeof(path)); if (should_load_game) diff --git a/frontend/drivers/platform_win32.c b/frontend/drivers/platform_win32.c index 64703e4dcb..31b238c814 100644 --- a/frontend/drivers/platform_win32.c +++ b/frontend/drivers/platform_win32.c @@ -42,8 +42,8 @@ #include "../../retroarch.h" #include "../../verbosity.h" -/* We only load this library once, so we let it be - * unloaded at application shutdown, since unloading +/* We only load this library once, so we let it be + * unloaded at application shutdown, since unloading * it early seems to cause issues on some systems. */ @@ -89,10 +89,10 @@ static bool gfx_init_dwm(void) return false; } - DragAcceptFiles_func = + DragAcceptFiles_func = (VOID (WINAPI*)(HWND, BOOL))dylib_proc(shell32lib, "DragAcceptFiles"); - mmcss = + mmcss = (HRESULT (WINAPI*)(BOOL))dylib_proc(dwmlib, "DwmEnableMMCSS"); if (mmcss) { @@ -116,7 +116,7 @@ static void gfx_set_dwm(void) if (settings->bools.video_disable_composition == dwm_composition_disabled) return; - composition_enable = + composition_enable = (HRESULT (WINAPI*)(UINT))dylib_proc(dwmlib, "DwmEnableComposition"); if (!composition_enable) { @@ -292,11 +292,11 @@ static void frontend_win32_init(void *data) { typedef BOOL (WINAPI *isProcessDPIAwareProc)(); typedef BOOL (WINAPI *setProcessDPIAwareProc)(); - HMODULE handle = + HMODULE handle = GetModuleHandle("User32.dll"); - isProcessDPIAwareProc isDPIAwareProc = + isProcessDPIAwareProc isDPIAwareProc = (isProcessDPIAwareProc)dylib_proc(handle, "IsProcessDPIAware"); - setProcessDPIAwareProc setDPIAwareProc = + setProcessDPIAwareProc setDPIAwareProc = (setProcessDPIAwareProc)dylib_proc(handle, "SetProcessDPIAware"); if (isDPIAwareProc) @@ -307,7 +307,7 @@ static void frontend_win32_init(void *data) setDPIAwareProc(); } } - + } enum frontend_powerstate frontend_win32_get_powerstate(int *seconds, int *percent) @@ -471,7 +471,7 @@ static uint64_t frontend_win32_get_mem_total(void) static uint64_t frontend_win32_get_mem_used(void) { - /* OSes below 2000 don't have the Ex version, + /* OSes below 2000 don't have the Ex version, * and non-Ex cannot work with >4GB RAM */ #if _WIN32_WINNT >= 0x0500 MEMORYSTATUSEX mem_info; @@ -492,24 +492,24 @@ static void frontend_win32_attach_console(void) #ifdef _WIN32_WINNT_WINXP /* msys will start the process with FILE_TYPE_PIPE connected. - * cmd will start the process with FILE_TYPE_UNKNOWN connected + * cmd will start the process with FILE_TYPE_UNKNOWN connected * (since this is subsystem windows application - * ... UNLESS stdout/stderr were redirected (then FILE_TYPE_DISK + * ... UNLESS stdout/stderr were redirected (then FILE_TYPE_DISK * will be connected most likely) * explorer will start the process with NOTHING connected. * * Now, let's not reconnect anything that's already connected. * If any are disconnected, open a console, and connect to them. - * In case we're launched from msys or cmd, try attaching to the + * In case we're launched from msys or cmd, try attaching to the * parent process console first. * - * Take care to leave a record of what we did, so we can + * Take care to leave a record of what we did, so we can * undo it precisely. */ - bool need_stdout = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) + bool need_stdout = (GetFileType(GetStdHandle(STD_OUTPUT_HANDLE)) == FILE_TYPE_UNKNOWN); - bool need_stderr = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) + bool need_stderr = (GetFileType(GetStdHandle(STD_ERROR_HANDLE)) == FILE_TYPE_UNKNOWN); if(need_stdout || need_stderr) @@ -534,8 +534,8 @@ static void frontend_win32_detach_console(void) if(console_needs_free) { - /* we don't reconnect stdout/stderr to anything here, - * because by definition, they weren't connected to + /* we don't reconnect stdout/stderr to anything here, + * because by definition, they weren't connected to * anything in the first place. */ FreeConsole(); console_needs_free = false; diff --git a/frontend/drivers/platform_xdk.c b/frontend/drivers/platform_xdk.c index 3c626285d8..e67d5935ba 100644 --- a/frontend/drivers/platform_xdk.c +++ b/frontend/drivers/platform_xdk.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -240,10 +240,10 @@ typedef struct _FILE_FS_SIZE_INFORMATION { #define DEVICE_TYPE ULONG // Structure of FileFsDeviceInformation -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; +typedef struct _FILE_FS_DEVICE_INFORMATION { + DEVICE_TYPE DeviceType; + ULONG Characteristics; +} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; // DEVICE_TYPEs (I took a guess as to which the XBOX might have.) #define FILE_DEVICE_CD_ROM 0x00000002 @@ -993,12 +993,12 @@ extern "C" // Thanks and credit go to Team Evox extern VOID WINAPI HalReturnToFirmware(DWORD); - extern INT WINAPI XNetLoadConfigParams(LPBYTE); - extern INT WINAPI XNetSaveConfigParams(LPBYTE); + extern INT WINAPI XNetLoadConfigParams(LPBYTE); + extern INT WINAPI XNetSaveConfigParams(LPBYTE); extern INT WINAPI XWriteTitleInfoNoReboot(LPVOID,LPVOID,DWORD,DWORD,LPVOID); - extern DWORD* LaunchDataPage; + extern DWORD* LaunchDataPage; } #endif @@ -1006,7 +1006,7 @@ extern "C" static enum frontend_fork xdk_fork_mode = FRONTEND_FORK_NONE; #ifdef _XBOX360 -typedef struct _STRING +typedef struct _STRING { USHORT Length; USHORT MaximumLength; @@ -1016,7 +1016,7 @@ typedef struct _STRING #ifdef __cplusplus extern "C" { #endif -VOID RtlInitAnsiString(PSTRING DestinationString, PCHAR SourceString); +VOID RtlInitAnsiString(PSTRING DestinationString, PCHAR SourceString); HRESULT ObDeleteSymbolicLink(PSTRING SymbolicLinkName); HRESULT ObCreateSymbolicLink(PSTRING SymbolicLinkName, PSTRING DeviceName); #ifdef __cplusplus diff --git a/frontend/frontend.c b/frontend/frontend.c index b6dcca2cd2..137d9fa0bf 100644 --- a/frontend/frontend.c +++ b/frontend/frontend.c @@ -102,7 +102,7 @@ int rarch_main(int argc, char *argv[], void *data) rarch_ctl(RARCH_CTL_PREINIT, NULL); frontend_driver_init_first(args); rarch_ctl(RARCH_CTL_INIT, NULL); - + if (frontend_driver_is_inited()) { content_ctx_info_t info; diff --git a/frontend/frontend.h b/frontend/frontend.h index fed99639ce..ef821097c4 100644 --- a/frontend/frontend.h +++ b/frontend/frontend.h @@ -34,14 +34,14 @@ RETRO_BEGIN_DECLS * and (optionally) autosave state. **/ void main_exit(void *args); - + /** * main_entry: * * Main function of RetroArch. * * If HAVE_MAIN is not defined, will contain main loop and will not - * be exited from until we exit the program. Otherwise, will + * be exited from until we exit the program. Otherwise, will * just do initialization. * * Returns: varies per platform. diff --git a/frontend/frontend_salamander.c b/frontend/frontend_salamander.c index e8c2441e29..52868ec0c8 100644 --- a/frontend/frontend_salamander.c +++ b/frontend/frontend_salamander.c @@ -56,7 +56,7 @@ static void find_first_libretro_core(char *first_file, RARCH_LOG("Searching for valid libretro implementation in: \"%s\".\n", dir); - + for (i = 0; i < list->size && !ret; i++) { char fname[PATH_MAX_LENGTH] = {0}; @@ -94,7 +94,7 @@ static void find_first_libretro_core(char *first_file, dir_list_free(list); } -/* Last fallback - we'll need to start the first executable file +/* Last fallback - we'll need to start the first executable file * we can find in the RetroArch cores directory. */ static void find_and_set_first_file(char *s, size_t len, @@ -135,9 +135,9 @@ static void salamander_init(char *s, size_t len) strlcpy(s, tmp_str, len); } #ifdef GEKKO - /* stupid libfat bug or something; sometimes it says + /* stupid libfat bug or something; sometimes it says * the file is there when it doesn't. */ - else + else { config_exists = false; } diff --git a/gfx/common/d3d_common.c b/gfx/common/d3d_common.c index 07976b7393..5de2e746c9 100644 --- a/gfx/common/d3d_common.c +++ b/gfx/common/d3d_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -111,7 +111,7 @@ LPDIRECT3DTEXTURE d3d_texture_new(LPDIRECT3DDEVICE dev, const char *path, unsigned width, unsigned height, unsigned miplevels, unsigned usage, D3DFORMAT format, D3DPOOL pool, unsigned filter, unsigned mipfilter, - D3DCOLOR color_key, void *src_info_data, + D3DCOLOR color_key, void *src_info_data, PALETTEENTRY *palette) { HRESULT hr; @@ -535,7 +535,7 @@ void d3d_clear(LPDIRECT3DDEVICE dev, #if defined(_XBOX1) D3DDevice_Clear(count, rects, flags, color, z, stencil); #elif defined(_XBOX360) - D3DDevice_Clear(dev, count, rects, flags, color, z, + D3DDevice_Clear(dev, count, rects, flags, color, z, stencil, false); #elif defined(HAVE_D3D9) && !defined(__cplusplus) IDirect3DDevice9_Clear(dev, count, rects, flags, @@ -646,10 +646,10 @@ void d3d_set_texture(LPDIRECT3DDEVICE dev, unsigned sampler, #if defined(_XBOX1) D3DDevice_SetTexture(sampler, tex); #elif defined(_XBOX360) - unsigned fetchConstant = + unsigned fetchConstant = GPU_CONVERT_D3D_TO_HARDWARE_TEXTUREFETCHCONSTANT(sampler); - uint64_t pendingMask3 = - D3DTAG_MASKENCODE(D3DTAG_START(D3DTAG_FETCHCONSTANTS) + uint64_t pendingMask3 = + D3DTAG_MASKENCODE(D3DTAG_START(D3DTAG_FETCHCONSTANTS) + fetchConstant, D3DTAG_START(D3DTAG_FETCHCONSTANTS) + fetchConstant); #if defined(__cplusplus) @@ -976,7 +976,7 @@ D3DTEXTUREFILTERTYPE d3d_translate_filter(unsigned type) return D3DTEXF_POINT; } - + void *d3d_matrix_transpose(void *_pout, const void *_pm) { unsigned i,j; diff --git a/gfx/common/d3d_common.h b/gfx/common/d3d_common.h index 8fd61d2aad..fa88fb2e55 100644 --- a/gfx/common/d3d_common.h +++ b/gfx/common/d3d_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -45,7 +45,7 @@ LPDIRECT3DTEXTURE d3d_texture_new(LPDIRECT3DDEVICE dev, const char *path, unsigned width, unsigned height, unsigned miplevels, unsigned usage, D3DFORMAT format, D3DPOOL pool, unsigned filter, unsigned mipfilter, - D3DCOLOR color_key, void *src_info, + D3DCOLOR color_key, void *src_info, PALETTEENTRY *palette); void d3d_set_stream_source(LPDIRECT3DDEVICE dev, unsigned stream_no, diff --git a/gfx/common/dbus_common.c b/gfx/common/dbus_common.c index 4fd335a8f6..7270510337 100644 --- a/gfx/common/dbus_common.c +++ b/gfx/common/dbus_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -30,7 +30,7 @@ void dbus_ensure_connection(void) #ifdef HAVE_DBUS DBusError err; int ret; - + dbus_error_init(&err); dbus_connection = dbus_bus_get_private(DBUS_BUS_SESSION, &err); diff --git a/gfx/common/dbus_common.h b/gfx/common/dbus_common.h index c8a4e5f3e4..97f6b2a97c 100644 --- a/gfx/common/dbus_common.h +++ b/gfx/common/dbus_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/drm_common.c b/gfx/common/drm_common.c index b1d11ec999..33052c83e1 100644 --- a/gfx/common/drm_common.c +++ b/gfx/common/drm_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (c) 2011-2017 - 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. diff --git a/gfx/common/drm_common.h b/gfx/common/drm_common.h index e66e1c1704..87458dac9a 100644 --- a/gfx/common/drm_common.h +++ b/gfx/common/drm_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (c) 2011-2017 - 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. diff --git a/gfx/common/egl_common.c b/gfx/common/egl_common.c index 691213f7b6..a0dd747c24 100644 --- a/gfx/common/egl_common.c +++ b/gfx/common/egl_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (c) 2011-2017 - 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. @@ -174,7 +174,7 @@ void egl_swap_buffers(void *data) void egl_set_swap_interval(egl_ctx_data_t *egl, unsigned interval) { /* Can be called before initialization. - * Some contexts require that swap interval + * Some contexts require that swap interval * is known at startup time. */ egl->interval = interval; diff --git a/gfx/common/egl_common.h b/gfx/common/egl_common.h index 70f48b666d..e82f889567 100644 --- a/gfx/common/egl_common.h +++ b/gfx/common/egl_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (c) 2011-2017 - 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. diff --git a/gfx/common/gl_common.c b/gfx/common/gl_common.c index 10c139bef0..98a4c41c58 100644 --- a/gfx/common/gl_common.c +++ b/gfx/common/gl_common.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/gl_common.h b/gfx/common/gl_common.h index 7fb5527dcf..46b1c0b621 100644 --- a/gfx/common/gl_common.h +++ b/gfx/common/gl_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * copyright (c) 2011-2017 - 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. diff --git a/gfx/common/vita2d_common.h b/gfx/common/vita2d_common.h index 010f3fca10..39006586a8 100644 --- a/gfx/common/vita2d_common.h +++ b/gfx/common/vita2d_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -41,12 +41,12 @@ struct vita_overlay_data { vita2d_texture *tex; float x; - float y; - float w; + float y; + float w; float h; float tex_x; - float tex_y; - float tex_w; + float tex_y; + float tex_w; float tex_h; float alpha_mod; float width; @@ -76,14 +76,14 @@ typedef struct vita_video bool should_resize; vita_menu_t menu; - + #ifdef HAVE_OVERLAY struct vita_overlay_data *overlay; unsigned overlays; bool overlay_enable; bool overlay_full_screen; #endif - + } vita_video_t; #endif diff --git a/gfx/common/vksym.h b/gfx/common/vksym.h index 02717d7d3f..257952d93a 100644 --- a/gfx/common/vksym.h +++ b/gfx/common/vksym.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/vulkan_common.c b/gfx/common/vulkan_common.c index cab3af0bd3..91990eadb4 100644 --- a/gfx/common/vulkan_common.c +++ b/gfx/common/vulkan_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - 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. @@ -162,14 +162,14 @@ void vulkan_copy_staging_to_dynamic(vk_t *vk, VkCommandBuffer cmd, vulkan_sync_texture_to_gpu(vk, staging); vulkan_transition_texture(vk, cmd, staging); - /* We don't have to sync against previous TRANSFER, - * since we observed the completion by fences. + /* We don't have to sync against previous TRANSFER, + * since we observed the completion by fences. * * If we have a single texture_optimal, we would need to sync against * previous transfers to avoid races. * - * We would also need to optionally maintain extra textures due to - * changes in resolution, so this seems like the sanest and + * We would also need to optionally maintain extra textures due to + * changes in resolution, so this seems like the sanest and * simplest solution. */ vulkan_image_layout_transition(vk, cmd, dynamic->image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, @@ -413,7 +413,7 @@ struct vk_texture vulkan_create_texture(vk_t *vk, /* If the texture is STREAMED and it's not DEVICE_LOCAL, we expect to hit a slower path, * so fallback to copy path. */ - if (type == VULKAN_TEXTURE_STREAMED && + if (type == VULKAN_TEXTURE_STREAMED && (vk->context->memory_properties.memoryTypes[alloc.memoryTypeIndex].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT) == 0) { @@ -657,8 +657,8 @@ struct vk_texture vulkan_create_texture(vk_t *vk, vkQueueSubmit(vk->context->queue, 1, &submit_info, VK_NULL_HANDLE); - /* TODO: Very crude, but texture uploads only happen - * during init, so waiting for GPU to complete transfer + /* TODO: Very crude, but texture uploads only happen + * during init, so waiting for GPU to complete transfer * and blocking isn't a big deal. */ vkQueueWaitIdle(vk->context->queue); #ifdef HAVE_THREADS @@ -733,7 +733,7 @@ static void vulkan_write_quad_descriptors( void vulkan_transition_texture(vk_t *vk, VkCommandBuffer cmd, struct vk_texture *texture) { /* Transition to GENERAL layout for linear streamed textures. - * We're using linear textures here, so only + * We're using linear textures here, so only * GENERAL layout is supported. * If we're already in GENERAL, add a host -> shader read memory barrier * to invalidate texture caches. @@ -774,7 +774,7 @@ static void vulkan_check_dynamic_state( if (vk->tracker.dirty & VULKAN_DIRTY_DYNAMIC_BIT) { VkRect2D sci; - + sci.offset.x = vk->vp.x; sci.offset.y = vk->vp.y; sci.extent.width = vk->vp.width; @@ -873,7 +873,7 @@ void vulkan_draw_quad(vk_t *vk, const struct vk_draw_quad *quad) if ( string_is_equal_fast(quad->mvp, - &vk->tracker.mvp, sizeof(*quad->mvp)) + &vk->tracker.mvp, sizeof(*quad->mvp)) || quad->texture->view != vk->tracker.view || quad->sampler != vk->tracker.sampler) { @@ -939,7 +939,7 @@ void vulkan_image_layout_transition( VkPipelineStageFlags srcStages, VkPipelineStageFlags dstStages) { - VkImageMemoryBarrier barrier = + VkImageMemoryBarrier barrier = { VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER }; barrier.srcAccessMask = srcAccess; @@ -982,7 +982,7 @@ struct vk_buffer vulkan_create_buffer( alloc.memoryTypeIndex = vulkan_find_memory_type( &context->memory_properties, mem_reqs.memoryTypeBits, - VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT); vkAllocateMemory(context->device, &alloc, NULL, &buffer.memory); vkBindBufferMemory(context->device, buffer.buffer, buffer.memory, 0); @@ -1011,12 +1011,12 @@ static struct vk_descriptor_pool *vulkan_alloc_descriptor_pool( const struct vk_descriptor_manager *manager) { unsigned i; - VkDescriptorPoolCreateInfo pool_info = { + VkDescriptorPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_POOL_CREATE_INFO }; - VkDescriptorSetAllocateInfo alloc_info = { + VkDescriptorSetAllocateInfo alloc_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO }; - struct vk_descriptor_pool *pool = + struct vk_descriptor_pool *pool = (struct vk_descriptor_pool*)calloc(1, sizeof(*pool)); if (!pool) return NULL; @@ -1120,12 +1120,12 @@ static bool vulkan_buffer_chain_suballoc(struct vk_buffer_chain *chain, range->data = (uint8_t*)chain->current->buffer.mapped + chain->offset; range->buffer = chain->current->buffer.buffer; range->offset = chain->offset; - chain->offset = (next_offset + chain->alignment - 1) + chain->offset = (next_offset + chain->alignment - 1) & ~(chain->alignment - 1); return true; } - + return false; } @@ -1149,7 +1149,7 @@ struct vk_buffer_chain vulkan_buffer_chain_init( VkBufferUsageFlags usage) { struct vk_buffer_chain chain; - + chain.block_size = block_size; chain.alignment = alignment; chain.offset = 0; @@ -1194,7 +1194,7 @@ bool vulkan_buffer_chain_alloc(const struct vulkan_context *context, } /* We have to allocate a new node, might allocate larger - * buffer here than block_size in case we have + * buffer here than block_size in case we have * a very large allocation. */ if (size < chain->block_size) size = chain->block_size; @@ -1684,7 +1684,7 @@ bool vulkan_context_init(gfx_ctx_vulkan_data_t *vk, } RARCH_LOG("Vulkan dynamic library loaded.\n"); - + GetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)dylib_proc(vulkan_library, "vkGetInstanceProcAddr"); @@ -2012,7 +2012,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, PFN_vkCreateWaylandSurfaceKHR create; if (!VULKAN_SYMBOL_WRAPPER_LOAD_INSTANCE_SYMBOL(vk->context.instance, "vkCreateWaylandSurfaceKHR", create)) return false; - VkWaylandSurfaceCreateInfoKHR surf_info; + VkWaylandSurfaceCreateInfoKHR surf_info; memset(&surf_info, 0, sizeof(surf_info)); @@ -2091,7 +2091,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, surf_info.window = *(const Window*)surface; if (create(vk->context.instance, - &surf_info, NULL, &vk->vk_surface) + &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) return false; } @@ -2114,7 +2114,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, surf_info.window = *(const xcb_window_t*)surface; if (create(vk->context.instance, - &surf_info, NULL, &vk->vk_surface) + &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) return false; } @@ -2136,7 +2136,7 @@ bool vulkan_surface_create(gfx_ctx_vulkan_data_t *vk, surf_info.mirSurface = surface; if (create(vk->context.instance, - &surf_info, NULL, &vk->vk_surface) + &surf_info, NULL, &vk->vk_surface) != VK_SUCCESS) return false; } @@ -2386,7 +2386,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, VkExtent2D swapchain_size; VkSwapchainKHR old_swapchain; VkSurfaceTransformFlagBitsKHR pre_transform; - VkSwapchainCreateInfoKHR info = { + VkSwapchainCreateInfoKHR info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR }; VkPresentModeKHR swapchain_present_mode = VK_PRESENT_MODE_FIFO_KHR; settings_t *settings = config_get_ptr(); @@ -2421,7 +2421,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, swapchain_present_mode = VK_PRESENT_MODE_MAILBOX_KHR; break; } - else if (!swap_interval && present_modes[i] + else if (!swap_interval && present_modes[i] == VK_PRESENT_MODE_IMMEDIATE_KHR) { swapchain_present_mode = VK_PRESENT_MODE_IMMEDIATE_KHR; @@ -2531,11 +2531,11 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, if (desired_swapchain_images < surface_properties.minImageCount) desired_swapchain_images = surface_properties.minImageCount; - if ((surface_properties.maxImageCount > 0) + if ((surface_properties.maxImageCount > 0) && (desired_swapchain_images > surface_properties.maxImageCount)) desired_swapchain_images = surface_properties.maxImageCount; - if (surface_properties.supportedTransforms + if (surface_properties.supportedTransforms & VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) pre_transform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; else @@ -2565,7 +2565,7 @@ bool vulkan_create_swapchain(gfx_ctx_vulkan_data_t *vk, info.presentMode = swapchain_present_mode; info.clipped = true; info.oldSwapchain = old_swapchain; - info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT + info.imageUsage = VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT | VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT; if (vkCreateSwapchainKHR(vk->context.device, diff --git a/gfx/common/vulkan_common.h b/gfx/common/vulkan_common.h index 732e7173e1..e4714142ef 100644 --- a/gfx/common/vulkan_common.h +++ b/gfx/common/vulkan_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - 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. diff --git a/gfx/common/wayland_common.h b/gfx/common/wayland_common.h index 4cec21d386..e48f450907 100644 --- a/gfx/common/wayland_common.h +++ b/gfx/common/wayland_common.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/win32_common.c b/gfx/common/win32_common.c index 426632bbd0..766838e671 100644 --- a/gfx/common/win32_common.c +++ b/gfx/common/win32_common.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -673,8 +673,8 @@ LRESULT CALLBACK WndProcGDI(HWND hwnd, UINT message, if (gdi && gdi->memDC) { RECT rect; - HBRUSH brush = CreateSolidBrush(RGB(1,81,127)); - + HBRUSH brush = CreateSolidBrush(RGB(1,81,127)); + GetClientRect(hwnd, &rect); StretchBlt(gdi->winDC, diff --git a/gfx/common/win32_common.h b/gfx/common/win32_common.h index c87a991fdb..9df4db8246 100644 --- a/gfx/common/win32_common.h +++ b/gfx/common/win32_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/x11_common.c b/gfx/common/x11_common.c index 1375fd1186..c7894ed41d 100644 --- a/gfx/common/x11_common.c +++ b/gfx/common/x11_common.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -139,7 +139,7 @@ void x11_move_window(Display *dpy, Window win, int x, int y, xev.xclient.message_type = XA_NET_MOVERESIZE_WINDOW; xev.xclient.window = win; xev.xclient.format = 32; - xev.xclient.data.l[0] = (1 << MOVERESIZE_X_SHIFT) + xev.xclient.data.l[0] = (1 << MOVERESIZE_X_SHIFT) | (1 << MOVERESIZE_Y_SHIFT); xev.xclient.data.l[1] = x; xev.xclient.data.l[2] = y; @@ -252,7 +252,7 @@ static bool get_video_mode(video_frame_info_t *video_info, *desktop_mode = *modes[0]; - /* If we use black frame insertion, we fake a 60 Hz monitor + /* If we use black frame insertion, we fake a 60 Hz monitor * for 120 Hz one, etc, so try to match that. */ refresh_mod = video_info->black_frame_insertion ? 0.5f : 1.0f; @@ -391,7 +391,7 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) bool down = event->type == KeyPress; int num = 0; KeySym keysym = 0; - + chars[0] = '\0'; if (!filter) @@ -407,7 +407,7 @@ static void x11_handle_key_event(XEvent *event, XIC ic, bool filter) /* XwcLookupString doesn't seem to work. */ num = Xutf8LookupString(ic, &event->xkey, keybuf, ARRAY_SIZE(keybuf), &keysym, &status); - /* libc functions need UTF-8 locale to work properly, + /* libc functions need UTF-8 locale to work properly, * which makes mbrtowc a bit impractical. * * Use custom UTF8 -> UTF-32 conversion. */ @@ -464,7 +464,7 @@ bool x11_alive(void *data) switch (event.type) { case ClientMessage: - if (event.xclient.window == g_x11_win && + if (event.xclient.window == g_x11_win && (Atom)event.xclient.data.l[0] == g_x11_quit_atom) frontend_driver_set_signal_handler_state(1); break; diff --git a/gfx/common/x11_common.h b/gfx/common/x11_common.h index d70f2d28c6..23fc4898bc 100644 --- a/gfx/common/x11_common.h +++ b/gfx/common/x11_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/xinerama_common.c b/gfx/common/xinerama_common.c index 0ce48c66ed..34879e8275 100644 --- a/gfx/common/xinerama_common.c +++ b/gfx/common/xinerama_common.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/common/xinerama_common.h b/gfx/common/xinerama_common.h index e66c17b849..3a7e00e4cf 100644 --- a/gfx/common/xinerama_common.h +++ b/gfx/common/xinerama_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers/ctr_gfx.c b/gfx/drivers/ctr_gfx.c index 0aabb51ccd..720fac0834 100644 --- a/gfx/drivers/ctr_gfx.c +++ b/gfx/drivers/ctr_gfx.c @@ -436,7 +436,7 @@ static void* ctr_init(const video_info_t* video, driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate); aptHook(&ctr->lcd_aptHook, ctr_lcd_aptHook, ctr); - font_driver_init_osd(ctr, false, + font_driver_init_osd(ctr, false, video->is_threaded, FONT_DRIVER_RENDER_CTR); @@ -826,7 +826,7 @@ static bool ctr_frame(void* data, const void* frame, topFramebufferInfo.unk = 0x00000000; u8* framebufferInfoHeader = gfxSharedMemory+0x200+gfxThreadID*0x80; - GSPGPU_FramebufferInfo* + GSPGPU_FramebufferInfo* framebufferInfo = (GSPGPU_FramebufferInfo*)&framebufferInfoHeader[0x4]; framebufferInfoHeader[0x0] ^= 1; framebufferInfo[framebufferInfoHeader[0x0]] = topFramebufferInfo; diff --git a/gfx/drivers/d3d.c b/gfx/drivers/d3d.c index 48aefd123e..4ef1375f90 100644 --- a/gfx/drivers/d3d.c +++ b/gfx/drivers/d3d.c @@ -333,8 +333,8 @@ static void d3d_viewport_info(void *data, struct video_viewport *vp) { d3d_video_t *d3d = (d3d_video_t*)data; - if ( !d3d || - !d3d->renderchain_driver || + if ( !d3d || + !d3d->renderchain_driver || !d3d->renderchain_driver->viewport_info) return; @@ -372,7 +372,7 @@ static void d3d_overlay_render(d3d_video_t *d3d, video_frame_info_t *video_info, vert[i][7] = 1.0f; vert[i][8] = overlay->alpha_mod; } - + d3d_viewport_info(d3d, &vp); overlay_width = vp.width; @@ -514,7 +514,7 @@ void d3d_make_d3dpp(void *data, #ifdef _XBOX d3dpp->Windowed = false; #else - d3dpp->Windowed = settings->bools.video_windowed_fullscreen + d3dpp->Windowed = settings->bools.video_windowed_fullscreen || !info->fullscreen; #endif FS_PRESENTINTERVAL(d3dpp) = D3DPRESENT_INTERVAL_IMMEDIATE; @@ -545,13 +545,13 @@ void d3d_make_d3dpp(void *data, d3dpp->BackBufferFormat = #ifdef _XBOX360 global->console.screen.gamma_correction ? - (D3DFORMAT)MAKESRGBFMT(info->rgb32 ? + (D3DFORMAT)MAKESRGBFMT(info->rgb32 ? D3DFMT_X8R8G8B8 : D3DFMT_LIN_R5G6B5) : #endif info->rgb32 ? D3DFMT_X8R8G8B8 : D3DFMT_LIN_R5G6B5; #else d3dpp->hDeviceWindow = win32_get_window(); - d3dpp->BackBufferFormat = !d3dpp->Windowed ? + d3dpp->BackBufferFormat = !d3dpp->Windowed ? D3DFMT_X8R8G8B8 : D3DFMT_UNKNOWN; #endif @@ -647,7 +647,7 @@ static bool d3d_init_base(void *data, const video_info_t *info) #endif if (!d3d_create_device(&d3d->dev, &d3dpp, - g_pD3D, + g_pD3D, focus_window, d3d->cur_mon_id) ) @@ -724,8 +724,8 @@ static void d3d_calculate_rect(void *data, if (fabsf(device_aspect - desired_aspect) < 0.0001f) { - /* If the aspect ratios of screen and desired aspect - * ratio are sufficiently equal (floating point stuff), + /* If the aspect ratios of screen and desired aspect + * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ } @@ -823,7 +823,7 @@ static bool d3d_initialize(d3d_video_t *d3d, const video_info_t *info) strlcpy(settings->paths.path_font, "game:\\media\\Arial_12.xpr", sizeof(settings->paths.path_font)); #endif - font_driver_init_osd(d3d, false, + font_driver_init_osd(d3d, false, info->is_threaded, FONT_DRIVER_RENDER_DIRECT3D_API); @@ -1513,8 +1513,8 @@ static bool d3d_read_viewport(void *data, uint8_t *buffer, bool is_idle) { d3d_video_t *d3d = (d3d_video_t*)data; - if ( !d3d || - !d3d->renderchain_driver || + if ( !d3d || + !d3d->renderchain_driver || !d3d->renderchain_driver->read_viewport) return false; @@ -1660,7 +1660,7 @@ static void video_texture_load_d3d(d3d_video_t *d3d, uintptr_t *id) { *id = (uintptr_t)d3d_texture_new(d3d->dev, NULL, - ti->width, ti->height, 1, + ti->width, ti->height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, 0, 0, 0, NULL, NULL); } diff --git a/gfx/drivers/d3d.h b/gfx/drivers/d3d.h index efd0d7ca76..dc72306b8e 100644 --- a/gfx/drivers/d3d.h +++ b/gfx/drivers/d3d.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers/dispmanx_gfx.c b/gfx/drivers/dispmanx_gfx.c index 18afe085ae..5eeaf51e7b 100644 --- a/gfx/drivers/dispmanx_gfx.c +++ b/gfx/drivers/dispmanx_gfx.c @@ -32,7 +32,7 @@ struct dispmanx_page { - /* Each page contains it's own resource handler + /* Each page contains it's own resource handler * instead of pointing to in by page number */ DISPMANX_RESOURCE_HANDLE_T resource; bool used; @@ -40,11 +40,11 @@ struct dispmanx_page * isolating it's used flag access. */ slock_t *page_used_mutex; - /* This field will allow us to access the + /* This field will allow us to access the * main _dispvars struct from the vsync CB function */ struct dispmanx_video *dispvars; - /* This field will allow us to access the + /* This field will allow us to access the * surface the page belongs to. */ struct dispmanx_surface *surface; }; @@ -60,23 +60,23 @@ struct dispmanx_surface * already when we enter the surface update function. No time to wait * for free pages before blitting and showing the just rendered frame! */ struct dispmanx_page *next_page; - unsigned int bpp; + unsigned int bpp; VC_RECT_T src_rect; VC_RECT_T dst_rect; VC_RECT_T bmp_rect; - /* Each surface has it's own element, and the + /* Each surface has it's own element, and the * resources are contained one in each page */ DISPMANX_ELEMENT_HANDLE_T element; - VC_DISPMANX_ALPHA_T alpha; + VC_DISPMANX_ALPHA_T alpha; VC_IMAGE_TYPE_T pixformat; - /* Surfaces with a higher layer will be on top of + /* Surfaces with a higher layer will be on top of * the ones with lower. Default is 0. */ int layer; - /* We need to keep this value for the blitting on + /* We need to keep this value for the blitting on * the surface_update function. */ int pitch; }; @@ -111,17 +111,17 @@ struct dispmanx_video bool rgb32; - /* We use this to keep track of internal resolution changes + /* We use this to keep track of internal resolution changes * done by cores in the main surface or in the menu. * We need these outside the surface because we free surfaces * and then we want to test if these values have changed before * recreating them. */ - int core_width; - int core_height; + int core_width; + int core_height; int core_pitch; - int menu_width; + int menu_width; int menu_height; - int menu_pitch; + int menu_pitch; /* Both main and menu surfaces are going to have the same aspect, * so we keep it here for future reference. */ float aspect_ratio; @@ -145,7 +145,7 @@ static struct dispmanx_page *dispmanx_get_free_page(struct dispmanx_video *_disp break; } } - + /* If no page is free at the moment, * wait until a free page is freed by vsync CB. */ if (!page) @@ -171,7 +171,7 @@ static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) struct dispmanx_surface *surface = page->surface; /* Marking the page as free must be done before the signaling - * so when update_main continues (it won't continue until we signal) + * so when update_main continues (it won't continue until we signal) * we can chose this page as free */ if (surface->current_page) { @@ -181,13 +181,13 @@ static void dispmanx_vsync_callback(DISPMANX_UPDATE_HANDLE_T u, void *data) surface->current_page->used = false; slock_unlock(surface->current_page->page_used_mutex); } - + /* The page on which we issued the flip that * caused this callback becomes the visible one */ surface->current_page = page; - /* These two things must be isolated "atomically" to avoid getting - * a false positive in the pending_mutex test in update_main. */ + /* These two things must be isolated "atomically" to avoid getting + * a false positive in the pending_mutex test in update_main. */ slock_lock(page->dispvars->pending_mutex); page->dispvars->pageflip_pending--; @@ -202,19 +202,19 @@ static void dispmanx_surface_free(struct dispmanx_video *_dispvars, int i; struct dispmanx_surface *surface = *sp; - /* What if we run into the vsync cb code after freeing the surface? + /* What if we run into the vsync cb code after freeing the surface? * We could be trying to get non-existant lock, signal non-existant condition.. - * So we wait for any pending flips to complete before freeing any surface. */ + * So we wait for any pending flips to complete before freeing any surface. */ slock_lock(_dispvars->pending_mutex); if (_dispvars->pageflip_pending > 0) scond_wait(_dispvars->vsync_condition, _dispvars->pending_mutex); slock_unlock(_dispvars->pending_mutex); for (i = 0; i < surface->numpages; i++) - { + { vc_dispmanx_resource_delete(surface->pages[i].resource); - surface->pages[i].used = false; - slock_free(surface->pages[i].page_used_mutex); + surface->pages[i].used = false; + slock_free(surface->pages[i].page_used_mutex); } free(surface->pages); @@ -238,12 +238,12 @@ static void dispmanx_surface_setup(struct dispmanx_video *_dispvars, *sp = calloc(1, sizeof(struct dispmanx_surface)); - surface = *sp; + surface = *sp; /* Setup surface parameters */ surface->numpages = numpages; - /* We receive the pitch for what we consider "useful info", - * excluding things that are between scanlines. + /* We receive the pitch for what we consider "useful info", + * excluding things that are between scanlines. * Then we align it to 16 pixels (not bytes) for performance reasons. */ surface->pitch = ALIGN_UP(visible_pitch, (pixformat == VC_IMAGE_XRGB8888 ? 64 : 32)); @@ -258,10 +258,10 @@ static void dispmanx_surface_setup(struct dispmanx_video *_dispvars, for (i = 0; i < surface->numpages; i++) { - surface->pages[i].used = false; - surface->pages[i].surface = surface; - surface->pages[i].dispvars = _dispvars; - surface->pages[i].page_used_mutex = slock_new(); + surface->pages[i].used = false; + surface->pages[i].surface = surface; + surface->pages[i].dispvars = _dispvars; + surface->pages[i].page_used_mutex = slock_new(); } /* No need to mutex this access to the "used" member because @@ -269,16 +269,16 @@ static void dispmanx_surface_setup(struct dispmanx_video *_dispvars, surface->next_page = &(surface->pages[0]); surface->next_page->used = true; - /* The "visible" width obtained from the core pitch. We blit based on + /* The "visible" width obtained from the core pitch. We blit based on * the "visible" width, for cores with things between scanlines. */ visible_width = visible_pitch / (bpp / 8); - + dst_width = _dispvars->dispmanx_height * aspect; dst_height = _dispvars->dispmanx_height; /* If we obtain a scaled image width that is bigger than the physical screen width, * then we keep the physical screen width as our maximun width. */ - if (dst_width > _dispvars->dispmanx_width) + if (dst_width > _dispvars->dispmanx_width) dst_width = _dispvars->dispmanx_width; dst_xpos = (_dispvars->dispmanx_width - dst_width) / 2; @@ -291,15 +291,15 @@ static void dispmanx_surface_setup(struct dispmanx_video *_dispvars, for (i = 0; i < surface->numpages; i++) { - surface->pages[i].resource = vc_dispmanx_resource_create(pixformat, + surface->pages[i].resource = vc_dispmanx_resource_create(pixformat, visible_width, src_height, &(_dispvars->vc_image_ptr)); } /* Add element. */ _dispvars->update = vc_dispmanx_update_start(0); surface->element = vc_dispmanx_element_add( - _dispvars->update,_dispvars->display, layer, - &surface->dst_rect, surface->pages[0].resource, + _dispvars->update,_dispvars->display, layer, + &surface->dst_rect, surface->pages[0].resource, &surface->src_rect, DISPMANX_PROTECTION_NONE, &surface->alpha, 0, (DISPMANX_TRANSFORM_T)0); @@ -309,7 +309,7 @@ static void dispmanx_surface_setup(struct dispmanx_video *_dispvars, static void dispmanx_surface_update_async(const void *frame, struct dispmanx_surface *surface) { struct dispmanx_page *page = NULL; - + /* Since it's an async update, there's no need for multiple pages */ page = &(surface->pages[0]); @@ -363,20 +363,20 @@ static void dispmanx_blank_console (struct dispmanx_video *_dispvars) /* Since pitch will be aligned to 16 pixels (not bytes) we use a * 16 pixels image to save the alignment */ uint16_t image[16] = {0x0000}; - float aspect = (float)_dispvars->dispmanx_width / (float)_dispvars->dispmanx_height; + float aspect = (float)_dispvars->dispmanx_width / (float)_dispvars->dispmanx_height; dispmanx_surface_setup(_dispvars, - 16, - 1, - 32, - 16, + 16, + 1, + 32, + 16, VC_IMAGE_RGB565, 255, aspect, 1, -1, &_dispvars->back_surface); - + /* Updating 1-page surface synchronously asks for truble, since the 1st CB will * signal but not free because the only page is on screen, so get_free will wait forever. */ dispmanx_surface_update_async(image, _dispvars->back_surface); @@ -393,8 +393,8 @@ static void *dispmanx_gfx_init(const video_info_t *video, bcm_host_init(); _dispvars->display = vc_dispmanx_display_open(0 /* LCD */); - /* If the console framebuffer has active overscan settings, - * the user must have overscan_scale=1 in config.txt to have + /* If the console framebuffer has active overscan settings, + * the user must have overscan_scale=1 in config.txt to have * the same size for both fb console and dispmanx. */ graphics_get_display_size(_dispvars->display, &_dispvars->dispmanx_width, &_dispvars->dispmanx_height); @@ -403,11 +403,11 @@ static void *dispmanx_gfx_init(const video_info_t *video, _dispvars->vc_image_ptr = 0; _dispvars->pageflip_pending = 0; _dispvars->menu_active = false; - _dispvars->rgb32 = video->rgb32; + _dispvars->rgb32 = video->rgb32; - /* It's very important that we set aspect here because the + /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() - * and we don't want the main surface to be setup in set_aspect() + * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _dispvars->aspect_ratio = video_driver_get_aspect_ratio(); @@ -424,8 +424,8 @@ static void *dispmanx_gfx_init(const video_info_t *video, if (input && input_data) *input = NULL; - - /* Enable/disable dispmanx bilinear filtering. */ + + /* Enable/disable dispmanx bilinear filtering. */ dispmanx_set_scaling(video->smooth); dispmanx_blank_console(_dispvars); @@ -442,8 +442,8 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width, if (!frame) return true; - if ( (width != _dispvars->core_width) || - (height != _dispvars->core_height) || + if ( (width != _dispvars->core_width) || + (height != _dispvars->core_height) || (_dispvars->aspect_ratio != aspect)) { /* Sanity check. */ @@ -455,25 +455,25 @@ static bool dispmanx_gfx_frame(void *data, const void *frame, unsigned width, _dispvars->core_pitch = pitch; _dispvars->aspect_ratio = aspect; - if (_dispvars->main_surface != NULL) + if (_dispvars->main_surface != NULL) dispmanx_surface_free(_dispvars, &_dispvars->main_surface); - /* Internal resolution or ratio has changed, so we need + /* Internal resolution or ratio has changed, so we need * to recreate the main surface. */ - dispmanx_surface_setup(_dispvars, - width, - height, - pitch, + dispmanx_surface_setup(_dispvars, + width, + height, + pitch, _dispvars->rgb32 ? 32 : 16, _dispvars->rgb32 ? VC_IMAGE_XRGB8888 : VC_IMAGE_RGB565, 255, - _dispvars->aspect_ratio, + _dispvars->aspect_ratio, video_info->max_swapchain_images, 0, &_dispvars->main_surface); - /* We need to recreate the menu surface too, if it exists already, so we - * free it and let dispmanx_set_texture_frame() recreate it as it detects it's NULL.*/ + /* We need to recreate the menu surface too, if it exists already, so we + * free it and let dispmanx_set_texture_frame() recreate it as it detects it's NULL.*/ if (_dispvars->menu_active && _dispvars->menu_surface) dispmanx_surface_free(_dispvars, &_dispvars->menu_surface); } @@ -514,14 +514,14 @@ static void dispmanx_set_texture_frame(void *data, const void *frame, bool rgb32 _dispvars->menu_pitch = width * (rgb32 ? 4 : 2); /* Menu surface only needs a page as it will be updated asynchronously. */ - dispmanx_surface_setup(_dispvars, - width, - height, - _dispvars->menu_pitch, + dispmanx_surface_setup(_dispvars, + width, + height, + _dispvars->menu_pitch, 16, VC_IMAGE_RGBA16, 210, - _dispvars->aspect_ratio, + _dispvars->aspect_ratio, 1, 0, &_dispvars->menu_surface); @@ -583,7 +583,7 @@ static bool dispmanx_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void dispmanx_gfx_set_rotation(void *data, unsigned rotation) @@ -600,15 +600,15 @@ static bool dispmanx_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle return true; } -static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) +static void dispmanx_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) { /* Due to RetroArch setting the data pointer to NULL internally * on core change, data is going to be NULL here after we load - * a new core from the GUI, so we can't count on accessing it - * to store the aspect ratio we are going to use, so we tell RA + * a new core from the GUI, so we can't count on accessing it + * to store the aspect ratio we are going to use, so we tell RA * to keep track of the new aspect ratio and we get it in gfx_frame() - * with video_driver_get_aspect_ratio() to find out if it has changed. */ - + * with video_driver_get_aspect_ratio() to find out if it has changed. */ + switch (aspect_ratio_idx) { case ASPECT_RATIO_SQUARE: @@ -669,7 +669,7 @@ static void dispmanx_gfx_free(void *data) dispmanx_surface_free(_dispvars, &_dispvars->main_surface); dispmanx_surface_free(_dispvars, &_dispvars->back_surface); - if (_dispvars->menu_surface) + if (_dispvars->menu_surface) dispmanx_surface_free(_dispvars, &_dispvars->menu_surface); /* Close display and deinitialize. */ diff --git a/gfx/drivers/drm_gfx.c b/gfx/drivers/drm_gfx.c index 01fb0dec6a..4516bd10e1 100644 --- a/gfx/drivers/drm_gfx.c +++ b/gfx/drivers/drm_gfx.c @@ -68,18 +68,18 @@ struct drm_rect struct drm_page { - struct modeset_buf buf; + struct modeset_buf buf; bool used; /* Each page has it's own mutex for * isolating it's used flag access. */ slock_t *page_used_mutex; - /* This field will allow us to access the + /* This field will allow us to access the * main _dispvars struct from the vsync CB function */ - struct drm_video *drmvars; + struct drm_video *drmvars; - /* This field will allow us to access the + /* This field will allow us to access the * surface the page belongs to. */ struct drm_surface *surface; }; @@ -93,18 +93,18 @@ struct drm_surface /* the page that's currently on screen */ struct drm_page *current_page; - unsigned int bpp; + unsigned int bpp; uint32_t pixformat; - + /* The internal buffers size. */ int src_width; int src_height; - /* Surfaces with a higher layer will be on top of + /* Surfaces with a higher layer will be on top of * the ones with lower. Default is 0. */ int layer; - /* We need to keep this value for the blitting on + /* We need to keep this value for the blitting on * the surface_update function. */ int pitch; int total_pitch; @@ -123,7 +123,7 @@ struct drm_struct drmModeCrtcPtr orig_crtc; - uint32_t plane_id; + uint32_t plane_id; uint32_t plane_fb_prop_id; drmModeEncoder *encoder; @@ -136,13 +136,13 @@ struct drm_video struct drm_surface *main_surface; struct drm_surface *menu_surface; - /* Total dispmanx video dimensions. + /* Total dispmanx video dimensions. * Not counting overscan settings. */ unsigned int kms_width; unsigned int kms_height; /* For threading */ - scond_t *vsync_condition; + scond_t *vsync_condition; slock_t *vsync_cond_mutex; slock_t *pending_mutex; @@ -151,13 +151,13 @@ struct drm_video bool rgb32; - /* We use this to keep track of internal resolution changes + /* We use this to keep track of internal resolution changes * done by cores in the main surface or in the menu. * We need these outside the surface because we free surfaces * and then we want to test if these values have changed before * recreating them. */ - int core_width; - int core_height; + int core_width; + int core_height; int core_pitch; /* Both main and menu surfaces are going to have the same aspect, * so we keep it here for future reference. */ @@ -172,15 +172,15 @@ static int modeset_create_dumbfb(int fd, static void deinit_drm(void) { - /* Restore the original videomode/connector/scanoutbuffer(fb) - * combination (the original CRTC, that is). */ + /* Restore the original videomode/connector/scanoutbuffer(fb) + * combination (the original CRTC, that is). */ drmModeSetCrtc(drm.fd, drm.orig_crtc->crtc_id, drm.orig_crtc->buffer_id, drm.orig_crtc->x, drm.orig_crtc->y, - &drm.connector_id, 1, &drm.orig_crtc->mode); + &drm.connector_id, 1, &drm.orig_crtc->mode); #if 0 - /* TODO: Free surfaces here along + /* TODO: Free surfaces here along * with their pages (framebuffers)! */ if (bufs[0].fb_id) @@ -193,12 +193,12 @@ static void deinit_drm(void) static void drm_surface_free(void *data, struct drm_surface **sp) { - int i; + int i; struct drm_video *_drmvars = data; struct drm_surface *surface = *sp; for (i = 0; i < surface->numpages; i++) - surface->pages[i].used = false; + surface->pages[i].used = false; free(surface->pages); @@ -212,9 +212,9 @@ static void drm_surface_set_aspect(struct drm_surface *surface, float aspect) surface->aspect = aspect; } -static void drm_surface_setup(void *data, int src_width, int src_height, +static void drm_surface_setup(void *data, int src_width, int src_height, int pitch, int bpp, uint32_t pixformat, - int alpha, float aspect, int numpages, int layer, + int alpha, float aspect, int numpages, int layer, struct drm_surface **sp) { struct drm_video *_drmvars = data; @@ -223,23 +223,23 @@ static void drm_surface_setup(void *data, int src_width, int src_height, *sp = calloc (1, sizeof(struct drm_surface)); - surface = *sp; + surface = *sp; /* Setup surface parameters */ surface->numpages = numpages; - /* We receive the total pitch, including things that are - * between scanlines and we calculate the visible pitch - * from the visible width. + /* We receive the total pitch, including things that are + * between scanlines and we calculate the visible pitch + * from the visible width. * * These will be used to increase the offsets for blitting. */ surface->total_pitch = pitch; - surface->pitch = src_width * bpp; + surface->pitch = src_width * bpp; surface->bpp = bpp; surface->pixformat = pixformat; surface->src_width = src_width; surface->src_height = src_height; surface->aspect = aspect; - + /* Allocate memory for all the pages in each surface * and initialize variables inside each page's struct. */ surface->pages = (struct drm_page*) @@ -247,10 +247,10 @@ static void drm_surface_setup(void *data, int src_width, int src_height, for (i = 0; i < surface->numpages; i++) { - surface->pages[i].used = false; - surface->pages[i].surface = surface; - surface->pages[i].drmvars = _drmvars; - surface->pages[i].page_used_mutex = slock_new(); + surface->pages[i].used = false; + surface->pages[i].surface = surface; + surface->pages[i].drmvars = _drmvars; + surface->pages[i].page_used_mutex = slock_new(); } /* Create the framebuffer for each one of the pages of the surface. */ @@ -259,7 +259,7 @@ static void drm_surface_setup(void *data, int src_width, int src_height, surface->pages[i].buf.width = src_width; surface->pages[i].buf.height = src_height; int ret = modeset_create_dumbfb( - drm.fd, &surface->pages[i].buf, bpp, pixformat); + drm.fd, &surface->pages[i].buf, bpp, pixformat); if (ret) { @@ -272,20 +272,20 @@ static void drm_surface_setup(void *data, int src_width, int src_height, static void drm_page_flip(struct drm_surface *surface) { - /* We alredy have the id of the FB_ID property of + /* We alredy have the id of the FB_ID property of * the plane on which we are going to do a pageflip: * we got it back in drm_plane_setup() */ int ret; static drmModeAtomicReqPtr req = NULL; - req = drmModeAtomicAlloc(); + req = drmModeAtomicAlloc(); - /* We add the buffer to the plane properties we want to - * set on an atomically, in a single step. + /* We add the buffer to the plane properties we want to + * set on an atomically, in a single step. * We pass the plane id, the property id and the new fb id. */ - ret = drmModeAtomicAddProperty(req, - drm.plane_id, - drm.plane_fb_prop_id, + ret = drmModeAtomicAddProperty(req, + drm.plane_id, + drm.plane_fb_prop_id, surface->pages[surface->flip_page].buf.fb_id); if (ret < 0) @@ -294,9 +294,9 @@ static void drm_page_flip(struct drm_surface *surface) } /*... now we just need to do the commit */ - /* REMEMBER!!! The DRM_MODE_PAGE_FLIP_EVENT flag asks the kernel - * to send you an event to the drm.fd once the - * pageflip is complete. If you don't want -12 errors + /* REMEMBER!!! The DRM_MODE_PAGE_FLIP_EVENT flag asks the kernel + * to send you an event to the drm.fd once the + * pageflip is complete. If you don't want -12 errors * (ENOMEM), namely "Cannot allocate memory", then * you must drain the event queue of that fd. */ ret = drmModeAtomicCommit(drm.fd, req, 0, NULL); @@ -324,7 +324,7 @@ static void drm_surface_update(void *data, const void *frame, for (line = 0; line < surface->src_height; line++) { memcpy ( - surface->pages[surface->flip_page].buf.map + dst_offset, + surface->pages[surface->flip_page].buf.map + dst_offset, (uint8_t*)frame + src_offset, surface->pitch); src_offset += surface->total_pitch; @@ -342,7 +342,7 @@ static uint32_t get_plane_prop_id(uint32_t obj_id, const char *name) int i,j; drmModePlaneRes *plane_resources; drmModePlane *plane; - drmModeObjectProperties *props; + drmModeObjectProperties *props; drmModePropertyRes **props_info; char format_str[5]; @@ -354,16 +354,16 @@ static uint32_t get_plane_prop_id(uint32_t obj_id, const char *name) if (plane->plane_id != obj_id) continue; - /* TODO: Improvement. We get all the properties of the + /* TODO: Improvement. We get all the properties of the * plane and info about the properties. - * We should have done this already... + * We should have done this already... * This implementation must be improved. */ props = drmModeObjectGetProperties(drm.fd, plane->plane_id, DRM_MODE_OBJECT_PLANE); props_info = malloc(props->count_props * sizeof *props_info); for (j = 0; j < props->count_props; ++j) - props_info[j] = drmModeGetProperty(drm.fd, props->props[j]); + props_info[j] = drmModeGetProperty(drm.fd, props->props[j]); /* We look for the prop_id we need */ for (j = 0; j < props->count_props; j++) @@ -409,7 +409,7 @@ static uint64_t drm_plane_type(drmModePlane *plane) * access them simultaneously here. * We are interested in OVERLAY planes only, that's type 0 or DRM_PLANE_TYPE_OVERLAY * (see /usr/xf86drmMode.h for definition). */ - drmModeObjectPropertiesPtr props = + drmModeObjectPropertiesPtr props = drmModeObjectGetProperties(drm.fd, plane->plane_id, DRM_MODE_OBJECT_PLANE); for (j = 0; j < props->count_props; j++) @@ -421,14 +421,14 @@ static uint64_t drm_plane_type(drmModePlane *plane) return (0); } -/* This configures our only overlay plane to render the given surface. */ +/* This configures our only overlay plane to render the given surface. */ static void drm_plane_setup(struct drm_surface *surface) { int i,j; char fmt_name[5]; /* Get plane resources */ - drmModePlane *plane; + drmModePlane *plane; drmModePlaneRes *plane_resources; plane_resources = drmModeGetPlaneResources(drm.fd); if (!plane_resources) @@ -437,14 +437,14 @@ static void drm_plane_setup(struct drm_surface *surface) } RARCH_LOG ("DRM: Number of planes on FD %d is %d\n", - drm.fd, plane_resources->count_planes); + drm.fd, plane_resources->count_planes); - /* dump_planes(drm.fd); */ + /* dump_planes(drm.fd); */ - /* Look for a plane/overlay we can use with the configured CRTC + /* Look for a plane/overlay we can use with the configured CRTC * Find a plane which can be connected to our CRTC. Find the * CRTC index first, then iterate over available planes. - * Yes, strangely we need the in-use CRTC index to mask possible_crtc + * Yes, strangely we need the in-use CRTC index to mask possible_crtc * during the planes iteration... */ unsigned int crtc_index = 0; for (i = 0; i < (unsigned int)drm.resources->count_crtcs; i++) @@ -457,8 +457,8 @@ static void drm_plane_setup(struct drm_surface *surface) } } - /* Programmer!! Save your sanity!! Primary planes have to - * cover the entire CRTC, and if you don't do that, you + /* Programmer!! Save your sanity!! Primary planes have to + * cover the entire CRTC, and if you don't do that, you * will get dmesg error "Plane must cover entire CRTC". * * Look at linux/source/drivers/gpu/drm/drm_plane_helper.c comments for more info. @@ -473,20 +473,20 @@ static void drm_plane_setup(struct drm_surface *surface) continue; } - /* We are only interested in overlay planes. No overlay, no fun. + /* We are only interested in overlay planes. No overlay, no fun. * (no scaling, must cover crtc..etc) so we skip primary planes */ if (drm_plane_type(plane) != DRM_PLANE_TYPE_OVERLAY) { RARCH_LOG ("DRM: plane with ID %d is not an overlay. May be primary or cursor. Not usable.\n", plane->plane_id); continue; - } + } if (!format_support(plane, surface->pixformat)) { RARCH_LOG ("DRM: plane with ID %d does not support framebuffer format\n", plane->plane_id); continue; - } + } drm.plane_id = plane->plane_id; drmModeFreePlane(plane); @@ -504,7 +504,7 @@ static void drm_plane_setup(struct drm_surface *surface) } /* We are going to be changing the framebuffer ID property of the chosen overlay every time - * we do a pageflip, so we get the property ID here to have it handy on the PageFlip function. */ + * we do a pageflip, so we get the property ID here to have it handy on the PageFlip function. */ drm.plane_fb_prop_id = get_plane_prop_id(drm.plane_id, "FB_ID"); if (!drm.plane_fb_prop_id) { @@ -531,14 +531,14 @@ static void drm_plane_setup(struct drm_surface *surface) uint32_t src_x = 0; uint32_t src_y = 0; - /* We have to set a buffer for the plane, whatever buffer we want, + /* We have to set a buffer for the plane, whatever buffer we want, * but we must set a buffer so the plane starts reading from it now. */ - if (drmModeSetPlane(drm.fd, drm.plane_id, drm.crtc_id, + if (drmModeSetPlane(drm.fd, drm.plane_id, drm.crtc_id, surface->pages[surface->flip_page].buf.fb_id, plane_flags, plane_x, plane_y, plane_w, plane_h, src_x<<16, src_y<<16, src_w<<16, src_h<<16)) { - RARCH_ERR("[DRM]: failed to enable plane: %s\n", strerror(errno)); + RARCH_ERR("[DRM]: failed to enable plane: %s\n", strerror(errno)); } RARCH_LOG("[DRM]: src_w %d, src_h %d, plane_w %d, plane_h %d\n", @@ -615,7 +615,7 @@ static bool init_drm(void) * VERY important or we won't get all the available planes on drmGetPlaneResources()! * We also need to enable the ATOMIC cap to see the atomic properties in objects!! */ ret = drmSetClientCap(drm.fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1); - if (ret) + if (ret) RARCH_ERR ("DRM: can't set UNIVERSAL PLANES cap.\n"); else RARCH_LOG ("DRM: UNIVERSAL PLANES cap set\n"); @@ -623,8 +623,8 @@ static bool init_drm(void) ret = drmSetClientCap(drm.fd, DRM_CLIENT_CAP_ATOMIC, 1); if (ret) - { - /*If this happens, check kernel support and kernel parameters + { + /*If this happens, check kernel support and kernel parameters * (add i915.nuclear_pageflip=y to the kernel boot line for example) */ RARCH_ERR ("DRM: can't set ATOMIC caps: %s\n", strerror(errno)); } @@ -674,7 +674,7 @@ static bool init_drm(void) drm.crtc_id = drm.encoder->crtc_id; drm.connector_id = connector->connector_id; - /* Backup original crtc and it's mode, so we can restore the original video mode + /* Backup original crtc and it's mode, so we can restore the original video mode * on exit in case we change it. */ drm.orig_crtc = drmModeGetCrtc(drm.fd, drm.encoder->crtc_id); drm.current_mode = &(drm.orig_crtc->mode); @@ -683,7 +683,7 @@ static bool init_drm(void) struct modeset_buf buf; buf.width = drm.current_mode->hdisplay; buf.height = drm.current_mode->vdisplay; - ret = modeset_create_dumbfb(drm.fd, &buf, 4, DRM_FORMAT_XRGB8888); + ret = modeset_create_dumbfb(drm.fd, &buf, 4, DRM_FORMAT_XRGB8888); if (ret) { RARCH_ERR ("DRM: can't create dumb fb\n"); @@ -692,7 +692,7 @@ static bool init_drm(void) if (drmModeSetCrtc(drm.fd, drm.crtc_id, buf.fb_id, 0, 0, &drm.connector_id, 1, drm.current_mode)) { - RARCH_ERR ("DRM: failed to set mode\n"); + RARCH_ERR ("DRM: failed to set mode\n"); return false; } @@ -710,11 +710,11 @@ static void *drm_gfx_init(const video_info_t *video, /* Setup surface parameters */ _drmvars->menu_active = false; - _drmvars->rgb32 = video->rgb32; + _drmvars->rgb32 = video->rgb32; - /* It's very important that we set aspect here because the + /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() - * and we don't want the main surface to be setup in set_aspect() + * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _drmvars->current_aspect = video_driver_get_aspect_ratio(); @@ -743,9 +743,9 @@ static void *drm_gfx_init(const video_info_t *video, RARCH_LOG ("DRM: Init successful.\n"); } - _drmvars->kms_width = drm.current_mode->hdisplay; - _drmvars->kms_height = drm.current_mode->vdisplay; - + _drmvars->kms_width = drm.current_mode->hdisplay; + _drmvars->kms_height = drm.current_mode->vdisplay; + return _drmvars; } @@ -755,7 +755,7 @@ static bool drm_gfx_frame(void *data, const void *frame, unsigned width, { struct drm_video *_drmvars = data; - if ( ( width != _drmvars->core_width) || + if ( ( width != _drmvars->core_width) || (height != _drmvars->core_height)) { /* Sanity check. */ @@ -766,22 +766,22 @@ static bool drm_gfx_frame(void *data, const void *frame, unsigned width, _drmvars->core_height = height; _drmvars->core_pitch = pitch; - if (_drmvars->main_surface != NULL) + if (_drmvars->main_surface != NULL) drm_surface_free(_drmvars, &_drmvars->main_surface); /* We need to recreate the main surface and it's pages (buffers). */ - drm_surface_setup(_drmvars, - width, - height, - pitch, + drm_surface_setup(_drmvars, + width, + height, + pitch, _drmvars->rgb32 ? 4 : 2, _drmvars->rgb32 ? DRM_FORMAT_XRGB8888 : DRM_FORMAT_RGB565, 255, - _drmvars->current_aspect, + _drmvars->current_aspect, 3, 0, &_drmvars->main_surface); - + /* We need to change the plane to read from the main surface */ drm_plane_setup(_drmvars->main_surface); } @@ -820,34 +820,34 @@ static void drm_set_texture_frame(void *data, const void *frame, bool rgb32, if (!_drmvars->menu_active) return; - /* If menu is active in this frame but the + /* If menu is active in this frame but the * menu surface is NULL, we allocate a new one.*/ if (!_drmvars->menu_surface) { - drm_surface_setup(_drmvars, - width, - height, - width * 4, + drm_surface_setup(_drmvars, + width, + height, + width * 4, 4, DRM_FORMAT_XRGB8888, 210, - _drmvars->current_aspect, + _drmvars->current_aspect, 2, 0, &_drmvars->menu_surface); - /* We need to re-setup the ONLY plane as the setup + /* We need to re-setup the ONLY plane as the setup * depends on input buffers dimensions. */ drm_plane_setup(_drmvars->menu_surface); } - /* We have to go on a pixel format conversion adventure - * for now, until we can convince RGUI to output + /* We have to go on a pixel format conversion adventure + * for now, until we can convince RGUI to output * in an 8888 format. */ - unsigned int src_pitch = width * 2; + unsigned int src_pitch = width * 2; unsigned int dst_pitch = width * 4; unsigned int dst_width = width; - uint32_t line[dst_width]; + uint32_t line[dst_width]; /* The output pixel array with the converted pixels. */ char *frame_output = (char *) malloc (dst_pitch * height); @@ -859,12 +859,12 @@ static void drm_set_texture_frame(void *data, const void *frame, bool rgb32, { for (j = 0; j < src_pitch / 2; j++) { - uint16_t src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); + uint16_t src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); /* The hex AND is for keeping only the part we need for each component. */ uint32_t R = (src_pix << 8) & 0x00FF0000; uint32_t G = (src_pix << 4) & 0x0000FF00; uint32_t B = (src_pix << 0) & 0x000000FF; - line[j] = (0 | R | G | B); + line[j] = (0 | R | G | B); } memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch); } @@ -923,7 +923,7 @@ static bool drm_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void drm_gfx_set_rotation(void *data, unsigned rotation) @@ -940,20 +940,20 @@ static bool drm_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle) return true; } -static void drm_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) +static void drm_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) { struct drm_video *_drmvars = data; /* Here we obtain the new aspect ratio. */ float new_aspect = aspectratio_lut[aspect_ratio_idx].value; if (_drmvars->current_aspect != new_aspect) - { + { _drmvars->current_aspect = new_aspect; drm_surface_set_aspect(_drmvars->main_surface, new_aspect); if (_drmvars->menu_active) { drm_surface_set_aspect(_drmvars->menu_surface, new_aspect); - drm_plane_setup(_drmvars->menu_surface); + drm_plane_setup(_drmvars->menu_surface); } } } @@ -996,13 +996,13 @@ static void drm_gfx_free(void *data) drm_surface_free(_drmvars, &_drmvars->main_surface); - if (_drmvars->menu_surface) + if (_drmvars->menu_surface) drm_surface_free(_drmvars, &_drmvars->menu_surface); /* Destroy mutexes and conditions. */ slock_free(_drmvars->pending_mutex); slock_free(_drmvars->vsync_cond_mutex); - scond_free(_drmvars->vsync_condition); + scond_free(_drmvars->vsync_condition); free(_drmvars); } diff --git a/gfx/drivers/exynos_gfx.c b/gfx/drivers/exynos_gfx.c index 4b0476f4b5..6d0efe41e7 100644 --- a/gfx/drivers/exynos_gfx.c +++ b/gfx/drivers/exynos_gfx.c @@ -195,10 +195,10 @@ static int exynos_get_device_index(void) return index; } -/* The main pageflip handler, which the DRM executes +/* The main pageflip handler, which the DRM executes * when it flips to the page. * - * Decreases the pending pageflip count and + * Decreases the pending pageflip count and * updates the current page. */ static void exynos_page_flip_handler(int fd, unsigned frame, unsigned sec, @@ -222,7 +222,7 @@ static struct exynos_page *exynos_get_free_page( { unsigned i; - for (i = 0; i < cnt; ++i) + for (i = 0; i < cnt; ++i) { if (!p[i].used) return &p[i]; @@ -1513,7 +1513,7 @@ static bool exynos_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static bool exynos_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle) diff --git a/gfx/drivers/gdi_gfx.c b/gfx/drivers/gdi_gfx.c index b1ded17fdb..c28aa01784 100644 --- a/gfx/drivers/gdi_gfx.c +++ b/gfx/drivers/gdi_gfx.c @@ -190,7 +190,7 @@ static bool gdi_gfx_frame(void *data, const void *frame, bool draw = true; gdi_t *gdi = (gdi_t*)data; HWND hwnd = win32_get_window(); - BITMAPINFO *info; + BITMAPINFO *info; if (!frame || !frame_width || !frame_height) return true; @@ -493,7 +493,7 @@ static void gdi_set_texture_frame(void *data, } } -static void gdi_set_osd_msg(void *data, +static void gdi_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, const void *params, void *font) diff --git a/gfx/drivers/gl.c b/gfx/drivers/gl.c index c717513f74..27c79b9a1e 100644 --- a/gfx/drivers/gl.c +++ b/gfx/drivers/gl.c @@ -740,19 +740,19 @@ static void gl_render_osd_background( video_coords_t coords; struct uniform_info uniform_param; float colors[4]; - const unsigned + const unsigned vertices_total = 6; float *dummy = (float*)calloc(4 * vertices_total, sizeof(float)); float *verts = (float*)malloc(2 * vertices_total * sizeof(float)); settings_t *settings = config_get_ptr(); - int msg_width = + int msg_width = font_driver_get_message_width(NULL, msg, strlen(msg), 1.0f); /* shader driver expects vertex coords as 0..1 */ float x = video_info->font_msg_pos_x; float y = video_info->font_msg_pos_y; float width = msg_width / (float)video_info->width; - float height = + float height = settings->floats.video_font_size / (float)video_info->height; float x2 = 0.005f; /* extend background around text */ @@ -796,7 +796,7 @@ static void gl_render_osd_background( coords_data.handle_data = NULL; coords_data.data = &coords; - + video_driver_set_viewport(video_info->width, video_info->height, true, false); @@ -1033,7 +1033,7 @@ static bool gl_frame(void *data, const void *frame, glBindTexture(GL_TEXTURE_2D, gl->texture[gl->tex_index]); /* Can be NULL for frame dupe / NULL render. */ - if (frame) + if (frame) { if (!gl->hw_render_fbo_init) { @@ -1082,7 +1082,7 @@ static bool gl_frame(void *data, const void *frame, if (gl->fbo_feedback_enable) { - const struct video_fbo_rect + const struct video_fbo_rect *rect = &gl->fbo_rect[gl->fbo_feedback_pass]; GLfloat xamt = (GLfloat)rect->img_width / rect->width; GLfloat yamt = (GLfloat)rect->img_height / rect->height; @@ -1946,7 +1946,7 @@ static void *gl_init(const video_info_t *video, const input_driver_t **input, vo video_context_driver_input_driver(&inp); if (video->font_enable) - font_driver_init_osd(gl, false, + font_driver_init_osd(gl, false, video->is_threaded, FONT_DRIVER_RENDER_OPENGL_API); diff --git a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h index 1b048d2223..c6ad48e071 100644 --- a/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h +++ b/gfx/drivers/gl_shaders/pipeline_snowflake.glsl.frag.h @@ -1,4 +1,4 @@ -/* credits to: TheTimJames +/* credits to: TheTimJames https://www.shadertoy.com/view/Md2GRw */ @@ -17,17 +17,17 @@ static const char* stock_fragment_xmb_snowflake = GLSL( } float rand_float(float x) - { + { return rand(vec2(x, 1.0)); } - + float snow(vec3 pos, vec2 uv, float o) { vec2 d = (pos.xy - uv); float a = atan(d.y,d.x) + sin(atime*1.0 + o) * 10.0; - + float dist = d.x*d.x + d.y*d.y; - + if(dist < pos.z/400.0) { float col = 0.0; @@ -41,7 +41,7 @@ static const char* stock_fragment_xmb_snowflake = GLSL( } return col * pos.z; } - + return 0.0; } @@ -54,12 +54,12 @@ static const char* stock_fragment_xmb_snowflake = GLSL( float z = rand_float(float(i) + 13.0); float x = 1.8 - (3.6) * (rand_float(floor((time*((z + 1.0) / 2.0) +o) / 2.0)) + sin(time * o /1000.0) / 10.0); float y = 1.0 - mod((time * ((z + 1.0)/2.0)) + o, 2.0); - - color += snow(vec3(x,y,z), c, o); + + color += snow(vec3(x,y,z), c, o); } - + return color; - } + } void main(void) { @@ -67,9 +67,9 @@ static const char* stock_fragment_xmb_snowflake = GLSL( uv = uv * 2.0 - 1.0; vec2 p = uv; p.x *= OutputSize.x / OutputSize.y; - + atime = (time + 1.0) / 4.0; - + gl_FragColor = vec4(col(p)); } diff --git a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.h b/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.h index 256ae4378b..52f2385bbe 100644 --- a/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.h +++ b/gfx/drivers/gl_shaders/pipeline_xmb_ribbon_simple.cg.h @@ -51,7 +51,7 @@ static const char *stock_xmb_ribbon_simple = CG( float4 color : COLOR; }; - output main_fragment(uniform input IN) + output main_fragment(uniform input IN) { output OUT; OUT.color = float4(0.05, 0.05, 0.05, 1.0); diff --git a/gfx/drivers/gx_gfx.c b/gfx/drivers/gx_gfx.c index 14b7f61c38..7726a4a876 100644 --- a/gfx/drivers/gx_gfx.c +++ b/gfx/drivers/gx_gfx.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -270,7 +270,7 @@ static void retrace_callback(u32 retrace_count) static bool gx_isValidXOrigin(int origin) { - if(origin < 0 || origin + gx_used_system_xOrigin < 0 || + if(origin < 0 || origin + gx_used_system_xOrigin < 0 || gx_mode.viWidth + origin + gx_used_system_xOrigin > 720) return false; return true; @@ -304,7 +304,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, VIDEO_SetPostRetraceCallback(NULL); g_draw_done = false; /* wait for next even field */ - /* this prevents screen artifacts when switching + /* this prevents screen artifacts when switching * between interlaced & non-interlaced modes */ do VIDEO_WaitVSync(); while (!VIDEO_GetNextField()); @@ -418,7 +418,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, } gx_mode.viXOrigin = gx_xOrigin = tmpOrigin; - gx_mode.viYOrigin = gx_yOrigin = + gx_mode.viYOrigin = gx_yOrigin = (max_height - gx_mode.viHeight) / (2 * viHeightMultiplier); gx_xOriginNeg = 0, gx_xOriginPos = 0; @@ -485,7 +485,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, GX_SetDispCopyDst((u16)xfbWidth, (u16)xfbHeight); GX_SetCopyFilter(gx_mode.aa, gx_mode.sample_pattern, - (gx_mode.xfbMode == VI_XFBMODE_SF) + (gx_mode.xfbMode == VI_XFBMODE_SF) ? GX_FALSE : settings->bools.video_vfilter, gx_mode.vfilter); GXColor color = { 0, 0, 0, 0xff }; @@ -495,7 +495,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); GX_InvalidateTexAll(); GX_Flush(); - + /* Now apply all the configuration to the screen */ VIDEO_Configure(&gx_mode); VIDEO_ClearFrameBuffer(&gx_mode, gx->framebuf[0], COLOR_BLACK); @@ -507,7 +507,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, VIDEO_SetBlack(false); VIDEO_Flush(); VIDEO_WaitVSync(); - + RARCH_LOG("[GX]: Resolution: %dx%d (%s)\n", gx_mode.fbWidth, gx_mode.efbHeight, (gx_mode.viTVMode & 3) == VI_INTERLACE ? "interlaced" : "progressive"); @@ -524,7 +524,7 @@ static void gx_set_video_mode(void *data, unsigned fbWidth, unsigned lines, if (modetype == VI_NON_INTERLACE) refresh_rate = 59.8261f; } - + driver_ctl(RARCH_DRIVER_CTL_SET_REFRESH_RATE, &refresh_rate); } @@ -977,8 +977,8 @@ static void gx_resize(void *data) #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), + /* 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) @@ -1111,8 +1111,8 @@ static void gx_blit_line(gx_video_t *gx, { uint8_t rem = 1 << ((i + j * FONT_WIDTH) & 7); unsigned offset = (i + j * FONT_WIDTH) >> 3; - bool col = - (bitmap_bin[FONT_OFFSET((unsigned char)*message) + offset] + bool col = + (bitmap_bin[FONT_OFFSET((unsigned char)*message) + offset] & rem); GXColor c = b; @@ -1213,7 +1213,7 @@ static void gx_set_texture_enable(void *data, bool enable, bool full_screen) return; gx->menu_texture_enable = enable; - /* need to make sure the game texture is the right pixel + /* need to make sure the game texture is the right pixel * format for menu overlay. */ gx->should_resize = true; } @@ -1379,7 +1379,7 @@ static bool gx_overlay_load(void *data, images[i].height * sizeof(uint32_t)); /* Default. Stretch to whole screen. */ - gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); + gx_overlay_tex_geom(gx, i, 0, 0, 1, 1); gx_overlay_vertex_geom(gx, i, 0, 0, 1, 1); gx->overlay[i].alpha_mod = 1.0f; } @@ -1647,7 +1647,7 @@ static bool gx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } video_driver_t video_gx = { diff --git a/gfx/drivers/gx_gfx_vi_encoder.c b/gfx/drivers/gx_gfx_vi_encoder.c index 104650f040..5b7a4ca905 100644 --- a/gfx/drivers/gx_gfx_vi_encoder.c +++ b/gfx/drivers/gx_gfx_vi_encoder.c @@ -1,413 +1,413 @@ -/**************************************************************************** - * 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 - -#include - -#include "../../defines/gx_defines.h" - -void udelay(int us); - -static u32 i2cIdentFirst = 0; -static u32 i2cIdentFlag = 1; -static vu32* const _i2cReg = (u32*)0xCD800000; - -static INLINE void __viOpenI2C(u32 channel) -{ - u32 val = ((_i2cReg[49]&~0x8000)|0x4000) | _SHIFTL(channel,15,1); - _i2cReg[49] = val; -} - -static INLINE void __viSetSCL(u32 channel) -{ - u32 val = (_i2cReg[48]&~0x4000) | _SHIFTL(channel,14,1); - _i2cReg[48] = val; -} - -static INLINE void __viSetSDA(u32 channel) -{ - u32 val = (_i2cReg[48]&~0x8000) | _SHIFTL(channel,15,1); - _i2cReg[48] = val; -} - -#define __viGetSDA() (_SHIFTR(_i2cReg[50],15,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) - { - __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); - return 0; - } - - __viOpenI2C(1); - for(i=0;i +#include +#include +#include +#include + +#include + +#include "../../defines/gx_defines.h" + +void udelay(int us); + +static u32 i2cIdentFirst = 0; +static u32 i2cIdentFlag = 1; +static vu32* const _i2cReg = (u32*)0xCD800000; + +static INLINE void __viOpenI2C(u32 channel) +{ + u32 val = ((_i2cReg[49]&~0x8000)|0x4000) | _SHIFTL(channel,15,1); + _i2cReg[49] = val; +} + +static INLINE void __viSetSCL(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x4000) | _SHIFTL(channel,14,1); + _i2cReg[48] = val; +} + +static INLINE void __viSetSDA(u32 channel) +{ + u32 val = (_i2cReg[48]&~0x8000) | _SHIFTL(channel,15,1); + _i2cReg[48] = val; +} + +#define __viGetSDA() (_SHIFTR(_i2cReg[50],15,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) + { + __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); + return 0; + } + + __viOpenI2C(1); + for(i=0;ifbname, &status); @@ -873,7 +873,7 @@ static void omap_render_msg(omap_video_t *vid, const char *msg) int base_x, base_y; int glyph_width, glyph_height; const uint8_t *src = NULL; - const struct font_glyph *glyph = + const struct font_glyph *glyph = vid->font_driver->get_glyph(vid->font, (uint8_t)*msg); if (!glyph) @@ -888,7 +888,7 @@ static void omap_render_msg(omap_video_t *vid, const char *msg) glyph_width = glyph->width; glyph_height = glyph->height; - src = atlas->buffer + glyph->atlas_offset_x + + src = atlas->buffer + glyph->atlas_offset_x + glyph->atlas_offset_y * atlas->width; if (base_x < 0) @@ -1085,7 +1085,7 @@ static bool omap_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void omap_gfx_set_rotation(void *data, unsigned rotation) diff --git a/gfx/drivers/psp1_gfx.c b/gfx/drivers/psp1_gfx.c index 128fab83b5..8133a8dcf5 100644 --- a/gfx/drivers/psp1_gfx.c +++ b/gfx/drivers/psp1_gfx.c @@ -122,7 +122,7 @@ typedef struct psp1_video #define PSP_FRAME_SLICE_COUNT (PSP_FRAME_ROWS_COUNT * PSP_FRAME_COLUMNS_COUNT) #define PSP_FRAME_VERTEX_COUNT (PSP_FRAME_SLICE_COUNT * 2) -static INLINE void psp_set_screen_coords (psp1_sprite_t* framecoords, +static INLINE void psp_set_screen_coords (psp1_sprite_t* framecoords, int x, int y, int width, int height, unsigned rotation) { int i; @@ -261,7 +261,7 @@ static void psp_on_vblank(u32 sub, psp1_video_t *psp) static void *psp_init(const video_info_t *video, const input_driver_t **input, void **input_data) { - /* TODO : add ASSERT() checks or use main RAM if + /* TODO : add ASSERT() checks or use main RAM if * VRAM is too low for desired video->input_scale. */ int pixel_format, lut_pixel_format, lut_block_count; @@ -284,11 +284,11 @@ static void *psp_init(const video_info_t *video, psp->vp.full_width = SCEGU_SCR_WIDTH; psp->vp.full_height = SCEGU_SCR_HEIGHT; - /* Make sure anything using uncached pointers reserves + /* Make sure anything using uncached pointers reserves * whole cachelines (memory address and size need to be a multiple of 64) * so it isn't overwritten by an unlucky cache writeback. * - * This includes display lists since the Gu library uses + * This includes display lists since the Gu library uses * uncached pointers to write to them. */ /* Allocate more space if bigger display lists are needed. */ @@ -367,8 +367,8 @@ static void *psp_init(const video_info_t *video, psp->draw_buffer = SCEGU_VRAM_BP_0; psp->bpp_log2 = 1; - pixel_format = - (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_0RGB1555) + pixel_format = + (video_driver_get_pixel_format() == RETRO_PIXEL_FORMAT_0RGB1555) ? GU_PSM_5551 : GU_PSM_5650 ; lut_pixel_format = GU_PSM_T16; @@ -410,7 +410,7 @@ static void *psp_init(const video_info_t *video, sceGuFinish(); sceGuSync(0, 0); - + /* TODO : check if necessary */ sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); @@ -428,10 +428,10 @@ static void *psp_init(const video_info_t *video, /* green only */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0x0000FF00, 0xFFFFFFFF); - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); - + /* restore */ sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0xFFFFFFFF); @@ -446,7 +446,7 @@ static void *psp_init(const video_info_t *video, sceGuClutMode(pixel_format, 0, color_mask, 0); sceGuClutLoad(lut_block_count, LUT_b); - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); @@ -544,10 +544,10 @@ static bool psp_frame(void *data, const void *frame, sceGuTexFilter(psp->tex_filter, psp->tex_filter); sceGuClear(GU_COLOR_BUFFER_BIT); - /* frame in VRAM ? texture/palette was + /* frame in VRAM ? texture/palette was * set in core so draw directly */ - if (psp->hw_render) - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | + if (psp->hw_render) + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, (void*)(psp->frame_coords)); else @@ -672,7 +672,7 @@ static void psp_set_texture_frame(void *data, const void *frame, bool rgb32, #endif sceGuBlendFunc(GU_ADD, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F); ; - sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | + sceGuDrawArray(GU_SPRITES, GU_TEXTURE_32BITF | GU_VERTEX_32BITF | GU_TRANSFORM_2D, PSP_FRAME_VERTEX_COUNT, NULL, psp->menu.frame_coords); sceGuFinish(); @@ -725,7 +725,7 @@ static void psp_update_viewport(psp1_video_t* psp, if ((fabsf(device_aspect - desired_aspect) < 0.0001f) || (fabsf((16.0/9.0) - desired_aspect) < 0.02f)) { - /* If the aspect ratios of screen and desired aspect + /* If the aspect ratios of screen and desired aspect * ratio are sufficiently equal (floating point stuff), * assume they are actually equal. */ @@ -825,7 +825,7 @@ static void psp_apply_state_changes(void *data) static void psp_viewport_info(void *data, struct video_viewport *vp) { psp1_video_t *psp = (psp1_video_t*)data; - + if (psp) *vp = psp->vp; } @@ -951,7 +951,7 @@ static bool psp_set_shader(void *data, (void)type; (void)path; - return false; + return false; } video_driver_t video_psp1 = { diff --git a/gfx/drivers/psp1_gfx.h b/gfx/drivers/psp1_gfx.h index 4d2021379c..5798f56149 100644 --- a/gfx/drivers/psp1_gfx.h +++ b/gfx/drivers/psp1_gfx.h @@ -32,7 +32,7 @@ typedef struct int ge_callback_id; GuSwapBuffersCallback swapBuffersCallback; - int swapBuffersBehaviour; + int swapBuffersBehaviour; } GuSettings; typedef struct diff --git a/gfx/drivers/sdl2_gfx.c b/gfx/drivers/sdl2_gfx.c index 8431ebb531..a77061f6e5 100644 --- a/gfx/drivers/sdl2_gfx.c +++ b/gfx/drivers/sdl2_gfx.c @@ -178,7 +178,7 @@ static void sdl2_render_msg(sdl2_video_t *vid, const char *msg) { SDL_Rect src_rect, dst_rect; int off_x, off_y, tex_x, tex_y; - const struct font_glyph *gly = + const struct font_glyph *gly = vid->font_driver->get_glyph(vid->font_data, (uint8_t)*msg); if (!gly) @@ -292,7 +292,7 @@ static void sdl_refresh_viewport(sdl2_video_t *vid) vid->video.force_aspect); else if (settings->uints.video_aspect_ratio_idx == ASPECT_RATIO_CUSTOM) { - const struct video_viewport *custom = + const struct video_viewport *custom = (const struct video_viewport*)video_viewport_get_custom(); vid->vp.x = custom->x; @@ -694,7 +694,7 @@ static void sdl2_poke_texture_enable(void *data, bool enable, bool full_screen) vid->menu.active = enable; } -static void sdl2_poke_set_osd_msg(void *data, +static void sdl2_poke_set_osd_msg(void *data, video_frame_info_t *video_info, const char *msg, const void *params, void *font) @@ -760,7 +760,7 @@ static bool sdl2_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } video_driver_t video_sdl2 = { diff --git a/gfx/drivers/sdl_gfx.c b/gfx/drivers/sdl_gfx.c index 7f2060296c..0e2d2d473a 100644 --- a/gfx/drivers/sdl_gfx.c +++ b/gfx/drivers/sdl_gfx.c @@ -152,7 +152,7 @@ static void sdl_render_msg(sdl_video_t *vid, SDL_Surface *buffer, base_x = msg_base_x + glyph->draw_offset_x; base_y = msg_base_y + glyph->draw_offset_y; - src = atlas->buffer + glyph->atlas_offset_x + src = atlas->buffer + glyph->atlas_offset_x + glyph->atlas_offset_y * atlas->width; if (base_x < 0) @@ -470,7 +470,7 @@ static void sdl_apply_state_changes(void *data) static void sdl_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { - enum scaler_pix_fmt format = rgb32 + enum scaler_pix_fmt format = rgb32 ? SCALER_FMT_ARGB8888 : SCALER_FMT_RGBA4444; sdl_video_t *vid = (sdl_video_t*)data; @@ -560,7 +560,7 @@ static bool sdl_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void sdl_gfx_set_rotation(void *data, unsigned rotation) diff --git a/gfx/drivers/sunxi_gfx.c b/gfx/drivers/sunxi_gfx.c index 90a9eadbc5..2c4eecbe5f 100644 --- a/gfx/drivers/sunxi_gfx.c +++ b/gfx/drivers/sunxi_gfx.c @@ -492,7 +492,7 @@ void pixman_composite_src_8888_8888_asm_neon(int width, uint16_t *src, int src_stride_pixels); -/* Pointer to the blitting function. Will be asigned +/* Pointer to the blitting function. Will be asigned * when we find out what bpp the core uses. */ void (*pixman_blit) (int width, int height, @@ -503,7 +503,7 @@ void (*pixman_blit) (int width, struct sunxi_page { - uint32_t *address; + uint32_t *address; unsigned int offset; }; @@ -523,13 +523,13 @@ struct sunxi_video unsigned int src_pitch; unsigned int src_bpp; unsigned int src_bytes_per_pixel; - unsigned int src_pixels_per_line; + unsigned int src_pixels_per_line; unsigned int dst_pitch; unsigned int dst_pixels_per_line; - unsigned int bytes_per_pixel; + unsigned int bytes_per_pixel; - struct sunxi_page *pages; - struct sunxi_page *nextPage; + struct sunxi_page *pages; + struct sunxi_page *nextPage; bool pageflip_pending; /* Keep the vsync while loop going. Set to false to exit. */ @@ -541,7 +541,7 @@ struct sunxi_video /* For threading */ sthread_t *vsync_thread; - scond_t *vsync_condition; + scond_t *vsync_condition; slock_t *pending_mutex; /* menu data */ @@ -611,7 +611,7 @@ static void sunxi_vsync_thread_func(void *data) _dispvars->pageflip_pending = false; scond_signal(_dispvars->vsync_condition); slock_unlock(_dispvars->pending_mutex); - } + } } static void *sunxi_gfx_init(const video_info_t *video, @@ -642,9 +642,9 @@ static void *sunxi_gfx_init(const video_info_t *video, _dispvars->keep_vsync = true; _dispvars->menu_active = false; _dispvars->bytes_per_pixel = video->rgb32 ? 4 : 2; - /* It's very important that we set aspect here because the + /* It's very important that we set aspect here because the * call seq when a core is loaded is gfx_init()->set_aspect()->gfx_frame() - * and we don't want the main surface to be setup in set_aspect() + * and we don't want the main surface to be setup in set_aspect() * before we get to gfx_frame(). */ _dispvars->aspect_ratio = video_driver_get_aspect_ratio(); @@ -688,15 +688,15 @@ static void sunxi_gfx_free(void *data) _dispvars->keep_vsync = false; sthread_join(_dispvars->vsync_thread); } - - slock_free(_dispvars->pending_mutex); + + slock_free(_dispvars->pending_mutex); scond_free(_dispvars->vsync_condition); - free(_dispvars->pages); + free(_dispvars->pages); /* Restore text console contents and reactivate cursor blinking. */ sunxi_restore_console(_dispvars); - + sunxi_disp_close(_dispvars->sunxi_disp); free(_dispvars); } @@ -714,14 +714,14 @@ static void sunxi_update_main(const void *frame, struct sunxi_video *_dispvars) pixman_blit( _dispvars->src_width, _dispvars->src_height, - _dispvars->nextPage->address, + _dispvars->nextPage->address, _dispvars->dst_pixels_per_line, (uint16_t*)frame, _dispvars->src_pixels_per_line ); /* Issue pageflip. Will flip on next vsync. */ - sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp, _dispvars->sunxi_disp->bits_per_pixel, + sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp, _dispvars->sunxi_disp->bits_per_pixel, _dispvars->nextPage->offset, _dispvars->src_width, _dispvars->src_height, _dispvars->sunxi_disp->xres); @@ -740,16 +740,16 @@ static void sunxi_setup_scale (void *data, _dispvars->src_width = width; _dispvars->src_height = height; - /* Total pitch, including things the + /* Total pitch, including things the * cores render between "visible" scanlines. */ - _dispvars->src_pitch = pitch; + _dispvars->src_pitch = pitch; /* Pixels per line */ _dispvars->src_pixels_per_line = _dispvars->src_pitch/_dispvars->bytes_per_pixel; - /* Incremental offset that sums up on + /* Incremental offset that sums up on * each previous page offset. - * Total offset of each page has to + * Total offset of each page has to * be adjusted when internal resolution changes. */ for (i = 0; i < NUMPAGES; i++) { @@ -758,7 +758,7 @@ static void sunxi_setup_scale (void *data, } visible_width = _dispvars->sunxi_disp->yres * _dispvars->aspect_ratio; - xpos = (_dispvars->sunxi_disp->xres - visible_width) / 2; + xpos = (_dispvars->sunxi_disp->xres - visible_width) / 2; /* setup layer window */ sunxi_layer_set_output_window(_dispvars->sunxi_disp, xpos, 0, visible_width, _dispvars->sunxi_disp->yres); @@ -854,7 +854,7 @@ static bool sunxi_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void sunxi_set_texture_enable(void *data, bool state, bool full_screen) @@ -863,7 +863,7 @@ static void sunxi_set_texture_enable(void *data, bool state, bool full_screen) /* If it wasn't active and starts being active... */ if (!_dispvars->menu_active && state) - { + { /* Stop the vsync thread. */ _dispvars->keep_vsync = false; sthread_join(_dispvars->vsync_thread); @@ -889,10 +889,10 @@ static void sunxi_set_texture_frame(void *data, const void *frame, bool rgb32, /* We have to go on a pixel format conversion adventure for now, until we can * convince RGUI to output in an 8888 format. */ - unsigned int src_pitch = width * 2; + unsigned int src_pitch = width * 2; unsigned int dst_pitch = _dispvars->sunxi_disp->xres * 4; unsigned int dst_width = _dispvars->sunxi_disp->xres; - uint32_t line[dst_width]; + uint32_t line[dst_width]; /* Remember, memcpy() works with 8bits pointers for increments. */ char *dst_base_addr = (char*)(_dispvars->pages[0].address); @@ -901,24 +901,24 @@ static void sunxi_set_texture_frame(void *data, const void *frame, bool rgb32, { for (j = 0; j < src_pitch / 2; j++) { - uint16_t src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); + uint16_t src_pix = *((uint16_t*)frame + (src_pitch / 2 * i) + j); /* The hex AND is for keeping only the part we need for each component. */ uint32_t R = (src_pix << 8) & 0x00FF0000; uint32_t G = (src_pix << 4) & 0x0000FF00; uint32_t B = (src_pix << 0) & 0x000000FF; - line[j] = (0 | R | G | B); + line[j] = (0 | R | G | B); } memcpy(dst_base_addr + (dst_pitch * i), (char*)line, dst_pitch); } /* Issue pageflip. Will flip on next vsync. */ sunxi_layer_set_rgb_input_buffer(_dispvars->sunxi_disp, - _dispvars->sunxi_disp->bits_per_pixel, + _dispvars->sunxi_disp->bits_per_pixel, _dispvars->pages[0].offset, width, height, _dispvars->sunxi_disp->xres); } } -static void sunxi_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) +static void sunxi_set_aspect_ratio (void *data, unsigned aspect_ratio_idx) { struct sunxi_video *_dispvars = (struct sunxi_video*)data; float new_aspect = aspectratio_lut[aspect_ratio_idx].value; diff --git a/gfx/drivers/vga_gfx.c b/gfx/drivers/vga_gfx.c index 9bbf431186..301dec6e19 100644 --- a/gfx/drivers/vga_gfx.c +++ b/gfx/drivers/vga_gfx.c @@ -139,7 +139,7 @@ static void *vga_gfx_init(const video_info_t *video, vga_gfx_create(); if (video->font_enable) - font_driver_init_osd(NULL, false, + font_driver_init_osd(NULL, false, video->is_threaded, FONT_DRIVER_RENDER_VGA); return vga; diff --git a/gfx/drivers/vita2d_gfx.c b/gfx/drivers/vita2d_gfx.c index 8cc1ba72be..8e4c13ee35 100644 --- a/gfx/drivers/vita2d_gfx.c +++ b/gfx/drivers/vita2d_gfx.c @@ -42,7 +42,7 @@ extern void *memcpy_neon(void *dst, const void *src, size_t n); static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate); - + static void *vita2d_gfx_init(const video_info_t *video, const input_driver_t **input, void **input_data) { @@ -86,7 +86,7 @@ static void *vita2d_gfx_init(const video_info_t *video, vita->vsync = video->vsync; vita->rgb32 = video->rgb32; - vita->tex_filter = video->smooth + vita->tex_filter = video->smooth ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT; video_driver_set_size(&temp_width, &temp_height); @@ -106,7 +106,7 @@ static void *vita2d_gfx_init(const video_info_t *video, #ifdef HAVE_OVERLAY vita->overlay_enable = false; #endif - font_driver_init_osd(vita, false, + font_driver_init_osd(vita, false, video->is_threaded, FONT_DRIVER_RENDER_VITA2D); @@ -479,21 +479,21 @@ static void vita2d_gfx_set_viewport(void *data, unsigned viewport_width, if (fabsf(device_aspect - desired_aspect) < 0.0001f) { - /* If the aspect ratios of screen and desired aspect - * ratio are sufficiently equal (floating point stuff), + /* 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.0f) + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(viewport_width * (0.5f - delta)); viewport_width = (unsigned)roundf(2.0f * viewport_width * delta); } else { - delta = (device_aspect / desired_aspect - 1.0f) + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(viewport_height * (0.5f - delta)); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); @@ -569,7 +569,7 @@ static void vita_set_filtering(void *data, unsigned index, bool smooth) if (vita) { - vita->tex_filter = smooth ? + vita->tex_filter = smooth ? SCE_GXM_TEXTURE_FILTER_LINEAR : SCE_GXM_TEXTURE_FILTER_POINT; vita2d_texture_set_filters(vita->texture,vita->tex_filter, vita->tex_filter); @@ -696,13 +696,13 @@ static uintptr_t vita_load_texture(void *video_data, void *data, uint32_t *tex32 = NULL; const uint32_t *frame32 = NULL; struct texture_image *image = (struct texture_image*)data; - struct vita2d_texture *texture = vita2d_create_empty_texture_format(image->width, + struct vita2d_texture *texture = vita2d_create_empty_texture_format(image->width, image->height,SCE_GXM_TEXTURE_FORMAT_U8U8U8U8_ARGB); if (!texture) return 0; - if ((filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) || + if ((filter_type == TEXTURE_FILTER_MIPMAP_LINEAR) || (filter_type == TEXTURE_FILTER_LINEAR)) vita2d_texture_set_filters(texture, SCE_GXM_TEXTURE_FILTER_LINEAR, @@ -771,7 +771,7 @@ static bool vita_get_current_sw_framebuffer(void *data, framebuffer->data = vita2d_texture_get_datap(vita->texture); framebuffer->pitch = vita2d_texture_get_stride(vita->texture); - framebuffer->format = vita->rgb32 + framebuffer->format = vita->rgb32 ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; framebuffer->memory_flags = 0; @@ -849,7 +849,7 @@ static bool vita2d_overlay_load(void *data, const void *image_data, unsigned num for (j = 0; j < o->height; j++) for (k = 0; k < o->width; k++) tex32[k + j*stride] = frame32[k + j*pitch]; - + vita2d_overlay_tex_geom(vita, i, 0, 0, 1, 1); /* Default. Stretch to whole screen. */ vita2d_overlay_vertex_geom(vita, i, 0, 0, 1, 1); vita->overlay[i].alpha_mod = 1.0f; @@ -881,7 +881,7 @@ static void vita2d_overlay_vertex_geom(void *data, unsigned image, { vita_video_t *vita = (vita_video_t*)data; struct vita_overlay_data *o = NULL; - + /* Flipped, so we preserve top-down semantics. */ /*y = 1.0f - y; h = -h;*/ @@ -891,7 +891,7 @@ static void vita2d_overlay_vertex_geom(void *data, unsigned image, if (o) { - + o->w = w*PSP_FB_WIDTH/o->width; o->h = h*PSP_FB_HEIGHT/o->height; o->x = PSP_FB_WIDTH*(1-w)/2+x; @@ -924,14 +924,14 @@ static void vita2d_render_overlay(void *data) for (i = 0; i < vita->overlays; i++) { - vita2d_draw_texture_tint_part_scale(vita->overlay[i].tex, - vita->overlay[i].x, - vita->overlay[i].y, - vita->overlay[i].tex_x, - vita->overlay[i].tex_y, - vita->overlay[i].tex_w, - vita->overlay[i].tex_h, - vita->overlay[i].w, + vita2d_draw_texture_tint_part_scale(vita->overlay[i].tex, + vita->overlay[i].x, + vita->overlay[i].y, + vita->overlay[i].tex_x, + vita->overlay[i].tex_y, + vita->overlay[i].tex_w, + vita->overlay[i].tex_h, + vita->overlay[i].w, vita->overlay[i].h, RGBA8(0xFF,0xFF,0xFF,(uint8_t)(vita->overlay[i].alpha_mod * 255.0f))); } diff --git a/gfx/drivers/vulkan.c b/gfx/drivers/vulkan.c index dafcb40fb7..f18f2ba290 100644 --- a/gfx/drivers/vulkan.c +++ b/gfx/drivers/vulkan.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -78,7 +78,7 @@ static void vulkan_init_render_pass( VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO }; VkAttachmentDescription attachment = {0}; VkSubpassDescription subpass = {0}; - VkAttachmentReference color_ref = { 0, + VkAttachmentReference color_ref = { 0, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL }; /* Backbuffer format. */ @@ -93,7 +93,7 @@ static void vulkan_init_render_pass( attachment.stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE; attachment.stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE; - /* The image layout will be attachment_optimal + /* The image layout will be attachment_optimal * when we're executing the renderpass. */ attachment.initialLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; attachment.finalLayout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL; @@ -170,9 +170,9 @@ static void vulkan_init_framebuffers( static void vulkan_init_pipeline_layout( vk_t *vk) { - VkDescriptorSetLayoutCreateInfo set_layout_info = { + VkDescriptorSetLayoutCreateInfo set_layout_info = { VK_STRUCTURE_TYPE_DESCRIPTOR_SET_LAYOUT_CREATE_INFO }; - VkPipelineLayoutCreateInfo layout_info = { + VkPipelineLayoutCreateInfo layout_info = { VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO }; VkDescriptorSetLayoutBinding bindings[2] = {{0}}; @@ -245,22 +245,22 @@ static void vulkan_init_pipelines( ; unsigned i; - VkPipelineInputAssemblyStateCreateInfo input_assembly = { + VkPipelineInputAssemblyStateCreateInfo input_assembly = { VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO }; - VkPipelineVertexInputStateCreateInfo vertex_input = { + VkPipelineVertexInputStateCreateInfo vertex_input = { VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO }; - VkPipelineRasterizationStateCreateInfo raster = { + VkPipelineRasterizationStateCreateInfo raster = { VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO }; VkPipelineColorBlendAttachmentState blend_attachment = {0}; - VkPipelineColorBlendStateCreateInfo blend = { + VkPipelineColorBlendStateCreateInfo blend = { VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO }; - VkPipelineViewportStateCreateInfo viewport = { + VkPipelineViewportStateCreateInfo viewport = { VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO }; - VkPipelineDepthStencilStateCreateInfo depth_stencil = { + VkPipelineDepthStencilStateCreateInfo depth_stencil = { VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO }; - VkPipelineMultisampleStateCreateInfo multisample = { + VkPipelineMultisampleStateCreateInfo multisample = { VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO }; - VkPipelineDynamicStateCreateInfo dynamic = { + VkPipelineDynamicStateCreateInfo dynamic = { VK_STRUCTURE_TYPE_PIPELINE_DYNAMIC_STATE_CREATE_INFO }; VkPipelineShaderStageCreateInfo shader_stages[2] = { @@ -268,9 +268,9 @@ static void vulkan_init_pipelines( { VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO }, }; - VkGraphicsPipelineCreateInfo pipe = { + VkGraphicsPipelineCreateInfo pipe = { VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO }; - VkShaderModuleCreateInfo module_info = { + VkShaderModuleCreateInfo module_info = { VK_STRUCTURE_TYPE_SHADER_MODULE_CREATE_INFO }; VkVertexInputAttributeDescription attributes[3] = {{0}}; VkVertexInputBindingDescription binding = {0}; @@ -517,13 +517,13 @@ static void vulkan_init_command_buffers(vk_t *vk) for (i = 0; i < vk->num_swapchain_images; i++) { - VkCommandPoolCreateInfo pool_info = { + VkCommandPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; - VkCommandBufferAllocateInfo info = { + VkCommandBufferAllocateInfo info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO }; pool_info.queueFamilyIndex = vk->context->graphics_queue_index; - pool_info.flags = + pool_info.flags = VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT; vkCreateCommandPool(vk->context->device, @@ -622,7 +622,7 @@ static void vulkan_init_descriptor_pool(vk_t *vk) for (i = 0; i < vk->num_swapchain_images; i++) { - vk->swapchain[i].descriptor_manager = + vk->swapchain[i].descriptor_manager = vulkan_create_descriptor_manager( vk->context->device, pool_sizes, 2, vk->pipelines.set_layout); @@ -761,7 +761,7 @@ static bool vulkan_init_default_filter_chain(vk_t *vk) vk->filter_chain = vulkan_filter_chain_create_default( &info, - vk->video.smooth ? + vk->video.smooth ? VULKAN_FILTER_CHAIN_LINEAR : VULKAN_FILTER_CHAIN_NEAREST); if (!vk->filter_chain) @@ -848,10 +848,10 @@ static void vulkan_init_static_resources(vk_t *vk) { unsigned i; uint32_t blank[4 * 4]; - VkCommandPoolCreateInfo pool_info = { + VkCommandPoolCreateInfo pool_info = { VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO }; /* Create the pipeline cache. */ - VkPipelineCacheCreateInfo cache = { + VkPipelineCacheCreateInfo cache = { VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO }; vkCreatePipelineCache(vk->context->device, @@ -1072,8 +1072,8 @@ static void vulkan_init_hw_render(vk_t *vk) static void vulkan_init_readback(vk_t *vk) { /* Only bother with this if we're doing GPU recording. - * Check recording_is_enabled() and not - * driver.recording_data, because recording is + * Check recording_is_enabled() and not + * driver.recording_data, because recording is * not initialized yet. */ settings_t *settings = config_get_ptr(); @@ -1171,7 +1171,7 @@ static void *vulkan_init(const video_info_t *video, vk->fullscreen = video->fullscreen; vk->tex_w = RARCH_SCALE_BASE * video->input_scale; vk->tex_h = RARCH_SCALE_BASE * video->input_scale; - vk->tex_fmt = video->rgb32 + vk->tex_fmt = video->rgb32 ? VK_FORMAT_B8G8R8A8_UNORM : VK_FORMAT_R5G6B5_UNORM_PACK16; vk->keep_aspect = video->force_aspect; RARCH_LOG("[Vulkan]: Using %s format.\n", video->rgb32 ? "BGRA8888" : "RGB565"); @@ -1195,7 +1195,7 @@ static void *vulkan_init(const video_info_t *video, video_context_driver_input_driver(&inp); if (video->font_enable) - font_driver_init_osd(vk, false, + font_driver_init_osd(vk, false, video->is_threaded, FONT_DRIVER_RENDER_VULKAN_API); @@ -1422,21 +1422,21 @@ static void vulkan_set_viewport(void *data, unsigned viewport_width, if (fabsf(device_aspect - desired_aspect) < 0.0001f) { - /* If the aspect ratios of screen and desired aspect - * ratio are sufficiently equal (floating point stuff), + /* 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.0f) + delta = (desired_aspect / device_aspect - 1.0f) / 2.0f + 0.5f; x = (int)roundf(viewport_width * (0.5f - delta)); viewport_width = (unsigned)roundf(2.0f * viewport_width * delta); } else { - delta = (device_aspect / desired_aspect - 1.0f) + delta = (device_aspect / desired_aspect - 1.0f) / 2.0f + 0.5f; y = (int)roundf(viewport_height * (0.5f - delta)); viewport_height = (unsigned)roundf(2.0f * viewport_height * delta); @@ -1604,13 +1604,13 @@ static bool vulkan_frame(void *data, const void *frame, unsigned height = video_info->height; VkClearValue clear_color; - VkCommandBufferBeginInfo begin_info = { + VkCommandBufferBeginInfo begin_info = { VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO }; - VkRenderPassBeginInfo rp_info = { + VkRenderPassBeginInfo rp_info = { VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO }; - VkSubmitInfo submit_info = { + VkSubmitInfo submit_info = { VK_STRUCTURE_TYPE_SUBMIT_INFO }; - unsigned frame_index = + unsigned frame_index = vk->context->current_swapchain_index; /* Bookkeeping on start of frame. */ @@ -1658,12 +1658,12 @@ static bool vulkan_frame(void *data, const void *frame, const uint8_t *src = (const uint8_t*)frame; unsigned bpp = vk->video.rgb32 ? 4 : 2; - if ( chain->texture.width != frame_width + if ( chain->texture.width != frame_width || chain->texture.height != frame_height) { chain->texture = vulkan_create_texture(vk, &chain->texture, frame_width, frame_height, chain->texture.format, NULL, NULL, - chain->texture_optimal.memory + chain->texture_optimal.memory ? VULKAN_TEXTURE_STAGING : VULKAN_TEXTURE_STREAMED); vulkan_map_persistent_texture( @@ -1685,7 +1685,7 @@ static bool vulkan_frame(void *data, const void *frame, if (chain->texture.stride == pitch && pitch == frame_width * bpp) memcpy(dst, src, frame_width * frame_height * bpp); else - for (y = 0; y < frame_height; y++, + for (y = 0; y < frame_height; y++, dst += chain->texture.stride, src += pitch) memcpy(dst, src, frame_width * bpp); } @@ -1849,8 +1849,8 @@ static bool vulkan_frame(void *data, const void *frame, if (chain->backbuffer.image != VK_NULL_HANDLE && (vk->readback.pending || vk->readback.streamed)) { - /* We cannot safely read back from an image which - * has already been presented as we need to + /* We cannot safely read back from an image which + * has already been presented as we need to * maintain the PRESENT_SRC_KHR layout. * * If we're reading back, perform the readback before presenting. @@ -2068,7 +2068,7 @@ static bool vulkan_get_current_sw_framebuffer(void *data, { struct vk_per_frame *chain = NULL; vk_t *vk = (vk_t*)data; - vk->chain = + vk->chain = &vk->swapchain[vk->context->current_swapchain_index]; chain = vk->chain; @@ -2095,7 +2095,7 @@ static bool vulkan_get_current_sw_framebuffer(void *data, framebuffer->data = chain->texture.mapped; framebuffer->pitch = chain->texture.stride; - framebuffer->format = vk->video.rgb32 + framebuffer->format = vk->video.rgb32 ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; framebuffer->memory_flags = 0; @@ -2369,7 +2369,7 @@ static bool vulkan_read_viewport(void *data, uint8_t *buffer, bool is_idle) { unsigned x, y; const uint8_t *src = (const uint8_t*)staging->mapped; - buffer += 3 * (vk->vp.height - 1) + buffer += 3 * (vk->vp.height - 1) * vk->vp.width; for (y = 0; y < vk->vp.height; y++, @@ -2532,7 +2532,7 @@ static bool vulkan_overlay_load(void *data, const void *image_data, unsigned num_images) { unsigned i, j; - const struct texture_image *images = + const struct texture_image *images = (const struct texture_image*)image_data; vk_t *vk = (vk_t*)data; static const struct vk_color white = { diff --git a/gfx/drivers/xenon360_gfx.c b/gfx/drivers/xenon360_gfx.c index 3832e7c538..9101d047cc 100644 --- a/gfx/drivers/xenon360_gfx.c +++ b/gfx/drivers/xenon360_gfx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -284,7 +284,7 @@ static bool xenon360_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } static void xenon360_gfx_viewport_info(void *data, struct video_viewport *vp) diff --git a/gfx/drivers/xshm_gfx.c b/gfx/drivers/xshm_gfx.c index 75882f5f21..900a8a61a4 100644 --- a/gfx/drivers/xshm_gfx.c +++ b/gfx/drivers/xshm_gfx.c @@ -40,10 +40,10 @@ typedef struct xshm { Display* display; Window wndw; - + int width; int height; - + XShmSegmentInfo shmInfo; XImage* image; GC gc; @@ -54,11 +54,11 @@ static void *xshm_gfx_init(const video_info_t *video, { xshm_t* xshm = (xshm_t*)malloc(sizeof(xshm_t)); Window parent; - + XInitThreads(); - + xshm->display = XOpenDisplay(NULL); - + #ifdef RARCH_INTERNAL parent = DefaultRootWindow(xshm->display); #else @@ -71,26 +71,26 @@ static void *xshm_gfx_init(const video_info_t *video, 0, 24, CopyFromParent, NULL, CWBorderPixel, &attributes); XSetWindowBackground(xshm->display, xshm->wndw, 0); XMapWindow(xshm->display, xshm->wndw); - + xshm->shmInfo.shmid = shmget(IPC_PRIVATE, sizeof(uint32_t) * video->width * video->height, IPC_CREAT|0600); if (xshm->shmInfo.shmid<0) abort();//seems like an out of memory situation... let's just blow up - + xshm->shmInfo.shmaddr = (char*)shmat(xshm->shmInfo.shmid, 0, 0); xshm->shmInfo.readOnly = False; XShmAttach(xshm->display, &xshm->shmInfo); XSync(xshm->display, False);//no idea why this is required, but I get weird errors without it xshm->image = XShmCreateImage(xshm->display, NULL, 24, ZPixmap, xshm->shmInfo.shmaddr, &xshm->shmInfo, video->width, video->height); - + xshm->gc = XCreateGC(xshm->display, xshm->wndw, 0, NULL); - + xshm->width = video->width; xshm->height = video->height; - + if (input) *input = NULL; if (input_data) *input_data = NULL; - + return xshm; } @@ -100,7 +100,7 @@ static bool xshm_gfx_frame(void *data, const void *frame, unsigned width, { xshm_t* xshm = (xshm_t*)data; int y; - + for (y=0;yshmInfo.shmaddr + sizeof(uint32_t)*xshm->width*y, @@ -110,17 +110,17 @@ static bool xshm_gfx_frame(void *data, const void *frame, unsigned width, #ifdef HAVE_MENU menu_driver_frame(video_info); #endif - + XShmPutImage(xshm->display, xshm->wndw, xshm->gc, xshm->image, 0, 0, 0, 0, xshm->width, xshm->height, False); XFlush(xshm->display); - + return true; } static void xshm_gfx_set_nonblock_state(void *data, bool toggle) { - + } static bool xshm_gfx_alive(void *data) @@ -140,17 +140,17 @@ static bool xshm_gfx_suppress_screensaver(void *data, bool enable) static void xshm_gfx_free(void *data) { - + } static void xshm_gfx_set_rotation(void *data, unsigned rotation) { - + } static void xshm_gfx_viewport_info(void *data, struct video_viewport *vp) { - + } static bool xshm_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle) @@ -160,29 +160,29 @@ static bool xshm_gfx_read_viewport(void *data, uint8_t *buffer, bool is_idle) static void xshm_poke_set_filtering(void *data, unsigned index, bool smooth) { - + } static void xshm_poke_set_aspect_ratio(void *data, unsigned aspect_ratio_idx) { - + } static void xshm_poke_apply_state_changes(void *data) { - + } #ifdef HAVE_MENU static void xshm_poke_set_texture_frame(void *data, const void *frame, bool rgb32, unsigned width, unsigned height, float alpha) { - + } static void xshm_poke_texture_enable(void *data, bool enable, bool full_screen) { - + } static void xshm_poke_set_osd_msg(void *data, @@ -190,17 +190,17 @@ static void xshm_poke_set_osd_msg(void *data, const char *msg, const struct font_params *params, void *font) { - + } static void xshm_show_mouse(void *data, bool state) { - + } static void xshm_grab_mouse_toggle(void *data) { - + } #endif @@ -247,7 +247,7 @@ static bool xshm_gfx_set_shader(void *data, (void)type; (void)path; - return false; + return false; } video_driver_t video_xshm = { diff --git a/gfx/drivers/xvideo.c b/gfx/drivers/xvideo.c index dc3738c551..8df8f528bb 100644 --- a/gfx/drivers/xvideo.c +++ b/gfx/drivers/xvideo.c @@ -98,11 +98,11 @@ static void xv_set_nonblock_state(void *data, bool state) static INLINE void xv_calculate_yuv(uint8_t *y, uint8_t *u, uint8_t *v, unsigned r, unsigned g, unsigned b) { - int y_ = (int)(+((double)r * 0.257) + ((double)g * 0.504) + int y_ = (int)(+((double)r * 0.257) + ((double)g * 0.504) + ((double)b * 0.098) + 16.0); - int u_ = (int)(-((double)r * 0.148) - ((double)g * 0.291) + int u_ = (int)(-((double)r * 0.148) - ((double)g * 0.291) + ((double)b * 0.439) + 128.0); - int v_ = (int)(+((double)r * 0.439) - ((double)g * 0.368) + int v_ = (int)(+((double)r * 0.439) - ((double)g * 0.368) - ((double)b * 0.071) + 128.0); *y = y_ < 0 ? 0 : (y_ > 255 ? 255 : y_); @@ -139,8 +139,8 @@ static void xv_init_font(xv_t *xv, const char *font_path, unsigned font_size) if (!settings->bools.video_font_enable) return; - if (font_renderer_create_default((const void**)&xv->font_driver, - &xv->font, *settings->paths.path_font + if (font_renderer_create_default((const void**)&xv->font_driver, + &xv->font, *settings->paths.path_font ? settings->paths.path_font : NULL, settings->floats.video_font_size)) { @@ -234,7 +234,7 @@ static void render32_yuy2(xv_t *xv, const void *input_, uint8_t y0, u, v; unsigned img_width; uint32_t p = *input++; - p = ((p >> 8) & 0xf800) | ((p >> 5) & 0x07e0) + p = ((p >> 8) & 0xf800) | ((p >> 5) & 0x07e0) | ((p >> 3) & 0x1f); /* ARGB -> RGB16 */ y0 = xv->ytable[p]; @@ -268,7 +268,7 @@ static void render32_uyvy(xv_t *xv, const void *input_, uint8_t y0, u, v; unsigned img_width; uint32_t p = *input++; - p = ((p >> 8) & 0xf800) + p = ((p >> 8) & 0xf800) | ((p >> 5) & 0x07e0) | ((p >> 3) & 0x1f); /* ARGB -> RGB16 */ y0 = xv->ytable[p]; @@ -335,8 +335,8 @@ static bool xv_adaptor_set_format(xv_t *xv, Display *dpy, { for (j = 0; j < ARRAY_SIZE(formats); j++) { - if (format[i].type == XvYUV - && format[i].bits_per_pixel == 16 + if (format[i].type == XvYUV + && format[i].bits_per_pixel == 16 && format[i].format == XvPacked) { if (format[i].component_order[0] == formats[j].components[0] && @@ -345,7 +345,7 @@ static bool xv_adaptor_set_format(xv_t *xv, Display *dpy, format[i].component_order[3] == formats[j].components[3]) { xv->fourcc = format[i].id; - xv->render_func = video->rgb32 + xv->render_func = video->rgb32 ? formats[j].render_32 : formats[j].render_16; xv->luma_index[0] = formats[j].luma_index[0]; @@ -387,7 +387,7 @@ static void xv_calc_out_rect(bool keep_aspect, float desired_aspect = video_driver_get_aspect_ratio(); float device_aspect = (float)vp_width / vp_height; - /* If the aspect ratios of screen and desired aspect ratio + /* If the aspect ratios of screen and desired aspect ratio * are sufficiently equal (floating point stuff), * assume they are actually equal. */ @@ -453,7 +453,7 @@ static void *xv_init(const video_info_t *video, RARCH_ERR("[XVideo]: Check DISPLAY variable and if X is running.\n"); goto error; } - + av_info = video_viewport_get_system_av_info(); if (av_info) @@ -492,7 +492,7 @@ static void *xv_init(const video_info_t *video, for (i = 0; i < adaptor_count; i++) { - /* Find adaptor that supports both input (memory->drawable) + /* Find adaptor that supports both input (memory->drawable) * and image (drawable->screen) masks. */ if (adaptor_info[i].num_formats < 1) @@ -524,7 +524,7 @@ static void *xv_init(const video_info_t *video, visualtemplate.screen = DefaultScreen(g_x11_dpy); visualtemplate.depth = xv->depth; visualtemplate.visual = 0; - visualinfo = XGetVisualInfo(g_x11_dpy, VisualIDMask | + visualinfo = XGetVisualInfo(g_x11_dpy, VisualIDMask | VisualScreenMask | VisualDepthMask, &visualtemplate, &visualmatches); if (!visualinfo) @@ -541,7 +541,7 @@ static void *xv_init(const video_info_t *video, attributes.colormap = g_x11_cmap; attributes.border_pixel = 0; - attributes.event_mask = StructureNotifyMask | KeyPressMask | + attributes.event_mask = StructureNotifyMask | KeyPressMask | KeyReleaseMask | ButtonReleaseMask | ButtonPressMask | DestroyNotify | ClientMessage; if (video->fullscreen) @@ -677,7 +677,7 @@ static bool xv_check_resize(xv_t *xv, unsigned width, unsigned height) xv->width = xv->image->width; xv->height = xv->image->height; - xv->shminfo.shmid = + xv->shminfo.shmid = shmget(IPC_PRIVATE, xv->image->data_size, IPC_CREAT | 0777); if (xv->shminfo.shmid < 0) @@ -686,7 +686,7 @@ static bool xv_check_resize(xv_t *xv, unsigned width, unsigned height) return false; } - xv->shminfo.shmaddr = xv->image->data = + xv->shminfo.shmaddr = xv->image->data = (char*)shmat(xv->shminfo.shmid, NULL, 0); xv->shminfo.readOnly = false; @@ -733,21 +733,21 @@ static void xv_render_msg(xv_t *xv, const char *msg, int base_x, base_y, glyph_width, glyph_height, max_width, max_height; const uint8_t *src = NULL; uint8_t *out = NULL; - const struct font_glyph *glyph = + const struct font_glyph *glyph = xv->font_driver->get_glyph(xv->font, (uint8_t)*msg); if (!glyph) continue; - /* Make sure we always start on the correct boundary + /* Make sure we always start on the correct boundary * so the indices are correct. */ - base_x = (msg_base_x + glyph->draw_offset_x + 1) & ~1; + base_x = (msg_base_x + glyph->draw_offset_x + 1) & ~1; base_y = msg_base_y + glyph->draw_offset_y; glyph_width = glyph->width; glyph_height = glyph->height; - src = atlas->buffer + glyph->atlas_offset_x + + src = atlas->buffer + glyph->atlas_offset_x + glyph->atlas_offset_y * atlas->width; if (base_x < 0) @@ -793,21 +793,21 @@ static void xv_render_msg(xv_t *xv, const char *msg, alpha[1] = src[x + 1]; /* Blended alpha for the sub-sampled U/V channels. */ - alpha_sub = (alpha[0] + alpha[1]) >> 1; + alpha_sub = (alpha[0] + alpha[1]) >> 1; for (i = 0; i < 2; i++) { - unsigned blended = (xv->font_y * alpha[i] + unsigned blended = (xv->font_y * alpha[i] + ((256 - alpha[i]) * out[out_x + luma_index[i]])) >> 8; out[out_x + luma_index[i]] = blended; } /* Blend chroma channels */ - blended = (xv->font_u * alpha_sub + blended = (xv->font_u * alpha_sub + ((256 - alpha_sub) * out[out_x + chroma_u_index])) >> 8; out[out_x + chroma_u_index] = blended; - blended = (xv->font_v * alpha_sub + blended = (xv->font_v * alpha_sub + ((256 - alpha_sub) * out[out_x + chroma_v_index])) >> 8; out[out_x + chroma_v_index] = blended; } @@ -938,7 +938,7 @@ static bool xv_set_shader(void *data, (void)type; (void)path; - return false; + return false; } video_driver_t video_xvideo = { diff --git a/gfx/drivers_context/android_ctx.c b/gfx/drivers_context/android_ctx.c index 341aa465c6..acd73fe27c 100644 --- a/gfx/drivers_context/android_ctx.c +++ b/gfx/drivers_context/android_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -230,7 +230,7 @@ static void android_gfx_ctx_check_window(void *data, bool *quit, break; case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN - /* Swapchains are recreated in set_resize as a + /* Swapchains are recreated in set_resize as a * central place, so use that to trigger swapchain reinit. */ *resize = and->vk.need_new_swapchain; new_width = and->width; @@ -370,7 +370,7 @@ static bool android_gfx_ctx_bind_api(void *data, enum gfx_ctx_api api, unsigned major, unsigned minor) { unsigned version; - + switch (api) { case GFX_CTX_OPENGL_API: @@ -582,7 +582,7 @@ static uint32_t android_gfx_ctx_get_flags(void *data) { uint32_t flags = 0; BIT32_SET(flags, GFX_CTX_FLAGS_NONE); - + return flags; } diff --git a/gfx/drivers_context/cgl_ctx.c b/gfx/drivers_context/cgl_ctx.c index 4593b46d8e..53e923da92 100644 --- a/gfx/drivers_context/cgl_ctx.c +++ b/gfx/drivers_context/cgl_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -116,7 +116,7 @@ static bool gfx_ctx_cgl_set_video_mode(void *data, static void gfx_ctx_cgl_destroy(void *data) { gfx_ctx_cgl_data_t *cgl = (gfx_ctx_cgl_data_t*)data; - + if (cgl->glCtx) { CGLSetCurrentContext(NULL); @@ -230,9 +230,9 @@ static CGSSurfaceID attach_gl_context_to_window(CGLContextObj glCtx, CGSConnectionID cid = CGSMainConnectionID(); printf("cid:%d wid:%d\n", cid, wid); - + /* determine window size */ - /* FIXME/TODO - CGWindowListCopyWindowInfo was introduced on OSX 10.5, + /* FIXME/TODO - CGWindowListCopyWindowInfo was introduced on OSX 10.5, * find alternative for lower versions. */ wins = CGWindowListCopyWindowInfo(kCGWindowListOptionIncludingWindow, wid); /* expect one result only */ win = (CFDictionaryRef)CFArrayGetValueAtIndex(wins, 0); @@ -242,33 +242,33 @@ static CGSSurfaceID attach_gl_context_to_window(CGLContextObj glCtx, CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(bnd, CFSTR("Height")), kCFNumberFloat64Type, &h); CFRelease(wins); - + /* create a surface. */ if(CGSAddSurface(cid, wid, &sid) != kCGErrorSuccess) { printf("ERR: no surface\n"); } printf("sid:%d\n", sid); - + /* set surface size, and order it frontmost */ if(CGSSetSurfaceBounds(cid, wid, sid, CGRectMake(0, 0, w, h)) != kCGErrorSuccess) printf("ERR: cant set bounds\n"); if(CGSOrderSurface(cid, wid, sid, 1, 0) != kCGErrorSuccess) printf("ERR: cant order front\n"); - + /* attach context to the surface */ if(CGLSetSurface(glCtx, cid, wid, sid) != kCGErrorSuccess) { printf("ERR: cant set surface\n"); } - + /* check drawable */ CGLGetParameter(glCtx, kCGLCPHasDrawable, ¶ms); if(params != 1) { printf("ERR: no drawable\n"); } - + *width = (int)w; *height = (int)h; diff --git a/gfx/drivers_context/d3d_ctx.c b/gfx/drivers_context/d3d_ctx.c index d5e3923be9..4a5e6d667d 100644 --- a/gfx/drivers_context/d3d_ctx.c +++ b/gfx/drivers_context/d3d_ctx.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2014 - OV2 - * + * * 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. @@ -341,7 +341,7 @@ static void gfx_ctx_d3d_swap_interval(void *data, unsigned interval) { d3d_video_t *d3d = (d3d_video_t*)data; #ifdef _XBOX - unsigned d3d_interval = interval ? + unsigned d3d_interval = interval ? D3DPRESENT_INTERVAL_ONE : D3DPRESENT_INTERVAL_IMMEDIATE; d3d_set_render_state(d3d->dev, XBOX_PRESENTATIONINTERVAL, d3d_interval); diff --git a/gfx/drivers_context/drm_ctx.c b/gfx/drivers_context/drm_ctx.c index e5eb203075..5c101eb57f 100644 --- a/gfx/drivers_context/drm_ctx.c +++ b/gfx/drivers_context/drm_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -85,7 +85,7 @@ typedef struct gfx_ctx_drm_data unsigned fb_width; unsigned fb_height; - bool core_hw_context_enable; + bool core_hw_context_enable; } gfx_ctx_drm_data_t; struct drm_fb @@ -161,7 +161,7 @@ static void drm_flip_handler(int fd, unsigned frame, (void)fd; (void)sec; (void)usec; - + #if 0 static unsigned first_page_flip; static unsigned last_page_flip; @@ -189,7 +189,7 @@ static bool gfx_ctx_drm_wait_flip(bool block) if (!waiting_for_flip) return false; - + if (block) timeout = -1; @@ -207,7 +207,7 @@ static bool gfx_ctx_drm_wait_flip(bool block) /* This buffer is not on-screen anymore. Release it to GBM. */ gbm_surface_release_buffer(g_gbm_surface, g_bo); /* This buffer is being shown now. */ - g_bo = g_next_bo; + g_bo = g_next_bo; return false; } @@ -225,7 +225,7 @@ static bool gfx_ctx_drm_queue_flip(void) if (drmModePageFlip(g_drm_fd, g_crtc_id, fb->fb_id, DRM_MODE_PAGE_FLIP_EVENT, &waiting_for_flip) == 0) return true; - + /* Failed to queue page flip. */ return false; } @@ -248,7 +248,7 @@ static void gfx_ctx_drm_swap_buffers(void *data, void *data2) break; } - /* I guess we have to wait for flip to have taken + /* I guess we have to wait for flip to have taken * place before another flip can be queued up. * * If true, we are still waiting for a flip @@ -263,7 +263,7 @@ static void gfx_ctx_drm_swap_buffers(void *data, void *data2) gbm_surface_has_free_buffers(g_gbm_surface)) return; - gfx_ctx_drm_wait_flip(true); + gfx_ctx_drm_wait_flip(true); } static void gfx_ctx_drm_get_video_size(void *data, @@ -389,7 +389,7 @@ nextgpu: drm_setup(fd); - /* First mode is assumed to be the "optimal" + /* First mode is assumed to be the "optimal" * one for get_video_size() purposes. */ drm->fb_width = g_drm_connector->modes[0].hdisplay; drm->fb_height = g_drm_connector->modes[0].vdisplay; @@ -454,7 +454,7 @@ static EGLint *gfx_ctx_drm_egl_fill_attribs( *attr++ = drm->egl.minor; /* Technically, we don't have core/compat until 3.2. - * Version 3.1 is either compat or not depending + * Version 3.1 is either compat or not depending * on GL_ARB_compatibility. */ if (version >= 3002) { @@ -476,7 +476,7 @@ static EGLint *gfx_ctx_drm_egl_fill_attribs( case GFX_CTX_OPENGL_ES_API: #ifdef HAVE_OPENGLES *attr++ = EGL_CONTEXT_CLIENT_VERSION; - *attr++ = drm->egl.major + *attr++ = drm->egl.major ? (EGLint)drm->egl.major : 2; #ifdef EGL_KHR_create_context if (drm->egl.minor > 0) @@ -581,7 +581,7 @@ static bool gfx_ctx_drm_egl_set_video_mode(gfx_ctx_drm_data_t *drm) attr = gfx_ctx_drm_egl_fill_attribs(drm, egl_attribs); egl_attribs_ptr = &egl_attribs[0]; - if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) + if (!egl_create_context(&drm->egl, (attr != egl_attribs_ptr) ? egl_attribs_ptr : NULL)) goto error; @@ -622,14 +622,14 @@ static bool gfx_ctx_drm_set_video_mode(void *data, frontend_driver_install_signal_handler(); - /* If we use black frame insertion, - * we fake a 60 Hz monitor for 120 Hz one, + /* If we use black frame insertion, + * we fake a 60 Hz monitor for 120 Hz one, * etc, so try to match that. */ - refresh_mod = video_info->black_frame_insertion + refresh_mod = video_info->black_frame_insertion ? 0.5f : 1.0f; /* Find desired video mode, and use that. - * If not fullscreen, we get desired windowed size, + * If not fullscreen, we get desired windowed size, * which is not appropriate. */ if ((width == 0 && height == 0) || !fullscreen) g_drm_mode = &g_drm_connector->modes[0]; @@ -637,7 +637,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data, { /* Try to match refresh_rate as closely as possible. * - * Lower resolutions tend to have multiple supported + * Lower resolutions tend to have multiple supported * refresh rates as well. */ float minimum_fps_diff = 0.0f; @@ -646,7 +646,7 @@ static bool gfx_ctx_drm_set_video_mode(void *data, for (i = 0; i < g_drm_connector->count_modes; i++) { float diff; - if (width != g_drm_connector->modes[i].hdisplay || + if (width != g_drm_connector->modes[i].hdisplay || height != g_drm_connector->modes[i].vdisplay) continue; diff --git a/gfx/drivers_context/gdi_ctx.c b/gfx/drivers_context/gdi_ctx.c index 9d1e5980ae..eee7296ad4 100644 --- a/gfx/drivers_context/gdi_ctx.c +++ b/gfx/drivers_context/gdi_ctx.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. @@ -136,7 +136,7 @@ static void *gfx_ctx_gdi_init( if (g_inited) return NULL; - + win32_window_reset(); win32_monitor_init(); diff --git a/gfx/drivers_context/gfx_null_ctx.c b/gfx/drivers_context/gfx_null_ctx.c index e6bf37c819..1dd79a9b6f 100644 --- a/gfx/drivers_context/gfx_null_ctx.c +++ b/gfx/drivers_context/gfx_null_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -64,7 +64,7 @@ static void gfx_ctx_null_destroy(void *data) (void)data; } -static void gfx_ctx_null_input_driver(void *data, +static void gfx_ctx_null_input_driver(void *data, const char *name, const input_driver_t **input, void **input_data) { diff --git a/gfx/drivers_context/khr_display_ctx.c b/gfx/drivers_context/khr_display_ctx.c index 53e3bfb528..b0dd26cc64 100644 --- a/gfx/drivers_context/khr_display_ctx.c +++ b/gfx/drivers_context/khr_display_ctx.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - 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. @@ -242,7 +242,7 @@ const gfx_ctx_driver_t gfx_ctx_khr_display = { "khr_display", gfx_ctx_khr_display_get_flags, gfx_ctx_khr_display_set_flags, - NULL, + NULL, gfx_ctx_khr_display_get_context_data, NULL }; diff --git a/gfx/drivers_context/mali_fbdev_ctx.c b/gfx/drivers_context/mali_fbdev_ctx.c index e9b97dbe78..aa7e7395b4 100644 --- a/gfx/drivers_context/mali_fbdev_ctx.c +++ b/gfx/drivers_context/mali_fbdev_ctx.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - 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. @@ -168,7 +168,7 @@ static bool gfx_ctx_mali_fbdev_set_video_mode(void *data, close(fd); fd = -1; - + width = vinfo.xres; height = vinfo.yres; diff --git a/gfx/drivers_context/opendingux_fbdev_ctx.c b/gfx/drivers_context/opendingux_fbdev_ctx.c index b50317e200..9ad56bc662 100644 --- a/gfx/drivers_context/opendingux_fbdev_ctx.c +++ b/gfx/drivers_context/opendingux_fbdev_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2014 2015 - Jean-Andre Santoni - * + * * 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. @@ -79,7 +79,7 @@ static void *gfx_ctx_opendingux_init(video_frame_info_t *video_info, void *video if (!viv) return NULL; - + #ifdef HAVE_EGL frontend_driver_install_signal_handler(); diff --git a/gfx/drivers_context/ps3_ctx.c b/gfx/drivers_context/ps3_ctx.c index 0c3775ec58..050e241db9 100644 --- a/gfx/drivers_context/ps3_ctx.c +++ b/gfx/drivers_context/ps3_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -102,7 +102,7 @@ static void gfx_ctx_ps3_get_available_resolutions(void) } global->console.screen.resolutions.count = 0; - global->console.screen.resolutions.list = + global->console.screen.resolutions.list = malloc(resolution_count * sizeof(uint32_t)); for (i = 0; i < num_videomodes; i++) @@ -119,15 +119,15 @@ static void gfx_ctx_ps3_get_available_resolutions(void) if (global->console.screen.resolutions.current.id == videomode[i]) { defaultresolution = false; - global->console.screen.resolutions.current.idx = + global->console.screen.resolutions.current.idx = global->console.screen.resolutions.count-1; } } } - /* In case we didn't specify a resolution - + /* In case we didn't specify a resolution - * make the last resolution - that was added to the list (the highest resolution) + that was added to the list (the highest resolution) the default resolution */ if (global->console.screen.resolutions.current.id > num_videomodes || defaultresolution) { @@ -195,7 +195,7 @@ static void gfx_ctx_ps3_get_video_size(void *data, #if defined(HAVE_PSGL) if (ps3) - psglGetDeviceDimensions(ps3->gl_device, width, height); + psglGetDeviceDimensions(ps3->gl_device, width, height); #endif } @@ -224,7 +224,7 @@ static void *gfx_ctx_ps3_init(video_frame_info_t *video_info, void *video_driver sys_spu_initialize(6, 1); psglInit(&options); - params.enable = + params.enable = PSGL_DEVICE_PARAMETERS_COLOR_FORMAT | PSGL_DEVICE_PARAMETERS_DEPTH_FORMAT | PSGL_DEVICE_PARAMETERS_MULTISAMPLING_MODE; @@ -265,7 +265,7 @@ static void *gfx_ctx_ps3_init(video_frame_info_t *video_info, void *video_driver psglResetCurrentContext(); #endif - global->console.screen.pal_enable = + global->console.screen.pal_enable = cellVideoOutGetResolutionAvailability( CELL_VIDEO_OUT_PRIMARY, CELL_VIDEO_OUT_RESOLUTION_576, CELL_VIDEO_OUT_ASPECT_AUTO, 0); diff --git a/gfx/drivers_context/sdl_gl_ctx.c b/gfx/drivers_context/sdl_gl_ctx.c index 6c9f70df40..4827c7da84 100644 --- a/gfx/drivers_context/sdl_gl_ctx.c +++ b/gfx/drivers_context/sdl_gl_ctx.c @@ -114,7 +114,7 @@ static void sdl_ctx_destroy(void *data) if (!sdl) return; - + sdl_ctx_destroy_resources(sdl); free(sdl); } diff --git a/gfx/drivers_context/vc_egl_ctx.c b/gfx/drivers_context/vc_egl_ctx.c index 26e1b695f4..62714cf62c 100644 --- a/gfx/drivers_context/vc_egl_ctx.c +++ b/gfx/drivers_context/vc_egl_ctx.c @@ -110,23 +110,23 @@ static void gfx_ctx_vc_get_video_size(void *data, vc_ctx_data_t *vc = (vc_ctx_data_t*)data; settings_t *settings = config_get_ptr(); - /* Use dispmanx upscaling if + /* Use dispmanx upscaling if * fullscreen_x and fullscreen_y are set. */ if (settings->uints.video_fullscreen_x != 0 && settings->uints.video_fullscreen_y != 0) { /* Keep input and output aspect ratio equal. - * There are other aspect ratio settings + * There are other aspect ratio settings * which can be used to stretch video output. */ /* Calculate source and destination aspect ratios. */ - float srcAspect = (float)settings->uints.video_fullscreen_x + float srcAspect = (float)settings->uints.video_fullscreen_x / (float)settings->uints.video_fullscreen_y; float dstAspect = (float)vc->fb_width / (float)vc->fb_height; - /* If source and destination aspect ratios + /* If source and destination aspect ratios * are not equal correct source width. */ if (srcAspect != dstAspect) *width = (unsigned)(settings->uints.video_fullscreen_y * dstAspect); @@ -198,7 +198,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver) /* If we set this env variable, Broadcom's EGL implementation will block * on vsync with a double buffer when we call eglSwapBuffers. Less input lag! - * Has to be done before any EGL call. + * Has to be done before any EGL call. * NOTE this is commented out because it should be the right way to do it, but * currently it doesn't work, so we are using an vsync callback based solution.*/ /* if (video_info->max_swapchain_images <= 2) @@ -216,7 +216,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver) goto error; } - if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API) + if (!egl_create_context(&vc->egl, (vc_api == GFX_CTX_OPENGL_ES_API) ? context_attributes : NULL)) { egl_report_error(); @@ -236,7 +236,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver) src_rect.x = 0; src_rect.y = 0; - /* Use dispmanx upscaling if fullscreen_x + /* Use dispmanx upscaling if fullscreen_x * and fullscreen_y are set. */ if (settings->uints.video_fullscreen_x != 0 && settings->uints.video_fullscreen_y != 0) @@ -281,11 +281,11 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver) settings->uints.video_fullscreen_y != 0) { /* Keep input and output aspect ratio equal. - * There are other aspect ratio settings which + * There are other aspect ratio settings which * can be used to stretch video output. */ /* Calculate source and destination aspect ratios. */ - float srcAspect = (float)settings->uints.video_fullscreen_x + float srcAspect = (float)settings->uints.video_fullscreen_x / (float)settings->uints.video_fullscreen_y; float dstAspect = (float)vc->fb_width / (float)vc->fb_height; @@ -313,7 +313,7 @@ static void *gfx_ctx_vc_init(video_frame_info_t *video_info, void *video_driver) vc->vsync_condition_mutex = slock_new(); vc->vsync_callback_set = false; if (video_info->max_swapchain_images <= 2) { - /* Start sending vsync callbacks so we can wait for vsync after eglSwapBuffers */ + /* Start sending vsync callbacks so we can wait for vsync after eglSwapBuffers */ vc_dispmanx_vsync_callback(vc->dispman_display, dispmanx_vsync_callback, (void*)vc); vc->vsync_callback_set = true; } @@ -525,7 +525,7 @@ static bool gfx_ctx_vc_image_buffer_init(void *data, peglCreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)egl_get_proc_address("eglCreateImageKHR"); peglDestroyImageKHR = (PFNEGLDESTROYIMAGEKHRPROC)egl_get_proc_address("eglDestroyImageKHR"); - if (!peglCreateImageKHR || !peglDestroyImageKHR + if (!peglCreateImageKHR || !peglDestroyImageKHR || !gfx_ctx_vc_egl_query_extension(vc, "KHR_image")) return false; @@ -644,7 +644,7 @@ static void gfx_ctx_vc_swap_buffers(void *data, void *data2) } slock_lock(vc->vsync_condition_mutex); scond_wait(vc->vsync_condition, vc->vsync_condition_mutex); - slock_unlock(vc->vsync_condition_mutex); + slock_unlock(vc->vsync_condition_mutex); } else if (vc->vsync_callback_set) { /* Stop generating vsync callbacks from now on */ diff --git a/gfx/drivers_context/vivante_fbdev_ctx.c b/gfx/drivers_context/vivante_fbdev_ctx.c index 17fdf3e19b..10ea704ee6 100644 --- a/gfx/drivers_context/vivante_fbdev_ctx.c +++ b/gfx/drivers_context/vivante_fbdev_ctx.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011 2017 - Daniel De Matteis * Copyright (C) 2014 2015 - Jean-Andre Santoni - * + * * 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. diff --git a/gfx/drivers_context/wayland_ctx.c b/gfx/drivers_context/wayland_ctx.c index cde0887fb0..29f45c925b 100644 --- a/gfx/drivers_context/wayland_ctx.c +++ b/gfx/drivers_context/wayland_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -68,7 +68,7 @@ typedef struct gfx_ctx_wayland_data struct wl_seat *seat; struct wl_shm *shm; unsigned swap_interval; - bool core_hw_context_enable; + bool core_hw_context_enable; unsigned buffer_scale; @@ -293,7 +293,7 @@ static void pointer_handle_button(void *data, wl->input.mouse.middle = true; } else - { + { if (button == BTN_LEFT) wl->input.mouse.left = false; else if (button == BTN_RIGHT) @@ -645,7 +645,7 @@ static void gfx_ctx_wl_check_window(void *data, bool *quit, { case GFX_CTX_VULKAN_API: #ifdef HAVE_VULKAN - /* Swapchains are recreated in set_resize as a + /* Swapchains are recreated in set_resize as a * central place, so use that to trigger swapchain reinit. */ *resize = wl->vk.need_new_swapchain; #endif @@ -1133,7 +1133,7 @@ static bool gfx_ctx_wl_set_video_mode(void *data, #ifdef HAVE_VULKAN if (!vulkan_surface_create(&wl->vk, VULKAN_WSI_WAYLAND, - wl->input.dpy, wl->surface, + wl->input.dpy, wl->surface, wl->width, wl->height, wl->swap_interval)) goto error; #endif diff --git a/gfx/drivers_context/wgl_ctx.c b/gfx/drivers_context/wgl_ctx.c index 9b5e441503..c6179a088f 100644 --- a/gfx/drivers_context/wgl_ctx.c +++ b/gfx/drivers_context/wgl_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -159,9 +159,9 @@ static void create_gl_context(HWND hwnd, bool *quit) else { win32_hrc = wglCreateContext(win32_hdc); - + /* We'll create shared context later if not. */ - if (win32_hrc && !core_context && !debug) + if (win32_hrc && !core_context && !debug) { win32_hw_hrc = wglCreateContext(win32_hdc); if (win32_hw_hrc) @@ -203,7 +203,7 @@ static void create_gl_context(HWND hwnd, bool *quit) *aptr++ = win32_minor; /* Technically, we don't have core/compat until 3.2. - * Version 3.1 is either compat or not depending + * Version 3.1 is either compat or not depending * on GL_ARB_compatibility. */ if ((win32_major * 1000 + win32_minor) >= 3002) @@ -280,7 +280,7 @@ void create_graphics_context(HWND hwnd, bool *quit) height = rect.bottom - rect.top; if (!vulkan_surface_create(&win32_vk, VULKAN_WSI_WIN32, - &instance, &hwnd, + &instance, &hwnd, width, height, win32_interval)) *quit = true; @@ -462,7 +462,7 @@ static void *gfx_ctx_wgl_init(video_frame_info_t *video_info, void *video_driver return NULL; dll_handle = dylib_load("OpenGL32.dll"); - + win32_window_reset(); win32_monitor_init(); diff --git a/gfx/drivers_context/x_ctx.c b/gfx/drivers_context/x_ctx.c index 1faa28b95f..64673379cd 100644 --- a/gfx/drivers_context/x_ctx.c +++ b/gfx/drivers_context/x_ctx.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. @@ -169,7 +169,7 @@ static int GLXExtensionSupported(Display *dpy, const char *extension) const char *client_extensions = glXGetClientString(dpy, GLX_EXTENSIONS); const char *pos = strstr(extensionsString, extension); - if ( (pos != NULL) && + if ( (pos != NULL) && (pos == extensionsString || pos[-1] == ' ') && (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0') ) @@ -178,7 +178,7 @@ static int GLXExtensionSupported(Display *dpy, const char *extension) pos = strstr(client_extensions, extension); if ( - (pos != NULL) && + (pos != NULL) && (pos == extensionsString || pos[-1] == ' ') && (pos[strlen(extension)] == ' ' || pos[strlen(extension)] == '\0') ) @@ -227,7 +227,7 @@ static void gfx_ctx_x_destroy_resources(gfx_ctx_x_data_t *x) x->g_hw_ctx = NULL; } } - + if (g_x11_win) { if (x->g_glx_win) @@ -290,7 +290,7 @@ static void gfx_ctx_x_destroy(void *data) gfx_ctx_x_data_t *x = (gfx_ctx_x_data_t*)data; if (!x) return; - + gfx_ctx_x_destroy_resources(x); switch (x_api) @@ -706,8 +706,8 @@ static bool gfx_ctx_x_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, - vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask | + vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); @@ -740,13 +740,13 @@ static bool gfx_ctx_x_set_video_mode(void *data, } else if (fullscreen) { - /* We attempted true fullscreen, but failed. + /* We attempted true fullscreen, but failed. * Attempt using windowed fullscreen. */ XMapRaised(g_x11_dpy, g_x11_win); RARCH_LOG("[GLX]: Using windowed fullscreen.\n"); - /* We have to move the window to the screen we want + /* We have to move the window to the screen we want * to go fullscreen on first. * x_off and y_off usually get ignored in XCreateWindow(). */ @@ -756,7 +756,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, else { XMapWindow(g_x11_dpy, g_x11_win); - /* If we want to map the window on a different screen, + /* If we want to map the window on a different screen, * we'll have to do it by force. * Otherwise, we should try to let the window manager sort it out. * x_off and y_off usually get ignored in XCreateWindow(). */ @@ -788,7 +788,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, if (x->g_core_es_core) { /* Technically, we don't have core/compat until 3.2. - * Version 3.1 is either compat or not depending on + * Version 3.1 is either compat or not depending on * GL_ARB_compatibility. */ *aptr++ = GLX_CONTEXT_PROFILE_MASK_ARB; @@ -864,7 +864,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, /* Use XCB surface since it's the most supported WSI. * We can obtain the XCB connection directly from X11. */ if (!vulkan_surface_create(&x->vk, VULKAN_WSI_XCB, - g_x11_dpy, &g_x11_win, + g_x11_dpy, &g_x11_win, width, height, x->g_interval)) goto error; } @@ -923,7 +923,7 @@ static bool gfx_ctx_x_set_video_mode(void *data, gfx_ctx_x_swap_interval(data, x->g_interval); - /* This can blow up on some drivers. + /* This can blow up on some drivers. * It's not fatal, so override errors for this call. */ old_handler = XSetErrorHandler(x_nul_handler); XSetInputFocus(g_x11_dpy, g_x11_win, RevertToNone, CurrentTime); diff --git a/gfx/drivers_context/xegl_ctx.c b/gfx/drivers_context/xegl_ctx.c index 351c021215..59d7d65c62 100644 --- a/gfx/drivers_context/xegl_ctx.c +++ b/gfx/drivers_context/xegl_ctx.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -87,7 +87,7 @@ static void gfx_ctx_xegl_destroy(void *data) free(data); - /* Do not close g_x11_dpy. We'll keep one for the entire application + /* Do not close g_x11_dpy. We'll keep one for the entire application * lifecycle to work-around nVidia EGL limitations. */ } @@ -212,7 +212,7 @@ static EGLint *xegl_fill_attribs(xegl_ctx_data_t *xegl, EGLint *attr) *attr++ = xegl->egl.minor; /* Technically, we don't have core/compat until 3.2. - * Version 3.1 is either compat or not depending + * Version 3.1 is either compat or not depending * on GL_ARB_compatibility. */ if (version >= 3002) @@ -294,7 +294,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, swa.colormap = g_x11_cmap = XCreateColormap( g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), vi->visual, AllocNone); - swa.event_mask = StructureNotifyMask | KeyPressMask | + swa.event_mask = StructureNotifyMask | KeyPressMask | ButtonPressMask | ButtonReleaseMask | KeyReleaseMask; swa.override_redirect = fullscreen ? True : False; @@ -337,8 +337,8 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, g_x11_win = XCreateWindow(g_x11_dpy, RootWindow(g_x11_dpy, vi->screen), x_off, y_off, width, height, 0, - vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask | + vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask | (true_full ? CWOverrideRedirect : 0), &swa); XSetWindowBackground(g_x11_dpy, g_x11_win, 0); @@ -362,14 +362,14 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, RARCH_LOG("[X/EGL]: Using true fullscreen.\n"); XMapRaised(g_x11_dpy, g_x11_win); } - else if (fullscreen) + else if (fullscreen) { /* We attempted true fullscreen, but failed. * Attempt using windowed fullscreen. */ XMapRaised(g_x11_dpy, g_x11_win); RARCH_LOG("[X/EGL]: Using windowed fullscreen.\n"); - /* We have to move the window to the screen we + /* We have to move the window to the screen we * want to go fullscreen on first. * x_off and y_off usually get ignored in XCreateWindow(). */ @@ -380,7 +380,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, { XMapWindow(g_x11_dpy, g_x11_win); - /* If we want to map the window on a different screen, + /* If we want to map the window on a different screen, * we'll have to do it by force. * * Otherwise, we should try to let the window manager sort it out. @@ -397,7 +397,7 @@ static bool gfx_ctx_xegl_set_video_mode(void *data, gfx_ctx_xegl_set_swap_interval(&xegl->egl, xegl->egl.interval); #endif - /* This can blow up on some drivers. It's not fatal, + /* This can blow up on some drivers. It's not fatal, * so override errors for this call. */ old_handler = XSetErrorHandler(x_nul_handler); @@ -583,7 +583,7 @@ const gfx_ctx_driver_t gfx_ctx_x_egl = gfx_ctx_xegl_init, gfx_ctx_xegl_destroy, gfx_ctx_xegl_bind_api, - gfx_ctx_xegl_set_swap_interval, + gfx_ctx_xegl_set_swap_interval, gfx_ctx_xegl_set_video_mode, x11_get_video_size, NULL, /* get_video_output_size */ diff --git a/gfx/drivers_font/caca_font.c b/gfx/drivers_font/caca_font.c index 6d6f37196a..0454aa3844 100644 --- a/gfx/drivers_font/caca_font.c +++ b/gfx/drivers_font/caca_font.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. diff --git a/gfx/drivers_font/ctr_font.c b/gfx/drivers_font/ctr_font.c index e78054768b..08d3080ce5 100644 --- a/gfx/drivers_font/ctr_font.c +++ b/gfx/drivers_font/ctr_font.c @@ -262,7 +262,7 @@ static void ctr_font_render_line( GPU_SetViewport(NULL, VIRT_TO_PHYS(ctr->drawbuffers.top.left), 0, 0, CTR_TOP_FRAMEBUFFER_HEIGHT, - ctr->video_mode == CTR_VIDEO_MODE_800x240 + ctr->video_mode == CTR_VIDEO_MODE_800x240 ? CTR_TOP_FRAMEBUFFER_WIDTH * 2 : CTR_TOP_FRAMEBUFFER_WIDTH); GPU_DrawArray(GPU_GEOMETRY_PRIM, 0, v - ctr->vertex_cache.current); diff --git a/gfx/drivers_font/d3d_w32_font.c b/gfx/drivers_font/d3d_w32_font.c index 892197f16b..c0c707689e 100644 --- a/gfx/drivers_font/d3d_w32_font.c +++ b/gfx/drivers_font/d3d_w32_font.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_font/gdi_font.c b/gfx/drivers_font/gdi_font.c index 177b38b2bf..133de8af2f 100644 --- a/gfx/drivers_font/gdi_font.c +++ b/gfx/drivers_font/gdi_font.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. diff --git a/gfx/drivers_font/gl_raster_font.c b/gfx/drivers_font/gl_raster_font.c index 16a2bbc55f..72d84a3205 100644 --- a/gfx/drivers_font/gl_raster_font.c +++ b/gfx/drivers_font/gl_raster_font.c @@ -303,7 +303,7 @@ static void gl_raster_font_render_line( { i = 0; while ((i < MAX_MSG_LEN_CHUNK) && (msg < msg_end)) - { + { int off_x, off_y, tex_x, tex_y, width, height; unsigned code = utf8_walk(&msg); const struct font_glyph *glyph = font->font_driver->get_glyph( @@ -374,7 +374,7 @@ static void gl_raster_font_render_message( for (;;) { const char *delim = strchr(msg, '\n'); - unsigned msg_len = delim + unsigned msg_len = delim ? (unsigned)(delim - msg) : (unsigned)strlen(msg); /* Draw the line */ diff --git a/gfx/drivers_font/ps_libdbgfont.c b/gfx/drivers_font/ps_libdbgfont.c index 25268c031e..d98f1d8cd3 100644 --- a/gfx/drivers_font/ps_libdbgfont.c +++ b/gfx/drivers_font/ps_libdbgfont.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -96,7 +96,7 @@ static void libdbg_font_render_msg( DbgFontPrint(x, y, scale - 0.01f, WHITE, msg); #ifdef SN_TARGET_PSP2 - /* FIXME - if we ever get around to this port, + /* FIXME - if we ever get around to this port, * move this out to some better place */ sceDbgFontFlush(); #endif diff --git a/gfx/drivers_font/vga_font.c b/gfx/drivers_font/vga_font.c index 229186e3c7..a217494edc 100644 --- a/gfx/drivers_font/vga_font.c +++ b/gfx/drivers_font/vga_font.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2016 - Brad Parker - * + * * 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. diff --git a/gfx/drivers_font/vita2d_font.c b/gfx/drivers_font/vita2d_font.c index 7a4777a3eb..f6cdcace8a 100644 --- a/gfx/drivers_font/vita2d_font.c +++ b/gfx/drivers_font/vita2d_font.c @@ -38,14 +38,14 @@ static void *vita2d_font_init_font(void *data, bool is_threaded) { unsigned int stride, pitch, j, k; - const uint8_t *frame32 = NULL; + const uint8_t *frame32 = NULL; uint8_t *tex32 = NULL; const struct font_atlas *atlas = NULL; vita_font_t *font = (vita_font_t*)calloc(1, sizeof(*font)); if (!font) return NULL; - + font->vita = (vita_video_t*)data; if (!font_renderer_create_default((const void**)&font->font_driver, @@ -78,7 +78,7 @@ static void *vita2d_font_init_font(void *data, for (j = 0; j < atlas->height; j++) for (k = 0; k < atlas->width; k++) tex32[k + j*stride] = frame32[k + j*pitch]; - + font->atlas->dirty = false; return font; @@ -169,7 +169,7 @@ static void vita2d_font_render_line( int off_x, off_y, tex_x, tex_y, width, height; unsigned int stride, pitch, j, k; const struct font_glyph *glyph = NULL; - const uint8_t *frame32 = NULL; + const uint8_t *frame32 = NULL; uint8_t *tex32 = NULL; const char *msg_tmp = &msg[i]; unsigned code = utf8_walk(&msg_tmp); @@ -192,7 +192,7 @@ static void vita2d_font_render_line( tex_y = glyph->atlas_offset_y; width = glyph->width; height = glyph->height; - + if (font->atlas->dirty) { stride = vita2d_texture_get_stride(font->texture); @@ -203,7 +203,7 @@ static void vita2d_font_render_line( for (j = 0; j < font->atlas->height; j++) for (k = 0; k < font->atlas->width; k++) tex32[k + j*stride] = frame32[k + j*pitch]; - + font->atlas->dirty = false; } diff --git a/gfx/drivers_font/vulkan_raster_font.c b/gfx/drivers_font/vulkan_raster_font.c index c76910b500..a562aa33b0 100644 --- a/gfx/drivers_font/vulkan_raster_font.c +++ b/gfx/drivers_font/vulkan_raster_font.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2016-2017 - 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. @@ -43,7 +43,7 @@ static void *vulkan_raster_font_init_font(void *data, const char *font_path, float font_size, bool is_threaded) { - vulkan_raster_t *font = + vulkan_raster_t *font = (vulkan_raster_t*)calloc(1, sizeof(*font)); #if 0 @@ -95,7 +95,7 @@ static void vulkan_raster_font_free_font(void *data, bool is_threaded) font->font_driver->free(font->font_data); vkQueueWaitIdle(font->vk->context->queue); - vulkan_destroy_texture( + vulkan_destroy_texture( font->vk->context->device, &font->texture); vulkan_destroy_texture( font->vk->context->device, &font->texture_optimal); @@ -124,7 +124,7 @@ static int vulkan_get_message_width(void *data, const char *msg, unsigned msg_len, float scale) { vulkan_raster_t *font = (vulkan_raster_t*)data; - + unsigned i; int delta_x = 0; @@ -133,7 +133,7 @@ static int vulkan_get_message_width(void *data, const char *msg, for (i = 0; i < msg_len; i++) { - const struct font_glyph *glyph = + const struct font_glyph *glyph = font->font_driver->get_glyph(font->font_data, (uint8_t)msg[i]); if (!glyph) /* Do something smarter here ... */ glyph = font->font_driver->get_glyph(font->font_data, '?'); @@ -272,7 +272,7 @@ static void vulkan_raster_font_render_message( static void vulkan_raster_font_flush(vulkan_raster_t *font) { struct vk_draw_triangles call; - + call.pipeline = font->vk->pipelines.font; call.texture = &font->texture_optimal; call.sampler = font->vk->samplers.mipmap_linear; @@ -407,7 +407,7 @@ static void vulkan_raster_font_render_msg( color_dark[3] = color[3] * drop_alpha; vulkan_raster_font_render_message(font, msg, scale, color_dark, - x + scale * drop_x / vk->vp.width, y + + x + scale * drop_x / vk->vp.width, y + scale * drop_y / vk->vp.height, text_align); } diff --git a/gfx/drivers_font/xdk1_xfonts.c b/gfx/drivers_font/xdk1_xfonts.c index 4e0c808d64..f76883f683 100644 --- a/gfx/drivers_font/xdk1_xfonts.c +++ b/gfx/drivers_font/xdk1_xfonts.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -60,7 +60,7 @@ static void xfonts_free_font(void *data, bool is_threaded) if (font) free(font); - + font = NULL; } diff --git a/gfx/drivers_font_renderer/bitmap.h b/gfx/drivers_font_renderer/bitmap.h index 5a5a4ba82b..8483021532 100644 --- a/gfx/drivers_font_renderer/bitmap.h +++ b/gfx/drivers_font_renderer/bitmap.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_font_renderer/bitmapfont.c b/gfx/drivers_font_renderer/bitmapfont.c index b6d289ec03..71a0996420 100644 --- a/gfx/drivers_font_renderer/bitmapfont.c +++ b/gfx/drivers_font_renderer/bitmapfont.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -56,7 +56,7 @@ static void char_to_texture(bm_renderer_t *handle, uint8_t letter, unsigned atlas_x, unsigned atlas_y) { unsigned y, x; - uint8_t *target = handle->atlas.buffer + atlas_x + + uint8_t *target = handle->atlas.buffer + atlas_x + atlas_y * handle->atlas.width; for (y = 0; y < FONT_HEIGHT; y++) @@ -101,9 +101,9 @@ static void *font_renderer_bmp_init(const char *font_path, float font_size) for (i = 0; i < BMP_ATLAS_SIZE; i++) { - unsigned x = (i % BMP_ATLAS_COLS) * + unsigned x = (i % BMP_ATLAS_COLS) * handle->scale_factor * FONT_WIDTH; - unsigned y = (i / BMP_ATLAS_COLS) * + unsigned y = (i / BMP_ATLAS_COLS) * handle->scale_factor * FONT_HEIGHT; char_to_texture(handle, i, x, y); @@ -138,10 +138,10 @@ static const char *font_renderer_bmp_get_default_font(void) static int font_renderer_bmp_get_line_height(void* data) { bm_renderer_t *handle = (bm_renderer_t*)data; - + if (!handle) return FONT_HEIGHT; - + return FONT_HEIGHT * handle->scale_factor; } diff --git a/gfx/drivers_font_renderer/coretext.c b/gfx/drivers_font_renderer/coretext.c index 9205e00f22..33a321b97e 100644 --- a/gfx/drivers_font_renderer/coretext.c +++ b/gfx/drivers_font_renderer/coretext.c @@ -124,7 +124,7 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1080 kCTFontOrientationDefault, #else - kCTFontDefaultOrientation, + kCTFontDefaultOrientation, #endif glyphs, advances, CT_ATLAS_SIZE); @@ -177,8 +177,8 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer CGContextSetTextMatrix(offscreen, CGAffineTransformIdentity); - attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, - sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, + attr = CFDictionaryCreate(NULL, (const void **)&keys, (const void **)&values, + sizeof(keys) / sizeof(keys[0]), &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); for (i = 0; i < CT_ATLAS_SIZE; i++) @@ -208,7 +208,7 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer glyph_cstr[1] = 0; glyph_cfstr = CFStringCreateWithCString( NULL, glyph_cstr, kCFStringEncodingASCII ); - attrString = + attrString = CFAttributedStringCreate(NULL, glyph_cfstr, attr); CFRelease(glyph_cfstr); glyph_cfstr = NULL; @@ -232,7 +232,7 @@ static bool coretext_font_renderer_create_atlas(CTFontRef face, ct_font_renderer for (c = 0; c < max_width; c++) { unsigned src_idx = (unsigned)(r * bytesPerRow + c); - unsigned dest_idx = + unsigned dest_idx = (r + offset_y) * (CT_ATLAS_COLS * max_width) + (c + offset_x); uint8_t v = src[src_idx]; diff --git a/gfx/drivers_font_renderer/freetype.c b/gfx/drivers_font_renderer/freetype.c index 966ab74548..2c4edbf965 100644 --- a/gfx/drivers_font_renderer/freetype.c +++ b/gfx/drivers_font_renderer/freetype.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -263,7 +263,7 @@ error: return NULL; } -/* Not the cleanest way to do things for sure, +/* Not the cleanest way to do things for sure, * but should hopefully work ... */ static const char *font_paths[] = { diff --git a/gfx/drivers_font_renderer/stb_unicode.c b/gfx/drivers_font_renderer/stb_unicode.c index d22a461f61..878b3cd93d 100644 --- a/gfx/drivers_font_renderer/stb_unicode.c +++ b/gfx/drivers_font_renderer/stb_unicode.c @@ -211,7 +211,7 @@ static bool font_renderer_stb_unicode_create_atlas( static void *font_renderer_stb_unicode_init(const char *font_path, float font_size) { int ascent, descent, line_gap; - stb_unicode_font_renderer_t *self = + stb_unicode_font_renderer_t *self = (stb_unicode_font_renderer_t*)calloc(1, sizeof(*self)); if (!self || font_size < 1.0) diff --git a/gfx/drivers_renderchain/d3d8_renderchain.c b/gfx/drivers_renderchain/d3d8_renderchain.c index faef44aee7..3427ce988e 100644 --- a/gfx/drivers_renderchain/d3d8_renderchain.c +++ b/gfx/drivers_renderchain/d3d8_renderchain.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -78,17 +78,17 @@ static bool d3d8_renderchain_create_first_pass(void *data, LPDIRECT3DDEVICE d3dr = (LPDIRECT3DDEVICE)d3d->dev; d3d8_renderchain_t *chain = (d3d8_renderchain_t*)d3d->renderchain_data; - chain->vertex_buf = d3d_vertex_buffer_new(d3dr, 4 * sizeof(Vertex), - D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, + chain->vertex_buf = d3d_vertex_buffer_new(d3dr, 4 * sizeof(Vertex), + D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, NULL); if (!chain->vertex_buf) return false; - chain->tex = d3d_texture_new(d3dr, NULL, + chain->tex = d3d_texture_new(d3dr, NULL, chain->tex_w, chain->tex_h, 1, 0, - info->rgb32 - ? + info->rgb32 + ? #ifdef _XBOX D3DFMT_LIN_X8R8G8B8 : D3DFMT_LIN_R5G6B5, #else @@ -193,7 +193,7 @@ static void d3d8_renderchain_blit_to_texture(void *data, const void *frame, } /* Set the texture to NULL so D3D doesn't complain about it being in use... */ - d3d_set_texture(d3dr, 0, NULL); + d3d_set_texture(d3dr, 0, NULL); d3d_texture_blit(chain->pixel_size, chain->tex, &d3dlr, frame, width, height, pitch); } @@ -249,7 +249,7 @@ static bool d3d8_renderchain_init(void *data, unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; struct video_viewport *custom_vp = video_viewport_get_custom(); (void)final_viewport_data; - + video_driver_get_size(&width, &height); chain->dev = (LPDIRECT3DDEVICE)dev_data; @@ -346,7 +346,7 @@ static void d3d8_renderchain_convert_geometry( (void)width; (void)height; (void)final_viewport_data; - + /* stub */ } @@ -361,7 +361,7 @@ static bool d3d8_renderchain_reinit(void *data, return false; chain->pixel_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); - chain->tex_w = chain->tex_h = RARCH_SCALE_BASE * video->input_scale; + chain->tex_w = chain->tex_h = RARCH_SCALE_BASE * video->input_scale; RARCH_LOG( "Reinitializing renderchain - and textures (%u x %u @ %u bpp)\n", chain->tex_w, chain->tex_h, chain->pixel_size * CHAR_BIT); diff --git a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c index 8d96721d86..b40c011604 100644 --- a/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c +++ b/gfx/drivers_renderchain/d3d9_hlsl_renderchain.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -99,14 +99,14 @@ static bool hlsl_d3d9_renderchain_create_first_pass(void *data, d3d->renderchain_data; chain->vertex_buf = d3d_vertex_buffer_new( - d3dr, 4 * sizeof(Vertex), - D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, + d3dr, 4 * sizeof(Vertex), + D3DUSAGE_WRITEONLY, D3DFVF_CUSTOMVERTEX, D3DPOOL_MANAGED, NULL); if (!chain->vertex_buf) return false; - chain->tex = d3d_texture_new(d3dr, NULL, + chain->tex = d3d_texture_new(d3dr, NULL, chain->tex_w, chain->tex_h, 1, 0, #ifdef _XBOX info->rgb32 ? D3DFMT_LIN_X8R8G8B8 : D3DFMT_LIN_R5G6B5, @@ -137,7 +137,7 @@ static void hlsl_d3d9_renderchain_set_vertices( video_shader_ctx_info_t shader_info; unsigned width, height; d3d_video_t *d3d = (d3d_video_t*)data; - hlsl_d3d9_renderchain_t *chain = d3d ? + hlsl_d3d9_renderchain_t *chain = d3d ? (hlsl_d3d9_renderchain_t*)d3d->renderchain_data : NULL; video_driver_get_size(&width, &height); @@ -191,7 +191,7 @@ static void hlsl_d3d9_renderchain_set_vertices( d3d_vertex_buffer_unlock(chain->vertex_buf); } - hlsl_d3d9_renderchain_set_mvp(chain, + hlsl_d3d9_renderchain_set_mvp(chain, d3d, width, height, d3d->dev_rotation); shader_info.data = d3d; @@ -236,7 +236,7 @@ static void hlsl_d3d9_renderchain_blit_to_texture( } /* Set the texture to NULL so D3D doesn't complain about it being in use... */ - d3d_set_texture(d3dr, 0, NULL); + d3d_set_texture(d3dr, 0, NULL); d3d_texture_blit(chain->pixel_size, chain->tex, &d3dlr, frame, width, height, pitch); } @@ -269,7 +269,7 @@ static void hlsl_d3d9_renderchain_free(void *data) void *hlsl_d3d9_renderchain_new(void) { - hlsl_d3d9_renderchain_t *renderchain = + hlsl_d3d9_renderchain_t *renderchain = (hlsl_d3d9_renderchain_t*)calloc(1, sizeof(*renderchain)); if (!renderchain) return NULL; @@ -277,7 +277,7 @@ void *hlsl_d3d9_renderchain_new(void) return renderchain; } -static bool hlsl_d3d9_renderchain_init_shader(void *data, +static bool hlsl_d3d9_renderchain_init_shader(void *data, void *renderchain_data) { video_shader_ctx_init_t init; @@ -316,12 +316,12 @@ static bool hlsl_d3d9_renderchain_init(void *data, const LinkInfo *link_info = (const LinkInfo*)info_data; hlsl_d3d9_renderchain_t *chain = (hlsl_d3d9_renderchain_t*) d3d->renderchain_data; - unsigned fmt = (rgb32) + unsigned fmt = (rgb32) ? RETRO_PIXEL_FORMAT_XRGB8888 : RETRO_PIXEL_FORMAT_RGB565; struct video_viewport *custom_vp = video_viewport_get_custom(); (void)final_viewport_data; - + if (!hlsl_d3d9_renderchain_init_shader(d3d, NULL)) return false; @@ -426,7 +426,7 @@ static void hlsl_d3d9_renderchain_convert_geometry( (void)width; (void)height; (void)final_viewport_data; - + /* stub */ } @@ -442,7 +442,7 @@ static bool hlsl_d3d9_renderchain_reinit(void *data, chain->pixel_size = video->rgb32 ? sizeof(uint32_t) : sizeof(uint16_t); chain->tex_w = RARCH_SCALE_BASE * video->input_scale; - chain->tex_h = RARCH_SCALE_BASE * video->input_scale; + chain->tex_h = RARCH_SCALE_BASE * video->input_scale; RARCH_LOG( "Reinitializing renderchain - and textures (%u x %u @ %u bpp)\n", diff --git a/gfx/drivers_renderchain/gl1_renderchain.c b/gfx/drivers_renderchain/gl1_renderchain.c index 56a5d27650..3eb1f887c7 100644 --- a/gfx/drivers_renderchain/gl1_renderchain.c +++ b/gfx/drivers_renderchain/gl1_renderchain.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -213,7 +213,7 @@ static void gl1_renderchain_restore_default_state(void *data, } static void gl1_renderchain_copy_frame( - void *data, + void *data, void *chain_data, video_frame_info_t *video_info, const void *frame, diff --git a/gfx/drivers_renderchain/gl2_renderchain.c b/gfx/drivers_renderchain/gl2_renderchain.c index 9f4a14fb07..95168fb8aa 100644 --- a/gfx/drivers_renderchain/gl2_renderchain.c +++ b/gfx/drivers_renderchain/gl2_renderchain.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -177,7 +177,7 @@ void gl_load_texture_data( const void *frame, unsigned base_size); void gl_set_viewport( - void *data, video_frame_info_t *video_info, + void *data, video_frame_info_t *video_info, unsigned viewport_width, unsigned viewport_height, bool force_full, bool allow_rotate); @@ -198,12 +198,12 @@ static void gl2_renderchain_convert_geometry( break; case RARCH_SCALE_ABSOLUTE: - fbo_rect->img_width = fbo_rect->max_img_width = + fbo_rect->img_width = fbo_rect->max_img_width = fbo_scale->abs_x; break; case RARCH_SCALE_VIEWPORT: - fbo_rect->img_width = fbo_rect->max_img_width = + fbo_rect->img_width = fbo_rect->max_img_width = fbo_scale->scale_x * vp_width; break; } @@ -221,7 +221,7 @@ static void gl2_renderchain_convert_geometry( break; case RARCH_SCALE_VIEWPORT: - fbo_rect->img_height = fbo_rect->max_img_height = + fbo_rect->img_height = fbo_rect->max_img_height = fbo_scale->scale_y * vp_height; break; } @@ -248,7 +248,7 @@ static bool gl_recreate_fbo( RARCH_GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, *texture, 0); - if (gl2_check_fb_status(RARCH_GL_FRAMEBUFFER) + if (gl2_check_fb_status(RARCH_GL_FRAMEBUFFER) == RARCH_GL_FRAMEBUFFER_COMPLETE) return true; @@ -256,13 +256,13 @@ static bool gl_recreate_fbo( return false; } -static void gl_check_fbo_dimension(gl_t *gl, +static void gl_check_fbo_dimension(gl_t *gl, void *chain_data, unsigned i, bool update_feedback) { struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; - /* Check proactively since we might suddently + /* Check proactively since we might suddently * get sizes of tex_w width or tex_h height. */ gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; unsigned img_width = fbo_rect->max_img_width; @@ -275,14 +275,14 @@ static void gl_check_fbo_dimension(gl_t *gl, gl_recreate_fbo(fbo_rect, chain->fbo[i], &chain->fbo_texture[i]); - /* Update feedback texture in-place so we avoid having to + /* Update feedback texture in-place so we avoid having to * juggle two different fbo_rect structs since they get updated here. */ if (update_feedback) { if (gl_recreate_fbo(fbo_rect, gl->fbo_feedback, &gl->fbo_feedback_texture)) { - /* Make sure the feedback textures are cleared + /* Make sure the feedback textures are cleared * so we don't feedback noise. */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -293,7 +293,7 @@ static void gl_check_fbo_dimension(gl_t *gl, i, fbo_rect->width, fbo_rect->height); } -/* On resize, we might have to recreate our FBOs +/* On resize, we might have to recreate our FBOs * due to "Viewport" scale, and set a new viewport. */ static void gl2_renderchain_check_fbo_dimensions(void *data, @@ -309,7 +309,7 @@ static void gl2_renderchain_check_fbo_dimensions(void *data, struct video_fbo_rect *fbo_rect = &gl->fbo_rect[i]; if (fbo_rect) { - bool update_feedback = gl->fbo_feedback_enable + bool update_feedback = gl->fbo_feedback_enable && (unsigned)i == gl->fbo_feedback_pass; if ((fbo_rect->max_img_width > fbo_rect->width) || @@ -590,7 +590,7 @@ static bool gl_create_fbo_targets(gl_t *gl, void *chain_data) if (status != RARCH_GL_FRAMEBUFFER_COMPLETE) goto error; - /* Make sure the feedback textures are cleared + /* Make sure the feedback textures are cleared * so we don't feedback noise. */ glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -606,7 +606,7 @@ error: return false; } -static void gl_create_fbo_texture(gl_t *gl, +static void gl_create_fbo_texture(gl_t *gl, void *chain_data, unsigned i, GLuint texture) { GLenum mag_filter, wrap_enum; @@ -617,7 +617,7 @@ static void gl_create_fbo_texture(gl_t *gl, gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; settings_t *settings = config_get_ptr(); GLuint base_filt = settings->bools.video_smooth ? GL_LINEAR : GL_NEAREST; - GLuint base_mip_filt = settings->bools.video_smooth ? + GLuint base_mip_filt = settings->bools.video_smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST; unsigned mip_level = i + 2; bool mipmapped = video_shader_driver_mipmap_input(&mip_level); @@ -628,7 +628,7 @@ static void gl_create_fbo_texture(gl_t *gl, if (video_shader_driver_filter_type(&filter_type)) { - min_filter = mipmapped ? (smooth ? + min_filter = mipmapped ? (smooth ? GL_LINEAR_MIPMAP_LINEAR : GL_NEAREST_MIPMAP_NEAREST) : (smooth ? GL_LINEAR : GL_NEAREST); } @@ -663,21 +663,21 @@ static void gl_create_fbo_texture(gl_t *gl, { #ifndef HAVE_OPENGLES bool srgb_fbo = chain->fbo_scale[i].srgb_fbo; - + if (!fp_fbo && srgb_fbo) { if (!chain->has_srgb_fbo) RARCH_ERR("[GL]: sRGB FBO was requested, but it is not supported. Falling back to UNORM. Result may have banding!\n"); } - + if (settings->bools.video_force_srgb_disable) srgb_fbo = false; - + if (srgb_fbo && chain->has_srgb_fbo) { RARCH_LOG("[GL]: FBO pass #%d is sRGB.\n", i); #ifdef HAVE_OPENGLES2 - /* EXT defines are same as core GLES3 defines, + /* EXT defines are same as core GLES3 defines, * but GLES3 variant requires different arguments. */ glTexImage2D(GL_TEXTURE_2D, 0, GL_SRGB_ALPHA_EXT, @@ -700,7 +700,7 @@ static void gl_create_fbo_texture(gl_t *gl, gl->fbo_rect[i].width, gl->fbo_rect[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); #else - /* Avoid potential performance + /* Avoid potential performance * reductions on particular platforms. */ gl_load_texture_image(GL_TEXTURE_2D, 0, RARCH_GL_INTERNAL_FORMAT32, @@ -734,7 +734,7 @@ static void gl_create_fbo_textures(gl_t *gl, void *chain_data) } /* Compute FBO geometry. - * When width/height changes or window sizes change, + * When width/height changes or window sizes change, * we have to recalculate geometry of our FBO. */ static void gl2_renderchain_recompute_pass_sizes( @@ -807,7 +807,7 @@ static void gl2_renderchain_start_render(void *data, video_frame_info_t *video_info) { /* Used when rendering to an FBO. - * Texture coords have to be aligned + * Texture coords have to be aligned * with vertex coordinates. */ static const GLfloat fbo_vertexes[] = { 0, 0, @@ -825,7 +825,7 @@ static void gl2_renderchain_start_render(void *data, video_info, gl->fbo_rect[0].img_width, gl->fbo_rect[0].img_height, true, false); - /* Need to preserve the "flipped" state when in FBO + /* Need to preserve the "flipped" state when in FBO * as well to have consistent texture coordinates. * * We will "flip" it in place on last pass. */ @@ -885,7 +885,7 @@ void gl2_renderchain_init( if (!scale.valid) { scale.scale_x = 1.0f; - scale.scale_y = 1.0f; + scale.scale_y = 1.0f; scale.type_x = scale.type_y = RARCH_SCALE_INPUT; scale.valid = true; } @@ -902,7 +902,7 @@ void gl2_renderchain_init( if (!chain->fbo_scale[i].valid) { chain->fbo_scale[i].scale_x = chain->fbo_scale[i].scale_y = 1.0f; - chain->fbo_scale[i].type_x = chain->fbo_scale[i].type_y = + chain->fbo_scale[i].type_x = chain->fbo_scale[i].type_y = RARCH_SCALE_INPUT; chain->fbo_scale[i].valid = true; } @@ -923,7 +923,7 @@ void gl2_renderchain_init( gl->fbo_feedback_enable = video_shader_driver_get_feedback_pass( &gl->fbo_feedback_pass); - if (gl->fbo_feedback_enable && gl->fbo_feedback_pass + if (gl->fbo_feedback_enable && gl->fbo_feedback_pass < (unsigned)chain->fbo_pass) { RARCH_LOG("[GL]: Creating feedback FBO %d @ %ux%u\n", i, @@ -1064,7 +1064,7 @@ static void gl2_renderchain_bind_prev_texture( memcpy(&gl->prev_info[0], tex_info, sizeof(*tex_info)); - /* Implement feedback by swapping out FBO/textures + /* Implement feedback by swapping out FBO/textures * for FBO pass #N and feedbacks. */ if (gl->fbo_feedback_enable) { @@ -1098,7 +1098,7 @@ static void gl2_renderchain_viewport_info( } static bool gl2_renderchain_read_viewport( - void *data, + void *data, void *chain_data, uint8_t *buffer, bool is_idle) { @@ -1160,7 +1160,7 @@ static bool gl2_renderchain_read_viewport( glUnmapBuffer(GL_PIXEL_PACK_BUFFER); glBindBuffer(GL_PIXEL_PACK_BUFFER, 0); } - else + else #endif { /* Use slow synchronous readbacks. Use this with plain screenshots @@ -1272,7 +1272,7 @@ static void gl2_renderchain_restore_default_state( } static void gl2_renderchain_copy_frame( - void *data, + void *data, void *chain_data, video_frame_info_t *video_info, const void *frame, @@ -1280,7 +1280,7 @@ static void gl2_renderchain_copy_frame( { gl_t *gl = (gl_t*)data; gl2_renderchain_t *chain = (gl2_renderchain_t*)chain_data; - + (void)chain; #if defined(HAVE_PSGL) @@ -1315,7 +1315,7 @@ static void gl2_renderchain_copy_frame( img_info.rgb32 = (gl->base_size == 4); img_info.handle = &img; - new_egl = + new_egl = video_context_driver_write_to_image_buffer(&img_info); if (img == EGL_NO_IMAGE_KHR) diff --git a/gfx/drivers_renderchain/null_renderchain.c b/gfx/drivers_renderchain/null_renderchain.c index a3ed173615..c017cb9876 100644 --- a/gfx/drivers_renderchain/null_renderchain.c +++ b/gfx/drivers_renderchain/null_renderchain.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_shader/shader_gl_cg.c b/gfx/drivers_shader/shader_gl_cg.c index e37b40352c..34bb362d9c 100644 --- a/gfx/drivers_shader/shader_gl_cg.c +++ b/gfx/drivers_shader/shader_gl_cg.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -294,7 +294,7 @@ static bool gl_cg_set_coords(void *handle_data, void *shader_data, const struct } static void gl_cg_set_texture_info( - cg_shader_data_t *cg, + cg_shader_data_t *cg, const struct cg_fbo_params *params, const struct video_tex_info *info) { @@ -316,7 +316,7 @@ static void gl_cg_set_texture_info( } static void gl_cg_set_params(void *data, void *shader_data, - unsigned width, unsigned height, + unsigned width, unsigned height, unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, @@ -717,7 +717,7 @@ static bool gl_cg_load_imports(void *data) core_get_memory(&mem_info); - if ((memtype != -1u) && + if ((memtype != -1u) && (cg->shader->variable[i].addr >= mem_info.size)) { RARCH_ERR("Address out of bounds.\n"); @@ -744,7 +744,7 @@ static bool gl_cg_load_imports(void *data) tracker_info.script_is_file = true; } - tracker_info.script_class = + tracker_info.script_class = *cg->shader->script_class ? cg->shader->script_class : NULL; #endif @@ -1019,7 +1019,7 @@ static void gl_cg_set_program_attributes(void *data, unsigned i) attr_buf_tex[0] = attr_buf_vid_size[0] = attr_buf_tex_size[0] = attr_buf_coord[0] = '\0'; - snprintf(attr_buf_tex, sizeof(attr_buf_tex), + snprintf(attr_buf_tex, sizeof(attr_buf_tex), "%s.texture", prev_names[j]); snprintf(attr_buf_vid_size, sizeof(attr_buf_vid_size), "%s.video_size", prev_names[j]); @@ -1031,14 +1031,14 @@ static void gl_cg_set_program_attributes(void *data, unsigned i) cg->prg[i].prev[j].tex = cgGetNamedParameter(cg->prg[i].fprg, attr_buf_tex); - cg->prg[i].prev[j].vid_size_v = + cg->prg[i].prev[j].vid_size_v = cgGetNamedParameter(cg->prg[i].vprg, attr_buf_vid_size); - cg->prg[i].prev[j].vid_size_f = + cg->prg[i].prev[j].vid_size_f = cgGetNamedParameter(cg->prg[i].fprg, attr_buf_vid_size); - cg->prg[i].prev[j].tex_size_v = + cg->prg[i].prev[j].tex_size_v = cgGetNamedParameter(cg->prg[i].vprg, attr_buf_tex_size); - cg->prg[i].prev[j].tex_size_f = + cg->prg[i].prev[j].tex_size_f = cgGetNamedParameter(cg->prg[i].fprg, attr_buf_tex_size); cg->prg[i].prev[j].coord = cgGetNamedParameter(cg->prg[i].vprg, @@ -1109,7 +1109,7 @@ static void *gl_cg_init(void *data, const char *path) memset(cg->alias_define, 0, sizeof(cg->alias_define)); - if ( !string_is_empty(path) + if ( !string_is_empty(path) && string_is_equal_fast(path_get_extension(path), "cgp", 3)) { if (!gl_cg_load_preset(cg, path)) @@ -1126,12 +1126,12 @@ static void *gl_cg_init(void *data, const char *path) for (i = 1; i <= cg->shader->passes; i++) gl_cg_set_program_attributes(cg, i); - /* If we aren't using last pass non-FBO shader, + /* If we aren't using last pass non-FBO shader, * this shader will be assumed to be "fixed-function". * * Just use prg[0] for that pass, which will be * pass-through. */ - cg->prg[cg->shader->passes + 1] = cg->prg[0]; + cg->prg[cg->shader->passes + 1] = cg->prg[0]; /* No need to apply Android hack in Cg. */ cg->prg[VIDEO_SHADER_STOCK_BLEND] = cg->prg[0]; diff --git a/gfx/drivers_shader/shader_glsl.c b/gfx/drivers_shader/shader_glsl.c index e013c95acf..dc5b96528d 100644 --- a/gfx/drivers_shader/shader_glsl.c +++ b/gfx/drivers_shader/shader_glsl.c @@ -525,7 +525,7 @@ static bool gl_glsl_compile_programs( * load the file here, and pretend * we were really using XML all along. */ - if ( !string_is_empty(pass->source.path) + if ( !string_is_empty(pass->source.path) && !gl_glsl_load_source_path(pass, pass->source.path)) { RARCH_ERR("Failed to load GLSL shader: %s.\n", @@ -737,7 +737,7 @@ static void gl_glsl_destroy_resources(glsl_shader_data_t *glsl) return; glsl->current_idx = 0; - + glUseProgram(0); for (i = 0; i < GFX_MAX_SHADERS; i++) @@ -1465,8 +1465,8 @@ static bool gl_glsl_set_mvp(void *data, void *shader_data, const void *mat_data) { const math_matrix_4x4 *mat = (const math_matrix_4x4*)mat_data; - if ( (glsl->current_idx != glsl->active_idx) || - (mat->data != glsl->current_mat_data_pointer[glsl->active_idx]) || + if ( (glsl->current_idx != glsl->active_idx) || + (mat->data != glsl->current_mat_data_pointer[glsl->active_idx]) || (*mat->data != glsl->current_mat_data[glsl->active_idx])) { glUniformMatrix4fv(loc, 1, GL_FALSE, mat->data); @@ -1497,7 +1497,7 @@ static bool gl_glsl_set_coords(void *handle_data, void *shader_data, size_t size = 0; GLfloat *buffer = short_buffer; glsl_shader_data_t *glsl = (glsl_shader_data_t*)shader_data; - const struct shader_uniforms *uni = glsl + const struct shader_uniforms *uni = glsl ? &glsl->uniforms[glsl->active_idx] : NULL; if (!glsl || !glsl->shader->modern || !coords) diff --git a/gfx/drivers_shader/shader_glsl.h b/gfx/drivers_shader/shader_glsl.h index 7f77693a59..311bccdc95 100644 --- a/gfx/drivers_shader/shader_glsl.h +++ b/gfx/drivers_shader/shader_glsl.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_shader/shader_hlsl.c b/gfx/drivers_shader/shader_hlsl.c index 9ffedf5ef1..afc79cf913 100644 --- a/gfx/drivers_shader/shader_hlsl.c +++ b/gfx/drivers_shader/shader_hlsl.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -35,7 +35,7 @@ #include "../drivers/d3d_shaders/opaque.hlsl.d3d9.h" #include "shader_hlsl.h" -struct shader_program_hlsl_data +struct shader_program_hlsl_data { LPDIRECT3DVERTEXSHADER vprg; LPDIRECT3DPIXELSHADER fprg; @@ -188,9 +188,9 @@ static bool hlsl_compile_program( if (program_info->is_file) { ret_fp = D3DXCompileShaderFromFile(program_info->combined, NULL, NULL, - "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable); + "main_fragment", "ps_3_0", 0, &code_f, &listing_f, &program->f_ctable); ret_vp = D3DXCompileShaderFromFile(program_info->combined, NULL, NULL, - "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable); + "main_vertex", "vs_3_0", 0, &code_v, &listing_v, &program->v_ctable); } else { diff --git a/gfx/drivers_shader/shader_hlsl.h b/gfx/drivers_shader/shader_hlsl.h index 77bbe3c599..b5be3eb16f 100644 --- a/gfx/drivers_shader/shader_hlsl.h +++ b/gfx/drivers_shader/shader_hlsl.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_shader/shader_null.c b/gfx/drivers_shader/shader_null.c index 8ee92bff40..d85cfd1b97 100644 --- a/gfx/drivers_shader/shader_null.c +++ b/gfx/drivers_shader/shader_null.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/drivers_shader/shader_vulkan.h b/gfx/drivers_shader/shader_vulkan.h index 26c373023e..79ac7f2d8f 100644 --- a/gfx/drivers_shader/shader_vulkan.h +++ b/gfx/drivers_shader/shader_vulkan.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2016 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -65,7 +65,7 @@ enum vulkan_filter_chain_scale struct vulkan_filter_chain_pass_info { - /* For the last pass, make sure VIEWPORT scale + /* For the last pass, make sure VIEWPORT scale * with scale factors of 1 are used. */ enum vulkan_filter_chain_scale scale_type_x; enum vulkan_filter_chain_scale scale_type_y; diff --git a/gfx/drivers_shader/slang_preprocess.h b/gfx/drivers_shader/slang_preprocess.h index e889f31947..d2c94de12d 100644 --- a/gfx/drivers_shader/slang_preprocess.h +++ b/gfx/drivers_shader/slang_preprocess.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2017 - 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. diff --git a/gfx/drivers_tracker/video_state_python.h b/gfx/drivers_tracker/video_state_python.h index 4abdb929f2..3addbc790c 100644 --- a/gfx/drivers_tracker/video_state_python.h +++ b/gfx/drivers_tracker/video_state_python.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -30,7 +30,7 @@ py_state_t *py_state_new(const char *program, void py_state_free(py_state_t *handle); -float py_state_get(py_state_t *handle, +float py_state_get(py_state_t *handle, const char *id, unsigned frame_count); #endif diff --git a/gfx/font_driver.c b/gfx/font_driver.c index 1390412f68..61969afe56 100644 --- a/gfx/font_driver.c +++ b/gfx/font_driver.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -51,7 +51,7 @@ int font_renderer_create_default(const void **data, void **handle, { unsigned i; - const font_renderer_driver_t **drv = + const font_renderer_driver_t **drv = (const font_renderer_driver_t**)data; for (i = 0; font_backends[i]; i++) @@ -502,8 +502,8 @@ font_data_t *font_driver_init_first( bool ok = false; #ifdef HAVE_THREADS - if ( threading_hint - && is_threaded + if ( threading_hint + && is_threaded && !video_driver_is_hw_context()) ok = video_thread_font_init(&font_driver, &font_handle, video_data, font_path, font_size, api, font_init_first, @@ -528,7 +528,7 @@ font_data_t *font_driver_init_first( void font_driver_init_osd( void *video_data, - bool threading_hint, + bool threading_hint, bool is_threaded, enum font_driver_render_api api) { diff --git a/gfx/font_driver.h b/gfx/font_driver.h index eaa3ef6a85..2656d358c6 100644 --- a/gfx/font_driver.h +++ b/gfx/font_driver.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -49,10 +49,10 @@ enum text_alignment /* All coordinates and offsets are top-left oriented. * - * This is a texture-atlas approach which allows text to + * This is a texture-atlas approach which allows text to * be drawn in a single draw call. * - * It is up to the code using this interface to actually + * It is up to the code using this interface to actually * generate proper vertex buffers and upload the atlas texture to GPU. */ struct font_glyph @@ -64,7 +64,7 @@ struct font_glyph unsigned atlas_offset_x; unsigned atlas_offset_y; - /* When drawing this glyph, apply an offset to + /* When drawing this glyph, apply an offset to * current X/Y draw coordinate. */ int draw_offset_x; int draw_offset_y; @@ -115,7 +115,7 @@ typedef struct font_renderer void (*bind_block)(void *data, void *block); void (*flush)(unsigned width, unsigned height, void *data, video_frame_info_t *video_info); - + int (*get_message_width)(void *data, const char *msg, unsigned msg_len_full, float scale); } font_renderer_t; @@ -133,7 +133,7 @@ typedef struct font_renderer_driver const char *(*get_default_font)(void); const char *ident; - + int (*get_line_height)(void* data); } font_renderer_driver_t; @@ -147,7 +147,7 @@ typedef struct /* font_path can be NULL for default font. */ int font_renderer_create_default(const void **driver, void **handle, const char *font_path, unsigned font_size); - + void font_driver_render_msg(video_frame_info_t *video_info, void *font_data, const char *msg, const void *params); diff --git a/gfx/include/GL/glext.h b/gfx/include/GL/glext.h index a1381696b4..a0d2948292 100644 --- a/gfx/include/GL/glext.h +++ b/gfx/include/GL/glext.h @@ -7,7 +7,7 @@ extern "C" { /* ** Copyright (c) 2007-2012 The Khronos Group Inc. -** +** ** Permission is hereby granted, free of charge, to any person obtaining a ** copy of this software and/or associated documentation files (the ** "Materials"), to deal in the Materials without restriction, including @@ -15,10 +15,10 @@ extern "C" { ** distribute, sublicense, and/or sell copies of the Materials, and to ** permit persons to whom the Materials are furnished to do so, subject to ** the following conditions: -** +** ** The above copyright notice and this permission notice shall be included ** in all copies or substantial portions of the Materials. -** +** ** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, ** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF ** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. diff --git a/gfx/include/d3d8/d3d8.h b/gfx/include/d3d8/d3d8.h index 2600282c16..adf91ebf0b 100644 --- a/gfx/include/d3d8/d3d8.h +++ b/gfx/include/d3d8/d3d8.h @@ -1,1279 +1,1279 @@ -/*==========================================================================; - * - * Copyright (C) Microsoft Corporation. All Rights Reserved. - * - * File: d3d8.h - * Content: Direct3D include file - * - ****************************************************************************/ - -#ifndef _D3D8_H_ -#define _D3D8_H_ - -#ifndef DIRECT3D_VERSION -#define DIRECT3D_VERSION 0x0800 -#endif //DIRECT3D_VERSION - -// include this file content only if compiling for DX8 interfaces -#if(DIRECT3D_VERSION >= 0x0800) - - -/* This identifier is passed to Direct3DCreate8 in order to ensure that an - * application was built against the correct header files. This number is - * incremented whenever a header (or other) change would require applications - * to be rebuilt. If the version doesn't match, Direct3DCreate8 will fail. - * (The number itself has no meaning.)*/ - -#define D3D_SDK_VERSION 220 - - -#include - -#define COM_NO_WINDOWS_H -#include - -#include - -#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) - #define HMONITOR_DECLARED - DECLARE_HANDLE(HMONITOR); -#endif - -#define D3DAPI WINAPI - -/* - * Interface IID's - */ -#if defined( _WIN32 ) && !defined( _NO_COM) - -/* IID_IDirect3D8 */ -/* {1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512} */ -DEFINE_GUID(IID_IDirect3D8, 0x1dd9e8da, 0x1c77, 0x4d40, 0xb0, 0xcf, 0x98, 0xfe, 0xfd, 0xff, 0x95, 0x12); - -/* IID_IDirect3DDevice8 */ -/* {7385E5DF-8FE8-41D5-86B6-D7B48547B6CF} */ -DEFINE_GUID(IID_IDirect3DDevice8, 0x7385e5df, 0x8fe8, 0x41d5, 0x86, 0xb6, 0xd7, 0xb4, 0x85, 0x47, 0xb6, 0xcf); - -/* IID_IDirect3DResource8 */ -/* {1B36BB7B-09B7-410a-B445-7D1430D7B33F} */ -DEFINE_GUID(IID_IDirect3DResource8, 0x1b36bb7b, 0x9b7, 0x410a, 0xb4, 0x45, 0x7d, 0x14, 0x30, 0xd7, 0xb3, 0x3f); - -/* IID_IDirect3DBaseTexture8 */ -/* {B4211CFA-51B9-4a9f-AB78-DB99B2BB678E} */ -DEFINE_GUID(IID_IDirect3DBaseTexture8, 0xb4211cfa, 0x51b9, 0x4a9f, 0xab, 0x78, 0xdb, 0x99, 0xb2, 0xbb, 0x67, 0x8e); - -/* IID_IDirect3DTexture8 */ -/* {E4CDD575-2866-4f01-B12E-7EECE1EC9358} */ -DEFINE_GUID(IID_IDirect3DTexture8, 0xe4cdd575, 0x2866, 0x4f01, 0xb1, 0x2e, 0x7e, 0xec, 0xe1, 0xec, 0x93, 0x58); - -/* IID_IDirect3DCubeTexture8 */ -/* {3EE5B968-2ACA-4c34-8BB5-7E0C3D19B750} */ -DEFINE_GUID(IID_IDirect3DCubeTexture8, 0x3ee5b968, 0x2aca, 0x4c34, 0x8b, 0xb5, 0x7e, 0x0c, 0x3d, 0x19, 0xb7, 0x50); - -/* IID_IDirect3DVolumeTexture8 */ -/* {4B8AAAFA-140F-42ba-9131-597EAFAA2EAD} */ -DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4b8aaafa, 0x140f, 0x42ba, 0x91, 0x31, 0x59, 0x7e, 0xaf, 0xaa, 0x2e, 0xad); - -/* IID_IDirect3DVertexBuffer8 */ -/* {8AEEEAC7-05F9-44d4-B591-000B0DF1CB95} */ -DEFINE_GUID(IID_IDirect3DVertexBuffer8, 0x8aeeeac7, 0x05f9, 0x44d4, 0xb5, 0x91, 0x00, 0x0b, 0x0d, 0xf1, 0xcb, 0x95); - -/* IID_IDirect3DIndexBuffer8 */ -/* {0E689C9A-053D-44a0-9D92-DB0E3D750F86} */ -DEFINE_GUID(IID_IDirect3DIndexBuffer8, 0x0e689c9a, 0x053d, 0x44a0, 0x9d, 0x92, 0xdb, 0x0e, 0x3d, 0x75, 0x0f, 0x86); - -/* IID_IDirect3DSurface8 */ -/* {B96EEBCA-B326-4ea5-882F-2FF5BAE021DD} */ -DEFINE_GUID(IID_IDirect3DSurface8, 0xb96eebca, 0xb326, 0x4ea5, 0x88, 0x2f, 0x2f, 0xf5, 0xba, 0xe0, 0x21, 0xdd); - -/* IID_IDirect3DVolume8 */ -/* {BD7349F5-14F1-42e4-9C79-972380DB40C0} */ -DEFINE_GUID(IID_IDirect3DVolume8, 0xbd7349f5, 0x14f1, 0x42e4, 0x9c, 0x79, 0x97, 0x23, 0x80, 0xdb, 0x40, 0xc0); - -/* IID_IDirect3DSwapChain8 */ -/* {928C088B-76B9-4C6B-A536-A590853876CD} */ -DEFINE_GUID(IID_IDirect3DSwapChain8, 0x928c088b, 0x76b9, 0x4c6b, 0xa5, 0x36, 0xa5, 0x90, 0x85, 0x38, 0x76, 0xcd); - -#endif - -#ifdef __cplusplus - -interface IDirect3D8; -interface IDirect3DDevice8; - -interface IDirect3DResource8; -interface IDirect3DBaseTexture8; -interface IDirect3DTexture8; -interface IDirect3DVolumeTexture8; -interface IDirect3DCubeTexture8; - -interface IDirect3DVertexBuffer8; -interface IDirect3DIndexBuffer8; - -interface IDirect3DSurface8; -interface IDirect3DVolume8; - -interface IDirect3DSwapChain8; - -#endif - - -typedef interface IDirect3D8 IDirect3D8; -typedef interface IDirect3DDevice8 IDirect3DDevice8; -typedef interface IDirect3DResource8 IDirect3DResource8; -typedef interface IDirect3DBaseTexture8 IDirect3DBaseTexture8; -typedef interface IDirect3DTexture8 IDirect3DTexture8; -typedef interface IDirect3DVolumeTexture8 IDirect3DVolumeTexture8; -typedef interface IDirect3DCubeTexture8 IDirect3DCubeTexture8; -typedef interface IDirect3DVertexBuffer8 IDirect3DVertexBuffer8; -typedef interface IDirect3DIndexBuffer8 IDirect3DIndexBuffer8; -typedef interface IDirect3DSurface8 IDirect3DSurface8; -typedef interface IDirect3DVolume8 IDirect3DVolume8; -typedef interface IDirect3DSwapChain8 IDirect3DSwapChain8; - -#include "d3d8types.h" -#include "d3d8caps.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * DLL Function for creating a Direct3D8 object. This object supports - * enumeration and allows the creation of Direct3DDevice8 objects. - * Pass the value of the constant D3D_SDK_VERSION to this function, so - * that the run-time can validate that your application was compiled - * against the right headers. - */ - -IDirect3D8 * WINAPI Direct3DCreate8(UINT SDKVersion); - - -/* - * Direct3D interfaces - */ - - - - - - -#undef INTERFACE -#define INTERFACE IDirect3D8 - -DECLARE_INTERFACE_(IDirect3D8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3D8 methods ***/ - STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; - STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; - STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier) PURE; - STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter) PURE; - STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode) PURE; - STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; - STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed) PURE; - STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; - STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType) PURE; - STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; - STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps) PURE; - STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; - STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE; -}; - -typedef struct IDirect3D8 *LPDIRECT3D8, *PDIRECT3D8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3D8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3D8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3D8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a) -#define IDirect3D8_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) -#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) -#define IDirect3D8_GetAdapterModeCount(p,a) (p)->lpVtbl->GetAdapterModeCount(p,a) -#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->lpVtbl->EnumAdapterModes(p,a,b,c) -#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) -#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) -#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) -#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e) -#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) -#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) -#define IDirect3D8_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) -#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) -#else -#define IDirect3D8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3D8_AddRef(p) (p)->AddRef() -#define IDirect3D8_Release(p) (p)->Release() -#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a) -#define IDirect3D8_GetAdapterCount(p) (p)->GetAdapterCount() -#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) -#define IDirect3D8_GetAdapterModeCount(p,a) (p)->GetAdapterModeCount(a) -#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->EnumAdapterModes(a,b,c) -#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) -#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) -#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) -#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->CheckDeviceMultiSampleType(a,b,c,d,e) -#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) -#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) -#define IDirect3D8_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) -#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) -#endif - - - - - - - - - - - - - - - - - - - -#undef INTERFACE -#define INTERFACE IDirect3DDevice8 - -DECLARE_INTERFACE_(IDirect3DDevice8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DDevice8 methods ***/ - STDMETHOD(TestCooperativeLevel)(THIS) PURE; - STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; - STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE; - STDMETHOD(GetDirect3D)(THIS_ IDirect3D8** ppD3D8) PURE; - STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8* pCaps) PURE; - STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; - STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; - STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface8* pCursorBitmap) PURE; - STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE; - STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; - STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain8** pSwapChain) PURE; - STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; - STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; - STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; - STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; - STDMETHOD_(void, SetGammaRamp)(THIS_ DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; - STDMETHOD_(void, GetGammaRamp)(THIS_ D3DGAMMARAMP* pRamp) PURE; - STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) PURE; - STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) PURE; - STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) PURE; - STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) PURE; - STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) PURE; - STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) PURE; - STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) PURE; - STDMETHOD(CreateImageSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) PURE; - STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) PURE; - STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) PURE; - STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8* pDestSurface) PURE; - STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) PURE; - STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8** ppRenderTarget) PURE; - STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8** ppZStencilSurface) PURE; - STDMETHOD(BeginScene)(THIS) PURE; - STDMETHOD(EndScene)(THIS) PURE; - STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; - STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; - STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; - STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; - STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8* pViewport) PURE; - STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8* pViewport) PURE; - STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8* pMaterial) PURE; - STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8* pMaterial) PURE; - STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT8*) PURE; - STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT8*) PURE; - STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; - STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; - STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; - STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; - STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; - STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; - STDMETHOD(BeginStateBlock)(THIS) PURE; - STDMETHOD(EndStateBlock)(THIS_ DWORD* pToken) PURE; - STDMETHOD(ApplyStateBlock)(THIS_ DWORD Token) PURE; - STDMETHOD(CaptureStateBlock)(THIS_ DWORD Token) PURE; - STDMETHOD(DeleteStateBlock)(THIS_ DWORD Token) PURE; - STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,DWORD* pToken) PURE; - STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8* pClipStatus) PURE; - STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8* pClipStatus) PURE; - STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8** ppTexture) PURE; - STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8* pTexture) PURE; - STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; - STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; - STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; - STDMETHOD(GetInfo)(THIS_ DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) PURE; - STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; - STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; - STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; - STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; - STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; - STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; - STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; - STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; - STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) PURE; - STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) PURE; - STDMETHOD(SetVertexShader)(THIS_ DWORD Handle) PURE; - STDMETHOD(GetVertexShader)(THIS_ DWORD* pHandle) PURE; - STDMETHOD(DeleteVertexShader)(THIS_ DWORD Handle) PURE; - STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; - STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; - STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) PURE; - STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8** ppStreamData,UINT* pStride) PURE; - STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) PURE; - STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) PURE; - STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,DWORD* pHandle) PURE; - STDMETHOD(SetPixelShader)(THIS_ DWORD Handle) PURE; - STDMETHOD(GetPixelShader)(THIS_ DWORD* pHandle) PURE; - STDMETHOD(DeletePixelShader)(THIS_ DWORD Handle) PURE; - STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; - STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; - STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; - STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; - STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; -}; - -typedef struct IDirect3DDevice8 *LPDIRECT3DDEVICE8, *PDIRECT3DDEVICE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DDevice8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) -#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) -#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->lpVtbl->ResourceManagerDiscardBytes(p,a) -#define IDirect3DDevice8_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) -#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) -#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) -#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) -#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) -#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) -#define IDirect3DDevice8_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) -#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) -#define IDirect3DDevice8_Reset(p,a) (p)->lpVtbl->Reset(p,a) -#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) -#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) -#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) -#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b) -#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a) -#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g) -#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h) -#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f) -#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e) -#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e) -#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f) -#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e) -#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->lpVtbl->CreateImageSurface(p,a,b,c,d) -#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->lpVtbl->CopyRects(p,a,b,c,d,e) -#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) -#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->lpVtbl->GetFrontBuffer(p,a) -#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) -#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->lpVtbl->GetRenderTarget(p,a) -#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) -#define IDirect3DDevice8_BeginScene(p) (p)->lpVtbl->BeginScene(p) -#define IDirect3DDevice8_EndScene(p) (p)->lpVtbl->EndScene(p) -#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) -#define IDirect3DDevice8_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) -#define IDirect3DDevice8_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) -#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) -#define IDirect3DDevice8_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) -#define IDirect3DDevice8_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) -#define IDirect3DDevice8_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) -#define IDirect3DDevice8_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) -#define IDirect3DDevice8_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) -#define IDirect3DDevice8_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) -#define IDirect3DDevice8_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) -#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) -#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) -#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) -#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) -#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) -#define IDirect3DDevice8_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) -#define IDirect3DDevice8_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) -#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->lpVtbl->ApplyStateBlock(p,a) -#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->lpVtbl->CaptureStateBlock(p,a) -#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->lpVtbl->DeleteStateBlock(p,a) -#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) -#define IDirect3DDevice8_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) -#define IDirect3DDevice8_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) -#define IDirect3DDevice8_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) -#define IDirect3DDevice8_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) -#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) -#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) -#define IDirect3DDevice8_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) -#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->lpVtbl->GetInfo(p,a,b,c) -#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) -#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) -#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) -#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) -#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) -#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e) -#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) -#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) -#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e) -#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) -#define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) -#define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) -#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->lpVtbl->DeleteVertexShader(p,a) -#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c) -#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c) -#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c) -#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c) -#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->lpVtbl->SetStreamSource(p,a,b,c) -#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->lpVtbl->GetStreamSource(p,a,b,c) -#define IDirect3DDevice8_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b) -#define IDirect3DDevice8_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b) -#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) -#define IDirect3DDevice8_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) -#define IDirect3DDevice8_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) -#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->lpVtbl->DeletePixelShader(p,a) -#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c) -#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c) -#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c) -#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) -#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) -#define IDirect3DDevice8_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) -#else -#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DDevice8_AddRef(p) (p)->AddRef() -#define IDirect3DDevice8_Release(p) (p)->Release() -#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->TestCooperativeLevel() -#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() -#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->ResourceManagerDiscardBytes(a) -#define IDirect3DDevice8_GetDirect3D(p,a) (p)->GetDirect3D(a) -#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) -#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->GetDisplayMode(a) -#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->GetCreationParameters(a) -#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) -#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) -#define IDirect3DDevice8_ShowCursor(p,a) (p)->ShowCursor(a) -#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) -#define IDirect3DDevice8_Reset(p,a) (p)->Reset(a) -#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) -#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) -#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->GetRasterStatus(a) -#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b) -#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->GetGammaRamp(a) -#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->CreateTexture(a,b,c,d,e,f,g) -#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h) -#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->CreateCubeTexture(a,b,c,d,e,f) -#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->CreateVertexBuffer(a,b,c,d,e) -#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->CreateIndexBuffer(a,b,c,d,e) -#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->CreateRenderTarget(a,b,c,d,e,f) -#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->CreateDepthStencilSurface(a,b,c,d,e) -#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->CreateImageSurface(a,b,c,d) -#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->CopyRects(a,b,c,d,e) -#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) -#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->GetFrontBuffer(a) -#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) -#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->GetRenderTarget(a) -#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) -#define IDirect3DDevice8_BeginScene(p) (p)->BeginScene() -#define IDirect3DDevice8_EndScene(p) (p)->EndScene() -#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) -#define IDirect3DDevice8_SetTransform(p,a,b) (p)->SetTransform(a,b) -#define IDirect3DDevice8_GetTransform(p,a,b) (p)->GetTransform(a,b) -#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) -#define IDirect3DDevice8_SetViewport(p,a) (p)->SetViewport(a) -#define IDirect3DDevice8_GetViewport(p,a) (p)->GetViewport(a) -#define IDirect3DDevice8_SetMaterial(p,a) (p)->SetMaterial(a) -#define IDirect3DDevice8_GetMaterial(p,a) (p)->GetMaterial(a) -#define IDirect3DDevice8_SetLight(p,a,b) (p)->SetLight(a,b) -#define IDirect3DDevice8_GetLight(p,a,b) (p)->GetLight(a,b) -#define IDirect3DDevice8_LightEnable(p,a,b) (p)->LightEnable(a,b) -#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) -#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) -#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) -#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->SetRenderState(a,b) -#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->GetRenderState(a,b) -#define IDirect3DDevice8_BeginStateBlock(p) (p)->BeginStateBlock() -#define IDirect3DDevice8_EndStateBlock(p,a) (p)->EndStateBlock(a) -#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->ApplyStateBlock(a) -#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->CaptureStateBlock(a) -#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->DeleteStateBlock(a) -#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) -#define IDirect3DDevice8_SetClipStatus(p,a) (p)->SetClipStatus(a) -#define IDirect3DDevice8_GetClipStatus(p,a) (p)->GetClipStatus(a) -#define IDirect3DDevice8_GetTexture(p,a,b) (p)->GetTexture(a,b) -#define IDirect3DDevice8_SetTexture(p,a,b) (p)->SetTexture(a,b) -#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) -#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) -#define IDirect3DDevice8_ValidateDevice(p,a) (p)->ValidateDevice(a) -#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->GetInfo(a,b,c) -#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) -#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) -#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) -#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) -#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) -#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->DrawIndexedPrimitive(a,b,c,d,e) -#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) -#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) -#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->ProcessVertices(a,b,c,d,e) -#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->CreateVertexShader(a,b,c,d) -#define IDirect3DDevice8_SetVertexShader(p,a) (p)->SetVertexShader(a) -#define IDirect3DDevice8_GetVertexShader(p,a) (p)->GetVertexShader(a) -#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->DeleteVertexShader(a) -#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->SetVertexShaderConstant(a,b,c) -#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->GetVertexShaderConstant(a,b,c) -#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->GetVertexShaderDeclaration(a,b,c) -#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->GetVertexShaderFunction(a,b,c) -#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->SetStreamSource(a,b,c) -#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->GetStreamSource(a,b,c) -#define IDirect3DDevice8_SetIndices(p,a,b) (p)->SetIndices(a,b) -#define IDirect3DDevice8_GetIndices(p,a,b) (p)->GetIndices(a,b) -#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) -#define IDirect3DDevice8_SetPixelShader(p,a) (p)->SetPixelShader(a) -#define IDirect3DDevice8_GetPixelShader(p,a) (p)->GetPixelShader(a) -#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->DeletePixelShader(a) -#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->SetPixelShaderConstant(a,b,c) -#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->GetPixelShaderConstant(a,b,c) -#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->GetPixelShaderFunction(a,b,c) -#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) -#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) -#define IDirect3DDevice8_DeletePatch(p,a) (p)->DeletePatch(a) -#endif - - - -#undef INTERFACE -#define INTERFACE IDirect3DSwapChain8 - -DECLARE_INTERFACE_(IDirect3DSwapChain8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DSwapChain8 methods ***/ - STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; - STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; -}; - -typedef struct IDirect3DSwapChain8 *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DSwapChain8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DSwapChain8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) -#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) -#else -#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DSwapChain8_AddRef(p) (p)->AddRef() -#define IDirect3DSwapChain8_Release(p) (p)->Release() -#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) -#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) -#endif - - - -#undef INTERFACE -#define INTERFACE IDirect3DResource8 - -DECLARE_INTERFACE_(IDirect3DResource8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DResource8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; -}; - -typedef struct IDirect3DResource8 *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DResource8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DResource8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DResource8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DResource8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DResource8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DResource8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DResource8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DResource8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DResource8_GetType(p) (p)->lpVtbl->GetType(p) -#else -#define IDirect3DResource8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DResource8_AddRef(p) (p)->AddRef() -#define IDirect3DResource8_Release(p) (p)->Release() -#define IDirect3DResource8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DResource8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DResource8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DResource8_GetPriority(p) (p)->GetPriority() -#define IDirect3DResource8_PreLoad(p) (p)->PreLoad() -#define IDirect3DResource8_GetType(p) (p)->GetType() -#endif - - - - -#undef INTERFACE -#define INTERFACE IDirect3DBaseTexture8 - -DECLARE_INTERFACE_(IDirect3DBaseTexture8, IDirect3DResource8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DResource8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; - STDMETHOD_(DWORD, GetLOD)(THIS) PURE; - STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; -}; - -typedef struct IDirect3DBaseTexture8 *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DBaseTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DBaseTexture8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DBaseTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DBaseTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DBaseTexture8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) -#define IDirect3DBaseTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) -#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) -#else -#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DBaseTexture8_AddRef(p) (p)->AddRef() -#define IDirect3DBaseTexture8_Release(p) (p)->Release() -#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DBaseTexture8_GetPriority(p) (p)->GetPriority() -#define IDirect3DBaseTexture8_PreLoad(p) (p)->PreLoad() -#define IDirect3DBaseTexture8_GetType(p) (p)->GetType() -#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->SetLOD(a) -#define IDirect3DBaseTexture8_GetLOD(p) (p)->GetLOD() -#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->GetLevelCount() -#endif - - - - - -#undef INTERFACE -#define INTERFACE IDirect3DTexture8 - -DECLARE_INTERFACE_(IDirect3DTexture8, IDirect3DBaseTexture8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DBaseTexture8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; - STDMETHOD_(DWORD, GetLOD)(THIS) PURE; - STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; - STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; - STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface8** ppSurfaceLevel) PURE; - STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; - STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; - STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE; -}; - -typedef struct IDirect3DTexture8 *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DTexture8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DTexture8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) -#define IDirect3DTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) -#define IDirect3DTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) -#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) -#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) -#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d) -#define IDirect3DTexture8_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a) -#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) -#else -#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DTexture8_AddRef(p) (p)->AddRef() -#define IDirect3DTexture8_Release(p) (p)->Release() -#define IDirect3DTexture8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DTexture8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DTexture8_GetPriority(p) (p)->GetPriority() -#define IDirect3DTexture8_PreLoad(p) (p)->PreLoad() -#define IDirect3DTexture8_GetType(p) (p)->GetType() -#define IDirect3DTexture8_SetLOD(p,a) (p)->SetLOD(a) -#define IDirect3DTexture8_GetLOD(p) (p)->GetLOD() -#define IDirect3DTexture8_GetLevelCount(p) (p)->GetLevelCount() -#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) -#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b) -#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d) -#define IDirect3DTexture8_UnlockRect(p,a) (p)->UnlockRect(a) -#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->AddDirtyRect(a) -#endif - - - - - -#undef INTERFACE -#define INTERFACE IDirect3DVolumeTexture8 - -DECLARE_INTERFACE_(IDirect3DVolumeTexture8, IDirect3DBaseTexture8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DBaseTexture8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; - STDMETHOD_(DWORD, GetLOD)(THIS) PURE; - STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; - STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; - STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume8** ppVolumeLevel) PURE; - STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; - STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; - STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; -}; - -typedef struct IDirect3DVolumeTexture8 *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DVolumeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DVolumeTexture8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DVolumeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DVolumeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DVolumeTexture8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) -#define IDirect3DVolumeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) -#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) -#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) -#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) -#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d) -#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a) -#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) -#else -#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DVolumeTexture8_AddRef(p) (p)->AddRef() -#define IDirect3DVolumeTexture8_Release(p) (p)->Release() -#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DVolumeTexture8_GetPriority(p) (p)->GetPriority() -#define IDirect3DVolumeTexture8_PreLoad(p) (p)->PreLoad() -#define IDirect3DVolumeTexture8_GetType(p) (p)->GetType() -#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->SetLOD(a) -#define IDirect3DVolumeTexture8_GetLOD(p) (p)->GetLOD() -#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->GetLevelCount() -#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) -#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b) -#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d) -#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->UnlockBox(a) -#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->AddDirtyBox(a) -#endif - - - - - -#undef INTERFACE -#define INTERFACE IDirect3DCubeTexture8 - -DECLARE_INTERFACE_(IDirect3DCubeTexture8, IDirect3DBaseTexture8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DBaseTexture8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; - STDMETHOD_(DWORD, GetLOD)(THIS) PURE; - STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; - STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; - STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface8** ppCubeMapSurface) PURE; - STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; - STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; - STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT* pDirtyRect) PURE; -}; - -typedef struct IDirect3DCubeTexture8 *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DCubeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DCubeTexture8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DCubeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DCubeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DCubeTexture8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) -#define IDirect3DCubeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) -#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) -#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) -#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) -#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e) -#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b) -#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b) -#else -#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DCubeTexture8_AddRef(p) (p)->AddRef() -#define IDirect3DCubeTexture8_Release(p) (p)->Release() -#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DCubeTexture8_GetPriority(p) (p)->GetPriority() -#define IDirect3DCubeTexture8_PreLoad(p) (p)->PreLoad() -#define IDirect3DCubeTexture8_GetType(p) (p)->GetType() -#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->SetLOD(a) -#define IDirect3DCubeTexture8_GetLOD(p) (p)->GetLOD() -#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->GetLevelCount() -#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) -#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c) -#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e) -#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->UnlockRect(a,b) -#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b) -#endif - - - - -#undef INTERFACE -#define INTERFACE IDirect3DVertexBuffer8 - -DECLARE_INTERFACE_(IDirect3DVertexBuffer8, IDirect3DResource8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DResource8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; - STDMETHOD(Unlock)(THIS) PURE; - STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; -}; - -typedef struct IDirect3DVertexBuffer8 *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DVertexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DVertexBuffer8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DVertexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DVertexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DVertexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) -#define IDirect3DVertexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) -#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) -#else -#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DVertexBuffer8_AddRef(p) (p)->AddRef() -#define IDirect3DVertexBuffer8_Release(p) (p)->Release() -#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DVertexBuffer8_GetPriority(p) (p)->GetPriority() -#define IDirect3DVertexBuffer8_PreLoad(p) (p)->PreLoad() -#define IDirect3DVertexBuffer8_GetType(p) (p)->GetType() -#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) -#define IDirect3DVertexBuffer8_Unlock(p) (p)->Unlock() -#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->GetDesc(a) -#endif - - - - -#undef INTERFACE -#define INTERFACE IDirect3DIndexBuffer8 - -DECLARE_INTERFACE_(IDirect3DIndexBuffer8, IDirect3DResource8) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DResource8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; - STDMETHOD_(DWORD, GetPriority)(THIS) PURE; - STDMETHOD_(void, PreLoad)(THIS) PURE; - STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; - STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; - STDMETHOD(Unlock)(THIS) PURE; - STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; -}; - -typedef struct IDirect3DIndexBuffer8 *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DIndexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DIndexBuffer8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) -#define IDirect3DIndexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) -#define IDirect3DIndexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) -#define IDirect3DIndexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) -#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) -#define IDirect3DIndexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) -#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) -#else -#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DIndexBuffer8_AddRef(p) (p)->AddRef() -#define IDirect3DIndexBuffer8_Release(p) (p)->Release() -#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->SetPriority(a) -#define IDirect3DIndexBuffer8_GetPriority(p) (p)->GetPriority() -#define IDirect3DIndexBuffer8_PreLoad(p) (p)->PreLoad() -#define IDirect3DIndexBuffer8_GetType(p) (p)->GetType() -#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) -#define IDirect3DIndexBuffer8_Unlock(p) (p)->Unlock() -#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->GetDesc(a) -#endif - - - - -#undef INTERFACE -#define INTERFACE IDirect3DSurface8 - -DECLARE_INTERFACE_(IDirect3DSurface8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DSurface8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; - STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; - STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; - STDMETHOD(UnlockRect)(THIS) PURE; -}; - -typedef struct IDirect3DSurface8 *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DSurface8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DSurface8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DSurface8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DSurface8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DSurface8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) -#define IDirect3DSurface8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) -#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c) -#define IDirect3DSurface8_UnlockRect(p) (p)->lpVtbl->UnlockRect(p) -#else -#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DSurface8_AddRef(p) (p)->AddRef() -#define IDirect3DSurface8_Release(p) (p)->Release() -#define IDirect3DSurface8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DSurface8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DSurface8_GetContainer(p,a,b) (p)->GetContainer(a,b) -#define IDirect3DSurface8_GetDesc(p,a) (p)->GetDesc(a) -#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->LockRect(a,b,c) -#define IDirect3DSurface8_UnlockRect(p) (p)->UnlockRect() -#endif - - - - -#undef INTERFACE -#define INTERFACE IDirect3DVolume8 - -DECLARE_INTERFACE_(IDirect3DVolume8, IUnknown) -{ - /*** IUnknown methods ***/ - STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /*** IDirect3DVolume8 methods ***/ - STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; - STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; - STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; - STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC *pDesc) PURE; - STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; - STDMETHOD(UnlockBox)(THIS) PURE; -}; - -typedef struct IDirect3DVolume8 *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8; - -#if !defined(__cplusplus) || defined(CINTERFACE) -#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) -#define IDirect3DVolume8_AddRef(p) (p)->lpVtbl->AddRef(p) -#define IDirect3DVolume8_Release(p) (p)->lpVtbl->Release(p) -#define IDirect3DVolume8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) -#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) -#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) -#define IDirect3DVolume8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) -#define IDirect3DVolume8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) -#define IDirect3DVolume8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) -#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c) -#define IDirect3DVolume8_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) -#else -#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) -#define IDirect3DVolume8_AddRef(p) (p)->AddRef() -#define IDirect3DVolume8_Release(p) (p)->Release() -#define IDirect3DVolume8_GetDevice(p,a) (p)->GetDevice(a) -#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) -#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) -#define IDirect3DVolume8_FreePrivateData(p,a) (p)->FreePrivateData(a) -#define IDirect3DVolume8_GetContainer(p,a,b) (p)->GetContainer(a,b) -#define IDirect3DVolume8_GetDesc(p,a) (p)->GetDesc(a) -#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->LockBox(a,b,c) -#define IDirect3DVolume8_UnlockBox(p) (p)->UnlockBox() -#endif - -/**************************************************************************** - * Flags for SetPrivateData method on all D3D8 interfaces - * - * The passed pointer is an IUnknown ptr. The SizeOfData argument to SetPrivateData - * must be set to sizeof(IUnknown*). Direct3D will call AddRef through this - * pointer and Release when the private data is destroyed. The data will be - * destroyed when another SetPrivateData with the same GUID is set, when - * FreePrivateData is called, or when the D3D8 object is freed. - ****************************************************************************/ -#define D3DSPD_IUNKNOWN 0x00000001L - -/**************************************************************************** - * - * Parameter for IDirect3D8 Enum and GetCaps8 functions to get the info for - * the current mode only. - * - ****************************************************************************/ - -#define D3DCURRENT_DISPLAY_MODE 0x00EFFFFFL - -/**************************************************************************** - * - * Flags for IDirect3D8::CreateDevice's BehaviorFlags - * - ****************************************************************************/ - -#define D3DCREATE_FPU_PRESERVE 0x00000002L -#define D3DCREATE_MULTITHREADED 0x00000004L - -#define D3DCREATE_PUREDEVICE 0x00000010L -#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L -#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L -#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L - -#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100L - - -/**************************************************************************** - * - * Parameter for IDirect3D8::CreateDevice's iAdapter - * - ****************************************************************************/ - -#define D3DADAPTER_DEFAULT 0 - -/**************************************************************************** - * - * Flags for IDirect3D8::EnumAdapters - * - ****************************************************************************/ - -#define D3DENUM_NO_WHQL_LEVEL 0x00000002L - -/**************************************************************************** - * - * Maximum number of back-buffers supported in DX8 - * - ****************************************************************************/ - -#define D3DPRESENT_BACK_BUFFERS_MAX 3L - -/**************************************************************************** - * - * Flags for IDirect3DDevice8::SetGammaRamp - * - ****************************************************************************/ - -#define D3DSGR_NO_CALIBRATION 0x00000000L -#define D3DSGR_CALIBRATE 0x00000001L - -/**************************************************************************** - * - * Flags for IDirect3DDevice8::SetCursorPosition - * - ****************************************************************************/ - -#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L - -/**************************************************************************** - * - * Flags for DrawPrimitive/DrawIndexedPrimitive - * Also valid for Begin/BeginIndexed - * Also valid for VertexBuffer::CreateVertexBuffer - ****************************************************************************/ - - -/* - * DirectDraw error codes - */ -#define _FACD3D 0x876 -#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) - -/* - * Direct3D Errors - */ -#define D3D_OK S_OK - -#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072) -#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073) -#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074) -#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075) -#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076) -#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077) -#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078) -#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079) -#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081) -#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082) -#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086) -#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) - -#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) -#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151) -#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) -#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) -#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) -#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) -#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155) -#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) -#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157) - -#ifdef __cplusplus -}; -#endif - -#endif /* (DIRECT3D_VERSION >= 0x0800) */ -#endif /* _D3D_H_ */ - +/*==========================================================================; + * + * Copyright (C) Microsoft Corporation. All Rights Reserved. + * + * File: d3d8.h + * Content: Direct3D include file + * + ****************************************************************************/ + +#ifndef _D3D8_H_ +#define _D3D8_H_ + +#ifndef DIRECT3D_VERSION +#define DIRECT3D_VERSION 0x0800 +#endif //DIRECT3D_VERSION + +// include this file content only if compiling for DX8 interfaces +#if(DIRECT3D_VERSION >= 0x0800) + + +/* This identifier is passed to Direct3DCreate8 in order to ensure that an + * application was built against the correct header files. This number is + * incremented whenever a header (or other) change would require applications + * to be rebuilt. If the version doesn't match, Direct3DCreate8 will fail. + * (The number itself has no meaning.)*/ + +#define D3D_SDK_VERSION 220 + + +#include + +#define COM_NO_WINDOWS_H +#include + +#include + +#if !defined(HMONITOR_DECLARED) && (WINVER < 0x0500) + #define HMONITOR_DECLARED + DECLARE_HANDLE(HMONITOR); +#endif + +#define D3DAPI WINAPI + +/* + * Interface IID's + */ +#if defined( _WIN32 ) && !defined( _NO_COM) + +/* IID_IDirect3D8 */ +/* {1DD9E8DA-1C77-4d40-B0CF-98FEFDFF9512} */ +DEFINE_GUID(IID_IDirect3D8, 0x1dd9e8da, 0x1c77, 0x4d40, 0xb0, 0xcf, 0x98, 0xfe, 0xfd, 0xff, 0x95, 0x12); + +/* IID_IDirect3DDevice8 */ +/* {7385E5DF-8FE8-41D5-86B6-D7B48547B6CF} */ +DEFINE_GUID(IID_IDirect3DDevice8, 0x7385e5df, 0x8fe8, 0x41d5, 0x86, 0xb6, 0xd7, 0xb4, 0x85, 0x47, 0xb6, 0xcf); + +/* IID_IDirect3DResource8 */ +/* {1B36BB7B-09B7-410a-B445-7D1430D7B33F} */ +DEFINE_GUID(IID_IDirect3DResource8, 0x1b36bb7b, 0x9b7, 0x410a, 0xb4, 0x45, 0x7d, 0x14, 0x30, 0xd7, 0xb3, 0x3f); + +/* IID_IDirect3DBaseTexture8 */ +/* {B4211CFA-51B9-4a9f-AB78-DB99B2BB678E} */ +DEFINE_GUID(IID_IDirect3DBaseTexture8, 0xb4211cfa, 0x51b9, 0x4a9f, 0xab, 0x78, 0xdb, 0x99, 0xb2, 0xbb, 0x67, 0x8e); + +/* IID_IDirect3DTexture8 */ +/* {E4CDD575-2866-4f01-B12E-7EECE1EC9358} */ +DEFINE_GUID(IID_IDirect3DTexture8, 0xe4cdd575, 0x2866, 0x4f01, 0xb1, 0x2e, 0x7e, 0xec, 0xe1, 0xec, 0x93, 0x58); + +/* IID_IDirect3DCubeTexture8 */ +/* {3EE5B968-2ACA-4c34-8BB5-7E0C3D19B750} */ +DEFINE_GUID(IID_IDirect3DCubeTexture8, 0x3ee5b968, 0x2aca, 0x4c34, 0x8b, 0xb5, 0x7e, 0x0c, 0x3d, 0x19, 0xb7, 0x50); + +/* IID_IDirect3DVolumeTexture8 */ +/* {4B8AAAFA-140F-42ba-9131-597EAFAA2EAD} */ +DEFINE_GUID(IID_IDirect3DVolumeTexture8, 0x4b8aaafa, 0x140f, 0x42ba, 0x91, 0x31, 0x59, 0x7e, 0xaf, 0xaa, 0x2e, 0xad); + +/* IID_IDirect3DVertexBuffer8 */ +/* {8AEEEAC7-05F9-44d4-B591-000B0DF1CB95} */ +DEFINE_GUID(IID_IDirect3DVertexBuffer8, 0x8aeeeac7, 0x05f9, 0x44d4, 0xb5, 0x91, 0x00, 0x0b, 0x0d, 0xf1, 0xcb, 0x95); + +/* IID_IDirect3DIndexBuffer8 */ +/* {0E689C9A-053D-44a0-9D92-DB0E3D750F86} */ +DEFINE_GUID(IID_IDirect3DIndexBuffer8, 0x0e689c9a, 0x053d, 0x44a0, 0x9d, 0x92, 0xdb, 0x0e, 0x3d, 0x75, 0x0f, 0x86); + +/* IID_IDirect3DSurface8 */ +/* {B96EEBCA-B326-4ea5-882F-2FF5BAE021DD} */ +DEFINE_GUID(IID_IDirect3DSurface8, 0xb96eebca, 0xb326, 0x4ea5, 0x88, 0x2f, 0x2f, 0xf5, 0xba, 0xe0, 0x21, 0xdd); + +/* IID_IDirect3DVolume8 */ +/* {BD7349F5-14F1-42e4-9C79-972380DB40C0} */ +DEFINE_GUID(IID_IDirect3DVolume8, 0xbd7349f5, 0x14f1, 0x42e4, 0x9c, 0x79, 0x97, 0x23, 0x80, 0xdb, 0x40, 0xc0); + +/* IID_IDirect3DSwapChain8 */ +/* {928C088B-76B9-4C6B-A536-A590853876CD} */ +DEFINE_GUID(IID_IDirect3DSwapChain8, 0x928c088b, 0x76b9, 0x4c6b, 0xa5, 0x36, 0xa5, 0x90, 0x85, 0x38, 0x76, 0xcd); + +#endif + +#ifdef __cplusplus + +interface IDirect3D8; +interface IDirect3DDevice8; + +interface IDirect3DResource8; +interface IDirect3DBaseTexture8; +interface IDirect3DTexture8; +interface IDirect3DVolumeTexture8; +interface IDirect3DCubeTexture8; + +interface IDirect3DVertexBuffer8; +interface IDirect3DIndexBuffer8; + +interface IDirect3DSurface8; +interface IDirect3DVolume8; + +interface IDirect3DSwapChain8; + +#endif + + +typedef interface IDirect3D8 IDirect3D8; +typedef interface IDirect3DDevice8 IDirect3DDevice8; +typedef interface IDirect3DResource8 IDirect3DResource8; +typedef interface IDirect3DBaseTexture8 IDirect3DBaseTexture8; +typedef interface IDirect3DTexture8 IDirect3DTexture8; +typedef interface IDirect3DVolumeTexture8 IDirect3DVolumeTexture8; +typedef interface IDirect3DCubeTexture8 IDirect3DCubeTexture8; +typedef interface IDirect3DVertexBuffer8 IDirect3DVertexBuffer8; +typedef interface IDirect3DIndexBuffer8 IDirect3DIndexBuffer8; +typedef interface IDirect3DSurface8 IDirect3DSurface8; +typedef interface IDirect3DVolume8 IDirect3DVolume8; +typedef interface IDirect3DSwapChain8 IDirect3DSwapChain8; + +#include "d3d8types.h" +#include "d3d8caps.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * DLL Function for creating a Direct3D8 object. This object supports + * enumeration and allows the creation of Direct3DDevice8 objects. + * Pass the value of the constant D3D_SDK_VERSION to this function, so + * that the run-time can validate that your application was compiled + * against the right headers. + */ + +IDirect3D8 * WINAPI Direct3DCreate8(UINT SDKVersion); + + +/* + * Direct3D interfaces + */ + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3D8 + +DECLARE_INTERFACE_(IDirect3D8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3D8 methods ***/ + STDMETHOD(RegisterSoftwareDevice)(THIS_ void* pInitializeFunction) PURE; + STDMETHOD_(UINT, GetAdapterCount)(THIS) PURE; + STDMETHOD(GetAdapterIdentifier)(THIS_ UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER8* pIdentifier) PURE; + STDMETHOD_(UINT, GetAdapterModeCount)(THIS_ UINT Adapter) PURE; + STDMETHOD(EnumAdapterModes)(THIS_ UINT Adapter,UINT Mode,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetAdapterDisplayMode)(THIS_ UINT Adapter,D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(CheckDeviceType)(THIS_ UINT Adapter,D3DDEVTYPE CheckType,D3DFORMAT DisplayFormat,D3DFORMAT BackBufferFormat,BOOL Windowed) PURE; + STDMETHOD(CheckDeviceFormat)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) PURE; + STDMETHOD(CheckDeviceMultiSampleType)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType) PURE; + STDMETHOD(CheckDepthStencilMatch)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS8* pCaps) PURE; + STDMETHOD_(HMONITOR, GetAdapterMonitor)(THIS_ UINT Adapter) PURE; + STDMETHOD(CreateDevice)(THIS_ UINT Adapter,D3DDEVTYPE DeviceType,HWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice8** ppReturnedDeviceInterface) PURE; +}; + +typedef struct IDirect3D8 *LPDIRECT3D8, *PDIRECT3D8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3D8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3D8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3D8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->lpVtbl->RegisterSoftwareDevice(p,a) +#define IDirect3D8_GetAdapterCount(p) (p)->lpVtbl->GetAdapterCount(p) +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->lpVtbl->GetAdapterIdentifier(p,a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->lpVtbl->GetAdapterModeCount(p,a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->lpVtbl->EnumAdapterModes(p,a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->lpVtbl->GetAdapterDisplayMode(p,a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceType(p,a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->lpVtbl->CheckDeviceFormat(p,a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->lpVtbl->CheckDeviceMultiSampleType(p,a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->lpVtbl->CheckDepthStencilMatch(p,a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->lpVtbl->GetDeviceCaps(p,a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->lpVtbl->GetAdapterMonitor(p,a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->lpVtbl->CreateDevice(p,a,b,c,d,e,f) +#else +#define IDirect3D8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3D8_AddRef(p) (p)->AddRef() +#define IDirect3D8_Release(p) (p)->Release() +#define IDirect3D8_RegisterSoftwareDevice(p,a) (p)->RegisterSoftwareDevice(a) +#define IDirect3D8_GetAdapterCount(p) (p)->GetAdapterCount() +#define IDirect3D8_GetAdapterIdentifier(p,a,b,c) (p)->GetAdapterIdentifier(a,b,c) +#define IDirect3D8_GetAdapterModeCount(p,a) (p)->GetAdapterModeCount(a) +#define IDirect3D8_EnumAdapterModes(p,a,b,c) (p)->EnumAdapterModes(a,b,c) +#define IDirect3D8_GetAdapterDisplayMode(p,a,b) (p)->GetAdapterDisplayMode(a,b) +#define IDirect3D8_CheckDeviceType(p,a,b,c,d,e) (p)->CheckDeviceType(a,b,c,d,e) +#define IDirect3D8_CheckDeviceFormat(p,a,b,c,d,e,f) (p)->CheckDeviceFormat(a,b,c,d,e,f) +#define IDirect3D8_CheckDeviceMultiSampleType(p,a,b,c,d,e) (p)->CheckDeviceMultiSampleType(a,b,c,d,e) +#define IDirect3D8_CheckDepthStencilMatch(p,a,b,c,d,e) (p)->CheckDepthStencilMatch(a,b,c,d,e) +#define IDirect3D8_GetDeviceCaps(p,a,b,c) (p)->GetDeviceCaps(a,b,c) +#define IDirect3D8_GetAdapterMonitor(p,a) (p)->GetAdapterMonitor(a) +#define IDirect3D8_CreateDevice(p,a,b,c,d,e,f) (p)->CreateDevice(a,b,c,d,e,f) +#endif + + + + + + + + + + + + + + + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DDevice8 + +DECLARE_INTERFACE_(IDirect3DDevice8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DDevice8 methods ***/ + STDMETHOD(TestCooperativeLevel)(THIS) PURE; + STDMETHOD_(UINT, GetAvailableTextureMem)(THIS) PURE; + STDMETHOD(ResourceManagerDiscardBytes)(THIS_ DWORD Bytes) PURE; + STDMETHOD(GetDirect3D)(THIS_ IDirect3D8** ppD3D8) PURE; + STDMETHOD(GetDeviceCaps)(THIS_ D3DCAPS8* pCaps) PURE; + STDMETHOD(GetDisplayMode)(THIS_ D3DDISPLAYMODE* pMode) PURE; + STDMETHOD(GetCreationParameters)(THIS_ D3DDEVICE_CREATION_PARAMETERS *pParameters) PURE; + STDMETHOD(SetCursorProperties)(THIS_ UINT XHotSpot,UINT YHotSpot,IDirect3DSurface8* pCursorBitmap) PURE; + STDMETHOD_(void, SetCursorPosition)(THIS_ int X,int Y,DWORD Flags) PURE; + STDMETHOD_(BOOL, ShowCursor)(THIS_ BOOL bShow) PURE; + STDMETHOD(CreateAdditionalSwapChain)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DSwapChain8** pSwapChain) PURE; + STDMETHOD(Reset)(THIS_ D3DPRESENT_PARAMETERS* pPresentationParameters) PURE; + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; + STDMETHOD(GetRasterStatus)(THIS_ D3DRASTER_STATUS* pRasterStatus) PURE; + STDMETHOD_(void, SetGammaRamp)(THIS_ DWORD Flags,CONST D3DGAMMARAMP* pRamp) PURE; + STDMETHOD_(void, GetGammaRamp)(THIS_ D3DGAMMARAMP* pRamp) PURE; + STDMETHOD(CreateTexture)(THIS_ UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture8** ppTexture) PURE; + STDMETHOD(CreateVolumeTexture)(THIS_ UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture8** ppVolumeTexture) PURE; + STDMETHOD(CreateCubeTexture)(THIS_ UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture8** ppCubeTexture) PURE; + STDMETHOD(CreateVertexBuffer)(THIS_ UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer8** ppVertexBuffer) PURE; + STDMETHOD(CreateIndexBuffer)(THIS_ UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer8** ppIndexBuffer) PURE; + STDMETHOD(CreateRenderTarget)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,BOOL Lockable,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateDepthStencilSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CreateImageSurface)(THIS_ UINT Width,UINT Height,D3DFORMAT Format,IDirect3DSurface8** ppSurface) PURE; + STDMETHOD(CopyRects)(THIS_ IDirect3DSurface8* pSourceSurface,CONST RECT* pSourceRectsArray,UINT cRects,IDirect3DSurface8* pDestinationSurface,CONST POINT* pDestPointsArray) PURE; + STDMETHOD(UpdateTexture)(THIS_ IDirect3DBaseTexture8* pSourceTexture,IDirect3DBaseTexture8* pDestinationTexture) PURE; + STDMETHOD(GetFrontBuffer)(THIS_ IDirect3DSurface8* pDestSurface) PURE; + STDMETHOD(SetRenderTarget)(THIS_ IDirect3DSurface8* pRenderTarget,IDirect3DSurface8* pNewZStencil) PURE; + STDMETHOD(GetRenderTarget)(THIS_ IDirect3DSurface8** ppRenderTarget) PURE; + STDMETHOD(GetDepthStencilSurface)(THIS_ IDirect3DSurface8** ppZStencilSurface) PURE; + STDMETHOD(BeginScene)(THIS) PURE; + STDMETHOD(EndScene)(THIS) PURE; + STDMETHOD(Clear)(THIS_ DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) PURE; + STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) PURE; + STDMETHOD(GetTransform)(THIS_ D3DTRANSFORMSTATETYPE State,D3DMATRIX* pMatrix) PURE; + STDMETHOD(MultiplyTransform)(THIS_ D3DTRANSFORMSTATETYPE,CONST D3DMATRIX*) PURE; + STDMETHOD(SetViewport)(THIS_ CONST D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(GetViewport)(THIS_ D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(SetMaterial)(THIS_ CONST D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(GetMaterial)(THIS_ D3DMATERIAL8* pMaterial) PURE; + STDMETHOD(SetLight)(THIS_ DWORD Index,CONST D3DLIGHT8*) PURE; + STDMETHOD(GetLight)(THIS_ DWORD Index,D3DLIGHT8*) PURE; + STDMETHOD(LightEnable)(THIS_ DWORD Index,BOOL Enable) PURE; + STDMETHOD(GetLightEnable)(THIS_ DWORD Index,BOOL* pEnable) PURE; + STDMETHOD(SetClipPlane)(THIS_ DWORD Index,CONST float* pPlane) PURE; + STDMETHOD(GetClipPlane)(THIS_ DWORD Index,float* pPlane) PURE; + STDMETHOD(SetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD Value) PURE; + STDMETHOD(GetRenderState)(THIS_ D3DRENDERSTATETYPE State,DWORD* pValue) PURE; + STDMETHOD(BeginStateBlock)(THIS) PURE; + STDMETHOD(EndStateBlock)(THIS_ DWORD* pToken) PURE; + STDMETHOD(ApplyStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CaptureStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(DeleteStateBlock)(THIS_ DWORD Token) PURE; + STDMETHOD(CreateStateBlock)(THIS_ D3DSTATEBLOCKTYPE Type,DWORD* pToken) PURE; + STDMETHOD(SetClipStatus)(THIS_ CONST D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetClipStatus)(THIS_ D3DCLIPSTATUS8* pClipStatus) PURE; + STDMETHOD(GetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8** ppTexture) PURE; + STDMETHOD(SetTexture)(THIS_ DWORD Stage,IDirect3DBaseTexture8* pTexture) PURE; + STDMETHOD(GetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD* pValue) PURE; + STDMETHOD(SetTextureStageState)(THIS_ DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) PURE; + STDMETHOD(ValidateDevice)(THIS_ DWORD* pNumPasses) PURE; + STDMETHOD(GetInfo)(THIS_ DWORD DevInfoID,void* pDevInfoStruct,DWORD DevInfoStructSize) PURE; + STDMETHOD(SetPaletteEntries)(THIS_ UINT PaletteNumber,CONST PALETTEENTRY* pEntries) PURE; + STDMETHOD(GetPaletteEntries)(THIS_ UINT PaletteNumber,PALETTEENTRY* pEntries) PURE; + STDMETHOD(SetCurrentTexturePalette)(THIS_ UINT PaletteNumber) PURE; + STDMETHOD(GetCurrentTexturePalette)(THIS_ UINT *PaletteNumber) PURE; + STDMETHOD(DrawPrimitive)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) PURE; + STDMETHOD(DrawIndexedPrimitive)(THIS_ D3DPRIMITIVETYPE,UINT minIndex,UINT NumVertices,UINT startIndex,UINT primCount) PURE; + STDMETHOD(DrawPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCount,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(DrawIndexedPrimitiveUP)(THIS_ D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertexIndices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) PURE; + STDMETHOD(ProcessVertices)(THIS_ UINT SrcStartIndex,UINT DestIndex,UINT VertexCount,IDirect3DVertexBuffer8* pDestBuffer,DWORD Flags) PURE; + STDMETHOD(CreateVertexShader)(THIS_ CONST DWORD* pDeclaration,CONST DWORD* pFunction,DWORD* pHandle,DWORD Usage) PURE; + STDMETHOD(SetVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetVertexShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeleteVertexShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetVertexShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetVertexShaderDeclaration)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(GetVertexShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(SetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8* pStreamData,UINT Stride) PURE; + STDMETHOD(GetStreamSource)(THIS_ UINT StreamNumber,IDirect3DVertexBuffer8** ppStreamData,UINT* pStride) PURE; + STDMETHOD(SetIndices)(THIS_ IDirect3DIndexBuffer8* pIndexData,UINT BaseVertexIndex) PURE; + STDMETHOD(GetIndices)(THIS_ IDirect3DIndexBuffer8** ppIndexData,UINT* pBaseVertexIndex) PURE; + STDMETHOD(CreatePixelShader)(THIS_ CONST DWORD* pFunction,DWORD* pHandle) PURE; + STDMETHOD(SetPixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(GetPixelShader)(THIS_ DWORD* pHandle) PURE; + STDMETHOD(DeletePixelShader)(THIS_ DWORD Handle) PURE; + STDMETHOD(SetPixelShaderConstant)(THIS_ DWORD Register,CONST void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderConstant)(THIS_ DWORD Register,void* pConstantData,DWORD ConstantCount) PURE; + STDMETHOD(GetPixelShaderFunction)(THIS_ DWORD Handle,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(DrawRectPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DRECTPATCH_INFO* pRectPatchInfo) PURE; + STDMETHOD(DrawTriPatch)(THIS_ UINT Handle,CONST float* pNumSegs,CONST D3DTRIPATCH_INFO* pTriPatchInfo) PURE; + STDMETHOD(DeletePatch)(THIS_ UINT Handle) PURE; +}; + +typedef struct IDirect3DDevice8 *LPDIRECT3DDEVICE8, *PDIRECT3DDEVICE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DDevice8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DDevice8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->lpVtbl->TestCooperativeLevel(p) +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->lpVtbl->GetAvailableTextureMem(p) +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->lpVtbl->ResourceManagerDiscardBytes(p,a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->lpVtbl->GetDirect3D(p,a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->lpVtbl->GetDeviceCaps(p,a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->lpVtbl->GetDisplayMode(p,a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->lpVtbl->GetCreationParameters(p,a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->lpVtbl->SetCursorProperties(p,a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->lpVtbl->SetCursorPosition(p,a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->lpVtbl->ShowCursor(p,a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->lpVtbl->CreateAdditionalSwapChain(p,a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->lpVtbl->Reset(p,a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->lpVtbl->GetRasterStatus(p,a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->lpVtbl->SetGammaRamp(p,a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->lpVtbl->GetGammaRamp(p,a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->lpVtbl->CreateTexture(p,a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->CreateVolumeTexture(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->lpVtbl->CreateCubeTexture(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateVertexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->lpVtbl->CreateIndexBuffer(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->lpVtbl->CreateRenderTarget(p,a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->lpVtbl->CreateDepthStencilSurface(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->lpVtbl->CreateImageSurface(p,a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->lpVtbl->CopyRects(p,a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->lpVtbl->UpdateTexture(p,a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->lpVtbl->GetFrontBuffer(p,a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->lpVtbl->SetRenderTarget(p,a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->lpVtbl->GetRenderTarget(p,a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->lpVtbl->GetDepthStencilSurface(p,a) +#define IDirect3DDevice8_BeginScene(p) (p)->lpVtbl->BeginScene(p) +#define IDirect3DDevice8_EndScene(p) (p)->lpVtbl->EndScene(p) +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->lpVtbl->Clear(p,a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->lpVtbl->SetTransform(p,a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->lpVtbl->GetTransform(p,a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->lpVtbl->MultiplyTransform(p,a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->lpVtbl->SetViewport(p,a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->lpVtbl->GetViewport(p,a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->lpVtbl->SetMaterial(p,a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->lpVtbl->GetMaterial(p,a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->lpVtbl->SetLight(p,a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->lpVtbl->GetLight(p,a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->lpVtbl->LightEnable(p,a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->lpVtbl->GetLightEnable(p,a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->lpVtbl->SetClipPlane(p,a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->lpVtbl->GetClipPlane(p,a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->lpVtbl->SetRenderState(p,a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->lpVtbl->GetRenderState(p,a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->lpVtbl->BeginStateBlock(p) +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->lpVtbl->EndStateBlock(p,a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->lpVtbl->ApplyStateBlock(p,a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->lpVtbl->CaptureStateBlock(p,a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->lpVtbl->DeleteStateBlock(p,a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->lpVtbl->CreateStateBlock(p,a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->lpVtbl->SetClipStatus(p,a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->lpVtbl->GetClipStatus(p,a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->lpVtbl->GetTexture(p,a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->lpVtbl->SetTexture(p,a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->lpVtbl->GetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->lpVtbl->SetTextureStageState(p,a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->lpVtbl->ValidateDevice(p,a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->lpVtbl->GetInfo(p,a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->lpVtbl->SetPaletteEntries(p,a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->lpVtbl->GetPaletteEntries(p,a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->lpVtbl->SetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->lpVtbl->GetCurrentTexturePalette(p,a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->lpVtbl->DrawPrimitive(p,a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->lpVtbl->DrawIndexedPrimitive(p,a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->lpVtbl->DrawPrimitiveUP(p,a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->lpVtbl->DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->lpVtbl->ProcessVertices(p,a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->lpVtbl->CreateVertexShader(p,a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->lpVtbl->SetVertexShader(p,a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->lpVtbl->GetVertexShader(p,a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->lpVtbl->DeleteVertexShader(p,a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->SetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->lpVtbl->GetVertexShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->lpVtbl->GetVertexShaderDeclaration(p,a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->lpVtbl->GetVertexShaderFunction(p,a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->lpVtbl->SetStreamSource(p,a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->lpVtbl->GetStreamSource(p,a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->lpVtbl->SetIndices(p,a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->lpVtbl->GetIndices(p,a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->lpVtbl->CreatePixelShader(p,a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->lpVtbl->SetPixelShader(p,a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->lpVtbl->GetPixelShader(p,a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->lpVtbl->DeletePixelShader(p,a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->SetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->lpVtbl->GetPixelShaderConstant(p,a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->lpVtbl->GetPixelShaderFunction(p,a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->lpVtbl->DrawRectPatch(p,a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->lpVtbl->DrawTriPatch(p,a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->lpVtbl->DeletePatch(p,a) +#else +#define IDirect3DDevice8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DDevice8_AddRef(p) (p)->AddRef() +#define IDirect3DDevice8_Release(p) (p)->Release() +#define IDirect3DDevice8_TestCooperativeLevel(p) (p)->TestCooperativeLevel() +#define IDirect3DDevice8_GetAvailableTextureMem(p) (p)->GetAvailableTextureMem() +#define IDirect3DDevice8_ResourceManagerDiscardBytes(p,a) (p)->ResourceManagerDiscardBytes(a) +#define IDirect3DDevice8_GetDirect3D(p,a) (p)->GetDirect3D(a) +#define IDirect3DDevice8_GetDeviceCaps(p,a) (p)->GetDeviceCaps(a) +#define IDirect3DDevice8_GetDisplayMode(p,a) (p)->GetDisplayMode(a) +#define IDirect3DDevice8_GetCreationParameters(p,a) (p)->GetCreationParameters(a) +#define IDirect3DDevice8_SetCursorProperties(p,a,b,c) (p)->SetCursorProperties(a,b,c) +#define IDirect3DDevice8_SetCursorPosition(p,a,b,c) (p)->SetCursorPosition(a,b,c) +#define IDirect3DDevice8_ShowCursor(p,a) (p)->ShowCursor(a) +#define IDirect3DDevice8_CreateAdditionalSwapChain(p,a,b) (p)->CreateAdditionalSwapChain(a,b) +#define IDirect3DDevice8_Reset(p,a) (p)->Reset(a) +#define IDirect3DDevice8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DDevice8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#define IDirect3DDevice8_GetRasterStatus(p,a) (p)->GetRasterStatus(a) +#define IDirect3DDevice8_SetGammaRamp(p,a,b) (p)->SetGammaRamp(a,b) +#define IDirect3DDevice8_GetGammaRamp(p,a) (p)->GetGammaRamp(a) +#define IDirect3DDevice8_CreateTexture(p,a,b,c,d,e,f,g) (p)->CreateTexture(a,b,c,d,e,f,g) +#define IDirect3DDevice8_CreateVolumeTexture(p,a,b,c,d,e,f,g,h) (p)->CreateVolumeTexture(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_CreateCubeTexture(p,a,b,c,d,e,f) (p)->CreateCubeTexture(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateVertexBuffer(p,a,b,c,d,e) (p)->CreateVertexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateIndexBuffer(p,a,b,c,d,e) (p)->CreateIndexBuffer(a,b,c,d,e) +#define IDirect3DDevice8_CreateRenderTarget(p,a,b,c,d,e,f) (p)->CreateRenderTarget(a,b,c,d,e,f) +#define IDirect3DDevice8_CreateDepthStencilSurface(p,a,b,c,d,e) (p)->CreateDepthStencilSurface(a,b,c,d,e) +#define IDirect3DDevice8_CreateImageSurface(p,a,b,c,d) (p)->CreateImageSurface(a,b,c,d) +#define IDirect3DDevice8_CopyRects(p,a,b,c,d,e) (p)->CopyRects(a,b,c,d,e) +#define IDirect3DDevice8_UpdateTexture(p,a,b) (p)->UpdateTexture(a,b) +#define IDirect3DDevice8_GetFrontBuffer(p,a) (p)->GetFrontBuffer(a) +#define IDirect3DDevice8_SetRenderTarget(p,a,b) (p)->SetRenderTarget(a,b) +#define IDirect3DDevice8_GetRenderTarget(p,a) (p)->GetRenderTarget(a) +#define IDirect3DDevice8_GetDepthStencilSurface(p,a) (p)->GetDepthStencilSurface(a) +#define IDirect3DDevice8_BeginScene(p) (p)->BeginScene() +#define IDirect3DDevice8_EndScene(p) (p)->EndScene() +#define IDirect3DDevice8_Clear(p,a,b,c,d,e,f) (p)->Clear(a,b,c,d,e,f) +#define IDirect3DDevice8_SetTransform(p,a,b) (p)->SetTransform(a,b) +#define IDirect3DDevice8_GetTransform(p,a,b) (p)->GetTransform(a,b) +#define IDirect3DDevice8_MultiplyTransform(p,a,b) (p)->MultiplyTransform(a,b) +#define IDirect3DDevice8_SetViewport(p,a) (p)->SetViewport(a) +#define IDirect3DDevice8_GetViewport(p,a) (p)->GetViewport(a) +#define IDirect3DDevice8_SetMaterial(p,a) (p)->SetMaterial(a) +#define IDirect3DDevice8_GetMaterial(p,a) (p)->GetMaterial(a) +#define IDirect3DDevice8_SetLight(p,a,b) (p)->SetLight(a,b) +#define IDirect3DDevice8_GetLight(p,a,b) (p)->GetLight(a,b) +#define IDirect3DDevice8_LightEnable(p,a,b) (p)->LightEnable(a,b) +#define IDirect3DDevice8_GetLightEnable(p,a,b) (p)->GetLightEnable(a,b) +#define IDirect3DDevice8_SetClipPlane(p,a,b) (p)->SetClipPlane(a,b) +#define IDirect3DDevice8_GetClipPlane(p,a,b) (p)->GetClipPlane(a,b) +#define IDirect3DDevice8_SetRenderState(p,a,b) (p)->SetRenderState(a,b) +#define IDirect3DDevice8_GetRenderState(p,a,b) (p)->GetRenderState(a,b) +#define IDirect3DDevice8_BeginStateBlock(p) (p)->BeginStateBlock() +#define IDirect3DDevice8_EndStateBlock(p,a) (p)->EndStateBlock(a) +#define IDirect3DDevice8_ApplyStateBlock(p,a) (p)->ApplyStateBlock(a) +#define IDirect3DDevice8_CaptureStateBlock(p,a) (p)->CaptureStateBlock(a) +#define IDirect3DDevice8_DeleteStateBlock(p,a) (p)->DeleteStateBlock(a) +#define IDirect3DDevice8_CreateStateBlock(p,a,b) (p)->CreateStateBlock(a,b) +#define IDirect3DDevice8_SetClipStatus(p,a) (p)->SetClipStatus(a) +#define IDirect3DDevice8_GetClipStatus(p,a) (p)->GetClipStatus(a) +#define IDirect3DDevice8_GetTexture(p,a,b) (p)->GetTexture(a,b) +#define IDirect3DDevice8_SetTexture(p,a,b) (p)->SetTexture(a,b) +#define IDirect3DDevice8_GetTextureStageState(p,a,b,c) (p)->GetTextureStageState(a,b,c) +#define IDirect3DDevice8_SetTextureStageState(p,a,b,c) (p)->SetTextureStageState(a,b,c) +#define IDirect3DDevice8_ValidateDevice(p,a) (p)->ValidateDevice(a) +#define IDirect3DDevice8_GetInfo(p,a,b,c) (p)->GetInfo(a,b,c) +#define IDirect3DDevice8_SetPaletteEntries(p,a,b) (p)->SetPaletteEntries(a,b) +#define IDirect3DDevice8_GetPaletteEntries(p,a,b) (p)->GetPaletteEntries(a,b) +#define IDirect3DDevice8_SetCurrentTexturePalette(p,a) (p)->SetCurrentTexturePalette(a) +#define IDirect3DDevice8_GetCurrentTexturePalette(p,a) (p)->GetCurrentTexturePalette(a) +#define IDirect3DDevice8_DrawPrimitive(p,a,b,c) (p)->DrawPrimitive(a,b,c) +#define IDirect3DDevice8_DrawIndexedPrimitive(p,a,b,c,d,e) (p)->DrawIndexedPrimitive(a,b,c,d,e) +#define IDirect3DDevice8_DrawPrimitiveUP(p,a,b,c,d) (p)->DrawPrimitiveUP(a,b,c,d) +#define IDirect3DDevice8_DrawIndexedPrimitiveUP(p,a,b,c,d,e,f,g,h) (p)->DrawIndexedPrimitiveUP(a,b,c,d,e,f,g,h) +#define IDirect3DDevice8_ProcessVertices(p,a,b,c,d,e) (p)->ProcessVertices(a,b,c,d,e) +#define IDirect3DDevice8_CreateVertexShader(p,a,b,c,d) (p)->CreateVertexShader(a,b,c,d) +#define IDirect3DDevice8_SetVertexShader(p,a) (p)->SetVertexShader(a) +#define IDirect3DDevice8_GetVertexShader(p,a) (p)->GetVertexShader(a) +#define IDirect3DDevice8_DeleteVertexShader(p,a) (p)->DeleteVertexShader(a) +#define IDirect3DDevice8_SetVertexShaderConstant(p,a,b,c) (p)->SetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderConstant(p,a,b,c) (p)->GetVertexShaderConstant(a,b,c) +#define IDirect3DDevice8_GetVertexShaderDeclaration(p,a,b,c) (p)->GetVertexShaderDeclaration(a,b,c) +#define IDirect3DDevice8_GetVertexShaderFunction(p,a,b,c) (p)->GetVertexShaderFunction(a,b,c) +#define IDirect3DDevice8_SetStreamSource(p,a,b,c) (p)->SetStreamSource(a,b,c) +#define IDirect3DDevice8_GetStreamSource(p,a,b,c) (p)->GetStreamSource(a,b,c) +#define IDirect3DDevice8_SetIndices(p,a,b) (p)->SetIndices(a,b) +#define IDirect3DDevice8_GetIndices(p,a,b) (p)->GetIndices(a,b) +#define IDirect3DDevice8_CreatePixelShader(p,a,b) (p)->CreatePixelShader(a,b) +#define IDirect3DDevice8_SetPixelShader(p,a) (p)->SetPixelShader(a) +#define IDirect3DDevice8_GetPixelShader(p,a) (p)->GetPixelShader(a) +#define IDirect3DDevice8_DeletePixelShader(p,a) (p)->DeletePixelShader(a) +#define IDirect3DDevice8_SetPixelShaderConstant(p,a,b,c) (p)->SetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderConstant(p,a,b,c) (p)->GetPixelShaderConstant(a,b,c) +#define IDirect3DDevice8_GetPixelShaderFunction(p,a,b,c) (p)->GetPixelShaderFunction(a,b,c) +#define IDirect3DDevice8_DrawRectPatch(p,a,b,c) (p)->DrawRectPatch(a,b,c) +#define IDirect3DDevice8_DrawTriPatch(p,a,b,c) (p)->DrawTriPatch(a,b,c) +#define IDirect3DDevice8_DeletePatch(p,a) (p)->DeletePatch(a) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DSwapChain8 + +DECLARE_INTERFACE_(IDirect3DSwapChain8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSwapChain8 methods ***/ + STDMETHOD(Present)(THIS_ CONST RECT* pSourceRect,CONST RECT* pDestRect,HWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) PURE; + STDMETHOD(GetBackBuffer)(THIS_ UINT BackBuffer,D3DBACKBUFFER_TYPE Type,IDirect3DSurface8** ppBackBuffer) PURE; +}; + +typedef struct IDirect3DSwapChain8 *LPDIRECT3DSWAPCHAIN8, *PDIRECT3DSWAPCHAIN8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSwapChain8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->lpVtbl->Present(p,a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->lpVtbl->GetBackBuffer(p,a,b,c) +#else +#define IDirect3DSwapChain8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSwapChain8_AddRef(p) (p)->AddRef() +#define IDirect3DSwapChain8_Release(p) (p)->Release() +#define IDirect3DSwapChain8_Present(p,a,b,c,d) (p)->Present(a,b,c,d) +#define IDirect3DSwapChain8_GetBackBuffer(p,a,b,c) (p)->GetBackBuffer(a,b,c) +#endif + + + +#undef INTERFACE +#define INTERFACE IDirect3DResource8 + +DECLARE_INTERFACE_(IDirect3DResource8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; +}; + +typedef struct IDirect3DResource8 *LPDIRECT3DRESOURCE8, *PDIRECT3DRESOURCE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DResource8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DResource8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DResource8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DResource8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DResource8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DResource8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DResource8_GetType(p) (p)->lpVtbl->GetType(p) +#else +#define IDirect3DResource8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DResource8_AddRef(p) (p)->AddRef() +#define IDirect3DResource8_Release(p) (p)->Release() +#define IDirect3DResource8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DResource8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DResource8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DResource8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DResource8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DResource8_GetPriority(p) (p)->GetPriority() +#define IDirect3DResource8_PreLoad(p) (p)->PreLoad() +#define IDirect3DResource8_GetType(p) (p)->GetType() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DBaseTexture8 + +DECLARE_INTERFACE_(IDirect3DBaseTexture8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; +}; + +typedef struct IDirect3DBaseTexture8 *LPDIRECT3DBASETEXTURE8, *PDIRECT3DBASETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DBaseTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DBaseTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DBaseTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#else +#define IDirect3DBaseTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DBaseTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DBaseTexture8_Release(p) (p)->Release() +#define IDirect3DBaseTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DBaseTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DBaseTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DBaseTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DBaseTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DBaseTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DBaseTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DBaseTexture8_GetType(p) (p)->GetType() +#define IDirect3DBaseTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DBaseTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DBaseTexture8_GetLevelCount(p) (p)->GetLevelCount() +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DTexture8 + +DECLARE_INTERFACE_(IDirect3DTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetSurfaceLevel)(THIS_ UINT Level,IDirect3DSurface8** ppSurfaceLevel) PURE; + STDMETHOD(LockRect)(THIS_ UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DTexture8 *LPDIRECT3DTEXTURE8, *PDIRECT3DTEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->lpVtbl->GetSurfaceLevel(p,a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->lpVtbl->LockRect(p,a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->lpVtbl->UnlockRect(p,a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->lpVtbl->AddDirtyRect(p,a) +#else +#define IDirect3DTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DTexture8_Release(p) (p)->Release() +#define IDirect3DTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DTexture8_GetType(p) (p)->GetType() +#define IDirect3DTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DTexture8_GetSurfaceLevel(p,a,b) (p)->GetSurfaceLevel(a,b) +#define IDirect3DTexture8_LockRect(p,a,b,c,d) (p)->LockRect(a,b,c,d) +#define IDirect3DTexture8_UnlockRect(p,a) (p)->UnlockRect(a) +#define IDirect3DTexture8_AddDirtyRect(p,a) (p)->AddDirtyRect(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolumeTexture8 + +DECLARE_INTERFACE_(IDirect3DVolumeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(GetVolumeLevel)(THIS_ UINT Level,IDirect3DVolume8** ppVolumeLevel) PURE; + STDMETHOD(LockBox)(THIS_ UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS_ UINT Level) PURE; + STDMETHOD(AddDirtyBox)(THIS_ CONST D3DBOX* pDirtyBox) PURE; +}; + +typedef struct IDirect3DVolumeTexture8 *LPDIRECT3DVOLUMETEXTURE8, *PDIRECT3DVOLUMETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolumeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVolumeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->lpVtbl->GetVolumeLevel(p,a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->lpVtbl->LockBox(p,a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->lpVtbl->UnlockBox(p,a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->lpVtbl->AddDirtyBox(p,a) +#else +#define IDirect3DVolumeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolumeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DVolumeTexture8_Release(p) (p)->Release() +#define IDirect3DVolumeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolumeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolumeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolumeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolumeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVolumeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVolumeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVolumeTexture8_GetType(p) (p)->GetType() +#define IDirect3DVolumeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DVolumeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DVolumeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DVolumeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DVolumeTexture8_GetVolumeLevel(p,a,b) (p)->GetVolumeLevel(a,b) +#define IDirect3DVolumeTexture8_LockBox(p,a,b,c,d) (p)->LockBox(a,b,c,d) +#define IDirect3DVolumeTexture8_UnlockBox(p,a) (p)->UnlockBox(a) +#define IDirect3DVolumeTexture8_AddDirtyBox(p,a) (p)->AddDirtyBox(a) +#endif + + + + + +#undef INTERFACE +#define INTERFACE IDirect3DCubeTexture8 + +DECLARE_INTERFACE_(IDirect3DCubeTexture8, IDirect3DBaseTexture8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DBaseTexture8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD_(DWORD, SetLOD)(THIS_ DWORD LODNew) PURE; + STDMETHOD_(DWORD, GetLOD)(THIS) PURE; + STDMETHOD_(DWORD, GetLevelCount)(THIS) PURE; + STDMETHOD(GetLevelDesc)(THIS_ UINT Level,D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(GetCubeMapSurface)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface8** ppCubeMapSurface) PURE; + STDMETHOD(LockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS_ D3DCUBEMAP_FACES FaceType,UINT Level) PURE; + STDMETHOD(AddDirtyRect)(THIS_ D3DCUBEMAP_FACES FaceType,CONST RECT* pDirtyRect) PURE; +}; + +typedef struct IDirect3DCubeTexture8 *LPDIRECT3DCUBETEXTURE8, *PDIRECT3DCUBETEXTURE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DCubeTexture8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DCubeTexture8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DCubeTexture8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->lpVtbl->SetLOD(p,a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->lpVtbl->GetLOD(p) +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->lpVtbl->GetLevelCount(p) +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->lpVtbl->GetLevelDesc(p,a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->lpVtbl->GetCubeMapSurface(p,a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->lpVtbl->LockRect(p,a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->lpVtbl->UnlockRect(p,a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->lpVtbl->AddDirtyRect(p,a,b) +#else +#define IDirect3DCubeTexture8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DCubeTexture8_AddRef(p) (p)->AddRef() +#define IDirect3DCubeTexture8_Release(p) (p)->Release() +#define IDirect3DCubeTexture8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DCubeTexture8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DCubeTexture8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DCubeTexture8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DCubeTexture8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DCubeTexture8_GetPriority(p) (p)->GetPriority() +#define IDirect3DCubeTexture8_PreLoad(p) (p)->PreLoad() +#define IDirect3DCubeTexture8_GetType(p) (p)->GetType() +#define IDirect3DCubeTexture8_SetLOD(p,a) (p)->SetLOD(a) +#define IDirect3DCubeTexture8_GetLOD(p) (p)->GetLOD() +#define IDirect3DCubeTexture8_GetLevelCount(p) (p)->GetLevelCount() +#define IDirect3DCubeTexture8_GetLevelDesc(p,a,b) (p)->GetLevelDesc(a,b) +#define IDirect3DCubeTexture8_GetCubeMapSurface(p,a,b,c) (p)->GetCubeMapSurface(a,b,c) +#define IDirect3DCubeTexture8_LockRect(p,a,b,c,d,e) (p)->LockRect(a,b,c,d,e) +#define IDirect3DCubeTexture8_UnlockRect(p,a,b) (p)->UnlockRect(a,b) +#define IDirect3DCubeTexture8_AddDirtyRect(p,a,b) (p)->AddDirtyRect(a,b) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVertexBuffer8 + +DECLARE_INTERFACE_(IDirect3DVertexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVERTEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DVertexBuffer8 *LPDIRECT3DVERTEXBUFFER8, *PDIRECT3DVERTEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVertexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DVertexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DVertexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVertexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DVertexBuffer8_Release(p) (p)->Release() +#define IDirect3DVertexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVertexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVertexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVertexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVertexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DVertexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DVertexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DVertexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DVertexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DVertexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DVertexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DIndexBuffer8 + +DECLARE_INTERFACE_(IDirect3DIndexBuffer8, IDirect3DResource8) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DResource8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD_(DWORD, SetPriority)(THIS_ DWORD PriorityNew) PURE; + STDMETHOD_(DWORD, GetPriority)(THIS) PURE; + STDMETHOD_(void, PreLoad)(THIS) PURE; + STDMETHOD_(D3DRESOURCETYPE, GetType)(THIS) PURE; + STDMETHOD(Lock)(THIS_ UINT OffsetToLock,UINT SizeToLock,BYTE** ppbData,DWORD Flags) PURE; + STDMETHOD(Unlock)(THIS) PURE; + STDMETHOD(GetDesc)(THIS_ D3DINDEXBUFFER_DESC *pDesc) PURE; +}; + +typedef struct IDirect3DIndexBuffer8 *LPDIRECT3DINDEXBUFFER8, *PDIRECT3DINDEXBUFFER8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DIndexBuffer8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->lpVtbl->SetPriority(p,a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->lpVtbl->GetPriority(p) +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->lpVtbl->PreLoad(p) +#define IDirect3DIndexBuffer8_GetType(p) (p)->lpVtbl->GetType(p) +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->lpVtbl->Lock(p,a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->lpVtbl->Unlock(p) +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#else +#define IDirect3DIndexBuffer8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DIndexBuffer8_AddRef(p) (p)->AddRef() +#define IDirect3DIndexBuffer8_Release(p) (p)->Release() +#define IDirect3DIndexBuffer8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DIndexBuffer8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DIndexBuffer8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DIndexBuffer8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DIndexBuffer8_SetPriority(p,a) (p)->SetPriority(a) +#define IDirect3DIndexBuffer8_GetPriority(p) (p)->GetPriority() +#define IDirect3DIndexBuffer8_PreLoad(p) (p)->PreLoad() +#define IDirect3DIndexBuffer8_GetType(p) (p)->GetType() +#define IDirect3DIndexBuffer8_Lock(p,a,b,c,d) (p)->Lock(a,b,c,d) +#define IDirect3DIndexBuffer8_Unlock(p) (p)->Unlock() +#define IDirect3DIndexBuffer8_GetDesc(p,a) (p)->GetDesc(a) +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DSurface8 + +DECLARE_INTERFACE_(IDirect3DSurface8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DSurface8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DSURFACE_DESC *pDesc) PURE; + STDMETHOD(LockRect)(THIS_ D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) PURE; + STDMETHOD(UnlockRect)(THIS) PURE; +}; + +typedef struct IDirect3DSurface8 *LPDIRECT3DSURFACE8, *PDIRECT3DSURFACE8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DSurface8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DSurface8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DSurface8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->lpVtbl->LockRect(p,a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->lpVtbl->UnlockRect(p) +#else +#define IDirect3DSurface8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DSurface8_AddRef(p) (p)->AddRef() +#define IDirect3DSurface8_Release(p) (p)->Release() +#define IDirect3DSurface8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DSurface8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DSurface8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DSurface8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DSurface8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DSurface8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DSurface8_LockRect(p,a,b,c) (p)->LockRect(a,b,c) +#define IDirect3DSurface8_UnlockRect(p) (p)->UnlockRect() +#endif + + + + +#undef INTERFACE +#define INTERFACE IDirect3DVolume8 + +DECLARE_INTERFACE_(IDirect3DVolume8, IUnknown) +{ + /*** IUnknown methods ***/ + STDMETHOD(QueryInterface)(THIS_ REFIID riid, void** ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + /*** IDirect3DVolume8 methods ***/ + STDMETHOD(GetDevice)(THIS_ IDirect3DDevice8** ppDevice) PURE; + STDMETHOD(SetPrivateData)(THIS_ REFGUID refguid,CONST void* pData,DWORD SizeOfData,DWORD Flags) PURE; + STDMETHOD(GetPrivateData)(THIS_ REFGUID refguid,void* pData,DWORD* pSizeOfData) PURE; + STDMETHOD(FreePrivateData)(THIS_ REFGUID refguid) PURE; + STDMETHOD(GetContainer)(THIS_ REFIID riid,void** ppContainer) PURE; + STDMETHOD(GetDesc)(THIS_ D3DVOLUME_DESC *pDesc) PURE; + STDMETHOD(LockBox)(THIS_ D3DLOCKED_BOX * pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) PURE; + STDMETHOD(UnlockBox)(THIS) PURE; +}; + +typedef struct IDirect3DVolume8 *LPDIRECT3DVOLUME8, *PDIRECT3DVOLUME8; + +#if !defined(__cplusplus) || defined(CINTERFACE) +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->lpVtbl->QueryInterface(p,a,b) +#define IDirect3DVolume8_AddRef(p) (p)->lpVtbl->AddRef(p) +#define IDirect3DVolume8_Release(p) (p)->lpVtbl->Release(p) +#define IDirect3DVolume8_GetDevice(p,a) (p)->lpVtbl->GetDevice(p,a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->lpVtbl->SetPrivateData(p,a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->lpVtbl->GetPrivateData(p,a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->lpVtbl->FreePrivateData(p,a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->lpVtbl->GetContainer(p,a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->lpVtbl->GetDesc(p,a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->lpVtbl->LockBox(p,a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->lpVtbl->UnlockBox(p) +#else +#define IDirect3DVolume8_QueryInterface(p,a,b) (p)->QueryInterface(a,b) +#define IDirect3DVolume8_AddRef(p) (p)->AddRef() +#define IDirect3DVolume8_Release(p) (p)->Release() +#define IDirect3DVolume8_GetDevice(p,a) (p)->GetDevice(a) +#define IDirect3DVolume8_SetPrivateData(p,a,b,c,d) (p)->SetPrivateData(a,b,c,d) +#define IDirect3DVolume8_GetPrivateData(p,a,b,c) (p)->GetPrivateData(a,b,c) +#define IDirect3DVolume8_FreePrivateData(p,a) (p)->FreePrivateData(a) +#define IDirect3DVolume8_GetContainer(p,a,b) (p)->GetContainer(a,b) +#define IDirect3DVolume8_GetDesc(p,a) (p)->GetDesc(a) +#define IDirect3DVolume8_LockBox(p,a,b,c) (p)->LockBox(a,b,c) +#define IDirect3DVolume8_UnlockBox(p) (p)->UnlockBox() +#endif + +/**************************************************************************** + * Flags for SetPrivateData method on all D3D8 interfaces + * + * The passed pointer is an IUnknown ptr. The SizeOfData argument to SetPrivateData + * must be set to sizeof(IUnknown*). Direct3D will call AddRef through this + * pointer and Release when the private data is destroyed. The data will be + * destroyed when another SetPrivateData with the same GUID is set, when + * FreePrivateData is called, or when the D3D8 object is freed. + ****************************************************************************/ +#define D3DSPD_IUNKNOWN 0x00000001L + +/**************************************************************************** + * + * Parameter for IDirect3D8 Enum and GetCaps8 functions to get the info for + * the current mode only. + * + ****************************************************************************/ + +#define D3DCURRENT_DISPLAY_MODE 0x00EFFFFFL + +/**************************************************************************** + * + * Flags for IDirect3D8::CreateDevice's BehaviorFlags + * + ****************************************************************************/ + +#define D3DCREATE_FPU_PRESERVE 0x00000002L +#define D3DCREATE_MULTITHREADED 0x00000004L + +#define D3DCREATE_PUREDEVICE 0x00000010L +#define D3DCREATE_SOFTWARE_VERTEXPROCESSING 0x00000020L +#define D3DCREATE_HARDWARE_VERTEXPROCESSING 0x00000040L +#define D3DCREATE_MIXED_VERTEXPROCESSING 0x00000080L + +#define D3DCREATE_DISABLE_DRIVER_MANAGEMENT 0x00000100L + + +/**************************************************************************** + * + * Parameter for IDirect3D8::CreateDevice's iAdapter + * + ****************************************************************************/ + +#define D3DADAPTER_DEFAULT 0 + +/**************************************************************************** + * + * Flags for IDirect3D8::EnumAdapters + * + ****************************************************************************/ + +#define D3DENUM_NO_WHQL_LEVEL 0x00000002L + +/**************************************************************************** + * + * Maximum number of back-buffers supported in DX8 + * + ****************************************************************************/ + +#define D3DPRESENT_BACK_BUFFERS_MAX 3L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetGammaRamp + * + ****************************************************************************/ + +#define D3DSGR_NO_CALIBRATION 0x00000000L +#define D3DSGR_CALIBRATE 0x00000001L + +/**************************************************************************** + * + * Flags for IDirect3DDevice8::SetCursorPosition + * + ****************************************************************************/ + +#define D3DCURSOR_IMMEDIATE_UPDATE 0x00000001L + +/**************************************************************************** + * + * Flags for DrawPrimitive/DrawIndexedPrimitive + * Also valid for Begin/BeginIndexed + * Also valid for VertexBuffer::CreateVertexBuffer + ****************************************************************************/ + + +/* + * DirectDraw error codes + */ +#define _FACD3D 0x876 +#define MAKE_D3DHRESULT( code ) MAKE_HRESULT( 1, _FACD3D, code ) + +/* + * Direct3D Errors + */ +#define D3D_OK S_OK + +#define D3DERR_WRONGTEXTUREFORMAT MAKE_D3DHRESULT(2072) +#define D3DERR_UNSUPPORTEDCOLOROPERATION MAKE_D3DHRESULT(2073) +#define D3DERR_UNSUPPORTEDCOLORARG MAKE_D3DHRESULT(2074) +#define D3DERR_UNSUPPORTEDALPHAOPERATION MAKE_D3DHRESULT(2075) +#define D3DERR_UNSUPPORTEDALPHAARG MAKE_D3DHRESULT(2076) +#define D3DERR_TOOMANYOPERATIONS MAKE_D3DHRESULT(2077) +#define D3DERR_CONFLICTINGTEXTUREFILTER MAKE_D3DHRESULT(2078) +#define D3DERR_UNSUPPORTEDFACTORVALUE MAKE_D3DHRESULT(2079) +#define D3DERR_CONFLICTINGRENDERSTATE MAKE_D3DHRESULT(2081) +#define D3DERR_UNSUPPORTEDTEXTUREFILTER MAKE_D3DHRESULT(2082) +#define D3DERR_CONFLICTINGTEXTUREPALETTE MAKE_D3DHRESULT(2086) +#define D3DERR_DRIVERINTERNALERROR MAKE_D3DHRESULT(2087) + +#define D3DERR_NOTFOUND MAKE_D3DHRESULT(2150) +#define D3DERR_MOREDATA MAKE_D3DHRESULT(2151) +#define D3DERR_DEVICELOST MAKE_D3DHRESULT(2152) +#define D3DERR_DEVICENOTRESET MAKE_D3DHRESULT(2153) +#define D3DERR_NOTAVAILABLE MAKE_D3DHRESULT(2154) +#define D3DERR_OUTOFVIDEOMEMORY MAKE_D3DHRESULT(380) +#define D3DERR_INVALIDDEVICE MAKE_D3DHRESULT(2155) +#define D3DERR_INVALIDCALL MAKE_D3DHRESULT(2156) +#define D3DERR_DRIVERINVALIDCALL MAKE_D3DHRESULT(2157) + +#ifdef __cplusplus +}; +#endif + +#endif /* (DIRECT3D_VERSION >= 0x0800) */ +#endif /* _D3D_H_ */ + diff --git a/gfx/include/d3d8/d3dx8.h b/gfx/include/d3d8/d3dx8.h index a7d30d74eb..fc2688c43a 100644 --- a/gfx/include/d3d8/d3dx8.h +++ b/gfx/include/d3d8/d3dx8.h @@ -1,44 +1,44 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8.h -// Content: D3DX utility library -// -/////////////////////////////////////////////////////////////////////////// - -#ifndef __D3DX8_H__ -#define __D3DX8_H__ - -#include "d3d8.h" -#include - -#ifndef D3DXINLINE -#ifdef _MSC_VER - #if (_MSC_VER >= 1200) - #define D3DXINLINE __forceinline - #else - #define D3DXINLINE __inline - #endif -#else - #ifdef __cplusplus - #define D3DXINLINE inline - #else - #define D3DXINLINE - #endif -#endif -#endif - - -#define D3DX_DEFAULT ULONG_MAX -#define D3DX_DEFAULT_FLOAT FLT_MAX - -#include "d3dx8math.h" -#include "d3dx8core.h" -#include "d3dx8tex.h" -#include "d3dx8mesh.h" -#include "d3dx8shape.h" -#include "d3dx8effect.h" - - -#endif //__D3DX8_H__ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8.h +// Content: D3DX utility library +// +/////////////////////////////////////////////////////////////////////////// + +#ifndef __D3DX8_H__ +#define __D3DX8_H__ + +#include "d3d8.h" +#include + +#ifndef D3DXINLINE +#ifdef _MSC_VER + #if (_MSC_VER >= 1200) + #define D3DXINLINE __forceinline + #else + #define D3DXINLINE __inline + #endif +#else + #ifdef __cplusplus + #define D3DXINLINE inline + #else + #define D3DXINLINE + #endif +#endif +#endif + + +#define D3DX_DEFAULT ULONG_MAX +#define D3DX_DEFAULT_FLOAT FLT_MAX + +#include "d3dx8math.h" +#include "d3dx8core.h" +#include "d3dx8tex.h" +#include "d3dx8mesh.h" +#include "d3dx8shape.h" +#include "d3dx8effect.h" + + +#endif //__D3DX8_H__ diff --git a/gfx/include/d3d8/d3dx8core.h b/gfx/include/d3d8/d3dx8core.h index 7db338f9b4..2d70af640c 100644 --- a/gfx/include/d3d8/d3dx8core.h +++ b/gfx/include/d3d8/d3dx8core.h @@ -1,563 +1,563 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8core.h -// Content: D3DX core types and functions -// -/////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8CORE_H__ -#define __D3DX8CORE_H__ - - - -/////////////////////////////////////////////////////////////////////////// -// ID3DXBuffer: -// ------------ -// The buffer object is used by D3DX to return arbitrary size data. -// -// GetBufferPointer - -// Returns a pointer to the beginning of the buffer. -// -// GetBufferSize - -// Returns the size of the buffer, in bytes. -/////////////////////////////////////////////////////////////////////////// - -typedef interface ID3DXBuffer ID3DXBuffer; -typedef interface ID3DXBuffer *LPD3DXBUFFER; - -// {932E6A7E-C68E-45dd-A7BF-53D19C86DB1F} -DEFINE_GUID(IID_ID3DXBuffer, -0x932e6a7e, 0xc68e, 0x45dd, 0xa7, 0xbf, 0x53, 0xd1, 0x9c, 0x86, 0xdb, 0x1f); - -#undef INTERFACE -#define INTERFACE ID3DXBuffer - -DECLARE_INTERFACE_(ID3DXBuffer, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXBuffer - STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; - STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; -}; - - - -/////////////////////////////////////////////////////////////////////////// -// ID3DXFont: -// ---------- -// Font objects contain the textures and resources needed to render -// a specific font on a specific device. -// -// Begin - -// Prepartes device for drawing text. This is optional.. if DrawText -// is called outside of Begin/End, it will call Begin and End for you. -// -// DrawText - -// Draws formatted text on a D3D device. Some parameters are -// surprisingly similar to those of GDI's DrawText function. See GDI -// documentation for a detailed description of these parameters. -// -// End - -// Restores device state to how it was when Begin was called. -// -// OnLostDevice, OnResetDevice - -// Call OnLostDevice() on this object before calling Reset() on the -// device, so that this object can release any stateblocks and video -// memory resources. After Reset(), the call OnResetDevice(). -// -/////////////////////////////////////////////////////////////////////////// - -typedef interface ID3DXFont ID3DXFont; -typedef interface ID3DXFont *LPD3DXFONT; - - -// {89FAD6A5-024D-49af-8FE7-F51123B85E25} -DEFINE_GUID( IID_ID3DXFont, -0x89fad6a5, 0x24d, 0x49af, 0x8f, 0xe7, 0xf5, 0x11, 0x23, 0xb8, 0x5e, 0x25); - - -#undef INTERFACE -#define INTERFACE ID3DXFont - -DECLARE_INTERFACE_(ID3DXFont, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXFont - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(GetLogFont)(THIS_ LOGFONT* pLogFont) PURE; - - STDMETHOD(Begin)(THIS) PURE; - STDMETHOD_(INT, DrawTextA)(THIS_ LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; - STDMETHOD_(INT, DrawTextW)(THIS_ LPCWSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; - STDMETHOD(End)(THIS) PURE; - - STDMETHOD(OnLostDevice)(THIS) PURE; - STDMETHOD(OnResetDevice)(THIS) PURE; -}; - -#ifndef DrawText -#ifdef UNICODE -#define DrawText DrawTextW -#else -#define DrawText DrawTextA -#endif -#endif - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -HRESULT WINAPI - D3DXCreateFont( - LPDIRECT3DDEVICE8 pDevice, - HFONT hFont, - LPD3DXFONT* ppFont); - - -HRESULT WINAPI - D3DXCreateFontIndirect( - LPDIRECT3DDEVICE8 pDevice, - CONST LOGFONT* pLogFont, - LPD3DXFONT* ppFont); - -#ifdef __cplusplus -} -#endif //__cplusplus - - - - -/////////////////////////////////////////////////////////////////////////// -// ID3DXSprite: -// ------------ -// This object intends to provide an easy way to drawing sprites using D3D. -// -// Begin - -// Prepares device for drawing sprites -// -// Draw, DrawAffine, DrawTransform - -// Draws a sprite in screen-space. Before transformation, the sprite is -// the size of SrcRect, with its top-left corner at the origin (0,0). -// The color and alpha channels are modulated by Color. -// -// End - -// Restores device state to how it was when Begin was called. -// -// OnLostDevice, OnResetDevice - -// Call OnLostDevice() on this object before calling Reset() on the -// device, so that this object can release any stateblocks and video -// memory resources. After Reset(), the call OnResetDevice(). -/////////////////////////////////////////////////////////////////////////// - -typedef interface ID3DXSprite ID3DXSprite; -typedef interface ID3DXSprite *LPD3DXSPRITE; - - -// {13D69D15-F9B0-4e0f-B39E-C91EB33F6CE7} -DEFINE_GUID( IID_ID3DXSprite, -0x13d69d15, 0xf9b0, 0x4e0f, 0xb3, 0x9e, 0xc9, 0x1e, 0xb3, 0x3f, 0x6c, 0xe7); - - -#undef INTERFACE -#define INTERFACE ID3DXSprite - -DECLARE_INTERFACE_(ID3DXSprite, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXSprite - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - - STDMETHOD(Begin)(THIS) PURE; - - STDMETHOD(Draw)(THIS_ LPDIRECT3DTEXTURE8 pSrcTexture, - CONST RECT* pSrcRect, CONST D3DXVECTOR2* pScaling, - CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, - CONST D3DXVECTOR2* pTranslation, D3DCOLOR Color) PURE; - - STDMETHOD(DrawTransform)(THIS_ LPDIRECT3DTEXTURE8 pSrcTexture, - CONST RECT* pSrcRect, CONST D3DXMATRIX* pTransform, - D3DCOLOR Color) PURE; - - STDMETHOD(End)(THIS) PURE; - - STDMETHOD(OnLostDevice)(THIS) PURE; - STDMETHOD(OnResetDevice)(THIS) PURE; -}; - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -HRESULT WINAPI - D3DXCreateSprite( - LPDIRECT3DDEVICE8 pDevice, - LPD3DXSPRITE* ppSprite); - -#ifdef __cplusplus -} -#endif //__cplusplus - - - - -/////////////////////////////////////////////////////////////////////////// -// ID3DXRenderToSurface: -// --------------------- -// This object abstracts rendering to surfaces. These surfaces do not -// necessarily need to be render targets. If they are not, a compatible -// render target is used, and the result copied into surface at end scene. -// -// BeginScene, EndScene - -// Call BeginScene() and EndScene() at the beginning and ending of your -// scene. These calls will setup and restore render targets, viewports, -// etc.. -// -// OnLostDevice, OnResetDevice - -// Call OnLostDevice() on this object before calling Reset() on the -// device, so that this object can release any stateblocks and video -// memory resources. After Reset(), the call OnResetDevice(). -/////////////////////////////////////////////////////////////////////////// - -typedef struct _D3DXRTS_DESC -{ - UINT Width; - UINT Height; - D3DFORMAT Format; - BOOL DepthStencil; - D3DFORMAT DepthStencilFormat; - -} D3DXRTS_DESC; - - -typedef interface ID3DXRenderToSurface ID3DXRenderToSurface; -typedef interface ID3DXRenderToSurface *LPD3DXRENDERTOSURFACE; - - -// {82DF5B90-E34E-496e-AC1C-62117A6A5913} -DEFINE_GUID( IID_ID3DXRenderToSurface, -0x82df5b90, 0xe34e, 0x496e, 0xac, 0x1c, 0x62, 0x11, 0x7a, 0x6a, 0x59, 0x13); - - -#undef INTERFACE -#define INTERFACE ID3DXRenderToSurface - -DECLARE_INTERFACE_(ID3DXRenderToSurface, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXRenderToSurface - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(GetDesc)(THIS_ D3DXRTS_DESC* pDesc) PURE; - - STDMETHOD(BeginScene)(THIS_ LPDIRECT3DSURFACE8 pSurface, CONST D3DVIEWPORT8* pViewport) PURE; - STDMETHOD(EndScene)(THIS) PURE; - - STDMETHOD(OnLostDevice)(THIS) PURE; - STDMETHOD(OnResetDevice)(THIS) PURE; -}; - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -HRESULT WINAPI - D3DXCreateRenderToSurface( - LPDIRECT3DDEVICE8 pDevice, - UINT Width, - UINT Height, - D3DFORMAT Format, - BOOL DepthStencil, - D3DFORMAT DepthStencilFormat, - LPD3DXRENDERTOSURFACE* ppRenderToSurface); - -#ifdef __cplusplus -} -#endif //__cplusplus - - - -/////////////////////////////////////////////////////////////////////////// -// ID3DXRenderToEnvMap: -// -------------------- -// This object abstracts rendering to environment maps. These surfaces -// do not necessarily need to be render targets. If they are not, a -// compatible render target is used, and the result copied into the -// environment map at end scene. -// -// BeginCube, BeginSphere, BeginHemisphere, BeginParabolic - -// This function initiates the rendering of the environment map. As -// parameters, you pass the textures in which will get filled in with -// the resulting environment map. -// -// Face - -// Call this function to initiate the drawing of each face. For each -// environment map, you will call this six times.. once for each face -// in D3DCUBEMAP_FACES. -// -// End - -// This will restore all render targets, and if needed compose all the -// rendered faces into the environment map surfaces. -// -// OnLostDevice, OnResetDevice - -// Call OnLostDevice() on this object before calling Reset() on the -// device, so that this object can release any stateblocks and video -// memory resources. After Reset(), the call OnResetDevice(). -/////////////////////////////////////////////////////////////////////////// - -typedef struct _D3DXRTE_DESC -{ - UINT Size; - D3DFORMAT Format; - BOOL DepthStencil; - D3DFORMAT DepthStencilFormat; -} D3DXRTE_DESC; - - -typedef interface ID3DXRenderToEnvMap ID3DXRenderToEnvMap; -typedef interface ID3DXRenderToEnvMap *LPD3DXRenderToEnvMap; - -// {4E42C623-9451-44b7-8C86-ABCCDE5D52C8} -DEFINE_GUID( IID_ID3DXRenderToEnvMap, -0x4e42c623, 0x9451, 0x44b7, 0x8c, 0x86, 0xab, 0xcc, 0xde, 0x5d, 0x52, 0xc8); - - -#undef INTERFACE -#define INTERFACE ID3DXRenderToEnvMap - -DECLARE_INTERFACE_(ID3DXRenderToEnvMap, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXRenderToEnvMap - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(GetDesc)(THIS_ D3DXRTE_DESC* pDesc) PURE; - - STDMETHOD(BeginCube)(THIS_ - LPDIRECT3DCUBETEXTURE8 pCubeTex) PURE; - - STDMETHOD(BeginSphere)(THIS_ - LPDIRECT3DTEXTURE8 pTex) PURE; - - STDMETHOD(BeginHemisphere)(THIS_ - LPDIRECT3DTEXTURE8 pTexZPos, - LPDIRECT3DTEXTURE8 pTexZNeg) PURE; - - STDMETHOD(BeginParabolic)(THIS_ - LPDIRECT3DTEXTURE8 pTexZPos, - LPDIRECT3DTEXTURE8 pTexZNeg) PURE; - - STDMETHOD(Face)(THIS_ D3DCUBEMAP_FACES Face) PURE; - STDMETHOD(End)(THIS) PURE; - - STDMETHOD(OnLostDevice)(THIS) PURE; - STDMETHOD(OnResetDevice)(THIS) PURE; -}; - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -HRESULT WINAPI - D3DXCreateRenderToEnvMap( - LPDIRECT3DDEVICE8 pDevice, - UINT Size, - D3DFORMAT Format, - BOOL DepthStencil, - D3DFORMAT DepthStencilFormat, - LPD3DXRenderToEnvMap* ppRenderToEnvMap); - -#ifdef __cplusplus -} -#endif //__cplusplus - - - -/////////////////////////////////////////////////////////////////////////// -// Shader assemblers: -/////////////////////////////////////////////////////////////////////////// - -//------------------------------------------------------------------------- -// D3DXASM flags: -// -------------- -// -// D3DXASM_DEBUG -// Generate debug info. -// -// D3DXASM_SKIPVALIDATION -// Do not validate the generated code against known capabilities and -// constraints. This option is only recommended when assembling shaders -// you KNOW will work. (ie. have assembled before without this option.) -//------------------------------------------------------------------------- - -#define D3DXASM_DEBUG (1 << 0) -#define D3DXASM_SKIPVALIDATION (1 << 1) - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -//------------------------------------------------------------------------- -// D3DXAssembleShader: -// ------------------- -// Assembles an ascii description of a vertex or pixel shader into -// binary form. -// -// Parameters: -// pSrcFile -// Source file name -// hSrcModule -// Module handle. if NULL, current module will be used. -// pSrcResource -// Resource name in module -// pSrcData -// Pointer to source code -// SrcDataLen -// Size of source code, in bytes -// Flags -// D3DXASM_xxx flags -// ppConstants -// Returns an ID3DXBuffer object containing constant declarations. -// ppCompiledShader -// Returns an ID3DXBuffer object containing the object code. -// ppCompilationErrors -// Returns an ID3DXBuffer object containing ascii error messages -//------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXAssembleShaderFromFileA( - LPCSTR pSrcFile, - DWORD Flags, - LPD3DXBUFFER* ppConstants, - LPD3DXBUFFER* ppCompiledShader, - LPD3DXBUFFER* ppCompilationErrors); - -HRESULT WINAPI - D3DXAssembleShaderFromFileW( - LPCWSTR pSrcFile, - DWORD Flags, - LPD3DXBUFFER* ppConstants, - LPD3DXBUFFER* ppCompiledShader, - LPD3DXBUFFER* ppCompilationErrors); - -#ifdef UNICODE -#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileW -#else -#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileA -#endif - -HRESULT WINAPI - D3DXAssembleShaderFromResourceA( - HMODULE hSrcModule, - LPCSTR pSrcResource, - DWORD Flags, - LPD3DXBUFFER* ppConstants, - LPD3DXBUFFER* ppCompiledShader, - LPD3DXBUFFER* ppCompilationErrors); - -HRESULT WINAPI - D3DXAssembleShaderFromResourceW( - HMODULE hSrcModule, - LPCWSTR pSrcResource, - DWORD Flags, - LPD3DXBUFFER* ppConstants, - LPD3DXBUFFER* ppCompiledShader, - LPD3DXBUFFER* ppCompilationErrors); - -#ifdef UNICODE -#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceW -#else -#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceA -#endif - -HRESULT WINAPI - D3DXAssembleShader( - LPCVOID pSrcData, - UINT SrcDataLen, - DWORD Flags, - LPD3DXBUFFER* ppConstants, - LPD3DXBUFFER* ppCompiledShader, - LPD3DXBUFFER* ppCompilationErrors); - - -#ifdef __cplusplus -} -#endif //__cplusplus - - - -/////////////////////////////////////////////////////////////////////////// -// Misc APIs: -/////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -//------------------------------------------------------------------------- -// D3DXGetErrorString: -// ------------------ -// Returns the error string for given an hresult. Interprets all D3DX and -// D3D hresults. -// -// Parameters: -// hr -// The error code to be deciphered. -// pBuffer -// Pointer to the buffer to be filled in. -// BufferLen -// Count of characters in buffer. Any error message longer than this -// length will be truncated to fit. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXGetErrorStringA( - HRESULT hr, - LPSTR pBuffer, - UINT BufferLen); - -HRESULT WINAPI - D3DXGetErrorStringW( - HRESULT hr, - LPWSTR pBuffer, - UINT BufferLen); - -#ifdef UNICODE -#define D3DXGetErrorString D3DXGetErrorStringW -#else -#define D3DXGetErrorString D3DXGetErrorStringA -#endif - - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //__D3DX8CORE_H__ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8core.h +// Content: D3DX core types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8CORE_H__ +#define __D3DX8CORE_H__ + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXBuffer: +// ------------ +// The buffer object is used by D3DX to return arbitrary size data. +// +// GetBufferPointer - +// Returns a pointer to the beginning of the buffer. +// +// GetBufferSize - +// Returns the size of the buffer, in bytes. +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXBuffer ID3DXBuffer; +typedef interface ID3DXBuffer *LPD3DXBUFFER; + +// {932E6A7E-C68E-45dd-A7BF-53D19C86DB1F} +DEFINE_GUID(IID_ID3DXBuffer, +0x932e6a7e, 0xc68e, 0x45dd, 0xa7, 0xbf, 0x53, 0xd1, 0x9c, 0x86, 0xdb, 0x1f); + +#undef INTERFACE +#define INTERFACE ID3DXBuffer + +DECLARE_INTERFACE_(ID3DXBuffer, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBuffer + STDMETHOD_(LPVOID, GetBufferPointer)(THIS) PURE; + STDMETHOD_(DWORD, GetBufferSize)(THIS) PURE; +}; + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXFont: +// ---------- +// Font objects contain the textures and resources needed to render +// a specific font on a specific device. +// +// Begin - +// Prepartes device for drawing text. This is optional.. if DrawText +// is called outside of Begin/End, it will call Begin and End for you. +// +// DrawText - +// Draws formatted text on a D3D device. Some parameters are +// surprisingly similar to those of GDI's DrawText function. See GDI +// documentation for a detailed description of these parameters. +// +// End - +// Restores device state to how it was when Begin was called. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +// +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXFont ID3DXFont; +typedef interface ID3DXFont *LPD3DXFONT; + + +// {89FAD6A5-024D-49af-8FE7-F51123B85E25} +DEFINE_GUID( IID_ID3DXFont, +0x89fad6a5, 0x24d, 0x49af, 0x8f, 0xe7, 0xf5, 0x11, 0x23, 0xb8, 0x5e, 0x25); + + +#undef INTERFACE +#define INTERFACE ID3DXFont + +DECLARE_INTERFACE_(ID3DXFont, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXFont + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(GetLogFont)(THIS_ LOGFONT* pLogFont) PURE; + + STDMETHOD(Begin)(THIS) PURE; + STDMETHOD_(INT, DrawTextA)(THIS_ LPCSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + STDMETHOD_(INT, DrawTextW)(THIS_ LPCWSTR pString, INT Count, LPRECT pRect, DWORD Format, D3DCOLOR Color) PURE; + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + +#ifndef DrawText +#ifdef UNICODE +#define DrawText DrawTextW +#else +#define DrawText DrawTextA +#endif +#endif + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateFont( + LPDIRECT3DDEVICE8 pDevice, + HFONT hFont, + LPD3DXFONT* ppFont); + + +HRESULT WINAPI + D3DXCreateFontIndirect( + LPDIRECT3DDEVICE8 pDevice, + CONST LOGFONT* pLogFont, + LPD3DXFONT* ppFont); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXSprite: +// ------------ +// This object intends to provide an easy way to drawing sprites using D3D. +// +// Begin - +// Prepares device for drawing sprites +// +// Draw, DrawAffine, DrawTransform - +// Draws a sprite in screen-space. Before transformation, the sprite is +// the size of SrcRect, with its top-left corner at the origin (0,0). +// The color and alpha channels are modulated by Color. +// +// End - +// Restores device state to how it was when Begin was called. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXSprite ID3DXSprite; +typedef interface ID3DXSprite *LPD3DXSPRITE; + + +// {13D69D15-F9B0-4e0f-B39E-C91EB33F6CE7} +DEFINE_GUID( IID_ID3DXSprite, +0x13d69d15, 0xf9b0, 0x4e0f, 0xb3, 0x9e, 0xc9, 0x1e, 0xb3, 0x3f, 0x6c, 0xe7); + + +#undef INTERFACE +#define INTERFACE ID3DXSprite + +DECLARE_INTERFACE_(ID3DXSprite, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSprite + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + + STDMETHOD(Begin)(THIS) PURE; + + STDMETHOD(Draw)(THIS_ LPDIRECT3DTEXTURE8 pSrcTexture, + CONST RECT* pSrcRect, CONST D3DXVECTOR2* pScaling, + CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, + CONST D3DXVECTOR2* pTranslation, D3DCOLOR Color) PURE; + + STDMETHOD(DrawTransform)(THIS_ LPDIRECT3DTEXTURE8 pSrcTexture, + CONST RECT* pSrcRect, CONST D3DXMATRIX* pTransform, + D3DCOLOR Color) PURE; + + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +HRESULT WINAPI + D3DXCreateSprite( + LPDIRECT3DDEVICE8 pDevice, + LPD3DXSPRITE* ppSprite); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToSurface: +// --------------------- +// This object abstracts rendering to surfaces. These surfaces do not +// necessarily need to be render targets. If they are not, a compatible +// render target is used, and the result copied into surface at end scene. +// +// BeginScene, EndScene - +// Call BeginScene() and EndScene() at the beginning and ending of your +// scene. These calls will setup and restore render targets, viewports, +// etc.. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTS_DESC +{ + UINT Width; + UINT Height; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; + +} D3DXRTS_DESC; + + +typedef interface ID3DXRenderToSurface ID3DXRenderToSurface; +typedef interface ID3DXRenderToSurface *LPD3DXRENDERTOSURFACE; + + +// {82DF5B90-E34E-496e-AC1C-62117A6A5913} +DEFINE_GUID( IID_ID3DXRenderToSurface, +0x82df5b90, 0xe34e, 0x496e, 0xac, 0x1c, 0x62, 0x11, 0x7a, 0x6a, 0x59, 0x13); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToSurface + +DECLARE_INTERFACE_(ID3DXRenderToSurface, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToSurface + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTS_DESC* pDesc) PURE; + + STDMETHOD(BeginScene)(THIS_ LPDIRECT3DSURFACE8 pSurface, CONST D3DVIEWPORT8* pViewport) PURE; + STDMETHOD(EndScene)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToSurface( + LPDIRECT3DDEVICE8 pDevice, + UINT Width, + UINT Height, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRENDERTOSURFACE* ppRenderToSurface); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// ID3DXRenderToEnvMap: +// -------------------- +// This object abstracts rendering to environment maps. These surfaces +// do not necessarily need to be render targets. If they are not, a +// compatible render target is used, and the result copied into the +// environment map at end scene. +// +// BeginCube, BeginSphere, BeginHemisphere, BeginParabolic - +// This function initiates the rendering of the environment map. As +// parameters, you pass the textures in which will get filled in with +// the resulting environment map. +// +// Face - +// Call this function to initiate the drawing of each face. For each +// environment map, you will call this six times.. once for each face +// in D3DCUBEMAP_FACES. +// +// End - +// This will restore all render targets, and if needed compose all the +// rendered faces into the environment map surfaces. +// +// OnLostDevice, OnResetDevice - +// Call OnLostDevice() on this object before calling Reset() on the +// device, so that this object can release any stateblocks and video +// memory resources. After Reset(), the call OnResetDevice(). +/////////////////////////////////////////////////////////////////////////// + +typedef struct _D3DXRTE_DESC +{ + UINT Size; + D3DFORMAT Format; + BOOL DepthStencil; + D3DFORMAT DepthStencilFormat; +} D3DXRTE_DESC; + + +typedef interface ID3DXRenderToEnvMap ID3DXRenderToEnvMap; +typedef interface ID3DXRenderToEnvMap *LPD3DXRenderToEnvMap; + +// {4E42C623-9451-44b7-8C86-ABCCDE5D52C8} +DEFINE_GUID( IID_ID3DXRenderToEnvMap, +0x4e42c623, 0x9451, 0x44b7, 0x8c, 0x86, 0xab, 0xcc, 0xde, 0x5d, 0x52, 0xc8); + + +#undef INTERFACE +#define INTERFACE ID3DXRenderToEnvMap + +DECLARE_INTERFACE_(ID3DXRenderToEnvMap, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXRenderToEnvMap + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXRTE_DESC* pDesc) PURE; + + STDMETHOD(BeginCube)(THIS_ + LPDIRECT3DCUBETEXTURE8 pCubeTex) PURE; + + STDMETHOD(BeginSphere)(THIS_ + LPDIRECT3DTEXTURE8 pTex) PURE; + + STDMETHOD(BeginHemisphere)(THIS_ + LPDIRECT3DTEXTURE8 pTexZPos, + LPDIRECT3DTEXTURE8 pTexZNeg) PURE; + + STDMETHOD(BeginParabolic)(THIS_ + LPDIRECT3DTEXTURE8 pTexZPos, + LPDIRECT3DTEXTURE8 pTexZNeg) PURE; + + STDMETHOD(Face)(THIS_ D3DCUBEMAP_FACES Face) PURE; + STDMETHOD(End)(THIS) PURE; + + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateRenderToEnvMap( + LPDIRECT3DDEVICE8 pDevice, + UINT Size, + D3DFORMAT Format, + BOOL DepthStencil, + D3DFORMAT DepthStencilFormat, + LPD3DXRenderToEnvMap* ppRenderToEnvMap); + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// Shader assemblers: +/////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------------- +// D3DXASM flags: +// -------------- +// +// D3DXASM_DEBUG +// Generate debug info. +// +// D3DXASM_SKIPVALIDATION +// Do not validate the generated code against known capabilities and +// constraints. This option is only recommended when assembling shaders +// you KNOW will work. (ie. have assembled before without this option.) +//------------------------------------------------------------------------- + +#define D3DXASM_DEBUG (1 << 0) +#define D3DXASM_SKIPVALIDATION (1 << 1) + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//------------------------------------------------------------------------- +// D3DXAssembleShader: +// ------------------- +// Assembles an ascii description of a vertex or pixel shader into +// binary form. +// +// Parameters: +// pSrcFile +// Source file name +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to source code +// SrcDataLen +// Size of source code, in bytes +// Flags +// D3DXASM_xxx flags +// ppConstants +// Returns an ID3DXBuffer object containing constant declarations. +// ppCompiledShader +// Returns an ID3DXBuffer object containing the object code. +// ppCompilationErrors +// Returns an ID3DXBuffer object containing ascii error messages +//------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXAssembleShaderFromFileA( + LPCSTR pSrcFile, + DWORD Flags, + LPD3DXBUFFER* ppConstants, + LPD3DXBUFFER* ppCompiledShader, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXAssembleShaderFromFileW( + LPCWSTR pSrcFile, + DWORD Flags, + LPD3DXBUFFER* ppConstants, + LPD3DXBUFFER* ppCompiledShader, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileW +#else +#define D3DXAssembleShaderFromFile D3DXAssembleShaderFromFileA +#endif + +HRESULT WINAPI + D3DXAssembleShaderFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + DWORD Flags, + LPD3DXBUFFER* ppConstants, + LPD3DXBUFFER* ppCompiledShader, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXAssembleShaderFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + DWORD Flags, + LPD3DXBUFFER* ppConstants, + LPD3DXBUFFER* ppCompiledShader, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceW +#else +#define D3DXAssembleShaderFromResource D3DXAssembleShaderFromResourceA +#endif + +HRESULT WINAPI + D3DXAssembleShader( + LPCVOID pSrcData, + UINT SrcDataLen, + DWORD Flags, + LPD3DXBUFFER* ppConstants, + LPD3DXBUFFER* ppCompiledShader, + LPD3DXBUFFER* ppCompilationErrors); + + +#ifdef __cplusplus +} +#endif //__cplusplus + + + +/////////////////////////////////////////////////////////////////////////// +// Misc APIs: +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +//------------------------------------------------------------------------- +// D3DXGetErrorString: +// ------------------ +// Returns the error string for given an hresult. Interprets all D3DX and +// D3D hresults. +// +// Parameters: +// hr +// The error code to be deciphered. +// pBuffer +// Pointer to the buffer to be filled in. +// BufferLen +// Count of characters in buffer. Any error message longer than this +// length will be truncated to fit. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXGetErrorStringA( + HRESULT hr, + LPSTR pBuffer, + UINT BufferLen); + +HRESULT WINAPI + D3DXGetErrorStringW( + HRESULT hr, + LPWSTR pBuffer, + UINT BufferLen); + +#ifdef UNICODE +#define D3DXGetErrorString D3DXGetErrorStringW +#else +#define D3DXGetErrorString D3DXGetErrorStringA +#endif + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX8CORE_H__ diff --git a/gfx/include/d3d8/d3dx8effect.h b/gfx/include/d3d8/d3dx8effect.h index 96fc382815..8444935877 100644 --- a/gfx/include/d3d8/d3dx8effect.h +++ b/gfx/include/d3d8/d3dx8effect.h @@ -1,226 +1,226 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8effect.h -// Content: D3DX effect types and functions -// -/////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8EFFECT_H__ -#define __D3DX8EFFECT_H__ - - -#define D3DXFX_DONOTSAVESTATE (1 << 0) - - -typedef enum _D3DXPARAMETERTYPE -{ - D3DXPT_DWORD = 0, - D3DXPT_FLOAT = 1, - D3DXPT_VECTOR = 2, - D3DXPT_MATRIX = 3, - D3DXPT_TEXTURE = 4, - D3DXPT_VERTEXSHADER = 5, - D3DXPT_PIXELSHADER = 6, - D3DXPT_CONSTANT = 7, - D3DXPT_STRING = 8, - D3DXPT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ - -} D3DXPARAMETERTYPE; - - -typedef struct _D3DXEFFECT_DESC -{ - UINT Parameters; - UINT Techniques; - -} D3DXEFFECT_DESC; - - -typedef struct _D3DXPARAMETER_DESC -{ - LPCSTR Name; - LPCSTR Index; - D3DXPARAMETERTYPE Type; - -} D3DXPARAMETER_DESC; - - -typedef struct _D3DXTECHNIQUE_DESC -{ - LPCSTR Name; - LPCSTR Index; - UINT Passes; - -} D3DXTECHNIQUE_DESC; - - -typedef struct _D3DXPASS_DESC -{ - LPCSTR Name; - LPCSTR Index; - -} D3DXPASS_DESC; - - - -////////////////////////////////////////////////////////////////////////////// -// ID3DXEffect /////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -typedef interface ID3DXEffect ID3DXEffect; -typedef interface ID3DXEffect *LPD3DXEFFECT; - -// {648B1CEB-8D4E-4d66-B6FA-E44969E82E89} -DEFINE_GUID( IID_ID3DXEffect, -0x648b1ceb, 0x8d4e, 0x4d66, 0xb6, 0xfa, 0xe4, 0x49, 0x69, 0xe8, 0x2e, 0x89); - - -#undef INTERFACE -#define INTERFACE ID3DXEffect - -DECLARE_INTERFACE_(ID3DXEffect, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXEffect - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; - STDMETHOD(GetParameterDesc)(THIS_ LPCSTR pParameter, D3DXPARAMETER_DESC* pDesc) PURE; - STDMETHOD(GetTechniqueDesc)(THIS_ LPCSTR pTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; - STDMETHOD(GetPassDesc)(THIS_ LPCSTR pTechnique, LPCSTR pPass, D3DXPASS_DESC* pDesc) PURE; - STDMETHOD(FindNextValidTechnique)(THIS_ LPCSTR pTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; - STDMETHOD(CloneEffect)(THIS_ LPDIRECT3DDEVICE8 pDevice, LPD3DXEFFECT* ppEffect) PURE; - STDMETHOD(GetCompiledEffect)(THIS_ LPD3DXBUFFER* ppCompiledEffect) PURE; - - STDMETHOD(SetTechnique)(THIS_ LPCSTR pTechnique) PURE; - STDMETHOD(GetTechnique)(THIS_ LPCSTR* ppTechnique) PURE; - - STDMETHOD(SetDword)(THIS_ LPCSTR pParameter, DWORD dw) PURE; - STDMETHOD(GetDword)(THIS_ LPCSTR pParameter, DWORD* pdw) PURE; - STDMETHOD(SetFloat)(THIS_ LPCSTR pParameter, FLOAT f) PURE; - STDMETHOD(GetFloat)(THIS_ LPCSTR pParameter, FLOAT* pf) PURE; - STDMETHOD(SetVector)(THIS_ LPCSTR pParameter, CONST D3DXVECTOR4* pVector) PURE; - STDMETHOD(GetVector)(THIS_ LPCSTR pParameter, D3DXVECTOR4* pVector) PURE; - STDMETHOD(SetMatrix)(THIS_ LPCSTR pParameter, CONST D3DXMATRIX* pMatrix) PURE; - STDMETHOD(GetMatrix)(THIS_ LPCSTR pParameter, D3DXMATRIX* pMatrix) PURE; - STDMETHOD(SetTexture)(THIS_ LPCSTR pParameter, LPDIRECT3DBASETEXTURE8 pTexture) PURE; - STDMETHOD(GetTexture)(THIS_ LPCSTR pParameter, LPDIRECT3DBASETEXTURE8 *ppTexture) PURE; - STDMETHOD(SetVertexShader)(THIS_ LPCSTR pParameter, DWORD Handle) PURE; - STDMETHOD(GetVertexShader)(THIS_ LPCSTR pParameter, DWORD* pHandle) PURE; - STDMETHOD(SetPixelShader)(THIS_ LPCSTR pParameter, DWORD Handle) PURE; - STDMETHOD(GetPixelShader)(THIS_ LPCSTR pParameter, DWORD* pHandle) PURE; - STDMETHOD(SetString)(THIS_ LPCSTR pParameter, LPCSTR pString) PURE; - STDMETHOD(GetString)(THIS_ LPCSTR pParameter, LPCSTR* ppString) PURE; - STDMETHOD_(BOOL, IsParameterUsed)(THIS_ LPCSTR pParameter) PURE; - - STDMETHOD(Validate)(THIS) PURE; - STDMETHOD(Begin)(THIS_ UINT *pPasses, DWORD Flags) PURE; - STDMETHOD(Pass)(THIS_ UINT Pass) PURE; - STDMETHOD(End)(THIS) PURE; - STDMETHOD(OnLostDevice)(THIS) PURE; - STDMETHOD(OnResetDevice)(THIS) PURE; -}; - - - -////////////////////////////////////////////////////////////////////////////// -// APIs ////////////////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -//---------------------------------------------------------------------------- -// D3DXCreateEffect: -// ----------------- -// Creates an effect from an ascii or binaray effect description. -// -// Parameters: -// pDevice -// Pointer of the device on which to create the effect -// pSrcFile -// Name of the file containing the effect description -// hSrcModule -// Module handle. if NULL, current module will be used. -// pSrcResource -// Resource name in module -// pSrcData -// Pointer to effect description -// SrcDataSize -// Size of the effect description in bytes -// ppEffect -// Returns a buffer containing created effect. -// ppCompilationErrors -// Returns a buffer containing any error messages which occurred during -// compile. Or NULL if you do not care about the error messages. -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXCreateEffectFromFileA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - LPD3DXEFFECT* ppEffect, - LPD3DXBUFFER* ppCompilationErrors); - -HRESULT WINAPI - D3DXCreateEffectFromFileW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - LPD3DXEFFECT* ppEffect, - LPD3DXBUFFER* ppCompilationErrors); - -#ifdef UNICODE -#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileW -#else -#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileA -#endif - - -HRESULT WINAPI - D3DXCreateEffectFromResourceA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - LPD3DXEFFECT* ppEffect, - LPD3DXBUFFER* ppCompilationErrors); - -HRESULT WINAPI - D3DXCreateEffectFromResourceW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - LPD3DXEFFECT* ppEffect, - LPD3DXBUFFER* ppCompilationErrors); - -#ifdef UNICODE -#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceW -#else -#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceA -#endif - - -HRESULT WINAPI - D3DXCreateEffect( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - LPD3DXEFFECT* ppEffect, - LPD3DXBUFFER* ppCompilationErrors); - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //__D3DX8EFFECT_H__ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8effect.h +// Content: D3DX effect types and functions +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8EFFECT_H__ +#define __D3DX8EFFECT_H__ + + +#define D3DXFX_DONOTSAVESTATE (1 << 0) + + +typedef enum _D3DXPARAMETERTYPE +{ + D3DXPT_DWORD = 0, + D3DXPT_FLOAT = 1, + D3DXPT_VECTOR = 2, + D3DXPT_MATRIX = 3, + D3DXPT_TEXTURE = 4, + D3DXPT_VERTEXSHADER = 5, + D3DXPT_PIXELSHADER = 6, + D3DXPT_CONSTANT = 7, + D3DXPT_STRING = 8, + D3DXPT_FORCE_DWORD = 0x7fffffff /* force 32-bit size enum */ + +} D3DXPARAMETERTYPE; + + +typedef struct _D3DXEFFECT_DESC +{ + UINT Parameters; + UINT Techniques; + +} D3DXEFFECT_DESC; + + +typedef struct _D3DXPARAMETER_DESC +{ + LPCSTR Name; + LPCSTR Index; + D3DXPARAMETERTYPE Type; + +} D3DXPARAMETER_DESC; + + +typedef struct _D3DXTECHNIQUE_DESC +{ + LPCSTR Name; + LPCSTR Index; + UINT Passes; + +} D3DXTECHNIQUE_DESC; + + +typedef struct _D3DXPASS_DESC +{ + LPCSTR Name; + LPCSTR Index; + +} D3DXPASS_DESC; + + + +////////////////////////////////////////////////////////////////////////////// +// ID3DXEffect /////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +typedef interface ID3DXEffect ID3DXEffect; +typedef interface ID3DXEffect *LPD3DXEFFECT; + +// {648B1CEB-8D4E-4d66-B6FA-E44969E82E89} +DEFINE_GUID( IID_ID3DXEffect, +0x648b1ceb, 0x8d4e, 0x4d66, 0xb6, 0xfa, 0xe4, 0x49, 0x69, 0xe8, 0x2e, 0x89); + + +#undef INTERFACE +#define INTERFACE ID3DXEffect + +DECLARE_INTERFACE_(ID3DXEffect, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXEffect + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(GetDesc)(THIS_ D3DXEFFECT_DESC* pDesc) PURE; + STDMETHOD(GetParameterDesc)(THIS_ LPCSTR pParameter, D3DXPARAMETER_DESC* pDesc) PURE; + STDMETHOD(GetTechniqueDesc)(THIS_ LPCSTR pTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(GetPassDesc)(THIS_ LPCSTR pTechnique, LPCSTR pPass, D3DXPASS_DESC* pDesc) PURE; + STDMETHOD(FindNextValidTechnique)(THIS_ LPCSTR pTechnique, D3DXTECHNIQUE_DESC* pDesc) PURE; + STDMETHOD(CloneEffect)(THIS_ LPDIRECT3DDEVICE8 pDevice, LPD3DXEFFECT* ppEffect) PURE; + STDMETHOD(GetCompiledEffect)(THIS_ LPD3DXBUFFER* ppCompiledEffect) PURE; + + STDMETHOD(SetTechnique)(THIS_ LPCSTR pTechnique) PURE; + STDMETHOD(GetTechnique)(THIS_ LPCSTR* ppTechnique) PURE; + + STDMETHOD(SetDword)(THIS_ LPCSTR pParameter, DWORD dw) PURE; + STDMETHOD(GetDword)(THIS_ LPCSTR pParameter, DWORD* pdw) PURE; + STDMETHOD(SetFloat)(THIS_ LPCSTR pParameter, FLOAT f) PURE; + STDMETHOD(GetFloat)(THIS_ LPCSTR pParameter, FLOAT* pf) PURE; + STDMETHOD(SetVector)(THIS_ LPCSTR pParameter, CONST D3DXVECTOR4* pVector) PURE; + STDMETHOD(GetVector)(THIS_ LPCSTR pParameter, D3DXVECTOR4* pVector) PURE; + STDMETHOD(SetMatrix)(THIS_ LPCSTR pParameter, CONST D3DXMATRIX* pMatrix) PURE; + STDMETHOD(GetMatrix)(THIS_ LPCSTR pParameter, D3DXMATRIX* pMatrix) PURE; + STDMETHOD(SetTexture)(THIS_ LPCSTR pParameter, LPDIRECT3DBASETEXTURE8 pTexture) PURE; + STDMETHOD(GetTexture)(THIS_ LPCSTR pParameter, LPDIRECT3DBASETEXTURE8 *ppTexture) PURE; + STDMETHOD(SetVertexShader)(THIS_ LPCSTR pParameter, DWORD Handle) PURE; + STDMETHOD(GetVertexShader)(THIS_ LPCSTR pParameter, DWORD* pHandle) PURE; + STDMETHOD(SetPixelShader)(THIS_ LPCSTR pParameter, DWORD Handle) PURE; + STDMETHOD(GetPixelShader)(THIS_ LPCSTR pParameter, DWORD* pHandle) PURE; + STDMETHOD(SetString)(THIS_ LPCSTR pParameter, LPCSTR pString) PURE; + STDMETHOD(GetString)(THIS_ LPCSTR pParameter, LPCSTR* ppString) PURE; + STDMETHOD_(BOOL, IsParameterUsed)(THIS_ LPCSTR pParameter) PURE; + + STDMETHOD(Validate)(THIS) PURE; + STDMETHOD(Begin)(THIS_ UINT *pPasses, DWORD Flags) PURE; + STDMETHOD(Pass)(THIS_ UINT Pass) PURE; + STDMETHOD(End)(THIS) PURE; + STDMETHOD(OnLostDevice)(THIS) PURE; + STDMETHOD(OnResetDevice)(THIS) PURE; +}; + + + +////////////////////////////////////////////////////////////////////////////// +// APIs ////////////////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//---------------------------------------------------------------------------- +// D3DXCreateEffect: +// ----------------- +// Creates an effect from an ascii or binaray effect description. +// +// Parameters: +// pDevice +// Pointer of the device on which to create the effect +// pSrcFile +// Name of the file containing the effect description +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pSrcData +// Pointer to effect description +// SrcDataSize +// Size of the effect description in bytes +// ppEffect +// Returns a buffer containing created effect. +// ppCompilationErrors +// Returns a buffer containing any error messages which occurred during +// compile. Or NULL if you do not care about the error messages. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateEffectFromFileA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromFileW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileW +#else +#define D3DXCreateEffectFromFile D3DXCreateEffectFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateEffectFromResourceA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +HRESULT WINAPI + D3DXCreateEffectFromResourceW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + +#ifdef UNICODE +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceW +#else +#define D3DXCreateEffectFromResource D3DXCreateEffectFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateEffect( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPD3DXEFFECT* ppEffect, + LPD3DXBUFFER* ppCompilationErrors); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX8EFFECT_H__ diff --git a/gfx/include/d3d8/d3dx8math.h b/gfx/include/d3d8/d3dx8math.h index fa15ff778a..a1a68fd6b6 100644 --- a/gfx/include/d3d8/d3dx8math.h +++ b/gfx/include/d3d8/d3dx8math.h @@ -1,1213 +1,1213 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8math.h -// Content: D3DX math types and functions -// -////////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8MATH_H__ -#define __D3DX8MATH_H__ - -#include -#pragma warning(disable:4201) /* anonymous unions warning */ - -//=========================================================================== -// -// General purpose utilities -// -//=========================================================================== -#define D3DX_PI ((FLOAT) 3.141592654f) -#define D3DX_1BYPI ((FLOAT) 0.318309886f) - -#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f)) -#define D3DXToDegree( radian ) ((radian) * (180.0f / D3DX_PI)) - - - -//=========================================================================== -// -// Vectors -// -//=========================================================================== - -//-------------------------- -// 2D Vector -//-------------------------- -typedef struct D3DXVECTOR2 -{ -#ifdef __cplusplus -public: - D3DXVECTOR2() {}; - D3DXVECTOR2( CONST FLOAT * ); - D3DXVECTOR2( FLOAT x, FLOAT y ); - - // casting - operator FLOAT* (); - operator CONST FLOAT* () const; - - // assignment operators - D3DXVECTOR2& operator += ( CONST D3DXVECTOR2& ); - D3DXVECTOR2& operator -= ( CONST D3DXVECTOR2& ); - D3DXVECTOR2& operator *= ( FLOAT ); - D3DXVECTOR2& operator /= ( FLOAT ); - - // unary operators - D3DXVECTOR2 operator + () const; - D3DXVECTOR2 operator - () const; - - // binary operators - D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; - D3DXVECTOR2 operator - ( CONST D3DXVECTOR2& ) const; - D3DXVECTOR2 operator * ( FLOAT ) const; - D3DXVECTOR2 operator / ( FLOAT ) const; - - friend D3DXVECTOR2 operator * ( FLOAT, CONST D3DXVECTOR2& ); - - BOOL operator == ( CONST D3DXVECTOR2& ) const; - BOOL operator != ( CONST D3DXVECTOR2& ) const; - - -public: -#endif //__cplusplus - FLOAT x, y; -} D3DXVECTOR2, *LPD3DXVECTOR2; - - -//-------------------------- -// 3D Vector -//-------------------------- -#ifdef __cplusplus -typedef struct D3DXVECTOR3 : public D3DVECTOR -{ -public: - D3DXVECTOR3() {}; - D3DXVECTOR3( CONST FLOAT * ); - D3DXVECTOR3( CONST D3DVECTOR& ); - D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); - - // casting - operator FLOAT* (); - operator CONST FLOAT* () const; - - // assignment operators - D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); - D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); - D3DXVECTOR3& operator *= ( FLOAT ); - D3DXVECTOR3& operator /= ( FLOAT ); - - // unary operators - D3DXVECTOR3 operator + () const; - D3DXVECTOR3 operator - () const; - - // binary operators - D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; - D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; - D3DXVECTOR3 operator * ( FLOAT ) const; - D3DXVECTOR3 operator / ( FLOAT ) const; - - friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); - - BOOL operator == ( CONST D3DXVECTOR3& ) const; - BOOL operator != ( CONST D3DXVECTOR3& ) const; - -} D3DXVECTOR3, *LPD3DXVECTOR3; - -#else //!__cplusplus -typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3; -#endif //!__cplusplus - - -//-------------------------- -// 4D Vector -//-------------------------- -typedef struct D3DXVECTOR4 -{ -#ifdef __cplusplus -public: - D3DXVECTOR4() {}; - D3DXVECTOR4( CONST FLOAT* ); - D3DXVECTOR4( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); - - // casting - operator FLOAT* (); - operator CONST FLOAT* () const; - - // assignment operators - D3DXVECTOR4& operator += ( CONST D3DXVECTOR4& ); - D3DXVECTOR4& operator -= ( CONST D3DXVECTOR4& ); - D3DXVECTOR4& operator *= ( FLOAT ); - D3DXVECTOR4& operator /= ( FLOAT ); - - // unary operators - D3DXVECTOR4 operator + () const; - D3DXVECTOR4 operator - () const; - - // binary operators - D3DXVECTOR4 operator + ( CONST D3DXVECTOR4& ) const; - D3DXVECTOR4 operator - ( CONST D3DXVECTOR4& ) const; - D3DXVECTOR4 operator * ( FLOAT ) const; - D3DXVECTOR4 operator / ( FLOAT ) const; - - friend D3DXVECTOR4 operator * ( FLOAT, CONST D3DXVECTOR4& ); - - BOOL operator == ( CONST D3DXVECTOR4& ) const; - BOOL operator != ( CONST D3DXVECTOR4& ) const; - -public: -#endif //__cplusplus - FLOAT x, y, z, w; -} D3DXVECTOR4, *LPD3DXVECTOR4; - - -//=========================================================================== -// -// Matrices -// -//=========================================================================== -#ifdef __cplusplus -typedef struct D3DXMATRIX : public D3DMATRIX -{ -public: - D3DXMATRIX() {}; - D3DXMATRIX( CONST FLOAT * ); - D3DXMATRIX( CONST D3DMATRIX& ); - D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, - FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, - FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, - FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); - - - // access grants - FLOAT& operator () ( UINT Row, UINT Col ); - FLOAT operator () ( UINT Row, UINT Col ) const; - - // casting operators - operator FLOAT* (); - operator CONST FLOAT* () const; - - // assignment operators - D3DXMATRIX& operator *= ( CONST D3DXMATRIX& ); - D3DXMATRIX& operator += ( CONST D3DXMATRIX& ); - D3DXMATRIX& operator -= ( CONST D3DXMATRIX& ); - D3DXMATRIX& operator *= ( FLOAT ); - D3DXMATRIX& operator /= ( FLOAT ); - - // unary operators - D3DXMATRIX operator + () const; - D3DXMATRIX operator - () const; - - // binary operators - D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; - D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const; - D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const; - D3DXMATRIX operator * ( FLOAT ) const; - D3DXMATRIX operator / ( FLOAT ) const; - - friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& ); - - BOOL operator == ( CONST D3DXMATRIX& ) const; - BOOL operator != ( CONST D3DXMATRIX& ) const; - -} D3DXMATRIX, *LPD3DXMATRIX; - -#else //!__cplusplus -typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; -#endif //!__cplusplus - -//=========================================================================== -// -// Aligned Matrices -// -// This class helps keep matrices 16-byte aligned as preferred by P4 cpus. -// It aligns matrices on the stack and on the heap or in global scope. -// It does this using __declspec(align(16)) which works on VC7 and on VC 6 -// with the processor pack. Unfortunately there is no way to detect the -// latter so this is turned on only on VC7. On other compilers this is the -// the same as D3DXMATRIX. -// Using this class on a compiler that does not actually do the alignment -// can be dangerous since it will not expose bugs that ignore alignment. -// E.g if an object of this class in inside a struct or class, and some code -// memcopys data in it assuming tight packing. This could break on a compiler -// that eventually start aligning the matrix. -// -//=========================================================================== -#ifdef __cplusplus -typedef struct _D3DXMATRIXA16 : public D3DXMATRIX -{ - _D3DXMATRIXA16() {} - _D3DXMATRIXA16( CONST FLOAT * f): D3DXMATRIX(f) {} - _D3DXMATRIXA16( CONST D3DMATRIX& m): D3DXMATRIX(m) {} - _D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, - FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, - FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, - FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ) : - D3DXMATRIX(_11, _12, _13, _14, - _21, _22, _23, _24, - _31, _32, _33, _34, - _41, _42, _43, _44) {} - void* operator new(size_t s) - { - LPBYTE p = ::new BYTE[s + 16]; - if (p) - { - BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); - p += offset; - p[-1] = offset; - } - return p; - }; - - void* operator new[](size_t s) - { - LPBYTE p = ::new BYTE[s + 16]; - if (p) - { - BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); - p += offset; - p[-1] = offset; - } - return p; - }; - - // This is NOT a virtual operator. If you cast - // to D3DXMATRIX, do not delete using that - void operator delete(void* p) - { - if(p) - { - BYTE* pb = static_cast(p); - pb -= pb[-1]; - ::delete [] pb; - } - }; - - // This is NOT a virtual operator. If you cast - // to D3DXMATRIX, do not delete using that - void operator delete[](void* p) - { - if(p) - { - BYTE* pb = static_cast(p); - pb -= pb[-1]; - ::delete [] pb; - } - }; - - struct _D3DXMATRIXA16& operator=(CONST D3DXMATRIX& rhs) - { - memcpy(&_11, &rhs, sizeof(D3DXMATRIX)); - return *this; - }; -} _D3DXMATRIXA16; - -#else //!__cplusplus -typedef D3DXMATRIX _D3DXMATRIXA16; -#endif //!__cplusplus - -#if _MSC_VER >= 1300 // VC7 -#define _ALIGN_16 __declspec(align(16)) -#else -#define _ALIGN_16 // Earlier compiler may not understand this, do nothing. -#endif - -#define D3DXMATRIXA16 _ALIGN_16 _D3DXMATRIXA16 - -typedef D3DXMATRIXA16 *LPD3DXMATRIXA16; - -//=========================================================================== -// -// Quaternions -// -//=========================================================================== -typedef struct D3DXQUATERNION -{ -#ifdef __cplusplus -public: - D3DXQUATERNION() {} - D3DXQUATERNION( CONST FLOAT * ); - D3DXQUATERNION( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); - - // casting - operator FLOAT* (); - operator CONST FLOAT* () const; - - // assignment operators - D3DXQUATERNION& operator += ( CONST D3DXQUATERNION& ); - D3DXQUATERNION& operator -= ( CONST D3DXQUATERNION& ); - D3DXQUATERNION& operator *= ( CONST D3DXQUATERNION& ); - D3DXQUATERNION& operator *= ( FLOAT ); - D3DXQUATERNION& operator /= ( FLOAT ); - - // unary operators - D3DXQUATERNION operator + () const; - D3DXQUATERNION operator - () const; - - // binary operators - D3DXQUATERNION operator + ( CONST D3DXQUATERNION& ) const; - D3DXQUATERNION operator - ( CONST D3DXQUATERNION& ) const; - D3DXQUATERNION operator * ( CONST D3DXQUATERNION& ) const; - D3DXQUATERNION operator * ( FLOAT ) const; - D3DXQUATERNION operator / ( FLOAT ) const; - - friend D3DXQUATERNION operator * (FLOAT, CONST D3DXQUATERNION& ); - - BOOL operator == ( CONST D3DXQUATERNION& ) const; - BOOL operator != ( CONST D3DXQUATERNION& ) const; - -#endif //__cplusplus - FLOAT x, y, z, w; -} D3DXQUATERNION, *LPD3DXQUATERNION; - - -//=========================================================================== -// -// Planes -// -//=========================================================================== -typedef struct D3DXPLANE -{ -#ifdef __cplusplus -public: - D3DXPLANE() {} - D3DXPLANE( CONST FLOAT* ); - D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d ); - - // casting - operator FLOAT* (); - operator CONST FLOAT* () const; - - // unary operators - D3DXPLANE operator + () const; - D3DXPLANE operator - () const; - - // binary operators - BOOL operator == ( CONST D3DXPLANE& ) const; - BOOL operator != ( CONST D3DXPLANE& ) const; - -#endif //__cplusplus - FLOAT a, b, c, d; -} D3DXPLANE, *LPD3DXPLANE; - - -//=========================================================================== -// -// Colors -// -//=========================================================================== - -typedef struct D3DXCOLOR -{ -#ifdef __cplusplus -public: - D3DXCOLOR() {} - D3DXCOLOR( DWORD argb ); - D3DXCOLOR( CONST FLOAT * ); - D3DXCOLOR( CONST D3DCOLORVALUE& ); - D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a ); - - // casting - operator DWORD () const; - - operator FLOAT* (); - operator CONST FLOAT* () const; - - operator D3DCOLORVALUE* (); - operator CONST D3DCOLORVALUE* () const; - - operator D3DCOLORVALUE& (); - operator CONST D3DCOLORVALUE& () const; - - // assignment operators - D3DXCOLOR& operator += ( CONST D3DXCOLOR& ); - D3DXCOLOR& operator -= ( CONST D3DXCOLOR& ); - D3DXCOLOR& operator *= ( FLOAT ); - D3DXCOLOR& operator /= ( FLOAT ); - - // unary operators - D3DXCOLOR operator + () const; - D3DXCOLOR operator - () const; - - // binary operators - D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const; - D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const; - D3DXCOLOR operator * ( FLOAT ) const; - D3DXCOLOR operator / ( FLOAT ) const; - - friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR& ); - - BOOL operator == ( CONST D3DXCOLOR& ) const; - BOOL operator != ( CONST D3DXCOLOR& ) const; - -#endif //__cplusplus - FLOAT r, g, b, a; -} D3DXCOLOR, *LPD3DXCOLOR; - - - -//=========================================================================== -// -// D3DX math functions: -// -// NOTE: -// * All these functions can take the same object as in and out parameters. -// -// * Out parameters are typically also returned as return values, so that -// the output of one function may be used as a parameter to another. -// -//=========================================================================== - -//-------------------------- -// 2D Vector -//-------------------------- - -// inline - -FLOAT D3DXVec2Length - ( CONST D3DXVECTOR2 *pV ); - -FLOAT D3DXVec2LengthSq - ( CONST D3DXVECTOR2 *pV ); - -FLOAT D3DXVec2Dot - ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -// Z component of ((x1,y1,0) cross (x2,y2,0)) -FLOAT D3DXVec2CCW - ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -D3DXVECTOR2* D3DXVec2Add - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -D3DXVECTOR2* D3DXVec2Subtract - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -// Minimize each component. x = min(x1, x2), y = min(y1, y2) -D3DXVECTOR2* D3DXVec2Minimize - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -// Maximize each component. x = max(x1, x2), y = max(y1, y2) -D3DXVECTOR2* D3DXVec2Maximize - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); - -D3DXVECTOR2* D3DXVec2Scale - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ); - -// Linear interpolation. V1 + s(V2-V1) -D3DXVECTOR2* D3DXVec2Lerp - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, - FLOAT s ); - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -D3DXVECTOR2* WINAPI D3DXVec2Normalize - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV ); - -// Hermite interpolation between position V1, tangent T1 (when s == 0) -// and position V2, tangent T2 (when s == 1). -D3DXVECTOR2* WINAPI D3DXVec2Hermite - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pT1, - CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pT2, FLOAT s ); - -// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) -D3DXVECTOR2* WINAPI D3DXVec2CatmullRom - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV0, CONST D3DXVECTOR2 *pV1, - CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pV3, FLOAT s ); - -// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) -D3DXVECTOR2* WINAPI D3DXVec2BaryCentric - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, - CONST D3DXVECTOR2 *pV3, FLOAT f, FLOAT g); - -// Transform (x, y, 0, 1) by matrix. -D3DXVECTOR4* WINAPI D3DXVec2Transform - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); - -// Transform (x, y, 0, 1) by matrix, project result back into w=1. -D3DXVECTOR2* WINAPI D3DXVec2TransformCoord - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); - -// Transform (x, y, 0, 0) by matrix. -D3DXVECTOR2* WINAPI D3DXVec2TransformNormal - ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); - -#ifdef __cplusplus -} -#endif - - -//-------------------------- -// 3D Vector -//-------------------------- - -// inline - -FLOAT D3DXVec3Length - ( CONST D3DXVECTOR3 *pV ); - -FLOAT D3DXVec3LengthSq - ( CONST D3DXVECTOR3 *pV ); - -FLOAT D3DXVec3Dot - ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -D3DXVECTOR3* D3DXVec3Cross - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -D3DXVECTOR3* D3DXVec3Add - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -D3DXVECTOR3* D3DXVec3Subtract - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... -D3DXVECTOR3* D3DXVec3Minimize - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... -D3DXVECTOR3* D3DXVec3Maximize - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); - -D3DXVECTOR3* D3DXVec3Scale - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s); - -// Linear interpolation. V1 + s(V2-V1) -D3DXVECTOR3* D3DXVec3Lerp - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, - FLOAT s ); - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -D3DXVECTOR3* WINAPI D3DXVec3Normalize - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ); - -// Hermite interpolation between position V1, tangent T1 (when s == 0) -// and position V2, tangent T2 (when s == 1). -D3DXVECTOR3* WINAPI D3DXVec3Hermite - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pT1, - CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pT2, FLOAT s ); - -// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) -D3DXVECTOR3* WINAPI D3DXVec3CatmullRom - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV0, CONST D3DXVECTOR3 *pV1, - CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pV3, FLOAT s ); - -// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) -D3DXVECTOR3* WINAPI D3DXVec3BaryCentric - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, - CONST D3DXVECTOR3 *pV3, FLOAT f, FLOAT g); - -// Transform (x, y, z, 1) by matrix. -D3DXVECTOR4* WINAPI D3DXVec3Transform - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); - -// Transform (x, y, z, 1) by matrix, project result back into w=1. -D3DXVECTOR3* WINAPI D3DXVec3TransformCoord - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); - -// Transform (x, y, z, 0) by matrix. If you transforming a normal by a -// non-affine matrix, the matrix you pass to this function should be the -// transpose of the inverse of the matrix you would use to transform a coord. -D3DXVECTOR3* WINAPI D3DXVec3TransformNormal - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); - -// Project vector from object space into screen space -D3DXVECTOR3* WINAPI D3DXVec3Project - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT8 *pViewport, - CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); - -// Project vector from screen space into object space -D3DXVECTOR3* WINAPI D3DXVec3Unproject - ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT8 *pViewport, - CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); - -#ifdef __cplusplus -} -#endif - - - -//-------------------------- -// 4D Vector -//-------------------------- - -// inline - -FLOAT D3DXVec4Length - ( CONST D3DXVECTOR4 *pV ); - -FLOAT D3DXVec4LengthSq - ( CONST D3DXVECTOR4 *pV ); - -FLOAT D3DXVec4Dot - ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ); - -D3DXVECTOR4* D3DXVec4Add - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); - -D3DXVECTOR4* D3DXVec4Subtract - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); - -// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... -D3DXVECTOR4* D3DXVec4Minimize - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); - -// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... -D3DXVECTOR4* D3DXVec4Maximize - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); - -D3DXVECTOR4* D3DXVec4Scale - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s); - -// Linear interpolation. V1 + s(V2-V1) -D3DXVECTOR4* D3DXVec4Lerp - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, - FLOAT s ); - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -// Cross-product in 4 dimensions. -D3DXVECTOR4* WINAPI D3DXVec4Cross - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, - CONST D3DXVECTOR4 *pV3); - -D3DXVECTOR4* WINAPI D3DXVec4Normalize - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); - -// Hermite interpolation between position V1, tangent T1 (when s == 0) -// and position V2, tangent T2 (when s == 1). -D3DXVECTOR4* WINAPI D3DXVec4Hermite - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pT1, - CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pT2, FLOAT s ); - -// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) -D3DXVECTOR4* WINAPI D3DXVec4CatmullRom - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV0, CONST D3DXVECTOR4 *pV1, - CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pV3, FLOAT s ); - -// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) -D3DXVECTOR4* WINAPI D3DXVec4BaryCentric - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, - CONST D3DXVECTOR4 *pV3, FLOAT f, FLOAT g); - -// Transform vector by matrix. -D3DXVECTOR4* WINAPI D3DXVec4Transform - ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); - -#ifdef __cplusplus -} -#endif - - -//-------------------------- -// 4D Matrix -//-------------------------- - -// inline - -D3DXMATRIX* D3DXMatrixIdentity - ( D3DXMATRIX *pOut ); - -BOOL D3DXMatrixIsIdentity - ( CONST D3DXMATRIX *pM ); - - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -FLOAT WINAPI D3DXMatrixfDeterminant - ( CONST D3DXMATRIX *pM ); - -D3DXMATRIX* WINAPI D3DXMatrixTranspose - ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); - -// Matrix multiplication. The result represents the transformation M2 -// followed by the transformation M1. (Out = M1 * M2) -D3DXMATRIX* WINAPI D3DXMatrixMultiply - ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); - -// Matrix multiplication, followed by a transpose. (Out = T(M1 * M2)) -D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose - ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); - -// Calculate inverse of matrix. Inversion my fail, in which case NULL will -// be returned. The determinant of pM is also returned it pfDeterminant -// is non-NULL. -D3DXMATRIX* WINAPI D3DXMatrixInverse - ( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); - -// Build a matrix which scales by (sx, sy, sz) -D3DXMATRIX* WINAPI D3DXMatrixScaling - ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); - -// Build a matrix which translates by (x, y, z) -D3DXMATRIX* WINAPI D3DXMatrixTranslation - ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); - -// Build a matrix which rotates around the X axis -D3DXMATRIX* WINAPI D3DXMatrixRotationX - ( D3DXMATRIX *pOut, FLOAT Angle ); - -// Build a matrix which rotates around the Y axis -D3DXMATRIX* WINAPI D3DXMatrixRotationY - ( D3DXMATRIX *pOut, FLOAT Angle ); - -// Build a matrix which rotates around the Z axis -D3DXMATRIX* WINAPI D3DXMatrixRotationZ - ( D3DXMATRIX *pOut, FLOAT Angle ); - -// Build a matrix which rotates around an arbitrary axis -D3DXMATRIX* WINAPI D3DXMatrixRotationAxis - ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); - -// Build a matrix from a quaternion -D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion - ( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ); - -// Yaw around the Y axis, a pitch around the X axis, -// and a roll around the Z axis. -D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll - ( D3DXMATRIX *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); - - -// Build transformation matrix. NULL arguments are treated as identity. -// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt -D3DXMATRIX* WINAPI D3DXMatrixTransformation - ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pScalingCenter, - CONST D3DXQUATERNION *pScalingRotation, CONST D3DXVECTOR3 *pScaling, - CONST D3DXVECTOR3 *pRotationCenter, CONST D3DXQUATERNION *pRotation, - CONST D3DXVECTOR3 *pTranslation); - -// Build affine transformation matrix. NULL arguments are treated as identity. -// Mout = Ms * Mrc-1 * Mr * Mrc * Mt -D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation - ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR3 *pRotationCenter, - CONST D3DXQUATERNION *pRotation, CONST D3DXVECTOR3 *pTranslation); - -// Build a lookat matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixLookAtRH - ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, - CONST D3DXVECTOR3 *pUp ); - -// Build a lookat matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixLookAtLH - ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, - CONST D3DXVECTOR3 *pUp ); - -// Build a perspective projection matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH - ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); - -// Build a perspective projection matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH - ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); - -// Build a perspective projection matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH - ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); - -// Build a perspective projection matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH - ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); - -// Build a perspective projection matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH - ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, - FLOAT zf ); - -// Build a perspective projection matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH - ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, - FLOAT zf ); - -// Build an ortho projection matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixOrthoRH - ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); - -// Build an ortho projection matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixOrthoLH - ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); - -// Build an ortho projection matrix. (right-handed) -D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH - ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, - FLOAT zf ); - -// Build an ortho projection matrix. (left-handed) -D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH - ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, - FLOAT zf ); - -// Build a matrix which flattens geometry into a plane, as if casting -// a shadow from a light. -D3DXMATRIX* WINAPI D3DXMatrixShadow - ( D3DXMATRIX *pOut, CONST D3DXVECTOR4 *pLight, - CONST D3DXPLANE *pPlane ); - -// Build a matrix which reflects the coordinate system about a plane -D3DXMATRIX* WINAPI D3DXMatrixReflect - ( D3DXMATRIX *pOut, CONST D3DXPLANE *pPlane ); - -#ifdef __cplusplus -} -#endif - - -//-------------------------- -// Quaternion -//-------------------------- - -// inline - -FLOAT D3DXQuaternionLength - ( CONST D3DXQUATERNION *pQ ); - -// Length squared, or "norm" -FLOAT D3DXQuaternionLengthSq - ( CONST D3DXQUATERNION *pQ ); - -FLOAT D3DXQuaternionDot - ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ); - -// (0, 0, 0, 1) -D3DXQUATERNION* D3DXQuaternionIdentity - ( D3DXQUATERNION *pOut ); - -BOOL D3DXQuaternionIsIdentity - ( CONST D3DXQUATERNION *pQ ); - -// (-x, -y, -z, w) -D3DXQUATERNION* D3DXQuaternionConjugate - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -// Compute a quaternin's axis and angle of rotation. Expects unit quaternions. -void WINAPI D3DXQuaternionToAxisAngle - ( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle ); - -// Build a quaternion from a rotation matrix. -D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix - ( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM); - -// Rotation about arbitrary axis. -D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis - ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); - -// Yaw around the Y axis, a pitch around the X axis, -// and a roll around the Z axis. -D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll - ( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); - -// Quaternion multiplication. The result represents the rotation Q2 -// followed by the rotation Q1. (Out = Q2 * Q1) -D3DXQUATERNION* WINAPI D3DXQuaternionMultiply - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, - CONST D3DXQUATERNION *pQ2 ); - -D3DXQUATERNION* WINAPI D3DXQuaternionNormalize - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - -// Conjugate and re-norm -D3DXQUATERNION* WINAPI D3DXQuaternionInverse - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - -// Expects unit quaternions. -// if q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v) -D3DXQUATERNION* WINAPI D3DXQuaternionLn - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - -// Expects pure quaternions. (w == 0) w is ignored in calculation. -// if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) -D3DXQUATERNION* WINAPI D3DXQuaternionExp - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - -// Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). -// Expects unit quaternions. -D3DXQUATERNION* WINAPI D3DXQuaternionSlerp - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, - CONST D3DXQUATERNION *pQ2, FLOAT t ); - -// Spherical quadrangle interpolation. -// Slerp(Slerp(Q1, C, t), Slerp(A, B, t), 2t(1-t)) -D3DXQUATERNION* WINAPI D3DXQuaternionSquad - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, - CONST D3DXQUATERNION *pA, CONST D3DXQUATERNION *pB, - CONST D3DXQUATERNION *pC, FLOAT t ); - -// Setup control points for spherical quadrangle interpolation -// from Q1 to Q2. The control points are chosen in such a way -// to ensure the continuity of tangents with adjacent segments. -void WINAPI D3DXQuaternionSquadSetup - ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, - CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, - CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); - -// Barycentric interpolation. -// Slerp(Slerp(Q1, Q2, f+g), Slerp(Q1, Q3, f+g), g/(f+g)) -D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric - ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, - CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3, - FLOAT f, FLOAT g ); - -#ifdef __cplusplus -} -#endif - - -//-------------------------- -// Plane -//-------------------------- - -// inline - -// ax + by + cz + dw -FLOAT D3DXPlaneDot - ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV); - -// ax + by + cz + d -FLOAT D3DXPlaneDotCoord - ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); - -// ax + by + cz -FLOAT D3DXPlaneDotNormal - ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -// Normalize plane (so that |a,b,c| == 1) -D3DXPLANE* WINAPI D3DXPlaneNormalize - ( D3DXPLANE *pOut, CONST D3DXPLANE *pP); - -// Find the intersection between a plane and a line. If the line is -// parallel to the plane, NULL is returned. -D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine - ( D3DXVECTOR3 *pOut, CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV1, - CONST D3DXVECTOR3 *pV2); - -// Construct a plane from a point and a normal -D3DXPLANE* WINAPI D3DXPlaneFromPointNormal - ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pPoint, CONST D3DXVECTOR3 *pNormal); - -// Construct a plane from 3 points -D3DXPLANE* WINAPI D3DXPlaneFromPoints - ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, - CONST D3DXVECTOR3 *pV3); - -// Transform a plane by a matrix. The vector (a,b,c) must be normal. -// M should be the inverse transpose of the transformation desired. -D3DXPLANE* WINAPI D3DXPlaneTransform - ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); - -#ifdef __cplusplus -} -#endif - - -//-------------------------- -// Color -//-------------------------- - -// inline - -// (1-r, 1-g, 1-b, a) -D3DXCOLOR* D3DXColorNegative - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC); - -D3DXCOLOR* D3DXColorAdd - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); - -D3DXCOLOR* D3DXColorSubtract - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); - -D3DXCOLOR* D3DXColorScale - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); - -// (r1*r2, g1*g2, b1*b2, a1*a2) -D3DXCOLOR* D3DXColorModulate - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); - -// Linear interpolation of r,g,b, and a. C1 + s(C2-C1) -D3DXCOLOR* D3DXColorLerp - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s); - -// non-inline -#ifdef __cplusplus -extern "C" { -#endif - -// Interpolate r,g,b between desaturated color and color. -// DesaturatedColor + s(Color - DesaturatedColor) -D3DXCOLOR* WINAPI D3DXColorAdjustSaturation - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); - -// Interpolate r,g,b between 50% grey and color. Grey + s(Color - Grey) -D3DXCOLOR* WINAPI D3DXColorAdjustContrast - (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT c); - -#ifdef __cplusplus -} -#endif - - - - -//-------------------------- -// Misc -//-------------------------- - -#ifdef __cplusplus -extern "C" { -#endif - -// Calculate Fresnel term given the cosine of theta (likely obtained by -// taking the dot of two normals), and the refraction index of the material. -FLOAT WINAPI D3DXFresnelTerm - (FLOAT CosTheta, FLOAT RefractionIndex); - -#ifdef __cplusplus -} -#endif - - - -//=========================================================================== -// -// Matrix Stack -// -//=========================================================================== - -typedef interface ID3DXMatrixStack ID3DXMatrixStack; -typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; - -// {E3357330-CC5E-11d2-A434-00A0C90629A8} -DEFINE_GUID( IID_ID3DXMatrixStack, -0xe3357330, 0xcc5e, 0x11d2, 0xa4, 0x34, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); - - -#undef INTERFACE -#define INTERFACE ID3DXMatrixStack - -DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) -{ - // - // IUnknown methods - // - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // - // ID3DXMatrixStack methods - // - - // Pops the top of the stack, returns the current top - // *after* popping the top. - STDMETHOD(Pop)(THIS) PURE; - - // Pushes the stack by one, duplicating the current matrix. - STDMETHOD(Push)(THIS) PURE; - - // Loads identity in the current matrix. - STDMETHOD(LoadIdentity)(THIS) PURE; - - // Loads the given matrix into the current matrix - STDMETHOD(LoadMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; - - // Right-Multiplies the given matrix to the current matrix. - // (transformation is about the current world origin) - STDMETHOD(MultMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; - - // Left-Multiplies the given matrix to the current matrix - // (transformation is about the local origin of the object) - STDMETHOD(MultMatrixLocal)(THIS_ CONST D3DXMATRIX* pM ) PURE; - - // Right multiply the current matrix with the computed rotation - // matrix, counterclockwise about the given axis with the given angle. - // (rotation is about the current world origin) - STDMETHOD(RotateAxis) - (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; - - // Left multiply the current matrix with the computed rotation - // matrix, counterclockwise about the given axis with the given angle. - // (rotation is about the local origin of the object) - STDMETHOD(RotateAxisLocal) - (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; - - // Right multiply the current matrix with the computed rotation - // matrix. All angles are counterclockwise. (rotation is about the - // current world origin) - - // The rotation is composed of a yaw around the Y axis, a pitch around - // the X axis, and a roll around the Z axis. - STDMETHOD(RotateYawPitchRoll) - (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; - - // Left multiply the current matrix with the computed rotation - // matrix. All angles are counterclockwise. (rotation is about the - // local origin of the object) - - // The rotation is composed of a yaw around the Y axis, a pitch around - // the X axis, and a roll around the Z axis. - STDMETHOD(RotateYawPitchRollLocal) - (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; - - // Right multiply the current matrix with the computed scale - // matrix. (transformation is about the current world origin) - STDMETHOD(Scale)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; - - // Left multiply the current matrix with the computed scale - // matrix. (transformation is about the local origin of the object) - STDMETHOD(ScaleLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; - - // Right multiply the current matrix with the computed translation - // matrix. (transformation is about the current world origin) - STDMETHOD(Translate)(THIS_ FLOAT x, FLOAT y, FLOAT z ) PURE; - - // Left multiply the current matrix with the computed translation - // matrix. (transformation is about the local origin of the object) - STDMETHOD(TranslateLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; - - /* Obtain the current matrix at the top of the stack */ - STDMETHOD_(D3DXMATRIX*, GetTop)(THIS) PURE; -}; - -#ifdef __cplusplus -extern "C" { -#endif - -HRESULT WINAPI - D3DXCreateMatrixStack( - DWORD Flags, - LPD3DXMATRIXSTACK* ppStack); - -#ifdef __cplusplus -} -#endif - -#include "d3dx8math.inl" - -#pragma warning(default:4201) - -#endif /* __D3DX8MATH_H__ */ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8math.h +// Content: D3DX math types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8MATH_H__ +#define __D3DX8MATH_H__ + +#include +#pragma warning(disable:4201) /* anonymous unions warning */ + +//=========================================================================== +// +// General purpose utilities +// +//=========================================================================== +#define D3DX_PI ((FLOAT) 3.141592654f) +#define D3DX_1BYPI ((FLOAT) 0.318309886f) + +#define D3DXToRadian( degree ) ((degree) * (D3DX_PI / 180.0f)) +#define D3DXToDegree( radian ) ((radian) * (180.0f / D3DX_PI)) + + + +//=========================================================================== +// +// Vectors +// +//=========================================================================== + +//-------------------------- +// 2D Vector +//-------------------------- +typedef struct D3DXVECTOR2 +{ +#ifdef __cplusplus +public: + D3DXVECTOR2() {}; + D3DXVECTOR2( CONST FLOAT * ); + D3DXVECTOR2( FLOAT x, FLOAT y ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR2& operator += ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator -= ( CONST D3DXVECTOR2& ); + D3DXVECTOR2& operator *= ( FLOAT ); + D3DXVECTOR2& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR2 operator + () const; + D3DXVECTOR2 operator - () const; + + // binary operators + D3DXVECTOR2 operator + ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator - ( CONST D3DXVECTOR2& ) const; + D3DXVECTOR2 operator * ( FLOAT ) const; + D3DXVECTOR2 operator / ( FLOAT ) const; + + friend D3DXVECTOR2 operator * ( FLOAT, CONST D3DXVECTOR2& ); + + BOOL operator == ( CONST D3DXVECTOR2& ) const; + BOOL operator != ( CONST D3DXVECTOR2& ) const; + + +public: +#endif //__cplusplus + FLOAT x, y; +} D3DXVECTOR2, *LPD3DXVECTOR2; + + +//-------------------------- +// 3D Vector +//-------------------------- +#ifdef __cplusplus +typedef struct D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {}; + D3DXVECTOR3( CONST FLOAT * ); + D3DXVECTOR3( CONST D3DVECTOR& ); + D3DXVECTOR3( FLOAT x, FLOAT y, FLOAT z ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR3& operator += ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator -= ( CONST D3DXVECTOR3& ); + D3DXVECTOR3& operator *= ( FLOAT ); + D3DXVECTOR3& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR3 operator + () const; + D3DXVECTOR3 operator - () const; + + // binary operators + D3DXVECTOR3 operator + ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator - ( CONST D3DXVECTOR3& ) const; + D3DXVECTOR3 operator * ( FLOAT ) const; + D3DXVECTOR3 operator / ( FLOAT ) const; + + friend D3DXVECTOR3 operator * ( FLOAT, CONST struct D3DXVECTOR3& ); + + BOOL operator == ( CONST D3DXVECTOR3& ) const; + BOOL operator != ( CONST D3DXVECTOR3& ) const; + +} D3DXVECTOR3, *LPD3DXVECTOR3; + +#else //!__cplusplus +typedef struct _D3DVECTOR D3DXVECTOR3, *LPD3DXVECTOR3; +#endif //!__cplusplus + + +//-------------------------- +// 4D Vector +//-------------------------- +typedef struct D3DXVECTOR4 +{ +#ifdef __cplusplus +public: + D3DXVECTOR4() {}; + D3DXVECTOR4( CONST FLOAT* ); + D3DXVECTOR4( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXVECTOR4& operator += ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator -= ( CONST D3DXVECTOR4& ); + D3DXVECTOR4& operator *= ( FLOAT ); + D3DXVECTOR4& operator /= ( FLOAT ); + + // unary operators + D3DXVECTOR4 operator + () const; + D3DXVECTOR4 operator - () const; + + // binary operators + D3DXVECTOR4 operator + ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator - ( CONST D3DXVECTOR4& ) const; + D3DXVECTOR4 operator * ( FLOAT ) const; + D3DXVECTOR4 operator / ( FLOAT ) const; + + friend D3DXVECTOR4 operator * ( FLOAT, CONST D3DXVECTOR4& ); + + BOOL operator == ( CONST D3DXVECTOR4& ) const; + BOOL operator != ( CONST D3DXVECTOR4& ) const; + +public: +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXVECTOR4, *LPD3DXVECTOR4; + + +//=========================================================================== +// +// Matrices +// +//=========================================================================== +#ifdef __cplusplus +typedef struct D3DXMATRIX : public D3DMATRIX +{ +public: + D3DXMATRIX() {}; + D3DXMATRIX( CONST FLOAT * ); + D3DXMATRIX( CONST D3DMATRIX& ); + D3DXMATRIX( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ); + + + // access grants + FLOAT& operator () ( UINT Row, UINT Col ); + FLOAT operator () ( UINT Row, UINT Col ) const; + + // casting operators + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXMATRIX& operator *= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator += ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator -= ( CONST D3DXMATRIX& ); + D3DXMATRIX& operator *= ( FLOAT ); + D3DXMATRIX& operator /= ( FLOAT ); + + // unary operators + D3DXMATRIX operator + () const; + D3DXMATRIX operator - () const; + + // binary operators + D3DXMATRIX operator * ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator + ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator - ( CONST D3DXMATRIX& ) const; + D3DXMATRIX operator * ( FLOAT ) const; + D3DXMATRIX operator / ( FLOAT ) const; + + friend D3DXMATRIX operator * ( FLOAT, CONST D3DXMATRIX& ); + + BOOL operator == ( CONST D3DXMATRIX& ) const; + BOOL operator != ( CONST D3DXMATRIX& ) const; + +} D3DXMATRIX, *LPD3DXMATRIX; + +#else //!__cplusplus +typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; +#endif //!__cplusplus + +//=========================================================================== +// +// Aligned Matrices +// +// This class helps keep matrices 16-byte aligned as preferred by P4 cpus. +// It aligns matrices on the stack and on the heap or in global scope. +// It does this using __declspec(align(16)) which works on VC7 and on VC 6 +// with the processor pack. Unfortunately there is no way to detect the +// latter so this is turned on only on VC7. On other compilers this is the +// the same as D3DXMATRIX. +// Using this class on a compiler that does not actually do the alignment +// can be dangerous since it will not expose bugs that ignore alignment. +// E.g if an object of this class in inside a struct or class, and some code +// memcopys data in it assuming tight packing. This could break on a compiler +// that eventually start aligning the matrix. +// +//=========================================================================== +#ifdef __cplusplus +typedef struct _D3DXMATRIXA16 : public D3DXMATRIX +{ + _D3DXMATRIXA16() {} + _D3DXMATRIXA16( CONST FLOAT * f): D3DXMATRIX(f) {} + _D3DXMATRIXA16( CONST D3DMATRIX& m): D3DXMATRIX(m) {} + _D3DXMATRIXA16( FLOAT _11, FLOAT _12, FLOAT _13, FLOAT _14, + FLOAT _21, FLOAT _22, FLOAT _23, FLOAT _24, + FLOAT _31, FLOAT _32, FLOAT _33, FLOAT _34, + FLOAT _41, FLOAT _42, FLOAT _43, FLOAT _44 ) : + D3DXMATRIX(_11, _12, _13, _14, + _21, _22, _23, _24, + _31, _32, _33, _34, + _41, _42, _43, _44) {} + void* operator new(size_t s) + { + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; + }; + + void* operator new[](size_t s) + { + LPBYTE p = ::new BYTE[s + 16]; + if (p) + { + BYTE offset = (BYTE)(16 - ((UINT_PTR)p & 15)); + p += offset; + p[-1] = offset; + } + return p; + }; + + // This is NOT a virtual operator. If you cast + // to D3DXMATRIX, do not delete using that + void operator delete(void* p) + { + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } + }; + + // This is NOT a virtual operator. If you cast + // to D3DXMATRIX, do not delete using that + void operator delete[](void* p) + { + if(p) + { + BYTE* pb = static_cast(p); + pb -= pb[-1]; + ::delete [] pb; + } + }; + + struct _D3DXMATRIXA16& operator=(CONST D3DXMATRIX& rhs) + { + memcpy(&_11, &rhs, sizeof(D3DXMATRIX)); + return *this; + }; +} _D3DXMATRIXA16; + +#else //!__cplusplus +typedef D3DXMATRIX _D3DXMATRIXA16; +#endif //!__cplusplus + +#if _MSC_VER >= 1300 // VC7 +#define _ALIGN_16 __declspec(align(16)) +#else +#define _ALIGN_16 // Earlier compiler may not understand this, do nothing. +#endif + +#define D3DXMATRIXA16 _ALIGN_16 _D3DXMATRIXA16 + +typedef D3DXMATRIXA16 *LPD3DXMATRIXA16; + +//=========================================================================== +// +// Quaternions +// +//=========================================================================== +typedef struct D3DXQUATERNION +{ +#ifdef __cplusplus +public: + D3DXQUATERNION() {} + D3DXQUATERNION( CONST FLOAT * ); + D3DXQUATERNION( FLOAT x, FLOAT y, FLOAT z, FLOAT w ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // assignment operators + D3DXQUATERNION& operator += ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator -= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( CONST D3DXQUATERNION& ); + D3DXQUATERNION& operator *= ( FLOAT ); + D3DXQUATERNION& operator /= ( FLOAT ); + + // unary operators + D3DXQUATERNION operator + () const; + D3DXQUATERNION operator - () const; + + // binary operators + D3DXQUATERNION operator + ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator - ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( CONST D3DXQUATERNION& ) const; + D3DXQUATERNION operator * ( FLOAT ) const; + D3DXQUATERNION operator / ( FLOAT ) const; + + friend D3DXQUATERNION operator * (FLOAT, CONST D3DXQUATERNION& ); + + BOOL operator == ( CONST D3DXQUATERNION& ) const; + BOOL operator != ( CONST D3DXQUATERNION& ) const; + +#endif //__cplusplus + FLOAT x, y, z, w; +} D3DXQUATERNION, *LPD3DXQUATERNION; + + +//=========================================================================== +// +// Planes +// +//=========================================================================== +typedef struct D3DXPLANE +{ +#ifdef __cplusplus +public: + D3DXPLANE() {} + D3DXPLANE( CONST FLOAT* ); + D3DXPLANE( FLOAT a, FLOAT b, FLOAT c, FLOAT d ); + + // casting + operator FLOAT* (); + operator CONST FLOAT* () const; + + // unary operators + D3DXPLANE operator + () const; + D3DXPLANE operator - () const; + + // binary operators + BOOL operator == ( CONST D3DXPLANE& ) const; + BOOL operator != ( CONST D3DXPLANE& ) const; + +#endif //__cplusplus + FLOAT a, b, c, d; +} D3DXPLANE, *LPD3DXPLANE; + + +//=========================================================================== +// +// Colors +// +//=========================================================================== + +typedef struct D3DXCOLOR +{ +#ifdef __cplusplus +public: + D3DXCOLOR() {} + D3DXCOLOR( DWORD argb ); + D3DXCOLOR( CONST FLOAT * ); + D3DXCOLOR( CONST D3DCOLORVALUE& ); + D3DXCOLOR( FLOAT r, FLOAT g, FLOAT b, FLOAT a ); + + // casting + operator DWORD () const; + + operator FLOAT* (); + operator CONST FLOAT* () const; + + operator D3DCOLORVALUE* (); + operator CONST D3DCOLORVALUE* () const; + + operator D3DCOLORVALUE& (); + operator CONST D3DCOLORVALUE& () const; + + // assignment operators + D3DXCOLOR& operator += ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator -= ( CONST D3DXCOLOR& ); + D3DXCOLOR& operator *= ( FLOAT ); + D3DXCOLOR& operator /= ( FLOAT ); + + // unary operators + D3DXCOLOR operator + () const; + D3DXCOLOR operator - () const; + + // binary operators + D3DXCOLOR operator + ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator - ( CONST D3DXCOLOR& ) const; + D3DXCOLOR operator * ( FLOAT ) const; + D3DXCOLOR operator / ( FLOAT ) const; + + friend D3DXCOLOR operator * (FLOAT, CONST D3DXCOLOR& ); + + BOOL operator == ( CONST D3DXCOLOR& ) const; + BOOL operator != ( CONST D3DXCOLOR& ) const; + +#endif //__cplusplus + FLOAT r, g, b, a; +} D3DXCOLOR, *LPD3DXCOLOR; + + + +//=========================================================================== +// +// D3DX math functions: +// +// NOTE: +// * All these functions can take the same object as in and out parameters. +// +// * Out parameters are typically also returned as return values, so that +// the output of one function may be used as a parameter to another. +// +//=========================================================================== + +//-------------------------- +// 2D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec2Length + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2LengthSq + ( CONST D3DXVECTOR2 *pV ); + +FLOAT D3DXVec2Dot + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Z component of ((x1,y1,0) cross (x2,y2,0)) +FLOAT D3DXVec2CCW + ( CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Add + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Subtract + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2) +D3DXVECTOR2* D3DXVec2Minimize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2) +D3DXVECTOR2* D3DXVec2Maximize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2 ); + +D3DXVECTOR2* D3DXVec2Scale + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, FLOAT s ); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR2* D3DXVec2Lerp + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR2* WINAPI D3DXVec2Normalize + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR2* WINAPI D3DXVec2Hermite + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pT1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR2* WINAPI D3DXVec2CatmullRom + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV0, CONST D3DXVECTOR2 *pV1, + CONST D3DXVECTOR2 *pV2, CONST D3DXVECTOR2 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR2* WINAPI D3DXVec2BaryCentric + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV1, CONST D3DXVECTOR2 *pV2, + CONST D3DXVECTOR2 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, 0, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec2Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 1) by matrix, project result back into w=1. +D3DXVECTOR2* WINAPI D3DXVec2TransformCoord + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, 0, 0) by matrix. +D3DXVECTOR2* WINAPI D3DXVec2TransformNormal + ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 3D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec3Length + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3LengthSq + ( CONST D3DXVECTOR3 *pV ); + +FLOAT D3DXVec3Dot + ( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Cross + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Add + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Subtract + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR3* D3DXVec3Minimize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR3* D3DXVec3Maximize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ); + +D3DXVECTOR3* D3DXVec3Scale + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR3* D3DXVec3Lerp + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +D3DXVECTOR3* WINAPI D3DXVec3Normalize + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR3* WINAPI D3DXVec3Hermite + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pT1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR3* WINAPI D3DXVec3CatmullRom + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV0, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2, CONST D3DXVECTOR3 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR3* WINAPI D3DXVec3BaryCentric + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3, FLOAT f, FLOAT g); + +// Transform (x, y, z, 1) by matrix. +D3DXVECTOR4* WINAPI D3DXVec3Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 1) by matrix, project result back into w=1. +D3DXVECTOR3* WINAPI D3DXVec3TransformCoord + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the +// transpose of the inverse of the matrix you would use to transform a coord. +D3DXVECTOR3* WINAPI D3DXVec3TransformNormal + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +// Project vector from object space into screen space +D3DXVECTOR3* WINAPI D3DXVec3Project + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT8 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +// Project vector from screen space into object space +D3DXVECTOR3* WINAPI D3DXVec3Unproject + ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT8 *pViewport, + CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); + +#ifdef __cplusplus +} +#endif + + + +//-------------------------- +// 4D Vector +//-------------------------- + +// inline + +FLOAT D3DXVec4Length + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4LengthSq + ( CONST D3DXVECTOR4 *pV ); + +FLOAT D3DXVec4Dot + ( CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2 ); + +D3DXVECTOR4* D3DXVec4Add + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Subtract + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Minimize each component. x = min(x1, x2), y = min(y1, y2), ... +D3DXVECTOR4* D3DXVec4Minimize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +// Maximize each component. x = max(x1, x2), y = max(y1, y2), ... +D3DXVECTOR4* D3DXVec4Maximize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2); + +D3DXVECTOR4* D3DXVec4Scale + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, FLOAT s); + +// Linear interpolation. V1 + s(V2-V1) +D3DXVECTOR4* D3DXVec4Lerp + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + FLOAT s ); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Cross-product in 4 dimensions. +D3DXVECTOR4* WINAPI D3DXVec4Cross + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3); + +D3DXVECTOR4* WINAPI D3DXVec4Normalize + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +// Hermite interpolation between position V1, tangent T1 (when s == 0) +// and position V2, tangent T2 (when s == 1). +D3DXVECTOR4* WINAPI D3DXVec4Hermite + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pT1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pT2, FLOAT s ); + +// CatmullRom interpolation between V1 (when s == 0) and V2 (when s == 1) +D3DXVECTOR4* WINAPI D3DXVec4CatmullRom + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV0, CONST D3DXVECTOR4 *pV1, + CONST D3DXVECTOR4 *pV2, CONST D3DXVECTOR4 *pV3, FLOAT s ); + +// Barycentric coordinates. V1 + f(V2-V1) + g(V3-V1) +D3DXVECTOR4* WINAPI D3DXVec4BaryCentric + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV1, CONST D3DXVECTOR4 *pV2, + CONST D3DXVECTOR4 *pV3, FLOAT f, FLOAT g); + +// Transform vector by matrix. +D3DXVECTOR4* WINAPI D3DXVec4Transform + ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// 4D Matrix +//-------------------------- + +// inline + +D3DXMATRIX* D3DXMatrixIdentity + ( D3DXMATRIX *pOut ); + +BOOL D3DXMatrixIsIdentity + ( CONST D3DXMATRIX *pM ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +FLOAT WINAPI D3DXMatrixfDeterminant + ( CONST D3DXMATRIX *pM ); + +D3DXMATRIX* WINAPI D3DXMatrixTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +// Matrix multiplication. The result represents the transformation M2 +// followed by the transformation M1. (Out = M1 * M2) +D3DXMATRIX* WINAPI D3DXMatrixMultiply + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Matrix multiplication, followed by a transpose. (Out = T(M1 * M2)) +D3DXMATRIX* WINAPI D3DXMatrixMultiplyTranspose + ( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); + +// Calculate inverse of matrix. Inversion my fail, in which case NULL will +// be returned. The determinant of pM is also returned it pfDeterminant +// is non-NULL. +D3DXMATRIX* WINAPI D3DXMatrixInverse + ( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +// Build a matrix which scales by (sx, sy, sz) +D3DXMATRIX* WINAPI D3DXMatrixScaling + ( D3DXMATRIX *pOut, FLOAT sx, FLOAT sy, FLOAT sz ); + +// Build a matrix which translates by (x, y, z) +D3DXMATRIX* WINAPI D3DXMatrixTranslation + ( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build a matrix which rotates around the X axis +D3DXMATRIX* WINAPI D3DXMatrixRotationX + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Y axis +D3DXMATRIX* WINAPI D3DXMatrixRotationY + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around the Z axis +D3DXMATRIX* WINAPI D3DXMatrixRotationZ + ( D3DXMATRIX *pOut, FLOAT Angle ); + +// Build a matrix which rotates around an arbitrary axis +D3DXMATRIX* WINAPI D3DXMatrixRotationAxis + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Build a matrix from a quaternion +D3DXMATRIX* WINAPI D3DXMatrixRotationQuaternion + ( D3DXMATRIX *pOut, CONST D3DXQUATERNION *pQ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXMATRIX* WINAPI D3DXMatrixRotationYawPitchRoll + ( D3DXMATRIX *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + + +// Build transformation matrix. NULL arguments are treated as identity. +// Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixTransformation + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pScalingCenter, + CONST D3DXQUATERNION *pScalingRotation, CONST D3DXVECTOR3 *pScaling, + CONST D3DXVECTOR3 *pRotationCenter, CONST D3DXQUATERNION *pRotation, + CONST D3DXVECTOR3 *pTranslation); + +// Build affine transformation matrix. NULL arguments are treated as identity. +// Mout = Ms * Mrc-1 * Mr * Mrc * Mt +D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR3 *pRotationCenter, + CONST D3DXQUATERNION *pRotation, CONST D3DXVECTOR3 *pTranslation); + +// Build a lookat matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtRH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a lookat matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixLookAtLH + ( D3DXMATRIX *pOut, CONST D3DXVECTOR3 *pEye, CONST D3DXVECTOR3 *pAt, + CONST D3DXVECTOR3 *pUp ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovRH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveFovLH + ( D3DXMATRIX *pOut, FLOAT fovy, FLOAT Aspect, FLOAT zn, FLOAT zf ); + +// Build a perspective projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a perspective projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixPerspectiveOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoRH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoLH + ( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +// Build an ortho projection matrix. (right-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterRH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build an ortho projection matrix. (left-handed) +D3DXMATRIX* WINAPI D3DXMatrixOrthoOffCenterLH + ( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, + FLOAT zf ); + +// Build a matrix which flattens geometry into a plane, as if casting +// a shadow from a light. +D3DXMATRIX* WINAPI D3DXMatrixShadow + ( D3DXMATRIX *pOut, CONST D3DXVECTOR4 *pLight, + CONST D3DXPLANE *pPlane ); + +// Build a matrix which reflects the coordinate system about a plane +D3DXMATRIX* WINAPI D3DXMatrixReflect + ( D3DXMATRIX *pOut, CONST D3DXPLANE *pPlane ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Quaternion +//-------------------------- + +// inline + +FLOAT D3DXQuaternionLength + ( CONST D3DXQUATERNION *pQ ); + +// Length squared, or "norm" +FLOAT D3DXQuaternionLengthSq + ( CONST D3DXQUATERNION *pQ ); + +FLOAT D3DXQuaternionDot + ( CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2 ); + +// (0, 0, 0, 1) +D3DXQUATERNION* D3DXQuaternionIdentity + ( D3DXQUATERNION *pOut ); + +BOOL D3DXQuaternionIsIdentity + ( CONST D3DXQUATERNION *pQ ); + +// (-x, -y, -z, w) +D3DXQUATERNION* D3DXQuaternionConjugate + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Compute a quaternin's axis and angle of rotation. Expects unit quaternions. +void WINAPI D3DXQuaternionToAxisAngle + ( CONST D3DXQUATERNION *pQ, D3DXVECTOR3 *pAxis, FLOAT *pAngle ); + +// Build a quaternion from a rotation matrix. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationMatrix + ( D3DXQUATERNION *pOut, CONST D3DXMATRIX *pM); + +// Rotation about arbitrary axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationAxis + ( D3DXQUATERNION *pOut, CONST D3DXVECTOR3 *pV, FLOAT Angle ); + +// Yaw around the Y axis, a pitch around the X axis, +// and a roll around the Z axis. +D3DXQUATERNION* WINAPI D3DXQuaternionRotationYawPitchRoll + ( D3DXQUATERNION *pOut, FLOAT Yaw, FLOAT Pitch, FLOAT Roll ); + +// Quaternion multiplication. The result represents the rotation Q2 +// followed by the rotation Q1. (Out = Q2 * Q1) +D3DXQUATERNION* WINAPI D3DXQuaternionMultiply + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2 ); + +D3DXQUATERNION* WINAPI D3DXQuaternionNormalize + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Conjugate and re-norm +D3DXQUATERNION* WINAPI D3DXQuaternionInverse + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects unit quaternions. +// if q = (cos(theta), sin(theta) * v); ln(q) = (0, theta * v) +D3DXQUATERNION* WINAPI D3DXQuaternionLn + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Expects pure quaternions. (w == 0) w is ignored in calculation. +// if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) +D3DXQUATERNION* WINAPI D3DXQuaternionExp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); + +// Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). +// Expects unit quaternions. +D3DXQUATERNION* WINAPI D3DXQuaternionSlerp + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, FLOAT t ); + +// Spherical quadrangle interpolation. +// Slerp(Slerp(Q1, C, t), Slerp(A, B, t), 2t(1-t)) +D3DXQUATERNION* WINAPI D3DXQuaternionSquad + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pA, CONST D3DXQUATERNION *pB, + CONST D3DXQUATERNION *pC, FLOAT t ); + +// Setup control points for spherical quadrangle interpolation +// from Q1 to Q2. The control points are chosen in such a way +// to ensure the continuity of tangents with adjacent segments. +void WINAPI D3DXQuaternionSquadSetup + ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, + CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); + +// Barycentric interpolation. +// Slerp(Slerp(Q1, Q2, f+g), Slerp(Q1, Q3, f+g), g/(f+g)) +D3DXQUATERNION* WINAPI D3DXQuaternionBaryCentric + ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3, + FLOAT f, FLOAT g ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Plane +//-------------------------- + +// inline + +// ax + by + cz + dw +FLOAT D3DXPlaneDot + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR4 *pV); + +// ax + by + cz + d +FLOAT D3DXPlaneDotCoord + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +// ax + by + cz +FLOAT D3DXPlaneDotNormal + ( CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Normalize plane (so that |a,b,c| == 1) +D3DXPLANE* WINAPI D3DXPlaneNormalize + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +// Find the intersection between a plane and a line. If the line is +// parallel to the plane, NULL is returned. +D3DXVECTOR3* WINAPI D3DXPlaneIntersectLine + ( D3DXVECTOR3 *pOut, CONST D3DXPLANE *pP, CONST D3DXVECTOR3 *pV1, + CONST D3DXVECTOR3 *pV2); + +// Construct a plane from a point and a normal +D3DXPLANE* WINAPI D3DXPlaneFromPointNormal + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pPoint, CONST D3DXVECTOR3 *pNormal); + +// Construct a plane from 3 points +D3DXPLANE* WINAPI D3DXPlaneFromPoints + ( D3DXPLANE *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2, + CONST D3DXVECTOR3 *pV3); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +D3DXPLANE* WINAPI D3DXPlaneTransform + ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +#ifdef __cplusplus +} +#endif + + +//-------------------------- +// Color +//-------------------------- + +// inline + +// (1-r, 1-g, 1-b, a) +D3DXCOLOR* D3DXColorNegative + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC); + +D3DXCOLOR* D3DXColorAdd + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorSubtract + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +D3DXCOLOR* D3DXColorScale + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// (r1*r2, g1*g2, b1*b2, a1*a2) +D3DXCOLOR* D3DXColorModulate + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2); + +// Linear interpolation of r,g,b, and a. C1 + s(C2-C1) +D3DXCOLOR* D3DXColorLerp + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC1, CONST D3DXCOLOR *pC2, FLOAT s); + +// non-inline +#ifdef __cplusplus +extern "C" { +#endif + +// Interpolate r,g,b between desaturated color and color. +// DesaturatedColor + s(Color - DesaturatedColor) +D3DXCOLOR* WINAPI D3DXColorAdjustSaturation + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT s); + +// Interpolate r,g,b between 50% grey and color. Grey + s(Color - Grey) +D3DXCOLOR* WINAPI D3DXColorAdjustContrast + (D3DXCOLOR *pOut, CONST D3DXCOLOR *pC, FLOAT c); + +#ifdef __cplusplus +} +#endif + + + + +//-------------------------- +// Misc +//-------------------------- + +#ifdef __cplusplus +extern "C" { +#endif + +// Calculate Fresnel term given the cosine of theta (likely obtained by +// taking the dot of two normals), and the refraction index of the material. +FLOAT WINAPI D3DXFresnelTerm + (FLOAT CosTheta, FLOAT RefractionIndex); + +#ifdef __cplusplus +} +#endif + + + +//=========================================================================== +// +// Matrix Stack +// +//=========================================================================== + +typedef interface ID3DXMatrixStack ID3DXMatrixStack; +typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; + +// {E3357330-CC5E-11d2-A434-00A0C90629A8} +DEFINE_GUID( IID_ID3DXMatrixStack, +0xe3357330, 0xcc5e, 0x11d2, 0xa4, 0x34, 0x0, 0xa0, 0xc9, 0x6, 0x29, 0xa8); + + +#undef INTERFACE +#define INTERFACE ID3DXMatrixStack + +DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) +{ + // + // IUnknown methods + // + STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID * ppvObj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + + // + // ID3DXMatrixStack methods + // + + // Pops the top of the stack, returns the current top + // *after* popping the top. + STDMETHOD(Pop)(THIS) PURE; + + // Pushes the stack by one, duplicating the current matrix. + STDMETHOD(Push)(THIS) PURE; + + // Loads identity in the current matrix. + STDMETHOD(LoadIdentity)(THIS) PURE; + + // Loads the given matrix into the current matrix + STDMETHOD(LoadMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right-Multiplies the given matrix to the current matrix. + // (transformation is about the current world origin) + STDMETHOD(MultMatrix)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Left-Multiplies the given matrix to the current matrix + // (transformation is about the local origin of the object) + STDMETHOD(MultMatrixLocal)(THIS_ CONST D3DXMATRIX* pM ) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the current world origin) + STDMETHOD(RotateAxis) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + STDMETHOD(RotateAxisLocal) + (THIS_ CONST D3DXVECTOR3* pV, FLOAT Angle) PURE; + + // Right multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // current world origin) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRoll) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Left multiply the current matrix with the computed rotation + // matrix. All angles are counterclockwise. (rotation is about the + // local origin of the object) + + // The rotation is composed of a yaw around the Y axis, a pitch around + // the X axis, and a roll around the Z axis. + STDMETHOD(RotateYawPitchRollLocal) + (THIS_ FLOAT Yaw, FLOAT Pitch, FLOAT Roll) PURE; + + // Right multiply the current matrix with the computed scale + // matrix. (transformation is about the current world origin) + STDMETHOD(Scale)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Left multiply the current matrix with the computed scale + // matrix. (transformation is about the local origin of the object) + STDMETHOD(ScaleLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + // Right multiply the current matrix with the computed translation + // matrix. (transformation is about the current world origin) + STDMETHOD(Translate)(THIS_ FLOAT x, FLOAT y, FLOAT z ) PURE; + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + STDMETHOD(TranslateLocal)(THIS_ FLOAT x, FLOAT y, FLOAT z) PURE; + + /* Obtain the current matrix at the top of the stack */ + STDMETHOD_(D3DXMATRIX*, GetTop)(THIS) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +HRESULT WINAPI + D3DXCreateMatrixStack( + DWORD Flags, + LPD3DXMATRIXSTACK* ppStack); + +#ifdef __cplusplus +} +#endif + +#include "d3dx8math.inl" + +#pragma warning(default:4201) + +#endif /* __D3DX8MATH_H__ */ diff --git a/gfx/include/d3d8/d3dx8mesh.h b/gfx/include/d3d8/d3dx8mesh.h index d4cadd95b9..f17d92c8bd 100644 --- a/gfx/include/d3d8/d3dx8mesh.h +++ b/gfx/include/d3d8/d3dx8mesh.h @@ -1,760 +1,760 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8mesh.h -// Content: D3DX mesh types and functions -// -////////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8MESH_H__ -#define __D3DX8MESH_H__ - -#include "dxfile.h" // defines LPDIRECTXFILEDATA - -// {2A835771-BF4D-43f4-8E14-82A809F17D8A} -DEFINE_GUID(IID_ID3DXBaseMesh, -0x2a835771, 0xbf4d, 0x43f4, 0x8e, 0x14, 0x82, 0xa8, 0x9, 0xf1, 0x7d, 0x8a); - -// {CCAE5C3B-4DD1-4d0f-997E-4684CA64557F} -DEFINE_GUID(IID_ID3DXMesh, -0xccae5c3b, 0x4dd1, 0x4d0f, 0x99, 0x7e, 0x46, 0x84, 0xca, 0x64, 0x55, 0x7f); - -// {19FBE386-C282-4659-97BD-CB869B084A6C} -DEFINE_GUID(IID_ID3DXPMesh, -0x19fbe386, 0xc282, 0x4659, 0x97, 0xbd, 0xcb, 0x86, 0x9b, 0x8, 0x4a, 0x6c); - -// {4E3CA05C-D4FF-4d11-8A02-16459E08F6F4} -DEFINE_GUID(IID_ID3DXSPMesh, -0x4e3ca05c, 0xd4ff, 0x4d11, 0x8a, 0x2, 0x16, 0x45, 0x9e, 0x8, 0xf6, 0xf4); - -// {8DB06ECC-EBFC-408a-9404-3074B4773515} -DEFINE_GUID(IID_ID3DXSkinMesh, -0x8db06ecc, 0xebfc, 0x408a, 0x94, 0x4, 0x30, 0x74, 0xb4, 0x77, 0x35, 0x15); - -// Mesh options - lower 3 bytes only, upper byte used by _D3DXMESHOPT option flags -enum _D3DXMESH { - D3DXMESH_32BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. - D3DXMESH_DONOTCLIP = 0x002, // Use D3DUSAGE_DONOTCLIP for VB & IB. - D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. - D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. - D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. - D3DXMESH_VB_SYSTEMMEM = 0x010, // Use D3DPOOL_SYSTEMMEM for VB. Overrides D3DXMESH_MANAGEDVERTEXBUFFER - D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. - D3DXMESH_VB_WRITEONLY = 0x040, // Use D3DUSAGE_WRITEONLY for VB. - D3DXMESH_VB_DYNAMIC = 0x080, // Use D3DUSAGE_DYNAMIC for VB. - D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000, // Use D3DUSAGE_SOFTWAREPROCESSING for VB. - D3DXMESH_IB_SYSTEMMEM = 0x100, // Use D3DPOOL_SYSTEMMEM for IB. Overrides D3DXMESH_MANAGEDINDEXBUFFER - D3DXMESH_IB_MANAGED = 0x200, // Use D3DPOOL_MANAGED for IB. - D3DXMESH_IB_WRITEONLY = 0x400, // Use D3DUSAGE_WRITEONLY for IB. - D3DXMESH_IB_DYNAMIC = 0x800, // Use D3DUSAGE_DYNAMIC for IB. - D3DXMESH_IB_SOFTWAREPROCESSING= 0x10000, // Use D3DUSAGE_SOFTWAREPROCESSING for IB. - - D3DXMESH_VB_SHARE = 0x1000, // Valid for Clone* calls only, forces cloned mesh/pmesh to share vertex buffer - - D3DXMESH_USEHWONLY = 0x2000, // Valid for ID3DXSkinMesh::ConvertToBlendedMesh - - // Helper options - D3DXMESH_SYSTEMMEM = 0x110, // D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM - D3DXMESH_MANAGED = 0x220, // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED - D3DXMESH_WRITEONLY = 0x440, // D3DXMESH_VB_WRITEONLY | D3DXMESH_IB_WRITEONLY - D3DXMESH_DYNAMIC = 0x880, // D3DXMESH_VB_DYNAMIC | D3DXMESH_IB_DYNAMIC - D3DXMESH_SOFTWAREPROCESSING = 0x18000, // D3DXMESH_VB_SOFTWAREPROCESSING | D3DXMESH_IB_SOFTWAREPROCESSING - -}; - -// option field values for specifying min value in D3DXGeneratePMesh and D3DXSimplifyMesh -enum _D3DXMESHSIMP -{ - D3DXMESHSIMP_VERTEX = 0x1, - D3DXMESHSIMP_FACE = 0x2, - -}; - -enum _MAX_FVF_DECL_SIZE -{ - MAX_FVF_DECL_SIZE = 20 -}; - -typedef struct ID3DXBaseMesh *LPD3DXBASEMESH; -typedef struct ID3DXMesh *LPD3DXMESH; -typedef struct ID3DXPMesh *LPD3DXPMESH; -typedef struct ID3DXSPMesh *LPD3DXSPMESH; -typedef struct ID3DXSkinMesh *LPD3DXSKINMESH; - -typedef struct _D3DXATTRIBUTERANGE -{ - DWORD AttribId; - DWORD FaceStart; - DWORD FaceCount; - DWORD VertexStart; - DWORD VertexCount; -} D3DXATTRIBUTERANGE; - -typedef D3DXATTRIBUTERANGE* LPD3DXATTRIBUTERANGE; - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus -struct D3DXMATERIAL -{ - D3DMATERIAL8 MatD3D; - LPSTR pTextureFilename; -}; -typedef struct D3DXMATERIAL *LPD3DXMATERIAL; -#ifdef __cplusplus -} -#endif //__cplusplus - -typedef struct _D3DXATTRIBUTEWEIGHTS -{ - FLOAT Position; - FLOAT Boundary; - FLOAT Normal; - FLOAT Diffuse; - FLOAT Specular; - FLOAT Tex[8]; -} D3DXATTRIBUTEWEIGHTS; - -typedef D3DXATTRIBUTEWEIGHTS* LPD3DXATTRIBUTEWEIGHTS; - -enum _D3DXWELDEPSILONSFLAGS -{ - D3DXWELDEPSILONS_WELDALL = 0x1, // weld all vertices marked by adjacency as being overlapping - - D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched - // vertices so that both components identical AND if all components "equal" - // remove one of the vertices - D3DXWELDEPSILONS_DONOTREMOVEVERTICES = 0x4, // instructs weld to only allow modifications to vertices and not removal - // ONLY valid if D3DXWELDEPSILONS_WELDPARTIALMATCHES is set - // useful to modify vertices to be equal, but not allow vertices to be removed -}; - -typedef struct _D3DXWELDEPSILONS -{ - FLOAT SkinWeights; - FLOAT Normal; - FLOAT Tex[8]; - DWORD Flags; -} D3DXWELDEPSILONS; - -typedef D3DXWELDEPSILONS* LPD3DXWELDEPSILONS; - - -#undef INTERFACE -#define INTERFACE ID3DXBaseMesh - -DECLARE_INTERFACE_(ID3DXBaseMesh, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXBaseMesh - STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; - STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetFVF)(THIS) PURE; - STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; - STDMETHOD_(DWORD, GetOptions)(THIS) PURE; - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; - STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; - STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockVertexBuffer)(THIS) PURE; - STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockIndexBuffer)(THIS) PURE; - STDMETHOD(GetAttributeTable)( - THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; - - STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; - STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; - STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; -}; - - -#undef INTERFACE -#define INTERFACE ID3DXMesh - -DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXBaseMesh - STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; - STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetFVF)(THIS) PURE; - STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; - STDMETHOD_(DWORD, GetOptions)(THIS) PURE; - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; - STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; - STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockVertexBuffer)(THIS) PURE; - STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockIndexBuffer)(THIS) PURE; - STDMETHOD(GetAttributeTable)( - THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; - - STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; - STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; - STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; - - // ID3DXMesh - STDMETHOD(LockAttributeBuffer)(THIS_ DWORD Flags, DWORD** ppData) PURE; - STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; - STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, - DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, - LPD3DXMESH* ppOptMesh) PURE; - STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, - DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap) PURE; - -}; - - -#undef INTERFACE -#define INTERFACE ID3DXPMesh - -DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXBaseMesh - STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; - STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetFVF)(THIS) PURE; - STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; - STDMETHOD_(DWORD, GetOptions)(THIS) PURE; - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; - STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; - STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockVertexBuffer)(THIS) PURE; - STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; - STDMETHOD(UnlockIndexBuffer)(THIS) PURE; - STDMETHOD(GetAttributeTable)( - THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; - - STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; - STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; - STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; - - // ID3DXPMesh - STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3D, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3D, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(SetNumFaces)(THIS_ DWORD Faces) PURE; - STDMETHOD(SetNumVertices)(THIS_ DWORD Vertices) PURE; - STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetMinFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetMinVertices)(THIS) PURE; - STDMETHOD(Save)(THIS_ IStream *pStream, LPD3DXMATERIAL pMaterials, DWORD NumMaterials) PURE; - - STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, - DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, - LPD3DXMESH* ppOptMesh) PURE; - - STDMETHOD(OptimizeBaseLOD)(THIS_ DWORD Flags, DWORD* pFaceRemap) PURE; - STDMETHOD(TrimByFaces)(THIS_ DWORD NewFacesMin, DWORD NewFacesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; - STDMETHOD(TrimByVertices)(THIS_ DWORD NewVerticesMin, DWORD NewVerticesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; - - STDMETHOD(GetAdjacency)(THIS_ DWORD* pAdjacency) PURE; -}; - - -#undef INTERFACE -#define INTERFACE ID3DXSPMesh - -DECLARE_INTERFACE_(ID3DXSPMesh, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXSPMesh - STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetFVF)(THIS) PURE; - STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; - STDMETHOD_(DWORD, GetOptions)(THIS) PURE; - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3D, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, - DWORD FVF, LPDIRECT3DDEVICE8 pD3D, DWORD *pVertexRemapOut, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMesh)(THIS_ DWORD Options, - CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3D, DWORD *pVertexRemapOut, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(ReduceFaces)(THIS_ DWORD Faces) PURE; - STDMETHOD(ReduceVertices)(THIS_ DWORD Vertices) PURE; - STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; - STDMETHOD(GetVertexAttributeWeights)(THIS_ LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights) PURE; - STDMETHOD(GetVertexWeights)(THIS_ FLOAT *pVertexWeights) PURE; -}; - -#define UNUSED16 (0xffff) -#define UNUSED32 (0xffffffff) - -// ID3DXMesh::Optimize options - upper byte only, lower 3 bytes used from _D3DXMESH option flags -enum _D3DXMESHOPT { - D3DXMESHOPT_COMPACT = 0x01000000, - D3DXMESHOPT_ATTRSORT = 0x02000000, - D3DXMESHOPT_VERTEXCACHE = 0x04000000, - D3DXMESHOPT_STRIPREORDER = 0x08000000, - D3DXMESHOPT_IGNOREVERTS = 0x10000000, // optimize faces only, don't touch vertices - D3DXMESHOPT_SHAREVB = 0x1000, // same as D3DXMESH_VB_SHARE -}; - -// Subset of the mesh that has the same attribute and bone combination. -// This subset can be rendered in a single draw call -typedef struct _D3DXBONECOMBINATION -{ - DWORD AttribId; - DWORD FaceStart; - DWORD FaceCount; - DWORD VertexStart; - DWORD VertexCount; - DWORD* BoneId; -} D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION; - - -#undef INTERFACE -#define INTERFACE ID3DXSkinMesh - -DECLARE_INTERFACE_(ID3DXSkinMesh, IUnknown) -{ - // IUnknown - STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; - STDMETHOD_(ULONG, AddRef)(THIS) PURE; - STDMETHOD_(ULONG, Release)(THIS) PURE; - - // ID3DXMesh - STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; - STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; - STDMETHOD_(DWORD, GetFVF)(THIS) PURE; - STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; - STDMETHOD_(DWORD, GetOptions)(THIS) PURE; - STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; - STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; - STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; - STDMETHOD(LockVertexBuffer)(THIS_ DWORD flags, BYTE** ppData) PURE; - STDMETHOD(UnlockVertexBuffer)(THIS) PURE; - STDMETHOD(LockIndexBuffer)(THIS_ DWORD flags, BYTE** ppData) PURE; - STDMETHOD(UnlockIndexBuffer)(THIS) PURE; - STDMETHOD(LockAttributeBuffer)(THIS_ DWORD flags, DWORD** ppData) PURE; - STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; - // ID3DXSkinMesh - STDMETHOD_(DWORD, GetNumBones)(THIS) PURE; - STDMETHOD(GetOriginalMesh)(THIS_ LPD3DXMESH* ppMesh) PURE; - STDMETHOD(SetBoneInfluence)(THIS_ DWORD bone, DWORD numInfluences, CONST DWORD* vertices, CONST FLOAT* weights) PURE; - STDMETHOD_(DWORD, GetNumBoneInfluences)(THIS_ DWORD bone) PURE; - STDMETHOD(GetBoneInfluence)(THIS_ DWORD bone, DWORD* vertices, FLOAT* weights) PURE; - STDMETHOD(GetMaxVertexInfluences)(THIS_ DWORD* maxVertexInfluences) PURE; - STDMETHOD(GetMaxFaceInfluences)(THIS_ DWORD* maxFaceInfluences) PURE; - - STDMETHOD(ConvertToBlendedMesh)(THIS_ DWORD Options, - CONST LPDWORD pAdjacencyIn, - LPDWORD pAdjacencyOut, - DWORD* pNumBoneCombinations, - LPD3DXBUFFER* ppBoneCombinationTable, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap, - LPD3DXMESH* ppMesh) PURE; - - STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ DWORD Options, - CONST LPDWORD pAdjacencyIn, - DWORD paletteSize, - LPDWORD pAdjacencyOut, - DWORD* pNumBoneCombinations, - LPD3DXBUFFER* ppBoneCombinationTable, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap, - LPD3DXMESH* ppMesh) PURE; - - STDMETHOD(GenerateSkinnedMesh)(THIS_ DWORD Options, - FLOAT minWeight, - CONST LPDWORD pAdjacencyIn, - LPDWORD pAdjacencyOut, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap, - LPD3DXMESH* ppMesh) PURE; - STDMETHOD(UpdateSkinnedMesh)(THIS_ CONST D3DXMATRIX* pBoneTransforms, CONST D3DXMATRIX* pBoneInvTransforms, LPD3DXMESH pMesh) PURE; -}; - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -HRESULT WINAPI - D3DXCreateMesh( - DWORD NumFaces, - DWORD NumVertices, - DWORD Options, - CONST DWORD *pDeclaration, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXMESH* ppMesh); - -HRESULT WINAPI - D3DXCreateMeshFVF( - DWORD NumFaces, - DWORD NumVertices, - DWORD Options, - DWORD FVF, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXMESH* ppMesh); - -HRESULT WINAPI - D3DXCreateSPMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, - CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, - CONST FLOAT *pVertexWeights, - LPD3DXSPMESH* ppSMesh); - -// clean a mesh up for simplification, try to make manifold -HRESULT WINAPI - D3DXCleanMesh( - LPD3DXMESH pMeshIn, - CONST DWORD* pAdjacencyIn, - LPD3DXMESH* ppMeshOut, - DWORD* pAdjacencyOut, - LPD3DXBUFFER* ppErrorsAndWarnings); - -HRESULT WINAPI - D3DXValidMesh( - LPD3DXMESH pMeshIn, - CONST DWORD* pAdjacency, - LPD3DXBUFFER* ppErrorsAndWarnings); - -HRESULT WINAPI - D3DXGeneratePMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, - CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, - CONST FLOAT *pVertexWeights, - DWORD MinValue, - DWORD Options, - LPD3DXPMESH* ppPMesh); - -HRESULT WINAPI - D3DXSimplifyMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, - CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, - CONST FLOAT *pVertexWeights, - DWORD MinValue, - DWORD Options, - LPD3DXMESH* ppMesh); - -HRESULT WINAPI - D3DXComputeBoundingSphere( - PVOID pPointsFVF, - DWORD NumVertices, - DWORD FVF, - D3DXVECTOR3 *pCenter, - FLOAT *pRadius); - -HRESULT WINAPI - D3DXComputeBoundingBox( - PVOID pPointsFVF, - DWORD NumVertices, - DWORD FVF, - D3DXVECTOR3 *pMin, - D3DXVECTOR3 *pMax); - -HRESULT WINAPI - D3DXComputeNormals( - LPD3DXBASEMESH pMesh, - CONST DWORD *pAdjacency); - -HRESULT WINAPI - D3DXCreateBuffer( - DWORD NumBytes, - LPD3DXBUFFER *ppBuffer); - - -HRESULT WINAPI - D3DXLoadMeshFromX( - LPSTR pFilename, - DWORD Options, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - DWORD *pNumMaterials, - LPD3DXMESH *ppMesh); - -HRESULT WINAPI - D3DXLoadMeshFromXInMemory( - PBYTE Memory, - DWORD SizeOfMemory, - DWORD Options, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - DWORD *pNumMaterials, - LPD3DXMESH *ppMesh); - -HRESULT WINAPI - D3DXLoadMeshFromXResource( - HMODULE Module, - LPCTSTR Name, - LPCTSTR Type, - DWORD Options, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - DWORD *pNumMaterials, - LPD3DXMESH *ppMesh); - -HRESULT WINAPI - D3DXSaveMeshToX( - LPSTR pFilename, - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, - CONST LPD3DXMATERIAL pMaterials, - DWORD NumMaterials, - DWORD Format - ); - -HRESULT WINAPI - D3DXCreatePMeshFromStream( - IStream *pStream, - DWORD Options, - LPDIRECT3DDEVICE8 pD3DDevice, - LPD3DXBUFFER *ppMaterials, - DWORD* pNumMaterials, - LPD3DXPMESH *ppPMesh); - -HRESULT WINAPI - D3DXCreateSkinMesh( - DWORD NumFaces, - DWORD NumVertices, - DWORD NumBones, - DWORD Options, - CONST DWORD *pDeclaration, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXSKINMESH* ppSkinMesh); - -HRESULT WINAPI - D3DXCreateSkinMeshFVF( - DWORD NumFaces, - DWORD NumVertices, - DWORD NumBones, - DWORD Options, - DWORD FVF, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXSKINMESH* ppSkinMesh); - -HRESULT WINAPI - D3DXCreateSkinMeshFromMesh( - LPD3DXMESH pMesh, - DWORD numBones, - LPD3DXSKINMESH* ppSkinMesh); - -HRESULT WINAPI - D3DXLoadMeshFromXof( - LPDIRECTXFILEDATA pXofObjMesh, - DWORD Options, - LPDIRECT3DDEVICE8 pD3DDevice, - LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - DWORD *pNumMaterials, - LPD3DXMESH *ppMesh); - -HRESULT WINAPI - D3DXLoadSkinMeshFromXof( - LPDIRECTXFILEDATA pxofobjMesh, - DWORD Options, - LPDIRECT3DDEVICE8 pD3D, - LPD3DXBUFFER* ppAdjacency, - LPD3DXBUFFER* ppMaterials, - DWORD *pMatOut, - LPD3DXBUFFER* ppBoneNames, - LPD3DXBUFFER* ppBoneTransforms, - LPD3DXSKINMESH* ppMesh); - -HRESULT WINAPI - D3DXTessellateNPatches( - LPD3DXMESH pMeshIn, - CONST DWORD* pAdjacencyIn, - FLOAT NumSegs, - BOOL QuadraticInterpNormals, // if false use linear intrep for normals, if true use quadratic - LPD3DXMESH *ppMeshOut, - LPD3DXBUFFER *ppAdjacencyOut); - -UINT WINAPI - D3DXGetFVFVertexSize(DWORD FVF); - -HRESULT WINAPI - D3DXDeclaratorFromFVF( - DWORD FVF, - DWORD Declaration[MAX_FVF_DECL_SIZE]); - -HRESULT WINAPI - D3DXFVFFromDeclarator( - CONST DWORD *pDeclarator, - DWORD *pFVF); - -HRESULT WINAPI - D3DXWeldVertices( - CONST LPD3DXMESH pMesh, - LPD3DXWELDEPSILONS pEpsilons, - CONST DWORD *pAdjacencyIn, - DWORD *pAdjacencyOut, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap); - -typedef struct _D3DXINTERSECTINFO -{ - DWORD FaceIndex; // index of face intersected - FLOAT U; // Barycentric Hit Coordinates - FLOAT V; // Barycentric Hit Coordinates - FLOAT Dist; // Ray-Intersection Parameter Distance -} D3DXINTERSECTINFO, *LPD3DXINTERSECTINFO; - - -HRESULT WINAPI - D3DXIntersect( - LPD3DXBASEMESH pMesh, - CONST D3DXVECTOR3 *pRayPos, - CONST D3DXVECTOR3 *pRayDir, - BOOL *pHit, // True if any faces were intersected - DWORD *pFaceIndex, // index of closest face intersected - FLOAT *pU, // Barycentric Hit Coordinates - FLOAT *pV, // Barycentric Hit Coordinates - FLOAT *pDist, // Ray-Intersection Parameter Distance - LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) - DWORD *pCountOfHits); // Number of entries in AllHits array - -HRESULT WINAPI - D3DXIntersectSubset( - LPD3DXBASEMESH pMesh, - DWORD AttribId, - CONST D3DXVECTOR3 *pRayPos, - CONST D3DXVECTOR3 *pRayDir, - BOOL *pHit, // True if any faces were intersected - DWORD *pFaceIndex, // index of closest face intersected - FLOAT *pU, // Barycentric Hit Coordinates - FLOAT *pV, // Barycentric Hit Coordinates - FLOAT *pDist, // Ray-Intersection Parameter Distance - LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) - DWORD *pCountOfHits); // Number of entries in AllHits array - - -HRESULT WINAPI D3DXSplitMesh - ( - CONST LPD3DXMESH pMeshIn, - CONST DWORD *pAdjacencyIn, - CONST DWORD MaxSize, - CONST DWORD Options, - DWORD *pMeshesOut, - LPD3DXBUFFER *ppMeshArrayOut, - LPD3DXBUFFER *ppAdjacencyArrayOut, - LPD3DXBUFFER *ppFaceRemapArrayOut, - LPD3DXBUFFER *ppVertRemapArrayOut - ); - -BOOL D3DXIntersectTri -( - CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position - CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position - CONST D3DXVECTOR3 *p2, // Triangle vertex 2 position - CONST D3DXVECTOR3 *pRayPos, // Ray origin - CONST D3DXVECTOR3 *pRayDir, // Ray direction - FLOAT *pU, // Barycentric Hit Coordinates - FLOAT *pV, // Barycentric Hit Coordinates - FLOAT *pDist); // Ray-Intersection Parameter Distance - -BOOL WINAPI - D3DXSphereBoundProbe( - CONST D3DXVECTOR3 *pCenter, - FLOAT Radius, - CONST D3DXVECTOR3 *pRayPosition, - CONST D3DXVECTOR3 *pRayDirection); - -BOOL WINAPI - D3DXBoxBoundProbe( - CONST D3DXVECTOR3 *pMin, - CONST D3DXVECTOR3 *pMax, - CONST D3DXVECTOR3 *pRayPosition, - CONST D3DXVECTOR3 *pRayDirection); - -enum _D3DXERR { - D3DXERR_CANNOTMODIFYINDEXBUFFER = MAKE_DDHRESULT(2900), - D3DXERR_INVALIDMESH = MAKE_DDHRESULT(2901), - D3DXERR_CANNOTATTRSORT = MAKE_DDHRESULT(2902), - D3DXERR_SKINNINGNOTSUPPORTED = MAKE_DDHRESULT(2903), - D3DXERR_TOOMANYINFLUENCES = MAKE_DDHRESULT(2904), - D3DXERR_INVALIDDATA = MAKE_DDHRESULT(2905), - D3DXERR_LOADEDMESHASNODATA = MAKE_DDHRESULT(2906), -}; - - -#define D3DX_COMP_TANGENT_NONE 0xFFFFFFFF - -HRESULT WINAPI D3DXComputeTangent(LPD3DXMESH InMesh, - DWORD TexStage, - LPD3DXMESH OutMesh, - DWORD TexStageUVec, - DWORD TexStageVVec, - DWORD Wrap, - DWORD *Adjacency); - -HRESULT WINAPI -D3DXConvertMeshSubsetToSingleStrip -( - LPD3DXBASEMESH MeshIn, - DWORD AttribId, - DWORD IBOptions, - LPDIRECT3DINDEXBUFFER8 *ppIndexBuffer, - DWORD *pNumIndices -); - -HRESULT WINAPI -D3DXConvertMeshSubsetToStrips -( - LPD3DXBASEMESH MeshIn, - DWORD AttribId, - DWORD IBOptions, - LPDIRECT3DINDEXBUFFER8 *ppIndexBuffer, - DWORD *pNumIndices, - LPD3DXBUFFER *ppStripLengths, - DWORD *pNumStrips -); - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //__D3DX8MESH_H__ - - +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8mesh.h +// Content: D3DX mesh types and functions +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8MESH_H__ +#define __D3DX8MESH_H__ + +#include "dxfile.h" // defines LPDIRECTXFILEDATA + +// {2A835771-BF4D-43f4-8E14-82A809F17D8A} +DEFINE_GUID(IID_ID3DXBaseMesh, +0x2a835771, 0xbf4d, 0x43f4, 0x8e, 0x14, 0x82, 0xa8, 0x9, 0xf1, 0x7d, 0x8a); + +// {CCAE5C3B-4DD1-4d0f-997E-4684CA64557F} +DEFINE_GUID(IID_ID3DXMesh, +0xccae5c3b, 0x4dd1, 0x4d0f, 0x99, 0x7e, 0x46, 0x84, 0xca, 0x64, 0x55, 0x7f); + +// {19FBE386-C282-4659-97BD-CB869B084A6C} +DEFINE_GUID(IID_ID3DXPMesh, +0x19fbe386, 0xc282, 0x4659, 0x97, 0xbd, 0xcb, 0x86, 0x9b, 0x8, 0x4a, 0x6c); + +// {4E3CA05C-D4FF-4d11-8A02-16459E08F6F4} +DEFINE_GUID(IID_ID3DXSPMesh, +0x4e3ca05c, 0xd4ff, 0x4d11, 0x8a, 0x2, 0x16, 0x45, 0x9e, 0x8, 0xf6, 0xf4); + +// {8DB06ECC-EBFC-408a-9404-3074B4773515} +DEFINE_GUID(IID_ID3DXSkinMesh, +0x8db06ecc, 0xebfc, 0x408a, 0x94, 0x4, 0x30, 0x74, 0xb4, 0x77, 0x35, 0x15); + +// Mesh options - lower 3 bytes only, upper byte used by _D3DXMESHOPT option flags +enum _D3DXMESH { + D3DXMESH_32BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. + D3DXMESH_DONOTCLIP = 0x002, // Use D3DUSAGE_DONOTCLIP for VB & IB. + D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. + D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. + D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. + D3DXMESH_VB_SYSTEMMEM = 0x010, // Use D3DPOOL_SYSTEMMEM for VB. Overrides D3DXMESH_MANAGEDVERTEXBUFFER + D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. + D3DXMESH_VB_WRITEONLY = 0x040, // Use D3DUSAGE_WRITEONLY for VB. + D3DXMESH_VB_DYNAMIC = 0x080, // Use D3DUSAGE_DYNAMIC for VB. + D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000, // Use D3DUSAGE_SOFTWAREPROCESSING for VB. + D3DXMESH_IB_SYSTEMMEM = 0x100, // Use D3DPOOL_SYSTEMMEM for IB. Overrides D3DXMESH_MANAGEDINDEXBUFFER + D3DXMESH_IB_MANAGED = 0x200, // Use D3DPOOL_MANAGED for IB. + D3DXMESH_IB_WRITEONLY = 0x400, // Use D3DUSAGE_WRITEONLY for IB. + D3DXMESH_IB_DYNAMIC = 0x800, // Use D3DUSAGE_DYNAMIC for IB. + D3DXMESH_IB_SOFTWAREPROCESSING= 0x10000, // Use D3DUSAGE_SOFTWAREPROCESSING for IB. + + D3DXMESH_VB_SHARE = 0x1000, // Valid for Clone* calls only, forces cloned mesh/pmesh to share vertex buffer + + D3DXMESH_USEHWONLY = 0x2000, // Valid for ID3DXSkinMesh::ConvertToBlendedMesh + + // Helper options + D3DXMESH_SYSTEMMEM = 0x110, // D3DXMESH_VB_SYSTEMMEM | D3DXMESH_IB_SYSTEMMEM + D3DXMESH_MANAGED = 0x220, // D3DXMESH_VB_MANAGED | D3DXMESH_IB_MANAGED + D3DXMESH_WRITEONLY = 0x440, // D3DXMESH_VB_WRITEONLY | D3DXMESH_IB_WRITEONLY + D3DXMESH_DYNAMIC = 0x880, // D3DXMESH_VB_DYNAMIC | D3DXMESH_IB_DYNAMIC + D3DXMESH_SOFTWAREPROCESSING = 0x18000, // D3DXMESH_VB_SOFTWAREPROCESSING | D3DXMESH_IB_SOFTWAREPROCESSING + +}; + +// option field values for specifying min value in D3DXGeneratePMesh and D3DXSimplifyMesh +enum _D3DXMESHSIMP +{ + D3DXMESHSIMP_VERTEX = 0x1, + D3DXMESHSIMP_FACE = 0x2, + +}; + +enum _MAX_FVF_DECL_SIZE +{ + MAX_FVF_DECL_SIZE = 20 +}; + +typedef struct ID3DXBaseMesh *LPD3DXBASEMESH; +typedef struct ID3DXMesh *LPD3DXMESH; +typedef struct ID3DXPMesh *LPD3DXPMESH; +typedef struct ID3DXSPMesh *LPD3DXSPMESH; +typedef struct ID3DXSkinMesh *LPD3DXSKINMESH; + +typedef struct _D3DXATTRIBUTERANGE +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; +} D3DXATTRIBUTERANGE; + +typedef D3DXATTRIBUTERANGE* LPD3DXATTRIBUTERANGE; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus +struct D3DXMATERIAL +{ + D3DMATERIAL8 MatD3D; + LPSTR pTextureFilename; +}; +typedef struct D3DXMATERIAL *LPD3DXMATERIAL; +#ifdef __cplusplus +} +#endif //__cplusplus + +typedef struct _D3DXATTRIBUTEWEIGHTS +{ + FLOAT Position; + FLOAT Boundary; + FLOAT Normal; + FLOAT Diffuse; + FLOAT Specular; + FLOAT Tex[8]; +} D3DXATTRIBUTEWEIGHTS; + +typedef D3DXATTRIBUTEWEIGHTS* LPD3DXATTRIBUTEWEIGHTS; + +enum _D3DXWELDEPSILONSFLAGS +{ + D3DXWELDEPSILONS_WELDALL = 0x1, // weld all vertices marked by adjacency as being overlapping + + D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched + // vertices so that both components identical AND if all components "equal" + // remove one of the vertices + D3DXWELDEPSILONS_DONOTREMOVEVERTICES = 0x4, // instructs weld to only allow modifications to vertices and not removal + // ONLY valid if D3DXWELDEPSILONS_WELDPARTIALMATCHES is set + // useful to modify vertices to be equal, but not allow vertices to be removed +}; + +typedef struct _D3DXWELDEPSILONS +{ + FLOAT SkinWeights; + FLOAT Normal; + FLOAT Tex[8]; + DWORD Flags; +} D3DXWELDEPSILONS; + +typedef D3DXWELDEPSILONS* LPD3DXWELDEPSILONS; + + +#undef INTERFACE +#define INTERFACE ID3DXBaseMesh + +DECLARE_INTERFACE_(ID3DXBaseMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXMesh + +DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + // ID3DXMesh + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD Flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap) PURE; + +}; + + +#undef INTERFACE +#define INTERFACE ID3DXPMesh + +DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXBaseMesh + STDMETHOD(DrawSubset)(THIS_ DWORD AttribId) PURE; + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD Flags, BYTE** ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(GetAttributeTable)( + THIS_ D3DXATTRIBUTERANGE *pAttribTable, DWORD* pAttribTableSize) PURE; + + STDMETHOD(ConvertPointRepsToAdjacency)(THIS_ CONST DWORD* pPRep, DWORD* pAdjacency) PURE; + STDMETHOD(ConvertAdjacencyToPointReps)(THIS_ CONST DWORD* pAdjacency, DWORD* pPRep) PURE; + STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Epsilon, DWORD* pAdjacency) PURE; + + // ID3DXPMesh + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3D, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3D, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(SetNumFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(SetNumVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMinFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetMinVertices)(THIS) PURE; + STDMETHOD(Save)(THIS_ IStream *pStream, LPD3DXMATERIAL pMaterials, DWORD NumMaterials) PURE; + + STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppOptMesh) PURE; + + STDMETHOD(OptimizeBaseLOD)(THIS_ DWORD Flags, DWORD* pFaceRemap) PURE; + STDMETHOD(TrimByFaces)(THIS_ DWORD NewFacesMin, DWORD NewFacesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + STDMETHOD(TrimByVertices)(THIS_ DWORD NewVerticesMin, DWORD NewVerticesMax, DWORD *rgiFaceRemap, DWORD *rgiVertRemap) PURE; + + STDMETHOD(GetAdjacency)(THIS_ DWORD* pAdjacency) PURE; +}; + + +#undef INTERFACE +#define INTERFACE ID3DXSPMesh + +DECLARE_INTERFACE_(ID3DXSPMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXSPMesh + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3D, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(CloneMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + DWORD FVF, LPDIRECT3DDEVICE8 pD3D, DWORD *pVertexRemapOut, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + CONST DWORD *pDeclaration, LPDIRECT3DDEVICE8 pD3D, DWORD *pVertexRemapOut, LPD3DXPMESH* ppCloneMesh) PURE; + STDMETHOD(ReduceFaces)(THIS_ DWORD Faces) PURE; + STDMETHOD(ReduceVertices)(THIS_ DWORD Vertices) PURE; + STDMETHOD_(DWORD, GetMaxFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetMaxVertices)(THIS) PURE; + STDMETHOD(GetVertexAttributeWeights)(THIS_ LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights) PURE; + STDMETHOD(GetVertexWeights)(THIS_ FLOAT *pVertexWeights) PURE; +}; + +#define UNUSED16 (0xffff) +#define UNUSED32 (0xffffffff) + +// ID3DXMesh::Optimize options - upper byte only, lower 3 bytes used from _D3DXMESH option flags +enum _D3DXMESHOPT { + D3DXMESHOPT_COMPACT = 0x01000000, + D3DXMESHOPT_ATTRSORT = 0x02000000, + D3DXMESHOPT_VERTEXCACHE = 0x04000000, + D3DXMESHOPT_STRIPREORDER = 0x08000000, + D3DXMESHOPT_IGNOREVERTS = 0x10000000, // optimize faces only, don't touch vertices + D3DXMESHOPT_SHAREVB = 0x1000, // same as D3DXMESH_VB_SHARE +}; + +// Subset of the mesh that has the same attribute and bone combination. +// This subset can be rendered in a single draw call +typedef struct _D3DXBONECOMBINATION +{ + DWORD AttribId; + DWORD FaceStart; + DWORD FaceCount; + DWORD VertexStart; + DWORD VertexCount; + DWORD* BoneId; +} D3DXBONECOMBINATION, *LPD3DXBONECOMBINATION; + + +#undef INTERFACE +#define INTERFACE ID3DXSkinMesh + +DECLARE_INTERFACE_(ID3DXSkinMesh, IUnknown) +{ + // IUnknown + STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE; + STDMETHOD_(ULONG, AddRef)(THIS) PURE; + STDMETHOD_(ULONG, Release)(THIS) PURE; + + // ID3DXMesh + STDMETHOD_(DWORD, GetNumFaces)(THIS) PURE; + STDMETHOD_(DWORD, GetNumVertices)(THIS) PURE; + STDMETHOD_(DWORD, GetFVF)(THIS) PURE; + STDMETHOD(GetDeclaration)(THIS_ DWORD Declaration[MAX_FVF_DECL_SIZE]) PURE; + STDMETHOD_(DWORD, GetOptions)(THIS) PURE; + STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE8* ppDevice) PURE; + STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER8* ppVB) PURE; + STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER8* ppIB) PURE; + STDMETHOD(LockVertexBuffer)(THIS_ DWORD flags, BYTE** ppData) PURE; + STDMETHOD(UnlockVertexBuffer)(THIS) PURE; + STDMETHOD(LockIndexBuffer)(THIS_ DWORD flags, BYTE** ppData) PURE; + STDMETHOD(UnlockIndexBuffer)(THIS) PURE; + STDMETHOD(LockAttributeBuffer)(THIS_ DWORD flags, DWORD** ppData) PURE; + STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; + // ID3DXSkinMesh + STDMETHOD_(DWORD, GetNumBones)(THIS) PURE; + STDMETHOD(GetOriginalMesh)(THIS_ LPD3DXMESH* ppMesh) PURE; + STDMETHOD(SetBoneInfluence)(THIS_ DWORD bone, DWORD numInfluences, CONST DWORD* vertices, CONST FLOAT* weights) PURE; + STDMETHOD_(DWORD, GetNumBoneInfluences)(THIS_ DWORD bone) PURE; + STDMETHOD(GetBoneInfluence)(THIS_ DWORD bone, DWORD* vertices, FLOAT* weights) PURE; + STDMETHOD(GetMaxVertexInfluences)(THIS_ DWORD* maxVertexInfluences) PURE; + STDMETHOD(GetMaxFaceInfluences)(THIS_ DWORD* maxFaceInfluences) PURE; + + STDMETHOD(ConvertToBlendedMesh)(THIS_ DWORD Options, + CONST LPDWORD pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppMesh) PURE; + + STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ DWORD Options, + CONST LPDWORD pAdjacencyIn, + DWORD paletteSize, + LPDWORD pAdjacencyOut, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppMesh) PURE; + + STDMETHOD(GenerateSkinnedMesh)(THIS_ DWORD Options, + FLOAT minWeight, + CONST LPDWORD pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, + LPD3DXMESH* ppMesh) PURE; + STDMETHOD(UpdateSkinnedMesh)(THIS_ CONST D3DXMATRIX* pBoneTransforms, CONST D3DXMATRIX* pBoneInvTransforms, LPD3DXMESH pMesh) PURE; +}; + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +HRESULT WINAPI + D3DXCreateMesh( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + CONST DWORD *pDeclaration, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateMeshFVF( + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + DWORD FVF, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXCreateSPMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + LPD3DXSPMESH* ppSMesh); + +// clean a mesh up for simplification, try to make manifold +HRESULT WINAPI + D3DXCleanMesh( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + LPD3DXMESH* ppMeshOut, + DWORD* pAdjacencyOut, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXValidMesh( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacency, + LPD3DXBUFFER* ppErrorsAndWarnings); + +HRESULT WINAPI + D3DXGeneratePMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXPMESH* ppPMesh); + +HRESULT WINAPI + D3DXSimplifyMesh( + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST LPD3DXATTRIBUTEWEIGHTS pVertexAttributeWeights, + CONST FLOAT *pVertexWeights, + DWORD MinValue, + DWORD Options, + LPD3DXMESH* ppMesh); + +HRESULT WINAPI + D3DXComputeBoundingSphere( + PVOID pPointsFVF, + DWORD NumVertices, + DWORD FVF, + D3DXVECTOR3 *pCenter, + FLOAT *pRadius); + +HRESULT WINAPI + D3DXComputeBoundingBox( + PVOID pPointsFVF, + DWORD NumVertices, + DWORD FVF, + D3DXVECTOR3 *pMin, + D3DXVECTOR3 *pMax); + +HRESULT WINAPI + D3DXComputeNormals( + LPD3DXBASEMESH pMesh, + CONST DWORD *pAdjacency); + +HRESULT WINAPI + D3DXCreateBuffer( + DWORD NumBytes, + LPD3DXBUFFER *ppBuffer); + + +HRESULT WINAPI + D3DXLoadMeshFromX( + LPSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXInMemory( + PBYTE Memory, + DWORD SizeOfMemory, + DWORD Options, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXResource( + HMODULE Module, + LPCTSTR Name, + LPCTSTR Type, + DWORD Options, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXSaveMeshToX( + LPSTR pFilename, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, + CONST LPD3DXMATERIAL pMaterials, + DWORD NumMaterials, + DWORD Format + ); + +HRESULT WINAPI + D3DXCreatePMeshFromStream( + IStream *pStream, + DWORD Options, + LPDIRECT3DDEVICE8 pD3DDevice, + LPD3DXBUFFER *ppMaterials, + DWORD* pNumMaterials, + LPD3DXPMESH *ppPMesh); + +HRESULT WINAPI + D3DXCreateSkinMesh( + DWORD NumFaces, + DWORD NumVertices, + DWORD NumBones, + DWORD Options, + CONST DWORD *pDeclaration, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXSKINMESH* ppSkinMesh); + +HRESULT WINAPI + D3DXCreateSkinMeshFVF( + DWORD NumFaces, + DWORD NumVertices, + DWORD NumBones, + DWORD Options, + DWORD FVF, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXSKINMESH* ppSkinMesh); + +HRESULT WINAPI + D3DXCreateSkinMeshFromMesh( + LPD3DXMESH pMesh, + DWORD numBones, + LPD3DXSKINMESH* ppSkinMesh); + +HRESULT WINAPI + D3DXLoadMeshFromXof( + LPDIRECTXFILEDATA pXofObjMesh, + DWORD Options, + LPDIRECT3DDEVICE8 pD3DDevice, + LPD3DXBUFFER *ppAdjacency, + LPD3DXBUFFER *ppMaterials, + DWORD *pNumMaterials, + LPD3DXMESH *ppMesh); + +HRESULT WINAPI + D3DXLoadSkinMeshFromXof( + LPDIRECTXFILEDATA pxofobjMesh, + DWORD Options, + LPDIRECT3DDEVICE8 pD3D, + LPD3DXBUFFER* ppAdjacency, + LPD3DXBUFFER* ppMaterials, + DWORD *pMatOut, + LPD3DXBUFFER* ppBoneNames, + LPD3DXBUFFER* ppBoneTransforms, + LPD3DXSKINMESH* ppMesh); + +HRESULT WINAPI + D3DXTessellateNPatches( + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + FLOAT NumSegs, + BOOL QuadraticInterpNormals, // if false use linear intrep for normals, if true use quadratic + LPD3DXMESH *ppMeshOut, + LPD3DXBUFFER *ppAdjacencyOut); + +UINT WINAPI + D3DXGetFVFVertexSize(DWORD FVF); + +HRESULT WINAPI + D3DXDeclaratorFromFVF( + DWORD FVF, + DWORD Declaration[MAX_FVF_DECL_SIZE]); + +HRESULT WINAPI + D3DXFVFFromDeclarator( + CONST DWORD *pDeclarator, + DWORD *pFVF); + +HRESULT WINAPI + D3DXWeldVertices( + CONST LPD3DXMESH pMesh, + LPD3DXWELDEPSILONS pEpsilons, + CONST DWORD *pAdjacencyIn, + DWORD *pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap); + +typedef struct _D3DXINTERSECTINFO +{ + DWORD FaceIndex; // index of face intersected + FLOAT U; // Barycentric Hit Coordinates + FLOAT V; // Barycentric Hit Coordinates + FLOAT Dist; // Ray-Intersection Parameter Distance +} D3DXINTERSECTINFO, *LPD3DXINTERSECTINFO; + + +HRESULT WINAPI + D3DXIntersect( + LPD3DXBASEMESH pMesh, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + +HRESULT WINAPI + D3DXIntersectSubset( + LPD3DXBASEMESH pMesh, + DWORD AttribId, + CONST D3DXVECTOR3 *pRayPos, + CONST D3DXVECTOR3 *pRayDir, + BOOL *pHit, // True if any faces were intersected + DWORD *pFaceIndex, // index of closest face intersected + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist, // Ray-Intersection Parameter Distance + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + DWORD *pCountOfHits); // Number of entries in AllHits array + + +HRESULT WINAPI D3DXSplitMesh + ( + CONST LPD3DXMESH pMeshIn, + CONST DWORD *pAdjacencyIn, + CONST DWORD MaxSize, + CONST DWORD Options, + DWORD *pMeshesOut, + LPD3DXBUFFER *ppMeshArrayOut, + LPD3DXBUFFER *ppAdjacencyArrayOut, + LPD3DXBUFFER *ppFaceRemapArrayOut, + LPD3DXBUFFER *ppVertRemapArrayOut + ); + +BOOL D3DXIntersectTri +( + CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position + CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position + CONST D3DXVECTOR3 *p2, // Triangle vertex 2 position + CONST D3DXVECTOR3 *pRayPos, // Ray origin + CONST D3DXVECTOR3 *pRayDir, // Ray direction + FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pV, // Barycentric Hit Coordinates + FLOAT *pDist); // Ray-Intersection Parameter Distance + +BOOL WINAPI + D3DXSphereBoundProbe( + CONST D3DXVECTOR3 *pCenter, + FLOAT Radius, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +BOOL WINAPI + D3DXBoxBoundProbe( + CONST D3DXVECTOR3 *pMin, + CONST D3DXVECTOR3 *pMax, + CONST D3DXVECTOR3 *pRayPosition, + CONST D3DXVECTOR3 *pRayDirection); + +enum _D3DXERR { + D3DXERR_CANNOTMODIFYINDEXBUFFER = MAKE_DDHRESULT(2900), + D3DXERR_INVALIDMESH = MAKE_DDHRESULT(2901), + D3DXERR_CANNOTATTRSORT = MAKE_DDHRESULT(2902), + D3DXERR_SKINNINGNOTSUPPORTED = MAKE_DDHRESULT(2903), + D3DXERR_TOOMANYINFLUENCES = MAKE_DDHRESULT(2904), + D3DXERR_INVALIDDATA = MAKE_DDHRESULT(2905), + D3DXERR_LOADEDMESHASNODATA = MAKE_DDHRESULT(2906), +}; + + +#define D3DX_COMP_TANGENT_NONE 0xFFFFFFFF + +HRESULT WINAPI D3DXComputeTangent(LPD3DXMESH InMesh, + DWORD TexStage, + LPD3DXMESH OutMesh, + DWORD TexStageUVec, + DWORD TexStageVVec, + DWORD Wrap, + DWORD *Adjacency); + +HRESULT WINAPI +D3DXConvertMeshSubsetToSingleStrip +( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER8 *ppIndexBuffer, + DWORD *pNumIndices +); + +HRESULT WINAPI +D3DXConvertMeshSubsetToStrips +( + LPD3DXBASEMESH MeshIn, + DWORD AttribId, + DWORD IBOptions, + LPDIRECT3DINDEXBUFFER8 *ppIndexBuffer, + DWORD *pNumIndices, + LPD3DXBUFFER *ppStripLengths, + DWORD *pNumStrips +); + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX8MESH_H__ + + diff --git a/gfx/include/d3d8/d3dx8shape.h b/gfx/include/d3d8/d3dx8shape.h index c4d3630983..e874d6479f 100644 --- a/gfx/include/d3d8/d3dx8shape.h +++ b/gfx/include/d3d8/d3dx8shape.h @@ -1,220 +1,220 @@ -/////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8shapes.h -// Content: D3DX simple shapes -// -/////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8SHAPES_H__ -#define __D3DX8SHAPES_H__ - -/////////////////////////////////////////////////////////////////////////// -// Functions: -/////////////////////////////////////////////////////////////////////////// - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - -//------------------------------------------------------------------------- -// D3DXCreatePolygon: -// ------------------ -// Creates a mesh containing an n-sided polygon. The polygon is centered -// at the origin. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// Length Length of each side. -// Sides Number of sides the polygon has. (Must be >= 3) -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreatePolygon( - LPDIRECT3DDEVICE8 pDevice, - FLOAT Length, - UINT Sides, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateBox: -// -------------- -// Creates a mesh containing an axis-aligned box. The box is centered at -// the origin. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// Width Width of box (along X-axis) -// Height Height of box (along Y-axis) -// Depth Depth of box (along Z-axis) -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateBox( - LPDIRECT3DDEVICE8 pDevice, - FLOAT Width, - FLOAT Height, - FLOAT Depth, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateCylinder: -// ------------------- -// Creates a mesh containing a cylinder. The generated cylinder is -// centered at the origin, and its axis is aligned with the Z-axis. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// Radius1 Radius at -Z end (should be >= 0.0f) -// Radius2 Radius at +Z end (should be >= 0.0f) -// Length Length of cylinder (along Z-axis) -// Slices Number of slices about the main axis -// Stacks Number of stacks along the main axis -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateCylinder( - LPDIRECT3DDEVICE8 pDevice, - FLOAT Radius1, - FLOAT Radius2, - FLOAT Length, - UINT Slices, - UINT Stacks, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateSphere: -// ----------------- -// Creates a mesh containing a sphere. The sphere is centered at the -// origin. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// Radius Radius of the sphere (should be >= 0.0f) -// Slices Number of slices about the main axis -// Stacks Number of stacks along the main axis -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateSphere( - LPDIRECT3DDEVICE8 pDevice, - FLOAT Radius, - UINT Slices, - UINT Stacks, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateTorus: -// ---------------- -// Creates a mesh containing a torus. The generated torus is centered at -// the origin, and its axis is aligned with the Z-axis. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// InnerRadius Inner radius of the torus (should be >= 0.0f) -// OuterRadius Outer radius of the torue (should be >= 0.0f) -// Sides Number of sides in a cross-section (must be >= 3) -// Rings Number of rings making up the torus (must be >= 3) -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateTorus( - LPDIRECT3DDEVICE8 pDevice, - FLOAT InnerRadius, - FLOAT OuterRadius, - UINT Sides, - UINT Rings, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateTeapot: -// ----------------- -// Creates a mesh containing a teapot. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// ppMesh The mesh object which will be created -// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateTeapot( - LPDIRECT3DDEVICE8 pDevice, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency); - - -//------------------------------------------------------------------------- -// D3DXCreateText: -// --------------- -// Creates a mesh containing the specified text using the font associated -// with the device context. -// -// Parameters: -// -// pDevice The D3D device with which the mesh is going to be used. -// hDC Device context, with desired font selected -// pText Text to generate -// Deviation Maximum chordal deviation from true font outlines -// Extrusion Amount to extrude text in -Z direction -// ppMesh The mesh object which will be created -// pGlyphMetrics Address of buffer to receive glyph metric data (or NULL) -//------------------------------------------------------------------------- -HRESULT WINAPI - D3DXCreateTextA( - LPDIRECT3DDEVICE8 pDevice, - HDC hDC, - LPCSTR pText, - FLOAT Deviation, - FLOAT Extrusion, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency, - LPGLYPHMETRICSFLOAT pGlyphMetrics); - -HRESULT WINAPI - D3DXCreateTextW( - LPDIRECT3DDEVICE8 pDevice, - HDC hDC, - LPCWSTR pText, - FLOAT Deviation, - FLOAT Extrusion, - LPD3DXMESH* ppMesh, - LPD3DXBUFFER* ppAdjacency, - LPGLYPHMETRICSFLOAT pGlyphMetrics); - -#ifdef UNICODE -#define D3DXCreateText D3DXCreateTextW -#else -#define D3DXCreateText D3DXCreateTextA -#endif - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //__D3DX8SHAPES_H__ +/////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8shapes.h +// Content: D3DX simple shapes +// +/////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8SHAPES_H__ +#define __D3DX8SHAPES_H__ + +/////////////////////////////////////////////////////////////////////////// +// Functions: +/////////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + +//------------------------------------------------------------------------- +// D3DXCreatePolygon: +// ------------------ +// Creates a mesh containing an n-sided polygon. The polygon is centered +// at the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Length Length of each side. +// Sides Number of sides the polygon has. (Must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreatePolygon( + LPDIRECT3DDEVICE8 pDevice, + FLOAT Length, + UINT Sides, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateBox: +// -------------- +// Creates a mesh containing an axis-aligned box. The box is centered at +// the origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Width Width of box (along X-axis) +// Height Height of box (along Y-axis) +// Depth Depth of box (along Z-axis) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateBox( + LPDIRECT3DDEVICE8 pDevice, + FLOAT Width, + FLOAT Height, + FLOAT Depth, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateCylinder: +// ------------------- +// Creates a mesh containing a cylinder. The generated cylinder is +// centered at the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius1 Radius at -Z end (should be >= 0.0f) +// Radius2 Radius at +Z end (should be >= 0.0f) +// Length Length of cylinder (along Z-axis) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateCylinder( + LPDIRECT3DDEVICE8 pDevice, + FLOAT Radius1, + FLOAT Radius2, + FLOAT Length, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateSphere: +// ----------------- +// Creates a mesh containing a sphere. The sphere is centered at the +// origin. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// Radius Radius of the sphere (should be >= 0.0f) +// Slices Number of slices about the main axis +// Stacks Number of stacks along the main axis +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateSphere( + LPDIRECT3DDEVICE8 pDevice, + FLOAT Radius, + UINT Slices, + UINT Stacks, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTorus: +// ---------------- +// Creates a mesh containing a torus. The generated torus is centered at +// the origin, and its axis is aligned with the Z-axis. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// InnerRadius Inner radius of the torus (should be >= 0.0f) +// OuterRadius Outer radius of the torue (should be >= 0.0f) +// Sides Number of sides in a cross-section (must be >= 3) +// Rings Number of rings making up the torus (must be >= 3) +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTorus( + LPDIRECT3DDEVICE8 pDevice, + FLOAT InnerRadius, + FLOAT OuterRadius, + UINT Sides, + UINT Rings, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateTeapot: +// ----------------- +// Creates a mesh containing a teapot. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// ppMesh The mesh object which will be created +// ppAdjacency Returns a buffer containing adjacency info. Can be NULL. +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTeapot( + LPDIRECT3DDEVICE8 pDevice, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency); + + +//------------------------------------------------------------------------- +// D3DXCreateText: +// --------------- +// Creates a mesh containing the specified text using the font associated +// with the device context. +// +// Parameters: +// +// pDevice The D3D device with which the mesh is going to be used. +// hDC Device context, with desired font selected +// pText Text to generate +// Deviation Maximum chordal deviation from true font outlines +// Extrusion Amount to extrude text in -Z direction +// ppMesh The mesh object which will be created +// pGlyphMetrics Address of buffer to receive glyph metric data (or NULL) +//------------------------------------------------------------------------- +HRESULT WINAPI + D3DXCreateTextA( + LPDIRECT3DDEVICE8 pDevice, + HDC hDC, + LPCSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +HRESULT WINAPI + D3DXCreateTextW( + LPDIRECT3DDEVICE8 pDevice, + HDC hDC, + LPCWSTR pText, + FLOAT Deviation, + FLOAT Extrusion, + LPD3DXMESH* ppMesh, + LPD3DXBUFFER* ppAdjacency, + LPGLYPHMETRICSFLOAT pGlyphMetrics); + +#ifdef UNICODE +#define D3DXCreateText D3DXCreateTextW +#else +#define D3DXCreateText D3DXCreateTextA +#endif + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX8SHAPES_H__ diff --git a/gfx/include/d3d8/d3dx8tex.h b/gfx/include/d3d8/d3dx8tex.h index 2bdfce8b82..cb30a7cf37 100644 --- a/gfx/include/d3d8/d3dx8tex.h +++ b/gfx/include/d3d8/d3dx8tex.h @@ -1,1592 +1,1592 @@ -////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) Microsoft Corporation. All Rights Reserved. -// -// File: d3dx8tex.h -// Content: D3DX texturing APIs -// -////////////////////////////////////////////////////////////////////////////// - -#include "d3dx8.h" - -#ifndef __D3DX8TEX_H__ -#define __D3DX8TEX_H__ - - -//---------------------------------------------------------------------------- -// D3DX_FILTER flags: -// ------------------ -// -// A valid filter must contain one of these values: -// -// D3DX_FILTER_NONE -// No scaling or filtering will take place. Pixels outside the bounds -// of the source image are assumed to be transparent black. -// D3DX_FILTER_POINT -// Each destination pixel is computed by sampling the nearest pixel -// from the source image. -// D3DX_FILTER_LINEAR -// Each destination pixel is computed by linearly interpolating between -// the nearest pixels in the source image. This filter works best -// when the scale on each axis is less than 2. -// D3DX_FILTER_TRIANGLE -// Every pixel in the source image contributes equally to the -// destination image. This is the slowest of all the filters. -// D3DX_FILTER_BOX -// Each pixel is computed by averaging a 2x2(x2) box pixels from -// the source image. Only works when the dimensions of the -// destination are half those of the source. (as with mip maps) -// -// And can be OR'd with any of these optional flags: -// -// D3DX_FILTER_MIRROR_U -// Indicates that pixels off the edge of the texture on the U-axis -// should be mirrored, not wraped. -// D3DX_FILTER_MIRROR_V -// Indicates that pixels off the edge of the texture on the V-axis -// should be mirrored, not wraped. -// D3DX_FILTER_MIRROR_W -// Indicates that pixels off the edge of the texture on the W-axis -// should be mirrored, not wraped. -// D3DX_FILTER_MIRROR -// Same as specifying D3DX_FILTER_MIRROR_U | D3DX_FILTER_MIRROR_V | -// D3DX_FILTER_MIRROR_V -// D3DX_FILTER_DITHER -// Dithers the resulting image. -// -//---------------------------------------------------------------------------- - -#define D3DX_FILTER_NONE (1 << 0) -#define D3DX_FILTER_POINT (2 << 0) -#define D3DX_FILTER_LINEAR (3 << 0) -#define D3DX_FILTER_TRIANGLE (4 << 0) -#define D3DX_FILTER_BOX (5 << 0) - -#define D3DX_FILTER_MIRROR_U (1 << 16) -#define D3DX_FILTER_MIRROR_V (2 << 16) -#define D3DX_FILTER_MIRROR_W (4 << 16) -#define D3DX_FILTER_MIRROR (7 << 16) -#define D3DX_FILTER_DITHER (8 << 16) - - -//---------------------------------------------------------------------------- -// D3DX_NORMALMAP flags: -// --------------------- -// These flags are used to control how D3DXComputeNormalMap generates normal -// maps. Any number of these flags may be OR'd together in any combination. -// -// D3DX_NORMALMAP_MIRROR_U -// Indicates that pixels off the edge of the texture on the U-axis -// should be mirrored, not wraped. -// D3DX_NORMALMAP_MIRROR_V -// Indicates that pixels off the edge of the texture on the V-axis -// should be mirrored, not wraped. -// D3DX_NORMALMAP_MIRROR -// Same as specifying D3DX_NORMALMAP_MIRROR_U | D3DX_NORMALMAP_MIRROR_V -// D3DX_NORMALMAP_INVERTSIGN -// Inverts the direction of each normal -// D3DX_NORMALMAP_COMPUTE_OCCLUSION -// Compute the per pixel Occlusion term and encodes it into the alpha. -// An Alpha of 1 means that the pixel is not obscured in anyway, and -// an alpha of 0 would mean that the pixel is completly obscured. -// -//---------------------------------------------------------------------------- - -//---------------------------------------------------------------------------- - -#define D3DX_NORMALMAP_MIRROR_U (1 << 16) -#define D3DX_NORMALMAP_MIRROR_V (2 << 16) -#define D3DX_NORMALMAP_MIRROR (3 << 16) -#define D3DX_NORMALMAP_INVERTSIGN (8 << 16) -#define D3DX_NORMALMAP_COMPUTE_OCCLUSION (16 << 16) - - - - -//---------------------------------------------------------------------------- -// D3DX_CHANNEL flags: -// ------------------- -// These flags are used by functions which operate on or more channels -// in a texture. -// -// D3DX_CHANNEL_RED -// Indicates the red channel should be used -// D3DX_CHANNEL_BLUE -// Indicates the blue channel should be used -// D3DX_CHANNEL_GREEN -// Indicates the green channel should be used -// D3DX_CHANNEL_ALPHA -// Indicates the alpha channel should be used -// D3DX_CHANNEL_LUMINANCE -// Indicates the luminaces of the red green and blue channels should be -// used. -// -//---------------------------------------------------------------------------- - -#define D3DX_CHANNEL_RED (1 << 0) -#define D3DX_CHANNEL_BLUE (1 << 1) -#define D3DX_CHANNEL_GREEN (1 << 2) -#define D3DX_CHANNEL_ALPHA (1 << 3) -#define D3DX_CHANNEL_LUMINANCE (1 << 4) - - - - -//---------------------------------------------------------------------------- -// D3DXIMAGE_FILEFORMAT: -// --------------------- -// This enum is used to describe supported image file formats. -// -//---------------------------------------------------------------------------- - -typedef enum _D3DXIMAGE_FILEFORMAT -{ - D3DXIFF_BMP = 0, - D3DXIFF_JPG = 1, - D3DXIFF_TGA = 2, - D3DXIFF_PNG = 3, - D3DXIFF_DDS = 4, - D3DXIFF_PPM = 5, - D3DXIFF_DIB = 6, - D3DXIFF_FORCE_DWORD = 0x7fffffff - -} D3DXIMAGE_FILEFORMAT; - - -//---------------------------------------------------------------------------- -// LPD3DXFILL2D and LPD3DXFILL3D: -// ------------------------------ -// Function types used by the texture fill functions. -// -// Parameters: -// pOut -// Pointer to a vector which the function uses to return its result. -// X,Y,Z,W will be mapped to R,G,B,A respectivly. -// pTexCoord -// Pointer to a vector containing the coordinates of the texel currently -// being evaluated. Textures and VolumeTexture texcoord components -// range from 0 to 1. CubeTexture texcoord component range from -1 to 1. -// pTexelSize -// Pointer to a vector containing the dimensions of the current texel. -// pData -// Pointer to user data. -// -//---------------------------------------------------------------------------- - -typedef VOID (*LPD3DXFILL2D)(D3DXVECTOR4 *pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData); -typedef VOID (*LPD3DXFILL3D)(D3DXVECTOR4 *pOut, D3DXVECTOR3 *pTexCoord, D3DXVECTOR3 *pTexelSize, LPVOID pData); - - - -//---------------------------------------------------------------------------- -// D3DXIMAGE_INFO: -// --------------- -// This structure is used to return a rough description of what the -// the original contents of an image file looked like. -// -// Width -// Width of original image in pixels -// Height -// Height of original image in pixels -// Depth -// Depth of original image in pixels -// MipLevels -// Number of mip levels in original image -// Format -// D3D format which most closely describes the data in original image -// ResourceType -// D3DRESOURCETYPE representing the type of texture stored in the file. -// D3DRTYPE_TEXTURE, D3DRTYPE_VOLUMETEXTURE, or D3DRTYPE_CUBETEXTURE. -// ImageFileFormat -// D3DXIMAGE_FILEFORMAT representing the format of the image file. -// -//---------------------------------------------------------------------------- - -typedef struct _D3DXIMAGE_INFO -{ - UINT Width; - UINT Height; - UINT Depth; - UINT MipLevels; - D3DFORMAT Format; - D3DRESOURCETYPE ResourceType; - D3DXIMAGE_FILEFORMAT ImageFileFormat; - -} D3DXIMAGE_INFO; - - - - - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - - - -////////////////////////////////////////////////////////////////////////////// -// Image File APIs /////////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// -; -//---------------------------------------------------------------------------- -// GetImageInfoFromFile/Resource: -// ------------------------------ -// Fills in a D3DXIMAGE_INFO struct with information about an image file. -// -// Parameters: -// pSrcFile -// File name of the source image. -// pSrcModule -// Module where resource is located, or NULL for module associated -// with image the os used to create the current process. -// pSrcResource -// Resource name -// pSrcData -// Pointer to file in memory. -// SrcDataSize -// Size in bytes of file in memory. -// pSrcInfo -// Pointer to a D3DXIMAGE_INFO structure to be filled in with the -// description of the data in the source image file. -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXGetImageInfoFromFileA( - LPCSTR pSrcFile, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXGetImageInfoFromFileW( - LPCWSTR pSrcFile, - D3DXIMAGE_INFO* pSrcInfo); - -#ifdef UNICODE -#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileW -#else -#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileA -#endif - - -HRESULT WINAPI - D3DXGetImageInfoFromResourceA( - HMODULE hSrcModule, - LPCSTR pSrcResource, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXGetImageInfoFromResourceW( - HMODULE hSrcModule, - LPCWSTR pSrcResource, - D3DXIMAGE_INFO* pSrcInfo); - -#ifdef UNICODE -#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceW -#else -#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceA -#endif - - -HRESULT WINAPI - D3DXGetImageInfoFromFileInMemory( - LPCVOID pSrcData, - UINT SrcDataSize, - D3DXIMAGE_INFO* pSrcInfo); - - - - -////////////////////////////////////////////////////////////////////////////// -// Load/Save Surface APIs //////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// D3DXLoadSurfaceFromFile/Resource: -// --------------------------------- -// Load surface from a file or resource -// -// Parameters: -// pDestSurface -// Destination surface, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestRect -// Destination rectangle, or NULL for entire surface -// pSrcFile -// File name of the source image. -// pSrcModule -// Module where resource is located, or NULL for module associated -// with image the os used to create the current process. -// pSrcResource -// Resource name -// pSrcData -// Pointer to file in memory. -// SrcDataSize -// Size in bytes of file in memory. -// pSrcRect -// Source rectangle, or NULL for entire image -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// pSrcInfo -// Pointer to a D3DXIMAGE_INFO structure to be filled in with the -// description of the data in the source image file, or NULL. -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadSurfaceFromFileA( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - LPCSTR pSrcFile, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXLoadSurfaceFromFileW( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - LPCWSTR pSrcFile, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -#ifdef UNICODE -#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileW -#else -#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileA -#endif - - - -HRESULT WINAPI - D3DXLoadSurfaceFromResourceA( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - HMODULE hSrcModule, - LPCSTR pSrcResource, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXLoadSurfaceFromResourceW( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - - -#ifdef UNICODE -#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceW -#else -#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceA -#endif - - - -HRESULT WINAPI - D3DXLoadSurfaceFromFileInMemory( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - LPCVOID pSrcData, - UINT SrcDataSize, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - - - -//---------------------------------------------------------------------------- -// D3DXLoadSurfaceFromSurface: -// --------------------------- -// Load surface from another surface (with color conversion) -// -// Parameters: -// pDestSurface -// Destination surface, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestRect -// Destination rectangle, or NULL for entire surface -// pSrcSurface -// Source surface -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcRect -// Source rectangle, or NULL for entire surface -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadSurfaceFromSurface( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - LPDIRECT3DSURFACE8 pSrcSurface, - CONST PALETTEENTRY* pSrcPalette, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey); - - -//---------------------------------------------------------------------------- -// D3DXLoadSurfaceFromMemory: -// -------------------------- -// Load surface from memory. -// -// Parameters: -// pDestSurface -// Destination surface, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestRect -// Destination rectangle, or NULL for entire surface -// pSrcMemory -// Pointer to the top-left corner of the source image in memory -// SrcFormat -// Pixel format of the source image. -// SrcPitch -// Pitch of source image, in bytes. For DXT formats, this number -// should represent the width of one row of cells, in bytes. -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcRect -// Source rectangle. -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadSurfaceFromMemory( - LPDIRECT3DSURFACE8 pDestSurface, - CONST PALETTEENTRY* pDestPalette, - CONST RECT* pDestRect, - LPCVOID pSrcMemory, - D3DFORMAT SrcFormat, - UINT SrcPitch, - CONST PALETTEENTRY* pSrcPalette, - CONST RECT* pSrcRect, - DWORD Filter, - D3DCOLOR ColorKey); - - -//---------------------------------------------------------------------------- -// D3DXSaveSurfaceToFile: -// ---------------------- -// Save a surface to a image file. -// -// Parameters: -// pDestFile -// File name of the destination file -// DestFormat -// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. -// pSrcSurface -// Source surface, containing the image to be saved -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcRect -// Source rectangle, or NULL for the entire image -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXSaveSurfaceToFileA( - LPCSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DSURFACE8 pSrcSurface, - CONST PALETTEENTRY* pSrcPalette, - CONST RECT* pSrcRect); - -HRESULT WINAPI - D3DXSaveSurfaceToFileW( - LPCWSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DSURFACE8 pSrcSurface, - CONST PALETTEENTRY* pSrcPalette, - CONST RECT* pSrcRect); - -#ifdef UNICODE -#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileW -#else -#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileA -#endif - - - - -////////////////////////////////////////////////////////////////////////////// -// Load/Save Volume APIs ///////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// D3DXLoadVolumeFromFile/Resource: -// -------------------------------- -// Load volume from a file or resource -// -// Parameters: -// pDestVolume -// Destination volume, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestBox -// Destination box, or NULL for entire volume -// pSrcFile -// File name of the source image. -// pSrcModule -// Module where resource is located, or NULL for module associated -// with image the os used to create the current process. -// pSrcResource -// Resource name -// pSrcData -// Pointer to file in memory. -// SrcDataSize -// Size in bytes of file in memory. -// pSrcBox -// Source box, or NULL for entire image -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// pSrcInfo -// Pointer to a D3DXIMAGE_INFO structure to be filled in with the -// description of the data in the source image file, or NULL. -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadVolumeFromFileA( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - LPCSTR pSrcFile, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXLoadVolumeFromFileW( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - LPCWSTR pSrcFile, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -#ifdef UNICODE -#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileW -#else -#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileA -#endif - - -HRESULT WINAPI - D3DXLoadVolumeFromResourceA( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - HMODULE hSrcModule, - LPCSTR pSrcResource, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -HRESULT WINAPI - D3DXLoadVolumeFromResourceW( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - -#ifdef UNICODE -#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceW -#else -#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceA -#endif - - - -HRESULT WINAPI - D3DXLoadVolumeFromFileInMemory( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - LPCVOID pSrcData, - UINT SrcDataSize, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo); - - - -//---------------------------------------------------------------------------- -// D3DXLoadVolumeFromVolume: -// ------------------------- -// Load volume from another volume (with color conversion) -// -// Parameters: -// pDestVolume -// Destination volume, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestBox -// Destination box, or NULL for entire volume -// pSrcVolume -// Source volume -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcBox -// Source box, or NULL for entire volume -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadVolumeFromVolume( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - LPDIRECT3DVOLUME8 pSrcVolume, - CONST PALETTEENTRY* pSrcPalette, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey); - - - -//---------------------------------------------------------------------------- -// D3DXLoadVolumeFromMemory: -// ------------------------- -// Load volume from memory. -// -// Parameters: -// pDestVolume -// Destination volume, which will receive the image. -// pDestPalette -// Destination palette of 256 colors, or NULL -// pDestBox -// Destination box, or NULL for entire volume -// pSrcMemory -// Pointer to the top-left corner of the source volume in memory -// SrcFormat -// Pixel format of the source volume. -// SrcRowPitch -// Pitch of source image, in bytes. For DXT formats, this number -// should represent the size of one row of cells, in bytes. -// SrcSlicePitch -// Pitch of source image, in bytes. For DXT formats, this number -// should represent the size of one slice of cells, in bytes. -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcBox -// Source box. -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXLoadVolumeFromMemory( - LPDIRECT3DVOLUME8 pDestVolume, - CONST PALETTEENTRY* pDestPalette, - CONST D3DBOX* pDestBox, - LPCVOID pSrcMemory, - D3DFORMAT SrcFormat, - UINT SrcRowPitch, - UINT SrcSlicePitch, - CONST PALETTEENTRY* pSrcPalette, - CONST D3DBOX* pSrcBox, - DWORD Filter, - D3DCOLOR ColorKey); - - - -//---------------------------------------------------------------------------- -// D3DXSaveVolumeToFile: -// --------------------- -// Save a volume to a image file. -// -// Parameters: -// pDestFile -// File name of the destination file -// DestFormat -// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. -// pSrcVolume -// Source volume, containing the image to be saved -// pSrcPalette -// Source palette of 256 colors, or NULL -// pSrcBox -// Source box, or NULL for the entire volume -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXSaveVolumeToFileA( - LPCSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DVOLUME8 pSrcVolume, - CONST PALETTEENTRY* pSrcPalette, - CONST D3DBOX* pSrcBox); - -HRESULT WINAPI - D3DXSaveVolumeToFileW( - LPCWSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DVOLUME8 pSrcVolume, - CONST PALETTEENTRY* pSrcPalette, - CONST D3DBOX* pSrcBox); - -#ifdef UNICODE -#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileW -#else -#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileA -#endif - - - - -////////////////////////////////////////////////////////////////////////////// -// Create/Save Texture APIs ////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// D3DXCheckTextureRequirements: -// ----------------------------- -// Checks texture creation parameters. If parameters are invalid, this -// function returns corrected parameters. -// -// Parameters: -// -// pDevice -// The D3D device to be used -// pWidth, pHeight, pDepth, pSize -// Desired size in pixels, or NULL. Returns corrected size. -// pNumMipLevels -// Number of desired mipmap levels, or NULL. Returns corrected number. -// Usage -// Texture usage flags -// pFormat -// Desired pixel format, or NULL. Returns corrected format. -// Pool -// Memory pool to be used to create texture -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXCheckTextureRequirements( - LPDIRECT3DDEVICE8 pDevice, - UINT* pWidth, - UINT* pHeight, - UINT* pNumMipLevels, - DWORD Usage, - D3DFORMAT* pFormat, - D3DPOOL Pool); - -HRESULT WINAPI - D3DXCheckCubeTextureRequirements( - LPDIRECT3DDEVICE8 pDevice, - UINT* pSize, - UINT* pNumMipLevels, - DWORD Usage, - D3DFORMAT* pFormat, - D3DPOOL Pool); - -HRESULT WINAPI - D3DXCheckVolumeTextureRequirements( - LPDIRECT3DDEVICE8 pDevice, - UINT* pWidth, - UINT* pHeight, - UINT* pDepth, - UINT* pNumMipLevels, - DWORD Usage, - D3DFORMAT* pFormat, - D3DPOOL Pool); - - -//---------------------------------------------------------------------------- -// D3DXCreateTexture: -// ------------------ -// Create an empty texture -// -// Parameters: -// -// pDevice -// The D3D device with which the texture is going to be used. -// Width, Height, Depth, Size -// size in pixels; these must be non-zero -// MipLevels -// number of mip levels desired; if zero or D3DX_DEFAULT, a complete -// mipmap chain will be created. -// Usage -// Texture usage flags -// Format -// Pixel format. -// Pool -// Memory pool to be used to create texture -// ppTexture, ppCubeTexture, ppVolumeTexture -// The texture object that will be created -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXCreateTexture( - LPDIRECT3DDEVICE8 pDevice, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateCubeTexture( - LPDIRECT3DDEVICE8 pDevice, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTexture( - LPDIRECT3DDEVICE8 pDevice, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - - - -//---------------------------------------------------------------------------- -// D3DXCreateTextureFromFile/Resource: -// ----------------------------------- -// Create a texture object from a file or resource. -// -// Parameters: -// -// pDevice -// The D3D device with which the texture is going to be used. -// pSrcFile -// File name. -// hSrcModule -// Module handle. if NULL, current module will be used. -// pSrcResource -// Resource name in module -// pvSrcData -// Pointer to file in memory. -// SrcDataSize -// Size in bytes of file in memory. -// Width, Height, Depth, Size -// Size in pixels; if zero or D3DX_DEFAULT, the size will be taken -// from the file. -// MipLevels -// Number of mip levels; if zero or D3DX_DEFAULT, a complete mipmap -// chain will be created. -// Usage -// Texture usage flags -// Format -// Desired pixel format. If D3DFMT_UNKNOWN, the format will be -// taken from the file. -// Pool -// Memory pool to be used to create texture -// Filter -// D3DX_FILTER flags controlling how the image is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. -// MipFilter -// D3DX_FILTER flags controlling how each miplevel is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_BOX, -// ColorKey -// Color to replace with transparent black, or 0 to disable colorkey. -// This is always a 32-bit ARGB color, independent of the source image -// format. Alpha is significant, and should usually be set to FF for -// opaque colorkeys. (ex. Opaque black == 0xff000000) -// pSrcInfo -// Pointer to a D3DXIMAGE_INFO structure to be filled in with the -// description of the data in the source image file, or NULL. -// pPalette -// 256 color palette to be filled in, or NULL -// ppTexture, ppCubeTexture, ppVolumeTexture -// The texture object that will be created -// -//---------------------------------------------------------------------------- - - -// FromFile - -HRESULT WINAPI - D3DXCreateTextureFromFileA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateTextureFromFileW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - LPDIRECT3DTEXTURE8* ppTexture); - -#ifdef UNICODE -#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileW -#else -#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileA -#endif - - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -#ifdef UNICODE -#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileW -#else -#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileA -#endif - - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -#ifdef UNICODE -#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileW -#else -#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileA -#endif - - -// FromResource - -HRESULT WINAPI - D3DXCreateTextureFromResourceA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateTextureFromResourceW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - LPDIRECT3DTEXTURE8* ppTexture); - -#ifdef UNICODE -#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceW -#else -#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceA -#endif - - -HRESULT WINAPI - D3DXCreateCubeTextureFromResourceA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromResourceW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -#ifdef UNICODE -#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceW -#else -#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceA -#endif - - -HRESULT WINAPI - D3DXCreateVolumeTextureFromResourceA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromResourceW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -#ifdef UNICODE -#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceW -#else -#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceA -#endif - - -// FromFileEx - -HRESULT WINAPI - D3DXCreateTextureFromFileExA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateTextureFromFileExW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DTEXTURE8* ppTexture); - -#ifdef UNICODE -#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExW -#else -#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExA -#endif - - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileExA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileExW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -#ifdef UNICODE -#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExW -#else -#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExA -#endif - - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileExA( - LPDIRECT3DDEVICE8 pDevice, - LPCSTR pSrcFile, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileExW( - LPDIRECT3DDEVICE8 pDevice, - LPCWSTR pSrcFile, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -#ifdef UNICODE -#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExW -#else -#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExA -#endif - - -// FromResourceEx - -HRESULT WINAPI - D3DXCreateTextureFromResourceExA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateTextureFromResourceExW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DTEXTURE8* ppTexture); - -#ifdef UNICODE -#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExW -#else -#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExA -#endif - - -HRESULT WINAPI - D3DXCreateCubeTextureFromResourceExA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromResourceExW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -#ifdef UNICODE -#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExW -#else -#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExA -#endif - - -HRESULT WINAPI - D3DXCreateVolumeTextureFromResourceExA( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCSTR pSrcResource, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromResourceExW( - LPDIRECT3DDEVICE8 pDevice, - HMODULE hSrcModule, - LPCWSTR pSrcResource, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - -#ifdef UNICODE -#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExW -#else -#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExA -#endif - - -// FromFileInMemory - -HRESULT WINAPI - D3DXCreateTextureFromFileInMemory( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileInMemory( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileInMemory( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - - -// FromFileInMemoryEx - -HRESULT WINAPI - D3DXCreateTextureFromFileInMemoryEx( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - UINT Width, - UINT Height, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DTEXTURE8* ppTexture); - -HRESULT WINAPI - D3DXCreateCubeTextureFromFileInMemoryEx( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - UINT Size, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DCUBETEXTURE8* ppCubeTexture); - -HRESULT WINAPI - D3DXCreateVolumeTextureFromFileInMemoryEx( - LPDIRECT3DDEVICE8 pDevice, - LPCVOID pSrcData, - UINT SrcDataSize, - UINT Width, - UINT Height, - UINT Depth, - UINT MipLevels, - DWORD Usage, - D3DFORMAT Format, - D3DPOOL Pool, - DWORD Filter, - DWORD MipFilter, - D3DCOLOR ColorKey, - D3DXIMAGE_INFO* pSrcInfo, - PALETTEENTRY* pPalette, - LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); - - - -//---------------------------------------------------------------------------- -// D3DXSaveTextureToFile: -// ---------------------- -// Save a texture to a file. -// -// Parameters: -// pDestFile -// File name of the destination file -// DestFormat -// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. -// pSrcTexture -// Source texture, containing the image to be saved -// pSrcPalette -// Source palette of 256 colors, or NULL -// -//---------------------------------------------------------------------------- - - -HRESULT WINAPI - D3DXSaveTextureToFileA( - LPCSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DBASETEXTURE8 pSrcTexture, - CONST PALETTEENTRY* pSrcPalette); - -HRESULT WINAPI - D3DXSaveTextureToFileW( - LPCWSTR pDestFile, - D3DXIMAGE_FILEFORMAT DestFormat, - LPDIRECT3DBASETEXTURE8 pSrcTexture, - CONST PALETTEENTRY* pSrcPalette); - -#ifdef UNICODE -#define D3DXSaveTextureToFile D3DXSaveTextureToFileW -#else -#define D3DXSaveTextureToFile D3DXSaveTextureToFileA -#endif - - - - -////////////////////////////////////////////////////////////////////////////// -// Misc Texture APIs ///////////////////////////////////////////////////////// -////////////////////////////////////////////////////////////////////////////// - -//---------------------------------------------------------------------------- -// D3DXFilterTexture: -// ------------------ -// Filters mipmaps levels of a texture. -// -// Parameters: -// pBaseTexture -// The texture object to be filtered -// pPalette -// 256 color palette to be used, or NULL for non-palettized formats -// SrcLevel -// The level whose image is used to generate the subsequent levels. -// Filter -// D3DX_FILTER flags controlling how each miplevel is filtered. -// Or D3DX_DEFAULT for D3DX_FILTER_BOX, -// -//---------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXFilterTexture( - LPDIRECT3DBASETEXTURE8 pBaseTexture, - CONST PALETTEENTRY* pPalette, - UINT SrcLevel, - DWORD Filter); - -#define D3DXFilterCubeTexture D3DXFilterTexture -#define D3DXFilterVolumeTexture D3DXFilterTexture - - - -//---------------------------------------------------------------------------- -// D3DXFillTexture: -// ---------------- -// Uses a user provided function to fill each texel of each mip level of a -// given texture. -// -// Paramters: -// pTexture, pCubeTexture, pVolumeTexture -// Pointer to the texture to be filled. -// pFunction -// Pointer to user provided evalutor function which will be used to -// compute the value of each texel. -// pData -// Pointer to an arbitrary block of user defined data. This pointer -// will be passed to the function provided in pFunction -//----------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXFillTexture( - LPDIRECT3DTEXTURE8 pTexture, - LPD3DXFILL2D pFunction, - LPVOID pData); - -HRESULT WINAPI - D3DXFillCubeTexture( - LPDIRECT3DCUBETEXTURE8 pCubeTexture, - LPD3DXFILL3D pFunction, - LPVOID pData); - -HRESULT WINAPI - D3DXFillVolumeTexture( - LPDIRECT3DVOLUMETEXTURE8 pVolumeTexture, - LPD3DXFILL3D pFunction, - LPVOID pData); - - - -//---------------------------------------------------------------------------- -// D3DXComputeNormalMap: -// --------------------- -// Converts a height map into a normal map. The (x,y,z) components of each -// normal are mapped to the (r,g,b) channels of the output texture. -// -// Parameters -// pTexture -// Pointer to the destination texture -// pSrcTexture -// Pointer to the source heightmap texture -// pSrcPalette -// Source palette of 256 colors, or NULL -// Flags -// D3DX_NORMALMAP flags -// Channel -// D3DX_CHANNEL specifying source of height information -// Amplitude -// The constant value which the height information is multiplied by. -//--------------------------------------------------------------------------- - -HRESULT WINAPI - D3DXComputeNormalMap( - LPDIRECT3DTEXTURE8 pTexture, - LPDIRECT3DTEXTURE8 pSrcTexture, - CONST PALETTEENTRY* pSrcPalette, - DWORD Flags, - DWORD Channel, - FLOAT Amplitude); - - - - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif //__D3DX8TEX_H__ +////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) Microsoft Corporation. All Rights Reserved. +// +// File: d3dx8tex.h +// Content: D3DX texturing APIs +// +////////////////////////////////////////////////////////////////////////////// + +#include "d3dx8.h" + +#ifndef __D3DX8TEX_H__ +#define __D3DX8TEX_H__ + + +//---------------------------------------------------------------------------- +// D3DX_FILTER flags: +// ------------------ +// +// A valid filter must contain one of these values: +// +// D3DX_FILTER_NONE +// No scaling or filtering will take place. Pixels outside the bounds +// of the source image are assumed to be transparent black. +// D3DX_FILTER_POINT +// Each destination pixel is computed by sampling the nearest pixel +// from the source image. +// D3DX_FILTER_LINEAR +// Each destination pixel is computed by linearly interpolating between +// the nearest pixels in the source image. This filter works best +// when the scale on each axis is less than 2. +// D3DX_FILTER_TRIANGLE +// Every pixel in the source image contributes equally to the +// destination image. This is the slowest of all the filters. +// D3DX_FILTER_BOX +// Each pixel is computed by averaging a 2x2(x2) box pixels from +// the source image. Only works when the dimensions of the +// destination are half those of the source. (as with mip maps) +// +// And can be OR'd with any of these optional flags: +// +// D3DX_FILTER_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR_W +// Indicates that pixels off the edge of the texture on the W-axis +// should be mirrored, not wraped. +// D3DX_FILTER_MIRROR +// Same as specifying D3DX_FILTER_MIRROR_U | D3DX_FILTER_MIRROR_V | +// D3DX_FILTER_MIRROR_V +// D3DX_FILTER_DITHER +// Dithers the resulting image. +// +//---------------------------------------------------------------------------- + +#define D3DX_FILTER_NONE (1 << 0) +#define D3DX_FILTER_POINT (2 << 0) +#define D3DX_FILTER_LINEAR (3 << 0) +#define D3DX_FILTER_TRIANGLE (4 << 0) +#define D3DX_FILTER_BOX (5 << 0) + +#define D3DX_FILTER_MIRROR_U (1 << 16) +#define D3DX_FILTER_MIRROR_V (2 << 16) +#define D3DX_FILTER_MIRROR_W (4 << 16) +#define D3DX_FILTER_MIRROR (7 << 16) +#define D3DX_FILTER_DITHER (8 << 16) + + +//---------------------------------------------------------------------------- +// D3DX_NORMALMAP flags: +// --------------------- +// These flags are used to control how D3DXComputeNormalMap generates normal +// maps. Any number of these flags may be OR'd together in any combination. +// +// D3DX_NORMALMAP_MIRROR_U +// Indicates that pixels off the edge of the texture on the U-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR_V +// Indicates that pixels off the edge of the texture on the V-axis +// should be mirrored, not wraped. +// D3DX_NORMALMAP_MIRROR +// Same as specifying D3DX_NORMALMAP_MIRROR_U | D3DX_NORMALMAP_MIRROR_V +// D3DX_NORMALMAP_INVERTSIGN +// Inverts the direction of each normal +// D3DX_NORMALMAP_COMPUTE_OCCLUSION +// Compute the per pixel Occlusion term and encodes it into the alpha. +// An Alpha of 1 means that the pixel is not obscured in anyway, and +// an alpha of 0 would mean that the pixel is completly obscured. +// +//---------------------------------------------------------------------------- + +//---------------------------------------------------------------------------- + +#define D3DX_NORMALMAP_MIRROR_U (1 << 16) +#define D3DX_NORMALMAP_MIRROR_V (2 << 16) +#define D3DX_NORMALMAP_MIRROR (3 << 16) +#define D3DX_NORMALMAP_INVERTSIGN (8 << 16) +#define D3DX_NORMALMAP_COMPUTE_OCCLUSION (16 << 16) + + + + +//---------------------------------------------------------------------------- +// D3DX_CHANNEL flags: +// ------------------- +// These flags are used by functions which operate on or more channels +// in a texture. +// +// D3DX_CHANNEL_RED +// Indicates the red channel should be used +// D3DX_CHANNEL_BLUE +// Indicates the blue channel should be used +// D3DX_CHANNEL_GREEN +// Indicates the green channel should be used +// D3DX_CHANNEL_ALPHA +// Indicates the alpha channel should be used +// D3DX_CHANNEL_LUMINANCE +// Indicates the luminaces of the red green and blue channels should be +// used. +// +//---------------------------------------------------------------------------- + +#define D3DX_CHANNEL_RED (1 << 0) +#define D3DX_CHANNEL_BLUE (1 << 1) +#define D3DX_CHANNEL_GREEN (1 << 2) +#define D3DX_CHANNEL_ALPHA (1 << 3) +#define D3DX_CHANNEL_LUMINANCE (1 << 4) + + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_FILEFORMAT: +// --------------------- +// This enum is used to describe supported image file formats. +// +//---------------------------------------------------------------------------- + +typedef enum _D3DXIMAGE_FILEFORMAT +{ + D3DXIFF_BMP = 0, + D3DXIFF_JPG = 1, + D3DXIFF_TGA = 2, + D3DXIFF_PNG = 3, + D3DXIFF_DDS = 4, + D3DXIFF_PPM = 5, + D3DXIFF_DIB = 6, + D3DXIFF_FORCE_DWORD = 0x7fffffff + +} D3DXIMAGE_FILEFORMAT; + + +//---------------------------------------------------------------------------- +// LPD3DXFILL2D and LPD3DXFILL3D: +// ------------------------------ +// Function types used by the texture fill functions. +// +// Parameters: +// pOut +// Pointer to a vector which the function uses to return its result. +// X,Y,Z,W will be mapped to R,G,B,A respectivly. +// pTexCoord +// Pointer to a vector containing the coordinates of the texel currently +// being evaluated. Textures and VolumeTexture texcoord components +// range from 0 to 1. CubeTexture texcoord component range from -1 to 1. +// pTexelSize +// Pointer to a vector containing the dimensions of the current texel. +// pData +// Pointer to user data. +// +//---------------------------------------------------------------------------- + +typedef VOID (*LPD3DXFILL2D)(D3DXVECTOR4 *pOut, D3DXVECTOR2 *pTexCoord, D3DXVECTOR2 *pTexelSize, LPVOID pData); +typedef VOID (*LPD3DXFILL3D)(D3DXVECTOR4 *pOut, D3DXVECTOR3 *pTexCoord, D3DXVECTOR3 *pTexelSize, LPVOID pData); + + + +//---------------------------------------------------------------------------- +// D3DXIMAGE_INFO: +// --------------- +// This structure is used to return a rough description of what the +// the original contents of an image file looked like. +// +// Width +// Width of original image in pixels +// Height +// Height of original image in pixels +// Depth +// Depth of original image in pixels +// MipLevels +// Number of mip levels in original image +// Format +// D3D format which most closely describes the data in original image +// ResourceType +// D3DRESOURCETYPE representing the type of texture stored in the file. +// D3DRTYPE_TEXTURE, D3DRTYPE_VOLUMETEXTURE, or D3DRTYPE_CUBETEXTURE. +// ImageFileFormat +// D3DXIMAGE_FILEFORMAT representing the format of the image file. +// +//---------------------------------------------------------------------------- + +typedef struct _D3DXIMAGE_INFO +{ + UINT Width; + UINT Height; + UINT Depth; + UINT MipLevels; + D3DFORMAT Format; + D3DRESOURCETYPE ResourceType; + D3DXIMAGE_FILEFORMAT ImageFileFormat; + +} D3DXIMAGE_INFO; + + + + + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + + + +////////////////////////////////////////////////////////////////////////////// +// Image File APIs /////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// +; +//---------------------------------------------------------------------------- +// GetImageInfoFromFile/Resource: +// ------------------------------ +// Fills in a D3DXIMAGE_INFO struct with information about an image file. +// +// Parameters: +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXGetImageInfoFromFileA( + LPCSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromFileW( + LPCWSTR pSrcFile, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileW +#else +#define D3DXGetImageInfoFromFile D3DXGetImageInfoFromFileA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromResourceA( + HMODULE hSrcModule, + LPCSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXGetImageInfoFromResourceW( + HMODULE hSrcModule, + LPCWSTR pSrcResource, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceW +#else +#define D3DXGetImageInfoFromResource D3DXGetImageInfoFromResourceA +#endif + + +HRESULT WINAPI + D3DXGetImageInfoFromFileInMemory( + LPCVOID pSrcData, + UINT SrcDataSize, + D3DXIMAGE_INFO* pSrcInfo); + + + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Surface APIs //////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromFile/Resource: +// --------------------------------- +// Load surface from a file or resource +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcRect +// Source rectangle, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromFileA( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromFileW( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCWSTR pSrcFile, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileW +#else +#define D3DXLoadSurfaceFromFile D3DXLoadSurfaceFromFileA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceA( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadSurfaceFromResourceW( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + +#ifdef UNICODE +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceW +#else +#define D3DXLoadSurfaceFromResource D3DXLoadSurfaceFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadSurfaceFromFileInMemory( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromSurface: +// --------------------------- +// Load surface from another surface (with color conversion) +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcSurface +// Source surface +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for entire surface +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromSurface( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPDIRECT3DSURFACE8 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXLoadSurfaceFromMemory: +// -------------------------- +// Load surface from memory. +// +// Parameters: +// pDestSurface +// Destination surface, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestRect +// Destination rectangle, or NULL for entire surface +// pSrcMemory +// Pointer to the top-left corner of the source image in memory +// SrcFormat +// Pixel format of the source image. +// SrcPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the width of one row of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadSurfaceFromMemory( + LPDIRECT3DSURFACE8 pDestSurface, + CONST PALETTEENTRY* pDestPalette, + CONST RECT* pDestRect, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcPitch, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect, + DWORD Filter, + D3DCOLOR ColorKey); + + +//---------------------------------------------------------------------------- +// D3DXSaveSurfaceToFile: +// ---------------------- +// Save a surface to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcSurface +// Source surface, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcRect +// Source rectangle, or NULL for the entire image +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveSurfaceToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE8 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +HRESULT WINAPI + D3DXSaveSurfaceToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DSURFACE8 pSrcSurface, + CONST PALETTEENTRY* pSrcPalette, + CONST RECT* pSrcRect); + +#ifdef UNICODE +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileW +#else +#define D3DXSaveSurfaceToFile D3DXSaveSurfaceToFileA +#endif + + + + +////////////////////////////////////////////////////////////////////////////// +// Load/Save Volume APIs ///////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromFile/Resource: +// -------------------------------- +// Load volume from a file or resource +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcFile +// File name of the source image. +// pSrcModule +// Module where resource is located, or NULL for module associated +// with image the os used to create the current process. +// pSrcResource +// Resource name +// pSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// pSrcBox +// Source box, or NULL for entire image +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromFileA( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromFileW( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCWSTR pSrcFile, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileW +#else +#define D3DXLoadVolumeFromFile D3DXLoadVolumeFromFileA +#endif + + +HRESULT WINAPI + D3DXLoadVolumeFromResourceA( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +HRESULT WINAPI + D3DXLoadVolumeFromResourceW( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + +#ifdef UNICODE +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceW +#else +#define D3DXLoadVolumeFromResource D3DXLoadVolumeFromResourceA +#endif + + + +HRESULT WINAPI + D3DXLoadVolumeFromFileInMemory( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcData, + UINT SrcDataSize, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromVolume: +// ------------------------- +// Load volume from another volume (with color conversion) +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcVolume +// Source volume +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for entire volume +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromVolume( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPDIRECT3DVOLUME8 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXLoadVolumeFromMemory: +// ------------------------- +// Load volume from memory. +// +// Parameters: +// pDestVolume +// Destination volume, which will receive the image. +// pDestPalette +// Destination palette of 256 colors, or NULL +// pDestBox +// Destination box, or NULL for entire volume +// pSrcMemory +// Pointer to the top-left corner of the source volume in memory +// SrcFormat +// Pixel format of the source volume. +// SrcRowPitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one row of cells, in bytes. +// SrcSlicePitch +// Pitch of source image, in bytes. For DXT formats, this number +// should represent the size of one slice of cells, in bytes. +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box. +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXLoadVolumeFromMemory( + LPDIRECT3DVOLUME8 pDestVolume, + CONST PALETTEENTRY* pDestPalette, + CONST D3DBOX* pDestBox, + LPCVOID pSrcMemory, + D3DFORMAT SrcFormat, + UINT SrcRowPitch, + UINT SrcSlicePitch, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox, + DWORD Filter, + D3DCOLOR ColorKey); + + + +//---------------------------------------------------------------------------- +// D3DXSaveVolumeToFile: +// --------------------- +// Save a volume to a image file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcVolume +// Source volume, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// pSrcBox +// Source box, or NULL for the entire volume +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXSaveVolumeToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME8 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +HRESULT WINAPI + D3DXSaveVolumeToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DVOLUME8 pSrcVolume, + CONST PALETTEENTRY* pSrcPalette, + CONST D3DBOX* pSrcBox); + +#ifdef UNICODE +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileW +#else +#define D3DXSaveVolumeToFile D3DXSaveVolumeToFileA +#endif + + + + +////////////////////////////////////////////////////////////////////////////// +// Create/Save Texture APIs ////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXCheckTextureRequirements: +// ----------------------------- +// Checks texture creation parameters. If parameters are invalid, this +// function returns corrected parameters. +// +// Parameters: +// +// pDevice +// The D3D device to be used +// pWidth, pHeight, pDepth, pSize +// Desired size in pixels, or NULL. Returns corrected size. +// pNumMipLevels +// Number of desired mipmap levels, or NULL. Returns corrected number. +// Usage +// Texture usage flags +// pFormat +// Desired pixel format, or NULL. Returns corrected format. +// Pool +// Memory pool to be used to create texture +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCheckTextureRequirements( + LPDIRECT3DDEVICE8 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckCubeTextureRequirements( + LPDIRECT3DDEVICE8 pDevice, + UINT* pSize, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + +HRESULT WINAPI + D3DXCheckVolumeTextureRequirements( + LPDIRECT3DDEVICE8 pDevice, + UINT* pWidth, + UINT* pHeight, + UINT* pDepth, + UINT* pNumMipLevels, + DWORD Usage, + D3DFORMAT* pFormat, + D3DPOOL Pool); + + +//---------------------------------------------------------------------------- +// D3DXCreateTexture: +// ------------------ +// Create an empty texture +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// Width, Height, Depth, Size +// size in pixels; these must be non-zero +// MipLevels +// number of mip levels desired; if zero or D3DX_DEFAULT, a complete +// mipmap chain will be created. +// Usage +// Texture usage flags +// Format +// Pixel format. +// Pool +// Memory pool to be used to create texture +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXCreateTexture( + LPDIRECT3DDEVICE8 pDevice, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTexture( + LPDIRECT3DDEVICE8 pDevice, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTexture( + LPDIRECT3DDEVICE8 pDevice, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXCreateTextureFromFile/Resource: +// ----------------------------------- +// Create a texture object from a file or resource. +// +// Parameters: +// +// pDevice +// The D3D device with which the texture is going to be used. +// pSrcFile +// File name. +// hSrcModule +// Module handle. if NULL, current module will be used. +// pSrcResource +// Resource name in module +// pvSrcData +// Pointer to file in memory. +// SrcDataSize +// Size in bytes of file in memory. +// Width, Height, Depth, Size +// Size in pixels; if zero or D3DX_DEFAULT, the size will be taken +// from the file. +// MipLevels +// Number of mip levels; if zero or D3DX_DEFAULT, a complete mipmap +// chain will be created. +// Usage +// Texture usage flags +// Format +// Desired pixel format. If D3DFMT_UNKNOWN, the format will be +// taken from the file. +// Pool +// Memory pool to be used to create texture +// Filter +// D3DX_FILTER flags controlling how the image is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_TRIANGLE. +// MipFilter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX, +// ColorKey +// Color to replace with transparent black, or 0 to disable colorkey. +// This is always a 32-bit ARGB color, independent of the source image +// format. Alpha is significant, and should usually be set to FF for +// opaque colorkeys. (ex. Opaque black == 0xff000000) +// pSrcInfo +// Pointer to a D3DXIMAGE_INFO structure to be filled in with the +// description of the data in the source image file, or NULL. +// pPalette +// 256 color palette to be filled in, or NULL +// ppTexture, ppCubeTexture, ppVolumeTexture +// The texture object that will be created +// +//---------------------------------------------------------------------------- + + +// FromFile + +HRESULT WINAPI + D3DXCreateTextureFromFileA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DTEXTURE8* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileW +#else +#define D3DXCreateTextureFromFile D3DXCreateTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileW +#else +#define D3DXCreateCubeTextureFromFile D3DXCreateCubeTextureFromFileA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileW +#else +#define D3DXCreateVolumeTextureFromFile D3DXCreateVolumeTextureFromFileA +#endif + + +// FromResource + +HRESULT WINAPI + D3DXCreateTextureFromResourceA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DTEXTURE8* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceW +#else +#define D3DXCreateTextureFromResource D3DXCreateTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceW +#else +#define D3DXCreateCubeTextureFromResource D3DXCreateCubeTextureFromResourceA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceW +#else +#define D3DXCreateVolumeTextureFromResource D3DXCreateVolumeTextureFromResourceA +#endif + + +// FromFileEx + +HRESULT WINAPI + D3DXCreateTextureFromFileExA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromFileExW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE8* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExW +#else +#define D3DXCreateTextureFromFileEx D3DXCreateTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileExW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExW +#else +#define D3DXCreateCubeTextureFromFileEx D3DXCreateCubeTextureFromFileExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExA( + LPDIRECT3DDEVICE8 pDevice, + LPCSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileExW( + LPDIRECT3DDEVICE8 pDevice, + LPCWSTR pSrcFile, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExW +#else +#define D3DXCreateVolumeTextureFromFileEx D3DXCreateVolumeTextureFromFileExA +#endif + + +// FromResourceEx + +HRESULT WINAPI + D3DXCreateTextureFromResourceExA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateTextureFromResourceExW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE8* ppTexture); + +#ifdef UNICODE +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExW +#else +#define D3DXCreateTextureFromResourceEx D3DXCreateTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromResourceExW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +#ifdef UNICODE +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExW +#else +#define D3DXCreateCubeTextureFromResourceEx D3DXCreateCubeTextureFromResourceExA +#endif + + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExA( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromResourceExW( + LPDIRECT3DDEVICE8 pDevice, + HMODULE hSrcModule, + LPCWSTR pSrcResource, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + +#ifdef UNICODE +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExW +#else +#define D3DXCreateVolumeTextureFromResourceEx D3DXCreateVolumeTextureFromResourceExA +#endif + + +// FromFileInMemory + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemory( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemory( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemory( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + + +// FromFileInMemoryEx + +HRESULT WINAPI + D3DXCreateTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DTEXTURE8* ppTexture); + +HRESULT WINAPI + D3DXCreateCubeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Size, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DCUBETEXTURE8* ppCubeTexture); + +HRESULT WINAPI + D3DXCreateVolumeTextureFromFileInMemoryEx( + LPDIRECT3DDEVICE8 pDevice, + LPCVOID pSrcData, + UINT SrcDataSize, + UINT Width, + UINT Height, + UINT Depth, + UINT MipLevels, + DWORD Usage, + D3DFORMAT Format, + D3DPOOL Pool, + DWORD Filter, + DWORD MipFilter, + D3DCOLOR ColorKey, + D3DXIMAGE_INFO* pSrcInfo, + PALETTEENTRY* pPalette, + LPDIRECT3DVOLUMETEXTURE8* ppVolumeTexture); + + + +//---------------------------------------------------------------------------- +// D3DXSaveTextureToFile: +// ---------------------- +// Save a texture to a file. +// +// Parameters: +// pDestFile +// File name of the destination file +// DestFormat +// D3DXIMAGE_FILEFORMAT specifying file format to use when saving. +// pSrcTexture +// Source texture, containing the image to be saved +// pSrcPalette +// Source palette of 256 colors, or NULL +// +//---------------------------------------------------------------------------- + + +HRESULT WINAPI + D3DXSaveTextureToFileA( + LPCSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE8 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +HRESULT WINAPI + D3DXSaveTextureToFileW( + LPCWSTR pDestFile, + D3DXIMAGE_FILEFORMAT DestFormat, + LPDIRECT3DBASETEXTURE8 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette); + +#ifdef UNICODE +#define D3DXSaveTextureToFile D3DXSaveTextureToFileW +#else +#define D3DXSaveTextureToFile D3DXSaveTextureToFileA +#endif + + + + +////////////////////////////////////////////////////////////////////////////// +// Misc Texture APIs ///////////////////////////////////////////////////////// +////////////////////////////////////////////////////////////////////////////// + +//---------------------------------------------------------------------------- +// D3DXFilterTexture: +// ------------------ +// Filters mipmaps levels of a texture. +// +// Parameters: +// pBaseTexture +// The texture object to be filtered +// pPalette +// 256 color palette to be used, or NULL for non-palettized formats +// SrcLevel +// The level whose image is used to generate the subsequent levels. +// Filter +// D3DX_FILTER flags controlling how each miplevel is filtered. +// Or D3DX_DEFAULT for D3DX_FILTER_BOX, +// +//---------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFilterTexture( + LPDIRECT3DBASETEXTURE8 pBaseTexture, + CONST PALETTEENTRY* pPalette, + UINT SrcLevel, + DWORD Filter); + +#define D3DXFilterCubeTexture D3DXFilterTexture +#define D3DXFilterVolumeTexture D3DXFilterTexture + + + +//---------------------------------------------------------------------------- +// D3DXFillTexture: +// ---------------- +// Uses a user provided function to fill each texel of each mip level of a +// given texture. +// +// Paramters: +// pTexture, pCubeTexture, pVolumeTexture +// Pointer to the texture to be filled. +// pFunction +// Pointer to user provided evalutor function which will be used to +// compute the value of each texel. +// pData +// Pointer to an arbitrary block of user defined data. This pointer +// will be passed to the function provided in pFunction +//----------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXFillTexture( + LPDIRECT3DTEXTURE8 pTexture, + LPD3DXFILL2D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillCubeTexture( + LPDIRECT3DCUBETEXTURE8 pCubeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + +HRESULT WINAPI + D3DXFillVolumeTexture( + LPDIRECT3DVOLUMETEXTURE8 pVolumeTexture, + LPD3DXFILL3D pFunction, + LPVOID pData); + + + +//---------------------------------------------------------------------------- +// D3DXComputeNormalMap: +// --------------------- +// Converts a height map into a normal map. The (x,y,z) components of each +// normal are mapped to the (r,g,b) channels of the output texture. +// +// Parameters +// pTexture +// Pointer to the destination texture +// pSrcTexture +// Pointer to the source heightmap texture +// pSrcPalette +// Source palette of 256 colors, or NULL +// Flags +// D3DX_NORMALMAP flags +// Channel +// D3DX_CHANNEL specifying source of height information +// Amplitude +// The constant value which the height information is multiplied by. +//--------------------------------------------------------------------------- + +HRESULT WINAPI + D3DXComputeNormalMap( + LPDIRECT3DTEXTURE8 pTexture, + LPDIRECT3DTEXTURE8 pSrcTexture, + CONST PALETTEENTRY* pSrcPalette, + DWORD Flags, + DWORD Channel, + FLOAT Amplitude); + + + + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif //__D3DX8TEX_H__ diff --git a/gfx/include/d3d9/d3dx9anim.h b/gfx/include/d3d9/d3dx9anim.h index ecdabdc52c..0d0a945344 100644 --- a/gfx/include/d3d9/d3dx9anim.h +++ b/gfx/include/d3d9/d3dx9anim.h @@ -10,19 +10,19 @@ #define __D3DX9ANIM_H__ /* {698CFB3F-9289-4d95-9A57-33A94B5A65F9} */ -DEFINE_GUID(IID_ID3DXAnimationSet, +DEFINE_GUID(IID_ID3DXAnimationSet, 0x698cfb3f, 0x9289, 0x4d95, 0x9a, 0x57, 0x33, 0xa9, 0x4b, 0x5a, 0x65, 0xf9); /* {FA4E8E3A-9786-407d-8B4C-5995893764AF} */ -DEFINE_GUID(IID_ID3DXKeyframedAnimationSet, +DEFINE_GUID(IID_ID3DXKeyframedAnimationSet, 0xfa4e8e3a, 0x9786, 0x407d, 0x8b, 0x4c, 0x59, 0x95, 0x89, 0x37, 0x64, 0xaf); /* {6CC2480D-3808-4739-9F88-DE49FACD8D4C} */ -DEFINE_GUID(IID_ID3DXCompressedAnimationSet, +DEFINE_GUID(IID_ID3DXCompressedAnimationSet, 0x6cc2480d, 0x3808, 0x4739, 0x9f, 0x88, 0xde, 0x49, 0xfa, 0xcd, 0x8d, 0x4c); /* {AC8948EC-F86D-43e2-96DE-31FC35F96D9E} */ -DEFINE_GUID(IID_ID3DXAnimationController, +DEFINE_GUID(IID_ID3DXAnimationController, 0xac8948ec, 0xf86d, 0x43e2, 0x96, 0xde, 0x31, 0xfc, 0x35, 0xf9, 0x6d, 0x9e); typedef enum _D3DXMESHDATATYPE @@ -82,22 +82,22 @@ typedef interface ID3DXAllocateHierarchy *LPD3DXALLOCATEHIERARCHY; DECLARE_INTERFACE(ID3DXAllocateHierarchy) { - STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, + STDMETHOD(CreateFrame)(THIS_ LPCSTR Name, LPD3DXFRAME *ppNewFrame) PURE; - STDMETHOD(CreateMeshContainer)(THIS_ - LPCSTR Name, - CONST D3DXMESHDATA *pMeshData, - CONST D3DXMATERIAL *pMaterials, - CONST D3DXEFFECTINSTANCE *pEffectInstances, - DWORD NumMaterials, - CONST DWORD *pAdjacency, - LPD3DXSKININFO pSkinInfo, + STDMETHOD(CreateMeshContainer)(THIS_ + LPCSTR Name, + CONST D3DXMESHDATA *pMeshData, + CONST D3DXMATERIAL *pMaterials, + CONST D3DXEFFECTINSTANCE *pEffectInstances, + DWORD NumMaterials, + CONST DWORD *pAdjacency, + LPD3DXSKININFO pSkinInfo, LPD3DXMESHCONTAINER *ppNewMeshContainer) PURE; - STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree) PURE; + STDMETHOD(DestroyFrame)(THIS_ LPD3DXFRAME pFrameToFree) PURE; - STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree) PURE; + STDMETHOD(DestroyMeshContainer)(THIS_ LPD3DXMESHCONTAINER pMeshContainerToFree) PURE; }; typedef interface ID3DXLoadUserData ID3DXLoadUserData; @@ -109,12 +109,12 @@ typedef interface ID3DXLoadUserData *LPD3DXLOADUSERDATA; DECLARE_INTERFACE(ID3DXLoadUserData) { STDMETHOD(LoadTopLevelData)(LPD3DXFILEDATA pXofChildData) PURE; - - STDMETHOD(LoadFrameChildData)(LPD3DXFRAME pFrame, + + STDMETHOD(LoadFrameChildData)(LPD3DXFRAME pFrame, + LPD3DXFILEDATA pXofChildData) PURE; + + STDMETHOD(LoadMeshChildData)(LPD3DXMESHCONTAINER pMeshContainer, LPD3DXFILEDATA pXofChildData) PURE; - - STDMETHOD(LoadMeshChildData)(LPD3DXMESHCONTAINER pMeshContainer, - LPD3DXFILEDATA pXofChildData) PURE; }; typedef interface ID3DXSaveUserData ID3DXSaveUserData; @@ -125,22 +125,22 @@ typedef interface ID3DXSaveUserData *LPD3DXSAVEUSERDATA; DECLARE_INTERFACE(ID3DXSaveUserData) { - STDMETHOD(AddFrameChildData)(CONST D3DXFRAME *pFrame, - LPD3DXFILESAVEOBJECT pXofSave, + STDMETHOD(AddFrameChildData)(CONST D3DXFRAME *pFrame, + LPD3DXFILESAVEOBJECT pXofSave, LPD3DXFILESAVEDATA pXofFrameData) PURE; - - STDMETHOD(AddMeshChildData)(CONST D3DXMESHCONTAINER *pMeshContainer, - LPD3DXFILESAVEOBJECT pXofSave, + + STDMETHOD(AddMeshChildData)(CONST D3DXMESHCONTAINER *pMeshContainer, + LPD3DXFILESAVEOBJECT pXofSave, LPD3DXFILESAVEDATA pXofMeshData) PURE; - - /* NOTE: this is called once per Save. All top level objects should be added using the + + /* NOTE: this is called once per Save. All top level objects should be added using the * provided interface. One call adds objects before the frame hierarchy, the other after */ - STDMETHOD(AddTopLevelDataObjectsPre)(LPD3DXFILESAVEOBJECT pXofSave) PURE; - STDMETHOD(AddTopLevelDataObjectsPost)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + STDMETHOD(AddTopLevelDataObjectsPre)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + STDMETHOD(AddTopLevelDataObjectsPost)(LPD3DXFILESAVEOBJECT pXofSave) PURE; /* callbacks for the user to register and then save templates to the XFile */ - STDMETHOD(RegisterTemplates)(LPD3DXFILE pXFileApi) PURE; - STDMETHOD(SaveTemplates)(LPD3DXFILESAVEOBJECT pXofSave) PURE; + STDMETHOD(RegisterTemplates)(LPD3DXFILE pXFileApi) PURE; + STDMETHOD(SaveTemplates)(LPD3DXFILESAVEOBJECT pXofSave) PURE; }; typedef enum _D3DXCALLBACK_SEARCH_FLAGS @@ -177,7 +177,7 @@ DECLARE_INTERFACE_(ID3DXAnimationSet, IUnknown) STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; /* SRT */ - STDMETHOD(GetSRT)(THIS_ + STDMETHOD(GetSRT)(THIS_ DOUBLE PeriodicPosition, /* Position mapped to period (use GetPeriodicPosition) */ UINT Animation, /* Animation index */ D3DXVECTOR3 *pScale, /* Returns the scale */ @@ -185,7 +185,7 @@ DECLARE_INTERFACE_(ID3DXAnimationSet, IUnknown) D3DXVECTOR3 *pTranslation) PURE; /* Returns the translation */ /* Callbacks */ - STDMETHOD(GetCallback)(THIS_ + STDMETHOD(GetCallback)(THIS_ DOUBLE Position, /* Position from which to find callbacks */ DWORD Flags, /* Callback search flags */ DOUBLE *pCallbackPosition, /* Returns the position of the callback */ @@ -252,7 +252,7 @@ DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; /* SRT */ - STDMETHOD(GetSRT)(THIS_ + STDMETHOD(GetSRT)(THIS_ DOUBLE PeriodicPosition, /* Position mapped to period (use GetPeriodicPosition) */ UINT Animation, /* Animation index */ D3DXVECTOR3 *pScale, /* Returns the scale */ @@ -260,7 +260,7 @@ DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) D3DXVECTOR3 *pTranslation) PURE; /* Returns the translation */ /* Callbacks */ - STDMETHOD(GetCallback)(THIS_ + STDMETHOD(GetCallback)(THIS_ DOUBLE Position, /* Position from which to find callbacks */ DWORD Flags, /* Callback search flags */ DOUBLE *pCallbackPosition, /* Returns the position of the callback */ @@ -300,7 +300,7 @@ DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) STDMETHOD(UnregisterTranslationKey)(THIS_ UINT Animation, UINT Key) PURE; /* One-time animaton SRT keyframe registration */ - STDMETHOD(RegisterAnimationSRTKeys)(THIS_ + STDMETHOD(RegisterAnimationSRTKeys)(THIS_ LPCSTR pName, /* Animation name */ UINT NumScaleKeys, /* Number of scale keys */ UINT NumRotationKeys, /* Number of rotation keys */ @@ -311,7 +311,7 @@ DECLARE_INTERFACE_(ID3DXKeyframedAnimationSet, ID3DXAnimationSet) DWORD *pAnimationIndex) PURE; /* Returns the animation index */ /* Compression */ - STDMETHOD(Compress)(THIS_ + STDMETHOD(Compress)(THIS_ DWORD Flags, /* Compression flags (use D3DXCOMPRESS_STRONG for better results) */ FLOAT Lossiness, /* Compression loss ratio in the [0, 1] range */ LPD3DXFRAME pHierarchy, /* Frame hierarchy (optional) */ @@ -352,7 +352,7 @@ DECLARE_INTERFACE_(ID3DXCompressedAnimationSet, ID3DXAnimationSet) STDMETHOD(GetAnimationIndexByName)(THIS_ LPCSTR pName, UINT *pIndex) PURE; /* SRT */ - STDMETHOD(GetSRT)(THIS_ + STDMETHOD(GetSRT)(THIS_ DOUBLE PeriodicPosition, /* Position mapped to period (use GetPeriodicPosition) */ UINT Animation, /* Animation index */ D3DXVECTOR3 *pScale, /* Returns the scale */ @@ -360,7 +360,7 @@ DECLARE_INTERFACE_(ID3DXCompressedAnimationSet, ID3DXAnimationSet) D3DXVECTOR3 *pTranslation) PURE; /* Returns the translation */ /* Callbacks */ - STDMETHOD(GetCallback)(THIS_ + STDMETHOD(GetCallback)(THIS_ DOUBLE Position, /* Position from which to find callbacks */ DWORD Flags, /* Callback search flags */ DOUBLE *pCallbackPosition, /* Returns the position of the callback */ @@ -441,7 +441,7 @@ typedef interface ID3DXAnimationCallbackHandler *LPD3DXANIMATIONCALLBACKHANDLER; DECLARE_INTERFACE(ID3DXAnimationCallbackHandler) { - STDMETHOD(HandleCallback)(THIS_ UINT Track, LPVOID pCallbackData) PURE; + STDMETHOD(HandleCallback)(THIS_ UINT Track, LPVOID pCallbackData) PURE; }; typedef interface ID3DXAnimationController ID3DXAnimationController; @@ -464,11 +464,11 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) STDMETHOD_(UINT, GetMaxNumEvents)(THIS) PURE; /* Animation output registration */ - STDMETHOD(RegisterAnimationOutput)(THIS_ - LPCSTR pName, - D3DXMATRIX *pMatrix, - D3DXVECTOR3 *pScale, - D3DXQUATERNION *pRotation, + STDMETHOD(RegisterAnimationOutput)(THIS_ + LPCSTR pName, + D3DXMATRIX *pMatrix, + D3DXVECTOR3 *pScale, + D3DXQUATERNION *pRotation, D3DXVECTOR3 *pTranslation) PURE; /* Animation set registration */ @@ -528,11 +528,11 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) STDMETHOD(GetEventDesc)(THIS_ D3DXEVENTHANDLE hEvent, LPD3DXEVENT_DESC pDesc) PURE; /* Cloning */ - STDMETHOD(CloneAnimationController)(THIS_ - UINT MaxNumAnimationOutputs, - UINT MaxNumAnimationSets, - UINT MaxNumTracks, - UINT MaxNumEvents, + STDMETHOD(CloneAnimationController)(THIS_ + UINT MaxNumAnimationOutputs, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, LPD3DXANIMATIONCONTROLLER *ppAnimController) PURE; }; @@ -540,26 +540,26 @@ DECLARE_INTERFACE_(ID3DXAnimationController, IUnknown) extern "C" { #endif /* __cplusplus */ -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshHierarchyFromXA ( LPCSTR Filename, DWORD MeshOptions, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXALLOCATEHIERARCHY pAlloc, - LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXLOADUSERDATA pUserDataLoader, LPD3DXFRAME *ppFrameHierarchy, LPD3DXANIMATIONCONTROLLER *ppAnimController ); -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshHierarchyFromXW ( LPCWSTR Filename, DWORD MeshOptions, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXALLOCATEHIERARCHY pAlloc, - LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXLOADUSERDATA pUserDataLoader, LPD3DXFRAME *ppFrameHierarchy, LPD3DXANIMATIONCONTROLLER *ppAnimController ); @@ -570,7 +570,7 @@ D3DXLoadMeshHierarchyFromXW #define D3DXLoadMeshHierarchyFromX D3DXLoadMeshHierarchyFromXA #endif -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshHierarchyFromXInMemory ( LPCVOID Memory, @@ -578,27 +578,27 @@ D3DXLoadMeshHierarchyFromXInMemory DWORD MeshOptions, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXALLOCATEHIERARCHY pAlloc, - LPD3DXLOADUSERDATA pUserDataLoader, + LPD3DXLOADUSERDATA pUserDataLoader, LPD3DXFRAME *ppFrameHierarchy, LPD3DXANIMATIONCONTROLLER *ppAnimController ); -HRESULT WINAPI +HRESULT WINAPI D3DXSaveMeshHierarchyToFileA ( LPCSTR Filename, DWORD XFormat, - CONST D3DXFRAME *pFrameRoot, + CONST D3DXFRAME *pFrameRoot, LPD3DXANIMATIONCONTROLLER pAnimcontroller, LPD3DXSAVEUSERDATA pUserDataSaver ); -HRESULT WINAPI +HRESULT WINAPI D3DXSaveMeshHierarchyToFileW ( LPCWSTR Filename, DWORD XFormat, - CONST D3DXFRAME *pFrameRoot, + CONST D3DXFRAME *pFrameRoot, LPD3DXANIMATIONCONTROLLER pAnimController, LPD3DXSAVEUSERDATA pUserDataSaver ); @@ -616,14 +616,14 @@ D3DXFrameDestroy LPD3DXALLOCATEHIERARCHY pAlloc ); -HRESULT WINAPI +HRESULT WINAPI D3DXFrameAppendChild ( LPD3DXFRAME pFrameParent, CONST D3DXFRAME *pFrameChild ); -LPD3DXFRAME WINAPI +LPD3DXFRAME WINAPI D3DXFrameFind ( CONST D3DXFRAME *pFrameRoot, @@ -640,7 +640,7 @@ D3DXFrameRegisterNamedMatrices /* * D3DXFrameNumNamedMatrices: * -------------------------- - * Counts number of frames in a subtree that have non-null names + * Counts number of frames in a subtree that have non-null names * * Parameters: * pFrameRoot @@ -672,9 +672,9 @@ D3DXFrameNumNamedMatrices HRESULT WINAPI D3DXFrameCalculateBoundingSphere ( - CONST D3DXFRAME *pFrameRoot, - LPD3DXVECTOR3 pObjectCenter, - FLOAT *pObjectRadius + CONST D3DXFRAME *pFrameRoot, + LPD3DXVECTOR3 pObjectCenter, + FLOAT *pObjectRadius ); @@ -682,7 +682,7 @@ D3DXFrameCalculateBoundingSphere * D3DXCreateKeyframedAnimationSet: * -------------------------------- * This function creates a compressable keyframed animations set interface. - * + * * Parameters: * pName * Name of the animation set @@ -698,28 +698,28 @@ D3DXFrameCalculateBoundingSphere * Array of callback keys * ppAnimationSet * Returns the animation set interface - * + * */ HRESULT WINAPI D3DXCreateKeyframedAnimationSet ( - LPCSTR pName, + LPCSTR pName, DOUBLE TicksPerSecond, D3DXPLAYBACK_TYPE Playback, - UINT NumAnimations, - UINT NumCallbackKeys, - CONST D3DXKEY_CALLBACK *pCallbackKeys, - LPD3DXKEYFRAMEDANIMATIONSET *ppAnimationSet + UINT NumAnimations, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXKEYFRAMEDANIMATIONSET *ppAnimationSet ); /* * D3DXCreateCompressedAnimationSet: * -------------------------------- - * This function creates a compressed animations set interface from + * This function creates a compressed animations set interface from * compressed data. - * + * * Parameters: * pName * Name of the animation set @@ -735,28 +735,28 @@ D3DXCreateKeyframedAnimationSet * Array of callback keys * ppAnimationSet * Returns the animation set interface - * + * */ HRESULT WINAPI D3DXCreateCompressedAnimationSet ( - LPCSTR pName, + LPCSTR pName, DOUBLE TicksPerSecond, D3DXPLAYBACK_TYPE Playback, - LPD3DXBUFFER pCompressedData, - UINT NumCallbackKeys, - CONST D3DXKEY_CALLBACK *pCallbackKeys, - LPD3DXCOMPRESSEDANIMATIONSET *ppAnimationSet + LPD3DXBUFFER pCompressedData, + UINT NumCallbackKeys, + CONST D3DXKEY_CALLBACK *pCallbackKeys, + LPD3DXCOMPRESSEDANIMATIONSET *ppAnimationSet ); HRESULT WINAPI D3DXCreateAnimationController ( - UINT MaxNumMatrices, - UINT MaxNumAnimationSets, - UINT MaxNumTracks, - UINT MaxNumEvents, + UINT MaxNumMatrices, + UINT MaxNumAnimationSets, + UINT MaxNumTracks, + UINT MaxNumEvents, LPD3DXANIMATIONCONTROLLER *ppAnimController ); diff --git a/gfx/include/d3d9/d3dx9core.h b/gfx/include/d3d9/d3dx9core.h index c3df8ce5c3..e3e10bd37e 100644 --- a/gfx/include/d3d9/d3dx9core.h +++ b/gfx/include/d3d9/d3dx9core.h @@ -24,7 +24,7 @@ BOOL WINAPI D3DXCheckVersion(UINT D3DSdkVersion, UINT D3DXSdkVersion); BOOL WINAPI - D3DXDebugMute(BOOL Mute); + D3DXDebugMute(BOOL Mute); UINT WINAPI D3DXGetDriverLevel(LPDIRECT3DDEVICE9 pDevice); @@ -37,7 +37,7 @@ typedef interface ID3DXBuffer ID3DXBuffer; typedef interface ID3DXBuffer *LPD3DXBUFFER; // {8BA5FB08-5195-40e2-AC58-0D989C3A0102} -DEFINE_GUID(IID_ID3DXBuffer, +DEFINE_GUID(IID_ID3DXBuffer, 0x8ba5fb08, 0x5195, 0x40e2, 0xac, 0x58, 0xd, 0x98, 0x9c, 0x3a, 0x1, 0x2); #undef INTERFACE @@ -70,7 +70,7 @@ typedef interface ID3DXSprite *LPD3DXSPRITE; // {BA0B762D-7D28-43ec-B9DC-2F84443B0614} -DEFINE_GUID(IID_ID3DXSprite, +DEFINE_GUID(IID_ID3DXSprite, 0xba0b762d, 0x7d28, 0x43ec, 0xb9, 0xdc, 0x2f, 0x84, 0x44, 0x3b, 0x6, 0x14); @@ -107,9 +107,9 @@ DECLARE_INTERFACE_(ID3DXSprite, IUnknown) extern "C" { #endif //__cplusplus -HRESULT WINAPI - D3DXCreateSprite( - LPDIRECT3DDEVICE9 pDevice, +HRESULT WINAPI + D3DXCreateSprite( + LPDIRECT3DDEVICE9 pDevice, LPD3DXSPRITE* ppSprite); #ifdef __cplusplus @@ -160,7 +160,7 @@ typedef interface ID3DXFont *LPD3DXFONT; // {D79DBB70-5F21-4d36-BBC2-FF525C213CDC} -DEFINE_GUID(IID_ID3DXFont, +DEFINE_GUID(IID_ID3DXFont, 0xd79dbb70, 0x5f21, 0x4d36, 0xbb, 0xc2, 0xff, 0x52, 0x5c, 0x21, 0x3c, 0xdc); @@ -228,9 +228,9 @@ extern "C" { #endif //__cplusplus -HRESULT WINAPI +HRESULT WINAPI D3DXCreateFontA( - LPDIRECT3DDEVICE9 pDevice, + LPDIRECT3DDEVICE9 pDevice, INT Height, UINT Width, UINT Weight, @@ -243,9 +243,9 @@ HRESULT WINAPI LPCSTR pFaceName, LPD3DXFONT* ppFont); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateFontW( - LPDIRECT3DDEVICE9 pDevice, + LPDIRECT3DDEVICE9 pDevice, INT Height, UINT Width, UINT Weight, @@ -265,16 +265,16 @@ HRESULT WINAPI #endif -HRESULT WINAPI - D3DXCreateFontIndirectA( - LPDIRECT3DDEVICE9 pDevice, - CONST D3DXFONT_DESCA* pDesc, +HRESULT WINAPI + D3DXCreateFontIndirectA( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCA* pDesc, LPD3DXFONT* ppFont); -HRESULT WINAPI - D3DXCreateFontIndirectW( - LPDIRECT3DDEVICE9 pDevice, - CONST D3DXFONT_DESCW* pDesc, +HRESULT WINAPI + D3DXCreateFontIndirectW( + LPDIRECT3DDEVICE9 pDevice, + CONST D3DXFONT_DESCW* pDesc, LPD3DXFONT* ppFont); #ifdef UNICODE @@ -304,7 +304,7 @@ typedef interface ID3DXRenderToSurface *LPD3DXRENDERTOSURFACE; // {6985F346-2C3D-43b3-BE8B-DAAE8A03D894} -DEFINE_GUID(IID_ID3DXRenderToSurface, +DEFINE_GUID(IID_ID3DXRenderToSurface, 0x6985f346, 0x2c3d, 0x43b3, 0xbe, 0x8b, 0xda, 0xae, 0x8a, 0x3, 0xd8, 0x94); @@ -364,7 +364,7 @@ typedef interface ID3DXRenderToEnvMap *LPD3DXRenderToEnvMap; // {313F1B4B-C7B0-4fa2-9D9D-8D380B64385E} -DEFINE_GUID(IID_ID3DXRenderToEnvMap, +DEFINE_GUID(IID_ID3DXRenderToEnvMap, 0x313f1b4b, 0xc7b0, 0x4fa2, 0x9d, 0x9d, 0x8d, 0x38, 0xb, 0x64, 0x38, 0x5e); @@ -382,17 +382,17 @@ DECLARE_INTERFACE_(ID3DXRenderToEnvMap, IUnknown) STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; STDMETHOD(GetDesc)(THIS_ D3DXRTE_DESC* pDesc) PURE; - STDMETHOD(BeginCube)(THIS_ + STDMETHOD(BeginCube)(THIS_ LPDIRECT3DCUBETEXTURE9 pCubeTex) PURE; STDMETHOD(BeginSphere)(THIS_ LPDIRECT3DTEXTURE9 pTex) PURE; - STDMETHOD(BeginHemisphere)(THIS_ + STDMETHOD(BeginHemisphere)(THIS_ LPDIRECT3DTEXTURE9 pTexZPos, LPDIRECT3DTEXTURE9 pTexZNeg) PURE; - STDMETHOD(BeginParabolic)(THIS_ + STDMETHOD(BeginParabolic)(THIS_ LPDIRECT3DTEXTURE9 pTexZPos, LPDIRECT3DTEXTURE9 pTexZNeg) PURE; @@ -427,7 +427,7 @@ typedef interface ID3DXLine *LPD3DXLINE; // {D379BA7F-9042-4ac4-9F5E-58192A4C6BD8} -DEFINE_GUID(IID_ID3DXLine, +DEFINE_GUID(IID_ID3DXLine, 0xd379ba7f, 0x9042, 0x4ac4, 0x9f, 0x5e, 0x58, 0x19, 0x2a, 0x4c, 0x6b, 0xd8); #undef INTERFACE @@ -449,7 +449,7 @@ DECLARE_INTERFACE_(ID3DXLine, IUnknown) DWORD dwVertexListCount, D3DCOLOR Color) PURE; STDMETHOD(DrawTransform)(THIS_ CONST D3DXVECTOR3 *pVertexList, - DWORD dwVertexListCount, CONST D3DXMATRIX* pTransform, + DWORD dwVertexListCount, CONST D3DXMATRIX* pTransform, D3DCOLOR Color) PURE; STDMETHOD(SetPattern)(THIS_ DWORD dwPattern) PURE; diff --git a/gfx/include/d3d9/d3dx9effect.h b/gfx/include/d3d9/d3dx9effect.h index 4fbb3f75aa..3947c7a91b 100644 --- a/gfx/include/d3d9/d3dx9effect.h +++ b/gfx/include/d3d9/d3dx9effect.h @@ -108,7 +108,7 @@ typedef interface ID3DXEffectPool ID3DXEffectPool; typedef interface ID3DXEffectPool *LPD3DXEFFECTPOOL; // {9537AB04-3250-412e-8213-FCD2F8677933} -DEFINE_GUID(IID_ID3DXEffectPool, +DEFINE_GUID(IID_ID3DXEffectPool, 0x9537ab04, 0x3250, 0x412e, 0x82, 0x13, 0xfc, 0xd2, 0xf8, 0x67, 0x79, 0x33); @@ -134,7 +134,7 @@ typedef interface ID3DXBaseEffect ID3DXBaseEffect; typedef interface ID3DXBaseEffect *LPD3DXBASEEFFECT; // {017C18AC-103F-4417-8C51-6BF6EF1E56BE} -DEFINE_GUID(IID_ID3DXBaseEffect, +DEFINE_GUID(IID_ID3DXBaseEffect, 0x17c18ac, 0x103f, 0x4417, 0x8c, 0x51, 0x6b, 0xf6, 0xef, 0x1e, 0x56, 0xbe); @@ -209,7 +209,7 @@ DECLARE_INTERFACE_(ID3DXBaseEffect, IUnknown) //Set Range of an Array to pass to device //Useful for sending only a subrange of an array down to the device - STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; }; @@ -217,7 +217,7 @@ DECLARE_INTERFACE_(ID3DXBaseEffect, IUnknown) //---------------------------------------------------------------------------- // ID3DXEffectStateManager: // ------------------------ -// This is a user implemented interface that can be used to manage device +// This is a user implemented interface that can be used to manage device // state changes made by an Effect. //---------------------------------------------------------------------------- @@ -225,7 +225,7 @@ typedef interface ID3DXEffectStateManager ID3DXEffectStateManager; typedef interface ID3DXEffectStateManager *LPD3DXEFFECTSTATEMANAGER; // {79AAB587-6DBC-4fa7-82DE-37FA1781C5CE} -DEFINE_GUID(IID_ID3DXEffectStateManager, +DEFINE_GUID(IID_ID3DXEffectStateManager, 0x79aab587, 0x6dbc, 0x4fa7, 0x82, 0xde, 0x37, 0xfa, 0x17, 0x81, 0xc5, 0xce); #undef INTERFACE @@ -240,11 +240,11 @@ DECLARE_INTERFACE_(ID3DXEffectStateManager, IUnknown) STDMETHOD_(ULONG, AddRef)(THIS) PURE; STDMETHOD_(ULONG, Release)(THIS) PURE; - // The following methods are called by the Effect when it wants to make + // The following methods are called by the Effect when it wants to make // the corresponding device call. Note that: - // 1. Users manage the state and are therefore responsible for making the - // the corresponding device calls themselves inside their callbacks. - // 2. Effects pay attention to the return values of the callbacks, and so + // 1. Users manage the state and are therefore responsible for making the + // the corresponding device calls themselves inside their callbacks. + // 2. Effects pay attention to the return values of the callbacks, and so // users must pay attention to what they return in their callbacks. STDMETHOD(SetTransform)(THIS_ D3DTRANSFORMSTATETYPE State, CONST D3DMATRIX *pMatrix) PURE; @@ -276,7 +276,7 @@ typedef interface ID3DXEffect ID3DXEffect; typedef interface ID3DXEffect *LPD3DXEFFECT; // {F6CEB4B3-4E4C-40dd-B883-8D8DE5EA0CD5} -DEFINE_GUID(IID_ID3DXEffect, +DEFINE_GUID(IID_ID3DXEffect, 0xf6ceb4b3, 0x4e4c, 0x40dd, 0xb8, 0x83, 0x8d, 0x8d, 0xe5, 0xea, 0xc, 0xd5); #undef INTERFACE @@ -350,10 +350,10 @@ DECLARE_INTERFACE_(ID3DXEffect, ID3DXBaseEffect) //Set Range of an Array to pass to device //Usefull for sending only a subrange of an array down to the device - STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; // ID3DXBaseEffect - - + + // Pool STDMETHOD(GetPool)(THIS_ LPD3DXEFFECTPOOL* ppPool) PURE; @@ -394,7 +394,7 @@ DECLARE_INTERFACE_(ID3DXEffect, ID3DXBaseEffect) // Cloning STDMETHOD(CloneEffect)(THIS_ LPDIRECT3DDEVICE9 pDevice, LPD3DXEFFECT* ppEffect) PURE; - + // Fast path for setting variables directly in ID3DXEffect STDMETHOD(SetRawValue)(THIS_ D3DXHANDLE hParameter, LPCVOID pData, UINT ByteOffset, UINT Bytes) PURE; }; @@ -407,7 +407,7 @@ typedef interface ID3DXEffectCompiler ID3DXEffectCompiler; typedef interface ID3DXEffectCompiler *LPD3DXEFFECTCOMPILER; // {51B8A949-1A31-47e6-BEA0-4B30DB53F1E0} -DEFINE_GUID(IID_ID3DXEffectCompiler, +DEFINE_GUID(IID_ID3DXEffectCompiler, 0x51b8a949, 0x1a31, 0x47e6, 0xbe, 0xa0, 0x4b, 0x30, 0xdb, 0x53, 0xf1, 0xe0); @@ -479,10 +479,10 @@ DECLARE_INTERFACE_(ID3DXEffectCompiler, ID3DXBaseEffect) STDMETHOD(GetTexture)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DBASETEXTURE9 *ppTexture) PURE; STDMETHOD(GetPixelShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DPIXELSHADER9 *ppPShader) PURE; STDMETHOD(GetVertexShader)(THIS_ D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9 *ppVShader) PURE; - + //Set Range of an Array to pass to device //Usefull for sending only a subrange of an array down to the device - STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; + STDMETHOD(SetArrayRange)(THIS_ D3DXHANDLE hParameter, UINT uStart, UINT uEnd) PURE; // ID3DXBaseEffect // Parameter sharing, specialization, and information @@ -588,7 +588,7 @@ HRESULT WINAPI LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - LPCSTR pSkipConstants, + LPCSTR pSkipConstants, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, @@ -600,7 +600,7 @@ HRESULT WINAPI LPCWSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - LPCSTR pSkipConstants, + LPCSTR pSkipConstants, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, @@ -620,7 +620,7 @@ HRESULT WINAPI LPCSTR pSrcResource, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - LPCSTR pSkipConstants, + LPCSTR pSkipConstants, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, @@ -633,7 +633,7 @@ HRESULT WINAPI LPCWSTR pSrcResource, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - LPCSTR pSkipConstants, + LPCSTR pSkipConstants, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, @@ -653,7 +653,7 @@ HRESULT WINAPI UINT SrcDataLen, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, - LPCSTR pSkipConstants, + LPCSTR pSkipConstants, DWORD Flags, LPD3DXEFFECTPOOL pPool, LPD3DXEFFECT* ppEffect, @@ -721,10 +721,10 @@ HRESULT WINAPI LPD3DXEFFECTCOMPILER* ppCompiler, LPD3DXBUFFER* ppParseErrors); -HRESULT WINAPI +HRESULT WINAPI D3DXDisassembleEffect( - LPD3DXEFFECT pEffect, - BOOL EnableColorCode, + LPD3DXEFFECT pEffect, + BOOL EnableColorCode, LPD3DXBUFFER *ppDisassembly); #ifdef __cplusplus diff --git a/gfx/include/d3d9/d3dx9math.h b/gfx/include/d3d9/d3dx9math.h index 165014b0df..f861629e0d 100644 --- a/gfx/include/d3d9/d3dx9math.h +++ b/gfx/include/d3d9/d3dx9math.h @@ -362,7 +362,7 @@ typedef struct _D3DMATRIX D3DXMATRIX, *LPD3DXMATRIX; * This class helps keep matrices 16-byte aligned as preferred by P4 cpus. * It aligns matrices on the stack and on the heap or in global scope. * It does this using __declspec(align(16)) which works on VC7 and on VC 6 - * with the processor pack. Unfortunately there is no way to detect the + * with the processor pack. Unfortunately there is no way to detect the * latter so this is turned on only on VC7. On other compilers this is the * the same as D3DXMATRIX. * @@ -392,7 +392,7 @@ typedef struct _D3DXMATRIXA16 : public D3DXMATRIX /* delete operators */ void operator delete ( void* ); /* These are NOT virtual; Do not */ void operator delete[] ( void* ); /* cast to D3DXMATRIX and delete. */ - + /* assignment operators */ _D3DXMATRIXA16& operator = ( CONST D3DXMATRIX& ); @@ -662,7 +662,7 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformCoord // Transform (x, y, 0, 0) by matrix. D3DXVECTOR2* WINAPI D3DXVec2TransformNormal ( D3DXVECTOR2 *pOut, CONST D3DXVECTOR2 *pV, CONST D3DXMATRIX *pM ); - + // Transform Array (x, y, 0, 1) by matrix. D3DXVECTOR4* WINAPI D3DXVec2TransformArray ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n); @@ -674,8 +674,8 @@ D3DXVECTOR2* WINAPI D3DXVec2TransformCoordArray // Transform Array (x, y, 0, 0) by matrix. D3DXVECTOR2* WINAPI D3DXVec2TransformNormalArray ( D3DXVECTOR2 *pOut, UINT OutStride, CONST D3DXVECTOR2 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); - - + + #ifdef __cplusplus } @@ -754,14 +754,14 @@ D3DXVECTOR4* WINAPI D3DXVec3Transform D3DXVECTOR3* WINAPI D3DXVec3TransformCoord ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); -// Transform (x, y, z, 0) by matrix. If you transforming a normal by a -// non-affine matrix, the matrix you pass to this function should be the +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the // transpose of the inverse of the matrix you would use to transform a coord. D3DXVECTOR3* WINAPI D3DXVec3TransformNormal ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); - - -// Transform Array (x, y, z, 1) by matrix. + + +// Transform Array (x, y, z, 1) by matrix. D3DXVECTOR4* WINAPI D3DXVec3TransformArray ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); @@ -769,8 +769,8 @@ D3DXVECTOR4* WINAPI D3DXVec3TransformArray D3DXVECTOR3* WINAPI D3DXVec3TransformCoordArray ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); -// Transform (x, y, z, 0) by matrix. If you transforming a normal by a -// non-affine matrix, the matrix you pass to this function should be the +// Transform (x, y, z, 0) by matrix. If you transforming a normal by a +// non-affine matrix, the matrix you pass to this function should be the // transpose of the inverse of the matrix you would use to transform a coord. D3DXVECTOR3* WINAPI D3DXVec3TransformNormalArray ( D3DXVECTOR3 *pOut, UINT OutStride, CONST D3DXVECTOR3 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); @@ -784,7 +784,7 @@ D3DXVECTOR3* WINAPI D3DXVec3Project D3DXVECTOR3* WINAPI D3DXVec3Unproject ( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DVIEWPORT9 *pViewport, CONST D3DXMATRIX *pProjection, CONST D3DXMATRIX *pView, CONST D3DXMATRIX *pWorld); - + // Project vector Array from object space into screen space D3DXVECTOR3* WINAPI D3DXVec3ProjectArray ( D3DXVECTOR3 *pOut, UINT OutStride,CONST D3DXVECTOR3 *pV, UINT VStride,CONST D3DVIEWPORT9 *pViewport, @@ -871,7 +871,7 @@ D3DXVECTOR4* WINAPI D3DXVec4BaryCentric // Transform vector by matrix. D3DXVECTOR4* WINAPI D3DXVec4Transform ( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); - + // Transform vector array by matrix. D3DXVECTOR4* WINAPI D3DXVec4TransformArray ( D3DXVECTOR4 *pOut, UINT OutStride, CONST D3DXVECTOR4 *pV, UINT VStride, CONST D3DXMATRIX *pM, UINT n ); @@ -903,7 +903,7 @@ FLOAT WINAPI D3DXMatrixDeterminant ( CONST D3DXMATRIX *pM ); HRESULT WINAPI D3DXMatrixDecompose - ( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, + ( D3DXVECTOR3 *pOutScale, D3DXQUATERNION *pOutRotation, D3DXVECTOR3 *pOutTranslation, CONST D3DXMATRIX *pM ); D3DXMATRIX* WINAPI D3DXMatrixTranspose @@ -968,9 +968,9 @@ D3DXMATRIX* WINAPI D3DXMatrixTransformation // Build 2D transformation matrix in XY plane. NULL arguments are treated as identity. // Mout = Msc-1 * Msr-1 * Ms * Msr * Msc * Mrc-1 * Mr * Mrc * Mt D3DXMATRIX* WINAPI D3DXMatrixTransformation2D - ( D3DXMATRIX *pOut, CONST D3DXVECTOR2* pScalingCenter, - FLOAT ScalingRotation, CONST D3DXVECTOR2* pScaling, - CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, + ( D3DXMATRIX *pOut, CONST D3DXVECTOR2* pScalingCenter, + FLOAT ScalingRotation, CONST D3DXVECTOR2* pScaling, + CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, CONST D3DXVECTOR2* pTranslation); // Build affine transformation matrix. NULL arguments are treated as identity. @@ -982,7 +982,7 @@ D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation // Build 2D affine transformation matrix in XY plane. NULL arguments are treated as identity. // Mout = Ms * Mrc-1 * Mr * Mrc * Mt D3DXMATRIX* WINAPI D3DXMatrixAffineTransformation2D - ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR2* pRotationCenter, + ( D3DXMATRIX *pOut, FLOAT Scaling, CONST D3DXVECTOR2* pRotationCenter, FLOAT Rotation, CONST D3DXVECTOR2* pTranslation); // Build a lookat matrix. (right-handed) @@ -1126,7 +1126,7 @@ D3DXQUATERNION* WINAPI D3DXQuaternionLn // if q = (0, theta * v); exp(q) = (cos(theta), sin(theta) * v) D3DXQUATERNION* WINAPI D3DXQuaternionExp ( D3DXQUATERNION *pOut, CONST D3DXQUATERNION *pQ ); - + // Spherical linear interpolation between Q1 (t == 0) and Q2 (t == 1). // Expects unit quaternions. D3DXQUATERNION* WINAPI D3DXQuaternionSlerp @@ -1141,11 +1141,11 @@ D3DXQUATERNION* WINAPI D3DXQuaternionSquad CONST D3DXQUATERNION *pC, FLOAT t ); // Setup control points for spherical quadrangle interpolation -// from Q1 to Q2. The control points are chosen in such a way +// from Q1 to Q2. The control points are chosen in such a way // to ensure the continuity of tangents with adjacent segments. void WINAPI D3DXQuaternionSquadSetup ( D3DXQUATERNION *pAOut, D3DXQUATERNION *pBOut, D3DXQUATERNION *pCOut, - CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, + CONST D3DXQUATERNION *pQ0, CONST D3DXQUATERNION *pQ1, CONST D3DXQUATERNION *pQ2, CONST D3DXQUATERNION *pQ3 ); // Barycentric interpolation. @@ -1209,7 +1209,7 @@ D3DXPLANE* WINAPI D3DXPlaneFromPoints // M should be the inverse transpose of the transformation desired. D3DXPLANE* WINAPI D3DXPlaneTransform ( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); - + // Transform an array of planes by a matrix. The vectors (a,b,c) must be normal. // M should be the inverse transpose of the transformation desired. D3DXPLANE* WINAPI D3DXPlaneTransformArray @@ -1276,7 +1276,7 @@ extern "C" { // Calculate Fresnel term given the cosine of theta (likely obtained by // taking the dot of two normals), and the refraction index of the material. FLOAT WINAPI D3DXFresnelTerm - (FLOAT CosTheta, FLOAT RefractionIndex); + (FLOAT CosTheta, FLOAT RefractionIndex); #ifdef __cplusplus } @@ -1292,7 +1292,7 @@ typedef interface ID3DXMatrixStack ID3DXMatrixStack; typedef interface ID3DXMatrixStack *LPD3DXMATRIXSTACK; // {C7885BA7-F990-4fe7-922D-8515E477DD85} -DEFINE_GUID(IID_ID3DXMatrixStack, +DEFINE_GUID(IID_ID3DXMatrixStack, 0xc7885ba7, 0xf990, 0x4fe7, 0x92, 0x2d, 0x85, 0x15, 0xe4, 0x77, 0xdd, 0x85); @@ -1387,9 +1387,9 @@ DECLARE_INTERFACE_(ID3DXMatrixStack, IUnknown) extern "C" { #endif -HRESULT WINAPI - D3DXCreateMatrixStack( - DWORD Flags, +HRESULT WINAPI + D3DXCreateMatrixStack( + DWORD Flags, LPD3DXMATRIXSTACK* ppStack); #ifdef __cplusplus @@ -1402,7 +1402,7 @@ HRESULT WINAPI // // NOTE: // * Most of these functions can take the same object as in and out parameters. -// The exceptions are the rotation functions. +// The exceptions are the rotation functions. // // * Out parameters are typically also returned as return values, so that // the output of one function may be used as a parameter to another. @@ -1426,19 +1426,19 @@ extern "C" { FLOAT* WINAPI D3DXSHEvalDirection ( FLOAT *pOut, UINT Order, CONST D3DXVECTOR3 *pDir ); - + FLOAT* WINAPI D3DXSHRotate ( FLOAT *pOut, UINT Order, CONST D3DXMATRIX *pMatrix, CONST FLOAT *pIn ); - + FLOAT* WINAPI D3DXSHRotateZ ( FLOAT *pOut, UINT Order, FLOAT Angle, CONST FLOAT *pIn ); - + FLOAT* WINAPI D3DXSHAdd ( FLOAT *pOut, UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); FLOAT* WINAPI D3DXSHScale ( FLOAT *pOut, UINT Order, CONST FLOAT *pIn, CONST FLOAT Scale ); - + FLOAT WINAPI D3DXSHDot ( UINT Order, CONST FLOAT *pA, CONST FLOAT *pB ); @@ -1456,7 +1456,7 @@ FLOAT* WINAPI D3DXSHMultiply6( FLOAT *pOut, CONST FLOAT *pF, CONST FLOAT *pG); //============================================================================ HRESULT WINAPI D3DXSHEvalDirectionalLight - ( UINT Order, CONST D3DXVECTOR3 *pDir, + ( UINT Order, CONST D3DXVECTOR3 *pDir, FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); @@ -1469,7 +1469,7 @@ HRESULT WINAPI D3DXSHEvalConeLight ( UINT Order, CONST D3DXVECTOR3 *pDir, FLOAT Radius, FLOAT RIntensity, FLOAT GIntensity, FLOAT BIntensity, FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); - + HRESULT WINAPI D3DXSHEvalHemisphereLight ( UINT Order, CONST D3DXVECTOR3 *pDir, D3DXCOLOR Top, D3DXCOLOR Bottom, FLOAT *pROut, FLOAT *pGOut, FLOAT *pBOut ); @@ -1496,7 +1496,7 @@ HRESULT WINAPI D3DXSHEvalHemisphereLight // pGOut // Output SH vector for Green // pBOut -// Output SH vector for Blue +// Output SH vector for Blue // //============================================================================ diff --git a/gfx/include/d3d9/d3dx9mesh.h b/gfx/include/d3d9/d3dx9mesh.h index 6798c5898f..2418f7acdb 100644 --- a/gfx/include/d3d9/d3dx9mesh.h +++ b/gfx/include/d3d9/d3dx9mesh.h @@ -13,27 +13,27 @@ #define __D3DX9MESH_H__ // {7ED943DD-52E8-40b5-A8D8-76685C406330} -DEFINE_GUID(IID_ID3DXBaseMesh, +DEFINE_GUID(IID_ID3DXBaseMesh, 0x7ed943dd, 0x52e8, 0x40b5, 0xa8, 0xd8, 0x76, 0x68, 0x5c, 0x40, 0x63, 0x30); // {4020E5C2-1403-4929-883F-E2E849FAC195} -DEFINE_GUID(IID_ID3DXMesh, +DEFINE_GUID(IID_ID3DXMesh, 0x4020e5c2, 0x1403, 0x4929, 0x88, 0x3f, 0xe2, 0xe8, 0x49, 0xfa, 0xc1, 0x95); // {8875769A-D579-4088-AAEB-534D1AD84E96} -DEFINE_GUID(IID_ID3DXPMesh, +DEFINE_GUID(IID_ID3DXPMesh, 0x8875769a, 0xd579, 0x4088, 0xaa, 0xeb, 0x53, 0x4d, 0x1a, 0xd8, 0x4e, 0x96); // {667EA4C7-F1CD-4386-B523-7C0290B83CC5} -DEFINE_GUID(IID_ID3DXSPMesh, +DEFINE_GUID(IID_ID3DXSPMesh, 0x667ea4c7, 0xf1cd, 0x4386, 0xb5, 0x23, 0x7c, 0x2, 0x90, 0xb8, 0x3c, 0xc5); // {11EAA540-F9A6-4d49-AE6A-E19221F70CC4} -DEFINE_GUID(IID_ID3DXSkinInfo, +DEFINE_GUID(IID_ID3DXSkinInfo, 0x11eaa540, 0xf9a6, 0x4d49, 0xae, 0x6a, 0xe1, 0x92, 0x21, 0xf7, 0xc, 0xc4); // {3CE6CC22-DBF2-44f4-894D-F9C34A337139} -DEFINE_GUID(IID_ID3DXPatchMesh, +DEFINE_GUID(IID_ID3DXPatchMesh, 0x3ce6cc22, 0xdbf2, 0x44f4, 0x89, 0x4d, 0xf9, 0xc3, 0x4a, 0x33, 0x71, 0x39); //patch mesh can be quads or tris @@ -49,11 +49,11 @@ typedef enum _D3DXPATCHMESHTYPE { enum _D3DXMESH { D3DXMESH_32BIT = 0x001, // If set, then use 32 bit indices, if not set use 16 bit indices. D3DXMESH_DONOTCLIP = 0x002, // Use D3DUSAGE_DONOTCLIP for VB & IB. - D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. - D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. - D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. + D3DXMESH_POINTS = 0x004, // Use D3DUSAGE_POINTS for VB & IB. + D3DXMESH_RTPATCHES = 0x008, // Use D3DUSAGE_RTPATCHES for VB & IB. + D3DXMESH_NPATCHES = 0x4000,// Use D3DUSAGE_NPATCHES for VB & IB. D3DXMESH_VB_SYSTEMMEM = 0x010, // Use D3DPOOL_SYSTEMMEM for VB. Overrides D3DXMESH_MANAGEDVERTEXBUFFER - D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. + D3DXMESH_VB_MANAGED = 0x020, // Use D3DPOOL_MANAGED for VB. D3DXMESH_VB_WRITEONLY = 0x040, // Use D3DUSAGE_WRITEONLY for VB. D3DXMESH_VB_DYNAMIC = 0x080, // Use D3DUSAGE_DYNAMIC for VB. D3DXMESH_VB_SOFTWAREPROCESSING = 0x8000, // Use D3DUSAGE_SOFTWAREPROCESSING for VB. @@ -91,11 +91,11 @@ enum _D3DXMESHSIMP typedef enum _D3DXCLEANTYPE { D3DXCLEAN_BACKFACING = 0x00000001, D3DXCLEAN_BOWTIES = 0x00000002, - + // Helper options D3DXCLEAN_SKINNING = D3DXCLEAN_BACKFACING, // Bowtie cleaning modifies geometry and breaks skinning D3DXCLEAN_OPTIMIZATION = D3DXCLEAN_BACKFACING, - D3DXCLEAN_SIMPLIFICATION= D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES, + D3DXCLEAN_SIMPLIFICATION= D3DXCLEAN_BACKFACING | D3DXCLEAN_BOWTIES, } D3DXCLEANTYPE; enum _MAX_FVF_DECL_SIZE @@ -170,7 +170,7 @@ typedef D3DXMATERIAL *LPD3DXMATERIAL; typedef enum _D3DXEFFECTDEFAULTTYPE { - D3DXEDT_STRING = 0x1, // pValue points to a null terminated ASCII string + D3DXEDT_STRING = 0x1, // pValue points to a null terminated ASCII string D3DXEDT_FLOATS = 0x2, // pValue points to an array of floats - number of floats is NumBytes / sizeof(float) D3DXEDT_DWORD = 0x3, // pValue points to a DWORD @@ -208,7 +208,7 @@ enum _D3DXWELDEPSILONSFLAGS { D3DXWELDEPSILONS_WELDALL = 0x1, // weld all vertices marked by adjacency as being overlapping - D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched + D3DXWELDEPSILONS_WELDPARTIALMATCHES = 0x2, // if a given vertex component is within epsilon, modify partial matched // vertices so that both components identical AND if all components "equal" // remove one of the vertices D3DXWELDEPSILONS_DONOTREMOVEVERTICES = 0x4, // instructs weld to only allow modifications to vertices and not removal @@ -258,9 +258,9 @@ DECLARE_INTERFACE_(ID3DXBaseMesh, IUnknown) STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; STDMETHOD_(DWORD, GetOptions)(THIS) PURE; STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; @@ -298,9 +298,9 @@ DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; STDMETHOD_(DWORD, GetOptions)(THIS) PURE; STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; @@ -320,10 +320,10 @@ DECLARE_INTERFACE_(ID3DXMesh, ID3DXBaseMesh) // ID3DXMesh STDMETHOD(LockAttributeBuffer)(THIS_ DWORD Flags, DWORD** ppData) PURE; STDMETHOD(UnlockAttributeBuffer)(THIS) PURE; - STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, - DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + STDMETHOD(Optimize)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, LPD3DXMESH* ppOptMesh) PURE; - STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, + STDMETHOD(OptimizeInplace)(THIS_ DWORD Flags, CONST DWORD* pAdjacencyIn, DWORD* pAdjacencyOut, DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap) PURE; STDMETHOD(SetAttributeTable)(THIS_ CONST D3DXATTRIBUTERANGE *pAttribTable, DWORD cAttribTableSize) PURE; }; @@ -348,9 +348,9 @@ DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) STDMETHOD_(DWORD, GetNumBytesPerVertex)(THIS) PURE; STDMETHOD_(DWORD, GetOptions)(THIS) PURE; STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppCloneMesh) PURE; STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; @@ -368,9 +368,9 @@ DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) STDMETHOD(UpdateSemantics)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; // ID3DXPMesh - STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPMESH* ppCloneMesh) PURE; STDMETHOD(SetNumFaces)(THIS_ DWORD Faces) PURE; STDMETHOD(SetNumVertices)(THIS_ DWORD Vertices) PURE; @@ -380,8 +380,8 @@ DECLARE_INTERFACE_(ID3DXPMesh, ID3DXBaseMesh) STDMETHOD_(DWORD, GetMinVertices)(THIS) PURE; STDMETHOD(Save)(THIS_ IStream *pStream, CONST D3DXMATERIAL* pMaterials, CONST D3DXEFFECTINSTANCE* pEffectInstances, DWORD NumMaterials) PURE; - STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, - DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, + STDMETHOD(Optimize)(THIS_ DWORD Flags, DWORD* pAdjacencyOut, + DWORD* pFaceRemap, LPD3DXBUFFER *ppVertexRemap, LPD3DXMESH* ppOptMesh) PURE; STDMETHOD(OptimizeBaseLOD)(THIS_ DWORD Flags, DWORD* pFaceRemap) PURE; @@ -413,13 +413,13 @@ DECLARE_INTERFACE_(ID3DXSPMesh, IUnknown) STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; STDMETHOD_(DWORD, GetOptions)(THIS) PURE; STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9* ppDevice) PURE; - STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, + STDMETHOD(CloneMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(CloneMesh)(THIS_ DWORD Options, + STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pAdjacencyOut, DWORD *pVertexRemapOut, LPD3DXMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, + STDMETHOD(ClonePMeshFVF)(THIS_ DWORD Options, DWORD FVF, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsByFace, LPD3DXPMESH* ppCloneMesh) PURE; - STDMETHOD(ClonePMesh)(THIS_ DWORD Options, + STDMETHOD(ClonePMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDeclaration, LPDIRECT3DDEVICE9 pD3DDevice, DWORD *pVertexRemapOut, FLOAT *pErrorsbyFace, LPD3DXPMESH* ppCloneMesh) PURE; STDMETHOD(ReduceFaces)(THIS_ DWORD Faces) PURE; STDMETHOD(ReduceVertices)(THIS_ DWORD Vertices) PURE; @@ -441,7 +441,7 @@ enum _D3DXMESHOPT { D3DXMESHOPT_IGNOREVERTS = 0x10000000, // optimize faces only, don't touch vertices D3DXMESHOPT_DONOTSPLIT = 0x20000000, // do not split vertices shared between attribute groups when attribute sorting D3DXMESHOPT_DEVICEINDEPENDENT = 0x00400000, // Only affects VCache. uses a static known good cache size for all cards - + // D3DXMESHOPT_SHAREVB has been removed, please use D3DXMESH_VB_SHARE instead }; @@ -494,7 +494,7 @@ DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) STDMETHOD(GetDevice)(THIS_ LPDIRECT3DDEVICE9 *ppDevice) PURE; STDMETHOD(GetPatchInfo)(THIS_ LPD3DXPATCHINFO PatchInfo) PURE; - // Control mesh access + // Control mesh access STDMETHOD(GetVertexBuffer)(THIS_ LPDIRECT3DVERTEXBUFFER9* ppVB) PURE; STDMETHOD(GetIndexBuffer)(THIS_ LPDIRECT3DINDEXBUFFER9* ppIB) PURE; STDMETHOD(LockVertexBuffer)(THIS_ DWORD flags, LPVOID *ppData) PURE; @@ -507,18 +507,18 @@ DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) // This function returns the size of the tessellated mesh given a tessellation level. // This assumes uniform tessellation. For adaptive tessellation the Adaptive parameter must // be set to TRUE and TessellationLevel should be the max tessellation. - // This will result in the max mesh size necessary for adaptive tessellation. + // This will result in the max mesh size necessary for adaptive tessellation. STDMETHOD(GetTessSize)(THIS_ FLOAT fTessLevel,DWORD Adaptive, DWORD *NumTriangles,DWORD *NumVertices) PURE; - + //GenerateAdjacency determines which patches are adjacent with provided tolerance //this information is used internally to optimize tessellation STDMETHOD(GenerateAdjacency)(THIS_ FLOAT Tolerance) PURE; - + //CloneMesh Creates a new patchmesh with the specified decl, and converts the vertex buffer //to the new decl. Entries in the new decl which are new are set to 0. If the current mesh //has adjacency, the new mesh will also have adjacency STDMETHOD(CloneMesh)(THIS_ DWORD Options, CONST D3DVERTEXELEMENT9 *pDecl, LPD3DXPATCHMESH *pMesh) PURE; - + // Optimizes the patchmesh for efficient tessellation. This function is designed // to perform one time optimization for patch meshes that need to be tessellated // repeatedly by calling the Tessellate() method. The optimization performed is @@ -542,8 +542,8 @@ DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) D3DTEXTUREFILTERTYPE *MipFilter, D3DTEXTUREADDRESS *Wrap, DWORD *dwLODBias) PURE; - - // Performs the uniform tessellation based on the tessellation level. + + // Performs the uniform tessellation based on the tessellation level. // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. STDMETHOD(Tessellate)(THIS_ FLOAT fTessLevel,LPD3DXMESH pMesh) PURE; @@ -553,9 +553,9 @@ DECLARE_INTERFACE_(ID3DXPatchMesh, IUnknown) // at the 2 vertices it connects. // MaxTessLevel specifies the upper limit for adaptive tesselation. // This function will perform more efficiently if the patch mesh has been optimized using the Optimize() call. - STDMETHOD(TessellateAdaptive)(THIS_ + STDMETHOD(TessellateAdaptive)(THIS_ CONST D3DXVECTOR4 *pTrans, - DWORD dwMaxTessLevel, + DWORD dwMaxTessLevel, DWORD dwMinTessLevel, LPD3DXMESH pMesh) PURE; @@ -583,24 +583,24 @@ DECLARE_INTERFACE_(ID3DXSkinInfo, IUnknown) // This gets the max face influences based on a triangle mesh with the specified index buffer STDMETHOD(GetMaxFaceInfluences)(THIS_ LPDIRECT3DINDEXBUFFER9 pIB, DWORD NumFaces, DWORD* maxFaceInfluences) PURE; - + // Set min bone influence. Bone influences that are smaller than this are ignored STDMETHOD(SetMinBoneInfluence)(THIS_ FLOAT MinInfl) PURE; - // Get min bone influence. + // Get min bone influence. STDMETHOD_(FLOAT, GetMinBoneInfluence)(THIS) PURE; - + // Bone names are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object STDMETHOD(SetBoneName)(THIS_ DWORD Bone, LPCSTR pName) PURE; // pName is copied to an internal string buffer STDMETHOD_(LPCSTR, GetBoneName)(THIS_ DWORD Bone) PURE; // A pointer to an internal string buffer is returned. Do not free this. - + // Bone offset matrices are returned by D3DXLoadSkinMeshFromXof. They are not used by any other method of this object STDMETHOD(SetBoneOffsetMatrix)(THIS_ DWORD Bone, CONST D3DXMATRIX *pBoneTransform) PURE; // pBoneTransform is copied to an internal buffer STDMETHOD_(LPD3DXMATRIX, GetBoneOffsetMatrix)(THIS_ DWORD Bone) PURE; // A pointer to an internal matrix is returned. Do not free this. - + // Clone a skin info object STDMETHOD(Clone)(THIS_ LPD3DXSKININFO* ppSkinInfo) PURE; - - // Update bone influence information to match vertices after they are reordered. This should be called + + // Update bone influence information to match vertices after they are reordered. This should be called // if the target vertex buffer has been reordered externally. STDMETHOD(Remap)(THIS_ DWORD NumVertices, DWORD* pVertexRemap) PURE; @@ -611,39 +611,39 @@ DECLARE_INTERFACE_(ID3DXSkinInfo, IUnknown) STDMETHOD(GetDeclaration)(THIS_ D3DVERTEXELEMENT9 Declaration[MAX_FVF_DECL_SIZE]) PURE; // Apply SW skinning based on current pose matrices to the target vertices. - STDMETHOD(UpdateSkinnedMesh)(THIS_ - CONST D3DXMATRIX* pBoneTransforms, - CONST D3DXMATRIX* pBoneInvTransposeTransforms, - LPCVOID pVerticesSrc, + STDMETHOD(UpdateSkinnedMesh)(THIS_ + CONST D3DXMATRIX* pBoneTransforms, + CONST D3DXMATRIX* pBoneInvTransposeTransforms, + LPCVOID pVerticesSrc, PVOID pVerticesDst) PURE; // Takes a mesh and returns a new mesh with per vertex blend weights and a bone combination // table that describes which bones affect which subsets of the mesh - STDMETHOD(ConvertToBlendedMesh)(THIS_ + STDMETHOD(ConvertToBlendedMesh)(THIS_ LPD3DXMESH pMesh, - DWORD Options, - CONST DWORD *pAdjacencyIn, + DWORD Options, + CONST DWORD *pAdjacencyIn, LPDWORD pAdjacencyOut, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, DWORD* pMaxFaceInfl, - DWORD* pNumBoneCombinations, - LPD3DXBUFFER* ppBoneCombinationTable, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, LPD3DXMESH* ppMesh) PURE; - // Takes a mesh and returns a new mesh with per vertex blend weights and indices + // Takes a mesh and returns a new mesh with per vertex blend weights and indices // and a bone combination table that describes which bones palettes affect which subsets of the mesh - STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ + STDMETHOD(ConvertToIndexedBlendedMesh)(THIS_ LPD3DXMESH pMesh, - DWORD Options, - DWORD paletteSize, - CONST DWORD *pAdjacencyIn, - LPDWORD pAdjacencyOut, - DWORD* pFaceRemap, - LPD3DXBUFFER *ppVertexRemap, + DWORD Options, + DWORD paletteSize, + CONST DWORD *pAdjacencyIn, + LPDWORD pAdjacencyOut, + DWORD* pFaceRemap, + LPD3DXBUFFER *ppVertexRemap, DWORD* pMaxVertexInfl, - DWORD* pNumBoneCombinations, - LPD3DXBUFFER* ppBoneCombinationTable, + DWORD* pNumBoneCombinations, + LPD3DXBUFFER* ppBoneCombinationTable, LPD3DXMESH* ppMesh) PURE; }; @@ -652,28 +652,28 @@ extern "C" { #endif //__cplusplus -HRESULT WINAPI +HRESULT WINAPI D3DXCreateMesh( - DWORD NumFaces, - DWORD NumVertices, - DWORD Options, - CONST D3DVERTEXELEMENT9 *pDeclaration, - LPDIRECT3DDEVICE9 pD3DDevice, + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + CONST D3DVERTEXELEMENT9 *pDeclaration, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateMeshFVF( - DWORD NumFaces, - DWORD NumVertices, - DWORD Options, - DWORD FVF, - LPDIRECT3DDEVICE9 pD3DDevice, + DWORD NumFaces, + DWORD NumVertices, + DWORD Options, + DWORD FVF, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH* ppMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateSPMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, CONST FLOAT *pVertexWeights, LPD3DXSPMESH* ppSMesh); @@ -694,72 +694,72 @@ HRESULT WINAPI CONST DWORD* pAdjacency, LPD3DXBUFFER* ppErrorsAndWarnings); -HRESULT WINAPI +HRESULT WINAPI D3DXGeneratePMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, CONST FLOAT *pVertexWeights, - DWORD MinValue, - DWORD Options, + DWORD MinValue, + DWORD Options, LPD3DXPMESH* ppPMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXSimplifyMesh( - LPD3DXMESH pMesh, - CONST DWORD* pAdjacency, + LPD3DXMESH pMesh, + CONST DWORD* pAdjacency, CONST D3DXATTRIBUTEWEIGHTS *pVertexAttributeWeights, CONST FLOAT *pVertexWeights, - DWORD MinValue, - DWORD Options, + DWORD MinValue, + DWORD Options, LPD3DXMESH* ppMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXComputeBoundingSphere( CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position - DWORD NumVertices, + DWORD NumVertices, DWORD dwStride, // count in bytes to subsequent position vectors - D3DXVECTOR3 *pCenter, + D3DXVECTOR3 *pCenter, FLOAT *pRadius); -HRESULT WINAPI +HRESULT WINAPI D3DXComputeBoundingBox( CONST D3DXVECTOR3 *pFirstPosition, // pointer to first position - DWORD NumVertices, + DWORD NumVertices, DWORD dwStride, // count in bytes to subsequent position vectors - D3DXVECTOR3 *pMin, + D3DXVECTOR3 *pMin, D3DXVECTOR3 *pMax); -HRESULT WINAPI +HRESULT WINAPI D3DXComputeNormals( LPD3DXBASEMESH pMesh, CONST DWORD *pAdjacency); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateBuffer( - DWORD NumBytes, + DWORD NumBytes, LPD3DXBUFFER *ppBuffer); HRESULT WINAPI D3DXLoadMeshFromXA( - LPCSTR pFilename, - DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + LPCSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, DWORD *pNumMaterials, LPD3DXMESH *ppMesh); HRESULT WINAPI D3DXLoadMeshFromXW( - LPCWSTR pFilename, - DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + LPCWSTR pFilename, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, DWORD *pNumMaterials, LPD3DXMESH *ppMesh); @@ -769,67 +769,67 @@ HRESULT WINAPI #define D3DXLoadMeshFromX D3DXLoadMeshFromXA #endif -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshFromXInMemory( LPCVOID Memory, DWORD SizeOfMemory, - DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, DWORD *pNumMaterials, LPD3DXMESH *ppMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshFromXResource( HMODULE Module, LPCSTR Name, LPCSTR Type, - DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, DWORD *pNumMaterials, LPD3DXMESH *ppMesh); -HRESULT WINAPI +HRESULT WINAPI D3DXSaveMeshToXA( LPCSTR pFilename, LPD3DXMESH pMesh, CONST DWORD* pAdjacency, CONST D3DXMATERIAL* pMaterials, - CONST D3DXEFFECTINSTANCE* pEffectInstances, + CONST D3DXEFFECTINSTANCE* pEffectInstances, DWORD NumMaterials, DWORD Format ); -HRESULT WINAPI +HRESULT WINAPI D3DXSaveMeshToXW( LPCWSTR pFilename, LPD3DXMESH pMesh, CONST DWORD* pAdjacency, CONST D3DXMATERIAL* pMaterials, - CONST D3DXEFFECTINSTANCE* pEffectInstances, + CONST D3DXEFFECTINSTANCE* pEffectInstances, DWORD NumMaterials, DWORD Format ); - + #ifdef UNICODE #define D3DXSaveMeshToX D3DXSaveMeshToXW #else #define D3DXSaveMeshToX D3DXSaveMeshToXA #endif - -HRESULT WINAPI + +HRESULT WINAPI D3DXCreatePMeshFromStream( - IStream *pStream, + IStream *pStream, DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppEffectInstances, DWORD* pNumMaterials, LPD3DXPMESH *ppPMesh); @@ -838,10 +838,10 @@ HRESULT WINAPI HRESULT WINAPI D3DXCreateSkinInfo( DWORD NumVertices, - CONST D3DVERTEXELEMENT9 *pDeclaration, + CONST D3DVERTEXELEMENT9 *pDeclaration, DWORD NumBones, LPD3DXSKININFO* ppSkinInfo); - + // Creates a skin info object based on the number of vertices, number of bones, and a FVF describing the vertex layout of the target vertices // The bone names and initial bone transforms are not filled in the skin info object by this method. HRESULT WINAPI @@ -850,34 +850,34 @@ HRESULT WINAPI DWORD FVF, DWORD NumBones, LPD3DXSKININFO* ppSkinInfo); - + #ifdef __cplusplus } extern "C" { #endif //__cplusplus -HRESULT WINAPI +HRESULT WINAPI D3DXLoadMeshFromXof( - LPD3DXFILEDATA pxofMesh, - DWORD Options, - LPDIRECT3DDEVICE9 pD3DDevice, + LPD3DXFILEDATA pxofMesh, + DWORD Options, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppAdjacency, - LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppMaterials, + LPD3DXBUFFER *ppEffectInstances, DWORD *pNumMaterials, LPD3DXMESH *ppMesh); // This similar to D3DXLoadMeshFromXof, except also returns skinning info if present in the file -// If skinning info is not present, ppSkinInfo will be NULL +// If skinning info is not present, ppSkinInfo will be NULL HRESULT WINAPI D3DXLoadSkinMeshFromXof( - LPD3DXFILEDATA pxofMesh, + LPD3DXFILEDATA pxofMesh, DWORD Options, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER* ppAdjacency, LPD3DXBUFFER* ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppEffectInstances, DWORD *pMatOut, LPD3DXSKININFO* ppSkinInfo, LPD3DXMESH* ppMesh); @@ -894,12 +894,12 @@ HRESULT WINAPI DWORD NumBones, CONST D3DXBONECOMBINATION *pBoneCombinationTable, LPD3DXSKININFO* ppSkinInfo); - + HRESULT WINAPI D3DXTessellateNPatches( - LPD3DXMESH pMeshIn, - CONST DWORD* pAdjacencyIn, - FLOAT NumSegs, + LPD3DXMESH pMeshIn, + CONST DWORD* pAdjacencyIn, + FLOAT NumSegs, BOOL QuadraticInterpNormals, // if false use linear intrep for normals, if true use quadratic LPD3DXMESH *ppMeshOut, LPD3DXBUFFER *ppAdjacencyOut); @@ -907,7 +907,7 @@ HRESULT WINAPI //generates implied outputdecl from input decl //the decl generated from this should be used to generate the output decl for -//the tessellator subroutines. +//the tessellator subroutines. HRESULT WINAPI D3DXGenerateOutputDecl( @@ -917,14 +917,14 @@ HRESULT WINAPI //loads patches from an XFileData //since an X file can have up to 6 different patch meshes in it, //returns them in an array - pNumPatches will contain the number of -//meshes in the actual file. +//meshes in the actual file. HRESULT WINAPI D3DXLoadPatchMeshFromXof( LPD3DXFILEDATA pXofObjMesh, DWORD Options, LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXBUFFER *ppMaterials, - LPD3DXBUFFER *ppEffectInstances, + LPD3DXBUFFER *ppEffectInstances, PDWORD pNumMaterials, LPD3DXPATCHMESH *ppMesh); @@ -935,10 +935,10 @@ HRESULT WINAPI DWORD *pdwTriangles, //output number of triangles DWORD *pdwVertices); //output number of vertices -//computes the size of a single triangle patch +//computes the size of a single triangle patch HRESULT WINAPI D3DXTriPatchSize( - CONST FLOAT *pfNumSegs, //segments for each edge (3) + CONST FLOAT *pfNumSegs, //segments for each edge (3) DWORD *pdwTriangles, //output number of triangles DWORD *pdwVertices); //output number of vertices @@ -964,25 +964,25 @@ HRESULT WINAPI -//creates an NPatch PatchMesh from a D3DXMESH +//creates an NPatch PatchMesh from a D3DXMESH HRESULT WINAPI D3DXCreateNPatchMesh( LPD3DXMESH pMeshSysMem, LPD3DXPATCHMESH *pPatchMesh); - + //creates a patch mesh HRESULT WINAPI D3DXCreatePatchMesh( CONST D3DXPATCHINFO *pInfo, //patch type DWORD dwNumPatches, //number of patches DWORD dwNumVertices, //number of control vertices - DWORD dwOptions, //options + DWORD dwOptions, //options CONST D3DVERTEXELEMENT9 *pDecl, //format of control vertices - LPDIRECT3DDEVICE9 pD3DDevice, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXPATCHMESH *pPatchMesh); - + //returns the number of degenerates in a patch mesh - //text output put in string. HRESULT WINAPI @@ -994,10 +994,10 @@ HRESULT WINAPI UINT WINAPI D3DXGetFVFVertexSize(DWORD FVF); -UINT WINAPI +UINT WINAPI D3DXGetDeclVertexSize(CONST D3DVERTEXELEMENT9 *pDecl,DWORD Stream); -UINT WINAPI +UINT WINAPI D3DXGetDeclLength(CONST D3DVERTEXELEMENT9 *pDecl); HRESULT WINAPI @@ -1010,20 +1010,20 @@ HRESULT WINAPI CONST D3DVERTEXELEMENT9 *pDeclarator, DWORD *pFVF); -HRESULT WINAPI +HRESULT WINAPI D3DXWeldVertices( - LPD3DXMESH pMesh, + LPD3DXMESH pMesh, DWORD Flags, - CONST D3DXWELDEPSILONS *pEpsilons, - CONST DWORD *pAdjacencyIn, + CONST D3DXWELDEPSILONS *pEpsilons, + CONST DWORD *pAdjacencyIn, DWORD *pAdjacencyOut, - DWORD *pFaceRemap, + DWORD *pFaceRemap, LPD3DXBUFFER *ppVertexRemap); typedef struct _D3DXINTERSECTINFO { DWORD FaceIndex; // index of face intersected - FLOAT U; // Barycentric Hit Coordinates + FLOAT U; // Barycentric Hit Coordinates FLOAT V; // Barycentric Hit Coordinates FLOAT Dist; // Ray-Intersection Parameter Distance } D3DXINTERSECTINFO, *LPD3DXINTERSECTINFO; @@ -1033,13 +1033,13 @@ HRESULT WINAPI D3DXIntersect( LPD3DXBASEMESH pMesh, CONST D3DXVECTOR3 *pRayPos, - CONST D3DXVECTOR3 *pRayDir, + CONST D3DXVECTOR3 *pRayDir, BOOL *pHit, // True if any faces were intersected DWORD *pFaceIndex, // index of closest face intersected - FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pU, // Barycentric Hit Coordinates FLOAT *pV, // Barycentric Hit Coordinates FLOAT *pDist, // Ray-Intersection Parameter Distance - LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) DWORD *pCountOfHits); // Number of entries in AllHits array HRESULT WINAPI @@ -1047,20 +1047,20 @@ HRESULT WINAPI LPD3DXBASEMESH pMesh, DWORD AttribId, CONST D3DXVECTOR3 *pRayPos, - CONST D3DXVECTOR3 *pRayDir, + CONST D3DXVECTOR3 *pRayDir, BOOL *pHit, // True if any faces were intersected DWORD *pFaceIndex, // index of closest face intersected - FLOAT *pU, // Barycentric Hit Coordinates + FLOAT *pU, // Barycentric Hit Coordinates FLOAT *pV, // Barycentric Hit Coordinates FLOAT *pDist, // Ray-Intersection Parameter Distance - LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) + LPD3DXBUFFER *ppAllHits, // Array of D3DXINTERSECTINFOs for all hits (not just closest) DWORD *pCountOfHits); // Number of entries in AllHits array HRESULT WINAPI D3DXSplitMesh ( - LPD3DXMESH pMeshIn, - CONST DWORD *pAdjacencyIn, + LPD3DXMESH pMeshIn, + CONST DWORD *pAdjacencyIn, CONST DWORD MaxSize, CONST DWORD Options, DWORD *pMeshesOut, @@ -1070,7 +1070,7 @@ HRESULT WINAPI D3DXSplitMesh LPD3DXBUFFER *ppVertRemapArrayOut ); -BOOL WINAPI D3DXIntersectTri +BOOL WINAPI D3DXIntersectTri ( CONST D3DXVECTOR3 *p0, // Triangle vertex 0 position CONST D3DXVECTOR3 *p1, // Triangle vertex 1 position @@ -1088,9 +1088,9 @@ BOOL WINAPI CONST D3DXVECTOR3 *pRayPosition, CONST D3DXVECTOR3 *pRayDirection); -BOOL WINAPI +BOOL WINAPI D3DXBoxBoundProbe( - CONST D3DXVECTOR3 *pMin, + CONST D3DXVECTOR3 *pMin, CONST D3DXVECTOR3 *pMax, CONST D3DXVECTOR3 *pRayPosition, CONST D3DXVECTOR3 *pRayDirection); @@ -1124,11 +1124,11 @@ HRESULT WINAPI D3DXComputeTangentFrameEx(ID3DXMesh *pMesh, //puts the binorm in BINORM[BinormIndex] also specified in the decl. // //If neither the binorm or the tangnet are in the meshes declaration, -//the function will fail. +//the function will fail. // //If a tangent or Binorm field is in the Decl, but the user does not //wish D3DXComputeTangent to replace them, then D3DX_DEFAULT specified -//in the TangentIndex or BinormIndex will cause it to ignore the specified +//in the TangentIndex or BinormIndex will cause it to ignore the specified //semantic. // //Wrap should be specified if the texture coordinates wrap. @@ -1186,7 +1186,7 @@ typedef HRESULT (WINAPI *LPD3DXUVATLASCB)(FLOAT fPercentDone, LPVOID lpUserCont // integrated metric tensor for that face. This lets you control // the way this triangle may be stretched in the atlas. The IMT // passed in will be 3 floats (a,b,c) and specify a symmetric -// matrix (a b) that, given a vector (s,t), specifies the +// matrix (a b) that, given a vector (s,t), specifies the // (b c) // distance between a vector v1 and a vector v2 = v1 + (s,t) as // sqrt((s, t) * M * (s, t)^T). @@ -1202,7 +1202,7 @@ typedef HRESULT (WINAPI *LPD3DXUVATLASCB)(FLOAT fPercentDone, LPVOID lpUserCont // in some 2-D space. For D3DXUVAtlas, this space is created by // letting S be the direction from the first to the second // vertex, and T be the cross product between the normal and S. -// +// // pStatusCallback - Since the atlas creation process can be very CPU intensive, // this allows the programmer to specify a function to be called // periodically, similarly to how it is done in the PRT simulation @@ -1459,7 +1459,7 @@ HRESULT WINAPI LPD3DXBUFFER *ppStripLengths, DWORD *pNumStrips); - + //============================================================================ // // D3DXOptimizeFaces: @@ -1485,17 +1485,17 @@ HRESULT WINAPI //============================================================================ HRESULT WINAPI D3DXOptimizeFaces( - LPCVOID pbIndices, - UINT cFaces, - UINT cVertices, - BOOL b32BitIndices, + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, DWORD* pFaceRemap); - + //============================================================================ // // D3DXOptimizeVertices: // -------------------- -// Generate a vertex remapping to optimize for in order use of vertices for +// Generate a vertex remapping to optimize for in order use of vertices for // a given set of indices. This is commonly used after applying the face // remap generated by D3DXOptimizeFaces // @@ -1516,10 +1516,10 @@ HRESULT WINAPI //============================================================================ HRESULT WINAPI D3DXOptimizeVertices( - LPCVOID pbIndices, - UINT cFaces, - UINT cVertices, - BOOL b32BitIndices, + LPCVOID pbIndices, + UINT cFaces, + UINT cVertices, + BOOL b32BitIndices, DWORD* pVertexRemap); #ifdef __cplusplus @@ -1546,8 +1546,8 @@ typedef enum _D3DXSHGPUSIMOPT { D3DXSHGPUSIMOPT_SHADOWRES1024 = 2, D3DXSHGPUSIMOPT_SHADOWRES2048 = 3, - D3DXSHGPUSIMOPT_HIGHQUALITY = 4, - + D3DXSHGPUSIMOPT_HIGHQUALITY = 4, + D3DXSHGPUSIMOPT_FORCE_DWORD = 0x7fffffff } D3DXSHGPUSIMOPT; @@ -1560,7 +1560,7 @@ typedef struct _D3DXSHMATERIAL { BOOL bMirror; // Must be set to FALSE. bMirror == TRUE not currently supported BOOL bSubSurf; // true if the object does subsurface scattering - can't do this and be a mirror - // subsurface scattering parameters + // subsurface scattering parameters FLOAT RelativeIndexOfRefraction; D3DCOLORVALUE Absorption; D3DCOLORVALUE ReducedScattering; @@ -1583,10 +1583,10 @@ typedef struct _D3DXSHPRTSPLITMESHVERTDATA { typedef struct _D3DXSHPRTSPLITMESHCLUSTERDATA { UINT uVertStart; // initial index into remapped vertex array UINT uVertLength; // number of vertices in this super cluster - + UINT uFaceStart; // initial index into face array UINT uFaceLength; // number of faces in this super cluster - + UINT uClusterStart; // initial index into cluster array UINT uClusterLength; // number of clusters in this super cluster } D3DXSHPRTSPLITMESHCLUSTERDATA; @@ -1601,19 +1601,19 @@ typedef HRESULT (WINAPI *LPD3DXSHPRTSIMCB)(float fPercentDone, LPVOID lpUserCon // GUIDs // {F1827E47-00A8-49cd-908C-9D11955F8728} -DEFINE_GUID(IID_ID3DXPRTBuffer, +DEFINE_GUID(IID_ID3DXPRTBuffer, 0xf1827e47, 0xa8, 0x49cd, 0x90, 0x8c, 0x9d, 0x11, 0x95, 0x5f, 0x87, 0x28); // {A758D465-FE8D-45ad-9CF0-D01E56266A07} -DEFINE_GUID(IID_ID3DXPRTCompBuffer, +DEFINE_GUID(IID_ID3DXPRTCompBuffer, 0xa758d465, 0xfe8d, 0x45ad, 0x9c, 0xf0, 0xd0, 0x1e, 0x56, 0x26, 0x6a, 0x7); // {838F01EC-9729-4527-AADB-DF70ADE7FEA9} -DEFINE_GUID(IID_ID3DXTextureGutterHelper, +DEFINE_GUID(IID_ID3DXTextureGutterHelper, 0x838f01ec, 0x9729, 0x4527, 0xaa, 0xdb, 0xdf, 0x70, 0xad, 0xe7, 0xfe, 0xa9); // {683A4278-CD5F-4d24-90AD-C4E1B6855D53} -DEFINE_GUID(IID_ID3DXPRTEngine, +DEFINE_GUID(IID_ID3DXPRTEngine, 0x683a4278, 0xcd5f, 0x4d24, 0x90, 0xad, 0xc4, 0xe1, 0xb6, 0x85, 0x5d, 0x53); // interface defenitions @@ -1654,26 +1654,26 @@ DECLARE_INTERFACE_(ID3DXPRTBuffer, IUnknown) // every scalar in buffer is multiplied by Scale STDMETHOD(ScaleBuffer)(THIS_ FLOAT Scale) PURE; - + // every scalar contains the sum of this and pBuffers values - // pBuffer must have the same storage class/dimensions + // pBuffer must have the same storage class/dimensions STDMETHOD(AddBuffer)(THIS_ LPD3DXPRTBUFFER pBuffer) PURE; // GutterHelper (described below) will fill in the gutter // regions of a texture by interpolating "internal" values STDMETHOD(AttachGH)(THIS_ LPD3DXTEXTUREGUTTERHELPER) PURE; STDMETHOD(ReleaseGH)(THIS) PURE; - + // Evaluates attached gutter helper on the contents of this buffer STDMETHOD(EvalGH)(THIS) PURE; // extracts a given channel into texture pTexture // NumCoefficients starting from StartCoefficient are copied - STDMETHOD(ExtractTexture)(THIS_ UINT Channel, UINT StartCoefficient, + STDMETHOD(ExtractTexture)(THIS_ UINT Channel, UINT StartCoefficient, UINT NumCoefficients, LPDIRECT3DTEXTURE9 pTexture) PURE; // extracts NumCoefficients coefficients into mesh - only applicable on single channel - // buffers, otherwise just lockbuffer and copy data. With SHPRT data NumCoefficients + // buffers, otherwise just lockbuffer and copy data. With SHPRT data NumCoefficients // should be Order^2 STDMETHOD(ExtractToMesh)(THIS_ UINT NumCoefficients, D3DDECLUSAGE Usage, UINT UsageIndexStart, LPD3DXMESH pScene) PURE; @@ -1717,19 +1717,19 @@ DECLARE_INTERFACE_(ID3DXPRTCompBuffer, IUnknown) // copies basis vectors for cluster "Cluster" into pClusterBasis // (NumPCA+1)*NumCoeffs*NumChannels floats STDMETHOD(ExtractBasis)(THIS_ UINT Cluster, FLOAT *pClusterBasis) PURE; - + // UINT per sample - which cluster it belongs to STDMETHOD(ExtractClusterIDs)(THIS_ UINT *pClusterIDs) PURE; - + // copies NumExtract PCA projection coefficients starting at StartPCA // into pPCACoefficients - NumSamples*NumExtract floats copied STDMETHOD(ExtractPCA)(THIS_ UINT StartPCA, UINT NumExtract, FLOAT *pPCACoefficients) PURE; // copies NumPCA projection coefficients starting at StartPCA // into pTexture - should be able to cope with signed formats - STDMETHOD(ExtractTexture)(THIS_ UINT StartPCA, UINT NumpPCA, + STDMETHOD(ExtractTexture)(THIS_ UINT StartPCA, UINT NumpPCA, LPDIRECT3DTEXTURE9 pTexture) PURE; - + // copies NumPCA projection coefficients into mesh pScene // Usage is D3DDECLUSAGE where coefficients are to be stored // UsageIndexStart is starting index @@ -1767,7 +1767,7 @@ DECLARE_INTERFACE_(ID3DXTextureGutterHelper, IUnknown) STDMETHOD_(ULONG, Release)(THIS) PURE; // ID3DXTextureGutterHelper - + // dimensions of texture this is bound too STDMETHOD_(UINT, GetWidth)(THIS) PURE; STDMETHOD_(UINT, GetHeight)(THIS) PURE; @@ -1775,19 +1775,19 @@ DECLARE_INTERFACE_(ID3DXTextureGutterHelper, IUnknown) // Applying gutters recomputes all of the gutter texels of class "2" // based on texels of class "1" or "4" - + // Applies gutters to a raw float buffer - each texel is NumCoeffs floats // Width and Height must match GutterHelper STDMETHOD(ApplyGuttersFloat)(THIS_ FLOAT *pDataIn, UINT NumCoeffs, UINT Width, UINT Height); - + // Applies gutters to pTexture // Dimensions must match GutterHelper STDMETHOD(ApplyGuttersTex)(THIS_ LPDIRECT3DTEXTURE9 pTexture); - + // Applies gutters to a D3DXPRTBuffer // Dimensions must match GutterHelper STDMETHOD(ApplyGuttersPRT)(THIS_ LPD3DXPRTBUFFER pBuffer); - + // Resamples a texture from a mesh onto this gutterhelpers // parameterization. It is assumed that the UV coordinates // for this gutter helper are in TEXTURE 0 (usage/usage index) @@ -1802,63 +1802,63 @@ DECLARE_INTERFACE_(ID3DXTextureGutterHelper, IUnknown) // for pTextureIn // UsageIndex - which index for Usage above for pTextureIn // pTextureOut- Resampled texture - // + // // Usage would generally be D3DDECLUSAGE_TEXCOORD and UsageIndex other than zero STDMETHOD(ResampleTex)(THIS_ LPDIRECT3DTEXTURE9 pTextureIn, LPD3DXMESH pMeshIn, D3DDECLUSAGE Usage, UINT UsageIndex, - LPDIRECT3DTEXTURE9 pTextureOut); - + LPDIRECT3DTEXTURE9 pTextureOut); + // the routines below provide access to the data structures // used by the Apply functions // face map is a UINT per texel that represents the - // face of the mesh that texel belongs too - + // face of the mesh that texel belongs too - // only valid if same texel is valid in pGutterData // pFaceData must be allocated by the user STDMETHOD(GetFaceMap)(THIS_ UINT *pFaceData) PURE; - + // BaryMap is a D3DXVECTOR2 per texel // the 1st two barycentric coordinates for the corresponding // face (3rd weight is always 1-sum of first two) // only valid if same texel is valid in pGutterData // pBaryData must be allocated by the user STDMETHOD(GetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; - + // TexelMap is a D3DXVECTOR2 per texel that // stores the location in pixel coordinates where the // corresponding texel is mapped // pTexelData must be allocated by the user STDMETHOD(GetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; - + // GutterMap is a BYTE per texel // 0/1/2 for Invalid/Internal/Gutter texels // 4 represents a gutter texel that will be computed // during PRT // pGutterData must be allocated by the user STDMETHOD(GetGutterMap)(THIS_ BYTE *pGutterData) PURE; - + // face map is a UINT per texel that represents the - // face of the mesh that texel belongs too - + // face of the mesh that texel belongs too - // only valid if same texel is valid in pGutterData STDMETHOD(SetFaceMap)(THIS_ UINT *pFaceData) PURE; - + // BaryMap is a D3DXVECTOR2 per texel // the 1st two barycentric coordinates for the corresponding // face (3rd weight is always 1-sum of first two) // only valid if same texel is valid in pGutterData STDMETHOD(SetBaryMap)(THIS_ D3DXVECTOR2 *pBaryData) PURE; - + // TexelMap is a D3DXVECTOR2 per texel that // stores the location in pixel coordinates where the // corresponding texel is mapped STDMETHOD(SetTexelMap)(THIS_ D3DXVECTOR2 *pTexelData) PURE; - + // GutterMap is a BYTE per texel // 0/1/2 for Invalid/Internal/Gutter texels // 4 represents a gutter texel that will be computed // during PRT - STDMETHOD(SetGutterMap)(THIS_ BYTE *pGutterData) PURE; + STDMETHOD(SetGutterMap)(THIS_ BYTE *pGutterData) PURE; }; @@ -1895,7 +1895,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) STDMETHOD_(ULONG, Release)(THIS) PURE; // ID3DXPRTEngine - + // This sets a material per attribute in the scene mesh and it is // the only way to specify subsurface scattering parameters. if // bSetAlbedo is FALSE, NumChannels must match the current @@ -1909,53 +1909,53 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // albedo that might have been set before. FALSE won't clobber. // fLengthScale is used for subsurface scattering - scene is mapped into a 1mm unit cube // and scaled by this amount - STDMETHOD(SetMeshMaterials)(THIS_ CONST D3DXSHMATERIAL **ppMaterials, UINT NumMeshes, + STDMETHOD(SetMeshMaterials)(THIS_ CONST D3DXSHMATERIAL **ppMaterials, UINT NumMeshes, UINT NumChannels, BOOL bSetAlbedo, FLOAT fLengthScale) PURE; - + // setting albedo per-vertex or per-texel over rides the albedos stored per mesh // but it does not over ride any other settings - + // sets an albedo to be used per vertex - the albedo is represented as a float // pDataIn input pointer (pointint to albedo of 1st sample) // NumChannels 1 implies "grayscale" materials, set this to 3 to enable // color bleeding effects // Stride - stride in bytes to get to next samples albedo STDMETHOD(SetPerVertexAlbedo)(THIS_ CONST VOID *pDataIn, UINT NumChannels, UINT Stride) PURE; - + // represents the albedo per-texel instead of per-vertex (even if per-vertex PRT is used) // pAlbedoTexture - texture that stores the albedo (dimension arbitrary) // NumChannels 1 implies "grayscale" materials, set this to 3 to enable // color bleeding effects // pGH - optional gutter helper, otherwise one is constructed in computation routines and // destroyed (if not attached to buffers) - STDMETHOD(SetPerTexelAlbedo)(THIS_ LPDIRECT3DTEXTURE9 pAlbedoTexture, - UINT NumChannels, + STDMETHOD(SetPerTexelAlbedo)(THIS_ LPDIRECT3DTEXTURE9 pAlbedoTexture, + UINT NumChannels, LPD3DXTEXTUREGUTTERHELPER pGH) PURE; - + // gets the per-vertex albedo - STDMETHOD(GetVertexAlbedo)(THIS_ D3DXCOLOR *pVertColors, UINT NumVerts) PURE; - + STDMETHOD(GetVertexAlbedo)(THIS_ D3DXCOLOR *pVertColors, UINT NumVerts) PURE; + // If pixel PRT is being computed normals default to ones that are interpolated // from the vertex normals. This specifies a texture that stores an object // space normal map instead (must use a texture format that can represent signed values) - // pNormalTexture - normal map, must be same dimensions as PRTBuffers, signed + // pNormalTexture - normal map, must be same dimensions as PRTBuffers, signed STDMETHOD(SetPerTexelNormal)(THIS_ LPDIRECT3DTEXTURE9 pNormalTexture) PURE; - + // Copies per-vertex albedo from mesh // pMesh - mesh that represents the scene. It must have the same // properties as the mesh used to create the PRTEngine // Usage - D3DDECLUSAGE to extract albedos from // NumChannels 1 implies "grayscale" materials, set this to 3 to enable // color bleeding effects - STDMETHOD(ExtractPerVertexAlbedo)(THIS_ LPD3DXMESH pMesh, - D3DDECLUSAGE Usage, + STDMETHOD(ExtractPerVertexAlbedo)(THIS_ LPD3DXMESH pMesh, + D3DDECLUSAGE Usage, UINT NumChannels) PURE; // Resamples the input buffer into the output buffer // can be used to move between per-vertex and per-texel buffers. This can also be used // to convert single channel buffers to 3-channel buffers and vice-versa. STDMETHOD(ResampleBuffer)(THIS_ LPD3DXPRTBUFFER pBufferIn, LPD3DXPRTBUFFER pBufferOut) PURE; - + // Returns the scene mesh - including modifications from adaptive spatial sampling // The returned mesh only has positions, normals and texture coordinates (if defined) // pD3DDevice - d3d device that will be used to allocate the mesh @@ -1998,10 +1998,10 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // Adaptive - if TRUE adaptive sampling (angular) is used // AdaptiveThresh - threshold used to terminate adaptive angular sampling // ignored if adaptive sampling is not set - STDMETHOD(SetSamplingInfo)(THIS_ UINT NumRays, - BOOL UseSphere, - BOOL UseCosine, - BOOL Adaptive, + STDMETHOD(SetSamplingInfo)(THIS_ UINT NumRays, + BOOL UseSphere, + BOOL UseCosine, + BOOL Adaptive, FLOAT AdaptiveThresh) PURE; // Methods that compute the direct lighting contribution for objects @@ -2011,9 +2011,9 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // // SHOrder - order of SH to use // pDataOut - PRT buffer that is generated. Can be single channel - STDMETHOD(ComputeDirectLightingSH)(THIS_ UINT SHOrder, + STDMETHOD(ComputeDirectLightingSH)(THIS_ UINT SHOrder, LPD3DXPRTBUFFER pDataOut) PURE; - + // Adaptive variant of above function. This will refine the mesh // generating new vertices/faces to approximate the PRT signal // more faithfully. @@ -2023,15 +2023,15 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // MinEdgeLength - minimum edge length that will be generated // if value is too small a fairly conservative model dependent value // is used - // MaxSubdiv - maximum subdivision level, if 0 is specified it + // MaxSubdiv - maximum subdivision level, if 0 is specified it // will default to 4 // pDataOut - PRT buffer that is generated. Can be single channel. - STDMETHOD(ComputeDirectLightingSHAdaptive)(THIS_ UINT SHOrder, + STDMETHOD(ComputeDirectLightingSHAdaptive)(THIS_ UINT SHOrder, FLOAT AdaptiveThresh, FLOAT MinEdgeLength, UINT MaxSubdiv, LPD3DXPRTBUFFER pDataOut) PURE; - + // Function that computes the direct lighting contribution for objects // light is always represented using spherical harmonics (SH) // This is done on the GPU and is much faster then using the CPU. @@ -2068,7 +2068,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // pDataIn - input data (previous bounce) // pDataOut - result of subsurface scattering simulation // pDataTotal - [optional] results can be summed into this buffer - STDMETHOD(ComputeSS)(THIS_ LPD3DXPRTBUFFER pDataIn, + STDMETHOD(ComputeSS)(THIS_ LPD3DXPRTBUFFER pDataIn, LPD3DXPRTBUFFER pDataOut, LPD3DXPRTBUFFER pDataTotal) PURE; // Adaptive version of ComputeSS. @@ -2079,11 +2079,11 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // MinEdgeLength - minimum edge length that will be generated // if value is too small a fairly conservative model dependent value // is used - // MaxSubdiv - maximum subdivision level, if 0 is specified it - // will default to 4 + // MaxSubdiv - maximum subdivision level, if 0 is specified it + // will default to 4 // pDataOut - result of subsurface scattering simulation // pDataTotal - [optional] results can be summed into this buffer - STDMETHOD(ComputeSSAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, + STDMETHOD(ComputeSSAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, FLOAT AdaptiveThresh, FLOAT MinEdgeLength, UINT MaxSubdiv, @@ -2093,7 +2093,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // works for SH based PRT or generic lighting // Albedo is not multiplied by result // - // pDataIn - previous bounces data + // pDataIn - previous bounces data // pDataOut - PRT buffer that is generated // pDataTotal - [optional] can be used to keep a running sum STDMETHOD(ComputeBounce)(THIS_ LPD3DXPRTBUFFER pDataIn, @@ -2102,16 +2102,16 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // Adaptive version of above function. // - // pDataIn - previous bounces data, can be single channel + // pDataIn - previous bounces data, can be single channel // AdaptiveThresh - threshold for adaptive subdivision (in PRT vector error) // if value is less then 1e-6f, 1e-6f is specified // MinEdgeLength - minimum edge length that will be generated // if value is too small a fairly conservative model dependent value // is used - // MaxSubdiv - maximum subdivision level, if 0 is specified it + // MaxSubdiv - maximum subdivision level, if 0 is specified it // will default to 4 // pDataOut - PRT buffer that is generated - // pDataTotal - [optional] can be used to keep a running sum + // pDataTotal - [optional] can be used to keep a running sum STDMETHOD(ComputeBounceAdaptive)(THIS_ LPD3DXPRTBUFFER pDataIn, FLOAT AdaptiveThresh, FLOAT MinEdgeLength, @@ -2120,7 +2120,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) LPD3DXPRTBUFFER pDataTotal) PURE; // Computes projection of distant SH radiance into a local SH radiance - // function. This models how direct lighting is attenuated by the + // function. This models how direct lighting is attenuated by the // scene and is a form of "neighborhood transfer." The result is // a linear operator (matrix) at every sample point, if you multiply // this matrix by the distant SH lighting coefficients you get an @@ -2129,24 +2129,24 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // than be projected into another basis or used with any rendering // technique that uses spherical harmonics as input. // SetSamplingInfo must be called with TRUE for UseSphere and - // FALSE for UseCosine before this method is called. - // Generates SHOrderIn*SHOrderIn*SHOrderOut*SHOrderOut scalars + // FALSE for UseCosine before this method is called. + // Generates SHOrderIn*SHOrderIn*SHOrderOut*SHOrderOut scalars // per channel at each sample location. // // SHOrderIn - Order of the SH representation of distant lighting // SHOrderOut - Order of the SH representation of local lighting // NumVolSamples - Number of sample locations // pSampleLocs - position of sample locations - // pDataOut - PRT Buffer that will store output results - STDMETHOD(ComputeVolumeSamplesDirectSH)(THIS_ UINT SHOrderIn, - UINT SHOrderOut, + // pDataOut - PRT Buffer that will store output results + STDMETHOD(ComputeVolumeSamplesDirectSH)(THIS_ UINT SHOrderIn, + UINT SHOrderOut, UINT NumVolSamples, CONST D3DXVECTOR3 *pSampleLocs, LPD3DXPRTBUFFER pDataOut) PURE; - + // At each sample location computes a linear operator (matrix) that maps // the representation of source radiance (NumCoeffs in pSurfDataIn) - // into a local incident radiance function approximated with spherical + // into a local incident radiance function approximated with spherical // harmonics. For example if a light map data is specified in pSurfDataIn // the result is an SH representation of the flow of light at each sample // point. If PRT data for an outdoor scene is used, each sample point @@ -2155,7 +2155,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // ComputeVolumeSamplesDirectSH this gives the complete representation for // how light arrives at each sample point parameterized by distant lighting. // SetSamplingInfo must be called with TRUE for UseSphere and - // FALSE for UseCosine before this method is called. + // FALSE for UseCosine before this method is called. // Generates pSurfDataIn->NumCoeffs()*SHOrder*SHOrder scalars // per channel at each sample location. // @@ -2164,8 +2164,8 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // NumVolSamples - Number of sample locations // pSampleLocs - position of sample locations // pDataOut - PRT Buffer that will store output results - STDMETHOD(ComputeVolumeSamples)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, - UINT SHOrder, + STDMETHOD(ComputeVolumeSamples)(THIS_ LPD3DXPRTBUFFER pSurfDataIn, + UINT SHOrder, UINT NumVolSamples, CONST D3DXVECTOR3 *pSampleLocs, LPD3DXPRTBUFFER pDataOut) PURE; @@ -2185,7 +2185,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) LPD3DXPRTBUFFER pDataOut) PURE; - // given the solution for PRT or light maps, computes transfer vector at arbitrary + // given the solution for PRT or light maps, computes transfer vector at arbitrary // position/normal pairs in space // // pSurfDataIn - input data @@ -2204,21 +2204,21 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // Frees temporary data structures that can be created for subsurface scattering // this data is freed when the PRTComputeEngine is freed and is lazily created STDMETHOD(FreeSSData)(THIS) PURE; - + // Frees temporary data structures that can be created for bounce simulations // this data is freed when the PRTComputeEngine is freed and is lazily created STDMETHOD(FreeBounceData)(THIS) PURE; - // This computes the Local Deformable PRT (LDPRT) coefficients relative to the - // per sample normals that minimize error in a least squares sense with respect - // to the input PRT data set. These coefficients can be used with skinned/transformed - // normals to model global effects with dynamic objects. Shading normals can + // This computes the Local Deformable PRT (LDPRT) coefficients relative to the + // per sample normals that minimize error in a least squares sense with respect + // to the input PRT data set. These coefficients can be used with skinned/transformed + // normals to model global effects with dynamic objects. Shading normals can // optionally be solved for - these normals (along with the LDPRT coefficients) can // more accurately represent the PRT signal. The coefficients are for zonal // harmonics oriented in the normal/shading normal direction. // // pDataIn - SH PRT dataset that is input - // SHOrder - Order of SH to compute conv coefficients for + // SHOrder - Order of SH to compute conv coefficients for // pNormOut - Optional array of vectors (passed in) that will be filled with // "shading normals", LDPRT coefficients are optimized for // these normals. This array must be the same size as the number of @@ -2233,7 +2233,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // can be useful when using subsurface scattering // fScale - value to scale each vector in submesh by STDMETHOD(ScaleMeshChunk)(THIS_ UINT uMeshChunk, FLOAT fScale, LPD3DXPRTBUFFER pDataOut) PURE; - + // mutliplies each PRT vector by the albedo - can be used if you want to have the albedo // burned into the dataset, often better not to do this. If this is not done the user // must mutliply the albedo themselves when rendering - just multiply the albedo times @@ -2245,7 +2245,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // // pDataOut - dataset that will get albedo pushed into it STDMETHOD(MultiplyAlbedo)(THIS_ LPD3DXPRTBUFFER pDataOut) PURE; - + // Sets a pointer to an optional call back function that reports back to the // user percentage done and gives them the option of quitting // pCB - pointer to call back function, return S_OK for the simulation @@ -2254,16 +2254,16 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // will be invoked // lpUserContext - will be passed back to the users call back STDMETHOD(SetCallBack)(THIS_ LPD3DXSHPRTSIMCB pCB, FLOAT Frequency, LPVOID lpUserContext) PURE; - + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. This function // takes into account settings from SetMinMaxIntersection. If the closest intersection // is not needed this function is more efficient compared to the ClosestRayIntersection // method. // pRayPos - origin of ray // pRayDir - normalized ray direction (normalization required for SetMinMax to be meaningful) - + STDMETHOD_(BOOL, ShadowRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir) PURE; - + // Returns TRUE if the ray intersects the mesh, FALSE if it does not. If there is an // intersection the closest face that was intersected and its first two barycentric coordinates // are returned. This function takes into account settings from SetMinMaxIntersection. @@ -2276,7 +2276,7 @@ DECLARE_INTERFACE_(ID3DXPRTEngine, IUnknown) // pU - Barycentric coordinate for vertex 0 // pV - Barycentric coordinate for vertex 1 // pDist - Distance along ray where the intersection occured - + STDMETHOD_(BOOL, ClosestRayIntersects)(THIS_ CONST D3DXVECTOR3 *pRayPos, CONST D3DXVECTOR3 *pRayDir, DWORD *pFaceIndex, FLOAT *pU, FLOAT *pV, FLOAT *pDist) PURE; }; @@ -2308,8 +2308,8 @@ extern "C" { // //============================================================================ -HRESULT WINAPI - D3DXCreatePRTBuffer( +HRESULT WINAPI + D3DXCreatePRTBuffer( UINT NumSamples, UINT NumCoeffs, UINT NumChannels, @@ -2338,7 +2338,7 @@ HRESULT WINAPI //============================================================================ HRESULT WINAPI - D3DXCreatePRTBufferTex( + D3DXCreatePRTBufferTex( UINT Width, UINT Height, UINT NumCoeffs, @@ -2361,12 +2361,12 @@ HRESULT WINAPI HRESULT WINAPI D3DXLoadPRTBufferFromFileA( - LPCSTR pFilename, + LPCSTR pFilename, LPD3DXPRTBUFFER* ppBuffer); - + HRESULT WINAPI D3DXLoadPRTBufferFromFileW( - LPCWSTR pFilename, + LPCWSTR pFilename, LPD3DXPRTBUFFER* ppBuffer); #ifdef UNICODE @@ -2394,7 +2394,7 @@ HRESULT WINAPI D3DXSavePRTBufferToFileA( LPCSTR pFileName, LPD3DXPRTBUFFER pBuffer); - + HRESULT WINAPI D3DXSavePRTBufferToFileW( LPCWSTR pFileName, @@ -2404,7 +2404,7 @@ HRESULT WINAPI #define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileW #else #define D3DXSavePRTBufferToFile D3DXSavePRTBufferToFileA -#endif +#endif //============================================================================ @@ -2423,12 +2423,12 @@ HRESULT WINAPI HRESULT WINAPI D3DXLoadPRTCompBufferFromFileA( - LPCSTR pFilename, + LPCSTR pFilename, LPD3DXPRTCOMPBUFFER* ppBuffer); - + HRESULT WINAPI D3DXLoadPRTCompBufferFromFileW( - LPCWSTR pFilename, + LPCWSTR pFilename, LPD3DXPRTCOMPBUFFER* ppBuffer); #ifdef UNICODE @@ -2455,7 +2455,7 @@ HRESULT WINAPI D3DXSavePRTCompBufferToFileA( LPCSTR pFileName, LPD3DXPRTCOMPBUFFER pBuffer); - + HRESULT WINAPI D3DXSavePRTCompBufferToFileW( LPCWSTR pFileName, @@ -2465,7 +2465,7 @@ HRESULT WINAPI #define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileW #else #define D3DXSavePRTCompBufferToFile D3DXSavePRTCompBufferToFileA -#endif +#endif //============================================================================ // @@ -2496,10 +2496,10 @@ HRESULT WINAPI HRESULT WINAPI D3DXCreatePRTCompBuffer( D3DXSHCOMPRESSQUALITYTYPE Quality, - UINT NumClusters, + UINT NumClusters, UINT NumPCA, LPD3DXSHPRTSIMCB pCB, - LPVOID lpUserContext, + LPVOID lpUserContext, LPD3DXPRTBUFFER pBufferIn, LPD3DXPRTCOMPBUFFER *ppBufferOut ); @@ -2527,11 +2527,11 @@ HRESULT WINAPI //============================================================================ -HRESULT WINAPI - D3DXCreateTextureGutterHelper( +HRESULT WINAPI + D3DXCreateTextureGutterHelper( UINT Width, UINT Height, - LPD3DXMESH pMesh, + LPD3DXMESH pMesh, FLOAT GutterSize, LPD3DXTEXTUREGUTTERHELPER* ppBuffer); @@ -2560,12 +2560,12 @@ HRESULT WINAPI //============================================================================ -HRESULT WINAPI - D3DXCreatePRTEngine( +HRESULT WINAPI + D3DXCreatePRTEngine( LPD3DXMESH pMesh, DWORD *pAdjacency, BOOL ExtractUVs, - LPD3DXMESH pBlockerMesh, + LPD3DXMESH pBlockerMesh, LPD3DXPRTENGINE* ppEngine); //============================================================================ @@ -2602,15 +2602,15 @@ HRESULT WINAPI //============================================================================ -HRESULT WINAPI +HRESULT WINAPI D3DXConcatenateMeshes( - LPD3DXMESH *ppMeshes, - UINT NumMeshes, - DWORD Options, - CONST D3DXMATRIX *pGeomXForms, - CONST D3DXMATRIX *pTextureXForms, + LPD3DXMESH *ppMeshes, + UINT NumMeshes, + DWORD Options, + CONST D3DXMATRIX *pGeomXForms, + CONST D3DXMATRIX *pTextureXForms, CONST D3DVERTEXELEMENT9 *pDecl, - LPDIRECT3DDEVICE9 pD3DDevice, + LPDIRECT3DDEVICE9 pD3DDevice, LPD3DXMESH *ppMeshOut); //============================================================================ @@ -2636,16 +2636,16 @@ HRESULT WINAPI // that corresponding cluster was assigned to // pNumSuperClusters // Returns the number of super clusters allocated -// +// //============================================================================ -HRESULT WINAPI +HRESULT WINAPI D3DXSHPRTCompSuperCluster( - UINT *pClusterIDs, - LPD3DXMESH pScene, - UINT MaxNumClusters, + UINT *pClusterIDs, + LPD3DXMESH pScene, + UINT MaxNumClusters, UINT NumClusters, - UINT *pSuperClusterIDs, + UINT *pSuperClusterIDs, UINT *pNumSuperClusters); //============================================================================ @@ -2657,7 +2657,7 @@ HRESULT WINAPI // to split the mesh into a group of faces/vertices per super cluster. // Each super cluster contains all of the faces that contain any vertex // classified in one of its clusters. All of the vertices connected to this -// set of faces are also included with the returned array ppVertStatus +// set of faces are also included with the returned array ppVertStatus // indicating whether or not the vertex belongs to the supercluster. // // Parameters: @@ -2680,12 +2680,12 @@ HRESULT WINAPI // NumFaces // Number of faces in the original mesh (pInputIB is 3 times this length) // ppIBData -// LPD3DXBUFFER holds raw index buffer that will contain the resulting split faces. +// LPD3DXBUFFER holds raw index buffer that will contain the resulting split faces. // Format determined by bIBIs32Bit. Allocated by function // pIBDataLength // Length of ppIBData, assigned in function // OutputIBIs32Bit -// Indicates whether the output index buffer is to be 32-bit (otherwise +// Indicates whether the output index buffer is to be 32-bit (otherwise // 16-bit is assumed) // ppFaceRemap // LPD3DXBUFFER mapping of each face in ppIBData to original faces. Length is @@ -2703,33 +2703,33 @@ HRESULT WINAPI // //============================================================================ -HRESULT WINAPI +HRESULT WINAPI D3DXSHPRTCompSplitMeshSC( - UINT *pClusterIDs, - UINT NumVertices, - UINT NumClusters, - UINT *pSuperClusterIDs, + UINT *pClusterIDs, + UINT NumVertices, + UINT NumClusters, + UINT *pSuperClusterIDs, UINT NumSuperClusters, - LPVOID pInputIB, - BOOL InputIBIs32Bit, + LPVOID pInputIB, + BOOL InputIBIs32Bit, UINT NumFaces, - LPD3DXBUFFER *ppIBData, - UINT *pIBDataLength, - BOOL OutputIBIs32Bit, - LPD3DXBUFFER *ppFaceRemap, - LPD3DXBUFFER *ppVertData, - UINT *pVertDataLength, + LPD3DXBUFFER *ppIBData, + UINT *pIBDataLength, + BOOL OutputIBIs32Bit, + LPD3DXBUFFER *ppFaceRemap, + LPD3DXBUFFER *ppVertData, + UINT *pVertDataLength, UINT *pSCClusterList, D3DXSHPRTSPLITMESHCLUSTERDATA *pSCData); - - + + #ifdef __cplusplus } #endif //__cplusplus ////////////////////////////////////////////////////////////////////////////// // -// Definitions of .X file templates used by mesh load/save functions +// Definitions of .X file templates used by mesh load/save functions // that are not RM standard // ////////////////////////////////////////////////////////////////////////////// @@ -2739,35 +2739,35 @@ DEFINE_GUID(DXFILEOBJ_XSkinMeshHeader, 0x3cf169ce, 0xff7c, 0x44ab, 0x93, 0xc0, 0xf7, 0x8f, 0x62, 0xd1, 0x72, 0xe2); // {B8D65549-D7C9-4995-89CF-53A9A8B031E3} -DEFINE_GUID(DXFILEOBJ_VertexDuplicationIndices, +DEFINE_GUID(DXFILEOBJ_VertexDuplicationIndices, 0xb8d65549, 0xd7c9, 0x4995, 0x89, 0xcf, 0x53, 0xa9, 0xa8, 0xb0, 0x31, 0xe3); // {A64C844A-E282-4756-8B80-250CDE04398C} -DEFINE_GUID(DXFILEOBJ_FaceAdjacency, +DEFINE_GUID(DXFILEOBJ_FaceAdjacency, 0xa64c844a, 0xe282, 0x4756, 0x8b, 0x80, 0x25, 0xc, 0xde, 0x4, 0x39, 0x8c); // {6F0D123B-BAD2-4167-A0D0-80224F25FABB} -DEFINE_GUID(DXFILEOBJ_SkinWeights, +DEFINE_GUID(DXFILEOBJ_SkinWeights, 0x6f0d123b, 0xbad2, 0x4167, 0xa0, 0xd0, 0x80, 0x22, 0x4f, 0x25, 0xfa, 0xbb); // {A3EB5D44-FC22-429d-9AFB-3221CB9719A6} -DEFINE_GUID(DXFILEOBJ_Patch, +DEFINE_GUID(DXFILEOBJ_Patch, 0xa3eb5d44, 0xfc22, 0x429d, 0x9a, 0xfb, 0x32, 0x21, 0xcb, 0x97, 0x19, 0xa6); // {D02C95CC-EDBA-4305-9B5D-1820D7704BBF} -DEFINE_GUID(DXFILEOBJ_PatchMesh, +DEFINE_GUID(DXFILEOBJ_PatchMesh, 0xd02c95cc, 0xedba, 0x4305, 0x9b, 0x5d, 0x18, 0x20, 0xd7, 0x70, 0x4b, 0xbf); // {B9EC94E1-B9A6-4251-BA18-94893F02C0EA} -DEFINE_GUID(DXFILEOBJ_PatchMesh9, +DEFINE_GUID(DXFILEOBJ_PatchMesh9, 0xb9ec94e1, 0xb9a6, 0x4251, 0xba, 0x18, 0x94, 0x89, 0x3f, 0x2, 0xc0, 0xea); // {B6C3E656-EC8B-4b92-9B62-681659522947} -DEFINE_GUID(DXFILEOBJ_PMInfo, +DEFINE_GUID(DXFILEOBJ_PMInfo, 0xb6c3e656, 0xec8b, 0x4b92, 0x9b, 0x62, 0x68, 0x16, 0x59, 0x52, 0x29, 0x47); // {917E0427-C61E-4a14-9C64-AFE65F9E9844} -DEFINE_GUID(DXFILEOBJ_PMAttributeRange, +DEFINE_GUID(DXFILEOBJ_PMAttributeRange, 0x917e0427, 0xc61e, 0x4a14, 0x9c, 0x64, 0xaf, 0xe6, 0x5f, 0x9e, 0x98, 0x44); // {574CCC14-F0B3-4333-822D-93E8A8A08E4C} @@ -2775,35 +2775,35 @@ DEFINE_GUID(DXFILEOBJ_PMVSplitRecord, 0x574ccc14, 0xf0b3, 0x4333, 0x82, 0x2d, 0x93, 0xe8, 0xa8, 0xa0, 0x8e, 0x4c); // {B6E70A0E-8EF9-4e83-94AD-ECC8B0C04897} -DEFINE_GUID(DXFILEOBJ_FVFData, +DEFINE_GUID(DXFILEOBJ_FVFData, 0xb6e70a0e, 0x8ef9, 0x4e83, 0x94, 0xad, 0xec, 0xc8, 0xb0, 0xc0, 0x48, 0x97); // {F752461C-1E23-48f6-B9F8-8350850F336F} -DEFINE_GUID(DXFILEOBJ_VertexElement, +DEFINE_GUID(DXFILEOBJ_VertexElement, 0xf752461c, 0x1e23, 0x48f6, 0xb9, 0xf8, 0x83, 0x50, 0x85, 0xf, 0x33, 0x6f); // {BF22E553-292C-4781-9FEA-62BD554BDD93} -DEFINE_GUID(DXFILEOBJ_DeclData, +DEFINE_GUID(DXFILEOBJ_DeclData, 0xbf22e553, 0x292c, 0x4781, 0x9f, 0xea, 0x62, 0xbd, 0x55, 0x4b, 0xdd, 0x93); // {F1CFE2B3-0DE3-4e28-AFA1-155A750A282D} -DEFINE_GUID(DXFILEOBJ_EffectFloats, +DEFINE_GUID(DXFILEOBJ_EffectFloats, 0xf1cfe2b3, 0xde3, 0x4e28, 0xaf, 0xa1, 0x15, 0x5a, 0x75, 0xa, 0x28, 0x2d); // {D55B097E-BDB6-4c52-B03D-6051C89D0E42} -DEFINE_GUID(DXFILEOBJ_EffectString, +DEFINE_GUID(DXFILEOBJ_EffectString, 0xd55b097e, 0xbdb6, 0x4c52, 0xb0, 0x3d, 0x60, 0x51, 0xc8, 0x9d, 0xe, 0x42); // {622C0ED0-956E-4da9-908A-2AF94F3CE716} -DEFINE_GUID(DXFILEOBJ_EffectDWord, +DEFINE_GUID(DXFILEOBJ_EffectDWord, 0x622c0ed0, 0x956e, 0x4da9, 0x90, 0x8a, 0x2a, 0xf9, 0x4f, 0x3c, 0xe7, 0x16); // {3014B9A0-62F5-478c-9B86-E4AC9F4E418B} -DEFINE_GUID(DXFILEOBJ_EffectParamFloats, +DEFINE_GUID(DXFILEOBJ_EffectParamFloats, 0x3014b9a0, 0x62f5, 0x478c, 0x9b, 0x86, 0xe4, 0xac, 0x9f, 0x4e, 0x41, 0x8b); // {1DBC4C88-94C1-46ee-9076-2C28818C9481} -DEFINE_GUID(DXFILEOBJ_EffectParamString, +DEFINE_GUID(DXFILEOBJ_EffectParamString, 0x1dbc4c88, 0x94c1, 0x46ee, 0x90, 0x76, 0x2c, 0x28, 0x81, 0x8c, 0x94, 0x81); // {E13963BC-AE51-4c5d-B00F-CFA3A9D97CE5} @@ -2811,15 +2811,15 @@ DEFINE_GUID(DXFILEOBJ_EffectParamDWord, 0xe13963bc, 0xae51, 0x4c5d, 0xb0, 0xf, 0xcf, 0xa3, 0xa9, 0xd9, 0x7c, 0xe5); // {E331F7E4-0559-4cc2-8E99-1CEC1657928F} -DEFINE_GUID(DXFILEOBJ_EffectInstance, +DEFINE_GUID(DXFILEOBJ_EffectInstance, 0xe331f7e4, 0x559, 0x4cc2, 0x8e, 0x99, 0x1c, 0xec, 0x16, 0x57, 0x92, 0x8f); // {9E415A43-7BA6-4a73-8743-B73D47E88476} -DEFINE_GUID(DXFILEOBJ_AnimTicksPerSecond, +DEFINE_GUID(DXFILEOBJ_AnimTicksPerSecond, 0x9e415a43, 0x7ba6, 0x4a73, 0x87, 0x43, 0xb7, 0x3d, 0x47, 0xe8, 0x84, 0x76); // {7F9B00B3-F125-4890-876E-1CFFBF697C4D} -DEFINE_GUID(DXFILEOBJ_CompressedAnimationSet, +DEFINE_GUID(DXFILEOBJ_CompressedAnimationSet, 0x7f9b00b3, 0xf125, 0x4890, 0x87, 0x6e, 0x1c, 0x42, 0xbf, 0x69, 0x7c, 0x4d); #pragma pack(push, 1) @@ -3001,5 +3001,5 @@ typedef struct _XFILECOMPRESSEDANIMATIONSET DWORD nAttributeMispredicts; \ array DWORD attributeMispredicts[nAttributeMispredicts]; \ } " - + #endif //__D3DX9MESH_H__ diff --git a/gfx/include/d3d9/d3dx9shader.h b/gfx/include/d3d9/d3dx9shader.h index 74e40cfc80..174ec6667b 100644 --- a/gfx/include/d3d9/d3dx9shader.h +++ b/gfx/include/d3d9/d3dx9shader.h @@ -187,7 +187,7 @@ typedef interface ID3DXConstantTable ID3DXConstantTable; typedef interface ID3DXConstantTable *LPD3DXCONSTANTTABLE; // {AB3C758F-093E-4356-B762-4DB18F1B3A01} -DEFINE_GUID(IID_ID3DXConstantTable, +DEFINE_GUID(IID_ID3DXConstantTable, 0xab3c758f, 0x93e, 0x4356, 0xb7, 0x62, 0x4d, 0xb1, 0x8f, 0x1b, 0x3a, 0x1); @@ -243,7 +243,7 @@ typedef interface ID3DXTextureShader ID3DXTextureShader; typedef interface ID3DXTextureShader *LPD3DXTEXTURESHADER; // {3E3D67F8-AA7A-405d-A857-BA01D4758426} -DEFINE_GUID(IID_ID3DXTextureShader, +DEFINE_GUID(IID_ID3DXTextureShader, 0x3e3d67f8, 0xaa7a, 0x405d, 0xa8, 0x57, 0xba, 0x1, 0xd4, 0x75, 0x84, 0x26); #undef INTERFACE @@ -460,9 +460,9 @@ HRESULT WINAPI HRESULT WINAPI D3DXDisassembleShader( - CONST DWORD* pShader, - BOOL EnableColorCode, - LPCSTR pComments, + CONST DWORD* pShader, + BOOL EnableColorCode, + LPCSTR pComments, LPD3DXBUFFER* ppDisassembly); LPCSTR WINAPI @@ -519,18 +519,18 @@ HRESULT WINAPI HRESULT WINAPI D3DXCreateTextureShader( - CONST DWORD* pFunction, + CONST DWORD* pFunction, LPD3DXTEXTURESHADER* ppTextureShader); -HRESULT WINAPI +HRESULT WINAPI D3DXPreprocessShaderFromFileA( LPCSTR pSrcFile, CONST D3DXMACRO* pDefines, LPD3DXINCLUDE pInclude, LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs); - -HRESULT WINAPI + +HRESULT WINAPI D3DXPreprocessShaderFromFileW( LPCWSTR pSrcFile, CONST D3DXMACRO* pDefines, @@ -543,8 +543,8 @@ HRESULT WINAPI #else #define D3DXPreprocessShaderFromFile D3DXPreprocessShaderFromFileA #endif - -HRESULT WINAPI + +HRESULT WINAPI D3DXPreprocessShaderFromResourceA( HMODULE hSrcModule, LPCSTR pSrcResource, @@ -553,7 +553,7 @@ HRESULT WINAPI LPD3DXBUFFER* ppShaderText, LPD3DXBUFFER* ppErrorMsgs); -HRESULT WINAPI +HRESULT WINAPI D3DXPreprocessShaderFromResourceW( HMODULE hSrcModule, LPCWSTR pSrcResource, @@ -568,7 +568,7 @@ HRESULT WINAPI #define D3DXPreprocessShaderFromResource D3DXPreprocessShaderFromResourceA #endif -HRESULT WINAPI +HRESULT WINAPI D3DXPreprocessShader( LPCSTR pSrcData, UINT SrcDataSize, @@ -603,7 +603,7 @@ typedef struct _D3DXSHADER_CONSTANTTABLE DWORD Constants; // number of constants DWORD ConstantInfo; // D3DXSHADER_CONSTANTINFO[Constants] offset DWORD Flags; // flags shader was compiled with - DWORD Target; // LPCSTR offset + DWORD Target; // LPCSTR offset } D3DXSHADER_CONSTANTTABLE, *LPD3DXSHADER_CONSTANTTABLE; diff --git a/gfx/include/d3d9/d3dx9shape.h b/gfx/include/d3d9/d3dx9shape.h index 9d1ff52e7f..cc0c618c5a 100644 --- a/gfx/include/d3d9/d3dx9shape.h +++ b/gfx/include/d3d9/d3dx9shape.h @@ -16,39 +16,39 @@ extern "C" { #endif -HRESULT WINAPI +HRESULT WINAPI D3DXCreatePolygon( LPDIRECT3DDEVICE9 pDevice, - FLOAT Length, - UINT Sides, + FLOAT Length, + UINT Sides, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateBox( - LPDIRECT3DDEVICE9 pDevice, + LPDIRECT3DDEVICE9 pDevice, FLOAT Width, FLOAT Height, FLOAT Depth, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency); -HRESULT WINAPI +HRESULT WINAPI D3DXCreateCylinder( LPDIRECT3DDEVICE9 pDevice, - FLOAT Radius1, - FLOAT Radius2, - FLOAT Length, - UINT Slices, - UINT Stacks, + FLOAT Radius1, + FLOAT Radius2, + FLOAT Length, + UINT Slices, + UINT Stacks, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency); HRESULT WINAPI D3DXCreateSphere( - LPDIRECT3DDEVICE9 pDevice, - FLOAT Radius, - UINT Slices, + LPDIRECT3DDEVICE9 pDevice, + FLOAT Radius, + UINT Slices, UINT Stacks, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency); @@ -57,9 +57,9 @@ HRESULT WINAPI D3DXCreateTorus( LPDIRECT3DDEVICE9 pDevice, FLOAT InnerRadius, - FLOAT OuterRadius, + FLOAT OuterRadius, UINT Sides, - UINT Rings, + UINT Rings, LPD3DXMESH* ppMesh, LPD3DXBUFFER* ppAdjacency); diff --git a/gfx/include/d3d9/d3dx9tex.h b/gfx/include/d3d9/d3dx9tex.h index ec29c0187a..4de1ead96c 100644 --- a/gfx/include/d3d9/d3dx9tex.h +++ b/gfx/include/d3d9/d3dx9tex.h @@ -61,12 +61,12 @@ typedef enum _D3DXIMAGE_FILEFORMAT } D3DXIMAGE_FILEFORMAT; -typedef VOID (WINAPI *LPD3DXFILL2D)(D3DXVECTOR4 *pOut, +typedef VOID (WINAPI *LPD3DXFILL2D)(D3DXVECTOR4 *pOut, CONST D3DXVECTOR2 *pTexCoord, CONST D3DXVECTOR2 *pTexelSize, LPVOID pData); -typedef VOID (WINAPI *LPD3DXFILL3D)(D3DXVECTOR4 *pOut, +typedef VOID (WINAPI *LPD3DXFILL3D)(D3DXVECTOR4 *pOut, CONST D3DXVECTOR3 *pTexCoord, CONST D3DXVECTOR3 *pTexelSize, LPVOID pData); - + typedef struct _D3DXIMAGE_INFO { UINT Width; @@ -974,7 +974,7 @@ HRESULT WINAPI LPD3DXFILL3D pFunction, LPVOID pData); -HRESULT WINAPI +HRESULT WINAPI D3DXFillTextureTX( LPDIRECT3DTEXTURE9 pTexture, LPD3DXTEXTURESHADER pTextureShader); @@ -984,9 +984,9 @@ HRESULT WINAPI D3DXFillCubeTextureTX( LPDIRECT3DCUBETEXTURE9 pCubeTexture, LPD3DXTEXTURESHADER pTextureShader); - - -HRESULT WINAPI + + +HRESULT WINAPI D3DXFillVolumeTextureTX( LPDIRECT3DVOLUMETEXTURE9 pVolumeTexture, LPD3DXTEXTURESHADER pTextureShader); diff --git a/gfx/include/d3d9/d3dx9xof.h b/gfx/include/d3d9/d3dx9xof.h index 6b47acd273..0ad3a1250f 100644 --- a/gfx/include/d3d9/d3dx9xof.h +++ b/gfx/include/d3d9/d3dx9xof.h @@ -58,23 +58,23 @@ typedef struct _D3DXF_FILELOADMEMORY #if defined( _WIN32 ) && !defined( _NO_COM ) // {cef08cf9-7b4f-4429-9624-2a690a933201} -DEFINE_GUID( IID_ID3DXFile, +DEFINE_GUID( IID_ID3DXFile, 0xcef08cf9, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); // {cef08cfa-7b4f-4429-9624-2a690a933201} -DEFINE_GUID( IID_ID3DXFileSaveObject, +DEFINE_GUID( IID_ID3DXFileSaveObject, 0xcef08cfa, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); // {cef08cfb-7b4f-4429-9624-2a690a933201} -DEFINE_GUID( IID_ID3DXFileSaveData, +DEFINE_GUID( IID_ID3DXFileSaveData, 0xcef08cfb, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); // {cef08cfc-7b4f-4429-9624-2a690a933201} -DEFINE_GUID( IID_ID3DXFileEnumObject, +DEFINE_GUID( IID_ID3DXFileEnumObject, 0xcef08cfc, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); // {cef08cfd-7b4f-4429-9624-2a690a933201} -DEFINE_GUID( IID_ID3DXFileData, +DEFINE_GUID( IID_ID3DXFileData, 0xcef08cfd, 0x7b4f, 0x4429, 0x96, 0x24, 0x2a, 0x69, 0x0a, 0x93, 0x32, 0x01 ); #endif // defined( _WIN32 ) && !defined( _NO_COM ) @@ -131,7 +131,7 @@ DECLARE_INTERFACE_( ID3DXFile, IUnknown ) STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; STDMETHOD_( ULONG, AddRef )( THIS ) PURE; STDMETHOD_( ULONG, Release )( THIS ) PURE; - + STDMETHOD( CreateEnumObject )( THIS_ LPCVOID, D3DXF_FILELOADOPTIONS, ID3DXFileEnumObject** ) PURE; STDMETHOD( CreateSaveObject )( THIS_ LPCVOID, D3DXF_FILESAVEOPTIONS, @@ -152,7 +152,7 @@ DECLARE_INTERFACE_( ID3DXFileSaveObject, IUnknown ) STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; STDMETHOD_( ULONG, AddRef )( THIS ) PURE; STDMETHOD_( ULONG, Release )( THIS ) PURE; - + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; STDMETHOD( AddDataObject )( THIS_ REFGUID, LPCSTR, CONST GUID*, SIZE_T, LPCVOID, ID3DXFileSaveData** ) PURE; @@ -171,7 +171,7 @@ DECLARE_INTERFACE_( ID3DXFileSaveData, IUnknown ) STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; STDMETHOD_( ULONG, AddRef )( THIS ) PURE; STDMETHOD_( ULONG, Release )( THIS ) PURE; - + STDMETHOD( GetSave )( THIS_ ID3DXFileSaveObject** ) PURE; STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; STDMETHOD( GetId )( THIS_ LPGUID ) PURE; @@ -193,7 +193,7 @@ DECLARE_INTERFACE_( ID3DXFileEnumObject, IUnknown ) STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; STDMETHOD_( ULONG, AddRef )( THIS ) PURE; STDMETHOD_( ULONG, Release )( THIS ) PURE; - + STDMETHOD( GetFile )( THIS_ ID3DXFile** ) PURE; STDMETHOD( GetChildren )( THIS_ SIZE_T* ) PURE; STDMETHOD( GetChild )( THIS_ SIZE_T, ID3DXFileData** ) PURE; @@ -213,7 +213,7 @@ DECLARE_INTERFACE_( ID3DXFileData, IUnknown ) STDMETHOD( QueryInterface )( THIS_ REFIID, LPVOID* ) PURE; STDMETHOD_( ULONG, AddRef )( THIS ) PURE; STDMETHOD_( ULONG, Release )( THIS ) PURE; - + STDMETHOD( GetEnum )( THIS_ ID3DXFileEnumObject** ) PURE; STDMETHOD( GetName )( THIS_ LPSTR, SIZE_T* ) PURE; STDMETHOD( GetId )( THIS_ LPGUID ) PURE; diff --git a/gfx/include/d3d9caps.h b/gfx/include/d3d9caps.h index adc3fb1f8d..cd89f29450 100644 --- a/gfx/include/d3d9caps.h +++ b/gfx/include/d3d9caps.h @@ -107,14 +107,14 @@ typedef struct _D3DCONTENTPROTECTIONCAPS #define D3DCPCAPS_SEQUENTIAL_CTR_IV 0x00000100 #define D3DCPCAPS_ENCRYPTSLICEDATAONLY 0x00000200 -DEFINE_GUID(D3DCRYPTOTYPE_AES128_CTR, +DEFINE_GUID(D3DCRYPTOTYPE_AES128_CTR, 0x9b6bd711, 0x4f74, 0x41c9, 0x9e, 0x7b, 0xb, 0xe2, 0xd7, 0xd9, 0x3b, 0x4f); -DEFINE_GUID(D3DCRYPTOTYPE_PROPRIETARY, +DEFINE_GUID(D3DCRYPTOTYPE_PROPRIETARY, 0xab4e9afd, 0x1d1c, 0x46e6, 0xa7, 0x2f, 0x8, 0x69, 0x91, 0x7b, 0xd, 0xe8); -DEFINE_GUID(D3DKEYEXCHANGE_RSAES_OAEP, +DEFINE_GUID(D3DKEYEXCHANGE_RSAES_OAEP, 0xc1949895, 0xd72a, 0x4a1d, 0x8e, 0x5d, 0xed, 0x85, 0x7d, 0x17, 0x15, 0x20); -DEFINE_GUID(D3DKEYEXCHANGE_DXVA, +DEFINE_GUID(D3DKEYEXCHANGE_DXVA, 0x43d3775c, 0x38e5, 0x4924, 0x8d, 0x86, 0xd3, 0xfc, 0xcf, 0x15, 0x3e, 0x9b); #endif /* !D3D_DISABLE_9EX */ @@ -211,7 +211,7 @@ typedef struct _D3DCAPS9 DWORD VertexTextureFilterCaps; /* D3DPTFILTERCAPS for IDirect3DTexture9's for texture, used in vertex shaders */ DWORD MaxVShaderInstructionsExecuted; /* maximum number of vertex shader instructions that can be executed */ DWORD MaxPShaderInstructionsExecuted; /* maximum number of pixel shader instructions that can be executed */ - DWORD MaxVertexShader30InstructionSlots; + DWORD MaxVertexShader30InstructionSlots; DWORD MaxPixelShader30InstructionSlots; } D3DCAPS9; @@ -250,7 +250,7 @@ typedef struct _D3DCAPS9 */ #define D3DCAPS3_ALPHA_FULLSCREEN_FLIP_OR_DISCARD 0x00000020L -/* Indicates that the device can perform a gamma correction from +/* Indicates that the device can perform a gamma correction from * a windowed back buffer containing linear content to the sRGB desktop. */ #define D3DCAPS3_LINEAR_TO_SRGB_PRESENTATION 0x00000080L @@ -354,7 +354,7 @@ typedef struct _D3DCAPS9 #define D3DPRASTERCAPS_COLORPERSPECTIVE 0x00400000L /* Device iterates colors perspective correct */ #define D3DPRASTERCAPS_SCISSORTEST 0x01000000L #define D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS 0x02000000L -#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L +#define D3DPRASTERCAPS_DEPTHBIAS 0x04000000L #define D3DPRASTERCAPS_MULTISAMPLE_TOGGLE 0x08000000L /* @@ -428,7 +428,7 @@ typedef struct _D3DCAPS9 #define D3DPTEXTURECAPS_MIPCUBEMAP 0x00010000L /* Device can do mipmapped cube maps */ #define D3DPTEXTURECAPS_CUBEMAP_POW2 0x00020000L /* Device requires that cubemaps be power-of-2 dimension */ #define D3DPTEXTURECAPS_VOLUMEMAP_POW2 0x00040000L /* Device requires that volume maps be power-of-2 dimension */ -#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation +#define D3DPTEXTURECAPS_NOPROJECTEDBUMPENV 0x00200000L /* Device does not support projected bump env lookup operation in programmable and fixed function pixel shaders */ /* diff --git a/gfx/include/d3d9types.h b/gfx/include/d3d9types.h index b4b9a94ddf..ef96fda496 100644 --- a/gfx/include/d3d9types.h +++ b/gfx/include/d3d9types.h @@ -1173,7 +1173,7 @@ typedef enum _D3DSHADER_MIN_PRECISION } D3DSHADER_MIN_PRECISION; // If the older D3DSPDM_PARTIALPRECISION is set, // that is equivalent to the whole operation specifying -// D3DMP_16 (on all operands). The two encodings are not +// D3DMP_16 (on all operands). The two encodings are not // used together however. @@ -1451,7 +1451,7 @@ typedef enum _D3DFORMAT /* Binary format indicating that the data has no inherent type */ D3DFMT_BINARYBUFFER = 199, - + #endif // !D3D_DISABLE_9EX /* -- D3D9Ex only */ @@ -1632,7 +1632,7 @@ typedef enum _D3DRESOURCETYPE { #define D3DUSAGE_TEXTAPI (0x10000000L) #define D3DUSAGE_RESTRICTED_CONTENT (0x00000800L) #define D3DUSAGE_RESTRICT_SHARED_RESOURCE (0x00002000L) -#define D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER (0x00001000L) +#define D3DUSAGE_RESTRICT_SHARED_RESOURCE_DRIVER (0x00001000L) #endif /* !D3D_DISABLE_9EX */ /* -- D3D9Ex only */ @@ -1657,7 +1657,7 @@ typedef enum _D3DCUBEMAP_FACES #define D3DLOCK_DISCARD 0x00002000L #define D3DLOCK_NOOVERWRITE 0x00001000L #define D3DLOCK_NOSYSLOCK 0x00000800L -#define D3DLOCK_DONOTWAIT 0x00004000L +#define D3DLOCK_DONOTWAIT 0x00004000L #define D3DLOCK_NO_DIRTY_UPDATE 0x00008000L @@ -1984,7 +1984,7 @@ typedef struct _D3DPRESENTSTATS { typedef enum D3DSCANLINEORDERING { - D3DSCANLINEORDERING_UNKNOWN = 0, + D3DSCANLINEORDERING_UNKNOWN = 0, D3DSCANLINEORDERING_PROGRESSIVE = 1, D3DSCANLINEORDERING_INTERLACED = 2, } D3DSCANLINEORDERING; @@ -2046,14 +2046,14 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERY_INPUT typedef struct _D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT { - D3D_OMAC omac; + D3D_OMAC omac; GUID QueryType; HANDLE hChannel; UINT SequenceNumber; HRESULT ReturnCode; } D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_PROTECTION, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_PROTECTION, 0xa84eb584, 0xc495, 0x48aa, 0xb9, 0x4d, 0x8b, 0xd2, 0xd6, 0xfb, 0xce, 0x5); typedef struct _D3DAUTHENTICATEDCHANNEL_PROTECTION_FLAGS @@ -2062,7 +2062,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_PROTECTION_FLAGS { struct { - UINT ProtectionEnabled : 1; + UINT ProtectionEnabled : 1; UINT OverlayOrFullscreenRequired : 1; UINT Reserved : 30; }; @@ -2080,7 +2080,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYPROTECTION_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYPROTECTION_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_CHANNELTYPE, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_CHANNELTYPE, 0xbc1b18a5, 0xb1fb, 0x42ab, 0xbd, 0x94, 0xb5, 0x82, 0x8b, 0x4b, 0xf7, 0xbe); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYCHANNELTYPE_OUTPUT @@ -2092,7 +2092,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYCHANNELTYPE_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYCHANNELTYPE_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_DEVICEHANDLE, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_DEVICEHANDLE, 0xec1c539d, 0x8cff, 0x4e2a, 0xbc, 0xc4, 0xf5, 0x69, 0x2f, 0x99, 0xf4, 0x80); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYDEVICEHANDLE_OUTPUT @@ -2104,7 +2104,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYDEVICEHANDLE_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYDEVICEHANDLE_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_CRYPTOSESSION, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_CRYPTOSESSION, 0x2634499e, 0xd018, 0x4d74, 0xac, 0x17, 0x7f, 0x72, 0x40, 0x59, 0x52, 0x8d); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYCRYPTOSESSION_INPUT @@ -2126,7 +2126,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYCRYPTOSESSION_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYCRYPTOSESSION_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_RESTRICTEDSHAREDRESOURCEPROCESSCOUNT, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_RESTRICTEDSHAREDRESOURCEPROCESSCOUNT, 0xdb207b3, 0x9450, 0x46a6, 0x82, 0xde, 0x1b, 0x96, 0xd4, 0x4f, 0x9c, 0xf2); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESSCOUNT_OUTPUT @@ -2138,7 +2138,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESSCOUN } D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESSCOUNT_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_RESTRICTEDSHAREDRESOURCEPROCESS, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_RESTRICTEDSHAREDRESOURCEPROCESS, 0x649bbadb, 0xf0f4, 0x4639, 0xa1, 0x5b, 0x24, 0x39, 0x3f, 0xc3, 0xab, 0xac); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESS_INPUT @@ -2167,7 +2167,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESS_OUT } D3DAUTHENTICATEDCHANNEL_QUERYRESTRICTEDSHAREDRESOURCEPROCESS_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_UNRESTRICTEDPROTECTEDSHAREDRESOURCECOUNT, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_UNRESTRICTEDPROTECTEDSHAREDRESOURCECOUNT, 0x12f0bd6, 0xe662, 0x4474, 0xbe, 0xfd, 0xaa, 0x53, 0xe5, 0x14, 0x3c, 0x6d); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYUNRESTRICTEDPROTECTEDSHAREDRESOURCECOUNT_OUTPUT @@ -2179,7 +2179,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYUNRESTRICTEDPROTECTEDSHAREDRESOURCE } D3DAUTHENTICATEDCHANNEL_QUERYUNRESTRICTEDPROTECTEDSHAREDRESOURCECOUNT_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_OUTPUTIDCOUNT, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_OUTPUTIDCOUNT, 0x2c042b5e, 0x8c07, 0x46d5, 0xaa, 0xbe, 0x8f, 0x75, 0xcb, 0xad, 0x4c, 0x31); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTIDCOUNT_INPUT @@ -2187,7 +2187,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTIDCOUNT_INPUT D3DAUTHENTICATEDCHANNEL_QUERY_INPUT Input; HANDLE DeviceHandle; - HANDLE CryptoSessionHandle; + HANDLE CryptoSessionHandle; } D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTIDCOUNT_INPUT; @@ -2196,13 +2196,13 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTIDCOUNT_OUTPUT D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT Output; HANDLE DeviceHandle; - HANDLE CryptoSessionHandle; + HANDLE CryptoSessionHandle; UINT NumOutputIDs; } D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTIDCOUNT_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_OUTPUTID, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_OUTPUTID, 0x839ddca3, 0x9b4e, 0x41e4, 0xb0, 0x53, 0x89, 0x2b, 0xd2, 0xa1, 0x1e, 0xe7); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTID_INPUT @@ -2210,7 +2210,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTID_INPUT D3DAUTHENTICATEDCHANNEL_QUERY_INPUT Input; HANDLE DeviceHandle; - HANDLE CryptoSessionHandle; + HANDLE CryptoSessionHandle; UINT OutputIDIndex; } D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTID_INPUT; @@ -2220,14 +2220,14 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTID_OUTPUT D3DAUTHENTICATEDCHANNEL_QUERY_OUTPUT Output; HANDLE DeviceHandle; - HANDLE CryptoSessionHandle; + HANDLE CryptoSessionHandle; UINT OutputIDIndex; UINT64 OutputID; } D3DAUTHENTICATEDCHANNEL_QUERYOUTPUTID_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_ACCESSIBILITYATTRIBUTES, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_ACCESSIBILITYATTRIBUTES, 0x6214d9d2, 0x432c, 0x4abb, 0x9f, 0xce, 0x21, 0x6e, 0xea, 0x26, 0x9e, 0x3b); typedef enum _D3DBUSTYPE @@ -2241,8 +2241,8 @@ typedef enum _D3DBUSTYPE D3DBUSIMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_CHIP = 0x00020000, D3DBUSIMPL_MODIFIER_TRACKS_ON_MOTHER_BOARD_TO_SOCKET = 0x00030000, D3DBUSIMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR = 0x00040000, - D3DBUSIMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR_INSIDE_OF_NUAE = 0x00050000, - D3DBUSIMPL_MODIFIER_NON_STANDARD = 0x80000000, + D3DBUSIMPL_MODIFIER_DAUGHTER_BOARD_CONNECTOR_INSIDE_OF_NUAE = 0x00050000, + D3DBUSIMPL_MODIFIER_NON_STANDARD = 0x80000000, } D3DBUSTYPE; typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYINFOBUSTYPE_OUTPUT @@ -2256,7 +2256,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYINFOBUSTYPE_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYINFOBUSTYPE_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_ENCRYPTIONWHENACCESSIBLEGUIDCOUNT, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_ENCRYPTIONWHENACCESSIBLEGUIDCOUNT, 0xb30f7066, 0x203c, 0x4b07, 0x93, 0xfc, 0xce, 0xaa, 0xfd, 0x61, 0x24, 0x1e); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUIDCOUNT_OUTPUT @@ -2268,7 +2268,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUIDCOUNT_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUIDCOUNT_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_ENCRYPTIONWHENACCESSIBLEGUID, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_ENCRYPTIONWHENACCESSIBLEGUID, 0xf83a5958, 0xe986, 0x4bda, 0xbe, 0xb0, 0x41, 0x1f, 0x6a, 0x7a, 0x1, 0xb7); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUID_INPUT @@ -2289,7 +2289,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUID_OUTPUT } D3DAUTHENTICATEDCHANNEL_QUERYEVICTIONENCRYPTIONGUID_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDQUERY_CURRENTENCRYPTIONWHENACCESSIBLE, +DEFINE_GUID(D3DAUTHENTICATEDQUERY_CURRENTENCRYPTIONWHENACCESSIBLE, 0xec1791c7, 0xdad3, 0x4f15, 0x9e, 0xc3, 0xfa, 0xa9, 0x3d, 0x60, 0xd4, 0xf0); typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYUNCOMPRESSEDENCRYPTIONLEVEL_OUTPUT @@ -2303,24 +2303,24 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_QUERYUNCOMPRESSEDENCRYPTIONLEVEL_OUTPUT typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT { - D3D_OMAC omac; - GUID ConfigureType; - HANDLE hChannel; - UINT SequenceNumber; + D3D_OMAC omac; + GUID ConfigureType; + HANDLE hChannel; + UINT SequenceNumber; } D3DAUTHENTICATEDCHANNEL_CONFIGURE_INPUT; typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT { - D3D_OMAC omac; - GUID ConfigureType; + D3D_OMAC omac; + GUID ConfigureType; HANDLE hChannel; - UINT SequenceNumber; + UINT SequenceNumber; HRESULT ReturnCode; } D3DAUTHENTICATEDCHANNEL_CONFIGURE_OUTPUT; -DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_INITIALIZE, +DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_INITIALIZE, 0x6114bdb, 0x3523, 0x470a, 0x8d, 0xca, 0xfb, 0xc2, 0x84, 0x51, 0x54, 0xf0); typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE @@ -2333,7 +2333,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE } D3DAUTHENTICATEDCHANNEL_CONFIGUREINITIALIZE; -DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_PROTECTION, +DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_PROTECTION, 0x50455658, 0x3f47, 0x4362, 0xbf, 0x99, 0xbf, 0xdf, 0xcd, 0xe9, 0xed, 0x29); typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREPROTECTION @@ -2345,7 +2345,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREPROTECTION } D3DAUTHENTICATEDCHANNEL_CONFIGUREPROTECTION; -DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_CRYPTOSESSION, +DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_CRYPTOSESSION, 0x6346cc54, 0x2cfc, 0x4ad4, 0x82, 0x24, 0xd1, 0x58, 0x37, 0xde, 0x77, 0x0); typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION @@ -2359,7 +2359,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION } D3DAUTHENTICATEDCHANNEL_CONFIGURECRYPTOSESSION; -DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_SHAREDRESOURCE, +DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_SHAREDRESOURCE, 0x772d047, 0x1b40, 0x48e8, 0x9c, 0xa6, 0xb5, 0xf5, 0x10, 0xde, 0x9f, 0x1); typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURESHAREDRESOURCE @@ -2373,7 +2373,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGURESHAREDRESOURCE } D3DAUTHENTICATEDCHANNEL_CONFIGURESHAREDRESOURCE; -DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_ENCRYPTIONWHENACCESSIBLE, +DEFINE_GUID(D3DAUTHENTICATEDCONFIGURE_ENCRYPTIONWHENACCESSIBLE, 0x41fff286, 0x6ae0, 0x4d43, 0x9d, 0x55, 0xa4, 0x6e, 0x9e, 0xfd, 0x15, 0x8a); typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREUNCOMPRESSEDENCRYPTION @@ -2386,7 +2386,7 @@ typedef struct _D3DAUTHENTICATEDCHANNEL_CONFIGUREUNCOMPRESSEDENCRYPTION typedef struct _D3DENCRYPTED_BLOCK_INFO { - UINT NumEncryptedBytesAtBeginning; + UINT NumEncryptedBytesAtBeginning; UINT NumBytesInSkipPattern; UINT NumBytesInEncryptPattern; } D3DENCRYPTED_BLOCK_INFO; diff --git a/gfx/include/vulkan/vulkan.h b/gfx/include/vulkan/vulkan.h index 121738c08f..463e0a1731 100644 --- a/gfx/include/vulkan/vulkan.h +++ b/gfx/include/vulkan/vulkan.h @@ -49,7 +49,7 @@ extern "C" { #define VK_NULL_HANDLE 0 - + #define VK_DEFINE_HANDLE(object) typedef struct object##_T* object; @@ -60,7 +60,7 @@ extern "C" { #else #define VK_DEFINE_NON_DISPATCHABLE_HANDLE(object) typedef uint64_t object; #endif - + typedef uint32_t VkFlags; diff --git a/gfx/video_coord_array.c b/gfx/video_coord_array.c index 835b9ba967..f06a619861 100644 --- a/gfx/video_coord_array.c +++ b/gfx/video_coord_array.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/video_coord_array.h b/gfx/video_coord_array.h index 9a3ec1e1db..1dee18db50 100644 --- a/gfx/video_coord_array.h +++ b/gfx/video_coord_array.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * copyright (c) 2011-2017 - 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. diff --git a/gfx/video_driver.c b/gfx/video_driver.c index b07d869967..0302d7008b 100644 --- a/gfx/video_driver.c +++ b/gfx/video_driver.c @@ -175,7 +175,7 @@ static video_pixel_scaler_t *video_driver_scaler_ptr = NULL; static struct retro_hw_render_callback hw_render; -static const struct +static const struct retro_hw_render_context_negotiation_interface * hw_render_context_negotiation = NULL; @@ -192,7 +192,7 @@ static bool video_driver_active = false; static video_driver_frame_t frame_bak = NULL; /* If set during context deinit, the driver should keep - * graphics context alive to avoid having to reset all + * graphics context alive to avoid having to reset all * context state. */ static bool video_driver_cache_context = false; @@ -212,7 +212,7 @@ static void *video_context_data = NULL; /** * dynamic.c:dynamic_request_hw_context will try to set flag data when the context * is in the middle of being rebuilt; in these cases we will save flag - * data and set this to true. + * data and set this to true. * When the context is reinit, it checks this, reads from * deferred_flag_data and cleans it. * @@ -665,7 +665,7 @@ static void video_driver_filter_free(void) if (video_driver_state_filter) rarch_softfilter_free(video_driver_state_filter); video_driver_state_filter = NULL; - + if (video_driver_state_buffer) { #ifdef _3DS @@ -690,7 +690,7 @@ static void video_driver_init_filter(enum retro_pixel_format colfmt_int) unsigned width = geom->max_width; unsigned height = geom->max_height; /* Deprecated format. Gets pre-converted. */ - enum retro_pixel_format colfmt = + enum retro_pixel_format colfmt = (colfmt_int == RETRO_PIXEL_FORMAT_0RGB1555) ? RETRO_PIXEL_FORMAT_RGB565 : colfmt_int; @@ -718,11 +718,11 @@ static void video_driver_init_filter(enum retro_pixel_format colfmt_int) maxsize = MAX(pow2_x, pow2_y); video_driver_state_scale = maxsize / RARCH_SCALE_BASE; video_driver_state_out_rgb32 = rarch_softfilter_get_output_format( - video_driver_state_filter) == + video_driver_state_filter) == RETRO_PIXEL_FORMAT_XRGB8888; video_driver_state_out_bpp = video_driver_state_out_rgb32 ? - sizeof(uint32_t) : + sizeof(uint32_t) : sizeof(uint16_t); /* TODO: Aligned output. */ @@ -783,7 +783,7 @@ static void video_driver_monitor_compute_fps_statistics(void) double stddev = 0.0; unsigned samples = 0; - if (video_driver_frame_time_count < + if (video_driver_frame_time_count < (2 * MEASURE_FRAME_TIME_SAMPLES_COUNT)) { RARCH_LOG( @@ -838,7 +838,7 @@ static void video_driver_free_internal(void) if ( !video_driver_data_own - && video_driver_data + && video_driver_data && current_video && current_video->free ) current_video->free(video_driver_data); @@ -1057,7 +1057,7 @@ static bool video_driver_init_internal(bool *video_is_threaded) if (current_video->poke_interface) current_video->poke_interface(video_driver_data, &video_driver_poke); - if (current_video->viewport_info && + if (current_video->viewport_info && (!custom_vp->width || !custom_vp->height)) { @@ -1390,7 +1390,7 @@ bool video_driver_cached_frame(void) recording_data = NULL; retro_ctx.frame_cb( - (frame_cache_data != RETRO_HW_FRAME_BUFFER_VALID) + (frame_cache_data != RETRO_HW_FRAME_BUFFER_VALID) ? frame_cache_data : NULL, frame_cache_width, frame_cache_height, frame_cache_pitch); @@ -1625,13 +1625,13 @@ void video_driver_set_viewport_config(void) base_width = 1; if (base_height == 0) base_height = 1; - aspectratio_lut[ASPECT_RATIO_CONFIG].value = + aspectratio_lut[ASPECT_RATIO_CONFIG].value = (float)base_width / base_height; /* 1:1 PAR. */ } } else { - aspectratio_lut[ASPECT_RATIO_CONFIG].value = + aspectratio_lut[ASPECT_RATIO_CONFIG].value = settings->floats.video_aspect_ratio; } } @@ -1676,7 +1676,7 @@ void video_driver_set_viewport_core(void) if (geom->aspect_ratio > 0.0f) aspectratio_lut[ASPECT_RATIO_CORE].value = geom->aspect_ratio; else - aspectratio_lut[ASPECT_RATIO_CORE].value = + aspectratio_lut[ASPECT_RATIO_CORE].value = (float)geom->base_width / geom->base_height; } @@ -1918,10 +1918,10 @@ void video_driver_load_settings(config_file_t *conf) CONFIG_GET_INT_BASE(conf, global, console.screen.soft_filter_index, "soft_filter_index"); - CONFIG_GET_INT_BASE(conf, global, + CONFIG_GET_INT_BASE(conf, global, console.screen.resolutions.current.id, "current_resolution_id"); - CONFIG_GET_INT_BASE(conf, global, + CONFIG_GET_INT_BASE(conf, global, console.screen.flicker_filter_index, "flicker_filter_index"); } @@ -2050,7 +2050,7 @@ bool video_driver_is_active(void) } void video_driver_get_record_status( - bool *has_gpu_record, + bool *has_gpu_record, uint8_t **gpu_buf) { *gpu_buf = video_driver_record_gpu_buffer; @@ -2074,7 +2074,7 @@ void video_driver_gpu_record_deinit(void) bool video_driver_get_current_software_framebuffer(struct retro_framebuffer *fb) { if ( - video_driver_poke + video_driver_poke && video_driver_poke->get_current_software_framebuffer && video_driver_poke->get_current_software_framebuffer( video_driver_data, fb)) @@ -2087,7 +2087,7 @@ bool video_driver_get_hw_render_interface( const struct retro_hw_render_interface **iface) { if ( - video_driver_poke + video_driver_poke && video_driver_poke->get_hw_render_interface && video_driver_poke->get_hw_render_interface( video_driver_data, iface)) @@ -2109,11 +2109,11 @@ void video_driver_set_title_buf(void) struct retro_system_info info; core_get_system_info(&info); - fill_pathname_noext(video_driver_title_buf, + fill_pathname_noext(video_driver_title_buf, msg_hash_to_str(MSG_PROGRAM), " ", sizeof(video_driver_title_buf)); - strlcat(video_driver_title_buf, + strlcat(video_driver_title_buf, info.library_name, sizeof(video_driver_title_buf)); strlcat(video_driver_title_buf, @@ -2131,7 +2131,7 @@ void video_driver_set_title_buf(void) * @aspect_ratio : Aspect ratio (in float). * @keep_aspect : Preserve aspect ratio? * - * Gets viewport scaling dimensions based on + * Gets viewport scaling dimensions based on * scaled integer aspect ratio. **/ void video_viewport_get_scaled_integer(struct video_viewport *vp, @@ -2157,7 +2157,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, else { unsigned base_width; - /* Use system reported sizes as these define the + /* Use system reported sizes as these define the * geometry for the "normal" case. */ unsigned base_height = video_driver_av_info.geometry.base_height; @@ -2168,7 +2168,7 @@ void video_viewport_get_scaled_integer(struct video_viewport *vp, * This is sort of contradictory with the goal of integer scale, * but it is desirable in some cases. * - * If square pixels are used, base_height will be equal to + * If square pixels are used, base_height will be equal to * system->av_info.base_height. */ base_width = (unsigned)roundf(base_height * aspect_ratio); @@ -2244,7 +2244,7 @@ void video_driver_frame(const void *data, unsigned width, unsigned output_height = 0; unsigned output_pitch = 0; const char *msg = NULL; - retro_time_t new_time = + retro_time_t new_time = cpu_features_get_time_usec(); if (!video_driver_active) @@ -2276,8 +2276,8 @@ void video_driver_frame(const void *data, unsigned width, /* Get the amount of frames per seconds. */ if (video_driver_frame_count) { - unsigned write_index = - video_driver_frame_time_count++ & + unsigned write_index = + video_driver_frame_time_count++ & (MEASURE_FRAME_TIME_SAMPLES_COUNT - 1); video_driver_frame_time_samples[write_index] = new_time - fps_time; fps_time = new_time; @@ -2369,7 +2369,7 @@ void video_driver_frame(const void *data, unsigned width, if ( ( !video_driver_state_filter - || !video_info.post_filter_record + || !video_info.post_filter_record || !data || video_driver_record_gpu_buffer ) && recording_data @@ -2504,7 +2504,7 @@ void video_driver_build_info(video_frame_info_t *video_info) settings = config_get_ptr(); custom_vp = &settings->video_viewport_custom; video_info->refresh_rate = settings->floats.video_refresh_rate; - video_info->black_frame_insertion = + video_info->black_frame_insertion = settings->bools.video_black_frame_insertion; video_info->hard_sync = settings->bools.video_hard_sync; video_info->hard_sync_frames = settings->uints.video_hard_sync_frames; @@ -2521,7 +2521,7 @@ void video_driver_build_info(video_frame_info_t *video_info) if (libretro_get_shared_context() && hwr && hwr->context_type != RETRO_HW_CONTEXT_NONE) video_info->shared_context = true; - + video_info->font_enable = settings->bools.video_font_enable; video_info->font_msg_pos_x = settings->floats.video_msg_pos_x; video_info->font_msg_pos_y = settings->floats.video_msg_pos_y; @@ -2879,7 +2879,7 @@ bool video_context_driver_check_window(gfx_ctx_size_t *size_data) bool video_context_driver_init_image_buffer(const video_info_t *data) { - if ( + if ( current_video_context.image_buffer_init && current_video_context.image_buffer_init(video_context_data, data)) return true; @@ -2888,7 +2888,7 @@ bool video_context_driver_init_image_buffer(const video_info_t *data) bool video_context_driver_write_to_image_buffer(gfx_ctx_image_t *img) { - if ( + if ( current_video_context.image_buffer_write && current_video_context.image_buffer_write(video_context_data, img->frame, img->width, img->height, img->pitch, @@ -2978,7 +2978,7 @@ bool video_context_driver_get_proc_address(gfx_ctx_proc_address_t *proc) bool video_context_driver_get_metrics(gfx_ctx_metrics_t *metrics) { - if ( + if ( current_video_context.get_metrics(video_context_data, metrics->type, metrics->value)) @@ -3084,12 +3084,12 @@ bool video_context_driver_set_flags(gfx_ctx_flags_t *flags) { if (!flags) return false; - if (!current_video_context.set_flags) + if (!current_video_context.set_flags) { deferred_flag_data.flags = flags->flags; deferred_video_context_driver_set_flags = true; return false; - } + } current_video_context.set_flags(video_context_data, flags->flags); return true; @@ -3231,12 +3231,12 @@ static struct video_shader *video_shader_driver_get_current_shader_null(void *da static void video_shader_driver_set_params_null(void *data, void *shader_data, - unsigned width, unsigned height, - unsigned tex_width, unsigned tex_height, + unsigned width, unsigned height, + unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_count, - const void *info, - const void *prev_info, + const void *info, + const void *prev_info, const void *feedback_info, const void *fbo_info, unsigned fbo_info_cnt) { @@ -3289,7 +3289,7 @@ static void video_shader_driver_reset_to_defaults(void) if (current_shader->use) video_driver_cb_shader_use = current_shader->use; - else + else { current_shader->use = video_shader_driver_use_null; video_driver_cb_shader_use = video_shader_driver_use_null; @@ -3376,7 +3376,7 @@ bool video_shader_driver_info(video_shader_ctx_info_t *shader_info) bool video_shader_driver_filter_type(video_shader_ctx_filter_t *filter) { if (filter) - return current_shader->filter_type(shader_data, + return current_shader->filter_type(shader_data, filter->index, filter->smooth); return false; } diff --git a/gfx/video_driver.h b/gfx/video_driver.h index 43bbef97ca..6abae88e13 100644 --- a/gfx/video_driver.h +++ b/gfx/video_driver.h @@ -206,11 +206,11 @@ typedef struct shader_backend /* Set shader parameters. */ void (*set_params)(void *data, void *shader_data, - unsigned width, unsigned height, - unsigned tex_width, unsigned tex_height, + unsigned width, unsigned height, + unsigned tex_width, unsigned tex_height, unsigned out_width, unsigned out_height, unsigned frame_counter, - const void *info, + const void *info, const void *prev_info, const void *feedback_info, const void *fbo_info, unsigned fbo_info_cnt); @@ -340,20 +340,20 @@ typedef struct video_info /* Start with V-Sync enabled. */ bool vsync; - /* If true, the output image should have the aspect ratio + /* If true, the output image should have the aspect ratio * as set in aspect_ratio. */ bool force_aspect; bool font_enable; - /* Width of window. - * If fullscreen mode is requested, - * a width of 0 means the resolution of the + /* Width of window. + * If fullscreen mode is requested, + * a width of 0 means the resolution of the * desktop should be used. */ unsigned width; - /* Height of window. - * If fullscreen mode is requested, + /* Height of window. + * If fullscreen mode is requested, * a height of 0 means the resolutiof the desktop should be used. */ unsigned height; @@ -370,7 +370,7 @@ typedef struct video_info bool is_threaded; - /* Use 32bit RGBA rather than native RGB565/XBGR1555. + /* Use 32bit RGBA rather than native RGB565/XBGR1555. * * XRGB1555 format is 16-bit and has byte ordering: 0RRRRRGGGGGBBBBB, * in native endian. @@ -391,17 +391,17 @@ typedef struct video_info unsigned viwidth; #endif - /* + /* * input_scale defines the maximum size of the picture that will * ever be used with the frame callback. * * The maximum resolution is a multiple of 256x256 size (RARCH_SCALE_BASE), * so an input scale of 2 means you should allocate a texture or of 512x512. * - * Maximum input size: RARCH_SCALE_BASE * input_scale + * Maximum input size: RARCH_SCALE_BASE * input_scale */ unsigned input_scale; - + uintptr_t parent; } video_info_t; @@ -720,7 +720,7 @@ typedef struct video_poke_interface } video_poke_interface_t; -/* msg is for showing a message on the screen +/* msg is for showing a message on the screen * along with the video frame. */ typedef bool (*video_driver_frame_t)(void *data, const void *frame, unsigned width, @@ -737,20 +737,20 @@ typedef struct video_driver const input_driver_t **input, void **input_data); - /* Updates frame on the screen. + /* Updates frame on the screen. * Frame can be either XRGB1555, RGB565 or ARGB32 format - * depending on rgb32 setting in video_info_t. - * Pitch is the distance in bytes between two scanlines in memory. - * - * When msg is non-NULL, + * depending on rgb32 setting in video_info_t. + * Pitch is the distance in bytes between two scanlines in memory. + * + * When msg is non-NULL, * it's a message that should be displayed to the user. */ video_driver_frame_t frame; - /* Should we care about syncing to vblank? Fast forwarding. + /* Should we care about syncing to vblank? Fast forwarding. * - * Requests nonblocking operation. + * Requests nonblocking operation. * - * True = VSync is turned off. + * True = VSync is turned off. * False = VSync is turned on. * */ void (*set_nonblock_state)(void *data, bool toggle); @@ -804,7 +804,7 @@ typedef struct video_driver typedef struct d3d_renderchain_driver { - void (*set_mvp)(void *chain_data, + void (*set_mvp)(void *chain_data, void *data, unsigned vp_width, unsigned vp_height, unsigned rotation); void (*chain_free)(void *data); @@ -840,7 +840,7 @@ typedef struct gl_renderchain_driver void (*set_coords)(void *handle_data, void *chain_data, void *shader_data, const struct video_coords *coords); - void (*set_mvp)(void *data, + void (*set_mvp)(void *data, void *chain_data, void *shader_data, const void *mat_data); @@ -860,7 +860,7 @@ typedef struct gl_renderchain_driver void (*bind_pbo)(unsigned idx); void (*unbind_pbo)(void *data, void *chain_data); void (*copy_frame)( - void *data, + void *data, void *chain_data, video_frame_info_t *video_info, const void *frame, @@ -957,9 +957,9 @@ void video_driver_unset_own_driver(void); bool video_driver_owns_driver(void); bool video_driver_is_hw_context(void); struct retro_hw_render_callback *video_driver_get_hw_context(void); -const struct retro_hw_render_context_negotiation_interface +const struct retro_hw_render_context_negotiation_interface *video_driver_get_context_negotiation_interface(void); -void video_driver_set_context_negotiation_interface(const struct +void video_driver_set_context_negotiation_interface(const struct retro_hw_render_context_negotiation_interface *iface); bool video_driver_is_video_cache_context(void); void video_driver_set_video_cache_context_ack(void); @@ -968,9 +968,9 @@ void video_driver_set_active(void); bool video_driver_is_active(void); bool video_driver_gpu_record_init(unsigned size); void video_driver_gpu_record_deinit(void); -bool video_driver_get_current_software_framebuffer(struct +bool video_driver_get_current_software_framebuffer(struct retro_framebuffer *fb); -bool video_driver_get_hw_render_interface(const struct +bool video_driver_get_hw_render_interface(const struct retro_hw_render_interface **iface); bool video_driver_get_viewport_info(struct video_viewport *viewport); void video_driver_set_title_buf(void); @@ -989,7 +989,7 @@ const void *video_driver_find_handle(int index); * video_driver_find_ident: * @index : index of driver to get handle to. * - * Returns: Human-readable identifier of video driver at index. + * Returns: Human-readable identifier of video driver at index. * Can be NULL if nothing found. **/ const char *video_driver_find_ident(int index); @@ -1092,7 +1092,7 @@ void video_driver_menu_settings(void **list_data, void *list_info_data, * @aspect_ratio : Aspect ratio (in float). * @keep_aspect : Preserve aspect ratio? * - * Gets viewport scaling dimensions based on + * Gets viewport scaling dimensions based on * scaled integer aspect ratio. **/ void video_viewport_get_scaled_integer(struct video_viewport *vp, @@ -1194,7 +1194,7 @@ void video_driver_reinit(void); void video_driver_get_window_title(char *buf, unsigned len); void video_driver_get_record_status( - bool *has_gpu_record, + bool *has_gpu_record, uint8_t **gpu_buf); bool *video_driver_get_threaded(void); diff --git a/gfx/video_filter.c b/gfx/video_filter.c index 9c4f1bf740..86976263a2 100644 --- a/gfx/video_filter.c +++ b/gfx/video_filter.c @@ -165,7 +165,7 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt, userdata.conf = filt->conf; /* Index-specific configs take priority over ident-specific. */ - userdata.prefix[0] = key; + userdata.prefix[0] = key; userdata.prefix[1] = filt->impl->short_ident; /* Simple assumptions. */ @@ -209,7 +209,7 @@ static bool create_softfilter_graph(rarch_softfilter_t *filt, filt->impl_data = filt->impl->create( &softfilter_config, input_fmt, input_fmt, max_width, max_height, - threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : + threads != RARCH_SOFTFILTER_THREADS_AUTO ? threads : cpu_features_get_core_amount(), cpu_features, &userdata); if (!filt->impl_data) @@ -312,7 +312,7 @@ static bool append_softfilter_plugs(rarch_softfilter_t *filt, RARCH_LOG("[SoftFilter]: Found plug: %s (%s).\n", impl->ident, impl->short_ident); - + filt->plugs = new_plugs; filt->plugs[filt->num_plugs].lib = lib; filt->plugs[filt->num_plugs].impl = impl; @@ -524,7 +524,7 @@ void rarch_softfilter_process(rarch_softfilter_t *filt, if (filt->impl && filt->impl->get_work_packets) filt->impl->get_work_packets(filt->impl_data, filt->packets, output, output_stride, input, width, height, input_stride); - + #ifdef HAVE_THREADS /* Fire off workers */ for (i = 0; i < filt->threads; i++) diff --git a/gfx/video_filters/2xbr.c b/gfx/video_filters/2xbr.c index 4dd94db1d0..ef978ee741 100644 --- a/gfx/video_filters/2xbr.c +++ b/gfx/video_filters/2xbr.c @@ -32,7 +32,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - + #include "softfilter.h" #include #include @@ -68,17 +68,17 @@ struct filter_data uint16_t tbl_5_to_8[32]; uint16_t tbl_6_to_8[64]; }; - + static unsigned twoxbr_generic_input_fmts(void) { return SOFTFILTER_FMT_RGB565 | SOFTFILTER_FMT_XRGB8888; } - + static unsigned twoxbr_generic_output_fmts(unsigned input_fmts) { return input_fmts; } - + static unsigned twoxbr_generic_threads(void *data) { struct filter_data *filt = (struct filter_data*)data; @@ -218,7 +218,7 @@ static void SetupFormat(void * data) filt->RGBtoYUV[c] = y + u + v; } } - + static void *twoxbr_generic_create(const struct softfilter_config *config, unsigned in_fmt, unsigned out_fmt, unsigned max_width, unsigned max_height, @@ -244,7 +244,7 @@ static void *twoxbr_generic_create(const struct softfilter_config *config, return filt; } - + static void twoxbr_generic_output(void *data, unsigned *out_width, unsigned *out_height, unsigned width, unsigned height) @@ -252,7 +252,7 @@ static void twoxbr_generic_output(void *data, *out_width = width * TWOXBR_SCALE; *out_height = height * TWOXBR_SCALE; } - + static void twoxbr_generic_destroy(void *data) { struct filter_data *filt = (struct filter_data*)data; @@ -263,9 +263,9 @@ static void twoxbr_generic_destroy(void *data) free(filt->workers); free(filt); } - + #define ALPHA_BLEND_128_W(dst, src) dst = ((src & pg_lbmask) >> 1) + ((dst & pg_lbmask) >> 1) - + #define ALPHA_BLEND_32_W(dst, src) \ dst = ( \ (pg_red_mask & ((dst & pg_red_mask) + \ @@ -277,7 +277,7 @@ static void twoxbr_generic_destroy(void *data) (pg_blue_mask & ((dst & pg_blue_mask) + \ ((((src & pg_blue_mask) - \ (dst & pg_blue_mask))) >>3))) ) - + #define ALPHA_BLEND_8888_32_W(dst, src) \ dst = ( \ @@ -304,7 +304,7 @@ static void twoxbr_generic_destroy(void *data) (pg_blue_mask & ((dst & pg_blue_mask) + \ ((((src & pg_blue_mask) - \ (dst & pg_blue_mask))) >>2))) ) - + #define ALPHA_BLEND_8888_64_W(dst, src) \ dst = ( \ (pg_red_mask & ((dst & pg_red_mask) + \ @@ -330,7 +330,7 @@ static void twoxbr_generic_destroy(void *data) (pg_blue_mask & ((dst & pg_blue_mask) + \ ((((src & pg_blue_mask) - \ (dst & pg_blue_mask)) * 192) >>8))) ) - + #define ALPHA_BLEND_8888_192_W(dst, src) \ dst = ( \ @@ -375,44 +375,44 @@ static void twoxbr_generic_destroy(void *data) ALPHA_BLEND_224_W(E[N3], PIXEL); \ ALPHA_BLEND_64_W( E[N2], PIXEL); \ E[N1] = E[N2]; \ - - + + #define LEFT_2_2X(N3, N2, PIXEL)\ ALPHA_BLEND_192_W(E[N3], PIXEL); \ ALPHA_BLEND_64_W( E[N2], PIXEL); \ - + #define UP_2_2X(N3, N1, PIXEL)\ ALPHA_BLEND_192_W(E[N3], PIXEL); \ ALPHA_BLEND_64_W( E[N1], PIXEL); \ - + #define DIA_2X(N3, PIXEL)\ ALPHA_BLEND_128_W(E[N3], PIXEL); \ - + #define LEFT_UP_2_8888_2X(N3, N2, N1, PIXEL)\ ALPHA_BLEND_8888_224_W(E[N3], PIXEL); \ ALPHA_BLEND_8888_64_W( E[N2], PIXEL); \ E[N1] = E[N2]; \ - - + + #define LEFT_2_8888_2X(N3, N2, PIXEL)\ ALPHA_BLEND_8888_192_W(E[N3], PIXEL); \ ALPHA_BLEND_8888_64_W( E[N2], PIXEL); \ - + #define UP_2_8888_2X(N3, N1, PIXEL)\ ALPHA_BLEND_8888_192_W(E[N3], PIXEL); \ ALPHA_BLEND_8888_64_W( E[N1], PIXEL); \ - + #define DIA_8888_2X(N3, PIXEL)\ ALPHA_BLEND_128_W(E[N3], PIXEL); \ #define df(Z, A, B)\ abs(Z->RGBtoYUV[A] - Z->RGBtoYUV[B])\ - + #define eq(Z, A, B)\ (df(Z, A, B) < 155)\ - + float df8(uint32_t A, uint32_t B, @@ -443,7 +443,7 @@ int eq8(uint32_t A, uint32_t B, { uint32_t r, g, b; uint32_t y, u, v; - + #ifdef MSB_FIRST r = abs((int)(((A & pg_red_mask )>>24) - ((B & pg_red_mask )>> 24))); g = abs((int)(((A & pg_green_mask )>>16) - ((B & pg_green_mask )>> 16))); @@ -453,7 +453,7 @@ int eq8(uint32_t A, uint32_t B, g = abs((int)(((A & pg_green_mask)>>8 ) - ((B & pg_green_mask )>> 8))); r = abs((int)(((A & pg_red_mask ) - (B & pg_red_mask )))); #endif - + y = fabs(0.299*r + 0.587*g + 0.114*b); u = fabs(-0.169*r - 0.331*g + 0.500*b); v = fabs(0.500*r - 0.419*g - 0.081*b); @@ -495,7 +495,7 @@ int eq8(uint32_t A, uint32_t B, ALPHA_BLEND_128_W( E[N3], ((df(Z, PE,PF) <= df(Z, PE,PH)) ? PF : PH)); \ }\ }\ - + #define FILTRO_RGB8888(Z, PE, _PI, PH, PF, PG, PC, PD, PB, PA, G5, C4, G0, D0, C1, B1, F4, I4, H5, I5, A0, A1, N0, N1, N2, N3, pg_red_mask, pg_green_mask, pg_blue_mask) \ ex = (PE!=PH && PE!=PF); \ if ( ex )\ @@ -530,8 +530,8 @@ int eq8(uint32_t A, uint32_t B, ALPHA_BLEND_128_W( E[N3], ((df8(PE,PF, pg_red_mask, pg_green_mask, pg_blue_mask) <= df8(PE,PH, pg_red_mask, pg_green_mask, pg_blue_mask)) ? PF : PH)); \ }\ }\ - - + + #ifndef twoxbr_function #define twoxbr_function(FILTRO, Z) \ E[0] = E[1] = E[2] = E[3] = PE;\ @@ -546,8 +546,8 @@ int eq8(uint32_t A, uint32_t B, ++in; \ out += 2 #endif - - + + static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height, int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) @@ -563,12 +563,12 @@ static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height, (void)filt; nextline = (last) ? 0 : src_stride; - + for (; height; height--) { uint32_t *in = (uint32_t*)src; uint32_t *out = (uint32_t*)dst; - + for (finish = width; finish; finish -= 1) { uint32_t E[4]; @@ -594,7 +594,7 @@ static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height, uint32_t G5 = *(in + nextline + nextline - 1); uint32_t H5 = *(in + nextline + nextline); uint32_t I5 = *(in + nextline + nextline + 1); - + /* * Map of the pixels: A1 B1 C1 * A0 PA PB PC C4 @@ -602,15 +602,15 @@ static void twoxbr_generic_xrgb8888(void *data, unsigned width, unsigned height, * G0 PG PH _PI I4 * G5 H5 I5 */ - + twoxbr_function(FILTRO_RGB8888, filt); } - + src += src_stride; dst += 2 * dst_stride; } } - + static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height, int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) @@ -622,12 +622,12 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height, uint16_t pg_blue_mask = BLUE_MASK565; uint16_t pg_lbmask = PG_LBMASK565; unsigned nextline = (last) ? 0 : src_stride; - + for (; height; height--) { uint16_t *in = (uint16_t*)src; uint16_t *out = (uint16_t*)dst; - + for (finish = width; finish; finish -= 1) { uint16_t E[4]; @@ -653,7 +653,7 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height, uint16_t G5 = *(in + nextline + nextline - 1); uint16_t H5 = *(in + nextline + nextline); uint16_t I5 = *(in + nextline + nextline + 1); - + /* * Map of the pixels: A1 B1 C1 * A0 PA PB PC C4 @@ -661,47 +661,47 @@ static void twoxbr_generic_rgb565(void *data, unsigned width, unsigned height, * G0 PG PH _PI I4 * G5 H5 I5 */ - + twoxbr_function(FILTRO_RGB565, filt); } - + src += src_stride; dst += 2 * dst_stride; } } - + static void twoxbr_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; unsigned width = thr->width; unsigned height = thr->height; - + twoxbr_generic_rgb565(data, width, height, thr->first, thr->last, input, (unsigned)(thr->in_pitch / SOFTFILTER_BPP_RGB565), output, (unsigned)(thr->out_pitch / SOFTFILTER_BPP_RGB565)); } - + static void twoxbr_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint32_t *input = (uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; unsigned width = thr->width; unsigned height = thr->height; - + twoxbr_generic_xrgb8888(data, width, height, thr->first, thr->last, input, (unsigned)(thr->in_pitch / SOFTFILTER_BPP_XRGB8888), output, (unsigned)(thr->out_pitch / SOFTFILTER_BPP_XRGB8888)); } - + static void twoxbr_generic_packets(void *data, struct softfilter_work_packet *packets, void *output, size_t output_stride, @@ -713,25 +713,25 @@ static void twoxbr_generic_packets(void *data, for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; - + unsigned y_start = (height * i) / filt->threads; unsigned y_end = (height * (i + 1)) / filt->threads; - thr->out_data = (uint8_t*)output + y_start * + thr->out_data = (uint8_t*)output + y_start * TWOXBR_SCALE * output_stride; thr->in_data = (const uint8_t*)input + y_start * input_stride; thr->out_pitch = output_stride; thr->in_pitch = input_stride; thr->width = width; thr->height = y_end - y_start; - - /* Workers need to know if they can access + + /* Workers need to know if they can access * pixels outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; - + if (filt->in_fmt == SOFTFILTER_FMT_RGB565) packets[i].work = twoxbr_work_cb_rgb565; #if 0 @@ -743,14 +743,14 @@ static void twoxbr_generic_packets(void *data, packets[i].thread_data = thr; } } - + static const struct softfilter_implementation twoxbr_generic = { twoxbr_generic_input_fmts, twoxbr_generic_output_fmts, - + twoxbr_generic_create, twoxbr_generic_destroy, - + twoxbr_generic_threads, twoxbr_generic_output, twoxbr_generic_packets, @@ -758,14 +758,14 @@ static const struct softfilter_implementation twoxbr_generic = { "2xBR", "2xbr", }; - + const struct softfilter_implementation *softfilter_get_implementation( softfilter_simd_mask_t simd) { (void)simd; return &twoxbr_generic; } - + #ifdef RARCH_INTERNAL #undef softfilter_get_implementation #undef softfilter_thread_data diff --git a/gfx/video_filters/2xsai.c b/gfx/video_filters/2xsai.c index 42a005143a..7accb0ae6f 100644 --- a/gfx/video_filters/2xsai.c +++ b/gfx/video_filters/2xsai.c @@ -225,7 +225,7 @@ static void twoxsai_generic_destroy(void *data) #endif static void twoxsai_generic_xrgb8888(unsigned width, unsigned height, - int first, int last, uint32_t *src, + int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) { unsigned finish; @@ -257,7 +257,7 @@ static void twoxsai_generic_xrgb8888(unsigned width, unsigned height, } static void twoxsai_generic_rgb565(unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { unsigned finish; @@ -290,7 +290,7 @@ static void twoxsai_generic_rgb565(unsigned width, unsigned height, static void twoxsai_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -306,7 +306,7 @@ static void twoxsai_work_cb_rgb565(void *data, void *thread_data) static void twoxsai_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint32_t *input = (uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; @@ -331,12 +331,12 @@ static void twoxsai_generic_packets(void *data, for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; unsigned y_end = (height * (i + 1)) / filt->threads; - thr->out_data = (uint8_t*)output + y_start * + thr->out_data = (uint8_t*)output + y_start * TWOXSAI_SCALE * output_stride; thr->in_data = (const uint8_t*)input + y_start * input_stride; thr->out_pitch = output_stride; @@ -344,7 +344,7 @@ static void twoxsai_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can access pixels + /* Workers need to know if they can access pixels * outside their given buffer. */ thr->first = y_start; diff --git a/gfx/video_filters/blargg_ntsc_snes.c b/gfx/video_filters/blargg_ntsc_snes.c index a8a3ea715a..334885981e 100644 --- a/gfx/video_filters/blargg_ntsc_snes.c +++ b/gfx/video_filters/blargg_ntsc_snes.c @@ -182,7 +182,7 @@ static void blargg_ntsc_snes_render_rgb565(void *data, int width, int height, } static void blargg_ntsc_snes_rgb565(void *data, unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { blargg_ntsc_snes_render_rgb565(data, width, height, @@ -194,7 +194,7 @@ static void blargg_ntsc_snes_rgb565(void *data, unsigned width, unsigned height, static void blargg_ntsc_snes_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -217,7 +217,7 @@ static void blargg_ntsc_snes_generic_packets(void *data, unsigned i; for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; @@ -229,7 +229,7 @@ static void blargg_ntsc_snes_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can + /* Workers need to know if they can * access pixels outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; diff --git a/gfx/video_filters/darken.c b/gfx/video_filters/darken.c index b4b3a573a1..17cdce7334 100644 --- a/gfx/video_filters/darken.c +++ b/gfx/video_filters/darken.c @@ -104,7 +104,7 @@ static void darken_destroy(void *data) static void darken_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; const uint32_t *input = (const uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; @@ -120,7 +120,7 @@ static void darken_work_cb_xrgb8888(void *data, void *thread_data) static void darken_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; const uint16_t *input = (const uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -143,7 +143,7 @@ static void darken_packets(void *data, struct filter_data *filt = (struct filter_data*)data; for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; unsigned y_end = (height * (i + 1)) / filt->threads; diff --git a/gfx/video_filters/epx.c b/gfx/video_filters/epx.c index 2fa0407d96..0256f80ca6 100644 --- a/gfx/video_filters/epx.c +++ b/gfx/video_filters/epx.c @@ -196,7 +196,7 @@ static void epx_generic_rgb565 (unsigned width, unsigned height, static void epx_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -221,7 +221,7 @@ static void epx_generic_packets(void *data, for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; @@ -233,7 +233,7 @@ static void epx_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can + /* Workers need to know if they can * access pixels outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; diff --git a/gfx/video_filters/lq2x.c b/gfx/video_filters/lq2x.c index fc362801ad..e00be0d29b 100644 --- a/gfx/video_filters/lq2x.c +++ b/gfx/video_filters/lq2x.c @@ -104,7 +104,7 @@ static void lq2x_generic_destroy(void *data) } static void lq2x_generic_rgb565(unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { unsigned x, y; @@ -149,7 +149,7 @@ static void lq2x_generic_rgb565(unsigned width, unsigned height, } static void lq2x_generic_xrgb8888(unsigned width, unsigned height, - int first, int last, uint32_t *src, + int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) { unsigned x, y; @@ -194,7 +194,7 @@ static void lq2x_generic_xrgb8888(unsigned width, unsigned height, static void lq2x_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -210,7 +210,7 @@ static void lq2x_work_cb_rgb565(void *data, void *thread_data) static void lq2x_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint32_t *input = (uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; @@ -236,7 +236,7 @@ static void lq2x_generic_packets(void *data, unsigned i; for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; @@ -248,7 +248,7 @@ static void lq2x_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can access pixels + /* Workers need to know if they can access pixels * outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; diff --git a/gfx/video_filters/phosphor2x.c b/gfx/video_filters/phosphor2x.c index 1d3db0a02c..8ba64afe2a 100644 --- a/gfx/video_filters/phosphor2x.c +++ b/gfx/video_filters/phosphor2x.c @@ -118,7 +118,7 @@ static void blit_linear_line_xrgb8888(uint32_t * out, /* Blend edge pixels against black. */ out[0] = blend_pixels_xrgb8888(out[0], 0); - out[(width << 1) - 1] = + out[(width << 1) - 1] = blend_pixels_xrgb8888(out[(width << 1) - 1], 0); } @@ -133,12 +133,12 @@ static void blit_linear_line_rgb565(uint16_t * out, /* Blend in-between pixels. */ for (i = 1; i < (width << 1) - 1; i += 2) - out[i] = + out[i] = blend_pixels_rgb565(out[i - 1], out[i + 1]); /* Blend edge pixels against black. */ out[0] = blend_pixels_rgb565(out[0], 0); - out[(width << 1) - 1] = + out[(width << 1) - 1] = blend_pixels_rgb565(out[(width << 1) - 1], 0); } @@ -152,7 +152,7 @@ static void bleed_phosphors_xrgb8888(void *data, for (x = 0; x < width; x += 2) { unsigned r = red_xrgb8888(scanline[x]); - unsigned r_set = clamp8(r * filt->phosphor_bleed * + unsigned r_set = clamp8(r * filt->phosphor_bleed * filt->phosphor_bloom_8888[r]); set_red_xrgb8888(scanline[x + 1], r_set); } @@ -161,7 +161,7 @@ static void bleed_phosphors_xrgb8888(void *data, for (x = 0; x < width; x++) { unsigned g = green_xrgb8888(scanline[x]); - unsigned g_set = clamp8((g >> 1) + 0.5 * g * + unsigned g_set = clamp8((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_8888[g]); set_green_xrgb8888(scanline[x], g_set); } @@ -171,13 +171,13 @@ static void bleed_phosphors_xrgb8888(void *data, for (x = 1; x < width; x += 2) { unsigned b = blue_xrgb8888(scanline[x]); - unsigned b_set = clamp8(b * filt->phosphor_bleed * + unsigned b_set = clamp8(b * filt->phosphor_bleed * filt->phosphor_bloom_8888[b]); set_blue_xrgb8888(scanline[x + 1], b_set); } } -static void bleed_phosphors_rgb565(void *data, +static void bleed_phosphors_rgb565(void *data, uint16_t *scanline, unsigned width) { unsigned x; @@ -187,7 +187,7 @@ static void bleed_phosphors_rgb565(void *data, for (x = 0; x < width; x += 2) { unsigned r = red_rgb565(scanline[x]); - unsigned r_set = clamp6(r * filt->phosphor_bleed * + unsigned r_set = clamp6(r * filt->phosphor_bleed * filt->phosphor_bloom_565[r]); set_red_rgb565(scanline[x + 1], r_set); } @@ -196,7 +196,7 @@ static void bleed_phosphors_rgb565(void *data, for (x = 0; x < width; x++) { unsigned g = green_rgb565(scanline[x]); - unsigned g_set = clamp6((g >> 1) + 0.5 * g * + unsigned g_set = clamp6((g >> 1) + 0.5 * g * filt->phosphor_bleed * filt->phosphor_bloom_565[g]); set_green_rgb565(scanline[x], g_set); } @@ -206,7 +206,7 @@ static void bleed_phosphors_rgb565(void *data, for (x = 1; x < width; x += 2) { unsigned b = blue_rgb565(scanline[x]); - unsigned b_set = clamp6(b * filt->phosphor_bleed * + unsigned b_set = clamp6(b * filt->phosphor_bleed * filt->phosphor_bloom_565[b]); set_blue_rgb565(scanline[x + 1], b_set); } @@ -263,26 +263,26 @@ static void *phosphor2x_generic_create(const struct softfilter_config *config, #if 0 /* Initialize lookup tables: */ - phosphorBloom = (scaleTimes .* + phosphorBloom = (scaleTimes .* linspace(0, 1, 255) .^ (1/2.2)) + scaleAdd; /* Not exactly sure of order of operations here ... */ #endif for (i = 0; i < 256; i++) { - filt->phosphor_bloom_8888[i] = - filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) + + filt->phosphor_bloom_8888[i] = + filt->scale_times * powf((float)i / 255.0f, 1.0f/2.2f) + filt->scale_add; - filt->scan_range_8888[i] = - filt->scanrange_low + i * + filt->scan_range_8888[i] = + filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 255.0f; } for (i = 0; i < 64; i++) { - filt->phosphor_bloom_565[i] = + filt->phosphor_bloom_565[i] = filt->scale_times * powf((float)i / 31.0f, 1.0f/2.2f) + filt->scale_add; - filt->scan_range_565[i] = - filt->scanrange_low + i * + filt->scan_range_565[i] = + filt->scanrange_low + i * (filt->scanrange_high - filt->scanrange_low) / 31.0f; } @@ -311,7 +311,7 @@ static void phosphor2x_generic_destroy(void *data) static void phosphor2x_generic_xrgb8888(void *data, unsigned width, unsigned height, - int first, int last, uint32_t *src, + int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) { unsigned y; @@ -344,14 +344,14 @@ static void phosphor2x_generic_xrgb8888(void *data, for (x = 0; x < (width << 1); x++) { unsigned max = max_component_xrgb8888(out_line[x]); - set_red_xrgb8888(scan_out[x], - (uint32_t)(filt->scan_range_8888[max] * + set_red_xrgb8888(scan_out[x], + (uint32_t)(filt->scan_range_8888[max] * red_xrgb8888(out_line[x]))); - set_green_xrgb8888(scan_out[x], - (uint32_t)(filt->scan_range_8888[max] * + set_green_xrgb8888(scan_out[x], + (uint32_t)(filt->scan_range_8888[max] * green_xrgb8888(out_line[x]))); - set_blue_xrgb8888(scan_out[x], - (uint32_t)(filt->scan_range_8888[max] * + set_blue_xrgb8888(scan_out[x], + (uint32_t)(filt->scan_range_8888[max] * blue_xrgb8888(out_line[x]))); } } @@ -359,7 +359,7 @@ static void phosphor2x_generic_xrgb8888(void *data, static void phosphor2x_generic_rgb565(void *data, unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { unsigned y; @@ -390,14 +390,14 @@ static void phosphor2x_generic_rgb565(void *data, for (x = 0; x < (width << 1); x++) { unsigned max = max_component_rgb565(out_line[x]); - set_red_rgb565(scan_out[x], - (uint16_t)(filt->scan_range_565[max] * + set_red_rgb565(scan_out[x], + (uint16_t)(filt->scan_range_565[max] * red_rgb565(out_line[x]))); - set_green_rgb565(scan_out[x], - (uint16_t)(filt->scan_range_565[max] * + set_green_rgb565(scan_out[x], + (uint16_t)(filt->scan_range_565[max] * green_rgb565(out_line[x]))); - set_blue_rgb565(scan_out[x], - (uint16_t)(filt->scan_range_565[max] * + set_blue_rgb565(scan_out[x], + (uint16_t)(filt->scan_range_565[max] * blue_rgb565(out_line[x]))); } } @@ -405,7 +405,7 @@ static void phosphor2x_generic_rgb565(void *data, static void phosphor2x_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint32_t *input = (uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; @@ -421,7 +421,7 @@ static void phosphor2x_work_cb_xrgb8888(void *data, void *thread_data) static void phosphor2x_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; uint16_t *input = (uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -444,7 +444,7 @@ static void phosphor2x_generic_packets(void *data, unsigned i; for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; @@ -456,7 +456,7 @@ static void phosphor2x_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can access pixels + /* Workers need to know if they can access pixels * outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; diff --git a/gfx/video_filters/scale2x.c b/gfx/video_filters/scale2x.c index 34269b236d..e1125be4bc 100644 --- a/gfx/video_filters/scale2x.c +++ b/gfx/video_filters/scale2x.c @@ -168,7 +168,7 @@ static void scale2x_generic_destroy(void *data) static void scale2x_work_cb_xrgb8888(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; const uint32_t *input = (const uint32_t*)thr->in_data; uint32_t *output = (uint32_t*)thr->out_data; @@ -184,7 +184,7 @@ static void scale2x_work_cb_xrgb8888(void *data, void *thread_data) static void scale2x_work_cb_rgb565(void *data, void *thread_data) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)thread_data; const uint16_t *input = (const uint16_t*)thr->in_data; uint16_t *output = (uint16_t*)thr->out_data; @@ -192,7 +192,7 @@ static void scale2x_work_cb_rgb565(void *data, void *thread_data) unsigned height = thr->height; scale2x_generic_rgb565(width, height, - thr->first, thr->last, input, + thr->first, thr->last, input, (unsigned)(thr->in_pitch / SOFTFILTER_BPP_RGB565), output, (unsigned)(thr->out_pitch / SOFTFILTER_BPP_RGB565)); @@ -207,12 +207,12 @@ static void scale2x_generic_packets(void *data, unsigned i; for (i = 0; i < filt->threads; i++) { - struct softfilter_thread_data *thr = + struct softfilter_thread_data *thr = (struct softfilter_thread_data*)&filt->workers[i]; unsigned y_start = (height * i) / filt->threads; unsigned y_end = (height * (i + 1)) / filt->threads; - thr->out_data = (uint8_t*)output + y_start * + thr->out_data = (uint8_t*)output + y_start * SCALE2X_SCALE * output_stride; thr->in_data = (const uint8_t*)input + y_start * input_stride; thr->out_pitch = output_stride; @@ -220,7 +220,7 @@ static void scale2x_generic_packets(void *data, thr->width = width; thr->height = y_end - y_start; - /* Workers need to know if they can access pixels + /* Workers need to know if they can access pixels * outside their given buffer. */ thr->first = y_start; thr->last = y_end == height; diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc.c b/gfx/video_filters/snes_ntsc/snes_ntsc.c index 8ea1363ba4..bb33031389 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc.c +++ b/gfx/video_filters/snes_ntsc/snes_ntsc.c @@ -85,11 +85,11 @@ void snes_ntsc_init( snes_ntsc_t* ntsc, snes_ntsc_setup_t const* setup ) if ( !setup ) setup = &snes_ntsc_composite; init( &impl, setup ); - + merge_fields = setup->merge_fields; if ( setup->artifacts <= -1 && setup->fringing <= -1 ) merge_fields = 1; - + for ( entry = 0; entry < snes_ntsc_palette_size; entry++ ) { /* Reduce number of significant bits of source color. Clearing the @@ -130,41 +130,41 @@ void snes_ntsc_blit( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, long snes_ntsc_out_t* line_out = (snes_ntsc_out_t*) rgb_out; int n; ++line_in; - + for ( n = chunk_count; n; --n ) { /* order of input and output pixels must not be altered */ SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) ); SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) ); SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) ); SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH ); - + line_in += 3; line_out += 7; } - + /* finish final pixels */ SNES_NTSC_COLOR_IN( 0, snes_ntsc_black ); SNES_NTSC_RGB_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 1, snes_ntsc_black ); SNES_NTSC_RGB_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 2, snes_ntsc_black ); SNES_NTSC_RGB_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_RGB_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH ); - + burst_phase = (burst_phase + 1) % snes_ntsc_burst_count; input += in_row_width; rgb_out = (char*) rgb_out + out_pitch; @@ -185,52 +185,52 @@ void snes_ntsc_blit_hires( snes_ntsc_t const* ntsc, SNES_NTSC_IN_T const* input, snes_ntsc_out_t* line_out = (snes_ntsc_out_t*) rgb_out; int n; line_in += 2; - + for ( n = chunk_count; n; --n ) { /* twice as many input pixels per chunk */ SNES_NTSC_COLOR_IN( 0, SNES_NTSC_ADJ_IN( line_in [0] ) ); SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 1, SNES_NTSC_ADJ_IN( line_in [1] ) ); SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 2, SNES_NTSC_ADJ_IN( line_in [2] ) ); SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 3, SNES_NTSC_ADJ_IN( line_in [3] ) ); SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 4, SNES_NTSC_ADJ_IN( line_in [4] ) ); SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 5, SNES_NTSC_ADJ_IN( line_in [5] ) ); SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH ); - + line_in += 6; line_out += 7; } - + SNES_NTSC_COLOR_IN( 0, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 0, line_out [0], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 1, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 1, line_out [1], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 2, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 2, line_out [2], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 3, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 3, line_out [3], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 4, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 4, line_out [4], SNES_NTSC_OUT_DEPTH ); - + SNES_NTSC_COLOR_IN( 5, snes_ntsc_black ); SNES_NTSC_HIRES_OUT( 5, line_out [5], SNES_NTSC_OUT_DEPTH ); SNES_NTSC_HIRES_OUT( 6, line_out [6], SNES_NTSC_OUT_DEPTH ); - + burst_phase = (burst_phase + 1) % snes_ntsc_burst_count; input += in_row_width; rgb_out = (char*) rgb_out + out_pitch; diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc.h b/gfx/video_filters/snes_ntsc/snes_ntsc.h index 82205e0115..d9aa710e27 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc.h +++ b/gfx/video_filters/snes_ntsc/snes_ntsc.h @@ -20,7 +20,7 @@ typedef struct snes_ntsc_setup_t double contrast; /* -1 = dark (0.5) +1 = light (1.5) */ double brightness; /* -1 = dark (0.5) +1 = light (1.5) */ double sharpness; /* edge contrast enhancement/blurring */ - + /* Advanced parameters */ double gamma; /* -1 = dark (1.5) +1 = light (0.5) */ double resolution; /* image resolution */ @@ -29,7 +29,7 @@ typedef struct snes_ntsc_setup_t double bleed; /* color bleed (color resolution reduction) */ int merge_fields; /* if 1, merges even and odd fields together to reduce flicker */ float const* decoder_matrix; /* optional RGB decoder matrix, 6 elements */ - + unsigned long const* bsnes_colortbl; /* undocumented; set to 0 */ } snes_ntsc_setup_t; diff --git a/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h b/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h index 2d3c654589..fc9be63739 100644 --- a/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h +++ b/gfx/video_filters/snes_ntsc/snes_ntsc_impl.h @@ -87,7 +87,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) /* quadratic mapping to reduce negative (blurring) range */ float to_angle = (float) setup->resolution + 1; to_angle = PI / maxh * (float) LUMA_CUTOFF * (to_angle * to_angle + 1); - + kernels [kernel_size * 3 / 2] = maxh; /* default center value */ for ( i = 0; i < kernel_half * 2 + 1; i++ ) { @@ -105,7 +105,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) kernels [kernel_size * 3 / 2 - kernel_half + i] = dsf - (float) 0.5; } } - + /* apply blackman window and find sum */ sum = 0; for ( i = 0; i < kernel_half * 2 + 1; i++ ) @@ -114,7 +114,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) float blackman = 0.42f - 0.5f * (float) cos( x ) + 0.08f * (float) cos( x * 2 ); sum += (kernels [kernel_size * 3 / 2 - kernel_half + i] *= blackman); } - + /* normalize kernel */ sum = 1.0f / sum; for ( i = 0; i < kernel_half * 2 + 1; i++ ) @@ -130,7 +130,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) float const cutoff_factor = -0.03125f; float cutoff = (float) setup->bleed; int i; - + if ( cutoff < 0 ) { /* keep extreme value accessible only near upper end of scale (1.0) */ @@ -140,10 +140,10 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) cutoff *= -30.0f / 0.65f; } cutoff = cutoff_factor - 0.65f * cutoff_factor * cutoff; - + for ( i = -kernel_half; i <= kernel_half; i++ ) kernels [kernel_size / 2 + i] = (float) exp( i * i * cutoff ); - + /* normalize even and odd phases separately */ for ( i = 0; i < 2; i++ ) { @@ -151,7 +151,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) int x; for ( x = i; x < kernel_size; x += 2 ) sum += kernels [x]; - + sum = 1.0f / sum; for ( x = i; x < kernel_size; x += 2 ) { @@ -160,7 +160,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) } } } - + /* printf( "luma:\n" ); for ( i = kernel_size; i < kernel_size * 2; i++ ) @@ -169,7 +169,7 @@ static void init_filters( init_t* impl, snes_ntsc_setup_t const* setup ) for ( i = 0; i < kernel_size; i++ ) printf( "%f\n", kernels [i] ); */ - + /* generate linear rescale kernels */ #if rescale_out > 1 { @@ -205,7 +205,7 @@ static void init( init_t* impl, snes_ntsc_setup_t const* setup ) if ( !setup->palette ) impl->contrast *= default_palette_contrast; #endif - + impl->artifacts = (float) setup->artifacts; if ( impl->artifacts > 0 ) impl->artifacts *= artifacts_max - artifacts_mid; @@ -215,9 +215,9 @@ static void init( init_t* impl, snes_ntsc_setup_t const* setup ) if ( impl->fringing > 0 ) impl->fringing *= fringing_max - fringing_mid; impl->fringing = impl->fringing * fringing_mid + fringing_mid; - + init_filters( impl, setup ); - + /* generate gamma table */ if ( gamma_size > 1 ) { @@ -229,7 +229,7 @@ static void init( init_t* impl, snes_ntsc_setup_t const* setup ) impl->to_float [i] = (float) pow( i * to_float, gamma ) * impl->contrast + impl->brightness; } - + /* setup decoder matricies */ { float hue = (float) setup->hue * PI + PI / 180 * ext_decoder_hue; @@ -241,13 +241,13 @@ static void init( init_t* impl, snes_ntsc_setup_t const* setup ) if ( STD_HUE_CONDITION( setup ) ) hue += PI / 180 * (std_decoder_hue - ext_decoder_hue); } - + { float s = (float) sin( hue ) * sat; float c = (float) cos( hue ) * sat; float* out = impl->to_rgb; int n; - + n = burst_count; do { @@ -336,16 +336,16 @@ static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t float const qc1 = (q + yy) * pixel->kernel [1]; float const ic2 = (i - yy) * pixel->kernel [2]; float const qc3 = (q - yy) * pixel->kernel [3]; - + float const factor = impl->artifacts * pixel->negate; float const ii = i * factor; float const yc0 = (y + ii) * pixel->kernel [0]; float const yc2 = (y - ii) * pixel->kernel [2]; - + float const qq = q * factor; float const yc1 = (y + qq) * pixel->kernel [1]; float const yc3 = (y - qq) * pixel->kernel [3]; - + float const* k = &impl->kernel [pixel->offset]; int n; ++pixel; @@ -368,12 +368,12 @@ static void gen_kernel( init_t* impl, float y, float i, float q, snes_ntsc_rgb_t } } while ( alignment_count > 1 && --alignment_remain ); - + if ( burst_count <= 1 ) break; - + to_rgb += 6; - + ROTATE_IQ( i, q, -0.866025f, -0.5f ); /* -120 degrees */ } while ( --burst_remain ); diff --git a/gfx/video_filters/softfilter.h b/gfx/video_filters/softfilter.h index 937e3fba8d..99cd10eedc 100644 --- a/gfx/video_filters/softfilter.h +++ b/gfx/video_filters/softfilter.h @@ -41,20 +41,20 @@ extern "C" { #define SOFTFILTER_SIMD_PS (1 << 14) /* A bit-mask of all supported SIMD instruction sets. - * Allows an implementation to pick different + * Allows an implementation to pick different * softfilter_implementation structs. */ typedef unsigned softfilter_simd_mask_t; -/* Returns true if config key was found. Otherwise, returns false, +/* Returns true if config key was found. Otherwise, returns false, * and sets value to default value. */ -typedef int (*softfilter_config_get_float_t)(void *userdata, +typedef int (*softfilter_config_get_float_t)(void *userdata, const char *key, float *value, float default_value); typedef int (*softfilter_config_get_int_t)(void *userdata, const char *key, int *value, int default_value); /* Allocates an array with values. free() with softfilter_config_free_t. */ -typedef int (*softfilter_config_get_float_array_t)(void *userdata, +typedef int (*softfilter_config_get_float_array_t)(void *userdata, const char *key, float **values, unsigned *out_num_values, const float *default_values, unsigned num_default_values); @@ -79,16 +79,16 @@ struct softfilter_config softfilter_config_get_int_array_t get_int_array; softfilter_config_get_string_t get_string; - /* Avoid problems where softfilter plug and + /* Avoid problems where softfilter plug and * host are linked against different C runtimes. */ softfilter_config_free_t free; }; /* Dynamic library entrypoint. */ -typedef const struct softfilter_implementation +typedef const struct softfilter_implementation *(*softfilter_get_implementation_t)(softfilter_simd_mask_t); -/* The same SIMD mask argument is forwarded to create() callback +/* The same SIMD mask argument is forwarded to create() callback * as well to avoid having to keep lots of state around. */ const struct softfilter_implementation *softfilter_get_implementation( softfilter_simd_mask_t simd); @@ -111,11 +111,11 @@ const struct softfilter_implementation *softfilter_get_implementation( * Returns a bitmask of supported input formats. */ typedef unsigned (*softfilter_query_input_formats_t)(void); -/* Returns a bitmask of supported output formats +/* Returns a bitmask of supported output formats * for a given input format. */ typedef unsigned (*softfilter_query_output_formats_t)(unsigned input_format); -/* In softfilter_process_t, the softfilter implementation +/* In softfilter_process_t, the softfilter implementation * submits work units to a worker thread pool. */ typedef void (*softfilter_work_t)(void *data, void *thread_data); struct softfilter_work_packet @@ -124,10 +124,10 @@ struct softfilter_work_packet void *thread_data; }; -/* Create a filter with given input and output formats as well as +/* Create a filter with given input and output formats as well as * maximum possible input size. * - * Input sizes can very per call to softfilter_process_t, but they + * Input sizes can very per call to softfilter_process_t, but they * will never be larger than the maximum. */ typedef void *(*softfilter_create_t)(const struct softfilter_config *config, unsigned in_fmt, unsigned out_fmt, @@ -137,13 +137,13 @@ typedef void *(*softfilter_create_t)(const struct softfilter_config *config, typedef void (*softfilter_destroy_t)(void *data); /* Given an input size, query the output size of the filter. - * If width and height == max_width/max_height, no other combination + * If width and height == max_width/max_height, no other combination * of width/height must return a larger size in any dimension. */ typedef void (*softfilter_query_output_size_t)(void *data, unsigned *out_width, unsigned *out_height, unsigned width, unsigned height); -/* First step of processing a frame. The filter submits work by +/* First step of processing a frame. The filter submits work by * filling in the packets array. * * The number of elements in the array is as returned by query_num_threads. @@ -155,8 +155,8 @@ typedef void (*softfilter_get_work_packets_t)(void *data, const void *input, unsigned width, unsigned height, size_t input_stride); /* Returns the number of worker threads the filter will use. - * This can differ from the value passed to create() instead the filter - * cannot be parallelized, etc. The number of threads must be less-or-equal + * This can differ from the value passed to create() instead the filter + * cannot be parallelized, etc. The number of threads must be less-or-equal * compared to the value passed to create(). */ typedef unsigned (*softfilter_query_num_threads_t)(void *data); diff --git a/gfx/video_filters/super2xsai.c b/gfx/video_filters/super2xsai.c index 1d5c2bf309..f9dc321a9c 100644 --- a/gfx/video_filters/super2xsai.c +++ b/gfx/video_filters/super2xsai.c @@ -201,7 +201,7 @@ static void supertwoxsai_generic_destroy(void *data) #endif static void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, - int first, int last, uint32_t *src, + int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) { unsigned finish; @@ -221,7 +221,7 @@ static void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, // 1 2 3 S1 // A1 A2 //-------------------------------------- - + supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_xrgb8888, supertwoxsai_interpolate2_xrgb8888); } @@ -231,7 +231,7 @@ static void supertwoxsai_generic_xrgb8888(unsigned width, unsigned height, } static void supertwoxsai_generic_rgb565(unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { unsigned finish; @@ -251,7 +251,7 @@ static void supertwoxsai_generic_rgb565(unsigned width, unsigned height, // 1 2 3 S1 // A1 A2 //-------------------------------------- - + supertwoxsai_function(supertwoxsai_result, supertwoxsai_interpolate_rgb565, supertwoxsai_interpolate2_rgb565); } diff --git a/gfx/video_filters/supereagle.c b/gfx/video_filters/supereagle.c index 06b7c4c8c1..a191d104c3 100644 --- a/gfx/video_filters/supereagle.c +++ b/gfx/video_filters/supereagle.c @@ -215,7 +215,7 @@ static void supereagle_generic_destroy(void *data) #endif static void supereagle_generic_xrgb8888(unsigned width, unsigned height, - int first, int last, uint32_t *src, + int first, int last, uint32_t *src, unsigned src_stride, uint32_t *dst, unsigned dst_stride) { unsigned finish; @@ -239,7 +239,7 @@ static void supereagle_generic_xrgb8888(unsigned width, unsigned height, } static void supereagle_generic_rgb565(unsigned width, unsigned height, - int first, int last, uint16_t *src, + int first, int last, uint16_t *src, unsigned src_stride, uint16_t *dst, unsigned dst_stride) { unsigned finish; diff --git a/gfx/video_shader_parse.c b/gfx/video_shader_parse.c index e8f18968a7..3194beb4c8 100644 --- a/gfx/video_shader_parse.c +++ b/gfx/video_shader_parse.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -79,7 +79,7 @@ static const char *wrap_mode_to_str(enum gfx_wrap_type type) return "???"; } -/** +/** * wrap_str_to_mode: * @type : Wrap type in human-readable string format. * @@ -108,7 +108,7 @@ static enum gfx_wrap_type wrap_str_to_mode(const char *wrap_mode) return RARCH_WRAP_DEFAULT; } -/** +/** * video_shader_parse_pass: * @conf : Preset file to read from. * @pass : Shader passes handle. @@ -144,10 +144,10 @@ static bool video_shader_parse_pass(config_file_t *conf, float fattr = 0.0f; int iattr = 0; - fp_fbo_buf[0] = mipmap_buf[0] = alias_buf[0] = + fp_fbo_buf[0] = mipmap_buf[0] = alias_buf[0] = scale_name_buf[0] = attr_name_buf[0] = scale_type[0] = scale_type_x[0] = scale_type_y[0] = frame_count_mod[0] = - tmp_str[0] = shader_name[0] = filter_name_buf[0] = + tmp_str[0] = shader_name[0] = filter_name_buf[0] = wrap_name_buf[0] = wrap_mode[0] = frame_count_mod_buf[0] = '\0'; srgb_output_buf[0] = '\0'; @@ -332,7 +332,7 @@ error: return false; } -/** +/** * video_shader_parse_textures: * @conf : Preset file to read from. * @shader : Shader pass handle. @@ -385,7 +385,7 @@ static bool video_shader_parse_textures(config_file_t *conf, if (path_file_exists(tmp_path)) { - strlcpy(shader->lut[shader->luts].path, + strlcpy(shader->lut[shader->luts].path, tmp_path, sizeof(shader->lut[shader->luts].path)); } @@ -394,7 +394,7 @@ static bool video_shader_parse_textures(config_file_t *conf, snprintf(id_filter, sizeof(id_filter), "%s_linear", id); if (config_get_bool(conf, id_filter, &smooth)) - shader->lut[shader->luts].filter = smooth ? + shader->lut[shader->luts].filter = smooth ? RARCH_FILTER_LINEAR : RARCH_FILTER_NEAREST; else shader->lut[shader->luts].filter = RARCH_FILTER_UNSPEC; @@ -420,7 +420,7 @@ error: return false; } -/** +/** * video_shader_parse_find_parameter: * @params : Shader parameter handle. * @num_params : Number of shader params in @params. @@ -445,7 +445,7 @@ static struct video_shader_parameter *video_shader_parse_find_parameter( return NULL; } -/** +/** * video_shader_set_current_parameters: * @conf : Preset file to read from. * @shader : Shader passes handle. @@ -478,10 +478,10 @@ bool video_shader_resolve_current_parameters(config_file_t *conf, return true; } - for (id = strtok_r(parameters, ";", &save); id; + for (id = strtok_r(parameters, ";", &save); id; id = strtok_r(NULL, ";", &save)) { - struct video_shader_parameter *parameter = + struct video_shader_parameter *parameter = (struct video_shader_parameter*) video_shader_parse_find_parameter( shader->parameters, shader->num_parameters, id); @@ -500,12 +500,12 @@ bool video_shader_resolve_current_parameters(config_file_t *conf, return true; } -/** +/** * video_shader_resolve_parameters: * @conf : Preset file to read from. * @shader : Shader passes handle. * - * Resolves all shader parameters belonging to shaders. + * Resolves all shader parameters belonging to shaders. * * Returns: true (1) if successful, otherwise false (0). **/ @@ -595,12 +595,12 @@ bool video_shader_resolve_parameters(config_file_t *conf, return true; } -/** +/** * video_shader_parse_imports: * @conf : Preset file to read from. * @shader : Shader passes handle. * - * Resolves import parameters belonging to shaders. + * Resolves import parameters belonging to shaders. * * Returns: true (1) if successful, otherwise false (0). **/ @@ -615,7 +615,7 @@ static bool video_shader_parse_imports(config_file_t *conf, imports[0] = tmp_str[0] = '\0'; - if (!config_get_array(conf, "imports", imports, + if (!config_get_array(conf, "imports", imports, 1024 * sizeof(char))) { free(imports); @@ -637,10 +637,10 @@ static bool video_shader_parse_imports(config_file_t *conf, unsigned addr = 0; unsigned mask = 0; unsigned equal = 0; - struct state_tracker_uniform_info *var = + struct state_tracker_uniform_info *var = &shader->variable[shader->variables]; - semantic_buf[0] = wram_buf[0] = input_slot_buf[0] = + semantic_buf[0] = wram_buf[0] = input_slot_buf[0] = mask_buf[0] = equal_buf[0] = semantic[0] = '\0'; strlcpy(var->id, id, sizeof(var->id)); @@ -739,13 +739,13 @@ error: return false; } -/** +/** * video_shader_read_conf_cgp: * @conf : Preset file to read from. * @shader : Shader passes handle. * * Loads preset file and all associated state (passes, - * textures, imports, etc). + * textures, imports, etc). * * Returns: true (1) if successful, otherwise false (0). **/ @@ -925,13 +925,13 @@ static void shader_write_variable(config_file_t *conf, } } -/** +/** * video_shader_write_conf_cgp: * @conf : Preset file to read from. * @shader : Shader passes handle. * * Saves preset and all associated state (passes, - * textures, imports, etc) to disk. + * textures, imports, etc) to disk. **/ void video_shader_write_conf_cgp(config_file_t *conf, struct video_shader *shader) @@ -1001,7 +1001,7 @@ void video_shader_write_conf_cgp(config_file_t *conf, } config_set_string(conf, "parameters", parameters); - + for (i = 0; i < shader->num_parameters; i++) config_set_float(conf, shader->parameters[i].id, shader->parameters[i].current); @@ -1038,7 +1038,7 @@ void video_shader_write_conf_cgp(config_file_t *conf, if (shader->lut[i].filter != RARCH_FILTER_UNSPEC) { snprintf(key, sizeof(key), "%s_linear", shader->lut[i].id); - config_set_bool(conf, key, + config_set_bool(conf, key, shader->lut[i].filter == RARCH_FILTER_LINEAR); } @@ -1087,7 +1087,7 @@ void video_shader_write_conf_cgp(config_file_t *conf, * Parses type of shader. * * Returns: value of shader type on success, otherwise will return - * user-supplied @fallback value. + * user-supplied @fallback value. **/ enum rarch_shader_type video_shader_parse_type(const char *path, enum rarch_shader_type fallback) @@ -1127,7 +1127,7 @@ enum rarch_shader_type video_shader_parse_type(const char *path, { case GFX_CTX_OPENGL_API: case GFX_CTX_OPENGL_ES_API: - if (shader_type == RARCH_SHADER_GLSL + if (shader_type == RARCH_SHADER_GLSL || (cg_supported && shader_type == RARCH_SHADER_CG)) return shader_type; break; @@ -1165,7 +1165,7 @@ void video_shader_resolve_relative(struct video_shader *shader, unsigned i; size_t tmp_path_size = 4096 * sizeof(char); char *tmp_path = (char*)malloc(4096 * sizeof(char)); - + tmp_path[0] = '\0'; for (i = 0; i < shader->passes; i++) diff --git a/gfx/video_shader_parse.h b/gfx/video_shader_parse.h index 4dcbabfcf7..cb79c1f09c 100644 --- a/gfx/video_shader_parse.h +++ b/gfx/video_shader_parse.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -67,7 +67,7 @@ enum enum gfx_wrap_type { - RARCH_WRAP_BORDER = 0, /* Kinda deprecated, but keep as default. + RARCH_WRAP_BORDER = 0, /* Kinda deprecated, but keep as default. Will be translated to EDGE in GLES. */ RARCH_WRAP_DEFAULT = RARCH_WRAP_BORDER, RARCH_WRAP_EDGE, @@ -157,26 +157,26 @@ struct video_shader struct state_tracker_uniform_info variable[GFX_MAX_VARIABLES]; }; -/** +/** * video_shader_read_conf_cgp: * @conf : Preset file to read from. * @shader : Shader passes handle. * * Loads preset file and all associated state (passes, - * textures, imports, etc). + * textures, imports, etc). * * Returns: true (1) if successful, otherwise false (0). **/ bool video_shader_read_conf_cgp(config_file_t *conf, struct video_shader *shader); -/** +/** * video_shader_write_conf_cgp: * @conf : Preset file to read from. * @shader : Shader passes handle. * * Saves preset and all associated state (passes, - * textures, imports, etc) to disk. + * textures, imports, etc) to disk. **/ void video_shader_write_conf_cgp(config_file_t *conf, struct video_shader *shader); @@ -192,7 +192,7 @@ void video_shader_write_conf_cgp(config_file_t *conf, void video_shader_resolve_relative(struct video_shader *shader, const char *ref_path); -/** +/** * video_shader_resolve_parameters: * @conf : Preset file to read from. * @shader : Shader passes handle. @@ -204,12 +204,12 @@ void video_shader_resolve_relative(struct video_shader *shader, bool video_shader_resolve_current_parameters(config_file_t *conf, struct video_shader *shader); -/** +/** * video_shader_resolve_parameters: * @conf : Preset file to read from. * @shader : Shader passes handle. * - * Resolves all shader parameters belonging to shaders. + * Resolves all shader parameters belonging to shaders. * * Returns: true (1) if successful, otherwise false (0). **/ @@ -225,7 +225,7 @@ bool video_shader_resolve_parameters(config_file_t *conf, * Parses type of shader. * * Returns: value of shader type on success, otherwise will return - * user-supplied @fallback value. + * user-supplied @fallback value. **/ enum rarch_shader_type video_shader_parse_type(const char *path, enum rarch_shader_type fallback); diff --git a/gfx/video_state_tracker.c b/gfx/video_state_tracker.c index 8cebede20f..a36a50f8fb 100644 --- a/gfx/video_state_tracker.c +++ b/gfx/video_state_tracker.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -54,7 +54,7 @@ struct state_tracker_internal uint32_t prev[2]; int frame_count; int frame_count_prev; - uint32_t old_value; + uint32_t old_value; int transition_count; }; @@ -121,7 +121,7 @@ state_tracker_t* state_tracker_init(const struct state_tracker_info *info) tracker->info[i].addr = info->info[i].addr; tracker->info[i].type = info->info[i].type; - tracker->info[i].mask = (info->info[i].mask == 0) + tracker->info[i].mask = (info->info[i].mask == 0) ? 0xffff : info->info[i].mask; tracker->info[i].equal = info->info[i].equal; @@ -250,13 +250,13 @@ static void state_tracker_update_element( } uniform->value = info->frame_count_prev; break; - + #ifdef HAVE_PYTHON case RARCH_STATE_PYTHON: uniform->value = py_state_get(info->py, info->id, frame_count); break; #endif - + default: break; } @@ -282,7 +282,7 @@ unsigned state_tracker_get_uniform(state_tracker_t *tracker, unsigned elem, unsigned frame_count) { unsigned i, elems = elem; - + if (tracker->info_elem < elem) elems = tracker->info_elem; diff --git a/gfx/video_state_tracker.h b/gfx/video_state_tracker.h index abcd2e27e8..649f48e420 100644 --- a/gfx/video_state_tracker.h +++ b/gfx/video_state_tracker.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/gfx/video_thread_wrapper.c b/gfx/video_thread_wrapper.c index 59739117f4..3fc697d260 100644 --- a/gfx/video_thread_wrapper.c +++ b/gfx/video_thread_wrapper.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -590,7 +590,7 @@ static void video_thread_loop(void *data) if (thr->frame.updated) updated = true; - /* To avoid race condition where send_cmd is updated + /* To avoid race condition where send_cmd is updated * right after the switch is checked. */ pkt = thr->cmd_data; @@ -721,7 +721,7 @@ static bool video_thread_frame(void *data, const void *frame_, uint8_t *dst = NULL; thread_video_t *thr = (thread_video_t*)data; - /* If called from within read_viewport, we're actually in the + /* If called from within read_viewport, we're actually in the * driver thread, so just render directly. */ if (thr->frame.within_thread) { @@ -733,7 +733,7 @@ static bool video_thread_frame(void *data, const void *frame_, return false; } - copy_stride = width * (thr->info.rgb32 + copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); src = (const uint8_t*)frame_; @@ -762,7 +762,7 @@ static bool video_thread_frame(void *data, const void *frame_, } } - /* Drop frame if updated flag is still set, as thread is + /* Drop frame if updated flag is still set, as thread is * still working on last frame. */ if (!thr->frame.updated) { @@ -875,13 +875,13 @@ static void video_thread_set_viewport(void *data, unsigned width, thread_video_t *thr = (thread_video_t*)data; if (!thr) return; - + slock_lock(thr->lock); if (thr->driver && thr->driver->set_viewport) thr->driver->set_viewport(thr->driver_data, width, height, force_full, allow_rotate); - + slock_unlock(thr->lock); } @@ -898,10 +898,10 @@ static void video_thread_set_rotation(void *data, unsigned rotation) video_thread_send_and_wait_user_to_thread(thr, &pkt); } -/* This value is set async as stalling on the video driver for +/* This value is set async as stalling on the video driver for * every query is too slow. * - * This means this value might not be correct, so viewport + * This means this value might not be correct, so viewport * reads are not supported for now. */ static void video_thread_viewport_info(void *data, struct video_viewport *vp) { @@ -983,7 +983,7 @@ static bool thread_overlay_load(void *data, { thread_video_t *thr = (thread_video_t*)data; thread_packet_t pkt = { CMD_OVERLAY_LOAD }; - const struct texture_image *images = + const struct texture_image *images = (const struct texture_image*)image_data; if (!thr) @@ -1162,7 +1162,7 @@ static void thread_set_texture_frame(void *data, const void *frame, thread_video_t *thr = (thread_video_t*)data; slock_lock(thr->frame.lock); - required = width * height * + required = width * height * (rgb32 ? sizeof(uint32_t) : sizeof(uint16_t)); if (required > thr->texture.frame_cap) @@ -1246,7 +1246,7 @@ static void thread_apply_state_changes(void *data) slock_unlock(thr->frame.lock); } -/* This is read-only state which should not +/* This is read-only state which should not * have any kind of race condition. */ static struct video_shader *thread_get_current_shader(void *data) { @@ -1352,7 +1352,7 @@ static void video_thread_set_callbacks( * @out_driver : Output video driver * @out_data : Output video data * @input : Input input driver - * @input_data : Input input data + * @input_data : Input input data * @driver : Input Video driver * @info : Video info handle. * @@ -1381,7 +1381,7 @@ bool video_init_thread(const video_driver_t **out_driver, * video_thread_get_ptr: * @drv : Found driver. * - * Gets the underlying video driver associated with the + * Gets the underlying video driver associated with the * threaded video wrapper. Sets @drv to the found * video driver. * diff --git a/gfx/video_thread_wrapper.h b/gfx/video_thread_wrapper.h index 31c2010cff..3fd306590a 100644 --- a/gfx/video_thread_wrapper.h +++ b/gfx/video_thread_wrapper.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -43,7 +43,7 @@ typedef struct thread_video thread_video_t; * @out_driver : Output video driver * @out_data : Output video data * @input : Input input driver - * @input_data : Input input data + * @input_data : Input input data * @driver : Input Video driver * @info : Video info handle. * @@ -61,7 +61,7 @@ bool video_init_thread( * video_thread_get_ptr: * @drv : Found driver. * - * Gets the underlying video driver associated with the + * Gets the underlying video driver associated with the * threaded video wrapper. Sets @drv to the found * video driver. * diff --git a/input/common/input_x11_common.c b/input/common/input_x11_common.c index d9598496e0..dbbe53fc43 100644 --- a/input/common/input_x11_common.c +++ b/input/common/input_x11_common.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/input/common/input_x11_common.h b/input/common/input_x11_common.h index 4d325e4525..a0cd0342d5 100644 --- a/input/common/input_x11_common.h +++ b/input/common/input_x11_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/input/common/linux_common.c b/input/common/linux_common.c index 17825654a3..0d35611db1 100644 --- a/input/common/linux_common.c +++ b/input/common/linux_common.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -77,9 +77,9 @@ bool linux_terminal_init(void) void linux_terminal_claim_stdin(void) { - /* We need to disable use of stdin command interface if + /* We need to disable use of stdin command interface if * stdin is supposed to be used for input. */ - linux_stdin_claimed = true; + linux_stdin_claimed = true; } bool linux_terminal_grab_stdin(void *data) @@ -114,7 +114,7 @@ bool linux_terminal_disable_input(void) sa.sa_flags = SA_RESTART | SA_RESETHAND; sigemptyset(&sa.sa_mask); - /* Trap some standard termination codes so we + /* Trap some standard termination codes so we * can restore the keyboard before we lose control. */ sigaction(SIGABRT, &sa, NULL); sigaction(SIGBUS, &sa, NULL); diff --git a/input/common/linux_common.h b/input/common/linux_common.h index b924b7246d..701adbbd88 100644 --- a/input/common/linux_common.h +++ b/input/common/linux_common.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/input/connect/connect_ps4.c b/input/connect/connect_ps4.c index dcdd88a41e..ee5ead5c32 100644 --- a/input/connect/connect_ps4.c +++ b/input/connect/connect_ps4.c @@ -188,7 +188,7 @@ static bool hidpad_ps4_check_dpad(struct ps4 *rpt, unsigned id) static void hidpad_ps4_get_buttons(void *data, retro_bits_t* state) { struct hidpad_ps4_data *device = (struct hidpad_ps4_data*)data; - struct ps4 *rpt = device ? + struct ps4 *rpt = device ? (struct ps4*)&device->data : NULL; if (!device || !rpt) diff --git a/input/connect/connect_wiiupro.c b/input/connect/connect_wiiupro.c index 6356fc94fa..c3787bbe3c 100644 --- a/input/connect/connect_wiiupro.c +++ b/input/connect/connect_wiiupro.c @@ -121,7 +121,7 @@ static void hidpad_wiiupro_deinit(void *data) static void hidpad_wiiupro_get_buttons(void *data, retro_bits_t *state) { struct hidpad_wiiupro_data *device = (struct hidpad_wiiupro_data*)data; - struct wiiupro *rpt = device ? + struct wiiupro *rpt = device ? (struct wiiupro*)&device->data : NULL; if (!device || !rpt) diff --git a/input/drivers/android_input.c b/input/drivers/android_input.c index f25477e372..2eb4884bce 100644 --- a/input/drivers/android_input.c +++ b/input/drivers/android_input.c @@ -150,7 +150,7 @@ static void *libandroid_handle; static bool android_input_lookup_name_prekitkat(char *buf, int *vendorId, int *productId, size_t size, int id) -{ +{ jobject name = NULL; jmethodID getName = NULL; jobject device = NULL; @@ -502,9 +502,9 @@ static void *android_input_init(const char *joypad_driver) android->pads_connected = 0; android->quick_tap_time = 0; android->joypad = input_joypad_init_driver(joypad_driver, android); - + input_keymaps_init_keyboard_lut(rarch_key_map_android); - + frontend_android_get_version_sdk(&sdk); RARCH_LOG("sdk version: %d\n", sdk); @@ -528,7 +528,7 @@ static void *android_input_init(const char *joypad_driver) static int android_check_quick_tap(android_input_t *android) { - /* Check if the touch screen has been been quick tapped + /* Check if the touch screen has been been quick tapped * and then not touched again for 200ms * If so then return true and deactivate quick tap timer */ retro_time_t now = cpu_features_get_time_usec(); @@ -604,7 +604,7 @@ static int16_t android_lightgun_device_state(android_input_t *android, unsigned static INLINE void android_mouse_calculate_deltas(android_input_t *android, AInputEvent *event,size_t motion_ptr) { - /* Adjust mouse speed based on ratio + /* Adjust mouse speed based on ratio * between core resolution and system resolution */ float x, y; float x_scale = 1; @@ -663,7 +663,7 @@ static INLINE int android_input_poll_event_type_motion( (source == AINPUT_SOURCE_MOUSE && action != AMOTION_EVENT_ACTION_DOWN); - /* If source is mouse then calculate button state + /* If source is mouse then calculate button state * and mouse deltas and don't process as touchscreen event */ if (source == AINPUT_SOURCE_MOUSE) { @@ -677,7 +677,7 @@ static INLINE int android_input_poll_event_type_motion( } else { - /* If getButtonState is not available + /* If getButtonState is not available * then treat all MotionEvent.ACTION_DOWN as left button presses */ if (action == AMOTION_EVENT_ACTION_DOWN) android->mouse_l = 1; @@ -694,7 +694,7 @@ static INLINE int android_input_poll_event_type_motion( { if(action == AMOTION_EVENT_ACTION_UP && ENABLE_TOUCH_SCREEN_MOUSE) { - /* If touchscreen was pressed for less than 200ms + /* If touchscreen was pressed for less than 200ms * then register time stamp of a quick tap */ if((AMotionEvent_getEventTime(event)-AMotionEvent_getDownTime(event))/1000000 < 200) android->quick_tap_time = AMotionEvent_getEventTime(event); @@ -713,14 +713,14 @@ static INLINE int android_input_poll_event_type_motion( if(action == AMOTION_EVENT_ACTION_DOWN && ENABLE_TOUCH_SCREEN_MOUSE) { - /* When touch screen is pressed, set mouse + /* When touch screen is pressed, set mouse * previous position to current position * before starting to calculate mouse movement deltas. */ android->mouse_x_prev = AMotionEvent_getX(event, motion_ptr); android->mouse_y_prev = AMotionEvent_getY(event, motion_ptr); - /* If another touch happened within 200ms after a quick tap - * then cancel the quick tap and register left mouse button + /* If another touch happened within 200ms after a quick tap + * then cancel the quick tap and register left mouse button * as being held down */ if((AMotionEvent_getEventTime(event) - android->quick_tap_time)/1000000 < 200) { @@ -759,7 +759,7 @@ static INLINE int android_input_poll_event_type_motion( } } - /* If more than one pointer detected + /* If more than one pointer detected * then count it as a mouse right click */ if (ENABLE_TOUCH_SCREEN_MOUSE) android->mouse_r = (android->pointer_count == 2); @@ -920,7 +920,7 @@ static void handle_hotplug(android_input_t *android, android->pads_connected, device_name, id, pad_id1, pad_id2); #endif /* remove the remote or virtual controller device if it is mapped */ - if (strstr(android->pad_states[0].name,"SHIELD Remote") || + if (strstr(android->pad_states[0].name,"SHIELD Remote") || strstr(android->pad_states[0].name,"SHIELD Virtual Controller")) { pad_id1 = -1; @@ -930,7 +930,7 @@ static void handle_hotplug(android_input_t *android, strlcpy(name_buf, device_name, sizeof(name_buf)); } - /* if the actual controller has not been mapped yet, + /* if the actual controller has not been mapped yet, * then configure Virtual device for now */ if (strstr(device_name, "Virtual") && android->pads_connected==0) strlcpy (name_buf, "SHIELD Virtual Controller", sizeof(name_buf)); @@ -940,7 +940,7 @@ static void handle_hotplug(android_input_t *android, /* apply the hack only for the first controller * store the id for later use */ - if (strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03") + if (strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03") && android->pads_connected==0) pad_id1 = id; else if (strstr(device_name, "Virtual") && pad_id1 != -1) @@ -969,7 +969,7 @@ static void handle_hotplug(android_input_t *android, strlcpy (name_buf, "NVIDIA SHIELD Portable", sizeof(name_buf)); } } - + else if(strstr(device_model, "SHIELD") && ( strstr(device_name, "Virtual") || strstr(device_name, "gpio") || strstr(device_name, "NVIDIA Corporation NVIDIA Controller v01.03"))) @@ -1025,9 +1025,9 @@ static void handle_hotplug(android_input_t *android, * This device is composed of two hid devices * We make it look like one device */ - else if(strstr(device_model, "R800") && + else if(strstr(device_model, "R800") && ( - strstr(device_name, "keypad-game-zeus") || + strstr(device_name, "keypad-game-zeus") || strstr(device_name, "keypad-zeus") ) ) @@ -1199,7 +1199,7 @@ static void android_input_poll_input(void *data) if (port < 0 && !is_keyboard_id(id)) handle_hotplug(android, android_app, &port, id, source); - + switch (type_event) { case AINPUT_EVENT_TYPE_MOTION: @@ -1267,28 +1267,28 @@ static void android_input_poll_memcpy(void *data) } } -static bool android_input_key_pressed(void *data, int key) -{ +static bool android_input_key_pressed(void *data, int key) +{ rarch_joypad_info_t joypad_info; - android_input_t *android = (android_input_t*)data; + android_input_t *android = (android_input_t*)data; const struct retro_keybind *keyptr = (const struct retro_keybind*) &input_config_binds[0][key]; - if( keyptr->valid + if( keyptr->valid && android_keyboard_port_input_pressed(input_config_binds[0], - key)) - return true; + key)) + return true; joypad_info.joy_idx = 0; joypad_info.auto_binds = input_autoconf_binds[0]; joypad_info.axis_threshold = *(input_driver_get_float(INPUT_ACTION_AXIS_THRESHOLD)); - if (keyptr->valid && + if (keyptr->valid && input_joypad_pressed(android->joypad, joypad_info, - 0, input_config_binds[0], key)) - return true; + 0, input_config_binds[0], key)) + return true; - return false; + return false; } /* Handle all events. If our activity is in pause state, @@ -1317,7 +1317,7 @@ static void android_input_poll(void *data) android_input_poll_main_cmd(); break; } - + if (android_app->destroyRequested != 0) { rarch_ctl(RARCH_CTL_SET_SHUTDOWN, NULL); diff --git a/input/drivers/cocoa_input.h b/input/drivers/cocoa_input.h index 33194837f5..62f21b4904 100644 --- a/input/drivers/cocoa_input.h +++ b/input/drivers/cocoa_input.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2013-2014 - Jason Fetters - * + * * 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. diff --git a/input/drivers/ctr_input.c b/input/drivers/ctr_input.c index 9871a9669d..359dc9f5eb 100644 --- a/input/drivers/ctr_input.c +++ b/input/drivers/ctr_input.c @@ -45,7 +45,7 @@ static void ctr_input_poll(void *data) ctr->joypad->poll(); } -static int16_t ctr_input_state(void *data, +static int16_t ctr_input_state(void *data, rarch_joypad_info_t joypad_info, const struct retro_keybind **binds, unsigned port, unsigned device, diff --git a/input/drivers/gx_input.c b/input/drivers/gx_input.c index b4daff900d..cecbc92643 100644 --- a/input/drivers/gx_input.c +++ b/input/drivers/gx_input.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. diff --git a/input/drivers/linuxraw_input.c b/input/drivers/linuxraw_input.c index eee4a70cd6..5c2b780e9a 100644 --- a/input/drivers/linuxraw_input.c +++ b/input/drivers/linuxraw_input.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2012-2015 - 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- * ation, either version 3 of the License, or (at your option) any later version. @@ -113,7 +113,7 @@ static int16_t linuxraw_input_state(void *data, linuxraw->state[rarch_keysym_lut[(enum retro_key)binds[port][id].key]] ); if (!ret) - ret = input_joypad_pressed(linuxraw->joypad, + ret = input_joypad_pressed(linuxraw->joypad, joypad_info, port, binds[port], id); return ret; case RETRO_DEVICE_ANALOG: diff --git a/input/drivers/nullinput.c b/input/drivers/nullinput.c index 78498f88dc..edb3c93e3e 100644 --- a/input/drivers/nullinput.c +++ b/input/drivers/nullinput.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/input/drivers/ps3_input.c b/input/drivers/ps3_input.c index b5e2037027..8edc841960 100644 --- a/input/drivers/ps3_input.c +++ b/input/drivers/ps3_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -76,7 +76,7 @@ static int16_t ps3_mouse_device_state(ps3_input_t *ps3, { CellMouseData mouse_state; cellMouseGetData(id, &mouse_state); - + if (!ps3->mice_connected) return 0; @@ -205,8 +205,8 @@ static bool ps3_input_set_sensor_state(void *data, unsigned port, { case RETRO_SENSOR_ACCELEROMETER_ENABLE: cellPadGetInfo2(&pad_info); - if ((pad_info.device_capability[port] - & CELL_PAD_CAPABILITY_SENSOR_MODE) + if ((pad_info.device_capability[port] + & CELL_PAD_CAPABILITY_SENSOR_MODE) != CELL_PAD_CAPABILITY_SENSOR_MODE) return false; diff --git a/input/drivers/rwebinput_input.c b/input/drivers/rwebinput_input.c index 9d2fde4d96..3506b7e029 100644 --- a/input/drivers/rwebinput_input.c +++ b/input/drivers/rwebinput_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2015 - Michael Lelli * Copyright (C) 2011-2017 - 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. @@ -71,7 +71,7 @@ static bool rwebinput_key_pressed_internal(void *data, int key) unsigned sym; bool ret; rwebinput_input_t *rwebinput = (rwebinput_input_t*)data; - + if (key >= RETROK_LAST) return false; @@ -95,7 +95,7 @@ static bool rwebinput_is_pressed(rwebinput_input_t *rwebinput, { const struct retro_keybind *bind = &binds[id]; int key = binds[id].key; - return bind->valid && (key < RETROK_LAST) + return bind->valid && (key < RETROK_LAST) && rwebinput_key_pressed_internal(rwebinput, key); } diff --git a/input/drivers/sdl_input.c b/input/drivers/sdl_input.c index 5b462d55ff..5376f2b9ce 100644 --- a/input/drivers/sdl_input.c +++ b/input/drivers/sdl_input.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2014-2015 - Higor Euripedes - * + * * 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. @@ -96,7 +96,7 @@ static bool sdl_input_meta_key_pressed(void *data, int key) static int16_t sdl_joypad_device_state(sdl_input_t *sdl, rarch_joypad_info_t joypad_info, - const struct retro_keybind *binds, + const struct retro_keybind *binds, unsigned port, unsigned id, enum input_device_type *device) { if ((binds[id].key < RETROK_LAST) && sdl_key_pressed(binds[id].key)) @@ -200,9 +200,9 @@ static int16_t sdl_lightgun_device_state(sdl_input_t *sdl, unsigned id) case RETRO_DEVICE_ID_LIGHTGUN_TURBO: return sdl->mouse_r; case RETRO_DEVICE_ID_LIGHTGUN_START: - return sdl->mouse_m && sdl->mouse_r; + return sdl->mouse_m && sdl->mouse_r; case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: - return sdl->mouse_m && sdl->mouse_l; + return sdl->mouse_m && sdl->mouse_l; } return 0; diff --git a/input/drivers/wayland_input.c b/input/drivers/wayland_input.c index 21ff484568..6fab41d99f 100644 --- a/input/drivers/wayland_input.c +++ b/input/drivers/wayland_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2015 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -87,9 +87,9 @@ static int16_t input_wl_lightgun_state(input_ctx_wayland_data_t *wl, unsigned id case RETRO_DEVICE_ID_LIGHTGUN_TURBO: return wl->mouse.right; case RETRO_DEVICE_ID_LIGHTGUN_START: - return wl->mouse.middle && wl->mouse.right; + return wl->mouse.middle && wl->mouse.right; case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: - return wl->mouse.middle && wl->mouse.left; + return wl->mouse.middle && wl->mouse.left; } return 0; @@ -129,14 +129,14 @@ static int16_t input_wl_analog_pressed(input_ctx_wayland_data_t *wl, input_conv_analog_id_to_bind_id(idx, id, &id_minus, &id_plus); - if (binds - && binds[id_minus].valid + if (binds + && binds[id_minus].valid && (id_minus < RARCH_BIND_LIST_END) && BIT_GET(wl->key_state, rarch_keysym_lut[binds[id_minus].key]) ) pressed_minus = -0x7fff; - if (binds - && binds[id_plus].valid + if (binds + && binds[id_plus].valid && (id_plus < RARCH_BIND_LIST_END) && BIT_GET(wl->key_state, rarch_keysym_lut[binds[id_plus].key]) ) diff --git a/input/drivers/winraw_input.c b/input/drivers/winraw_input.c index fa6011291d..2b15c53c1b 100644 --- a/input/drivers/winraw_input.c +++ b/input/drivers/winraw_input.c @@ -1,857 +1,857 @@ -/* RetroArch - A frontend for libretro. - * Copyright (C) 2011-2017 - 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 "../input_driver.h" -#include "../input_keymaps.h" - -#include "../../configuration.h" -#include "../../gfx/video_driver.h" -#include "../../verbosity.h" - -typedef struct -{ - uint8_t keys[256]; -} winraw_keyboard_t; - -typedef struct -{ - HANDLE hnd; - LONG x, y, dlt_x, dlt_y; - LONG whl_u, whl_d; - bool btn_l, btn_m, btn_r, btn_b4, btn_b5; -} winraw_mouse_t; - -typedef struct -{ - bool kbd_mapp_block; - bool mouse_grab; - winraw_keyboard_t keyboard; - HWND window; - winraw_mouse_t *mice; - const input_device_driver_t *joypad; -} winraw_input_t; - -static winraw_keyboard_t *g_keyboard = NULL; -static winraw_mouse_t *g_mice = NULL; -static unsigned g_mouse_cnt = 0; -static bool g_mouse_xy_mapping_ready = false; -static double g_view_abs_ratio_x = 0.0; -static double g_view_abs_ratio_y = 0.0; - -static HWND winraw_create_window(WNDPROC wnd_proc) -{ - HWND wnd; - WNDCLASSA wc = {0}; - - wc.hInstance = GetModuleHandleA(NULL); - - if (!wc.hInstance) - { - RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError()); - return NULL; - } - - wc.lpfnWndProc = wnd_proc; - wc.lpszClassName = "winraw-input"; - if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) - { - RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError()); - return NULL; - } - - wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, - HWND_MESSAGE, NULL, NULL, NULL); - if (!wnd) - { - RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError()); - goto error; - } - - return wnd; - -error: - UnregisterClassA(wc.lpszClassName, NULL); - return NULL; -} - -static void winraw_destroy_window(HWND wnd) -{ - BOOL r; - - if (!wnd) - return; - - r = DestroyWindow(wnd); - - if (!r) - { - RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError()); - } - - r = UnregisterClassA("winraw-input", NULL); - - if (!r) - { - RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError()); - } -} - -static bool winraw_set_keyboard_input(HWND window) -{ - RAWINPUTDEVICE rid; - BOOL r; - - rid.dwFlags = window ? 0 : RIDEV_REMOVE; - rid.hwndTarget = window; - rid.usUsagePage = 0x01; /* generic desktop */ - rid.usUsage = 0x06; /* keyboard */ - - r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); - - if (!r) - { - RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError()); - return false; - } - - return true; -} - -static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt) -{ - UINT r; - unsigned i; - char name[256]; - UINT name_size = sizeof(name); - - for (i = 0; i < mouse_cnt; ++i) - { - r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size); - if (r == (UINT)-1 || r == 0) - name[0] = '\0'; - RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name); - } -} - -static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt) -{ - UINT i; - POINT crs_pos; - winraw_mouse_t *mice_r = NULL; - unsigned mouse_cnt_r = 0; - RAWINPUTDEVICELIST *devs = NULL; - UINT dev_cnt = 0; - UINT r = GetRawInputDeviceList( - NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); - - if (r == (UINT)-1) - { - RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); - goto error; - } - - devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST)); - if (!devs) - goto error; - - dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); - if (dev_cnt == (UINT)-1) - { - RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); - goto error; - } - - for (i = 0; i < dev_cnt; ++i) - mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0; - - if (mouse_cnt_r) - { - mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t)); - if (!mice_r) - goto error; - - if (!GetCursorPos(&crs_pos)) - goto error; - - for (i = 0; i < mouse_cnt_r; ++i) - { - mice_r[i].x = crs_pos.x; - mice_r[i].y = crs_pos.y; - } - } - - /* count is already checked, so this is safe */ - for (i = mouse_cnt_r = 0; i < dev_cnt; ++i) - { - if (devs[i].dwType == RIM_TYPEMOUSE) - mice_r[mouse_cnt_r++].hnd = devs[i].hDevice; - } - - winraw_log_mice_info(mice_r, mouse_cnt_r); - - *mice = mice_r; - *mouse_cnt = mouse_cnt_r; - - return true; - -error: - free(devs); - free(mice_r); - *mice = NULL; - *mouse_cnt = 0; - return false; -} - -static bool winraw_set_mouse_input(HWND window, bool grab) -{ - RAWINPUTDEVICE rid; - BOOL r; - - if (window) - rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0; - else - rid.dwFlags = RIDEV_REMOVE; - - rid.hwndTarget = window; - rid.usUsagePage = 0x01; /* generic desktop */ - rid.usUsage = 0x02; /* mouse */ - - r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); - - if (!r) - { - RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError()); - return false; - } - - return true; -} - -static int16_t winraw_lightgun_aiming_state(winraw_input_t *wr, - unsigned port, unsigned id) -{ - const int edge_detect = 32700; - struct video_viewport vp; - bool inside = false; - unsigned i; - settings_t *settings = config_get_ptr(); - winraw_mouse_t *mouse = NULL; - int16_t res_x = 0; - int16_t res_y = 0; - int16_t res_screen_x = 0; - int16_t res_screen_y = 0; - - if (port >= MAX_USERS) - return 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return 0; - - vp.x = 0; - vp.y = 0; - vp.width = 0; - vp.height = 0; - vp.full_width = 0; - vp.full_height = 0; - - if ( !( video_driver_translate_coord_viewport_wrap( - &vp, mouse->x, mouse->y, &res_x, &res_y, &res_screen_x, &res_screen_y ) ) ) - { - return 0; - } - - inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); - - switch ( id ) - { - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: - return inside ? res_x : 0; - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: - return inside ? res_y : 0; - case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: - return !inside; - default: - break; - } - - return 0; -} - -static int16_t winraw_mouse_state(winraw_input_t *wr, - unsigned port, bool abs, unsigned id) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - winraw_mouse_t *mouse = NULL; - - if (port >= MAX_USERS) - return 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return 0; - - switch (id) - { - case RETRO_DEVICE_ID_MOUSE_X: - return abs ? mouse->x : mouse->dlt_x; - case RETRO_DEVICE_ID_MOUSE_Y: - return abs ? mouse->y : mouse->dlt_y; - case RETRO_DEVICE_ID_MOUSE_LEFT: - return mouse->btn_l ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_RIGHT: - return mouse->btn_r ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_WHEELUP: - return mouse->whl_u ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: - return mouse->whl_d ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_MIDDLE: - return mouse->btn_m ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_BUTTON_4: - return mouse->btn_b4 ? 1 : 0; - case RETRO_DEVICE_ID_MOUSE_BUTTON_5: - return mouse->btn_b5 ? 1 : 0; - } - - return 0; -} - -static bool winraw_keyboard_pressed(winraw_input_t *wr, unsigned key) -{ - unsigned k = rarch_keysym_lut[(enum retro_key)key]; - return wr->keyboard.keys[k]; -} - -static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key) -{ - unsigned i; - winraw_mouse_t *mouse = NULL; - settings_t *settings = config_get_ptr(); - - if (port >= MAX_USERS) - return false; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return false; - - switch ( key ) - { - - case RETRO_DEVICE_ID_MOUSE_LEFT: - return mouse->btn_l; - case RETRO_DEVICE_ID_MOUSE_RIGHT: - return mouse->btn_r; - case RETRO_DEVICE_ID_MOUSE_MIDDLE: - return mouse->btn_m; - case RETRO_DEVICE_ID_MOUSE_BUTTON_4: - return mouse->btn_b4; - case RETRO_DEVICE_ID_MOUSE_BUTTON_5: - return mouse->btn_b5; - case RETRO_DEVICE_ID_MOUSE_WHEELUP: - return mouse->whl_u; - case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: - return mouse->whl_d; - } - - return false; -} - -static bool winraw_is_pressed(winraw_input_t *wr, - rarch_joypad_info_t joypad_info, - const struct retro_keybind *binds, - unsigned port, unsigned id) -{ - const struct retro_keybind *bind = &binds[id]; - - if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && winraw_keyboard_pressed(wr, bind->key)) - return true; - if (binds && binds[id].valid) - { - if (winraw_mbutton_pressed(wr, port, bind->mbutton)) - return true; - if (input_joypad_pressed(wr->joypad, joypad_info, port, binds, id)) - return true; - } - - return false; -} - -static void winraw_init_mouse_xy_mapping() -{ - struct video_viewport viewport; - int center_x; - int center_y; - unsigned i; - - if (video_driver_get_viewport_info(&viewport)) - { - center_x = viewport.x + viewport.width / 2; - center_y = viewport.y + viewport.height / 2; - - for (i = 0; i < g_mouse_cnt; ++i) - { - g_mice[i].x = center_x; - g_mice[i].y = center_y; - } - - g_view_abs_ratio_x = (double)viewport.full_width / 65535.0; - g_view_abs_ratio_y = (double)viewport.full_height / 65535.0; - - g_mouse_xy_mapping_ready = true; - } -} - -static int16_t winraw_deprecated_lightgun_state(winraw_input_t *wr, - unsigned port, unsigned id) -{ - unsigned i; - settings_t *settings = config_get_ptr(); - winraw_mouse_t *mouse = NULL; - - if (port >= MAX_USERS) - return 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - if (i == settings->uints.input_mouse_index[port]) - { - mouse = &wr->mice[i]; - break; - } - } - - if (!mouse) - return 0; - - switch (id) - { - case RETRO_DEVICE_ID_LIGHTGUN_X: - return mouse->dlt_x; - case RETRO_DEVICE_ID_LIGHTGUN_Y: - return mouse->dlt_y; - } - - return 0; -} - -static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state) -{ - POINT crs_pos; - - if (state->usFlags & MOUSE_MOVE_ABSOLUTE) - { - if (g_mouse_xy_mapping_ready) - { - state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX); - state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY); - InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x); - InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y); - mouse->x = state->lLastX; - mouse->y = state->lLastY; - } - else - winraw_init_mouse_xy_mapping(); - } - else if (state->lLastX || state->lLastY) - { - InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); - InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); - - if (!GetCursorPos(&crs_pos)) - { - RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError()); - } - else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) - { - RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError()); - } - else - { - mouse->x = crs_pos.x; - mouse->y = crs_pos.y; - } - } - - if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) - mouse->btn_l = true; - else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) - mouse->btn_l = false; - - if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) - mouse->btn_m = true; - else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) - mouse->btn_m = false; - - if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) - mouse->btn_r = true; - else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) - mouse->btn_r = false; - - if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) - mouse->btn_b4 = true; - else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP) - mouse->btn_b4 = false; - - if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) - mouse->btn_b5 = true; - else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP) - mouse->btn_b5 = false; - - if (state->usButtonFlags & RI_MOUSE_WHEEL) - { - if ((SHORT)state->usButtonData > 0) - InterlockedExchange(&mouse->whl_u, 1); - else if ((SHORT)state->usButtonData < 0) - InterlockedExchange(&mouse->whl_d, 1); - } -} - -static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) -{ - static uint8_t data[1024]; - UINT r; - unsigned i; - RAWINPUT *ri = (RAWINPUT*)data; - UINT size = sizeof(data); - - if (msg != WM_INPUT) - return DefWindowProcA(wnd, msg, wpar, lpar); - - /* app is in the background */ - if (GET_RAWINPUT_CODE_WPARAM(wpar) != RIM_INPUT) - goto end; - - r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT, - data, &size, sizeof(RAWINPUTHEADER)); - if (r == (UINT)-1) - { - RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n", - GetLastError()); - goto end; - } - - if (ri->header.dwType == RIM_TYPEKEYBOARD) - { - if (ri->data.keyboard.Message == WM_KEYDOWN) - g_keyboard->keys[ri->data.keyboard.VKey] = 1; - else if (ri->data.keyboard.Message == WM_KEYUP) - g_keyboard->keys[ri->data.keyboard.VKey] = 0; - } - else if (ri->header.dwType == RIM_TYPEMOUSE) - { - for (i = 0; i < g_mouse_cnt; ++i) - { - if (g_mice[i].hnd == ri->header.hDevice) - { - winraw_update_mouse_state(&g_mice[i], &ri->data.mouse); - break; - } - } - } - -end: - DefWindowProcA(wnd, msg, wpar, lpar); - return 0; -} - -static void *winraw_init(const char *joypad_driver) -{ - bool r; - winraw_input_t *wr = (winraw_input_t *) - calloc(1, sizeof(winraw_input_t)); - g_keyboard = (winraw_keyboard_t*) - calloc(1, sizeof(winraw_keyboard_t)); - - if (!wr || !g_keyboard) - goto error; - - RARCH_LOG("[WINRAW]: Initializing input driver... \n"); - - input_keymaps_init_keyboard_lut(rarch_key_map_winraw); - - wr->window = winraw_create_window(winraw_callback); - if (!wr->window) - goto error; - - r = winraw_init_devices(&g_mice, &g_mouse_cnt); - if (!r) - goto error; - - if (!g_mouse_cnt) - { - RARCH_LOG("[WINRAW]: Mouse unavailable.\n"); - } - else - { - wr->mice = (winraw_mouse_t*) - malloc(g_mouse_cnt * sizeof(winraw_mouse_t)); - if (!wr->mice) - goto error; - - memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t)); - } - - r = winraw_set_keyboard_input(wr->window); - if (!r) - goto error; - - r = winraw_set_mouse_input(wr->window, false); - if (!r) - goto error; - - wr->joypad = input_joypad_init_driver(joypad_driver, wr); - - return wr; - -error: - if (wr && wr->window) - { - winraw_set_mouse_input(NULL, false); - winraw_set_keyboard_input(NULL); - winraw_destroy_window(wr->window); - } - free(g_keyboard); - free(g_mice); - if (wr) - free(wr->mice); - free(wr); - return NULL; -} - -static void winraw_poll(void *d) -{ - unsigned i; - winraw_input_t *wr = (winraw_input_t*)d; - - memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t)); - - /* following keys are not handled by windows raw input api */ - wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0; - wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0; - - for (i = 0; i < g_mouse_cnt; ++i) - { - wr->mice[i].x = g_mice[i].x; - wr->mice[i].y = g_mice[i].y; - wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0); - wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0); - wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0); - wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0); - wr->mice[i].btn_l = g_mice[i].btn_l; - wr->mice[i].btn_m = g_mice[i].btn_m; - wr->mice[i].btn_r = g_mice[i].btn_r; - wr->mice[i].btn_b4 = g_mice[i].btn_b4; - wr->mice[i].btn_b5 = g_mice[i].btn_b5; - } - - if (wr->joypad) - wr->joypad->poll(); -} - -static int16_t winraw_input_state(void *d, - rarch_joypad_info_t joypad_info, - const struct retro_keybind **binds, - unsigned port, unsigned device, unsigned index, unsigned id) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - switch (device) - { - case RETRO_DEVICE_JOYPAD: - if (id < RARCH_BIND_LIST_END) - return winraw_is_pressed(wr, joypad_info, binds[port], port, id); - break; - case RETRO_DEVICE_KEYBOARD: - return (id < RETROK_LAST) && winraw_keyboard_pressed(wr, id); - case RETRO_DEVICE_MOUSE: - return winraw_mouse_state(wr, port, false, id); - case RARCH_DEVICE_MOUSE_SCREEN: - return winraw_mouse_state(wr, port, true, id); - case RETRO_DEVICE_ANALOG: - if (binds[port]) - return input_joypad_analog(wr->joypad, joypad_info, - port, index, id, binds[port]); - break; - case RETRO_DEVICE_LIGHTGUN: - switch ( id ) - { - /*aiming*/ - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: - case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: - case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: - return winraw_lightgun_aiming_state( wr, port, id ); - - /*buttons*/ - case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER); - case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD); - case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A); - case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B); - case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C); - case RETRO_DEVICE_ID_LIGHTGUN_START: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); - case RETRO_DEVICE_ID_LIGHTGUN_SELECT: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT); - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP); - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN); - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT); - case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT); - - /*deprecated*/ - case RETRO_DEVICE_ID_LIGHTGUN_X: - case RETRO_DEVICE_ID_LIGHTGUN_Y: - return winraw_deprecated_lightgun_state(wr, port, id); - case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: - return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); - } - break; - } - - return 0; -} - -static bool winraw_meta_key_pressed(void *u1, int u2) -{ - return false; -} - -static void winraw_free(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - if (wr->joypad) - wr->joypad->destroy(); - winraw_set_mouse_input(NULL, false); - winraw_set_keyboard_input(NULL); - winraw_destroy_window(wr->window); - free(g_mice); - free(g_keyboard); - free(wr->mice); - free(wr); - - g_mouse_xy_mapping_ready = false; -} - -static uint64_t winraw_get_capabilities(void *u) -{ - return (1 << RETRO_DEVICE_KEYBOARD) | - (1 << RETRO_DEVICE_MOUSE) | - (1 << RETRO_DEVICE_JOYPAD) | - (1 << RETRO_DEVICE_ANALOG) | - (1 << RETRO_DEVICE_LIGHTGUN); -} - -static void winraw_grab_mouse(void *d, bool grab) -{ - bool r = false; - winraw_input_t *wr = (winraw_input_t*)d; - - if (grab == wr->mouse_grab) - return; - - r = winraw_set_mouse_input(wr->window, grab); - if (!r) - return; - - wr->mouse_grab = grab; -} - -static bool winraw_set_rumble(void *d, unsigned port, - enum retro_rumble_effect effect, uint16_t strength) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return input_joypad_set_rumble(wr->joypad, port, effect, strength); -} - -static const input_device_driver_t *winraw_get_joypad_driver(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return wr->joypad; -} - -static bool winraw_keyboard_mapping_is_blocked(void *d) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - return wr->kbd_mapp_block; -} - -static void winraw_keyboard_mapping_set_block(void *d, bool block) -{ - winraw_input_t *wr = (winraw_input_t*)d; - - wr->kbd_mapp_block = block; -} - -input_driver_t input_winraw = { - winraw_init, - winraw_poll, - winraw_input_state, - winraw_meta_key_pressed, - winraw_free, - NULL, - NULL, - winraw_get_capabilities, - "raw", - winraw_grab_mouse, - NULL, - winraw_set_rumble, - winraw_get_joypad_driver, - NULL, - winraw_keyboard_mapping_is_blocked, - winraw_keyboard_mapping_set_block, -}; +/* RetroArch - A frontend for libretro. + * Copyright (C) 2011-2017 - 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 "../input_driver.h" +#include "../input_keymaps.h" + +#include "../../configuration.h" +#include "../../gfx/video_driver.h" +#include "../../verbosity.h" + +typedef struct +{ + uint8_t keys[256]; +} winraw_keyboard_t; + +typedef struct +{ + HANDLE hnd; + LONG x, y, dlt_x, dlt_y; + LONG whl_u, whl_d; + bool btn_l, btn_m, btn_r, btn_b4, btn_b5; +} winraw_mouse_t; + +typedef struct +{ + bool kbd_mapp_block; + bool mouse_grab; + winraw_keyboard_t keyboard; + HWND window; + winraw_mouse_t *mice; + const input_device_driver_t *joypad; +} winraw_input_t; + +static winraw_keyboard_t *g_keyboard = NULL; +static winraw_mouse_t *g_mice = NULL; +static unsigned g_mouse_cnt = 0; +static bool g_mouse_xy_mapping_ready = false; +static double g_view_abs_ratio_x = 0.0; +static double g_view_abs_ratio_y = 0.0; + +static HWND winraw_create_window(WNDPROC wnd_proc) +{ + HWND wnd; + WNDCLASSA wc = {0}; + + wc.hInstance = GetModuleHandleA(NULL); + + if (!wc.hInstance) + { + RARCH_ERR("[WINRAW]: GetModuleHandleA failed with error %lu.\n", GetLastError()); + return NULL; + } + + wc.lpfnWndProc = wnd_proc; + wc.lpszClassName = "winraw-input"; + if (!RegisterClassA(&wc) && GetLastError() != ERROR_CLASS_ALREADY_EXISTS) + { + RARCH_ERR("[WINRAW]: RegisterClassA failed with error %lu.\n", GetLastError()); + return NULL; + } + + wnd = CreateWindowExA(0, wc.lpszClassName, NULL, 0, 0, 0, 0, 0, + HWND_MESSAGE, NULL, NULL, NULL); + if (!wnd) + { + RARCH_ERR("[WINRAW]: CreateWindowExA failed with error %lu.\n", GetLastError()); + goto error; + } + + return wnd; + +error: + UnregisterClassA(wc.lpszClassName, NULL); + return NULL; +} + +static void winraw_destroy_window(HWND wnd) +{ + BOOL r; + + if (!wnd) + return; + + r = DestroyWindow(wnd); + + if (!r) + { + RARCH_WARN("[WINRAW]: DestroyWindow failed with error %lu.\n", GetLastError()); + } + + r = UnregisterClassA("winraw-input", NULL); + + if (!r) + { + RARCH_WARN("[WINRAW]: UnregisterClassA failed with error %lu.\n", GetLastError()); + } +} + +static bool winraw_set_keyboard_input(HWND window) +{ + RAWINPUTDEVICE rid; + BOOL r; + + rid.dwFlags = window ? 0 : RIDEV_REMOVE; + rid.hwndTarget = window; + rid.usUsagePage = 0x01; /* generic desktop */ + rid.usUsage = 0x06; /* keyboard */ + + r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); + + if (!r) + { + RARCH_ERR("[WINRAW]: RegisterRawInputDevices failed with error %lu.\n", GetLastError()); + return false; + } + + return true; +} + +static void winraw_log_mice_info(winraw_mouse_t *mice, unsigned mouse_cnt) +{ + UINT r; + unsigned i; + char name[256]; + UINT name_size = sizeof(name); + + for (i = 0; i < mouse_cnt; ++i) + { + r = GetRawInputDeviceInfoA(mice[i].hnd, RIDI_DEVICENAME, name, &name_size); + if (r == (UINT)-1 || r == 0) + name[0] = '\0'; + RARCH_LOG("[WINRAW]: Mouse #%u %s.\n", i, name); + } +} + +static bool winraw_init_devices(winraw_mouse_t **mice, unsigned *mouse_cnt) +{ + UINT i; + POINT crs_pos; + winraw_mouse_t *mice_r = NULL; + unsigned mouse_cnt_r = 0; + RAWINPUTDEVICELIST *devs = NULL; + UINT dev_cnt = 0; + UINT r = GetRawInputDeviceList( + NULL, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); + + if (r == (UINT)-1) + { + RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); + goto error; + } + + devs = (RAWINPUTDEVICELIST*)malloc(dev_cnt * sizeof(RAWINPUTDEVICELIST)); + if (!devs) + goto error; + + dev_cnt = GetRawInputDeviceList(devs, &dev_cnt, sizeof(RAWINPUTDEVICELIST)); + if (dev_cnt == (UINT)-1) + { + RARCH_ERR("[WINRAW]: GetRawInputDeviceList failed with error %lu.\n", GetLastError()); + goto error; + } + + for (i = 0; i < dev_cnt; ++i) + mouse_cnt_r += devs[i].dwType == RIM_TYPEMOUSE ? 1 : 0; + + if (mouse_cnt_r) + { + mice_r = (winraw_mouse_t*)calloc(1, mouse_cnt_r * sizeof(winraw_mouse_t)); + if (!mice_r) + goto error; + + if (!GetCursorPos(&crs_pos)) + goto error; + + for (i = 0; i < mouse_cnt_r; ++i) + { + mice_r[i].x = crs_pos.x; + mice_r[i].y = crs_pos.y; + } + } + + /* count is already checked, so this is safe */ + for (i = mouse_cnt_r = 0; i < dev_cnt; ++i) + { + if (devs[i].dwType == RIM_TYPEMOUSE) + mice_r[mouse_cnt_r++].hnd = devs[i].hDevice; + } + + winraw_log_mice_info(mice_r, mouse_cnt_r); + + *mice = mice_r; + *mouse_cnt = mouse_cnt_r; + + return true; + +error: + free(devs); + free(mice_r); + *mice = NULL; + *mouse_cnt = 0; + return false; +} + +static bool winraw_set_mouse_input(HWND window, bool grab) +{ + RAWINPUTDEVICE rid; + BOOL r; + + if (window) + rid.dwFlags = grab ? RIDEV_CAPTUREMOUSE : 0; + else + rid.dwFlags = RIDEV_REMOVE; + + rid.hwndTarget = window; + rid.usUsagePage = 0x01; /* generic desktop */ + rid.usUsage = 0x02; /* mouse */ + + r = RegisterRawInputDevices(&rid, 1, sizeof(RAWINPUTDEVICE)); + + if (!r) + { + RARCH_ERR("[WINRAW]: RegisterRawInputDevice failed with error %lu.\n", GetLastError()); + return false; + } + + return true; +} + +static int16_t winraw_lightgun_aiming_state(winraw_input_t *wr, + unsigned port, unsigned id) +{ + const int edge_detect = 32700; + struct video_viewport vp; + bool inside = false; + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + int16_t res_x = 0; + int16_t res_y = 0; + int16_t res_screen_x = 0; + int16_t res_screen_y = 0; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + vp.x = 0; + vp.y = 0; + vp.width = 0; + vp.height = 0; + vp.full_width = 0; + vp.full_height = 0; + + if ( !( video_driver_translate_coord_viewport_wrap( + &vp, mouse->x, mouse->y, &res_x, &res_y, &res_screen_x, &res_screen_y ) ) ) + { + return 0; + } + + inside = (res_x >= -edge_detect) && (res_y >= -edge_detect) && (res_x <= edge_detect) && (res_y <= edge_detect); + + switch ( id ) + { + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + return inside ? res_x : 0; + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + return inside ? res_y : 0; + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return !inside; + default: + break; + } + + return 0; +} + +static int16_t winraw_mouse_state(winraw_input_t *wr, + unsigned port, bool abs, unsigned id) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_MOUSE_X: + return abs ? mouse->x : mouse->dlt_x; + case RETRO_DEVICE_ID_MOUSE_Y: + return abs ? mouse->y : mouse->dlt_y; + case RETRO_DEVICE_ID_MOUSE_LEFT: + return mouse->btn_l ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return mouse->btn_r ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + return mouse->whl_u ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return mouse->whl_d ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return mouse->btn_m ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return mouse->btn_b4 ? 1 : 0; + case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return mouse->btn_b5 ? 1 : 0; + } + + return 0; +} + +static bool winraw_keyboard_pressed(winraw_input_t *wr, unsigned key) +{ + unsigned k = rarch_keysym_lut[(enum retro_key)key]; + return wr->keyboard.keys[k]; +} + +static bool winraw_mbutton_pressed(winraw_input_t *wr, unsigned port, unsigned key) +{ + unsigned i; + winraw_mouse_t *mouse = NULL; + settings_t *settings = config_get_ptr(); + + if (port >= MAX_USERS) + return false; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return false; + + switch ( key ) + { + + case RETRO_DEVICE_ID_MOUSE_LEFT: + return mouse->btn_l; + case RETRO_DEVICE_ID_MOUSE_RIGHT: + return mouse->btn_r; + case RETRO_DEVICE_ID_MOUSE_MIDDLE: + return mouse->btn_m; + case RETRO_DEVICE_ID_MOUSE_BUTTON_4: + return mouse->btn_b4; + case RETRO_DEVICE_ID_MOUSE_BUTTON_5: + return mouse->btn_b5; + case RETRO_DEVICE_ID_MOUSE_WHEELUP: + return mouse->whl_u; + case RETRO_DEVICE_ID_MOUSE_WHEELDOWN: + return mouse->whl_d; + } + + return false; +} + +static bool winraw_is_pressed(winraw_input_t *wr, + rarch_joypad_info_t joypad_info, + const struct retro_keybind *binds, + unsigned port, unsigned id) +{ + const struct retro_keybind *bind = &binds[id]; + + if (!wr->kbd_mapp_block && (bind->key < RETROK_LAST) && winraw_keyboard_pressed(wr, bind->key)) + return true; + if (binds && binds[id].valid) + { + if (winraw_mbutton_pressed(wr, port, bind->mbutton)) + return true; + if (input_joypad_pressed(wr->joypad, joypad_info, port, binds, id)) + return true; + } + + return false; +} + +static void winraw_init_mouse_xy_mapping() +{ + struct video_viewport viewport; + int center_x; + int center_y; + unsigned i; + + if (video_driver_get_viewport_info(&viewport)) + { + center_x = viewport.x + viewport.width / 2; + center_y = viewport.y + viewport.height / 2; + + for (i = 0; i < g_mouse_cnt; ++i) + { + g_mice[i].x = center_x; + g_mice[i].y = center_y; + } + + g_view_abs_ratio_x = (double)viewport.full_width / 65535.0; + g_view_abs_ratio_y = (double)viewport.full_height / 65535.0; + + g_mouse_xy_mapping_ready = true; + } +} + +static int16_t winraw_deprecated_lightgun_state(winraw_input_t *wr, + unsigned port, unsigned id) +{ + unsigned i; + settings_t *settings = config_get_ptr(); + winraw_mouse_t *mouse = NULL; + + if (port >= MAX_USERS) + return 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + if (i == settings->uints.input_mouse_index[port]) + { + mouse = &wr->mice[i]; + break; + } + } + + if (!mouse) + return 0; + + switch (id) + { + case RETRO_DEVICE_ID_LIGHTGUN_X: + return mouse->dlt_x; + case RETRO_DEVICE_ID_LIGHTGUN_Y: + return mouse->dlt_y; + } + + return 0; +} + +static void winraw_update_mouse_state(winraw_mouse_t *mouse, RAWMOUSE *state) +{ + POINT crs_pos; + + if (state->usFlags & MOUSE_MOVE_ABSOLUTE) + { + if (g_mouse_xy_mapping_ready) + { + state->lLastX = (LONG)(g_view_abs_ratio_x * state->lLastX); + state->lLastY = (LONG)(g_view_abs_ratio_y * state->lLastY); + InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX - mouse->x); + InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY - mouse->y); + mouse->x = state->lLastX; + mouse->y = state->lLastY; + } + else + winraw_init_mouse_xy_mapping(); + } + else if (state->lLastX || state->lLastY) + { + InterlockedExchangeAdd(&mouse->dlt_x, state->lLastX); + InterlockedExchangeAdd(&mouse->dlt_y, state->lLastY); + + if (!GetCursorPos(&crs_pos)) + { + RARCH_WARN("[WINRAW]: GetCursorPos failed with error %lu.\n", GetLastError()); + } + else if (!ScreenToClient((HWND)video_driver_window_get(), &crs_pos)) + { + RARCH_WARN("[WINRAW]: ScreenToClient failed with error %lu.\n", GetLastError()); + } + else + { + mouse->x = crs_pos.x; + mouse->y = crs_pos.y; + } + } + + if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_DOWN) + mouse->btn_l = true; + else if (state->usButtonFlags & RI_MOUSE_LEFT_BUTTON_UP) + mouse->btn_l = false; + + if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_DOWN) + mouse->btn_m = true; + else if (state->usButtonFlags & RI_MOUSE_MIDDLE_BUTTON_UP) + mouse->btn_m = false; + + if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_DOWN) + mouse->btn_r = true; + else if (state->usButtonFlags & RI_MOUSE_RIGHT_BUTTON_UP) + mouse->btn_r = false; + + if (state->usButtonFlags & RI_MOUSE_BUTTON_4_DOWN) + mouse->btn_b4 = true; + else if (state->usButtonFlags & RI_MOUSE_BUTTON_4_UP) + mouse->btn_b4 = false; + + if (state->usButtonFlags & RI_MOUSE_BUTTON_5_DOWN) + mouse->btn_b5 = true; + else if (state->usButtonFlags & RI_MOUSE_BUTTON_5_UP) + mouse->btn_b5 = false; + + if (state->usButtonFlags & RI_MOUSE_WHEEL) + { + if ((SHORT)state->usButtonData > 0) + InterlockedExchange(&mouse->whl_u, 1); + else if ((SHORT)state->usButtonData < 0) + InterlockedExchange(&mouse->whl_d, 1); + } +} + +static LRESULT CALLBACK winraw_callback(HWND wnd, UINT msg, WPARAM wpar, LPARAM lpar) +{ + static uint8_t data[1024]; + UINT r; + unsigned i; + RAWINPUT *ri = (RAWINPUT*)data; + UINT size = sizeof(data); + + if (msg != WM_INPUT) + return DefWindowProcA(wnd, msg, wpar, lpar); + + /* app is in the background */ + if (GET_RAWINPUT_CODE_WPARAM(wpar) != RIM_INPUT) + goto end; + + r = GetRawInputData((HRAWINPUT)lpar, RID_INPUT, + data, &size, sizeof(RAWINPUTHEADER)); + if (r == (UINT)-1) + { + RARCH_WARN("[WINRAW]: GetRawInputData failed with error %lu.\n", + GetLastError()); + goto end; + } + + if (ri->header.dwType == RIM_TYPEKEYBOARD) + { + if (ri->data.keyboard.Message == WM_KEYDOWN) + g_keyboard->keys[ri->data.keyboard.VKey] = 1; + else if (ri->data.keyboard.Message == WM_KEYUP) + g_keyboard->keys[ri->data.keyboard.VKey] = 0; + } + else if (ri->header.dwType == RIM_TYPEMOUSE) + { + for (i = 0; i < g_mouse_cnt; ++i) + { + if (g_mice[i].hnd == ri->header.hDevice) + { + winraw_update_mouse_state(&g_mice[i], &ri->data.mouse); + break; + } + } + } + +end: + DefWindowProcA(wnd, msg, wpar, lpar); + return 0; +} + +static void *winraw_init(const char *joypad_driver) +{ + bool r; + winraw_input_t *wr = (winraw_input_t *) + calloc(1, sizeof(winraw_input_t)); + g_keyboard = (winraw_keyboard_t*) + calloc(1, sizeof(winraw_keyboard_t)); + + if (!wr || !g_keyboard) + goto error; + + RARCH_LOG("[WINRAW]: Initializing input driver... \n"); + + input_keymaps_init_keyboard_lut(rarch_key_map_winraw); + + wr->window = winraw_create_window(winraw_callback); + if (!wr->window) + goto error; + + r = winraw_init_devices(&g_mice, &g_mouse_cnt); + if (!r) + goto error; + + if (!g_mouse_cnt) + { + RARCH_LOG("[WINRAW]: Mouse unavailable.\n"); + } + else + { + wr->mice = (winraw_mouse_t*) + malloc(g_mouse_cnt * sizeof(winraw_mouse_t)); + if (!wr->mice) + goto error; + + memcpy(wr->mice, g_mice, g_mouse_cnt * sizeof(winraw_mouse_t)); + } + + r = winraw_set_keyboard_input(wr->window); + if (!r) + goto error; + + r = winraw_set_mouse_input(wr->window, false); + if (!r) + goto error; + + wr->joypad = input_joypad_init_driver(joypad_driver, wr); + + return wr; + +error: + if (wr && wr->window) + { + winraw_set_mouse_input(NULL, false); + winraw_set_keyboard_input(NULL); + winraw_destroy_window(wr->window); + } + free(g_keyboard); + free(g_mice); + if (wr) + free(wr->mice); + free(wr); + return NULL; +} + +static void winraw_poll(void *d) +{ + unsigned i; + winraw_input_t *wr = (winraw_input_t*)d; + + memcpy(&wr->keyboard, g_keyboard, sizeof(winraw_keyboard_t)); + + /* following keys are not handled by windows raw input api */ + wr->keyboard.keys[VK_LCONTROL] = GetAsyncKeyState(VK_LCONTROL) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RCONTROL] = GetAsyncKeyState(VK_RCONTROL) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_LMENU] = GetAsyncKeyState(VK_LMENU) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RMENU] = GetAsyncKeyState(VK_RMENU) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_LSHIFT] = GetAsyncKeyState(VK_LSHIFT) >> 1 ? 1 : 0; + wr->keyboard.keys[VK_RSHIFT] = GetAsyncKeyState(VK_RSHIFT) >> 1 ? 1 : 0; + + for (i = 0; i < g_mouse_cnt; ++i) + { + wr->mice[i].x = g_mice[i].x; + wr->mice[i].y = g_mice[i].y; + wr->mice[i].dlt_x = InterlockedExchange(&g_mice[i].dlt_x, 0); + wr->mice[i].dlt_y = InterlockedExchange(&g_mice[i].dlt_y, 0); + wr->mice[i].whl_u = InterlockedExchange(&g_mice[i].whl_u, 0); + wr->mice[i].whl_d = InterlockedExchange(&g_mice[i].whl_d, 0); + wr->mice[i].btn_l = g_mice[i].btn_l; + wr->mice[i].btn_m = g_mice[i].btn_m; + wr->mice[i].btn_r = g_mice[i].btn_r; + wr->mice[i].btn_b4 = g_mice[i].btn_b4; + wr->mice[i].btn_b5 = g_mice[i].btn_b5; + } + + if (wr->joypad) + wr->joypad->poll(); +} + +static int16_t winraw_input_state(void *d, + rarch_joypad_info_t joypad_info, + const struct retro_keybind **binds, + unsigned port, unsigned device, unsigned index, unsigned id) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + switch (device) + { + case RETRO_DEVICE_JOYPAD: + if (id < RARCH_BIND_LIST_END) + return winraw_is_pressed(wr, joypad_info, binds[port], port, id); + break; + case RETRO_DEVICE_KEYBOARD: + return (id < RETROK_LAST) && winraw_keyboard_pressed(wr, id); + case RETRO_DEVICE_MOUSE: + return winraw_mouse_state(wr, port, false, id); + case RARCH_DEVICE_MOUSE_SCREEN: + return winraw_mouse_state(wr, port, true, id); + case RETRO_DEVICE_ANALOG: + if (binds[port]) + return input_joypad_analog(wr->joypad, joypad_info, + port, index, id, binds[port]); + break; + case RETRO_DEVICE_LIGHTGUN: + switch ( id ) + { + /*aiming*/ + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_X: + case RETRO_DEVICE_ID_LIGHTGUN_SCREEN_Y: + case RETRO_DEVICE_ID_LIGHTGUN_IS_OFFSCREEN: + return winraw_lightgun_aiming_state( wr, port, id ); + + /*buttons*/ + case RETRO_DEVICE_ID_LIGHTGUN_TRIGGER: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_TRIGGER); + case RETRO_DEVICE_ID_LIGHTGUN_RELOAD: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_RELOAD); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_A: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_A); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_B: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_B); + case RETRO_DEVICE_ID_LIGHTGUN_AUX_C: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_AUX_C); + case RETRO_DEVICE_ID_LIGHTGUN_START: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + case RETRO_DEVICE_ID_LIGHTGUN_SELECT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_SELECT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_UP: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_UP); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_DOWN: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_DOWN); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_LEFT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_LEFT); + case RETRO_DEVICE_ID_LIGHTGUN_DPAD_RIGHT: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_DPAD_RIGHT); + + /*deprecated*/ + case RETRO_DEVICE_ID_LIGHTGUN_X: + case RETRO_DEVICE_ID_LIGHTGUN_Y: + return winraw_deprecated_lightgun_state(wr, port, id); + case RETRO_DEVICE_ID_LIGHTGUN_PAUSE: + return winraw_is_pressed(wr, joypad_info, binds[port], port, RARCH_LIGHTGUN_START); + } + break; + } + + return 0; +} + +static bool winraw_meta_key_pressed(void *u1, int u2) +{ + return false; +} + +static void winraw_free(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + if (wr->joypad) + wr->joypad->destroy(); + winraw_set_mouse_input(NULL, false); + winraw_set_keyboard_input(NULL); + winraw_destroy_window(wr->window); + free(g_mice); + free(g_keyboard); + free(wr->mice); + free(wr); + + g_mouse_xy_mapping_ready = false; +} + +static uint64_t winraw_get_capabilities(void *u) +{ + return (1 << RETRO_DEVICE_KEYBOARD) | + (1 << RETRO_DEVICE_MOUSE) | + (1 << RETRO_DEVICE_JOYPAD) | + (1 << RETRO_DEVICE_ANALOG) | + (1 << RETRO_DEVICE_LIGHTGUN); +} + +static void winraw_grab_mouse(void *d, bool grab) +{ + bool r = false; + winraw_input_t *wr = (winraw_input_t*)d; + + if (grab == wr->mouse_grab) + return; + + r = winraw_set_mouse_input(wr->window, grab); + if (!r) + return; + + wr->mouse_grab = grab; +} + +static bool winraw_set_rumble(void *d, unsigned port, + enum retro_rumble_effect effect, uint16_t strength) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return input_joypad_set_rumble(wr->joypad, port, effect, strength); +} + +static const input_device_driver_t *winraw_get_joypad_driver(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return wr->joypad; +} + +static bool winraw_keyboard_mapping_is_blocked(void *d) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + return wr->kbd_mapp_block; +} + +static void winraw_keyboard_mapping_set_block(void *d, bool block) +{ + winraw_input_t *wr = (winraw_input_t*)d; + + wr->kbd_mapp_block = block; +} + +input_driver_t input_winraw = { + winraw_init, + winraw_poll, + winraw_input_state, + winraw_meta_key_pressed, + winraw_free, + NULL, + NULL, + winraw_get_capabilities, + "raw", + winraw_grab_mouse, + NULL, + winraw_set_rumble, + winraw_get_joypad_driver, + NULL, + winraw_keyboard_mapping_is_blocked, + winraw_keyboard_mapping_set_block, +}; diff --git a/input/drivers/x11_input.c b/input/drivers/x11_input.c index e21e9a100e..9e357870bf 100644 --- a/input/drivers/x11_input.c +++ b/input/drivers/x11_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2015 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -156,7 +156,7 @@ static int16_t x_pressed_analog(x11_input_t *x11, int id_plus_key = 0; unsigned sym = 0; int keycode = 0; - + input_conv_analog_id_to_bind_id(idx, id, &id_minus, &id_plus); id_minus_key = binds[id_minus].key; @@ -164,15 +164,15 @@ static int16_t x_pressed_analog(x11_input_t *x11, sym = rarch_keysym_lut[(enum retro_key)id_minus_key]; keycode = XKeysymToKeycode(x11->display, sym); - if ( binds[id_minus].valid + if ( binds[id_minus].valid && (id_minus_key < RETROK_LAST) && (x11->state[keycode >> 3] & (1 << (keycode & 7)))) pressed_minus = -0x7fff; sym = rarch_keysym_lut[(enum retro_key)id_plus_key]; keycode = XKeysymToKeycode(x11->display, sym); - if ( binds[id_plus].valid - && (id_plus_key < RETROK_LAST) + if ( binds[id_plus].valid + && (id_plus_key < RETROK_LAST) && (x11->state[keycode >> 3] & (1 << (keycode & 7)))) pressed_plus = 0x7fff; @@ -421,9 +421,9 @@ static void x_input_poll_mouse(x11_input_t *x11) { x11->mouse_x = win_x; x11->mouse_y = win_y; - x11->mouse_l = mask & Button1Mask; - x11->mouse_m = mask & Button2Mask; - x11->mouse_r = mask & Button3Mask; + x11->mouse_l = mask & Button1Mask; + x11->mouse_m = mask & Button2Mask; + x11->mouse_r = mask & Button3Mask; /* Somewhat hacky, but seem to do the job. */ if (x11->grab_mouse && video_driver_cb_has_focus()) diff --git a/input/drivers/xdk_xinput_input.c b/input/drivers/xdk_xinput_input.c index d6c45a6d8a..a603d0ae62 100644 --- a/input/drivers/xdk_xinput_input.c +++ b/input/drivers/xdk_xinput_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -106,7 +106,7 @@ static uint64_t xdk_input_get_capabilities(void *data) return (1 << RETRO_DEVICE_JOYPAD) | (1 << RETRO_DEVICE_ANALOG); } -/* FIXME - are we sure about treating low frequency motor as the +/* FIXME - are we sure about treating low frequency motor as the * "strong" motor? Does it apply for Xbox too? */ static bool xdk_input_set_rumble(void *data, unsigned port, @@ -119,9 +119,9 @@ static bool xdk_input_set_rumble(void *data, unsigned port, #endif xdk_input_t *xdk = (xdk_input_t*)data; bool val = false; - + (void)xdk; - + #if 0 #if defined(_XBOX360) if (effect == RETRO_RUMBLE_STRONG) diff --git a/input/drivers/xenon360_input.c b/input/drivers/xenon360_input.c index e1d1142bb9..f1c933a68e 100644 --- a/input/drivers/xenon360_input.c +++ b/input/drivers/xenon360_input.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/input/drivers_hid/libusb_hid.c b/input/drivers_hid/libusb_hid.c index f2fd6d0bca..c03004b395 100644 --- a/input/drivers_hid/libusb_hid.c +++ b/input/drivers_hid/libusb_hid.c @@ -94,13 +94,13 @@ static void adapter_thread(void *data) int size = 0; slock_lock(adapter->send_control_lock); - if (fifo_read_avail(adapter->send_control_buffer) + if (fifo_read_avail(adapter->send_control_buffer) >= sizeof(send_command_size)) { fifo_read(adapter->send_control_buffer, &send_command_size, sizeof(send_command_size)); - if (fifo_read_avail(adapter->send_control_buffer) + if (fifo_read_avail(adapter->send_control_buffer) >= sizeof(send_command_size)) { fifo_read(adapter->send_control_buffer, @@ -180,7 +180,7 @@ static void libusb_get_description(struct libusb_device *device, for(j = 0; j < inter->num_altsetting; j++) { - const struct libusb_interface_descriptor *interdesc = + const struct libusb_interface_descriptor *interdesc = &inter->altsetting[j]; #if 0 @@ -191,13 +191,13 @@ static void libusb_get_description(struct libusb_device *device, for(k = 0; k < (int)interdesc->bNumEndpoints; k++) { - const struct libusb_endpoint_descriptor *epdesc = + const struct libusb_endpoint_descriptor *epdesc = &interdesc->endpoint[k]; - bool is_int = (epdesc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) + bool is_int = (epdesc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_INTERRUPT; - bool is_out = (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + bool is_out = (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT; - bool is_in = (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) + bool is_in = (epdesc->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN; if (is_int) diff --git a/input/drivers_joypad/dinput_joypad.c b/input/drivers_joypad/dinput_joypad.c index b04e739790..c92d9179ad 100644 --- a/input/drivers_joypad/dinput_joypad.c +++ b/input/drivers_joypad/dinput_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -141,11 +141,11 @@ static bool guid_is_xinput_device(const GUID* product_guid) unsigned i, num_raw_devs = 0; PRAWINPUTDEVICELIST raw_devs = NULL; - /* Check for well known XInput device GUIDs, + /* Check for well known XInput device GUIDs, * thereby removing the need for the IG_ check. - * This lets us skip RAWINPUT for popular devices. + * This lets us skip RAWINPUT for popular devices. * - * Also, we need to do this for the Valve Streaming Gamepad + * Also, we need to do this for the Valve Streaming Gamepad * because it's virtualized and doesn't show up in the device list. */ for (i = 0; i < ARRAY_SIZE(common_xinput_guids); ++i) diff --git a/input/drivers_joypad/sdl_joypad.c b/input/drivers_joypad/sdl_joypad.c index fa141059e0..05ccfad1a5 100644 --- a/input/drivers_joypad/sdl_joypad.c +++ b/input/drivers_joypad/sdl_joypad.c @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2014-2017 - Higor Euripedes - * + * * 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. diff --git a/input/drivers_joypad/xinput_joypad.c b/input/drivers_joypad/xinput_joypad.c index f7eb8bd347..77a9680d52 100644 --- a/input/drivers_joypad/xinput_joypad.c +++ b/input/drivers_joypad/xinput_joypad.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2013-2015 - pinumbernumber * Copyright (C) 2011-2017 - 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. @@ -96,8 +96,8 @@ typedef struct #define ERROR_DEVICE_NOT_CONNECTED 1167 #endif -/* Due to 360 pads showing up under both XInput and DirectInput, - * and since we are going to have to pass through unhandled +/* Due to 360 pads showing up under both XInput and DirectInput, + * and since we are going to have to pass through unhandled * joypad numbers to DirectInput, a slightly ugly * hack is required here. dinput_joypad_init will fill this. * @@ -191,7 +191,7 @@ static bool xinput_joypad_init(void *data) * success anyway. */ - g_xinput_dll = dylib_load("xinput1_4.dll"); + g_xinput_dll = dylib_load("xinput1_4.dll"); if (!g_xinput_dll) { g_xinput_dll = dylib_load("xinput1_3.dll"); @@ -255,7 +255,7 @@ static bool xinput_joypad_init(void *data) (!g_xinput_states[3].connected)) return false; - RARCH_LOG("[XInput]: Pads connected: %d\n", g_xinput_states[0].connected + + RARCH_LOG("[XInput]: Pads connected: %d\n", g_xinput_states[0].connected + g_xinput_states[1].connected + g_xinput_states[2].connected + g_xinput_states[3].connected); g_xinput_block_pads = true; @@ -350,7 +350,7 @@ static const uint16_t button_index_to_bitmap_code[] = { XINPUT_GAMEPAD_BACK, XINPUT_GAMEPAD_LEFT_THUMB, XINPUT_GAMEPAD_RIGHT_THUMB, - XINPUT_GAMEPAD_GUIDE + XINPUT_GAMEPAD_GUIDE }; static bool xinput_joypad_button(unsigned port_num, uint16_t joykey) @@ -420,7 +420,7 @@ static int16_t xinput_joypad_axis (unsigned port_num, uint32_t joyaxis) return 0; /* triggers (axes 4,5) cannot be negative */ - if (AXIS_NEG_GET(joyaxis) <= 3) + if (AXIS_NEG_GET(joyaxis) <= 3) { axis = AXIS_NEG_GET(joyaxis); is_neg = true; @@ -475,8 +475,8 @@ static void xinput_joypad_poll(void) { if (g_xinput_states[i].connected) { - if (g_XInputGetStateEx(i, - &(g_xinput_states[i].xstate)) + if (g_XInputGetStateEx(i, + &(g_xinput_states[i].xstate)) == ERROR_DEVICE_NOT_CONNECTED) g_xinput_states[i].connected = false; } @@ -507,7 +507,7 @@ static bool xinput_joypad_rumble(unsigned pad, else if (effect == RETRO_RUMBLE_WEAK) g_xinput_rumble_states[xuser].wRightMotorSpeed = strength; - return (g_XInputSetState(xuser, &g_xinput_rumble_states[xuser]) + return (g_XInputSetState(xuser, &g_xinput_rumble_states[xuser]) == 0); } diff --git a/input/drivers_keyboard/keyboard_event_android.c b/input/drivers_keyboard/keyboard_event_android.c index cd7b7e27dd..6c2f95bec8 100644 --- a/input/drivers_keyboard/keyboard_event_android.c +++ b/input/drivers_keyboard/keyboard_event_android.c @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. @@ -19,7 +19,7 @@ #define AKEYCODE_ASSIST 219 -#define LAST_KEYCODE AKEYCODE_ASSIST +#define LAST_KEYCODE AKEYCODE_ASSIST #define MAX_KEYS ((LAST_KEYCODE + 7) / 8) diff --git a/input/drivers_keyboard/keyboard_event_android.h b/input/drivers_keyboard/keyboard_event_android.h index d80fb2f606..27e77f78a4 100644 --- a/input/drivers_keyboard/keyboard_event_android.h +++ b/input/drivers_keyboard/keyboard_event_android.h @@ -1,6 +1,6 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - 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. diff --git a/input/drivers_keyboard/keyboard_event_dos.c b/input/drivers_keyboard/keyboard_event_dos.c index f9b76ad4a6..62f23feff9 100644 --- a/input/drivers_keyboard/keyboard_event_dos.c +++ b/input/drivers_keyboard/keyboard_event_dos.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. diff --git a/input/drivers_keyboard/keyboard_event_dos.h b/input/drivers_keyboard/keyboard_event_dos.h index 0cecb85576..0239f5087d 100644 --- a/input/drivers_keyboard/keyboard_event_dos.h +++ b/input/drivers_keyboard/keyboard_event_dos.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Brad Parker - * + * * 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. diff --git a/input/drivers_keyboard/keyboard_event_xkb.c b/input/drivers_keyboard/keyboard_event_xkb.c index eae2f1e4c0..b406d12e73 100644 --- a/input/drivers_keyboard/keyboard_event_xkb.c +++ b/input/drivers_keyboard/keyboard_event_xkb.c @@ -152,7 +152,7 @@ void handle_xkb_state_mask(uint32_t depressed, xkb_state_update_mask(xkb_state, depressed, latched, locked, 0, 0, group); } -/* FIXME: Don't handle composed and dead-keys properly. +/* FIXME: Don't handle composed and dead-keys properly. * Waiting for support in libxkbcommon ... */ int handle_xkb(int code, int value) { diff --git a/input/include/GameController/GCController.h b/input/include/GameController/GCController.h index 5eab6264ce..7a7980338e 100644 --- a/input/include/GameController/GCController.h +++ b/input/include/GameController/GCController.h @@ -9,23 +9,23 @@ /** Use these constants with NSNotificationCenter to listen to connection and disconnection events. - + Use GCControllerDidConnectNotification for observing connections of controllers. Use GCControllerDidDisconnectNotification for observing disconnections of controllers. - + Connections and disconnections of controllers will also be reflected in the controllers array of the GCController class. - + The 'object' property of the notification will contain the GCController that was connected or disconnected. For example: - + - (void)controllerDidConnect:(NSNotification *)note { - + GCController *controller = note.object; - + .... } - + @see NSNotificationCenter @see GCController.controllers */ @@ -44,10 +44,10 @@ enum { /** Controllers are available to an application that links to GameController.framework. There are 2 ways to access controllers paired to the system, adopt both to ensure the best user experience: - + 1: Querying for the the current array or controllers using [GCController controllers]. 2: Registering for Connection/Disconnection notifications from NSNotificationCenter. - + Only controllers that support one of the allowed profiles, such as GCGamepad, will be enumerated. Check for the profile supported before using a controller in your application. Ignore a controller that doesn't support a profile that suits your application, as the user will expect their controller to either be fully supported or not supported at all. @@ -59,11 +59,11 @@ GAMECONTROLLER_EXPORT Set this block to be notified when a user intendeds to suspend or resume the current game state. A controller will have a button dedicated to suspending and resuming play and invoking context sensitive actions. During event handling the system will notify the application using this block such that the application can handle the suspension and resumption from the given controller. - + Use this to implement your canonical transition to a pause menu for example if that is your application's desired handling of suspension in play. You may pause and resume base don game state as well so the event is only called each time the pause/resume button is pressed. - + @param controller the controller that is suspending or resuming play. */ @property (copy) void (^controllerPausedHandler)(GCController *controller); @@ -84,29 +84,29 @@ GAMECONTROLLER_EXPORT /** A player index for the controller, defaults to GCControllerPlayerIndexUnset, unless the controller previously had a player index assigned to it on the current user's system. - + This can be set both for the application to keep track of controllers and as a signal to make a controller display a player index on a set of LEDs or some other mechanism. - + A controller is not guranteed to have a visual display of the playerIndex, but the API will keep track of the playerIndex for a controller while connected and in between being disconnected and connected again. Thus playerIndex persists for a controller with regards to a system. This makes it useful for persisting player-controller assignments across game sessions. - + Negative values less than GCControllerPlayerIndexUnset will just map back to GCControllerPlayerIndexUnset when read back. */ @property (nonatomic) NSInteger playerIndex; /** Gets the profile for the controller that suits current application. - + There are only two supported profiles. Each controller may be able to map its inputs into all profiles or just one kind of profile. Query for the controller profile that suits your game, the simplest kind will be supported by the broadest variety of controllers. A controller supporting the Extended Gamepad profile for example supports the Gamepad profile and more. As such it can always be used just in the Gamepad profile if that suits the game. - + A physical controller that supports a profile must support it completely. That means that all buttons and axis inputs must be valid inputs that a developer can utilize. - + If a controller does not support the given profile the returned value will be nil. Use this to filter controllers if the application requires a specific kind of profile. */ @@ -115,7 +115,7 @@ GAMECONTROLLER_EXPORT /** Get a list of controllers currently attached to the system. - + @see GCControllerDidConnectNotification @see GCControllerDidDisconnectNotification */ @@ -126,21 +126,21 @@ GAMECONTROLLER_EXPORT will get called once no more devices can be found. If there are already multiple controllers available for use, there may be little reason to automatically start discovery of new wireless controllers. In this situation it may be best to allow the user to start discovery manually via in-game UI. - + Once discovery has started new controllers will notify themselves as connected via GCControllerDidConnectNotification. As the notification arrives the controller is also available in the controllers array. The completionHandler could be used to update UI and/or game state to indicate that no more controllers will be found and the current set of controllers is what is available for use in the game. - + If a completionHandler was provided, it will be called once when discovery stops. Either from an explicit call to stopWirelessControllerDiscovery or from timing out or stopping in its natural course of operation. Thus the completionHandler will at most be called once per call to startWirelessControllerDiscoveryWithCompletionHandler:. - + The completionHandler may also not get called at all, if for example startWirelessControllerDiscoveryWithCompletionHandler: is called multiple times during dicovery. For this case the net effect is that the completionHandler is replaced with each call and only the last one set before discovery stops will be called. - + @param completionHandler an optional handler that is called when discovery stops. (may be nil, in which case you will not be notified when discovery stops) @see stopWirelessControllerDiscovery @see controllers @@ -152,7 +152,7 @@ GAMECONTROLLER_EXPORT process can be stopped. Calling stopWirelessControllerDiscovery when no discovery is currently in progress will return immediately without any effect, thus it is safe to call even if the completionHandler of startWirelessControllerDiscoveryWithCompletionHandler: has been called. - + @see startWirelessControllerDiscoveryWithCompletionHandler: */ + (void)stopWirelessControllerDiscovery; diff --git a/input/include/GameController/GCControllerAxisInput.h b/input/include/GameController/GCControllerAxisInput.h index 1bb95f3003..7fab120c55 100644 --- a/input/include/GameController/GCControllerAxisInput.h +++ b/input/include/GameController/GCControllerAxisInput.h @@ -12,7 +12,7 @@ GAMECONTROLLER_EXPORT /** Set this block if you want to be notified when the value on this axis changes. - + @param axis the element that has been modified. @param value the value the axis was set to at the time the valueChangedHandler fired. */ diff --git a/input/include/GameController/GCControllerButtonInput.h b/input/include/GameController/GCControllerButtonInput.h index 65e977cee4..735bceb9f3 100644 --- a/input/include/GameController/GCControllerButtonInput.h +++ b/input/include/GameController/GCControllerButtonInput.h @@ -12,7 +12,7 @@ GAMECONTROLLER_EXPORT /** Set this block if you want to be notified when the value on this button changes. - + @param button the element that has been modified. @param value the value the button was set to at the time the valueChangedHandler fired. @param pressed the pressed state of the button at the time the valueChangedHandler fired. @@ -28,7 +28,7 @@ typedef void (^GCControllerButtonValueChangedHandler)(GCControllerButtonInput *b /** Buttons are mostly used in a digital sense, thus we have a recommended method for checking for pressed state instead of interpreting the value. - + As a general guideline a button is pressed if the value exceeds 25%. However there may be hysterisis applied to counter noisy input values, thus incidental values around the threshold value may not trigger a change in pressed state. diff --git a/input/include/GameController/GCControllerDirectionPad.h b/input/include/GameController/GCControllerDirectionPad.h index afb15b3c6d..5bb1398d15 100644 --- a/input/include/GameController/GCControllerDirectionPad.h +++ b/input/include/GameController/GCControllerDirectionPad.h @@ -16,7 +16,7 @@ GAMECONTROLLER_EXPORT /** Set this block if you want to be notified when the value on this axis changes. - + @param dpad the direction pad collection whose axis have been modified. @param xValue the value the x axis was set to at the time the valueChangedHandler fired. @param yValue the value the y axis was set to at the time the valueChangedHandler fired. diff --git a/input/include/GameController/GCExtendedGamepad.h b/input/include/GameController/GCExtendedGamepad.h index 00e4fcb0de..e293ce24e8 100644 --- a/input/include/GameController/GCExtendedGamepad.h +++ b/input/include/GameController/GCExtendedGamepad.h @@ -12,12 +12,12 @@ /** Extended Gamepad profile. Has all the physical features of a Standard Gamepad and more. - + In comparison to the Standard gamepad, The directional pad on an Extended gamepad is optionally analog as the two thumbsticks provided are required to be analog. - + All controller profiles provide a base level of information about the controller they belong to. - + A profile maps the hardware notion of a controller into a logical controller. One that a developer can design for and depend on, no matter the underlying hardware. */ @@ -37,7 +37,7 @@ GAMECONTROLLER_EXPORT Set this block if you want to be notified when a value on a element changed. If multiple elements have changed this block will be called for each element that changed. As elements in a collection, such as the axis in a dpad, tend to change at the same time and thus will only call this once with the collection as the element. - + @param gamepad this gamepad that is being used to map the raw input data into logical values on controller elements such as the dpad or the buttons. @param element the element that has been modified. */ @@ -48,7 +48,7 @@ typedef void (^GCExtendedGamepadValueChangedHandler)(GCExtendedGamepad *gamepad, Polls the state vector of the controller and saves it to a snapshot. The snapshot is stored in a device independent format that can be serialized and used at a later date. This is useful for features such as quality assurance, save game or replay functionality among many. - + If your application is heavily multithreaded this may also be useful to guarantee atomicity of input handling as a snapshot will not change based on user input once it is taken. */ @@ -62,13 +62,13 @@ typedef void (^GCExtendedGamepadValueChangedHandler)(GCExtendedGamepad *gamepad, /** All face buttons are required to be analog in the Extended profile. These must be arranged in the diamond pattern given below: - + Y / \ X B \ / A - + */ @property (readonly) GCControllerButtonInput *buttonA; @property (readonly) GCControllerButtonInput *buttonB; diff --git a/input/include/GameController/GCExtendedGamepadSnapshot.h b/input/include/GameController/GCExtendedGamepadSnapshot.h index 8f6cd125f1..e8500d25fb 100644 --- a/input/include/GameController/GCExtendedGamepadSnapshot.h +++ b/input/include/GameController/GCExtendedGamepadSnapshot.h @@ -10,10 +10,10 @@ /** A GCExtendedGamepadSnapshot snapshot is a concrete GCExtendedGamepad implementation. It can be used directly in an application to implement controller input replays. It is also returned as the result of polling a controller. - + The current snapshotData is readily available to access as NSData. A developer can serialize this to any destination necessary using the NSData API. - + The data contains some version of a GCExtendedGamepadSnapShotData structure. @see -[GCExtendedGamepad saveSnapshot] @@ -32,12 +32,12 @@ typedef struct { // Standard information uint16_t version; //0x0100 uint16_t size; //sizeof(GCExtendedGamepadSnapShotDataV100) or larger - + // Extended gamepad data // Axes in the range [-1.0, 1.0] float_t dpadX; float_t dpadY; - + // Buttons in the range [0.0, 1.0] float_t buttonA; float_t buttonB; @@ -51,7 +51,7 @@ typedef struct { float_t leftThumbstickY; float_t rightThumbstickX; float_t rightThumbstickY; - + // Buttons in the range [0.0, 1.0] float_t leftTrigger; float_t rightTrigger; @@ -60,7 +60,7 @@ typedef struct { #pragma pack(pop) /**Fills out a v100 snapshot from any compatible NSData source - + @return NO if data is nil, snapshotData is nil or the contents of data does not contain a compatible snapshot. YES for all other cases. */ GAMECONTROLLER_EXPORT @@ -68,7 +68,7 @@ BOOL GCExtendedGamepadSnapShotDataV100FromNSData(GCExtendedGamepadSnapShotDataV1 /**Creates an NSData object from a v100 snapshot. If the version and size is not set in the snapshot the data will automatically have version 0x100 and sizeof(GCExtendedGamepadSnapShotDataV100) set as the values implicitly. - + @return nil if the snapshot is NULL, otherwise an NSData instance compatible with GCExtendedGamepadSnapshot.snapshotData */ GAMECONTROLLER_EXPORT diff --git a/input/include/GameController/GCGamepad.h b/input/include/GameController/GCGamepad.h index 74de5c3558..2c318fcb69 100644 --- a/input/include/GameController/GCGamepad.h +++ b/input/include/GameController/GCGamepad.h @@ -12,9 +12,9 @@ /** Standard Gamepad profile. - + All controller profiles provide a base level of information about the controller they belong to. - + A profile maps the hardware notion of a controller into a logical controller. One that a developer can design for and depend on, no matter the underlying hardware. */ @@ -34,7 +34,7 @@ GAMECONTROLLER_EXPORT Set this block if you want to be notified when a value on a element changed. If multiple elements have changed this block will be called for each element that changed. As elements in a collection, such as the axis in a dpad, tend to change at the same time and thus will only call this once with the collection as the element. - + @param gamepad this gamepad that is being used to map the raw input data into logical values on controller elements such as the dpad or the buttons. @param element the element that has been modified. */ @@ -45,7 +45,7 @@ typedef void (^GCGamepadValueChangedHandler)(GCGamepad *gamepad, GCControllerEle Polls the state vector of the controller and saves it to a snapshot. The snapshot is stored in a device independent format that can be serialized and used at a later date. This is useful for features such as quality assurance, save game or replay functionality among many. - + If your application is heavily multithreaded this may also be useful to guarantee atomicity of input handling as a snapshot will not change based on user input once it is taken. */ @@ -59,13 +59,13 @@ typedef void (^GCGamepadValueChangedHandler)(GCGamepad *gamepad, GCControllerEle /** All face buttons are required to be analog in the Standard profile. These must be arranged in the diamond pattern given below: - + Y / \ X B \ / A - + */ @property (readonly) GCControllerButtonInput *buttonA; @property (readonly) GCControllerButtonInput *buttonB; diff --git a/input/include/GameController/GCGamepadSnapshot.h b/input/include/GameController/GCGamepadSnapshot.h index b81922483c..117efdc9c5 100644 --- a/input/include/GameController/GCGamepadSnapshot.h +++ b/input/include/GameController/GCGamepadSnapshot.h @@ -11,12 +11,12 @@ A GCGamepadSnapshot snapshot is a concrete GCGamepad implementation. It can be used directly in an application to implement controller input replays. It is also returned as the result of polling a controller. - + The current snapshotData is readily available to access as NSData. A developer can serialize this to any destination necessary using the NSData API. - + The data contains some version of a GCGamepadSnapShotData structure. - + @see -[GCGamepad saveSnapshot] */ GAMECONTROLLER_EXPORT @@ -33,12 +33,12 @@ typedef struct { // Standard information uint16_t version; //0x0100 uint16_t size; //sizeof(GCGamepadSnapShotDataV100) or larger - + // Standard gamepad data // Axes in the range [-1.0, 1.0] float_t dpadX; float_t dpadY; - + // Buttons in the range [0.0, 1.0] float_t buttonA; float_t buttonB; @@ -46,12 +46,12 @@ typedef struct { float_t buttonY; float_t leftShoulder; float_t rightShoulder; - + } GCGamepadSnapShotDataV100; #pragma pack(pop) /**Fills out a v100 snapshot from any compatible NSData source - + @return NO if data is nil, snapshotData is nil or the contents of data does not contain a compatible snapshot. YES for all other cases. */ GAMECONTROLLER_EXPORT @@ -59,7 +59,7 @@ BOOL GCGamepadSnapShotDataV100FromNSData(GCGamepadSnapShotDataV100 *snapshotData /**Creates an NSData object from a v100 snapshot. If the version and size is not set in the snapshot the data will automatically have version 0x100 and sizeof(GCGamepadSnapShotDataV100) set as the values implicitly. - + @return nil if the snapshot is NULL, otherwise an NSData instance compatible with GCGamepadSnapshot.snapshotData */ GAMECONTROLLER_EXPORT diff --git a/input/input_driver.c b/input/input_driver.c index bbd4ed099b..3765d39916 100644 --- a/input/input_driver.c +++ b/input/input_driver.c @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -336,8 +336,8 @@ struct input_keyboard_line size_t ptr; size_t size; - /** Line complete callback. - * Calls back after return is + /** Line complete callback. + * Calls back after return is * pressed with the completed line. * Line can be NULL. **/ @@ -557,7 +557,7 @@ void input_poll(void) { input_driver_turbo_btns.frame_enable[i] = 0; - if (!input_driver_block_libretro_input && + if (!input_driver_block_libretro_input && libretro_input_binds[i][RARCH_TURBO_ENABLE].valid) { rarch_joypad_info_t joypad_info; @@ -608,7 +608,7 @@ void input_poll(void) * * Input state callback function. * - * Returns: Non-zero if the given key (identified by @id) + * Returns: Non-zero if the given key (identified by @id) * was pressed by the user (assigned to @port). **/ int16_t input_state(unsigned port, unsigned device, @@ -627,7 +627,7 @@ int16_t input_state(unsigned port, unsigned device, bsv_movie_ctl(BSV_MOVIE_CTL_SET_END, NULL); } - if ( !input_driver_flushing_input + if ( !input_driver_flushing_input && !input_driver_block_libretro_input) { settings_t *settings = config_get_ptr(); @@ -695,8 +695,8 @@ int16_t input_state(unsigned port, unsigned device, * * If turbo button is held, all buttons pressed except * for D-pad will go into a turbo mode. Until the button is - * released again, the input state will be modulated by a - * periodic pulse defined by the configured duty cycle. + * released again, the input state will be modulated by a + * periodic pulse defined by the configured duty cycle. */ if (res && input_driver_turbo_btns.frame_enable[port]) input_driver_turbo_btns.enable[port] |= (1 << id); @@ -706,7 +706,7 @@ int16_t input_state(unsigned port, unsigned device, if (input_driver_turbo_btns.enable[port] & (1 << id)) { /* if turbo button is enabled for this key ID */ - res = res && ((input_driver_turbo_btns.count + res = res && ((input_driver_turbo_btns.count % settings->uints.input_turbo_period) < settings->uints.input_turbo_duty_cycle); } @@ -803,10 +803,10 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) const struct retro_keybind *binds_norm = NULL; const struct retro_keybind *binds_auto = NULL; uint8_t max_users = (uint8_t)input_driver_max_users; - uint8_t port_max = - settings->bools.input_all_users_control_menu + uint8_t port_max = + settings->bools.input_all_users_control_menu ? max_users : 1; - + joypad_info.joy_idx = 0; joypad_info.auto_binds = NULL; @@ -815,7 +815,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) input_driver_block_libretro_input = false; input_driver_block_hotkey = false; - if (current_input->keyboard_mapping_is_blocked + if (current_input->keyboard_mapping_is_blocked && current_input->keyboard_mapping_is_blocked(current_input_data)) input_driver_block_hotkey = true; @@ -840,7 +840,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) joypad_info.auto_binds = input_autoconf_binds[joypad_info.joy_idx]; joypad_info.axis_threshold = input_driver_axis_threshold; - if (htkey->valid + if (htkey->valid && current_input->input_state(current_input_data, joypad_info, &binds[0], port, RETRO_DEVICE_JOYPAD, 0, RARCH_ENABLE_HOTKEY)) { @@ -862,9 +862,9 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) || !input_driver_block_hotkey)) ) { - const input_device_driver_t *first = current_input->get_joypad_driver + const input_device_driver_t *first = current_input->get_joypad_driver ? current_input->get_joypad_driver(current_input_data) : NULL; - const input_device_driver_t *sec = current_input->get_sec_joypad_driver + const input_device_driver_t *sec = current_input->get_sec_joypad_driver ? current_input->get_sec_joypad_driver(current_input_data) : NULL; for (port = 0; port < port_max; port++) @@ -883,7 +883,7 @@ void input_menu_keys_pressed(void *data, retro_bits_t* p_new_state) joykey = (input_config_binds[port][i].joykey != NO_BTN) ? input_config_binds[port][i].joykey : joypad_info.auto_binds[i].joykey; - joyaxis = (input_config_binds[port][i].joyaxis != AXIS_NONE) + joyaxis = (input_config_binds[port][i].joyaxis != AXIS_NONE) ? input_config_binds[port][i].joyaxis : joypad_info.auto_binds[i].joyaxis; if (sec) @@ -1048,7 +1048,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) input_driver_block_libretro_input = false; input_driver_block_hotkey = false; - if ( current_input->keyboard_mapping_is_blocked + if ( current_input->keyboard_mapping_is_blocked && current_input->keyboard_mapping_is_blocked(current_input_data)) input_driver_block_hotkey = true; @@ -1065,7 +1065,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) game_focus_toggle_valid = binds[RARCH_GAME_FOCUS_TOGGLE].valid; - /* Allows rarch_focus_toggle hotkey to still work + /* Allows rarch_focus_toggle hotkey to still work * even though every hotkey is blocked */ if (check_input_driver_block_hotkey( focus_normal, focus_binds_auto) && game_focus_toggle_valid) @@ -1098,7 +1098,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) } #ifdef HAVE_OVERLAY - if (overlay_ptr && + if (overlay_ptr && input_overlay_key_pressed(overlay_ptr, i)) { BIT256_SET_PTR(p_new_state, i); @@ -1123,7 +1123,7 @@ void input_keys_pressed(void *data, retro_bits_t* p_new_state) #endif #ifdef HAVE_NETWORKGAMEPAD - if (input_driver_remote && + if (input_driver_remote && input_remote_key_pressed(i, 0)) { BIT256_SET_PTR(p_new_state, i); @@ -1503,7 +1503,7 @@ const char* config_get_joypad_driver_options(void) * * Initialize a joypad driver of name @ident. * - * If ident points to NULL or a zero-length string, + * If ident points to NULL or a zero-length string, * equivalent to calling input_joypad_init_first(). * * Returns: joypad driver if found, otherwise NULL. @@ -1554,7 +1554,7 @@ const input_device_driver_t *input_joypad_init_first(void *data) } /** - * input_joypad_name: + * input_joypad_name: * @drv : Input device driver handle. * @port : Joystick number. * @@ -1600,7 +1600,7 @@ bool input_joypad_set_rumble(const input_device_driver_t *drv, * @drv : Input device driver handle. * @port : User number. * @idx : Analog key index. - * E.g.: + * E.g.: * - RETRO_DEVICE_INDEX_ANALOG_LEFT * - RETRO_DEVICE_INDEX_ANALOG_RIGHT * @ident : Analog key identifier. @@ -1715,12 +1715,12 @@ int16_t input_joypad_analog(const input_device_driver_t *drv, } /** - * input_joypad_axis_raw: + * input_joypad_axis_raw: * @drv : Input device driver handle. * @port : Joystick number. * @axis : Identifier of axis. * - * Checks if axis (@axis) was being pressed by user + * Checks if axis (@axis) was being pressed by user * with joystick number @port. * * Returns: true (1) if axis was pressed, otherwise @@ -1799,7 +1799,7 @@ bool input_mouse_button_raw(unsigned port, unsigned id) /** * input_conv_analog_id_to_bind_id: * @idx : Analog key index. - * E.g.: + * E.g.: * - RETRO_DEVICE_INDEX_ANALOG_LEFT * - RETRO_DEVICE_INDEX_ANALOG_RIGHT * @ident : Analog key identifier. @@ -1955,7 +1955,7 @@ static bool input_keyboard_line_event( const char *word = NULL; char c = character >= 128 ? '?' : character; - /* Treat extended chars as ? as we cannot support + /* Treat extended chars as ? as we cannot support * printable characters for unicode stuff. */ if (c == '\r' || c == '\n') @@ -2069,8 +2069,8 @@ bool input_keyboard_line_append(const char *word) * * Sets function pointer for keyboard line handle. * - * The underlying buffer can be reallocated at any time - * (or be NULL), but the pointer to it remains constant + * The underlying buffer can be reallocated at any time + * (or be NULL), but the pointer to it remains constant * throughout the objects lifetime. * * Returns: underlying buffer of the keyboard line. @@ -2213,7 +2213,7 @@ static const void *input_config_bind_map_get(unsigned i) bool input_config_bind_map_get_valid(unsigned i) { - const struct input_bind_map *keybind = + const struct input_bind_map *keybind = (const struct input_bind_map*)input_config_bind_map_get(i); if (!keybind) return false; @@ -2222,7 +2222,7 @@ bool input_config_bind_map_get_valid(unsigned i) unsigned input_config_bind_map_get_meta(unsigned i) { - const struct input_bind_map *keybind = + const struct input_bind_map *keybind = (const struct input_bind_map*)input_config_bind_map_get(i); if (!keybind) return 0; @@ -2231,7 +2231,7 @@ unsigned input_config_bind_map_get_meta(unsigned i) const char *input_config_bind_map_get_base(unsigned i) { - const struct input_bind_map *keybind = + const struct input_bind_map *keybind = (const struct input_bind_map*)input_config_bind_map_get(i); if (!keybind) return NULL; @@ -2240,7 +2240,7 @@ const char *input_config_bind_map_get_base(unsigned i) const char *input_config_bind_map_get_desc(unsigned i) { - const struct input_bind_map *keybind = + const struct input_bind_map *keybind = (const struct input_bind_map*)input_config_bind_map_get(i); if (!keybind) return NULL; @@ -2286,7 +2286,7 @@ const char *input_config_get_prefix(unsigned user, bool meta) const char *prefix = bind_user_prefix[user]; if (user == 0) - return meta ? "input" : prefix; + return meta ? "input" : prefix; if (!meta) return prefix; @@ -2330,7 +2330,7 @@ enum retro_key input_config_translate_str_to_rk(const char *str) * * Translate string representation to bind ID. * - * Returns: Bind ID value on success, otherwise + * Returns: Bind ID value on success, otherwise * RARCH_BIND_LIST_END on not found. **/ unsigned input_config_translate_str_to_bind_id(const char *str) @@ -2585,7 +2585,7 @@ static void input_config_get_bind_string_joyaxis(char *buf, const char *prefix, settings_t *settings = config_get_ptr(); if (bind->joyaxis_label && - !string_is_empty(bind->joyaxis_label) + !string_is_empty(bind->joyaxis_label) && settings->bools.input_descriptor_label_show) snprintf(buf, size, "%s%s (axis) ", prefix, bind->joyaxis_label); else @@ -2719,7 +2719,7 @@ void input_config_set_device_name(unsigned port, const char *name) strlcpy(input_device_names[port], name, sizeof(input_device_names[port])); - + input_autoconfigure_joypad_reindex_devices(); } } diff --git a/input/input_keymaps.c b/input/input_keymaps.c index ddd900a45f..ef4345e8c3 100644 --- a/input/input_keymaps.c +++ b/input/input_keymaps.c @@ -250,7 +250,7 @@ const struct input_key_map input_config_key_map[] = { { "rctrl", RETROK_RCTRL }, { "ralt", RETROK_RALT }, - /* Keys not referenced in any keyboard mapping + /* Keys not referenced in any keyboard mapping * (except perhaps rarch_key_map_apple_hid) */ { "caret", RETROK_CARET }, { "underscore", RETROK_UNDERSCORE }, @@ -932,7 +932,7 @@ const struct rarch_key_map rarch_key_map_x11[] = { /*{ ?, RETROK_POWER },*/ { XK_EuroSign, RETROK_EURO }, { XK_Undo, RETROK_UNDO }, - /* FIXME(shizeeg): RetroArch can't handle these buttons atm. + /* FIXME(shizeeg): RetroArch can't handle these buttons atm. * Do we really need RETROK_KP_INSERT, RETROK_KP_END, * RETROK_KP_DOWN, RETROK_KP_PAGEDOWN ??? * @@ -1681,7 +1681,7 @@ enum retro_key input_keymaps_translate_keysym_to_rk(unsigned sym) * @buf : Buffer. * @size : Size of @buf. * - * Translates a retro key identifier to a human-readable + * Translates a retro key identifier to a human-readable * identifier string. **/ void input_keymaps_translate_rk_to_str(enum retro_key key, char *buf, size_t size) diff --git a/input/input_keymaps.h b/input/input_keymaps.h index 1950436454..11757f2f68 100644 --- a/input/input_keymaps.h +++ b/input/input_keymaps.h @@ -42,7 +42,7 @@ struct apple_key_name_map_entry const char* const keyname; const uint32_t hid_id; }; - + extern const struct apple_key_name_map_entry apple_key_name_map[]; #endif @@ -86,7 +86,7 @@ enum retro_key input_keymaps_translate_keysym_to_rk(unsigned sym); * @buf : Buffer. * @size : Size of @buf. * - * Translates a retro key identifier to a human-readable + * Translates a retro key identifier to a human-readable * identifier string. **/ void input_keymaps_translate_rk_to_str(enum retro_key key, char *buf, size_t size); diff --git a/input/input_mapper.c b/input/input_mapper.c index 0cfd365c30..decfea1716 100644 --- a/input/input_mapper.c +++ b/input/input_mapper.c @@ -127,9 +127,9 @@ void input_mapper_state( if (id < RETROK_LAST) { /* - RARCH_LOG("State: UDLR %u %u %u %u\n", - MAPPER_GET_KEY(handle, RETROK_UP), - MAPPER_GET_KEY(handle, RETROK_DOWN), + RARCH_LOG("State: UDLR %u %u %u %u\n", + MAPPER_GET_KEY(handle, RETROK_UP), + MAPPER_GET_KEY(handle, RETROK_DOWN), MAPPER_GET_KEY(handle, RETROK_LEFT), MAPPER_GET_KEY(handle, RETROK_RIGHT) );*/ diff --git a/input/input_mapper.h b/input/input_mapper.h index 500faab4a0..c50519acd8 100644 --- a/input/input_mapper.h +++ b/input/input_mapper.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - Daniel De Matteis * Copyright (C) 2016-2017 - Andrés Suárez - * + * * 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. diff --git a/input/input_overlay.c b/input/input_overlay.c index 01bea5f40c..384d589015 100644 --- a/input/input_overlay.c +++ b/input/input_overlay.c @@ -40,7 +40,7 @@ typedef struct input_overlay_state { /* Left X, Left Y, Right X, Right Y */ - int16_t analog[4]; + int16_t analog[4]; uint32_t keys[RETROK_LAST / 32 + 1]; /* This is a bitmask of (1 << key_bind_id). */ uint64_t buttons; @@ -144,7 +144,7 @@ static void input_overlay_set_vertex_geom(input_overlay_t *ol) void input_overlay_set_scale_factor(input_overlay_t *ol, float scale) { size_t i; - + if (!ol) return; @@ -231,7 +231,7 @@ static void input_overlay_enable(input_overlay_t *ol, bool enable) * Check whether the given @x and @y coordinates of the overlay * descriptor @desc is inside the overlay descriptor's hitbox. * - * Returns: true (1) if X, Y coordinates are inside a hitbox, otherwise false (0). + * Returns: true (1) if X, Y coordinates are inside a hitbox, otherwise false (0). **/ static bool inside_hitbox(const struct overlay_desc *desc, float x, float y) { @@ -250,7 +250,7 @@ static bool inside_hitbox(const struct overlay_desc *desc, float x, float y) } case OVERLAY_HITBOX_RECT: - return + return (fabs(x - desc->x) <= desc->range_x_mod) && (fabs(y - desc->y) <= desc->range_y_mod); } @@ -348,7 +348,7 @@ static void input_overlay_poll( * input_overlay_update_desc_geom: * @ol : overlay handle. * @desc : overlay descriptors handle. - * + * * Update input overlay descriptors' vertex geometry. **/ static void input_overlay_update_desc_geom(input_overlay_t *ol, @@ -735,9 +735,9 @@ void input_state_overlay(input_overlay_t *ol, int16_t *ret, case RETRO_DEVICE_KEYBOARD: if (id < RETROK_LAST) { - /*RARCH_LOG("UDLR %u %u %u %u\n", - OVERLAY_GET_KEY(ol_state, RETROK_UP), - OVERLAY_GET_KEY(ol_state, RETROK_DOWN), + /*RARCH_LOG("UDLR %u %u %u %u\n", + OVERLAY_GET_KEY(ol_state, RETROK_UP), + OVERLAY_GET_KEY(ol_state, RETROK_DOWN), OVERLAY_GET_KEY(ol_state, RETROK_LEFT), OVERLAY_GET_KEY(ol_state, RETROK_RIGHT) );*/ @@ -765,7 +765,7 @@ void input_state_overlay(input_overlay_t *ol, int16_t *ret, * @port : the user to show the inputs of * * Adds inputs from current_input to the overlay, so it's displayed - * returns true if an input that is pressed will change the overlay + * returns true if an input that is pressed will change the overlay */ static bool input_overlay_add_inputs(input_overlay_t *ol, unsigned port, unsigned analog_dpad_mode) @@ -788,7 +788,7 @@ static bool input_overlay_add_inputs(input_overlay_t *ol, case OVERLAY_TYPE_BUTTONS: mask = desc->key_mask; id = RETRO_DEVICE_ID_JOYPAD_B; - /* Need to check all bits in the mask, + /* Need to check all bits in the mask, * multiple ones can be pressed */ current_button_pressed = false; while(mask) @@ -823,7 +823,7 @@ static bool input_overlay_add_inputs(input_overlay_t *ol, { float analog_x, analog_y; float dx, dy; - unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? + unsigned int index = (desc->type == OVERLAY_TYPE_ANALOG_RIGHT) ? RETRO_DEVICE_INDEX_ANALOG_RIGHT : RETRO_DEVICE_INDEX_ANALOG_LEFT; analog_x = input_state(port, RETRO_DEVICE_ANALOG, index, RETRO_DEVICE_ID_ANALOG_X); diff --git a/input/input_overlay.h b/input/input_overlay.h index ba81955f38..cac2269388 100644 --- a/input/input_overlay.h +++ b/input/input_overlay.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. @@ -34,13 +34,13 @@ RETRO_BEGIN_DECLS #define KEY_ANALOG_LEFT 0x56b92e81U #define KEY_ANALOG_RIGHT 0x2e4dc654U -/* Overlay driver acts as a medium between input drivers +/* Overlay driver acts as a medium between input drivers * and video driver. * - * Coordinates are fetched from input driver, and an + * Coordinates are fetched from input driver, and an * overlay with pressable actions are displayed on-screen. * - * This interface requires that the video driver has support + * This interface requires that the video driver has support * for the overlay interface. */ @@ -236,7 +236,7 @@ void input_overlay_next(input_overlay_t *ol, float opacity); /* * input_poll_overlay: - * @ol : pointer to overlay + * @ol : pointer to overlay * * Poll pressed buttons/keys on currently active overlay. **/ diff --git a/input/input_remapping.c b/input/input_remapping.c index 68e0d7363e..1493368454 100644 --- a/input/input_remapping.c +++ b/input/input_remapping.c @@ -90,15 +90,15 @@ bool input_remapping_load_file(void *data, const char *path) if (config_get_int(conf, keymapper_ident[j], &key_remap)) { settings->uints.input_keymapper_ids[j] = key_remap; -#if 0 +#if 0 RARCH_LOG ("%s: %u\n", keymapper_ident[j], settings->uints.input_keymapper_ids[j]); #endif } - else + else settings->uints.input_keymapper_ids[j] = RETROK_UNKNOWN; } - - + + } for (j = 0; j < 4; j++) @@ -244,7 +244,7 @@ bool input_remapping_remove_file(const char *path) ret = path_file_remove(remap_file) == 0 ? true : false;; free(buf); free(remap_file); - return ret; + return ret; } void input_remapping_set_defaults(bool deinit) @@ -252,7 +252,7 @@ void input_remapping_set_defaults(bool deinit) unsigned i, j; settings_t *settings = config_get_ptr(); global_t *global = global_get_ptr(); - + if (!global) return; @@ -273,7 +273,7 @@ void input_remapping_set_defaults(bool deinit) if (keybind) settings->uints.input_remap_ids[i][j] = keybind->id; settings->uints.input_keymapper_ids[j] = RETROK_UNKNOWN; - + } for (j = 0; j < 4; j++) settings->uints.input_remap_ids[i][RARCH_FIRST_CUSTOM_BIND + j] = j; diff --git a/input/input_remote.c b/input/input_remote.c index e66b8f5ae0..d74529c7d2 100644 --- a/input/input_remote.c +++ b/input/input_remote.c @@ -66,7 +66,7 @@ struct input_remote typedef struct input_remote_state { /* Left X, Left Y, Right X, Right Y */ - int16_t analog[4][MAX_USERS]; + int16_t analog[4][MAX_USERS]; /* This is a bitmask of (1 << key_bind_id). */ uint64_t buttons[MAX_USERS]; } input_remote_state_t; @@ -230,7 +230,7 @@ void input_remote_poll(input_remote_t *handle, unsigned max_users) unsigned user; settings_t *settings = config_get_ptr(); input_remote_state_t *input_state = input_remote_get_state_ptr(); - + for(user = 0; user < max_users; user++) { if (settings->bools.network_remote_enable_user[user]) diff --git a/input/input_remote.h b/input/input_remote.h index 861cea9149..a80185a724 100644 --- a/input/input_remote.h +++ b/input/input_remote.h @@ -1,7 +1,7 @@ /* RetroArch - A frontend for libretro. * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2017 - 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. diff --git a/intl/msg_hash_pt_br.c b/intl/msg_hash_pt_br.c index 37f690c57d..3f60fba684 100644 --- a/intl/msg_hash_pt_br.c +++ b/intl/msg_hash_pt_br.c @@ -28,7 +28,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) { uint32_t driver_hash = 0; settings_t *settings = config_get_ptr(); - + if (msg == MENU_ENUM_LABEL_CONNECT_NETPLAY_ROOM) { snprintf(s, len, @@ -36,7 +36,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) ); return 0; } - + if (msg <= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_END && msg >= MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN) { unsigned idx = msg - MENU_ENUM_LABEL_INPUT_HOTKEY_BIND_BEGIN; @@ -1069,7 +1069,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_LIBRETRO_LOG_LEVEL: snprintf(s, len, "Define o nível de registro de eventos dos \n" - "núcleos libretro. (GET_LOG_INTERFACE) \n" + "núcleos libretro. (GET_LOG_INTERFACE) \n" " \n" " Se o nível do registro de evento emitido \n" " pelo núcleo libretro for abaixo do nível \n" @@ -1491,7 +1491,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) case MENU_ENUM_LABEL_VIDEO_SWAP_INTERVAL: snprintf(s, len, "Intervalo de Troca da Sincronia Vertical \n" - "(V-Sync). \n" + "(V-Sync). \n" " \n" "Usa um intervalo de troca personalizado \n" "para V-Sync. Defina para reduzir \n" @@ -1583,7 +1583,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Habilitar controle do menu por toque."); break; case MENU_ENUM_LABEL_MENU_WALLPAPER: - snprintf(s, len, + snprintf(s, len, "Selecionar uma imagem para definir como \n" "plano de fundo."); break; @@ -2059,7 +2059,7 @@ int menu_hash_get_help_pt_br_enum(enum msg_hash_enums msg, char *s, size_t len) snprintf(s, len, "Você pode alterar a transparência de \n" "gamepad virtual indo em \n" - "'%s' -> '%s'. \n" + "'%s' -> '%s'. \n" " \n" "De lá você pode alterar a transparência, \n" "mudar o tamanho e opacidade dos botões, etc. \n" diff --git a/lakka.h b/lakka.h index f1659d2ef8..60d117cbdb 100644 --- a/lakka.h +++ b/lakka.h @@ -2,7 +2,7 @@ * Copyright (C) 2010-2014 - Hans-Kristian Arntzen * Copyright (C) 2011-2016 - Daniel De Matteis * Copyright (C) 2014-2016 - Jean-André Santoni - * + * * 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. diff --git a/libretro-common/audio/audio_mix.c b/libretro-common/audio/audio_mix.c index ac1dc1e25d..bd40ccb63c 100644 --- a/libretro-common/audio/audio_mix.c +++ b/libretro-common/audio/audio_mix.c @@ -56,7 +56,7 @@ void audio_mix_volume_SSE2(float *out, const float *in, float vol, size_t sample unsigned j; __m128 input[4]; __m128 additive[4]; - + input[0] = _mm_loadu_ps(out + 0); input[1] = _mm_loadu_ps(out + 4); input[2] = _mm_loadu_ps(out + 8); @@ -132,7 +132,7 @@ audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate) goto error; } - /* numsamples does not know or care about + /* numsamples does not know or care about * multiple channels, but we need space for 2 */ chunk->upsample_buf = (int16_t*)memalign_alloc(128, chunk->rwav->numsamples * 2 * sizeof(int16_t)); @@ -204,7 +204,7 @@ audio_chunk_t* audio_mix_load_wav_file(const char *path, int sample_rate) info.data_in = (const float*)chunk->float_buf; info.data_out = chunk->float_resample_buf; - /* a 'frame' consists of two channels, so we set this + /* a 'frame' consists of two channels, so we set this * to the number of samples irrespective of channel count */ info.input_frames = chunk->rwav->numsamples; info.output_frames = 0; diff --git a/libretro-common/audio/audio_mixer.c b/libretro-common/audio/audio_mixer.c index e6bc09eff2..3e912cb974 100644 --- a/libretro-common/audio/audio_mixer.c +++ b/libretro-common/audio/audio_mixer.c @@ -57,7 +57,7 @@ struct audio_mixer_sound { enum audio_mixer_type type; - + union { struct @@ -66,7 +66,7 @@ struct audio_mixer_sound unsigned frames; const float* pcm; } wav; - + #ifdef HAVE_STB_VORBIS struct { @@ -94,14 +94,14 @@ struct audio_mixer_voice float volume; audio_mixer_sound_t *sound; audio_mixer_stop_cb_t stop_cb; - + union { struct { unsigned position; } wav; - + #ifdef HAVE_STB_VORBIS struct { @@ -142,12 +142,12 @@ static bool wav2float(const rwav_t* wav, float** pcm, size_t samples_out) /* Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes */ float *f = (float*)memalign_alloc(16, ((samples_out + 15) & ~15) * sizeof(float)); - + if (!f) return false; - + *pcm = f; - + if (wav->bitspersample == 8) { float sample = 0.0f; @@ -221,7 +221,7 @@ static bool one_shot_resample(const float* in, size_t samples_in, if (!retro_resampler_realloc(&data, &resampler, NULL, ratio)) return false; - + /* * Allocate on a 16-byte boundary, and pad to a multiple of 16 bytes. We * add four more samples in the formula below just as safeguard, because @@ -233,7 +233,7 @@ static bool one_shot_resample(const float* in, size_t samples_in, *samples_out = samples_in * ratio + 4; *out = (float*)memalign_alloc(16, ((*samples_out + 15) & ~15) * sizeof(float)); - + if (*out == NULL) return false; @@ -251,12 +251,12 @@ static bool one_shot_resample(const float* in, size_t samples_in, void audio_mixer_init(unsigned rate) { unsigned i; - + s_rate = rate; - + for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++) s_voices[i].type = AUDIO_MIXER_TYPE_NONE; - + #ifdef HAVE_THREADS s_locker = slock_new(); #endif @@ -265,13 +265,13 @@ void audio_mixer_init(unsigned rate) void audio_mixer_done(void) { unsigned i; - + #ifdef HAVE_THREADS /* Dont call audio mixer functions after this point */ slock_free(s_locker); s_locker = NULL; #endif - + for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++) s_voices[i].type = AUDIO_MIXER_TYPE_NONE; } @@ -289,12 +289,12 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size) if (rwav_ret != RWAV_ITERATE_DONE) return NULL; - + samples = wav.numsamples * 2; - + if (!wav2float(&wav, &pcm, samples)) return NULL; - + if (wav.samplerate != s_rate) { float* resampled = NULL; @@ -302,23 +302,23 @@ audio_mixer_sound_t* audio_mixer_load_wav(void *buffer, int32_t size) if (!one_shot_resample(pcm, samples, wav.samplerate, &resampled, &samples)) return NULL; - + memalign_free((void*)pcm); pcm = resampled; } - + sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound)); - + if (!sound) { memalign_free((void*)pcm); return NULL; } - + sound->type = AUDIO_MIXER_TYPE_WAV; sound->types.wav.frames = (unsigned)(samples / 2); sound->types.wav.pcm = pcm; - + rwav_free(&wav); return sound; @@ -328,14 +328,14 @@ audio_mixer_sound_t* audio_mixer_load_ogg(void *buffer, int32_t size) { #ifdef HAVE_STB_VORBIS audio_mixer_sound_t* sound = (audio_mixer_sound_t*)calloc(1, sizeof(*sound)); - + if (!sound) return NULL; sound->type = AUDIO_MIXER_TYPE_OGG; sound->types.ogg.size = size; sound->types.ogg.data = buffer; - + return sound; #else return NULL; @@ -390,7 +390,7 @@ void audio_mixer_destroy(audio_mixer_sound_t* sound) case AUDIO_MIXER_TYPE_NONE: break; } - + free(sound); } @@ -424,11 +424,11 @@ static bool audio_mixer_play_ogg( return false; info = stb_vorbis_get_info(stb_vorbis); - + if (info.sample_rate != s_rate) { ratio = (double)s_rate / (double)info.sample_rate; - + if (!retro_resampler_realloc(&resampler_data, &resamp, NULL, ratio)) goto error; @@ -538,7 +538,7 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, if (!sound) return NULL; - + #ifdef HAVE_THREADS slock_lock(s_locker); #endif @@ -569,7 +569,7 @@ audio_mixer_voice_t* audio_mixer_play(audio_mixer_sound_t* sound, bool repeat, break; } - + if (res) { voice->type = sound->type; @@ -592,22 +592,22 @@ void audio_mixer_stop(audio_mixer_voice_t* voice) { audio_mixer_stop_cb_t stop_cb = NULL; audio_mixer_sound_t* sound = NULL; - + if (voice) { stop_cb = voice->stop_cb; sound = voice->sound; - + #ifdef HAVE_THREADS slock_lock(s_locker); #endif voice->type = AUDIO_MIXER_TYPE_NONE; - + #ifdef HAVE_THREADS slock_unlock(s_locker); #endif - + if (stop_cb) stop_cb(sound, AUDIO_MIXER_SOUND_STOPPED); } @@ -620,11 +620,11 @@ static void audio_mixer_mix_wav(float* buffer, size_t num_frames, int i; unsigned buf_free = (unsigned)(num_frames * 2); const audio_mixer_sound_t* sound = voice->sound; - unsigned pcm_available = sound->types.wav.frames + unsigned pcm_available = sound->types.wav.frames * 2 - voice->types.wav.position; - const float* pcm = sound->types.wav.pcm + + const float* pcm = sound->types.wav.pcm + voice->types.wav.position; - + again: if (pcm_available < buf_free) { @@ -668,7 +668,7 @@ static void audio_mixer_mix_ogg(float* buffer, size_t num_frames, unsigned buf_free = num_frames * 2; unsigned temp_samples = 0; float* pcm = NULL; - + if (voice->types.ogg.position == voice->types.ogg.samples) { again: @@ -790,7 +790,7 @@ again: else { int i; - for (i = buf_free; i != 0; --i ) + for (i = buf_free; i != 0; --i ) { samplei = *pcm++ * volume; samplef = (float)((int)samplei + 32768) / 65535.0f; @@ -810,11 +810,11 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo size_t j = 0; float* sample = NULL; audio_mixer_voice_t* voice = s_voices; - + #ifdef HAVE_THREADS slock_lock(s_locker); #endif - + for (i = 0; i < AUDIO_MIXER_MAX_VOICES; i++, voice++) { float volume = (override) ? volume_override : voice->volume; @@ -838,11 +838,11 @@ void audio_mixer_mix(float* buffer, size_t num_frames, float volume_override, bo break; } } - + #ifdef HAVE_THREADS slock_unlock(s_locker); #endif - + for (j = 0, sample = buffer; j < num_frames; j++, sample++) { if (*sample < -1.0f) diff --git a/libretro-common/audio/conversion/float_to_s16.c b/libretro-common/audio/conversion/float_to_s16.c index 3010cb798a..bb97945971 100644 --- a/libretro-common/audio/conversion/float_to_s16.c +++ b/libretro-common/audio/conversion/float_to_s16.c @@ -42,7 +42,7 @@ void convert_float_s16_asm(int16_t *out, const float *in, size_t samples); * @in : input buffer * @samples : size of samples to be converted * - * Converts floating point + * Converts floating point * to signed integer 16-bit. * * C implementation callback function. @@ -72,7 +72,7 @@ void convert_float_to_s16(int16_t *out, #elif defined(__ALTIVEC__) int samples_in = samples; - /* Unaligned loads/store is a bit expensive, + /* Unaligned loads/store is a bit expensive, * so we optimize for the good path (very likely). */ if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0) { @@ -106,7 +106,7 @@ void convert_float_to_s16(int16_t *out, #elif defined(_MIPS_ARCH_ALLEGREX) #ifdef DEBUG - /* Make sure the buffers are 16 byte aligned, this should be + /* Make sure the buffers are 16 byte aligned, this should be * the default behaviour of malloc in the PSPSDK. * Assume alignment. */ retro_assert(((uintptr_t)in & 0xf) == 0); diff --git a/libretro-common/audio/conversion/s16_to_float.c b/libretro-common/audio/conversion/s16_to_float.c index ff727913d3..814ddd8261 100644 --- a/libretro-common/audio/conversion/s16_to_float.c +++ b/libretro-common/audio/conversion/s16_to_float.c @@ -73,7 +73,7 @@ void convert_s16_to_float(float *out, #elif defined(__ALTIVEC__) size_t samples_in = samples; - /* Unaligned loads/store is a bit expensive, so we + /* Unaligned loads/store is a bit expensive, so we * optimize for the good path (very likely). */ if (((uintptr_t)out & 15) + ((uintptr_t)in & 15) == 0) { @@ -115,7 +115,7 @@ void convert_s16_to_float(float *out, #elif defined(_MIPS_ARCH_ALLEGREX) #ifdef DEBUG - /* Make sure the buffer is 16 byte aligned, this should be the + /* Make sure the buffer is 16 byte aligned, this should be the * default behaviour of malloc in the PSPSDK. * Only the output buffer can be assumed to be 16-byte aligned. */ retro_assert(((uintptr_t)out & 0xf) == 0); @@ -169,7 +169,7 @@ void convert_s16_to_float(float *out, gain = gain / 0x8000; for (; i < samples; i++) - out[i] = (float)in[i] * gain; + out[i] = (float)in[i] * gain; } /** diff --git a/libretro-common/audio/dsp_filter.c b/libretro-common/audio/dsp_filter.c index 0b695ec87e..7f428eee12 100644 --- a/libretro-common/audio/dsp_filter.c +++ b/libretro-common/audio/dsp_filter.c @@ -186,7 +186,7 @@ static bool append_plugs(retro_dsp_filter_t *dsp, struct string_list *list) dspfilter_get_implementation_t cb; const struct dspfilter_implementation *impl = NULL; struct retro_dsp_plug *new_plugs = NULL; - dylib_t lib = + dylib_t lib = dylib_load(list->elems[i].data); if (!lib) @@ -221,7 +221,7 @@ static bool append_plugs(retro_dsp_filter_t *dsp, struct string_list *list) } /* Found plug. */ - + dsp->plugs = new_plugs; dsp->plugs[dsp->num_plugs].lib = lib; dsp->plugs[dsp->num_plugs].impl = impl; @@ -233,7 +233,7 @@ static bool append_plugs(retro_dsp_filter_t *dsp, struct string_list *list) #endif retro_dsp_filter_t *retro_dsp_filter_new( - const char *filter_config, + const char *filter_config, void *string_data, float sample_rate) { diff --git a/libretro-common/audio/dsp_filters/chorus.c b/libretro-common/audio/dsp_filters/chorus.c index d48c346fb0..54d9aa715a 100644 --- a/libretro-common/audio/dsp_filters/chorus.c +++ b/libretro-common/audio/dsp_filters/chorus.c @@ -88,7 +88,7 @@ static void chorus_process(void *data, struct dspfilter_output *output, r_a = ch->old[1][(ch->old_ptr - delay_int - 0) & CHORUS_DELAY_MASK]; r_b = ch->old[1][(ch->old_ptr - delay_int - 1) & CHORUS_DELAY_MASK]; - /* Lerp introduces aliasing of the chorus component, + /* Lerp introduces aliasing of the chorus component, * but doing full polyphase here is probably overkill. */ chorus_l = l_a * (1.0f - delay_frac) + l_b * delay_frac; chorus_r = r_a * (1.0f - delay_frac) + r_b * delay_frac; diff --git a/libretro-common/audio/dsp_filters/eq.c b/libretro-common/audio/dsp_filters/eq.c index 4033aa6512..a3defe77e1 100644 --- a/libretro-common/audio/dsp_filters/eq.c +++ b/libretro-common/audio/dsp_filters/eq.c @@ -149,7 +149,7 @@ static void generate_response(fft_complex_t *response, gains++; } - /* Create a response by linear interpolation between + /* Create a response by linear interpolation between * known frequency sample points. */ for (i = 0; i <= samples; i++) { @@ -213,9 +213,9 @@ static void create_filter(struct eq_data *eq, unsigned size_log2, fft_process_inverse(fft, time_filter, eq->filter, 1); /* ifftshift() to create the correct linear phase filter. - * The filter response was designed with zero phase, which + * The filter response was designed with zero phase, which * won't work unless we compensate - * for the repeating property of the FFT here + * for the repeating property of the FFT here * by flipping left and right blocks. */ for (i = 0; i < half_block_size; i++) { diff --git a/libretro-common/audio/dsp_filters/iir.c b/libretro-common/audio/dsp_filters/iir.c index 801e908569..748d0b8c1e 100644 --- a/libretro-common/audio/dsp_filters/iir.c +++ b/libretro-common/audio/dsp_filters/iir.c @@ -212,7 +212,7 @@ static void iir_filter_init(struct iir_data *iir, a1 = -2.0 * cs; a2 = 1.0 - a1pha; break; - case NOTCH: + case NOTCH: b0 = 1.0; b1 = -2.0 * cs; b2 = 1.0; @@ -253,7 +253,7 @@ static void iir_filter_init(struct iir_data *iir, make_poly_from_roots(zeros, 2, b); make_poly_from_roots(poles, 2, a); } - + b0 = b[0]; b1 = b[1]; b2 = b[2]; @@ -272,15 +272,15 @@ static void iir_filter_init(struct iir_data *iir, b0 *= g; b1 *= g; b2 *= g; break; } - case PEQ: + case PEQ: b0 = 1.0 + a1pha * A; b1 = -2.0 * cs; b2 = 1.0 - a1pha * A; a0 = 1.0 + a1pha / A; a1 = -2.0 * cs; a2 = 1.0 - a1pha / A; - break; - case BBOOST: + break; + case BBOOST: beta = sqrt((A * A + 1) / 1.0 - (pow((A - 1), 2))); b0 = A * ((A + 1) - (A - 1) * cs + beta * sn); b1 = 2 * A * ((A - 1) - (A + 1) * cs); diff --git a/libretro-common/audio/dsp_filters/panning.c b/libretro-common/audio/dsp_filters/panning.c index 52935bb88e..da1cbc3d10 100644 --- a/libretro-common/audio/dsp_filters/panning.c +++ b/libretro-common/audio/dsp_filters/panning.c @@ -76,7 +76,7 @@ static void *panning_init(const struct dspfilter_info *info, config->get_float_array(userdata, "right_mix", &right, &num_right, default_right, 2); - memcpy(pan->left, (num_left == 2) ? + memcpy(pan->left, (num_left == 2) ? left : default_left, sizeof(pan->left)); memcpy(pan->right, (num_right == 2) ? right : default_right, sizeof(pan->right)); diff --git a/libretro-common/audio/resampler/audio_resampler.c b/libretro-common/audio/resampler/audio_resampler.c index a7cc0c2f47..0a4b8b3ff8 100644 --- a/libretro-common/audio/resampler/audio_resampler.c +++ b/libretro-common/audio/resampler/audio_resampler.c @@ -146,7 +146,7 @@ static bool resampler_append_plugs(void **re, * @ident : Identifier name for resampler we want. * @bw_ratio : Bandwidth ratio. * - * Reallocates resampler. Will free previous handle before + * Reallocates resampler. Will free previous handle before * allocating a new one. If ident is NULL, first resampler will be used. * * Returns: true (1) if successful, otherwise false (0). diff --git a/libretro-common/audio/resampler/drivers/nearest_resampler.c b/libretro-common/audio/resampler/drivers/nearest_resampler.c index c5244851a6..65ced854f6 100644 --- a/libretro-common/audio/resampler/drivers/nearest_resampler.c +++ b/libretro-common/audio/resampler/drivers/nearest_resampler.c @@ -23,14 +23,14 @@ #include #include #include - + #include
" }, { "WRITE_CORE_RAM", command_write_ram, "
..." }, #endif From 5311544c651d29d3cc08d0fb4c2a9dd865b2fd6a Mon Sep 17 00:00:00 2001 From: Ian House Date: Thu, 4 Jan 2018 12:45:01 -0500 Subject: [PATCH 633/698] Added overlay led driver, fixed a bug in the rpi led driver --- Makefile.common | 1 + configuration.c | 1 + input/input_overlay.c | 43 ++++++++++++++++++++++++++++- input/input_overlay.h | 9 ++++++ led/led_driver.c | 15 ++++++++-- led/overlay_led_driver.c | 59 ++++++++++++++++++++++++++++++++++++++++ led/rpi_led_driver.c | 8 +++--- 7 files changed, 129 insertions(+), 7 deletions(-) create mode 100644 led/overlay_led_driver.c diff --git a/Makefile.common b/Makefile.common index 3d177bc151..80dc89e373 100644 --- a/Makefile.common +++ b/Makefile.common @@ -200,6 +200,7 @@ OBJ += frontend/frontend.o \ input/input_driver.o \ led/led_driver.o \ led/null_led_driver.o \ + led/overlay_led_driver.o \ gfx/video_coord_array.o \ gfx/video_display_server.o \ gfx/video_driver.o \ diff --git a/configuration.c b/configuration.c index 39415013b0..9e7eacc246 100644 --- a/configuration.c +++ b/configuration.c @@ -2508,6 +2508,7 @@ static bool config_load_file(const char *path, bool set_defaults, buf[0] = '\0'; snprintf(buf, sizeof(buf), "led%u_map", i + 1); + settings->uints.led_map[i]=-1; CONFIG_GET_INT_BASE(conf, settings, uints.led_map[i], buf); } diff --git a/input/input_overlay.c b/input/input_overlay.c index c88f052faf..6592906e29 100644 --- a/input/input_overlay.c +++ b/input/input_overlay.c @@ -37,6 +37,9 @@ #define OVERLAY_GET_KEY(state, key) (((state)->keys[(key) / 32] >> ((key) % 32)) & 1) #define OVERLAY_SET_KEY(state, key) (state)->keys[(key) / 32] |= 1 << ((key) % 32) +#define MAX_VISIBILITY 32 +static enum overlay_visibility* visibility = NULL; + typedef struct input_overlay_state { /* Left X, Left Y, Right X, Right Y */ @@ -528,6 +531,39 @@ abort_load: free(data); } +void input_overlay_set_visibility(int overlay_idx,enum overlay_visibility vis) +{ + int i; + input_overlay_t *ol = overlay_ptr; + + if(visibility == NULL) + { + visibility = (enum overlay_visibility *)calloc(MAX_VISIBILITY,sizeof(enum overlay_visibility)); + for(i=0;iiface->set_alpha(ol->iface_data, overlay_idx, 0.0); +} + +static enum overlay_visibility input_overlay_get_visibility(int overlay_idx) +{ + if(visibility == NULL) return OVERLAY_VISIBILITY_DEFAULT; + if((overlay_idx < 0) || (overlay_idx >= MAX_VISIBILITY)) return OVERLAY_VISIBILITY_DEFAULT; + return visibility[overlay_idx]; +} + +static bool input_overlay_is_hidden(int overlay_idx) +{ + return (input_overlay_get_visibility(overlay_idx) == OVERLAY_VISIBILITY_HIDDEN); +} + /** * input_overlay_set_alpha_mod: * @ol : Overlay handle. @@ -544,7 +580,12 @@ void input_overlay_set_alpha_mod(input_overlay_t *ol, float mod) return; for (i = 0; i < ol->active->load_images_size; i++) - ol->iface->set_alpha(ol->iface_data, i, mod); + { + if(input_overlay_is_hidden(i)) + ol->iface->set_alpha(ol->iface_data, i, 0.0); + else + ol->iface->set_alpha(ol->iface_data, i, mod); + } } bool input_overlay_is_alive(input_overlay_t *ol) diff --git a/input/input_overlay.h b/input/input_overlay.h index 921a905548..16d4774d42 100644 --- a/input/input_overlay.h +++ b/input/input_overlay.h @@ -94,6 +94,13 @@ enum overlay_image_transfer_status OVERLAY_IMAGE_TRANSFER_ERROR }; +enum overlay_visibility +{ + OVERLAY_VISIBILITY_DEFAULT = 0, + OVERLAY_VISIBILITY_VISIBLE, + OVERLAY_VISIBILITY_HIDDEN +}; + struct overlay { bool full_screen; @@ -257,6 +264,8 @@ bool input_overlay_is_alive(input_overlay_t *ol); void input_overlay_loaded(void *task_data, void *user_data, const char *err); +void input_overlay_set_visibility(int overlay_idx,enum overlay_visibility vis); + /* FIXME - temporary. Globals are bad */ extern input_overlay_t *overlay_ptr; diff --git a/led/led_driver.c b/led/led_driver.c index e7a784331e..c8a98d2a63 100644 --- a/led/led_driver.c +++ b/led/led_driver.c @@ -20,6 +20,11 @@ #include "../verbosity.h" static led_driver_t *current_led_driver = NULL; +extern led_driver_t *null_led_driver; +extern led_driver_t *overlay_led_driver; +#if HAVE_RPILED +extern led_driver_t *rpi_led_driver; +#endif bool led_driver_init(void) { @@ -31,10 +36,16 @@ bool led_driver_init(void) current_led_driver = null_led_driver; -#if HAVE_RPILED - if(string_is_equal("rpi", drivername)) + if(string_is_equal("overlay",drivername)) + current_led_driver = overlay_led_driver; +#if HAVE_RPILED + else if(string_is_equal("rpi", drivername)) current_led_driver = rpi_led_driver; #endif + else + { + current_led_driver = null_led_driver; + } RARCH_LOG("[LED]: LED driver = '%s' %p\n", drivername,current_led_driver); diff --git a/led/overlay_led_driver.c b/led/overlay_led_driver.c new file mode 100644 index 0000000000..271d42c31b --- /dev/null +++ b/led/overlay_led_driver.c @@ -0,0 +1,59 @@ +#include +#include "led_driver.h" +#include "led_defines.h" + +#include "configuration.h" +#include "verbosity.h" + +#include "../gfx/video_driver.h" +#include "../input/input_overlay.h" + +typedef struct +{ + int setup[MAX_LEDS]; + int map[MAX_LEDS]; +} overlayled_t; + +static overlayled_t curins; +static overlayled_t *cur = &curins; + +static void overlay_init(void) +{ + int i; + settings_t *settings = config_get_ptr(); + RARCH_LOG("[LED]: overlay LED driver init\n"); + for(i=0;isetup[i] = 0; + cur->map[i] = settings->uints.led_map[i]; + RARCH_LOG("[LED]: overlay map[%d]=%d\n",i,cur->map[i]); + + if(cur->map[i] >= 0) + { + input_overlay_set_visibility(cur->map[i],OVERLAY_VISIBILITY_HIDDEN); + } + } +} + +static void overlay_free(void) +{ + RARCH_LOG("[LED]: overlay LED driver free\n"); +} + +static void overlay_set(int led,int state) +{ + int gpio = 0; + if((led < 0) || (led >= MAX_LEDS)) + { + RARCH_WARN("[LED]: invalid led %d\n",led); + return; + } + + gpio = cur->map[led]; + + if(gpio < 0) return; + input_overlay_set_visibility(gpio,state?OVERLAY_VISIBILITY_VISIBLE:OVERLAY_VISIBILITY_HIDDEN); + RARCH_LOG("[LED]: set visibility %d %d\n",gpio,state); +} + +static led_driver_t overlay_led_driver_ins = { overlay_init, overlay_free, overlay_set }; +led_driver_t *overlay_led_driver = &overlay_led_driver_ins; diff --git a/led/rpi_led_driver.c b/led/rpi_led_driver.c index ae39bb2769..b17600d5f5 100644 --- a/led/rpi_led_driver.c +++ b/led/rpi_led_driver.c @@ -53,7 +53,7 @@ static int set_gpio(int gpio,int value) { FILE *fp; char buf[256]; - snprintf(buf, sizeof(buf), "/sys/class/gpio/%d/value", gpio); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/value", gpio); fp = fopen(buf,"w"); if(!fp) @@ -71,7 +71,7 @@ static int setup_gpio(int gpio) { FILE *fp; char buf[256]; - snprintf(buf, sizeof(buf), "/sys/class/gpio/%d/direction", gpio); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction", gpio); fp = fopen(buf,"w"); if(!fp) @@ -88,7 +88,7 @@ static int setup_gpio(int gpio) fprintf(fp,"%d\n",gpio); fclose(fp); - snprintf(buf, sizeof(buf), "/sys/class/gpio/%d/direction",gpio); + snprintf(buf, sizeof(buf), "/sys/class/gpio/gpio%d/direction",gpio); fp = fopen(buf,"w"); } @@ -102,8 +102,8 @@ static int setup_gpio(int gpio) fprintf(fp,"out\n"); fclose(fp); return 1; - } + static void rpi_set(int led,int state) { int gpio = 0; From 2e0eb4df8e10469ad1efaab90629ff3a057a753c Mon Sep 17 00:00:00 2001 From: meepingsnesroms Date: Thu, 4 Jan 2018 11:40:03 -0800 Subject: [PATCH 634/698] Allow using custom bannertool and makerom for 3ds, for wav format not found error You can compile the latest version of bannertool for your system and have retroarch build with that instead of the builtin one that fails on windows. --- Makefile.ctr | 29 +++++++++++++++++++++-------- Makefile.ctr.salamander | 29 +++++++++++++++++++++-------- pkg/ctr/assets/silent.cwav | Bin 0 -> 256192 bytes retroarch_3ds.3ds | Bin 0 -> 4033536 bytes retroarch_3ds.bnr | Bin 0 -> 267808 bytes retroarch_3ds.cia | Bin 0 -> 4046784 bytes retroarch_3ds.core | 1 + retroarch_3ds.icn | Bin 0 -> 14016 bytes 8 files changed, 43 insertions(+), 16 deletions(-) create mode 100644 pkg/ctr/assets/silent.cwav create mode 100644 retroarch_3ds.3ds create mode 100644 retroarch_3ds.bnr create mode 100644 retroarch_3ds.cia create mode 100644 retroarch_3ds.core create mode 100644 retroarch_3ds.icn diff --git a/Makefile.ctr b/Makefile.ctr index f1cbd87da5..4b1c034361 100644 --- a/Makefile.ctr +++ b/Makefile.ctr @@ -176,15 +176,28 @@ STRIP := $(PREFIX)strip NM := $(PREFIX)nm LD := $(CXX) -ifneq ($(findstring Linux,$(shell uname -a)),) - MAKEROM = pkg/ctr/tools/makerom-linux - BANNERTOOL = pkg/ctr/tools/bannertool-linux -else ifneq ($(findstring Darwin,$(shell uname -a)),) - MAKEROM = pkg/ctr/tools/makerom-mac - BANNERTOOL = pkg/ctr/tools/bannertool-mac +ifeq ($(strip $(CTRBANNERTOOL)),) + ifneq ($(findstring Linux,$(shell uname -a)),) + BANNERTOOL = pkg/ctr/tools/bannertool-linux + else ifneq ($(findstring Darwin,$(shell uname -a)),) + BANNERTOOL = pkg/ctr/tools/bannertool-mac + else + BANNERTOOL = pkg/ctr/tools/bannertool.exe + endif else - MAKEROM = pkg/ctr/tools/makerom.exe - BANNERTOOL = pkg/ctr/tools/bannertool.exe + BANNERTOOL = $(CTRBANNERTOOL) +endif + +ifeq ($(strip $(CTRMAKEROM)),) + ifneq ($(findstring Linux,$(shell uname -a)),) + MAKEROM = pkg/ctr/tools/makerom-linux + else ifneq ($(findstring Darwin,$(shell uname -a)),) + MAKEROM = pkg/ctr/tools/makerom-mac + else + MAKEROM = pkg/ctr/tools/makerom.exe + endif +else + MAKEROM = $(CTRMAKEROM) endif %.o: %.vsh %.gsh diff --git a/Makefile.ctr.salamander b/Makefile.ctr.salamander index d2000812f3..2440d044f9 100644 --- a/Makefile.ctr.salamander +++ b/Makefile.ctr.salamander @@ -122,15 +122,28 @@ STRIP := $(PREFIX)strip NM := $(PREFIX)nm LD := $(CXX) -ifneq ($(findstring Linux,$(shell uname -a)),) - MAKEROM = pkg/ctr/tools/makerom-linux - BANNERTOOL = pkg/ctr/tools/bannertool-linux -else ifneq ($(findstring Darwin,$(shell uname -a)),) - MAKEROM = pkg/ctr/tools/makerom-mac - BANNERTOOL = pkg/ctr/tools/bannertool-mac +ifeq ($(strip $(CTRBANNERTOOL)),) + ifneq ($(findstring Linux,$(shell uname -a)),) + BANNERTOOL = pkg/ctr/tools/bannertool-linux + else ifneq ($(findstring Darwin,$(shell uname -a)),) + BANNERTOOL = pkg/ctr/tools/bannertool-mac + else + BANNERTOOL = pkg/ctr/tools/bannertool.exe + endif else - MAKEROM = pkg/ctr/tools/makerom.exe - BANNERTOOL = pkg/ctr/tools/bannertool.exe + BANNERTOOL = $(CTRBANNERTOOL) +endif + +ifeq ($(strip $(CTRMAKEROM)),) + ifneq ($(findstring Linux,$(shell uname -a)),) + MAKEROM = pkg/ctr/tools/makerom-linux + else ifneq ($(findstring Darwin,$(shell uname -a)),) + MAKEROM = pkg/ctr/tools/makerom-mac + else + MAKEROM = pkg/ctr/tools/makerom.exe + endif +else + MAKEROM = $(CTRMAKEROM) endif %.o: %.vsh %.gsh diff --git a/pkg/ctr/assets/silent.cwav b/pkg/ctr/assets/silent.cwav new file mode 100644 index 0000000000000000000000000000000000000000..ea81c48bc32a6b4e432831700f82b3558d1909e0 GIT binary patch literal 256192 zcmeIuF%AJy5C-7cbp?fv(lKm^L_;IAdjt;PE{@_j4xmz4^Oi(IrTr$^{by%h-X`CC z-|V`_EF!AhRau_OE9?G>{;p%huzY4tOO7K( zC9}G$zA3X?f5T_iFCrGrw)yq%_YpyW009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C7 z2oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N z0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+ z009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBly zK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF z5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk z1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs z0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZ zfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&U zAV7cs0RjXF5FkK+009C72oNAZfB*pk1PBlyK!5-N0t5&UAV7cs0RjXF5co^r3EQC; A?*IS* literal 0 HcmV?d00001 diff --git a/retroarch_3ds.3ds b/retroarch_3ds.3ds new file mode 100644 index 0000000000000000000000000000000000000000..50c316089f265b30a86d65038ba041bd42b3a645 GIT binary patch literal 4033536 zcmeFZcT`i)yXZYh=)HJsjmqK399nR@TnTAhpi8u(eJ*CxCcp8~L^&_m@t>oSV zVYjt}PjYAM$E#db()D@1|0+m*oxnWYUD@@l#+uXj))(7A%l;*1-sAdhCw+2uL+Z%s zM@4e?(h<|byxPty0l42o553L@3G&c58QYju9!<4RGBLK4ir&40b`M^!C_YQyXZec~ zSR=_jR(RRy{rt#ZhpCrzvXO6Zbq%#n>oNtjyt(Z%h6z5-c>cMUZjbJ-^*~2UeH#M+ zXaGP}Gym%f{$qglZyyN#N7;YV9TI`qxBR~;$A43v0NxM(UAF(Pu$!U%e?>753VA@_ zfWQHP0|EyG4hS3&I3RF9;DEpZf&XIy|7pCL{Bo~9KK@bR$j_aG(I3*^1*~(48LJ7bdR`QwdMlNBVwDyMyYO49IdO7D}M%~kKG zPYqo5-aY)OT>33hL&vA{k<+QV<*{fbtK+<;@(2+V%fmG-!I^1YA7#(e>$D(5r`EWc z9r29~Ep3V);7<{Qw8tXfXuU}H+LW$)o%Y2`eZg|h&GcJ*Acx@K zY*)10d~WvUspRjyi0$KxaUDnYO06F;oVvsFDvZ~!w1T$c>i_Hi|F`2(m(F-GOJ7V- z{`r&Z$g8SKn(om}`y-rdeWv%0ADeZ!m2h;|RDF6uWw%Lnessy_KJmop(k-Usfd~^a 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

!XnHw#p3SFG;Viq5ZOMl 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�@Vuk{meH91SJiJNG&SO{$iUsEI$ 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

fy;>>H@eM95?l;oM~ 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

~QP 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%0AYvl(y3h#fj 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

AD>^SRZdd*olhrVG2g?;r>3yq3F?MRW=~D2 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

hSbTkQ8?DfD>A7r3lTc7>`wq+3S#cr+AZ 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�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%0Dg7K_R7Fnz_R$Jhii0?c9 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%0D7TG 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%0A8v9GUi`OL#b4}8G6cdD^4NLlzh?!&?ym{SX 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

MmEraDQEh;X6P$d?MIo>IxqKRcOgGQAC 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 z zU3+cfYC4i}0!!vDQk0AXWWJzAHJ?p9&9JKwFxC;ywi{eB(+J&Tb!y-rX3dNk>S^yD zYkrk9&MkT7bwra)%==`SjX8lDTY1^LaY9*a>cwpKQM0PLZpIItnOPPUwgz9#*F@iX zX2*g$WYWC;h7KP;k3l2>SH1e9HNPWs&z(T*=B0H%xna3^LUuw09?IZY8`&~r!M7|S zSP7V$fhaCe&+5XEtp+6Vl1$5Hwu`j;?Mzah;0_o4S9TD-5g}?qL3Tq(XZeXSNNO3C z_)n+)z%(P(w6vDQPfQ!!x;+kkn6sdtupH6wThL#6utK7|P5mPFa-egaxqc zC&i8zJ*1J$U83o~sYh(q6P@ml_o^)1XV_DI#Q~UEOfTTYpleLhXGd+lgx?R}{d=71 z{1<8kLjrY-cr$;(WRg$MH0u9fwcUOEB>5=F&BI*Vh%UD>WuARksK_+yDF}K*+u2A% zhWj($C9m6{u6=^5K~Yqg32ypl#RFODR`OFvprFp?CLph}f!k2nd`7Pn^3)wNG<0MF zJH>E)FK*QN$d%5toTot}S&~#^xPdRkds46}MOyc!3gEw#pR(6^8Bx~=cOIuDh9+H_ z2gPRwa#P=LQX0{*4H@I2!vL%j_P6X(-d8;w6s7-0!^z7mqdrPN7FkxnurGvA);y z+7z_d*deCh4lK`AM+a7Rw283s-FlsWtU2U34YRfp>LRRE09Qdc$qp?yv97sQWdjPi zYb4h)=wPh6)C%N3gmsiRtGwlf5vjG;PkPLpVJtc-V+$s)j0{gLYg2o#rU0o;1w(nm zho($G{&?n99Mni^@5Qpbw7gKP4G6iQq5Rr^b>^+uK=5RFez#J|J;S)XhO7VH;qkNR znt#4n3>QK2dEKDWP*tc`-u4^9;i^FL7WhI8)Sig&p1a*eNZ9*BrE^kWWa_Wi=6Uxn8O(`z&10$Sx%{p_8`ixP({p|@61Uly z8!fOm6em??uw4JL!t*t1W>Ysr*esVB_1sGQ{GiZBy!+CH_@_eT(Dk7QoFo7!_; z#roN9R`TQpE_R1g9!vlq$2e42dO>Phb3?w1$~efgil=>$ ztQDH?&~Kt^5y%ul9?$@d(`;U2pSnrhtwoo7<iU$% zobU6EQ}J*8%3~SgO*Vq=ulPdF3q>ahRRBCAm=8P-#dX>uZu8II7{tsj)S^WHS&g}X zfLGIG_Bjs-0e~ThTwvAyAZkiz?!JR>K3t%+w7uR|O(-oMZl7+0v77kJv472pAjKLs~kp;TldS{vI5 zx4Npdla;3&X~Cwdg08GxwtacIP$OkeS~d0dwrCNY-0!=}DhkG3<5a$fC(9eearXTL~l`={bBv_4WJIv|mEI z-wi1zIJfQ5;ct3{QzgL+)!ivw5yZWAws82D%7?2f4C%%l!_rByA0kD&=voku2^I-M zDIl+Asw~mwdCeFfFGNb|hUi^Z_P5G&snavzdx{BQaQOK24N^TF^(54W_ax<7WM5Nl z&IvwVrAcYnOXd%6K)i}Mws^ah|MOm^OCj_v{hv5E-B`v7pkp~%J7X79MkKa+JxXMQ z9wc=Dg`ZYYL3O2|RW8Y^94u<_4W{f9F4Y`*R4CZn=IUxRDKWVM$RWjpk?bB}8lK^h zOcW>{!;sdYpagr*B^Q9dVttU7yqRIi>I{-~UoY(jatv$@L;5Qcob^WouJ>lNA-~?F zbFfQCID$zRPs;4WQYRTRr1XUR^0GDS>Xu`2Wp8C{a6pF*Q(-OFa>5MIfvPVl(L__Xch;NrgHKJeAZ9LuS{ zUU*S@j(j~S@nRs+(Zzyp*StvbqbU!4yt1q4f+6{;F04IcGmx~B*OI4V3G<*{bSl86 z-CQ3Zfb-SozFVIF(1NX1zVnkiz*f0?l+>2raZ0!4IQJU^HdH~;{kkn8WKZgjW8L#? zmV41-XRiFGVAxS2hhURoQ&gQF%nQ2gNbmY#;PCdzJLI95Xh1)Y!~4qF`2~WfaH9db zOO4Cq6-7l~izN7VZLF|u)!cTQn0}A^#QYWJ>u53rdu8lfdRs+!Ld@c^r@;`;=4l^V zcCQhrgaI(x)AiDQPtLNgE)Y9cB!Ob4p1*;BDs0`F7BRi;lfa^c-0$IbWszr>rukxPCydgMFVt=zs&_)&`T@RDjE-w>~)=w(|u(`(5CdOH_q`vPRaJl9y%+n#E z`9hZS^yXOlegFCvQ7t3ZFU`__w<(0bQngSh{YO~F;pO@*$^TTz7t;a}-q@wf)Qm-E zV3-TepDf6$SHkXhj~9C?9ANjs_-SL5K^N7p1k75qkp_v;fzV9(}JA>pf7gak8tNJ+wvgnfeVt8Yu!2%RIhv^5ZAs~>*S#9|o27;hLGxH~d|2kAN62`lLMB?Y5= z3F{dqU&{3Jzmm#|Xl*nKh>Cz$!bl)rsh-;|2e&&QfjRif-j;Etm9Mpi2w077gspaC zzOjg1{_fHzBMRRaQF)|-pIuA)A>FfjH!#gaxko^qN%K(w8lYiCOs@LwaL$D85EX+= z`$KozZqvr_PW4as5kueY%T?w*&Dm7mI(3u-O?wWx0b-i7!5)+iM>0X1a00?lfi|^i zjJAw&P?Lvrpv!|(Z~5dZ;xaC#vqJ4rEwxbVQ{d0Qd9$G zv)q}-rcqHErd%;yNmWj5Uz$+k2X0}RdCvdd5Ml5N;3b+R1*vs>!O2kPMhW#fOKC+I z)mW@O@LQweRNr|Bokr4||NI#z)8p3mlF_ zVS-4A7I)P8`+QtGJ4{{P^q%+20lIIro!y>+Ps~d5&k@4o0tNF&M6@i;^eOTRvtJ@Y zcq&FjG_H=>pa*E2Jme(0GNek0*Y+#UJaCIWw=gXaM)M4h%=DKLEf)im6!F*>*SbCJ z5mI+8K8*0!ks0RO!eid@?XVpCiE!p7FM=)bWc}mG?hWK{ocEAi{@J_QV;nnXCKTb} z&@8K^ROdKHQpi$CHSHBotSQP~d2vp_t(Uk3EPLmC($$@9bnc2LG9V^p{2(eevBK@# z7y{vF|Gw%um#;{UP#ZVC@BF^4X}cI$P)`6Pd*{fg5)n}-jFzt^7YL9fsz+x6w$r_R zuG@QqS_2$7fsx9omNEUsSEe@pZ*(aMqJGm}ZjS1{=^&)8iX3GUG9bJ6VXw7yqUyPq zOX2Z|gsg5`O7^lJPN|swxxu<tnqe?{A+KP0pXRu5>>m z8@}UT)bg*Puy_6}vG4r|#dtga+i2m5tpHwqf;5&mfHcn`|B7QWf# znQdVB$YVS|7Gajzy|wn~8H#ssFIr#RYyLNuB#{h;=ZqjMl{?NPr{8k${6^hljo|nE ziL|M)iJqGO1$x1)(3?tS1dq4HeAtM9Jr)T#-!;L;M}w_GP#LL7)lui|A>EvKuSs1Z&H2eIc48dFbKeUR%ys0-O~=Y3y2#YHibX<$p&x^1Jw~@Vf*n9NMds5xOC!7dM-ecGtQgamNc<(CBi# zdPOxUchTlZnpxWr{whMp0&{OAE*uq9W;xogKG)_3*~{>|?D-1g4y@={UB|%tqU+Ub zDAqlYxlsW1C6;_AQR9z?ns`SU7g-?Ux!6db*w3n5J9m3BK2s!Xq!X(D^7jXz;H!(f z0C6Tk-!%o=rNa|-oNI!{E)R-hfW`3W8H&47?~`6^-~W4#<6lOtw-X4}|1cI^Y@;HX z!ES+-MQ`~^F;3Q9S-o)H-69GKg=xSQ&SOa$gXn26uDuf6&@kWVU3yP?A&G*rmnDB+ zK{$V&!f7CSx$cAJ*amo}<{*!0$gEW2kev!9QaCLg8|;HZZ}B35=10f8Q^AvF-4tv+> zgDbsGYG6KwyvQUiLJjashZW?{R~$Kbq^7~S^vSe2CR< z5fActu*WOOC*=A2c0-d!^*~9AhkpAb_t*1gANHW9Oz(%_`*^8P%m~A9exsUS1mKc_ zZ1pd^-GkX^ne5=S5`SGi3YFv|)XMB;DTO!QW7ATZmKI6UsF29XD=y4SZ!eDwZxkL& z6#aw@x$U&?hTY3dm-f!J^yR{N^Pdl~cR6@Ih18U!ez^;^Ov5!hS8Vo`3H`(WKTmMD z)l26h|0v_hNHR$us+5rM6sv=YGB@}Ehn=ntxQ|c`5NLaucXB^}@Kcmuw zWTq~ep>umbwBX9SgFbkWz)ZwiPbuCjh5XIfb8-3n?eC*zb=lP;?p9qxrTVe-lRiiR z^Ocva*1gMEA#<_C`-##2U~L^U?dCO2%p%#K1dG(0waZ&CA#KLBAT5C%qSG}wq$V0b zC&hNLCfObMgAI`^(FsbxB*cID;)9T2JqW4{{#65%}I$$Ci&2mLDYHGc|4gk;&-KeWW)WNE*Z-N zZ6{oI#C&E{9+L~3X-*RS=0Pw904o&8(c7lSTc9+LVr_&z9|edsp$KTKZmrojwpEI7 zF0Ww-LwZg}eHnw>=^d4(w%&asJPgKxAi_)CY{Za|&6qx4$`f-1J0n1owhyhuuRFtNx_lx1uY+B$^)+HE0i$e&`i1~Wt!ohc z0}B+0l}9%9)+1iN-aEB%xY<90mruXJ8zn1LUslcR?=6&Xyz$6-J4kLe0$LzM14u}n z1;lkeu?MF^*UH)G787D1j__!d2yp|21bLw&o+H2Y(+bQO~^B-=l(7h z1|R^PBmR_DqojuWAi_BFv#Svdcw+t{PzvLs`TAvW;j;47Mf)L!b!suzje0Ch`j`4v7JiB*s!@Zho;i0qKbtv#Gn-VD;&&p#*tiaHwznWe zy24Ry)qSTBe##D|P~q=U)zYLj&P1oCbFL!AHwxa|*OQ38h^gHsUhNGaAV|~nqoKj0{-Yc2W``wOxqYuQ%ef?F zZw`aY&S^6M|CR$ldhqTr3qKvRsNvyDdaDW^sAR8epDV3{2I};sE-P{Se;+dyGsV$| zG1OK`*^vV`s>+!y=`+o)jY~QmN7Ea0D-U5#n;}?Y*9+|iWtaw#wmOl(4?V!(F*^inPXf8h zEqNtS4%qfRYD?H;R_CM4SXAtFX09$sqSJAl%yBL;K@oe>Y%N>RYYo_)#nsZSK|2F@ zp)< z$aWx|lw{BQf}s2_>$`qm=sPE}Pi58%NJ9z+^fH6*%vhv2Gs8k8lce1PFp6I8?i_p{5znZ!y|LtS1>ieA^aA4@FHhI z;0zj%YVUcPQa0VV^njv2iTZN9Wjh3O|V|FiafO zrn1o@hDnmz{2oxpbmZEH2y{qWdXl((c$PM!49JELnnSJ;{yhh~7v6_A5S!$FBg!6~ zo0|JXN3mi~KIj5d$xqYU$U!4@O&zv~v~#Pt`NS$)c*1$*i1Nt~Aeedk55|b$3M?V0 z7SMML&1!-`azKvlethlqLs=KaoA;T&pDv!>H}M7upd+3bJ3U2^u}(%Wi~X7VURHm% zyEsr2FXvBtiDzbfBh~6;QMqyFhUk(ool*c7Xhw@E0KT7;aID$4AEN|eh+WQTqExh% zcEgL<=mEKe<7U%he-6M=T6fi1an3j!5sFW(*SGgh4|;8z*27TCmSsb$)GGB8q30jd z1*QKR3N~a)9t`A_6$KtMw!o!-^A%@+4w8DjFN@aBss++M^(5pZkx8peShFi;Ikj*9 z6duUeXpc!UWY}?HG6cw&O{fls2yg76@);8J@+qXQ$q;`td}V7nBWB4$=v3j+zzv)7&4-G7cSxAJPF(k`CIF;XL>oO3TIYmb8ls{ z8u3ChT>Jd>W6sGuts+~q1OX0vR|5<2#I5K1t&vs$&LnQ_*K|f z9&{vP&d=c%k+P8Bdg7|$Y-sau!@P~GnI|Vb7?>ei#`#qv^*Hw3DoU=RMpMEVj5HO! zVTWzbu=&q$)bfmCh^Hv*-k?1#oURTLGE8{6K|H-Ju3}8HhZmaTGd3(Gh?$%kwv+uz znf{{-I3AKRdeqTNhB+XuWDLL$JH*(bU6*Vs29N^{;Yb(W&}87 z@ij1;?soYr(G3J-zi{30tCJr_iIJ|oct2h?V(_z+3p*IS$kt-A-#-Wboh?0yTC4C5 zjr>%eXrC4TNs%vhTGx0^8~i-f8IpRO7@bo>B# zzWsC6L>kF)G_bl;0byRgYy=}6s6IIplPBC2<1zu0+k$YEVot77o@xVGENd6HNFJy_ z$M7+zXPd|RRn_craf_@Xj8{$6gf2JQW}qet+a1^PR)yLf+qE$^=hWTd05!x=8boJD zfON`Y!hYIiquO`J>%huk@0k;6f4;mVka=fBoX^4H6k*ss@e zNZ0656X9yh*O2OfJc37?KH+q0)KLxy=x$+^lf9hTX9 zq0_QfDYaP5JX5cE;|gO${S2qFTcOvc&)uwO6ci`{FBmpI``;<4WCY(Nk;yJk(oOge zzh{bxGn-u0^eMFPX6n#i>dE7OD7I-1_xE2dxhcQ-!LcsjFvkoJyM?$0msh8&vX;HZ$ZN{%hlMd07dY%u3b%XfoUyj?rNPg^^SJ zqE~{FJa=HUpm9+5F1y%t6hRuaX54-rJQPtbi?6=Y2*mxUERp(u7BCP zBu5hFpszI`5p6MAe#JI4tWm)J2=HqXD!jJL=RR|VM<0fyKE(Z$akKKNju{)Xjc#B1 z&gnSOs|MjMZKh}b7e_!}TQ*Eup?u85p#2l6IWhzq%-XSAhF?TP-Rk5ka{@{+-+x+2 z(-^?gl2)~5C3vmb?+a4NpfgS!N>JqUAlE}fft!kT5+IAP=ldZOpM-+1S&h!J%jEpk z^DYO4M$CYk;qqSJV zb#j3nX{WVq3PkX!EJBBW`4;dDYbiJ@V$9C2gfeEF)!*F5{@hh*J8m2OCwHqCG1JUP z5@Uo76vdQn*^GEG_2~ZF2_rHP$r7ZL)_NFUIDx6)>Lay^mb>4Cw{7hligLt`+5RD#wfN7mWeL9pfyBoZWJq?-rT$E5+1| zfcX-?Vc_=8ErVV7zb0v}+qzck>VIH8Ky#yQ|$*janXonhsJ-874&Ir`|oC2t{4sHTT(rKmCx)ORD%IfOWhG zxT5qeil|2w5*+PLdl=T|flnt*8K9OF25hgt*4v}KK)YG@7I>559{y;rrv1E8M0FFq zWv|-652u(?00trBk}r&WV}q(uMLcr$y0-!jxJvWQ>4zJe^rp1lV%dME%6b?8mt*jj zM#S1c!s>YdLcP|;wf3?4e!I!_@P&qhbzQsb@r_Yvga@jRubS0!P4x!wj>@;MaliO| zWz#cPbwQB@VVdn3Znqc}P+W3GXB?bnFY}AmA*7!#6Sxr$C*Qjihw2Cb)KR{&tpc>- zuGDuvUO&*4#twhYVX(`haK+cQNyIa*23u01`UVmneyKb<7yzGWM%H5W+}JScFkE-2 z@v<P!x!9%eX`5 z+u$8gx?L0h6?gZtJ)G%Tc@;ewMZE(7pkh53Z5`84*E$0=`3Z+XKs_%UN*1>gHQN0N z`*U)bSJ1jd@%Wd~a5eQ)fv3au*+J(q-Daw%VcDR%i9E$?JMe~$sN#2}Y!dvMODd$= zQV48x#iymp$p(yWzU87Qn|CZlD4f@^HtJ91Vd|3_bj5&MpT=+X74lvu+Wd1rv7}F? z$4MBD0+^zs!eRGalr$-Jp=1)Wsh!=w6q$gn$u>xjCOa5oQxe->2cP{!dq03*0B3z8LSH2%+)bB<@Np(+D)mBx{*>jJm<^|IKR~$e@|RhW zoFwRI{O3ai`o_StKk1zWP4-x!Y;_4)=FQBZExRArzD z5KK5?0GVSaKV#6sA^(8;v7AtGa_P5t;}=b34z*u!mM&emBzj(mry3&zjDN{)+)f#> zXU;$ke_iyY+Ed4T(@Vu3E-ZAk%r-iA)XK1!9jQV+$M8(~)f|NyrggBQ{z58wY@GP5 zC0t_s@0%}fMfbH2lxh25lv;7wK7Kh9`tGlznyT2_q0NS+@ui0=<#I49GjDguiA4=` z8ofz^)$1$;Z2$iTl#5OdGGejCi7``)!KTgCl%_D@3d`v^mr*AvMGim zAtQ+ZV#4o5gDpp+*ZYoF5)yS^&tOr1mnC^vhgQzku_7-;#4N=5K1TbpG~sTcG`E=V z$R}gS?iX0fCbed^W39;sC`6}{qUR&7tl{1Fv2Rxvn}!7~Q|&~n9X`$Xi`w77 ze>J`|UETO3!^3mUx1Kt?H|#w9z)<>Es!1+jKvBtUhJ~ORh{y0?KQkvy>5N`116rbq z&y*DXThv86YJzn`r#m@JfLnu%-j4fMv!EUPjc}&*Dg)6rWiT;NS~wV&cJObm|3;g+ zj#*z3qIHIJ0IoN`d7{Fy={tfsE8B27wb%h?PJ!!u%;s$}Pg3St&FroJNg|mL&my>q+y(NBnnM0ch@ zJm4C^XXwpkcvwye70gTc-@V=x( zaYaC2Ol8?U#e_G>oftLV9kHUJCjn33*I_1 zM`}rn?D8Z=Y?b`1NB(K!MOe7GOMgk#PeV zpuKFjU6kH$u^?Z}&Pw~bIDpZ8Zr_+-A&);_F1c~In$KI3mCl*h&Y$-Mp#Sa6 zjP%sv!)~atfFe}&2C=2Xb%+ym1D)Y^kDM_c!YD#5A-59#(8^HLO|DLZGq$w-Th zZV}nEP4H-KiLy*dxC7PZdhZ)l;_w~80uvuSOyxBY5E|>48;r^L8(4=M8L$i^{(LnD z=MrlZZe@slY}o7XEz=k}M6^t_O#Uzlc?ynVb7o5*O6Yij+O^hf$a$l_c5I*Vk+E4U zjfRQUwv7CKE7X9tuB(TKykrR%sT2?3kIc;WR};iF7E;V%C8}q_Mgm=!ShGV{^yEyi zsCIgw8q0HycVL(M!Jb5Jh0@5V`#@d|Mi1%(Y5r`4S3(c5*NYgAQR6=1*IwZ&h>_PU zZUxWH<7@9uZ#{<3$tsT0r$=~52i`mz0~4Oc=Pd9O`5p?+MPGej=?Z&6OLg>ImVxk7 zc+|Z-@Aw;|bUdRB=60Y@|Cx~+q@2kNs%M*RSCqnBK(B@8b5U(}clJ2v)P%S~7t9z6O zo}OG{^qb!iqf$%O;+w<||D@Bsz3rXZvUb}!p6gUUiYSrs+-)l-F^BS$7ie&;!Vq*G z!+Qz(y&oB5wDm*tS{ZMFjWI}U0wB-umgDG#W8=&Dc59e0j zuXzds(IZ1sUq>inOuy}}IR-t)#l#W0sZ{r`p8+z$=6!$o_&aJeOt7bRsdzDC-$& z2fhyQ^$5)R&-0k`e+6A?eUH5MMIAlL%q%*jM@5qr!8)%%^tv(QCT{oZmG}n9mqJVo zd`$Hl9v#NIYq1J7_tYOZsj(@nmaj4FrIZ){yD+?lL+K|eWFw&c|7*qt(4E~)+EPt) zB9o`0&6b}w%hgeHrG8-2+c)>k7h&vL|F@zZ)x&WaVPgiz&>4KGb9W+0Pxa1xNpy}Q zYFhJ_C^yv-##y~Is1X(oHRgDE1)z;r>K<^l`Zg0Z{#RFd1`%5!Q2Lh{TxUU_b-M87 z8wFX67{(do`B)F2NeYST4Uz;jIqe+#DE>pZYLiOCvejB)WgM|+KDxDC$T38Gkxt6l z9Ky0t5vORdP1qAfz>vZsL20>jS3{Y}J!|MFvJfZaUO6JKTOp61E&c5Gvxwfn--Rut zn55?VHlLqUq)nvroJJ2%mlS)QmoRDfmAfe=GO==}HmP&a$>H-v6|I)*^?sDjfzRh> zmWvH0sI#p8>1vQ3rVIPRY~x#TPH|Z1k3~ab#&-XDqRGV=reR`uJ73z z+$#h{=}j4PNCcCAf#0!^?VC|;s3wi5jqVYr*Sw*i`k-Owj*#i9d&I_$eaGg@o0uBW zJd))!Gi+RyOKRKMS| zgOI*;2e8jlO@{~Anwkic7}+!3kD%67f%w3`#w(hd&WT%_6OoW)HV61G5wKS_D2J-Y zDu#ZR1+CJpE6X~WzP)E`(WD>{j;p^wEbG3m{k1xqvyUxjUT&wjg#nt{#P-Juhd3G2 zKH>O^OOt<_KSC<>-d+Rl6I3hHdh2*ogJ@)ry@5SEv1|}TKWl&)7`nXMTv$;1_-9`RSf!6V0 z-ThROgTp@lnU|og>0<{EX^)W01Hrrw@HDTf=0K+>kJ7HctP9_bqQW;9AeOw41y8Rb zPI6Co-aBKXrz&5a(P3#}c^q90mZKuZed2x>DJ<)*mq6N*4%Iwnf1XLb>%aAI9}WCe zk%fen%qD-q|5eQFhWqrqcfRC1YpQ@2tkzoa1xo=FMt>GuMkc%>Aq%KA8qPD539dew zMo4KPRKp_HVk|OCE-J|`H=QK`ShJkuL-^E`#;j}c)gXW4q^q&`st$mpgLeN* z_KAzTFPb|Y6S|IsfaLNE>Be*E4u|q@z^)vq+HbB7{ESkQO3)qjg2Yw`eezvIVz}D& z#iH3|e6ZiUMDcOEC^>z{Al2>g2?B81SvPq)J#PtuRtLz~ih^fXa=NG|7&#T@VLk~j zKkiE{6{SWO!al2<3K>RHCAX;An9fF0_lhyw$3K1iBADLoRWM=hC@YRh!Pmql?@XI{ z>pjlKxo1mX?Lcu6(n&4Gr{tOHBy+OBY$^(B-@bW;nSSY)@)>-EwEZn12`Z6c8kJf@s z^9T8eEg{sFT(LhE;Y9}zNB&JL?gX3L*ydnn4XNG(;BqBsmz~fpIkTvAI^{ufVDV{}U!u z4%*5b&4imIXA4^I#QJ}=LVzqAKQHN!#7IG;Vl4_AOR-9;0E9^P1yg{2rJj;5D7kvS zBShLYxVh|Z)^(%C;{gQ<0xPAX$mKMNEH`kD+BBv`*W2=cP)MYC$>=1SZpcc${*Zn% z=AUK2adl+5DMV?|k8YCIA7@6i`!wj5P3HT z$I3Os=l<3)TCuwhl88S3^oWL$r~Nm}e3KLuQ9s(;kLs6E4J zHiF>TT2)5e6)tjWD0cj1Dr@tu))=^XQi=1U(+*($;FijVlLk`?OHc|s z&b1>v8f!ce)$Y5cOa-Ul>YPf#f5P|)#eh>ai)TM$X)Z5D*X=M zN$FbMeyHJ>UsOfbL3p*f;ELQ5sdYR~AIKEha@NJ2Z~+|Ad|h}ojcaAPmP8$NSiBP^ z5#)3fz>AXr=O`rZk3RKN>U(;S-e)*5QIM~b{bJX&^YIxQfi?1t2Ude8-@ zUe)pSExtTd;njROIE*xEk|}#XNIiT8^o;b&h@$6M2Mlpn^;k-|VBa6I*G6IKm0$ye zEYtCwdk8?7RDV47j3_>6%d9u6&QD#{rGmq}0Q|_B3PN?04!CWmxyeM<73fc3G7;Ry zm<+OWw0tPgr<+sTuzeMR%DpWNyrQ! z3}scw{1NP)>99biU;xd5`|9!JYo$s>;uy^fumNHkC3O7@w=JwH&cHZi4SECR!p8<= z$o#h0c*D$gY*?=L_$?uw3%5kikF%v9?^%qnKq%$Iasgx3D-*oCUa|u)3L$e_Z!>(? zLixdkm5TwUAHZCTKrG@P!dFG1$L0`)*#Bd|r%ho0|FR$j2g~>nOy0^&)^Ci*DV(oJ zP=BxcPM}CeK;rh?L&h~c@2ja@H&2jvEnxQSFn@%aqDV}{sbZ$x&uZ9H?O~@%Z98#j z)z#XcsrN_~k36R%L)R2@6mjR*ROM2vOf@;3KYdFM=8CP;+-lb_I|E_O5JLd|-+6hT zq%d8+AJdN*FH7!aZ0G;aGVPHnvN(I$0GcX&(8I{Td`Mr}21}*f8->IS z$v{9VW;R9}SdyWz2{;oCxh*Cb))Pau7=O;VoU-x~^)CdX35_SNZE2PApwq1CU#YD) z35luO9Yp7RSBJN#xYDqmUSStIRpu6|oQ6Cs@z%;ZpvICv&ZR%igggiL`d-f@g-#}z zTtgrWR5C=~inrKi`#l@Zm6zWyf4i>>$6Tf3)#%C4rl9qCN9x}R4iVvR@=jgqZ@bf4 zePUlgXSorUO|d$jw>=D<6kp%L#YK|mAd40r#Kl6Q-4QLN_v$;?ess*N!+yQNMm`i? zGMH`MG8M6s{$54E+B3sx)p0%<+N-9@drxXzIIz1UqrW=e#xR7_;XPPjff=;jvA;G9 zZ_5VpteL)!m~V*HFB|R&Ft-grj*068!8GQ|W_*)z-Xo-0zw$p+B0;->BhWM^_Hm}0 zKmg3H?wDBUIq@?NJ(g}e2z5&p;=Y{~Bm&eA_8cEZ+O1inUb)S14VGZwIFyfFGHC!jnhuOxY#1DUU+c#zCR>C-?qCTl;@_9c7NA$g`t2i*?!Eni8yuzph8V&byrw<8xf?{?Girvd;FbUD z-$0&U2~OiJN3Ezz6#v^fYkPpz(PRoR5YB2EPmQsn%r7g~FhQwd{d<3mQJFfefn)xwMHI>KT3D(5ESh1Uu=Tt(YR_cxx~&6OXbj)I$y3i&Dj=5e8i9Ii)AfRMb% z+@?0sUh|9JZXiyC9082$eO|#3SOZH-+^Gbccq^Ep5#wYoWYiSu5hZx|3`%d0(`WLx z44=Q0Ww|+H{G-9WUbsISF|n&5Lcv7q2ghGQoW8albiufbF0%o%Vn-nuBG|2;u*36t zv7h03NDYlNhcYPmocW`+e>n7n&YiQNi$ikmG8|tj=l**9S;C~ay$Yo@9qlGn;c^pP zkPGZpNP#Rg(XXd!ZdZaxbCwS1xlrkWowFel?W2|?8$8MmIXpNg z6LP43rnGhz{U?UvKLCoRZoH5{m5js^n=5Ct|So7z! zx*@=K(6s)zMRJPTQtnKvfQ;`iNC%ky=d3?s{~@wU;m^Bm#WC{Bb1Lj#&&``fQ61B5 zzOTH%)t@)X@ykqhLB+HY1rXD+4{Y4c$o9m#BM+a?X2Ep{Qc}rU#vwn((D+vxo+G_} zk{TR~N(E8>2o7WJ(3#wP^F*LgidiVUEP=uu{Y|m@L*fkni!1YS)Z3kk*6WOMpkoL# z|19@lQ&1I6X*pu~YT zAHkPu4wMC0e%2Ua=>z;aXkIZr@9r|9Shs?w7?bJC_j}>*ul+6V6`X?stJb6)d{=Q6 zzE|E@;acKiG=gEhon5wnN3kP=I97g}3VQhfI?{P!ymVF4pxO%hBjqTsbm_=6Evbkh z8R*fH^%9vIvTq>_Ygm$LF!zJ7<`?hhlvCAb(gVx zh4|)Z=y92YsNb48uUa$3#U?V@&!au`l{9iicNoU^GSHdd_?qf>Fk}n*TOg$3?>k9K7P3l(>Jie zR+9t)tHA$k;lPalTMzAuGe>xST(Brdd+d7H(sJcnfog zQvJ7q#S%2Wz--o7hY23C7M~NY?CdP$Lq4SEu(?$8A^Ux+N53g=2>=Z>g3u4DO69#1 zEL21EX$VRv$WW$E7UkE=1Ht>0_C7gp*8OU5ugXhRKMNfbiBP-~_Q=A?6A*%#Xq3r&6@?0+RvB2qgP4CVG+2 zg5r|Q5h&NuSWgp&_3H5}%t3vjFJ0u2vn>xoU6Bjv$Yr9UZ$3|H^ndc_*QgBG~o7cx~HlNd7JgP+@P3SH(vxeE1o4S-|DF;8x(yH@18 z^9VgI*n5!UvBfsK!T>U_Lu^incO&*?4JVBdHJ04&SKn%O2**RDhCYmb@ z7$+i=k?!JnwO)xYcw7KULgi&Repg|wKgTGFQeM202H4yPvS?`M2au+XnW(@KjV&f# z$b*HVhbwOjn&?X1q5-v$Vkt$B)3@#=TJCy}Zm}F+Tvq8<97E=_C}pO!|1A>pjC%7g z3O*9G8x<+|M?F|!dv|W$D!E`faQH;uW@gx582Y$Gp99I*u_i`@39&-_3)C?FV_l^o zHp(PaPvh!>A)ssJsWTbLut!>$7kv->3q#ru;thlrXUSw4&gq17xjsOnxUt=Zmwkk? z>Tl-TO%-{MNow}NIr%ygreQQx34R#54JwP&7aa2#kq59VTvt|^{#EcuZ~7d)6S}i` z1Sp@c5?fYduOo)Q#b(ifz2b1pDM26ykocIec-M`KAOyD|O6<F=t=e{cz{QA!g^;dlAF1Nq3tlpr<((q@;q)V1(cmjtWIfqRxi zVZ4b0=ZuZnWjFNiqo941JrRi!{M=cY9UN4T-f}=8Y=1 z=G3gjz-wozLjIuFpT$TsMpKsIJtS-YB|0bosQ`T{RfE8~Mz9Z_hN8zSVU=n!)QNfx zKt~X63Efal8O00cq<(aZWhlDElH($iP9_$WpbO{Tk{(y2Y6Z|dit}^>lR`NBH?8P! z5%}}cwSqFRyst69hA3ibn{fX_EwK&V8P>NG40_Pen^4Q;Jr&bd$_iGn-%YpgER=jc z+kCdM;!2gb+Z8!W7w`106~T|M%2I@7X$FiB_4Bk?Vd)K{A!))S)U+t=@#o4_<+x@IDr2fw{+&=t z#;-hxT)ok8DEQ<2#2+h&Hmy9z!=*J<*Y6FyX$MrXVf7POP3+*h?F~Pu5miU~_!ko5 zH$2*n!;||NSRkdP;-aA~G=XV|IyG$XWgUx4+#7m8M@6Jv;;z}zlP-gOS8{DoD&CIQ zPr=q)8i_xO_(jss{3(Tj3=9PaDuI+0@~ z!e2MP7}FJGAYfT3uui%TvJm8dx=a;akO9H;g+9T#k|8H|U-T*Ci5h-xruRlo0s?Q} zxZ0D@HR{P$26M=m1u&r+5PKl?Hq~6fiVxJ^7=#6N4^S!Z3Pl%9Qc-GX9M8qXN*5u{ zSn!M^p-FZ9wdV`*2ngkB?T}AD5tB_NKU;Xm%&uOa42?7^B~7)o9QNI`Dfuzk?WLpp z+Sef{1T{I~JHw561;>$#k#uN)UA&IdL58ndk9Yl8cvk|zs^t+Bo6ku-?a&W16R{j1 zjEiSk8jU$}G!_4Xyta;dHfjf8MAoeF?&tAa*ZSwA<_rYo#=2Z_<^0M-i;xu+T6F9~8KR?U}vVp?vw^upu&Cs<+jnO4f%Z=bpbVL;Qt-;;3cm^8dTi z5jnJtn4BHJlDu_YHC1w!h*zi0Q$D4TU*?muW4awPX z0kfZ~3AM`_1?{+YArmuLdR_c^x8LnnYh-mBtyL5&61E3^U>y1IBJq?&#UfE*?I0mf)(O#u&&t9=tY=AFb|gjNV5F3a5X%9m)2 z;E?gh@fNh{sT*&HumsL`7lxlfsIX>}cVE11Y^9LqDR{H5atVpiFoWe{^7sXShBhy9 z6T)zYIna!4117}L01+U+79f3JP7o7(R&d`p#~^KrMy#I#teZfN@`=nTk#*mLzKKxd#Vg5BR3 zqI<3z+c@SumTJkjL#DLF-Im;6jnW=^{{+Fxo`Xj2ct?y zMZE*QYM*o;(FSXso`2+#<}eC;X%Q!g8sll9BNBjU8D2&}R*#Xb;aw&cJUkYpycT&BpIE8bRgxkBrebel@T&zlR%B#-7 z)xYTn{8aTe$KD<0OVg8w^X_MEle}5OvaC^DO~hewWo{Ct7El+{@e1Km)8s9+uEv+Z zN#*Q`>WPLOaULt1=lVSu`PLSXQ6+z3k^&m+JPojjgspDq!s-#&He*>}rSJc+o8vo( zO#u}8Qf_(@3F!$UqWbuxvUzf1daI^-oJ2+h6RJ?%L{$*1>q1(0Do<0-ce&t>DSMt|`l zdZGvXRp^*dIoS^obN=zykd=hNS7h0Pz86aj^q$1+|7P@ZuDQ#XRJI5JJ^x(;;Vg&| z{LI|cK4RDmu2&+B-G0owP`%UkNbPBgTAyOh{U?2>FLXR7HmHDC^hUb z19%6^2@q~h53j`B1Q>lDbI|K8FH*?uH%3$?kgE?{xuf&TwRin1YO*K{kA?5v%E)o9 z^ap0ILuG8ku46fU+jJFwLercat7r2FCiGz%T_SHP#bAz`a9b6C`IBB`1MoWW(9i;WWh~e zus=71g8>Qk5*F~DVn)yN_jly=f+U4Kj5u0y{cE=56gn;4(-G<8Ch#sIrwNh{G`y6N zEP4ni#7!WVu|EOE=dnE!=Jyr~t!M9^Mhlo`^&S$qaZ zm8TEziT^Ru&-A6KZRUomJxY3=49 zX&|}bAcljI_uWUu@vQ5M-WA-YS@XbG#$cP+9%WB8&K3_K9P*}|?hD8$cC~SO!r-G- z!Y0QPM?S|ySKZqZSFEDj9P-R;^RSiuGp&2AR4JQHW!oHJaV$%b3fmTa40w+{ARC7K z9Z7mQy)$RH=5V-4)=I+V3DE|(d~n}!#mXtPWnnU12*)1Q#BhFryg8P;Lt+>lS%agA zlhaw5K(&&vS;=-=xY!uDTkn9Ct02DjY2GkyOkOvclx`MYDdoZCg%qhgOm%lLAS~OY zk1XX=TRP`x5~WSDy|0O-%fa7gL-lov$ac)U8AIQYg2aw zf#@NDhYDTWO>oE8fEJjdp&0q32&4OeOERJKa46W8xmDq(afv%q}|6pV^#+9hIf-oNKh9hgBBOH>soKeHzy3bJgqmjuMzB!T&);Xq}_^iRC4kmY#mkrc4gU8m@Y;?1n zl7Oi;CELd(yv0dFMhseuYQGr1g8@sG#-ZqkgIyw28>2vrLuaWsy!DksxcvcBRHXW= z*-c2NndBMTy5|Tcw>39$GNikFB#5r-8SFS2XirPLybw7sm^wEuOxY=JXZjRAb~4mX zuP;+5bJhS8PmcG=9IVS(j*=D|bkFeu>l=Mwp~$QV+5hR`%D)&>Km; zCnsT^--pSiOp@`GU^^D};@*5Ul!kpw-mt{M_TCf)rZv-^OaW_dD%}?kFN3&(lR|(v z$P?D`$SkSbe-=ZT)Z!voJQoa>aNccVRUaJhoneVyJ4F-6k-};>o&kaomOeQvn*WB~ z`i0Ji4J((q@mX&)@DR`WJLE<~iRI7BvlH{30_el9!Uhhp2pCC0mV9xNUG0!AjLl0NTplJ~y5APy0< zAYl**TX)B=)3<0r;#35|RNZ~nPG{mi0n+2>qu!2PdaYqF0#yk+5{hH77xCU*i$;yg zyUO_dK@^^#y4`qSM?nEiDJz=0IqJa5McVyw+0qQcD~$4ELE=l7uPzPB2WCm$sPMa9 znB}0OhMSUGN=OLc#T@_LOZT%U*#@wVJP2Awv*xL=A8}Igh!bvmlbylSA6WTPic_Cb ze^dRECb6R%e%nIt@B4j}GW(Q5bq~+faPG>bhz$1u%3W=G%q}|bn~f(&ZH!mTHwp{i zNR6&f;SX0;D{x35*fqtFt6gIoXw_iSP8_#@A}8vIHUe4E+rSzFL0tw{Snnb{w!^i| z`3GiDVZ4ZWq&qV`XM%QPc2^7#y|O?h`j{%!W6BdGytv9rCL|@e>uNChIS3{6b?^*W zD7$s}HUeu&2KuS z9h@tbPO6BKq1vWKmj1O`TdTG4Lp`6bQ3w|*(PhI0MK@~hw|^UTu6^?!|4(mg8i9Jf ze2*}w!mW`bNs&C+x%_#K*p4D*Sn4&fr|M--{M7MKq1kI${Dw<`#5{fS`2TvbI!fM+ zuT2_4_atGOMf~I1VV3v1LbKPKr1<6T5yHS-)&KY?6Y`A9sHz#%%6;E5fI}Z>E$zAM z`9~YZ$I>oBK`6z&1GyLmNgU$a(6p=MWz`uy$$Yzz+NM75dNdxVltIjh;7I8BGBLfm z5zW0KmkAiRiG2S?V6bf2FiqKQ&`A{VNG12TVx&z|(V`LVvZbLp)o zc3`!+cSIY8NB&l8=1+|E#DkfPP@U`DU9}Sx8BzT>9&4^)#)4m3j7G-;s-z!)8l5@n zXQNq2F{CsGW7hcqIpYh4#*SUDP~0D^N&4#;CCYnxcy?9 z5AAKnrJS=O=XhPn)mlmOB%@SImi)Z7E0t=EQdX~2Q3u{lL3wv>oMHBQKPU(rEdMdJSwnGzZz1PWZ4p*2<8IciJ(2n2lV=@P><^K$*8yK9K=>_nXJb= z#QF!mJ2QyogxWQ?&L(i30l>%aemyN?kL-A~e@$cJR6Y*zv6e=c>q8A^P8m@BeQ7`| zt=Wjbt%`A#`$o|CQi8H@0%o!Y5^o!NVqYRZ4hpXhSa@)<*t)XQRnjwBSl zOk|#MDNv96$VuY-{Wb{eVuW1Q<0xC#JHT!);Fkba^mHO6tAw zEehfHlF?+Hn#A#=wQ-WEaQpjP7mR@eq4PN#u|W5IrbO35ucz(x=7quUX{N&3-DAcg8HeY#wf6e zGH$Zime{PjY_{n{(yo|_myNu1#=-Z;a1$|w{4U#{#$(lwS}bS2Ne%qEfls9$x52-7 zh}0LWDEO9jLojh{)aBV$V#i|ZFJ8k`hIYTUUa%T59FngM*pr zN_0+r#Ib-*8^O^YBOE+eljFwlW=iMQ%KA4}Azp|V!92-eD3MkTm>@WLT0=~h6#F(C z3Hyf*?M|NJP*^iT`2Q6(m%S(=f|U?%PyJ68lbJHpQ-*)^D3zKP3_9V-Bkp*1D28i5VR zNlV5$1fzm0gJYyTw1ZAEuQYmlv(}f@JlQTU4HtFftf6_v6GSjF+=+ZR>B&O8kSETk4W&34_#h>9@g->ID&!Y&su~oGuQz>-x zqWCu5gK$yXFdvLkC`V|8{*8aJ(pocU3$4!THmSBcWrggH0Q?#P{P0@qY}GIZjTw@R zp_sSn5#^t#oJHU&x>nvL(l>UAT=vP)4!+;9M3XnbySI@-T?1v_@YRu++%|8ww?%sP@x3a&Rs_C9**ISJC zL+s(F*`TFlf{|HP=p8n;+!#0Uil2fnMQ!)FIvFezNdrY6@R5_n9bK=`9k{|3J5SiH z5V2l~VAxZzo$TmAMSDL6h+_AOup6zb!yVj_q$6wV*TWP5_4FKDB9OkH+AW0UZ(1lD zLn5%NZ`#^xRFB)g>`k`-{tIyH=431YNh}7ZZ?b8mT$@e_TlTEO#b`r3P`Xjseu!px zS5#EP%>(6IuxIshqJr69C2+4(7+9LMRujn(|%9*a;nI5hZgW*A0&PYFv4iP{!vjrgcy8x{tT@ zo8HntLDj#`=xz@~Cy><$ejK5;*bRO1!5$g30??+5mUOlOHtj8ex9DK^gfIv_U1f>1 zdu9F+WBcw*2?1B>^T|{I53a}_I4D5A?}TgZX#}a9Azq)F>WbtR+JI0g-5>H3)^o+{ zZDhjkTGen1WdUqJt4=?CH(*D8FbIGKxi0=YIfnH|J$URBwWlj8{>uq$sFL1|yyLK4 zY##ksLfo$~>ndi8D?3CVij09y4jlH8A24cR)m5RDO2f-d?K zJ^9JBg3?I$M>;;^w1|sDs)~Aj8?I@E_)pm>ENXxJSE|CEM9^u-R6}zqg8eY&`d%G+ z4|DOLZfGF@*&)M{Few`jeoCcX;ax%hqZt6`22N=q zCj>orz(5b&Ta0BuJn#(pFy0k0GFJp1Jd&^t-B6v= zdus5V8tJQgA3S{{ch+LVS|kQ};AYUyDgC^XJGBS5>X6djBixR$;?tL-#f;$?UVYVY zT^ozD*r||5qtpY9$J(CuS0-Ia2?-|NC)}VXMx!K&d_$jJL!yGSyX|U3?#^mxeF6f0 zsj_e_+49YP?ST#kql*YVCuZ0Jr>;1#${VrTjGIP}=_aiDS0@Nx2b;ZFHy>$_87iSO zNl$U>Cr;#zkRPVlkRuqvCLP>2gK{$VLS}d$VGCw9zCV;BaGOBF{nlIHKG!j?#FSJf zNxWF?rPD#_^DF!+6;6`98@(tuF}hy>&saLYgckqCZ+byh-r+2%eR-Z|5ORpC<$*(P zbY|YQ2&?+0r0g3rf@>){tYxl=5r|wJGas_M&@@b!J`|$HWx^)abT8)sw45<#Q_uqN z;NqwF@h;R>%+=QAOg@Wf`dClj@B`2llAQD}6U198f`ZFR6^^q^T$>J z1%quv`~WN|a{(|tL<1-6*^M@m9!7K(>89Fy@SO`m< zCS3Q63$~kZj2^u(`V@s-LeCEAoO)@w!4$(6Nfe>VdCe%CD3#}4+Tf}K4=y^r+EM$) zja+~OvbF>ZERu} zgCJ$8zVLxQ*iYulo37OXe!!JeK6Aec%DS)gRfKEakM)smF|;mAw3mSZ_z+ zBONnPkiDlK=x9!!2q5*UZ=QsCXgWK<-1t-@@{eLGq$1yULI zjEpy+HbSPMZx!tG`g#Pc0FCJoxsTjWH9_UfNGIBpcb)WG2YgL8^TkB3%8Y2)r00$1 z^M%4q7teE;U~eb-k@#Knjk{g~Et59pdiI$!QB(j+B43<-gXYC);wL)J^!u;|+0oMi zN>n!V17--YjS)(Q9WyTOifj@vHR8PsrIcE>eOqgEtH^oZQHuQ$Cn#B@8t{4oR;DDl zi+A7>J7@4H>E>=q=jfAg5c#T*4a3{OD6V05fJrzPYYg{gm5!lfN;rzKFkwkw94WG3 z-#7Tm8k;ZZ(?tIjXf4?*(`)Pd0Y<9cD)DV*PO@UynQi?J2WKqh9piic7+omAnBNfF zZDZ!%+7$~<1Gh)sOqoZ>D{wh^z$GYtde65nQPavIEUl#uIx5jt+a}V1P`Y`D^j|4! z9+l4Qbz)g^x9be9TL0Ux<#i*arg3BG#fO6DML_<7}J+PVk?$9 zX`9BBpD*$&{f*k-*W=JHj7P-@yv;*}S9qOVe7S}(6z)OHTdT!4m75nd9T+gv){$w$ z69DbZQmCr(DkoZz+nk7`d;G^^ZEg$%xcvvl%`Kch7~~w8`JL$ybFNY-dWZ-D{^m(V zLv=4&2;+$lw{7c0gn~9;-9%ITuwE~JpefiT9I(G?0#f|3$jvaAcO& zKjiJoH;8BOgkQZDQ3fr@**^$@e#V|$V=@`X2}e#8!)I;rARU9yXDv*D&+j+gYVIx` zFwsIPXVqsJNDRSDngnn+RPnDx=nO+7*k0~}QyJRd@Z_MW2ZD+a>1%=T$uxn7`znez zx2u1G>PP-_?f4i$%roZrViV=J*g2KC`}QW}@g6@N;30059ITu0M_$>f6?)-qcYd7d zI-}1BgmJ7rW`&djv1ayX?M<(zBsBP!O_B@<0l1pc7!6_PCi@L&inkIQPaVEVgt&Lh zKn>rxeR2s|9P$p|8foPF_fqLlFq>Fu(%U1P>LetHPP0o&dI(e}!!pN27tePWCJZF| zVBtGP2D@2JC-c!dv(l`@bN9#EUCgQby#^P9MAz*$R)_x2&T6z_acH6x7%FIz*R18# zL#b9zmHy!_s&i!@%qo?O_kf2pXQ==*@-U$qA*cr|4T#UZ+AbL&AAInpaOZug& zN;B2C`O!YQTV`EYmocLe7>Usp7LUeRn3*zd_NvxROABU zNa49DJnl~_pLT&C;^@xQ9vU;Xlx>l>oc*`1kfK;YMe_BGmT6|rv-9o%17OYLs%Y)= zVY2GsU$~`6G<=Q?l7{UMol-=uv0}}kYc(SF_i)?{LTd=?^Y8LN5w%m^T17dhg(^0k zSRn=ZgiUeXeBrSLcBb&yO(azU@55c)SpNH{NF_l882{*58RpojPx4ZQ0ef@{`Wu5x zCQJyz^J3RR)+6bV`-cMIA|{~Y!(+QHiEH!Bvw2d`H(mf1{GUja5VK9aUdldfsHgOM*tRxR-ti=- zb=2ejiHXw5mM8sD51nVm%)0N(2&qU*6{GQr4q+C1rv}^KqQeG%errN|Q>7Y8|G~Hr z%o!oT>S%*pBgKkGQNk`T3)F!v!KgQSwEOgkXMe*)1e2+9HCdCw^`*Ip6{rY0nl zH%SpXX-X~^CRofSjD&R%Z9PFwa6~Cpd~GPV7o{s_F7<0MhklV4GUO}HaU2uC}M z_{(@`8F;ECr?z15tDX|cbn@WpC$6ly;G*4SYm}R7=2MEVnfKd-a}eCh-Jt07CZQ3QG8Ms(h{H} zRKxSKn#a7n#}*d?x1g#w{v^y=I>Dvx?fL^LM=wAbv54njXskm^A*j)%ImjfOVFH;4OAdLyxI`tw#oLQ7CKeJmBbjL!9 zEhO(VmsKU`e*s%$?$?B?4y9?eehKGr>p@->K8Q`@yLlMYSs$!X;sax8iz`s`fhqG? zfhW^;>EU%r3-*orxmwX6^wgkY}-00TdVgJ80*%z>Fax&9r~xut=>hWU8og zipxASwYCWEWc|`WNCt-|JrYKTGjFKg&ut;Uan}xD6Oem^L!M!Ws4}rUpMdbHznAnp zU`6Mh+Oa|9jJrvXx2?kbI%xw(lxP+M3>SJG62QDKb+rk|Y$fP+FgoOtyLhl3WH)f7 zV4--ciW;w0JKMQ0xN;9*?X}+20^ZuMzDE0I@||;33(7PEfJ)@(^Ys%ENm-OSt>k|l z$9ZXYwFZg6tWC^KdYGG$&dhd|3W&q4xKZ2}>*;v{2cv=aoQqnv#nJ_uL`$fzY`g`R zf8!=HXyFnI_-uZSin$)G#6J>k7Fm2;m+xXi`{QwfEkvPM+I+teTmZZc9(-8lESJIx z`%#dX-SzIXJdxWZ01@=?>i2_5jZfBtt!|y+sb?6H?QLXs0<2G(j28S5sdsGALd~06 zXYNW@{=YPZtg5C6l<)3JG;$NKzGQPAzB(M2+xxy@aW*M85 zK&;JKUPw1t2NhKe&sZ4pF>T#s`Wl(jj)uYjNAQG^Ee>q`vw(UZtYxCOG$qSX;~S2z zJSj|VO2CF^G{oiHdRAP2#DC0cJ)c3?RT%LsKCfPIvUe=0^4d0y+R9S$UV<(PTKVXD zDU>(p1x;ASwPI{+A*n<3Jl4c7h=cycj2Z4xT1PA5|hG9Z-kp3*7y>}DL1wSH}ca(FJM%<=O!U8p7|sc)571EACLfiFR>1q zi(_WJ9!QuY&!zsv1ka*K83vz?z*7{eLTcgX8i{d5eMrSbTFD%WI0Nw^)_j_(hUZvf zY&L=C=DqhL16_NBItG8IYB%9U;v`eT1%$v4g~R!VjU?#QXeHxt!JgYIaVyIj@DdS` zs(b`g=c|KYeUUJduh@4M5f$5AFoeMBG`@)eo6kR6+A$Z(`yfL5N)IkPdHiuq=VP^y zj)U4v9i{`E^NYxnHn&+9iP#A)lzvx>6Cq*+i|tT9NkSQjGf;sM;Xg}f zX}SYwoitc%J)*D&==?5QrakD)-Rv}-&L2oEBNAXjZJdxcVrj|!5*9_fsPmvpZwrnp z`UFf_r@^Cn{qhTfN#ga^2@hkUh@ArVXW{v8YlA3hbRZ{CFwQ|9$nG~!y#ffLujU`0 z^BcHq3J=)gnrVl4r?lBKAj7Htle#e9J{6E9e5E9dHOa8R^JSXP&Y!!xsDR87SqJl7 zSH7gqQTD!kDk`CA`C!shF0SP`hw!g*rXj#Ys~1&kSjvyt&B_p7nTcMzBjqK+ni9Zc z$y|qaj5f<&<$aT}gX`ZIG&N<+g%GgO^FkE#w^K%&iZ;GMiR_930}7{hLMy6BvdJDC zK2(v=RtlPhymj$MGz`Um7@7bMkXjX%t%`tPAG+XyP_fs0)E5oa#^96bQ6ykvvpt54 zpO1(gB7iy?L!=ws4Ral(QA2qq2%AlA6HTkHDdt0kHcShQ&xMwTyfc(d{T0*~-pzc~ zaKw(2R?4ND9WzU5Ybb;E31eQC2nJjTUFi+)|Bxeiy$Na>#x0Ik3Ry5kKE!oHUQP32 zu|=_W1<{m5_|spYmGfw{Dp4U}m8exTVkT^VmBew^G}$zd&~u>37%Yb=)V=!C9@kin z^hfd(BUKcp=?*OhoZ-Xe6FUl3!Qm2pE>iCT4~cM-ieNjEc_r#s^+|&r!5`%;h{#ZF zXU)`FrR@^52L{i^*bPd|d!$6d*{1EfdtW}2ZzrpF)^_Uc`P%0bvcRGB$pW1h*iAyu z7KgfAL&0=XaO1pOY4T?GW_dZkr#&SzT?#MHqPw)Snv-0T1?hUj;yq%LYk3_~C_8WS zgv}?#^5eqO3>pKQjLgYYjTzrRJb)kXOIq^7h>Wv&_qUw#y8c}r=*a~v?3#}$ygs9e zO~YvH`NOg79thonA<*T~I-W&``$KOT`bcFtGr8QqBAB$cZwo!z>gAi$u9kF z4@4|JKltM!`$7<0?W_*Me6x8%bvmEn5g=%wELgMi+i0glG@JC1y8_BG=0d{oUFTLz zuAatihPaLy7FCAVspXCZ#{@4G^7LZotn?+g>O|rBE@C5g5q_wiyBRRXh3!oCk-_ix z0O<2`UIVQ&&6X5crxrU(gmf>&a8&#wt#HTpt;&g!NZ^p{^bmiL{%Vjo0%QQS>4l*P$$k9& z%i#^9qCuX*H47fa6X>GXc&%EaMKrnowD7t|W%U>$51Z$cla!K1nU|IE^Y~ezDE(~d z9>6dw3dWz!tPxj7Lj<%lS{P9$TGa*_v~-O0c+ms-%ERv|0_aYeZfmZvuM%3!5=w;M{BZ=e@&&VDk;d7&OH;*~ z`k9VWVKqf-E;p8y@K#Sefb@eN7mZJop!&vrLb2q{G!v0tN#h!Ion8T!`l?0dz1Es^QO8a-egwhN@*h~L`4RoF8N3Su_ngaPrnV_~P)SYx*9_ZUauT#fx|-6yJ@E^)6m>buoGs`sU1zs;Vcu z&J@gASgu{>b>1L(-6@KDQf+a)_W0Q%op%bPAyLT7RRBLC077r%HsY>1n+HPo!%#!n zPbdl}fwL)BPtm?V{8BX<2~@&RGYl51E*mu4I6$L*gsD#eV9QV;TW2w2g?5DsgD#Y5@+vCLU)Se zFO7iQi+#O2*Q)Q+9oX7fTN9S!w$W36>b$v)0e&chg%G^S{HZDeCzN*j(UK9v@9WCa zpW}kH(N46N5**ey#xZo<#93pj=&&eHXvF@`FbB_ySu;F3y05K(o9G)dQ&OP(=Y73O zlbdz`o>w1nqP;)S-3uAD@BnOLXddrTf4KY#9?1rNSF$q_fo7MLrR&H(joKeZ*+%6j zIeY}ihm!}u)}?BP+kZ@x$bQ=~gvk|tkkF&GilP8PK)%1%S?Iy57P>m0GRQs9@+ZU< zK1Vc!qLZzmtO16>yd#8GGYjy~g@s9`NrhR+74!G#2t~*978{Z zziQ7wpI1i5OZG#H2QU0BhwSI9U5C$i!xhq+nT@@sU*4l(XB-Q}@MPG`x+6peIoAE+QkC5SsZ4pA4E^F@+=R?L&?FxUmg!hKwlc4lQK} zJ^AtXH4m91` zzRX97hpN>{qOg_`W%o zJw`Ef2xv$~gOKnk! z5w~t{q^sNOx@M`&ZV5mMw*{A*)G;<35tjZ*nZ%*`iTIXh>-Yf-}+xt^rxnN_aH z&XmnGjs5^)CA-uBO|t3lAkzMIc>)qr67l=!Uo}0~hKk#YPzuyK(3k|Scv15)@nk9d zlr?y4RvZ1GpQQ1S>wC%VfZOh6BhzG6aD`kQ69%ATdn6T=RX1LVg@T3CyH*f`$n#M4 zjjKh=uvw@3LZ#qPNw6tjL$pHk?pLnxx2glL@f^o^g$(vAcR~5 zGLy+%1mVqRJ>^{2*C<|s(RkMFJiFff13wi+trTL+pXc#xNDGPb8BWmJ5x|a8UFp8e z@>83Sr3=6`n=rihU^ox3%9m@4yLmKup9VjIfr_Z_!vTn@66b>Pq7jTCI=F$oV43eT z_@KQ3OkPKVN=vq{#@Eh2oOjZ`a})sPX1v^3dzm>t`nwZWH=&nUpLi3osD?Dr7%_jm zRcqHi*xY7pNgn)d!bbH16^WRm4P+f3f>(wuCEgI-@7Ew-#(b}p zOr`63v(7VO51MF=)xUS!1Kaf9>k&Pdn`j$wWckXnI*EgVlX+US$qck-il1qWT-h5Y zJdj{L_p2-_^cF7K8qKeL2Ia#P2#x<1O@(5Yu0}KnkIr1?8~H1GuzVv|$NHfdyzyg{ z_=V792fK69P7?4l)Uw9jcDuY~@KW(#(gnB*Bo!eLhx@?+s&?!y15KO(MNr{PL^!1E z$`dbPB)BxLp|Ya)hoDoSEM$t1Rep$}MTY7ILm-n6e)AjJ4O{!>t-}hopvrBdXXDbBfKYP44omMQYKryZMud?Axbxeu{OP#c^a$&c?-Pd zg>@px!*Srq^#J6mZw_p4z6|BTnQT&S;dvFyK80gb3R`izL^H_HG&T&npy>PhCE0K1d=3-0 zN6{Xo#5=BC`{wAtf^wh?c>8Z<8Q3|d^B$Kl%pqSO-oC=g~iL*)y}@w#XFZrd6K{SWM6|Hnqh1eUa8v&nmWh)*6N%}RU?c(+XzIs{iJr^gG~MhslxvQv z+g={5+Qmn%QN(J+;r2`Cp)IT1UX%kgSr!)Sz`_y)bod|Z-J|$`_;3Q$pYR9t3Q`vj z0EpiggfZ%3%+>5-VCdlrJKXpr7D@fq4!ok$^f3Oi1WP$rhL zuX>ETr9|cs98-7MFyd=3xyrkFZlBP+yxr@7G4}(`AdRdR-pY#|R~6^-ArMKB_yk?! zyCGHZY4CgF-8>4J;IT!A@`7lzdSO$Y>N=d(=`$}JD9P)KBx(bEu5gTf^0LM`hJa|A4!7B` zWfng2fU6?I8LizHFf%#JrIXJa9>E>0O;6etrwY9Yz!QP2myI21S}ES3+fssU-}+tC zRGTc=&Xv4Y4$0!_RphQ?^cU_^Z4{IrXCEaosw*83kwo4=Vd*{&xFxo+72Cy ztb~1+syJPExRP$C>H3DCOpH?;)7aHD9ag&Ho5-&}l+=q6#cTCTtXnhGU>HWqF83Dg^>4>a4(JsLQ{aziL2jly#ntTz)YTJsz zQbS6$sV~ynM+3(@9$Nf>mUjoQMqY~y6J3!LFn1NhKJn>T79oX`KzTmW-8aCtKoKFq z0`{$HO{A^MDDmM_c%vRu{HSb?lSE+>xOdL86g@n5mf_7yjUlcc*^YmJi`c9YVu>Ng z;yjP+FaZ*}{4ve#P+nghTs5!_vOrLUGBhB{GR|k-v(e$Hm&y7WadtkdVJImKB-z< z!hEi*G{W|GaM_Bk&96l3ZHX!Jf4uOhnFxDRq*YMK#SCjHPN9x{pd{E}7NOL-F6&0V zStzvI>^&!z?t61cPR=me={xxk&t8o8g+H+&x#!v47lfLO`WTbGtcy@W7_kFk3iQ>l z`LH_Qk(<4nPMlSaMDRJ+x7*kXTi@{e4ye@mN0^L6<`4bG_|WAyuw5fdXlH405?CY@ zg%7^tK<*qdI$HbL)0R=zH2y{C>WW`V0;yP)gZAp7sk(z!Bo3Lb`G+m!CX!hxS=EuJ z`~jq zJN6Rl&N(qhSiM^0>Z&K!k_w>?TPVrS29KR3b?h3Ta*haBfA^d~K6O7K`Vd%}uuGOyhQqsoZ zgrRoE%|`rb`}K#pFW8H>o8Q&D^tl-5Z?FPo)m9pVRZmx+KA9o|qga!89?cfRUp6GuWteG&~6Vo#0M@h`Dp4kbs&a6ad*NDM_0V@2F|Jz)%h@LPymBW)h94eo|% zJZZaj&ZkVkqddUfh7p4)I-eO0qgTq6)@a$ee0}4nZ290+>j>MwOlV#A3{%r@l-sZ@LwqpDDJl=~ z*#!KwY{ey@pyG7&{-itR+ev$k`qsLBImMj!cz0Gos7|R4>kMkB0NiFioy8gXI>(3i znR;ton@ye24Ducd!RVHetg=x!G7f!T5!)^m2!M@VT*@1RnzVT!7Q+id{M@2J+n6_M z^mbQTKCLPTEM*WGfzJ?NaMsAW@fkpPc-f5drzTN$iZt3+VakxfbOO!D%uhjYn@Z-i z-m{pisX`F4pzpsAxhb7;C%yhl@|+5L z2#JYKBHTj9zmeV@xE9`&f(fJT-8gyQ6{Nlx#W7rOdL$h*fwXUGS%T`QX zW>dH>(o<9W;W|(-DsU?z7EU<7x7Z`W;yP;dw_Gdd zT+yvsD}aleZ>hk(pf)}Gb_Lc@e-0its)~*yGP)lFbQe`{da2AHurA-JEf27ePZ~pzm}MVvfF^{^1<6<~hm?b)+Umoe>gZC0*Q#p&PztYiy6w z^H_;NR~-nC8o7{wFX&EazLQpH^w4o|^Ql>5g3CMYw#LBi?DW_RZ$=rg0NW7vlQG8o zQ7jHC+NkNO_7R_`$W&yugr4$)|uH29cRq65B&QcdIF(T9G9G!ldF?vy&vdl1fDCxxoa6qzg(!t zPFUeW z3)JQg-vgZG-rb2-2R6*707^wex>;-;plpQ2JoStO7KzCJ$u83FsI(mg*Q)&M1r56e z;EMbEmcK*Fet6gpLsq6I5+(hg?eY;MNa8cFDEOoiga8{*z*-tCFv{)mBDnu4OjO^| z8tR~!^-n6*+*c*h#%6-yA*%9qQ@RT^8^_jBaXGgfO7`o-{r5^Xu=8iauWs?p;8Wok zTNNU{2ov=8U$))K`n8|KNifAZ3QD@sSV83uO>`W*no^Im{v+Wu#xM$J3oVey?Y{%1FUh z!Eb`+k9G+*c>*XTV@06$o)q#iJQ;8f^}OZJ_ep}@TVRkzjPFd7Rx;J8&|GeJzf&;W zh&Aj&2?^drA!6-MG0-cUi8xMN*m^sB9@@ng6seLmYR6!ri&v%={w?LA{)>!n-s7Wi zQ?EMriN)y)-K9*=w3VJ@{FS@B=s`^kWUc8H^{!}_JB?BZM<>L%{b$N}UvC7`J%ZyU(PHBC>m&3)LpZA6q zkkVMKkwBYZJAsKnG>xiMfaf#Mu;yGp?$+g~sZx3^Cq(E~m5b%1qooG6@F>^^o+w|g z(})jC6sHvtHYVkTkn^kyI)ZkU6x!>~`2`pqtV2_uWO@UeA<+N%De67@2$aD| z3r|R^8A57iZ?~vwb_KB5Qos}k8>f`0oDXhD_GqP%(69Mj#Z|br+^yI~hDr5_HeCA9 zmTYhKyR?$GjYrkmyldvFiG5}FMfqWzQ)sIL0z^Ndm+z{kpGREikKJs*!XMe=xIDG_ zr8_*@G>sKUMQ&V7Y<`w)h(DBxgg6Qe8GcQ&U+F}J(KW1(n;Ht31=y&^>!Ma3q#z<_ zMj)T|&a_&+50t}l((>oEiaUy+Aff0CE&tCb`b5CQ4o^BFL9aJ;pgkFe!Jub=bz{Pp zhXGf47DnhOr`?`JQe0S&5qm4c2VYglL1URo9=_M|qi@|aoR0TluEDh%ef;y$ z2fKfg$0)S3P8k0S+$xa~y`t}!xpERuYbpHDXe}Pmm-Io*;@24EzfMep?RSNvm(y`z zdL%)o&sP;#j#FKHvtq01{VTUO9nDvZoo9Wdlbh$lioFZ?u9th6-{o+Xa(YW zBaA(BZmo`PEv;VV8`yR z{x5d#LDVv*glo{xpu!dZ*2q*pS}2?;MF}4JLn|05J5pCv6+Q+{ENz4Xn+(m+@hWEE zsh};&k_WOH6t!7A#s9PuWW5T#%d8oxw>$Ae2C1NSx5QNc;YF?eYk0;Y`}f#sX9~ND z7qula!3E}W=7VMeQhJwS`A#1A5=IyLWFflWaTdWV4@F0 zT*Tj3^fo~jYWq)X$%7u~V5hoAXISxjmM*DI zmQe#}FSAY{N{k!X@2gkfi_NJme92ogx97r;-5&MCL?nUO8MXCPYx(_ni0&lO?<`YicR~=3us+?OU3#e3Dm+7FJ!xaM@Cm8Z!&f6 zhxYuC6tuzw&GcUA)V)#|UDGP2d{#qx1Wb}yFx=*ZY232A_&(Zli=skMOVSNRyJB}7 zfQ5B#lB4s-GDDJfPvcr~u*|~o?8Ub_?2Vn6p#7xJy9x&3CE;QtxUBJB38+x5D0IWS zK0$R+o)*$#Y*go3_?Ab2LQ2TqHemE^$Gx&b02Y-JSk(SoqZ~l%OUWL3Ok-I4^lnvO zFiv55&QO>Ys$-fiz$9bHLJ*0nB==nSt*QD(7s}l+5$4s%XhT@T0OtfLIYW44u|P-C zj2LG@XTgY;qp5u3`!DuFF9WDh!VG|9T91ZqfuPX95oj#r?9>j~9hPir{@v?sQ=%cZ zrGor4jtZZf?nLK@^jF`4syz)@TaNz`R+`urWGOV`(ae?q(*C0~Z#j00MlC-oVsYSG zK$-nW7ta$&sacc&?GWYHB)u#EEhV-X<^`ORv+tmWZbBSo;wfQ-1qqj-=9oEqVmWqB z+u)wvt7t(quz#J)`E^H*nSa59gI@=6WR+!C^y~P zcWm*uG#BMPgq7E_N>EB4Dw2*J2{I88Ix!x7mnOx$%^8kT{8!F+5vo{w>{Q$(#(-pZ zxa%r~!}kNblCk54>F!OY=Ykc0Ufy?`^~b)Ol!Dt#8+N4rn=hzUbJ~0Q)l_XVq=4H8 zVUq?dI#J9H2ij$W&?lW?Thr{3-t6C%T{V;Ly&@@AM4o1N)VZisWetuP2&!@wLE$Pm zAy4Qw!rqo|FUVY+X#6JYCurPQREE&t;jeD0O3liyDYcOQ_tixPyKZ&WPL2UIEJK;I zlcI?FVWrAGXiL^n2rhA=V71$#M-UV(yUvwj{lbcd#%8+LOvmp3`mfnirkdw6o#XNV zaevBdG5I_k$cudS-vX)5;&WG3Vc{NoVgmyt^~kpASEfb6JPsQq#-%U53ThoPlY^id z!Qux2&7$-Z3qBztyiN?3bXSF1Uc={+FBjzmrNE-0sL-Yqunxfupp*9vB6jwr3BF9l zCRU5X(y11ePKs$ZThm8x-qWLEQ3x%jeKVIwe6vtvCR1F?ECE{oK!sZo%&)9XSWb)| zfWZ*q0%z^(GZ!D<)uX;(+nY=XE~f$iYmp4wQbi^8=XGBX8)L&g@J(=3vkX8qNjT&n zdcOODwO8kr5#?jSEk71Q9lA3xH-q15QG&9bB1h~}Ts>1>{Vey{nXqu$**QUGC;|28 z_=sw8b3aWF{iIOQz|qj!%=y;J0rsAWNuP(c_$j|vGdqyi^mGymz?t4ETM!-+j5jH|q=cD>9F3`NHqoYeI7 z2E64fkw$a2_!imDALJ#*ZiIk8e;r8ae!Hjh{vzT-U~#WT%=2`_KsXKBD>G=L)Te8L z%}rkEG5r!{5R|vkW&xW|7BV1*klQOvW#rVkNp#zs@zSw}^cRU7i&qZA2cW8DUj4Ox zpk8|J(#iV{?zZ$4l^DI8y{^wP|CajhS4UT$adFgS@SLje*KVlzDZw>YWT9V9{0X3tqQ&rend0t{G zywgfz5y~?l)|AEAQkpLx^Hxu@Jnnlvxtp(rEs5$XV1djSC(E)eGL6DyX(>3E28m4L z>;^6+iKjV-KZ?0jl}F3T&JrrYa&Vst@=@X?!!lB{+BE*xXGY&@SEJnfS%im%>5exNk|b%bZFUJMqEe-I=i}_2=H0uYDrA@n)S&5WCC`Ut zC@DYW;AD4?#O9#D$xk2Lr7P#kI-cfgWbBLsI1J1$O2rw^kS#YsJp<#B^C56H(1H&6KgWar#_Z@~no58IXG^b^DgYGXx~wwk)3m^2yfjp@wVx+w$BS6#|9;RGZw4DR=Qf@^DV~?eyiV<_(^ZC zv)1g4uy8g7^ptGT)abesAg}K`W zr9yZAc9}Uqftk3MH0(g3Ld6L2McAcZ_t{-%#R^=YK3O8iw`)Q0i(^SWFTCc6*Nijo zftT2;MQFotI-A5oP+doit%-b9GQ_C6w$E;0XAZF(>y#7puiWmoZY&C$qc>^Aw;r^? zM+32QYkT)?m!K^^Nm`$e&`(s=;++CN+Lu_dKzBEwzJbb52+x-+moNRTCyaz>uk3j1 z;iy^h!{aUoDc(5-I0ks$IBE(&L-ZQpMRNW73}^3B_E3v=dt%Rqu@sp!z6gye~4 zr8oUxdGg+wM1jZ`YeNLwpdD_X^n4(qXd*r(T3!F6*cTpn98x&icJ?&7=DzFOXU1FO z)q$!aC-)X#F)^(p?rT7ZhDx18Sr4l6W0VZ4$BfnNIHEgvaJ8+`g0;_*4cMFXeq;hRjrxX4RL_I&KvVz`V`3;2q?q{ zdALpz#LTf10HWApmL7ZuF4Kl0B0MBhW0tHwp8C8yWTkZckYY8M5_$n+ym|C`+mB#$1a@`Pj zK$#jgIwe^cnJBr0L%R=dL5G%*QA?^0Ae;}%r&h}5GcS~cegJ}*!ewJr@%V;kEUta1 zpeh^tq(M{vh=&v!8E#4mf+s7d|3!bw>S%L@P~~mOlG4sX`zL%@vV- z(mEptpeE}gm(KA8A5=N+;YvBnv-@mf`BvRo%-vr&h+HM{lK6W`m7DIGunKQ&|A9be}KJj96CIC#%ZQVdA=K-zp4_1sA z``1spN{1zAK%QC|l%3Fap}&RYVm>E(5kQoJ`5lX0bNlCUG>qK}JFqSeA?ux@EPouy ziuDnu8Td%n+VkP6A&r9jte&`kxXGdD;v49o`x`b2!Pvwoe=Ln;@fe9mKmVGkM{T|+ zShX0UDUM!WaibWJQe$VlL22&|E{hkit;qP~5NmX8LFEW%3hT>GS=r*k%bGe=!DXl* zjTZt~m?9E|QMP?hKWMqKj9befLD#Xci&D~P0>Wr{IY%Y6D>2)M^TR&iC8bBE`$Iq+Skm*;1q2bRGEYz)dk$aSwF1etyi`1 z#+y8G(dZF4aTf`Dzy%e>EZw0_Blt}{E)tA)W9Kh|hO(YZJXK;;N1Z74P$kmC7(t?P z(GMLQPdX`>-+${Ua^4ZAajWNf&fHg5D1Id)?;6)L^Y~N1NGE<)N)?eUy0-X`eW74y z)Iib~lo&crN05mQS2cMRL>2$oMqaohPYTaAI^cUXH0R#C7!oG>&b{YT%;deQfM57u zA@xcdu+{fa1|n*2OIl{39^T1nfwrzxjW zKyB4i$Ag3tiT^<&FrwbyB zeU&g73KP+KQS!eaI#PqKGsr;gK^n5cj45$!j_q~00|;9`D7gfy@?C!TfT9l9@i#~F zdv=cAGM0Esmm~Sr;l6zQKzIIM($hWt$DQv^(?BQxqeP@QtSPA0h!$@$Gqf^AfPIA@-tF% z=RKr9C|ciJ&wOsoz2AI5Gs-2rfjV=RUD@80EDxlcq!>^-tlQ(2=Gx-A@%lAobZxOF zSR?l2%+7un^T&t1?Cj&c-2D0x(FCOyz-If@ME`Pg4;;0cl}&1>9v`6rqt!citLM~W z_POk6W4#CiM;g;pY#c-LcmCaKXYCh2Y>|EZS~r$;Ck*q*KpfbB3Q@lvzRJpv#du>@ zOO*kJhd|Quq=mMk`zK3YNiV|G?iv&QUBjKl4q_+G-xe9oRw0E-d*;f`t`ErO>m$R2 zX;vY40j9M`=I{kjMGMWjd0fi1^l4djJtxAtZS12jD+lE2l$^wW*x!)WIMt_O%?xAi z_xDaeFyN->Qk$c}^hquhJAWIo+V-ox<=~|foX~dp?1Ey(Cx_9ofgE;+y}>w{>%Dw8 zPlS=I%*BK=OczAx3w*Tg!^)tX8R&$~lWs0s??Uf81akX|%*1E0k8V=rBxNu|^(HZL z4O~(dC3B&#rG{@-d~O{y={0juDvoE8Cru{J%MbnG-V%kddOnfrM@7@5}9YaxMxRf zX!{9vLUp!V6$Iy#kfuD+gvT$CPbIhAVq3O3?VsOa(%?j5ehVJc!mFHhCtsy|jZ%A? za-sXDiS&z%xz4;X!psv2bzpcXPn}VAu`GFZOK1e^2Vv=T0qpbL$i1)G8Vj8u z*gr_qZL4{boWE5}Nd?PtecVdQY+6G(oI*cR+c5}2-~hw6xQNZSba`7ZOcV_)jP8pL z?4hZ%h~A=3WsLYE-FKbrO4_>YaO1XMAi*u6MqMxx-0tL|j|PO3q~T`|>%Rb#NY)FC zF>dGw?4F)l>UwDhgg#`bZdA^}6R`M;JUaL0wmPGJP3{ht%1;ga@U;#rG`YxGkSfs# z9I9zX#GVOGd?UTYt%vNweG#|9ddwiiDeGQzLM~7sacf&yo1YNHF^w$+@BaIlAVboa zjeJeImjqZ@(R9VO*@D^L-m%_Vw~xPcg+_1zF&^@V0+QRpQ_frm+ei1@!cO+MqvG-! zZ3v2d4^FyxxGVVSp+O~#>#>fsneq5 zFVm#$i5IPv^2FtD^Md?kAO`k<(E4NRivUIi z;1pSo^Jw7nF_8H#pN5Fhq$<_JM5~`GnQkuPWe6Y@6G2 zc6KPf0b+vg?8;c2H_GfuXyOJr0IW)mOCzMT^9Y~XcT4^5*|V?-dxS1am?=8Fz^!QO ziEcEoSJnu=Oe?Ym7@|hyY#uuH`$T&1jRGNd#Yv{HoVgxH1u9I&l#rAm6zTFVm zXR}ny^*PT93|<}j8V@_nyct_rKc?r4O153)^VSYI6oER&yvD9ijbx`Svwk3 zD1MhAdsJ~AP zhbm8Z;H)sdYN4KT_jd{;0;7J+hDlvKsB!9`ec+7ZlwvW$q^=r+J)UUvnNu8w`=yZk zwpTkk$h_uJ|)C9+0o69K6Bj8_|9P$RzmoVY02Y^-FD zj@l<{Tn0hhAK%9sq-T<{GB-?OhH+)7yk@q`6zBOh!8iwJoA+G>5P}|DGdsgnY00ID z9;+oDx2gA`iyHD{VGPx8=|&UdoxI5 z!UtXWd>D&x+hnnWK(;c69lRRjM$`-;b^ruS>$v9|Lh=8iS_sFU3S<&8S!)#S=MDno zc!I^T({ZQMKplKD{q7BW5}mJR5m=>b>43hGB>v+$!93SqXZqmIvp1PN7Ak=ffL>_N zwUa{=Xg}g82-%G_x(X?AR#c1l5I*61%IoK~4mhz^)s#bLwK;LN{ef#x%qU-y+aNxt zTLfC5I1k=EH`5H%mNMdAh%TL*5dUQB8|ADE?*F`vt~O}g3UqwGv0{gd`PLger=WLd zK1dBNVt*xHuY=b?@E<1_(Bf-c(|>xl6HRUI?Ymb1Lvh_(J>!&HKkVpHZ5dmz`}m3Y zyRSsOC4gX%-e0NJgWBVxYEBY8TvDu=0nG8G}o1Xg^UJQxG2{|2b2*u;l!CYu}= zToP39yI`HVSSSUbzm##O&Ixz8^N9eWrFVFX*@psS0SJG+ zve*Vx?&m@3h<@nG9GwX`C_tLa!uVWHUayfe%S}daA+6HO>A-&9Q(W$Y0BJJxv3EVW zo0ndihy9Fp2s5H^0=1CI9*6;rl3jBq;Vwd1Z9cgk?**&yHRLtuW!Z9 zLVMfS7hV7EK=M}~CpbR-d3{qawGAsyln*A%T{7F>u!^~QvyQ3rNID>zjC(7_=K;g@jyo|9yNti%p9K{t+u;)F}`eS}#AMNxY@jv84(?iSpbC<;S>CMVpB#vBf{dhJgX;5Z|?4EW7y~LSo20=K6S*6uYR1KW;099U!9NV5^W~ z&RNE!GlL=FX!J$oQQV40VMrF0l15lG{zY8tYh5P30z?o}ow;zn+gNz|s{a*;t@qIn-;u&Z`N8Nr|IHlP0d!==npY-$I7p&`SK z9L^SqsJ}d+xtc9%#vW9dqg`@BL!~ysy24PEg$WasesUq{CfLmeA<8;>e#-LCjmhww z?VkDR>}(5FH~r@U!|7n1LoqQhrHUbLxyfn z)Q^c{wp-63++V%2*kb9hMC-D}Pa^VqatEzwa3KP?qt>N(>??K2f&GaYYhmh-oZWLT zta?u~UsMy)v%SKuW3i`>0k69@$3bxhgIAq&5nC@erivTVtYz#$II(vI`B1+YKeZ7n zA&$yDf9ioiysh@(soWxx6q7P@$`TCJnGUrqkm-^AT~h$dbT#@g;LxH_h)TSOieNfIzK?IXNT z>+=qZ>CuHJd7fwcb*M5H1HhwQMI+YDx*;_gl}kq`0I$03L0>HxPF;{B@;mWPw3c1x zvDK(r4nhA=6BB;XKh2%4@guI9Tfi%wk6kk!9AdWfgrR=RE<%#g3;DJMuaCf^Cb=Ux zON$(_NaFy#ykJ{I!)@ahS+Q+ll;XjtP9`f$D8N~Cx-EJmW zs#DUOU1nE@1e

6}8ZdK;mWon%3efu-XC327i(2$LNh1n7^R8SZC9L7|FU{FO5TT zSxo&#k9W(+j-zzQ{lSMA`E@T3y{L~Pd5M>F{4qDNU=X)42qu0Yt-(;=wtU_mA_MBM zeO)hg-JY16EIx}L0;YAoYv81_N@>^+YYX?+BFdLoC85f{&lZbZ;^s$3_-h_o{%36q zK~kpMk&`Nla~de2 zBodfiGvFxXO?q%_`uBVs}dfYb474r8)go3Nl#ULYuU;TiGxs3D{F! z;=Dh%$qLLAx}U6T-ElLwxHyq!B^ik!=nz~QJ=fvvcOkYw%0r0Vd4 z5_CDAeDq-)e&MD{zJtFxloY}RWl+1A?R&i&aVDh2&t*6|t46XU5sGnF&8NO_F0bhK zvAIAJUOM59#&e|sB$zkOg#wryca$qbPgb*#xrgA^8{v?q)z=V`mn$y`^&8is5gE$|b!G zn3vUCaCgVR(R6045%+L$h|i@x*S_Y$zXKGQ+>w)vAnT;^{tX~XLa8QQqsmB#MCg^z zbrc5$96j(dTUZ~&@-&;=4f*`y=j0PXc*Nho{Ve6OP;VgMT`O6)b0m!mofgUKp%G>; z%sZ9xBO@1)fR#UvM3YFC+QPcub&)#s;;$Y$?g|1{=k10i0OPzf*5StToVR`Py}2%G z8G)WzmtB0wP%yasfEC;8n_u4X*0$-!8lsoar>kSkL(#3)ZzAtix>gzFUUAQv`~uR> zu(#X1&?-LL&VmmiUk9qtN9^VaxM84piUmAcu&JO0)w&#)n3pkFwfigcrOqkv0Pxe$ z25>MIkz-z#?>#_dY>UNs{zkrqMaapX=WA=5hmGY@+5y^n8H>c3@b6^ouTnlyWG$PwE zl!@xgLXAhmErtWNqJoNBgx-*7!EK#^O?_tC8ZTL4wkme5y~`_RE8=Cgn@Y|LBp74) z$F=YoN;|S#sR{MH3BEXdJr3br=rHZBB$E%>?I4r0P-xR`M!OwoAYHdf*a_&!PCM&S z?idBJ-)||;c;{qqvxg?qFJs$rOsyMUfU=h`kSBTRWJTJ1F8R}&g?PQojKR=600o`~ zlf+B7UNO|gyYI;$T~e~UI?+mRPDfciRiO_PtSr8X({&7nLAlweQuQ`G6l4vqmbUnF z)Q_ZSa-vDr=C6=gDZ>}0ktv<;k#oNx%|jj!~h zf7rDIFY&Dpzz1|HJ_(gb&qvN8o<~TsX4EKE8e}$QKz0b4;?3?B zaBkI)&88ji2aj|(bKLnxOE*KT!*(zqMDpDrX(01G3z@fI`Jc+AM){qfRUG@3M$ks=G4HZ z#<PIhv`ZZcJTON%{h^*X47dpJNG7u{7D zhzmFAXQFQTuD(jDiE9Q}>v*y+g14KNJK#xdXf^JbAl!UBaFTM_<~#CMp%+IU3y|`J zBf@lhaT7dP3*+vm5d@g#extY0X6?&Sc3~;KmbXdMN!3G zsl>1F3=qol!3fW9_G>WS0^QNF$uA*q7YIkE)5 zxl`gv98z4@&bH`6@mr+A0dD$Rl@OW#FK&{HHHRi1HtCjRJ+&$7Kw(juD+M4Z6FU}*fVg6J+bX2O!hz>~p&rUn^4F*8Tvvc;1Tg8nmQN9)fGsZ8 zr`P*$%>Wij?~@E-gDS1&UqSFAV~e28q;c&>k_(qSm8f8GgvJ~6K7|lLrRaVCMA`_s zTR(aVaz7)U%r}p41EgqLy|t*iY8)V5Xl}wmLp zZucq^pkEG^dZumgTcOc-jtAWx46oqp|12Pt%&;jEVW>4Lv?%3T#lI&pEIc*nSJ2{j zfZW21KkUH6vIlz&Wl;C#1-neotZINXiYI&SiV`44+8unXC2*70VXr##M-BQDD)vvW zalu9t(Js_?Re@Ap`sq;$$Oc+>)^>|UFy?52W4u-cxPP`m;HF6t*q3oLMP1tlIQ!19 zz*$m54NJn4i$s4~5GCgrD*9T51~i+<8SZ$W181i^ZCg$e`!*FxbMamINLSZ+asdEu zB658S>Iff>*QeqdHmER6Hh4G~V!R5JC1Aw2O#KJj?4wapB*K=36n|d^G+!VPv+SPTH)f%OBSw@VmSk>REY zO!*9oPx1DUgK;qSHBhQ$I)0wuPIa1D0dofMWCHzvlz^M>lM!4A1}wdd+xXM+)W<+F z{oOo=2|@!hJe+^FThF`7l#HbNu*UAm2#7^6QHehZ%V^)+oip8QZGgkK-$qw6wNm~~ zL@o;Ajg?xBq4Qo@BMwxbA~?p2nBrG?-v#~Pr+Up$DhjW~1ji|knGn|zy#2A4K=syC z=kOzt99VQqL8M^!6oD>uL*p3{zI{Q@YID<-@oRS>`Ei3}-OY4ebk_oy#vbo{f2ek1 zlk4LTgaK7XSRKi{qrbQ7hO^P5TiapP=-$9|?aD^e5;LJr=pz`K^`56f|6RI2iwuy8 za;z~1*v{)6m4e0eq68{akoF)V%Ml= z)}KOs!-tK)K;msG7OAAflXZ0M{2zgD`qc$0wf}b$`P))aBNWwy^DZ(H8(*VJweCuJh7EVsLJ2X`1`6kWwZTd=Ui;7VtP1Hs-- z`ttiCNlT}-zZJ=5*AOjr3!e${ddGX`_E&7=dpP+ZMrO%3ZGV&r& zD5sQF_SyxZ&i!FA5QOH#z<(*FO{mTE#aG>j-Qe>XT$cY@fNX z`COxeSMU)$FmW&+OnU2#RYI9)U<{W%5mQ4-f+m01EG9Q8=86hrJrA0&gL~57Nm1X8 z@ZktfoYUmQ;#JF$c}V@Vl>ChMtKrM`J$g+wzL^BX?o1zMSr&RmbLvbQs}Rnq zKy_0DgGl0J7qmo+98+V3)2mV^^`pqH%ENE8abAp%n^=oxHn!!HP}|8vdP@jX{WydQ%h**#=DY?lCH<9E!;%-O;b^tk)9E3=X{aY3`ys|Iopld;P zcUXs!LMinTdAsKbhw2)g7sZGm4TZR#YNuKS1#}!S99*`lfBxjF5Ztw~nUeXPB0zu2 zrx7R|t>oZ%7^jk_qs-Ny7Np`=@Qk=>qp|-{+B=Uj+@Fp?teP_5gZ(WpB6TL%D~vN+ zi%2@l`UoAeR@*Mr`SAv5osVj5oM`11MNX2~pWsIXGTv}z90qlOZcR#Uj% zoeJ(iqR;SVdjS73E}GCZ?f}RFLOP~$0DTAF(`Vplocv=L1~(pD$gp%Yfv=PVbS=I; zHy=1}aA21s+_=xbh*`0{meZHTcob4<~t z#Eu4)1~uVsOnH0JklV%|1BZrS=c02i8?)4plf$^jAZ(p43RO-r2;CMwl3nGBw)blX zBkb1Dj4Q6YXd^+ogHAoNv(U-YgpsimPt+v-K`U1&?y0u|t;VQey#d{upc05IzTsS6 z*|QR9ca2e-jL-yD1)G5i!K^mz`3CSX(FDy?Jyru3Nr3aszRSTRF5%PquFU|`Q{4s36WGIviW8e}T5p~!qCke@Scm!G z#lPY^)8FV3-KJod+RN3D(DQ8BFMRT^9nP6)Du*L0+)FF zt}6$L{WU6+riuNA0FQIy6PGIxt(Rt3c6``G)hW!+vOFaDL#)5(H$6;zu)~Fk8ph$v zQ20tfE2`gs6pA8LOyN2M^Ccg&^G4>Ot+)_-bM4o1WBo-ug)4NyQHFy#ga7mvhNFNM z3LYng8hO&kwSqO(vRgcOpm125HQ#>&7uST=E18F(DFjSZysE`-i%$3uZ)KOgnU68p z_G#n1$>&(JZAht}(j(-qLWW%H3}{`l%G?XDUJZSvLWa`Rz+sfUI{r0d{E`(N0;8Vy zCDzY1%2iBXJ`i>_U7c6;>O1-7Fdxn`l5{DpTg53+Hdn?B&V76+N&TBMU5|iOD-&N3 zRkyY{{JGhN!$ZnDxCIerAr<}K2?1`_-Ej3)HN)^iUsBLh1mm%JFC#%vPg1>ImspiE z@qse1Z&c~z&2!b7mN4Yi)lj%Wzfw>(W1MSJNp5jEORo$Kan9fRG5L=?4`!p`E?Z%C zf`oYo1WD)ZLo>AbexqrO%9quXMjo& zx$cy*kHd*ZAx>b@y=6U=ragRyG$tFEhVxYXZm>ans6J4QM)RG%d^Dx+Y z=o5uCaO_1{?D7=kKvx-DYDj&oQF*x@EUOEjCv~)xd1^-56+^ve7Hpnr%kk|(-2F+cYCz$Q z93$hkRQ)f@2#Eqa@xqjv4a5zcw#y9=Kk`D5A0>{S_sOPt&9XxS6*5xod-s88e0}Pp z59Da7Zcdw|gKC#j7r4j01-@6Q)1?=Yk?U1&?j)7y=vDZy(Tmr0CmSI)YZJrRbSVJ- z=l4pnBDWZ4eK0-s$3;hN)r$~@h3#g$N{yABN+t=c^cNC0(4R{V@`d4jmA;ykRPS4J zbht&~zAsyza0^XE)H1&jsdV!L8G&UF;O)TULzTvODj}?{PJVp_}pQ@41du`uH0T@J@Mgeu$og9 z81cXapl{Xl%7qz=c@(Jm>`T;QX9DNey8@mK)rjkLe0Pz@rBTmTNjBJP6-$3R&)rma zCT$^r5IYh4O~fKR4)5hbnN22`4;7V4C7XKZaiJ$+$K%52)nH8*ATL;70AIL&4}Ave zd$23+PyY|tRZVFuG_4c12kE9f#RnNa3gOP$ITc2E#e z7typWL%bZxGctI+N4NBLE_lanO>5eJ_ZVC;e5k)a#2lVb8y>bzB(Yz+iIzAj-@>~- zq=tGrEx}3Kn(A~LDu1I%n7vM7!w{hDVo&qpqIejMFfu{1xVGZh2xC+?Ap-Qz|H+5` z;R}B=VzYIYi#WEWMV(lO%A0={4b~;#`hwc$^2j$ssWxLxVl{w|6Y`x#yhg(h^i3w6 z-7O)x)=pRZGK=L(Rnx}@D~#{+MuX^$Ye;&!pk-^$1ZI4D3GLgerX5NzixcaLxn4FW z`a*awV|vf#=a?PYk-3>aiOByyf#`f2sqNA-F*J(^kpzTX0AhUA+|R?2WwXpHCv!~w zV_pZ@kvzP^tJFLl3{}%s)`}Sr9gmWl3{mgjzaYS~K%VxEr;QIo&_X#CV&7L;PWMM& zsMO%|0|ZP)YyC=}(JCRxI9wh&0Ta`EZuc|}pF+j&^Ng|tZrlmy8air;nX2=gjc z8GZ`>=^}gD5kD}cOTe-Vj_@CRH5N4J5t2N3NU0kz1iiKU|2a|GALvY*6a2PT+H5bb z$b2gd-(PM(VKosfd?!=z$TipIdY5@wl>`q5Ld$BD@N&?w%G2W;uZ;->Q@I9h1LpY4 zItfYaSVCEkL^JARWd0ZswKcWqQ980U4BNI@9#|k=(FaYZu3bpQ;b_11CE7IwWJegqf9CZl1AN zNm_Jjr6Dxjyy0lf=7$V_XTHyQU=><~*qE&7swvq7t6GE4QYflc_}aD@T?pn{dh~t8 zi1@nr@${Vb1Lw6q8B3^~FnH&RvX-y!iqgO%^#T7mLn(>;mB=e*x8gVwFD#C`{rPEb zeU#Gr)r5Z`FRa~T_{(bFA|ta&91lqnbxZc+r@ikN)T;&9x?Tw`#x=#4EuEmS>zkQR zN82JWQ|D#bBHPQzL`p>u?;kOK?`_1``5h-E;XlZ4IMH(iT7ksh$wU4TYNfHZ$9yW{ zXMPp71D3NLr))qr)E<5IHF19wnABI^M0E4g z05kMd=DTEQE*@7NdQydBI6b5R{#SPy13{e zRU0jh{RxvNozk_3Sx6fj41qSz@f~mf2iJ^t2aR|(lf^^|Q%t-c=yE7U`Aj-Cl~B!R zessH-CI2^t<7sFru_1`z2D0C+Iwyr1%RlXUF|5#aC0~SIU-O}E2Y?P+X>^aOowz&V zV2~WHyqf8-P3{$V)Pn+zZ+yloq9)@1asC&yQ$`USwNvCnvKK<=)}tdVQZyn83+LJ# zVGo_t##4!Z$J(~HtXelzzbhKWswD> z1_8lpz~lh%Ah8#dZDmmdDF@Oci~D{#=Rn2byx~hzpV?n8ylry#!1ZQPeJGc&1p+D} zFtHKi{s(Bsaw@)N0htvx^+qMF!>*YbA;5?qlum_aWzmK0QvEDc8!I=pCaIqlvU2@9(3A^;V=Z~mUZ4cG#0gzg0=fMHOVc;g3|6mMFfao zk-y#t7Sa#P)fTTEZLOgA0AvE8C2~VgRlua`eKb$=xW?7MOCnBJ6gwAUBlldblN zyGd7)xKkQ{p}i^^K9een~AB2?FU1~UsBYA}lDzs3Xd6F$C9*2fnkrCQUh z@H|$5r-Z6t=A7n?%2L^J7;SRY@)8@oCh!mOlFA? z1A?|J`YKGcb=aBK)!kJIIanyoJ>C*(h~KZ9Yv1g$EQh-f@OO%{RsP%1C%`Ep;KA=l+sr<^FE1$D5mOttCno$kgpw~!niL1rHI)~C&I zUB7{%y`v==WtIU0BzhiITc1k)_k^pecak0sq{Mm#YOyWw`J}GN}3kK-@8yk)4Al6uDher?m(0d>hWJ@S*cmpXST-4!yw6S;TX~5O3D?HdN3XPq zbeSvc;gs^n;TH|fsfw`&4K$Y}SrzFIF$dQ#tpxH)0DNBAD;f77?}YpkzAIroxaOf| zWaouwYlI*o{_x~yhqCP}iYi_zmpJJ7B z4vG=I-UgVUF>^+)t>FY60ADZNA@K}KE^iu+ZasZn$Rn>3D zsHiAiK*0BE@gT8+4lGryN_T}G+r=_~5~nkYE>Vs&=t)K%U9y*J#YM$b7)u98>BpZa zdy*L{WmyX+dY@Au48i^7#=CG&cnzNYTC5C`?A^VI!N$>=IXNJ!(0{=;x~6gpa1f?; zhkMhw1rfwII|btvHX{6d`Yh=fKLj8mm7DYettnU|E5y59t5|MjU3G2OqM9*eAPWo= zESbiyJ?2G_14}FR7A2~c0eLB9Y7n4WjrPUo z88QKWMm#1Ua1+7G$G+fK3DBNpw8hOF;%9c%WzwGlo7suQ{?|H@2#RtEIwjn*; zQ5vZ?xH29vNEMeES4Nk{t?kotMQR7jLheUpgQ0#DYZRT&$)^8JJD~S@zT!7p z#qta$Dpl0A&3}5--_OXl7!;ZjDv>JYrBA9^AUck6izUQ=6cO#eToZf-W&H@$xrti0 zZXjWD8tnLfHjWC0zH+uwzBt>nT2fIx`0hnMpfoNJl5Bwh-z%z35J&p^@)E`WSk=Qu zsHxE7z_WG~9gekQB7`_tAdlT|#{iz&^k-l(_ukR56G^$$K>%&@;Yo&h^o6Uxa!)T& zaOi(fSdVw&2LG;Hn@Onfut7QWdYTBNDYm8qE5#G|@yo7&pNk43bICxj8dK5kB27Ib zl1mU;M6$19SS8_fx@k2l3XMWkRF@vr-o?)2Rf-Q(B^9-c!48w`<(!!b@Ro}4`-`2j z#(PnU$xY^d5LF18YFYQ zvmnDyzJyXZW%?_miK<1wnB~am>HqroAduV^#UwJF>@q(iQXb%xC4c~iRG1ok1NfkY zhb~`QWx7V6Wi+`|t7~rlT;$;lGt?+N-+b{*1j4L5?IIXJ;VQ<}_?o#cRhV@u z!SWT@Z(q%-G1H$BV`#WOn1q|s)Su+U-zS-;)_T-Vbj}uiLy^hOgRW*5oj%< zyVCsLX&z~>(&Lil1_U?j_Iq*8sBs^6*FJer97sp*NE>Z281I)(i013 zP=w?^1BR~oxU2+^kG>Cw958-5u)rk)vvm3e$d1fQf)5(fkg+%_C)-zds-5ewJv|XXsa*x;{z&Uob2n zjHg1=De>OODQ(Bx3)DjRY?1JF9QZLzkQ!5Ibi?4d6Tcvj4!4t#yj?$X=Hp;g?!)@& zUlFu|xoo3?JR1a)Ht7oOt`&{ng1HDa~&!@%l;jWq5j-EY%TTP!|QA=SE5B zx+e4jkb~T&$oPtya(JusbL*SPuO^vNyURN^4>K~h7;Omx&c~jYY*%A06D7_sCsu#d zX;d-Gi(#A*y-B?H~!oAu? zOvTZIN}OOQ-_l(fFFb2dmyBEkDUln&GlTxq#N}%Rr;GLfX}TMirQ<=O}2e zRmEjN18m!r!kRg0dz8Q;HfvUksaK2jmj;=8=FqQlmWuUd=7_>?AZ&6b#@qbe2r9Fp z9;^}KO+0{MFVezi)GSvbMy(u>p*f;Y`&`qrg!r@N4GD&NCz%Hqi!{rxT5N6$)ZpH64#A3cWU^ z99}puHU0_oXi5wpg}QBKMh(HNJTjn)1W%e?6`(r5dwZ)Pb<9+V>j}ncTi`o>+KwJ$ ze`0~jT+xqPR(jSNWkRdOfm&_TDHts11dgEXT}nBZ=ItG0Px7)tR`>kN-ALq5dF2Xd z&i5H18?nnkT-%c0atGvTRlP$LU0In(6^H{&&k$YSv!i@MYq91%SD#YIs@4{jme~)! zDH$}iYC}x%j=u=kk;pkfLfoz*ohuDSMNK8MfnRsnk!Y>qXz!1RKtJL9dF)Q;%||uK zCSY(qZkTdKQJdYi|IsKjj&KTCky1pk^TQ^njxnqZY znQMw*V_-vGpZqfQ=d}C!db)H6f)8z54{o}f89#s+0Of<71LFIVMv|Mb=6pbv^N)`l zIryAIvOQ~thQ83rn`CH(GC!@R8Gbpu)*Bi>VL({9Tx86+y~1euUAdmr&DI zgT9_(tO&dr!y|UUxN!62WqY(eFyOYLp0u$;EOd5CE_W7SC1D6~G z_AzU5>BpV`m?M)~3@<1#nRBvm1i0%$tUWqSu^1*XrMU!Ot!V3CCf*J2&Yol7U!kw^ z$w$j;&I#VYzp=cuaz)ixnRC0xj^RgZr<>pCq7anxse+_Tkxt(4ila&K3o1{cKyHcr zy7pEx*oxzg8$)DGVQ_9A%kb6@n*XV>Kga9aU*{*v61ip+c5Wg=ZJ9F35RJkIS+;TGJGMD8gE(IT%M++`<*VRTaMC1ss1rmLLtjIoXL|q2Qm><+kk`6rHa?vvIkvdQV0P$l1I=bgte3}e0|KZfgBQ?v zE4gNbd_qs~>d8*%{$b6w+C##gj%VOLF@-(-P5dn=(%}Jo+Jj|rffSF!ApEMr4ENk# zwbSRblE7KuAaAkSm;^Tl?VPwcMUZH|#?(`oG2q`MmEDqi50t}Z=UhJlAQ~vmWCL~V z(t8I=_QpOMd2ER^^c8#syMu{U66o=52&9xJprWnJx#F2>yLL!ES##gd)p2A?g{Fh` zztLZU{IL;ZyPp2ClLzqZOiDKX9K@Bi?Z^rwC#&g*PC6c;m=5 z2_?2W3O*nW-d{ewB3vDN1t-ZciR(GBJ`Z|b>a?tzTiSl@f!1##0`paJWxqObA9MlY z9tLPLqlW&d6RaLrI9@%uBT5{z!M#zmBv14jNttryCoE(Hp3O?>E&6|i&1u_%wiN=M zB?KW@7e`c4iym#`Hw6iGo+d@;LtLc@ZKbk;S8hVq{OH-}YoUV~oU8!=77S?}V@4kLWozdV8f~C}+Qb?f8DNZsr8i&-G&4qj za>CcRFZ$@AjVhck&Y@1RjgDWWH9)yTR|=XfS6Jh{y#0;B`61$8G;c2O z_y>(#I3oz4Z*a3UHIt9JNIu=|f62_hNfkub$q{Mr4xp61^+p^RKxH(D?#=ebtK~3E zDZL5-y%Ibg+_UE{1Ucb}iaK$adPadi#!P^H9ild>pI+4rKa(f<$xMSEef(e;ho@O= zS2IosMqVQnaL8$)@-BgY!+2;%y|fgqekXTcJ~BP+x`dG4IiqLYdP{KFB^-t7yL*OwNIErr5k&KY}3vtC0f2JDMgRefF1rP?A9`&I0 zjm~@o+fN~3>1Y(gu#nx59OoYCsSEAl=Z(@n24GynH{C(0DSB;rCh*H?-o?cmqg&3C zj1pNY#;Ttx8&=TMu}=N;4jaWGOQN@^j@(RG{_%ZZv^H9TkX%u#GS^Z=AHHuyo|`qA zk1dd?F&sItn}kC_wwO(Fx$r8CQ`jJuMu?v_jK9o*<;!{5@y;|;Gw?(1;XTfIN}xGS z45qM==Cw7GCO7arljW|Fnt07HJBxz(qd?i>Qy(4xU6>+yH}FSPODk|=2C_jm`7?9P z*~m*(K4dzR>RdAI3)2%h;fi0K>qB0VBjZvqiJih4IT9QM)%asKSbsAa3ep6UkYT3r zz}e@yPW78%%iKF?7eT*7mch}wxIp0K8EAx!gF|z>+c%=LN(*Fe$Xo6JCX0*5A90)S z4%0HJg0Zy_>&*iC_ez-o*r$LI;>*$Y;i8B5Z=*VY*gu2p^WivXbLC)$jxQm!_;E_J zBQ{ij3+~rk_v@nut8YfVCeFs|9ni~7woxHg1a*G8jZ>y)mFeI#48gk4vXSCw*Z4~# zqm2$Nd^XvrR5f0uA?H)1_KDTqp-@+Rb}BumhR!bi>_2+@gA!~@bK4ZA$8wuL*&!l= zRN;-8ob8^}NEqU@z~8AfE8~IPD8u=F=MdBs2FsIHsasTE0(xB!mlsEYFnOJgZc1ih z@S>KCyj1ZD} zgEOG3$=a_l5!ev+%~ku6=*gcB9(XsnJ!*>t0_bOaufBl53N1?9jG~0=99}iHsJy4b zSodlqhWlh$EDwn-btK@E_=9c;AS7>PhH?|ENEem9l_^vvu!&0&CxPXxC*ZoOKyy)^ znbf~pb&-zJnzosIP2*`}!(8{pES9Z@wUons_0 zBLQ2!be`A`S8iubj_1fa2+U*H+~G2;O0HVWglZe1oh-5b82>$G;wt$uNcEN{E_Gxn z{K6Hxjyc!i|%~ab(s@V< zwlA_;Z75`EeAD*zs(g=G%7tsX*CIf;LgF^fz7O zV->TZ4{XR#n>46Z4|Lj&AICXiO5GpO!7llJ8(YU?&BR;bEwdEqg7>pnlL)|c>S9JU zTi9?oYhf*?y%J(tdWm6+=wZ3TVV+1T;_wj-v}=s64aL7>b@n=KGT}y2dfAR0u0||{ zT1UdXEZk#mNwLIK&izlR|B~o3e@4SS*j7o%*&T{-Q&kp}xK`r0)GNyHKi1y6xfQ%iAL9y*~V*q{= zGxBmz7TV@=x661fb6&!8c(Z__dK3-xceO}wTK1iE=GoWUWTe|SKJw5IiQ)C*y6jP8 z^S*1=9c1D|!w1Ej{7Y5xbW-Pt99~!Bb)1keI1PTamGZyE>po*Fk`Mqd1KQo>1nFW2 zbc77wiryTRdH7>qkA=Nd(ewUxSaeb!+#ZIL#R26y;uZUeq)F!S6VFZ zoIeuXPDY)2>q(yz8^<#eYeOqFU~h?OKCC>p(0eJ#OK$TMc6jX1ZSkAdSB2scBiw1S z>RWN0v+K|5_+}ZrbYkuzDP_zf=;eLfJmn;@cGzw2S%Qkr+#n17PTY}ulQm6K%web& zhgK70ATk#_YylLBk=+wyv?FhKJ<1VdQ_qiEN}O$}t$|f+7)v9sPJ5$Ludu-+q)#Xm zI4zbMNR>E8W!!{O&R;Rp@o}>rE4z>g)Z7$kujLa$_*OHh$B{)v1z4`ME9|Os(G+ukK}q^5QERS9}51Al1QOI#O>FiwtSEg{p@F^4nLsWH@Dz z2SL1X+vExU;$g>VwzM5SOmAOCLNp&>#L{IEGZ|?Gt5O>OmsJZd)DddJ;73Uq*B4U{ z4@PQ{+i$NbjRhHt%YK6IKkv3A#W2V%iU@`tL4*u}=eGM+YqQn)jtoy;{#SRyYx@0b z&)$9U)S76v9(8qjA^^KcTy=SwyPfu%gcO4D*C7Su@qDU`9NB+?ePvP&P~V5CDYC9> zoVwBX1U)J=ctj0JMP^gUqN}&$apTg!018Oma z6B0KSpn4)>XQR18KsGql3|$X5SG^Pl^M>%>_K z{cxu%m}cackuHKnS7c~th?6P;2uJ*V5+&UQf>c4zrXAc11^~vxS~#u$htq>(k~W~$ zIE#tntBRFN!-e#zJoqDn*o>CPG}LKdj)yLl>$gU~vau7gmfK;&6PNSUTnihv{jF0& zvNY~Ir_4VxnU2@p{-A5u@Fqn0bLKXSWm*M9cVK%(9=wpe6IO8@JuXcsQ_F7DLw|Do zD=7<)Lh1}o9_$Szhs)#`kaJl;vgQibZhM+!AYL>oINnMPT9571xxQAw1q)OG4A9oX zHbNZb0Q+Gnwo@^E-vuKgy0d@*vd#xv>SB9KU7M|qdX^!TCI!eafCBYLtaBo-E!$*+q8XtI$5YlC+3Xe?qY6WR+YYKc> znK)8}o$18p!1krMqGG6`?VasAi2b}7g$Y;11bhS^A`SiwRFh;IGKG=@;;muDv{V*B z%iG_|mzsf_938ebw%46LF+2Wh>UcTPzSIG!{xec~BY$fX=vw zL2{a^`A@0-x7q{?@)I@#xwa(w9~C+qs9c80??FKn!z~Z%?D!;eF~Jkd>=3TRl%(7d zshYElK>^RE;Tw2aJR@y*$fEOemrZj2o9kd;9@R#tomDss@h3!crB%I?x$COwCq;P% zVUU~SvU78L3Vz5&$-cu98#HbGPjjdSqr<1jTf!9MeKXGPuek}xSToY~1{K#YjP#E) zH)h7yq0(pa4)vl)q=L`WbA|gZXf)_}T30LsEM_wgKW@(l$F)DJT4N(pxpQ~8RUuWx z$aWAdNy;P$dD41eU|YYvTU&*d8iLD=6F@`Tgr3GySDJ%)I*XvK7#cwv=EzN!AELmX z4ad*FPM=iOZ|~|G*F^z1_^n6W3n8`^a$}pl(Rja;SH+sIDgYb`W>?!&48|Dxjj45 zIuhpzUXY1=qoP=$Pcc1_*G9X{w@foE@YG?`7NksJcPX1YTCM;XCyR0>cW{)*%HEnS z*Kk?Lm9TJD>x zw6kop0$)W4O9Y1)CEq!LhQSF~aNH5iq*TOC9#OAHYUA|u^6Mm4N}t#l0!3XgnIw-y z>u*SGT{E==8G4d%Qdvq{ywLfEYiaAT#zG~chGmR$-%;2^(k0rJ5Tan>X6zT{O1mar z;xmzWDa|%AxZa+U0UZ2My;W1zYBJg7s{tC$XebJu#WiKvV=B~lNBIllYJB-ve@I9u z-7vkH_NPwfH6W7F$Qc*$qE=7pFNwZzJ90FZa4d%cfA*%Oa_GoBr8u4DT zC@_#r*xevAhT9F6_Fd8S7#CFwXa-bVpg0-UXSiEmYMf0U>Gw8?`7R$S0s(bs*q@6RFkUwd||T7L|hrKb_O z$E1~{)|^06LFj6XG1&QPMy*`)Rm=u=tDSrhGa~VuH+=pg1AVpuZ78m<_;w8f6vT?b zglV{_e+b=JvupB1>?4>zr*+&1dT1;D^bzWxyIq}ZQPjKhI;p137b(2L4)U5-hNTIL z6X1LIE6o$!Q;&%|GGTavS1RH+2#UBkRCDSNNrkgbiVL%)R|APxIR6gLBpK)$<6-1& z>U(ra^TbB)(1`C!BnQ%Lwyv}m(nEK<-F<<`7yMm-7K0ldeeKzHk3DG4l*?>6n91Ow zrt3zPCD`PkEgb5C*(xtT;v z?2+UBEEG_W;FoO849|4=RgJ^_Jj6QQni$X+-#$ka`%-ZDQfH%-v4x|p&9Y6m>>`4{ z6u1i+$n6kdOen^3zj7~sX?AK;U3$lOEb;SJ3-rYnx!}OsO8KGyy{A^Znz#-1wc-qH z>V;dStDLVn@vgQzY`HA@Y%V4x#D1S{D)+9e{(G~qFPU(<`|)9Cdvo!%$*)KM1>Dq* zI8`RFi`w%5mj>T%s&(f7sWm1%UI5Q($UIXq!TLNh(*T`!PqiGB zCn^RluZfAr%M>p(oO<#WB+1aqn8)H z2y%qPK5s)%`OutQy9f^&pC`p;MfQ>5sWS=GUTC&9siq0+G~Yp1)>J>K1=gZ5%O335 z+1E&I66EFELQF~)W6*&znVHjpsxNW2NM_a9g6||YfW`=WJ(;!e>`d0jAfOE-$#rH) z;ygk#tA+{v<`iM3HiZ=@yj{Xzf{Mlb(Kkl5x=xxNh#105r_QRF%pLT3rU@ceVrlO9 z>dpJeX=jqJ)Ox;{&tCx{A5;CDy6VMXJuy%4pLYgLg%uF=S5R=RkPfepbR!Bh`M?#l z+)E^OmDqSumW-_viZ7obT$-jkTEaY+rZb=PyD$c2nN(VeEd#}#5xq@pm)09(pf`j2 zCSlXI6;zJ$E~eHDuosA_Yrju(?eSixBAB(ZA;nPRK@8Mq*)`76YV#}Z!-7LhF8Di} z%)FE))|FC>tzvIcj*|!ryX%iD$Im2);>!% z|9&>Vye$t+rmX(tObg4mH8Fwdw;^7679qW>uOO!!U{gsa$GBq-D1npxP`~6R>@jQGjO{kNEIb82_>c@h`1CSye z;#U#mC7CF2w6_NYUVqx_+&-oJR~Hujo+H7DBZhl-hTkI3dleKGG2Ao$ys)^f*ynS9 zbf(t5RZ;sO7RN3SiAYW|g^7jZy3ZAE^I2XQLUHNkHwVarRpfcXtJY)XbG;xcC?F_- z%uS7X!x_X&r7{0$*6+ev(SnBfqWQu#!4gsb zhtnW|C7?X^zdLDMz|J9?n65!Zg)PIbB<3mKGQr|Aol=`tBPtjINX40e>XTplDdxzD zaT>Q8rJ_`((Hopo3T^RANs9QyV!P3Y<3i5EL$>v{1Rgm<*HPg^hUf=LFYc&COc9I} zRdnYSJogrK&1V4?$$L~&tXC*QiFp9e%ODIK0gHJz&&q@P>gE|U$FAhj-*k1Ahy$#0 zzLhJ^m=vS}R3tL>2PhyB!3lG69jEXlrRV(u^BB3w?(fJyh11dgnfPJ;-TM+mL?qf< zauYSsBHkC<9tol=P1S#BdBpH6NPRL$aJInI-_R<~Npj=Pza%-$vDupma*Bd`VQ#0i zB~-So8W$IlGe{jQAY7zx(y#LM_9EcI((AV)dXOT{XYNae@TidSUVr3qs()!fmy zc2Mi)o5b$p0KUNp*cv=ut`U2Ol^^)c(kVK7*^5QcH=M*g0`6lflFZ@q483Fbizo#3;r$Ku3K#~+mUPvsIL zOrEM#H5SolhQcJVoKxz6U!En?>W+S7ILG*P3YZPyt7MJ$nONiTG@?(5>@uP0dKS4# z&Zq@6n+(wtpr0`@xgi|r*#oVY5-)-j%)p_$S*83#myo7UU1PD6NZ0F8mt=6KaTvo* z0=F_&rx+Z^TpKS`&rR7YlWBzq44!fqcxw!<>{7So^s~mZ@os5OTe#MIG|HFYN8#V# zyU)A;Y%SSv{rSVO0X~reX;~Fm+ne=`^G$tsyqo|>K)An!$mVb<8VsN?7$I(s;XV=n zx2R3R6bUkJfj~6OI=rc$wkerhxyGpogny#%`9)JU|77#jBeL(K=;&mw+3|>Zd250R z*cSY%2atv5n?$|MH;i#o!gOvjP{809f2YQLxBS!l5_zbvc23GXU-Q7_t=QG4BDD;k zJlN8y<&}Xg59LonC9+3Aq2Pb>Hd+1+33P4vv+`@{x* z@kVEs$3&a7a3erEb|4c&+Q@`X{@ezWpamIbffaj%9|5FM43U9<`WLkIYhnJ*3|wZ> zoWW+dGwep660(%Jw;8q`Pll7-?8@fQZseVPijmHPG<&Oi@54JCqqTZ8CpDG(ELvid24jSF~P-;UebJcRIHJ1)!0TIUH{xSr*BIE_SweJ;E-n&;!4kiRWiv+n_%` zzsxKkj62ABJ15-E@ejmNr;oyx3M8D;y(P8t?Rmi`i~ff#7i;w*$?5DBH6*EHjo_7c zdCTQ;p;VRgf7Z~h^KxUM-rX}KGoGbIzy;4EC(NfF+BdSwY|fc&@}(Rzr>oZ~KJi{~ z>s|~CSxLa z;S+l=AOf_9xeL{q7|rM*=P7&Y_T)q0+!IF__S2x#P>%SoRO|h8WbLC zQiWJW99I`sK3qTce?e`GHS^n?G%4Cqf?R~v%zg6;5}ob{&er0LQSy``uWo@3^e}+} zb6c}R^ zbpBTQuRGuYkYGmhE#9v_RUO2%@`$`)Fq_zcI_$CJ;gT_UiGU5?F1IF=zxIfoIwn0j zGL|DMMwbJuijRk}hbYTBad%tfpI~)`xm!C<$x$7&ffpG$)xe6p$-A1fhx!a zA5(K(oL~2dKa-%%{Rd~9ex@u_Gc%OX=OlqzNE0M=5-c{*wfwsHR;t`0>PteEASheg zfR~=v2^c2yEu~Cea$$R`v&FKSHPP;~uUUrO*sv8J{Y17KW`uHoyLNyetVk}#UpkrMFr}V48&R!rUm9-s^coTF)H8U2c9y#oVWx&i zcX_*5U-E3;53TF!DU5%7pH5r#ogD@QF}lcvt#|~=P^P`k)^-$Q#)@pbcm7F8;MUr1qy(G*do3femUb(nCiG`8U!on8vFygg^0h!6gs)d>7q@+v;OGqE z(H1vsPiD7Mf`tQMFj-`j9f1e%NDam5Z(jEb)MhmAx#Y2j9(`HocHY$miY9`?{oWkK zy;r%$4Hs-t;RZm&9adYb(!BbGVtL52MGi3eO2%HEe+MSo@GGgFT}{QyDaU2Q>Xs~@ zC$)XuZGi~P+Yh^qbOf)bHzpr`qh5Wz?R;M%CTcN;D+t$o9-#Ca-#Zdf4?aS%x;DXg_*_= zH^RoMubO>^nfsFJv_}JOPAh%Rh#@Nb@TkMtRw2bRP^fW38VH(7u{At1e?VgMd|r~j z?hV1qQDXV50XMX^3nQN2xozFyM-c#7Mmtp9o!2qfxsLw*-vq; zNMi<2o?WS`l|Lt+ugRL5{wj*7sc9q*!)_gJICgQCZCNP$Ym$f7K>5h0Or~8tuz=~n zraal|&3Vr0j0!1_U#;udt5~n2kUA;fEWTwhJh}VK#^|z@U7UZ@A#!d$!HM-&W<^AVXR;BYncU_ie-Ti>wPo)0pMmy+%g)DjL<(}{6 zJ>d?s(IRWdmHhr_J8>#3^IPlH)hj-b(o6;LQ9cU;nX!qnocw}4q^mlb22kn*a_F|0 zT!M7fmx4>}GImtT97Q@yThfjxYU8cawgd(I;7FG#SQ|uG!tsFMiiwR#;XrWhzciRw zJ`CuH{m)Y;GHNP4!gGi@jI0exr6(9OY|vuWgmR#XtXwu#gKmPS@)TEWW|axN5xXnx z9yWTVt^#N*-zFe7oQXDOPWRXCYX(DwWz-m_eQ=a0!$oy&GrXEP-@=HO=+7$qj{v`1 zKiiBW3Yzhz*rtj7%3#B#eoDkS2VdkDqM3K~z1@K&PIqNkW(|D2won( z@O_{+Qz{O;WHOIF;Y)QkWI&Vq$2@!M9Me1sT zJc!9>{Vgl93=~2X5ocyGE2y4DIy@Y!f9_76UL)fn`Rpw2PfDKa0bRpr%IIa^+nJRe z7^4OAxgarJrIR>`8zHht`}-;A+Jk7p8ACb_i~_7l@d}qQMJ1Qtv)dL?QM@1U7bwED zRPw`pGXF`EEcQbP+B|jQnTmD7X^&$#;aYbIry2GkhS*v~ZixZeYk=Y1$c6v&*| zdfU89^#4A1D%FxZlLvO=<2iai@hUp~to(Dm%{o67WC+!=OUUqE|!I?(}!* z48CqU{VS>DD>YJGH!MgE*oi@9JDhBHYBVp$Y;ry-jYuX=vZzt?6+0CW-7xKT9KDR7v zDig~|_ybHK6Q&^w2K4+-1Od80R=f==7WWBZj><}kM*PkT!hfs#Iy4q4BZPuyIz7$ikqz=b}N=4EE484Zb-CjEnIc!@vx`eU2&2rF4rPBJmQwlosrJWl_|wn zT#E?caX#l}$)LyBC* zqT0BHnGO(3*}lr>19ii9vxz7{-IiwK4(zA};y3@Ct9wetmPffMSU4XP+MS(@YSNT> zh$p}wNUx)mqvH`W=^-P7)UNI56y&o;dHh*AUiq@(J!SD0@MtIVds71;WNwjMl^7)C z^|V&OP=O$GCW8MbGQnSJK<9QWgDbpT9yWsfhcIll)AEuDSRdVl7VV6sdej?`Z4=d` z@B|_md4mI#36s4RH-UV^{vZcvPO9quos9L0q?4T8%__W+-`_@?KG9c?zP!+WdYIec z1aaz(GyJ3H{^7;h@|$(@Ax|0E@WW0(mNEiT9Y?CEa$6y<;`1`0K8H3Ec_3>U&+^SM zS+j(M4DZ*b-Lqo9D4jLz1V3WzZrg=(P{m`9F>Ck|=13K$$G(HH?C?5~XU&a?$*2wW zUv4}i!8qwSGA=35zy&-N$8qjwC?jG@zwmCCcxpx62=f^D&Tem>Wprx*a1gFvtkc6I zXI~~8G=*Z5qgaEAUVPia{~AYgv$A8&I5aULFoiP}5OIz>HM=6t;*Sg-8LT0t=1Zm1 zsS4)Ayu?sYZX`35rNhOv+*Aaa^cGYufIa~@AJH1Q`V53y5`>0sBrc0^(Z;Wi-oB^l z?+JH#hLD*xm)4&FC8`=3E%1cc#p{XvDv@*|13Du3Ty)31!O5H$c-#{%%I&Y!2CRfF$NRwzBL0LHm_eV)1)ggrJm75X%uDrK zrZw=U#VjRn7ME(HvI4kgAuuuVx)B%(FxYi@5Ky!0T z9>oswL!KA;O`hFGmb`%TcWT!`Fr`eq2NR`JU635bB?|d$nX;+^c-RW^9KDNH!a48P zF^YCo`cf!Pxe4$$NCil5FM$iWI1S247)AeF&nFj7l8|FYQ2Kom>e~!`sV81OM<90i zmCH2&o6IA#ZewSu%{$rZv>#~jM$-oN*2@W}aAudq*tk(x;i?E|sF+x^C|hFO zQDx25o{>%g$u3nR~`Im5OMh}Ts7yFx{xl3fAr!Z0!Y8l&pMui%;Mwha-w zSExOxzOQotIqrC&<^0?cdv55XXj|uvZ4hfY>5WQfs!8iNM95uo`&p;T0Nrboz+#-* zUc1pI>kAo*F6?k%BYPCb#G%rs)mtp4J!-Ob=zuE@;Wh2E>{U1Ba+v&r&B;4a*qBDF`D}nN3wX$p zTf(AsV!Q}B;mTxkHRX9GJ9rS2bB*|nI@|0`5*cQ&7SnSeNeK@vLWYu zKE^BPt6+$2NwUP>7bu5+cMidT(A%3x?}qDtm1%!h{c)6T{%-2vT{QkEoW2t)&q$p( z#tSrszUoyJ2E-BQl&`>Fj6E8;eXXVmjRbT3xp`j~=FzI%IG3jUbhr1RzqxEWZB~m> zNK85ra6kkhpq-Wmb8V~FTyF+vSMdmEQ>>$PD$eP(rXt{A`WumKvIkn#zic1Y(FeCD zhb?OPLYolILb6QgcxsJqB5k_CIFfqwLPmn@-$`78x{7`;2jv=&R7&qa=rd`d=k@T; zK}=OpFCY^c*C!<%Uf5wGW9!4*;3W{mNR+|aD&<~HL2a>kx>sgjnO5GHzWvQQgD*ne z>>9RdL+r+?wVgHM{3=tKr#KH$f(!wMkE zkoE#0sTFKbM_bTWkvASCY(zg|meA6_u-@?42tGv2lP;~Usi&bs zmP$Zt)GtYCqn8oCxQ-Yf&pWRV4mqKk&sw3xqSxZWrmh-%4mTEcIME1p#5-oLd_(|e zxu}|xzt7QWDyvqdGkrWpnYXS%>Z0;>-sAc58U#hT=`Wrhug;!X3^C#4=&!|T-f}es z{2lEJhe?x&>BmG|LFFv4F_r!I4&jpc^kjmaH#tbs_2cFG>O)?@TuffKN|#6~i4I!w zN^ZJl8hj5iYhBKN9dtFesq|6t?i`inf67L9AyoPCm~KYNe7rCkaL2Ye^jCnZ%Hr`= z=6P=tOW1{jykiNqH|J+fcP5-i@6ga6 zCL3yP1(nP(4lzhuFa^&A)CbPyXuco-Rz&+o5`R-Hpr}4cYadN*8yu;T?z&j@sYYVM!(-L5_Ex_RqO0{^<3R+rV=d z9_QWY-4U}*ks8w5?qMS1-`H7WVYerlQfV_bqN#VOa?Ip|KG3^#qQJbLVM%=Z{qo$x z+o)ZkQuZLny%{->w}b?Q39U0oIlSLw+Ngk3{=<&OFH{O2pru@Bq768}a|&(#SK1-? zY?!=pR)PQYg)E?RM($>7)m_-ggh@HTAZbVoo-pX)*6l5NjS^J(T3|DV3; zJEa%<)*w>2IC$D*0cgm(h!FNp?gwWjr9q}vtia7X6A@}KP~`%wBXXn>VU&WbvZMWD z38t@`l*C~|RC&K^AtE{wQCs(gL1V(1I2%}eA_;5fP`nEM2qL=1f79e2L~oC%`5a^N z`|98Ab7p*I?1-6-sQQ-GHn7BVh>w$ zk$}J&KPrS5qyFQ~jjgnzeu4#XN>Dgri2aUTs-c|23Y~+Tt$CkR4-}o0;(>>#uEVYs zb|9Bkh1z<(!mY1K6utkakbu}f9{uFKf@K4LPRGV6OB}gK*7GSblSa`>PIkS?`Es|k z;KG4A-N5@@C5!v$utIHenc z)aBLw0)0c4$wQ-OEg||tK7b|9Sz5lSU}n(h!o|fXGPCA(Y+=T7?6S9ZLLG?wo#HXjeZE4qZ znTB^6QrrYZ&Q&0+_<)hmIS2gc+RcP7#t%#h8N&0Kr1P4!0eT^6PxHa2x884X@2{Ta z_po+E8sAqjGgv}H2Vf~ABY^?pA5!PCGeG_#C5Fhoi^7R{6L&uChX}y3A%;va>ib3` zWDe--vnOS+@wTc}I%o>4vBWNl$0;8j;h*%joTeR{$2#2~2xSn#5V6oWWN*Z;r^fX_ zjrP0B7cHL8IeUE0G-4Ll2!)0{M?l~a*(X{Z0aJT0DAv%5M8^m%?nRo1#H@e8bvB1@ z0e4vs7!+KVhtdnSvUT?xdb}-TKUTy#S*A@3%kc|?3BPgV^J$qEh-%6vgapk6C^&AA zM#F$SC8|YoV?Fwgqd!Fa?WN@hgO79E{-&n{)eLYY(%nt-XZD+E+CLFPLr6t4hV zTN=F=#(<^KaB+c+iQ((zfE;F&`pt?TYJ1X$JZ>PH=|q)wotUtj_}AZ=y+@Kryi;d0}_!;0b!tu?a8L~;bH53+-E(mXO4NbiGP3C>db4%CKh zqPdlzD4YyQVvjq1Dgju&{cif+@Ibc5_mFlbu8Mo-B zK0)kk0f(rY6hr3uoR{~O@FpkxpCTHn@{YsGZ;T@Mh5j@!%+4hEd;8)yL^8-Vj%E2-EEnGl!^`> zUzmDiLC*@?eT5@JfW4_QWAw|$SIO{{Ei36Rzr+k$SA^RDX<%i28&*~vPhd6Pm$C*2 zCO6Md1!A=qob%7ytCDDm}`8T33I;)(xUH(e79{WH>z&Xzj{!x$i}cLb}*<^%w2 zJC{Ndv|6(Lw&9q`%fT=s@W7Y_pY|O)m>}}|k={~X{FVu=M2K1(abdAUpY^OXLp?n(tO1~9QSE-z0}9mIei zpVi{ij@j|GSLI+{V$hlI9({mZ5Me*ceMq%*5btA%w)7_grg!F;^ckBnsLB3zY*@X7 zDjI;KJx1+mCLCpq71DI=#W(6?ju(3-+EMMyg2s(N*4?0bskJw9gbT8<&@tqiTuTF% zP~&Tre=^pBkJ=n$IhLlgC!;*}Ck_sBR^N=723CR#1>j$xG&)Ys+32*n`o<%puyQ8* z(ZXE0QhQzdd*E(VnZtVpv;1ms?j~g;kMQf^!+3&qB8X7V5P!Q1Iwrt24=Og^yS_g8 z9P(MUp3uW+lh81T3>H^0!zw!=L)UP=sJ!5Frq-Lr1_IU>{+2ig&10ZFYYS^9QuV3& z*e0E$p>!67sz->0STZrPogHzoR|lEu3{MGD3SpZWQTND%22(#$zyJW2s8U)N;^M4c z58jq!nY|vX+y^Mk!%S1b-AF+_(lfH1oV17BAu_;6-cYJS_5PAJ`O{r`ilO^E4B_+H z-gZ6b4ck$rIN0b){g@fK?JrI0qpvBmeDxS1(#iGmOo|m~N+5YJ6oldlCMN3TrUs6r zit7UMgLf2vwBL1(a9g%n)LEhUj0=~5DqYpg^~o#0EFi#@xie_+pfU)>Q1ll?^Ji~9B#u{{8O zU@zm$>nH^y_X*4J2jzLgn!~e_!R6fW@@68QkIN!T+i2DhgR~h&<}~|@BOG+b4ry<1 z1+zw_8-}Ltb-#Jqz22j>;O+E}>jzTI5%%zd zeX{mxzaQ+6ZN9mQa=IX}{q3m#lT52xh@%IAeyO#YW|pf-Ly2-@5Y7#Eemb*K2AuNm z2lhn^Ri1*-LRE4!uv>x+m)!Y?P{fA>(T{fTCcGATa>=7VnAKF2f**?`%E=n?eD`is zqMGK~Xw9aud61cVDsxznp)oqE!fhD0;I7`v)oC60p`wQ&tY^b^;YS==1e?62|s4GNQba zI5DM1GolaJqPU6J;WW|zm7DpU=l4ib-oY#I36cf!oxR#!r#eoPa6V~BnVtpEVO2iv z>|4tes-@^4v_L$&130g@iMOoV=zzqOp1Si^QCS5_R2)o4lOl|$8zsREWSQ!J{r*W> z)<;aR?1FDr94?_g1?Ty?vEmltjo-YIfrlArlfvS%ia!1w@fx#=as`U#6Oorg(I}!lRX7HY9^aS zk6-7zHQe4N#4h+^laSj8QAkOVrHYD=U;2_r%R;#j??1-_QA(*1GCTaXKdunThLnFf zO;D~qjOIDbSeyr|*i?405-jDQ(P{H`e74YZE`e3BL=V=- z>%r4YJ#d%RE@sQ!6w?!V0ML><1$sHcnNX~3SFqj-*#KMk`9Ev*xEpgyYW)&R2ys%D zi?&*Flb#V&Y#2^IQiN+VOszPMRP%xdw$J>kIcfyZjJG&!yH9upVWWs++^ivMYVOP9 zfI!1pMe(dN602WWCH)ayWdm_)1~kwtuurHNp{W^OqDeJ(h#(>QU$2?1!99tm=zAi&MnK@x; z+WOmSw!Sp_$Ls`tG7Tu_!)4W0f4yxx3zfGaVtl$MqN1I1C`Qul5xRpCh!yMFp?DH@ zAq)vD^_+TEfcvHfD{Ev6h4|AZeJ`>TWf^gJ=TOyVT~0EU^GxDW3M z!r1+G`HS&yDu=UzUVu7PQT4hTZsR|>R1HZum_Ug}#KAK>zH+g8INvriZ0=1LB!g^g zE|_Iz&b*T4GY)69lCNMBG}d>IlGHgDJT4$q1r|xpj5u2MVKGLP1|&ia;hjnM{3{dl zKxx+mF0MH`7JCFDBZI_o{Er0n1h{a}SQxxG1JBcidQlw=TkI*)2q=Z5b-)lamEwL~csGY=z2hGBpQ&or{uYaZ;YLoWv0kcZh zxI$ok{T0qVQet7jclioelmtuyb2m5ZuS@#yE#H*?p3Nee#COYK6@8=AcEsf(;MrL4Kw+!kb`rg#D zx+@?);UyO;Y=?%ht6tugr|J@mHBRlBc=`b>F|UTGj2^^^n4u3ANI?DIu{w-vp#@=x z59;kiT-M7q2;z_`39|zQ%r2(9rCSxAA)MF6!?7><|5`!&KfkVk51{MRrm$Pt(ORQ{ zwB7r<-oS3^XU;Fgz$pb>oy$gA0NQv$UwjS_s^U+ep8v+~8AF_qhgZ%1?!>C03p#j* zZ+yazaj0(zRqPVu=m)-D6=5=s8MzB<)0X$Sx1kYD&GtMmy{k_Fvf4xrv^aES|&N;oQOpnMRlph9-6 zCe^<=0UEo2x_u+FGJsk9kA4Hf>isam?&?%`ium_P3~vku*ze=;VHAoO+mvDsp?KmR zBRLs3nmhkSHnw}?RAmbP2xd+EIeD&<1S#xi-Iy-<1QJdU^ORv2#p-$gM`dgyi9P9< z#ET)P3)D=SpV`f3d&}i$E%HCFd6Ln+(@qRFDb0bjVC(d|v*Uvzo4wO7FCY4tR{b<)%mXo6bYjtg*P-!F@7qS$p;92eKO*8te4eL?jYH8dJPD21*6otkRFY6&qbic@zgnUv}Q=WgPHb)nL{GUH-t{|?d65w;W zs46}hEb3XTJUD1WOOwKY#@)|k&ls$KV2Vv$iD^Di8Fy+-fG!_gCMrBdae9vKPd5#K zzS_|sJcSvl!_92-%1RbBr{p!NN@V|kdTYdFm2DR4ekm{n-a8QwfZ>s?CV~j*?`#oZ zqy&l__8u`9GP$yqD(3hebKo&x4de|+{>6FC=!5uR9ehI$?ejzg%vu+Z8D8Q5ibqwE zT;M07e;qpQG};5H4rt1Ersk+Qd39!nieV6+xU}IDlWNQ(dQATQg@~vd(FQ({W5{Qa zp!IgtQU3KM?ICtK*o52|{-ta_v+j!EG`EgAN7N$!kk&T~a=y7dZE8O^^YW8}=P6ZP zn0z5Gv8pb0fd48EzhTXT@&b?wv5{t-MH*^3wq(2P?k`WHbDSU8dr9{Y_nw{b+L{0e zvASZ&NOO-A$JgR2cRB1N)>`Q|zQas+^nykfopclxb^VbPwoTwC^z?Y`CbJl}@fI-P zI>1{;K*c2%U3r-bNbcb$7PAeCA3Eo?;SvWOShrUh-K|+qy+&pwbgg2`dK%Xf0D`Mh z-u&D}Ovo&WA)}Ct6UP^&?Nh}x!m4YX4e3D(dfQA zrg0JoE#vvk|7Ap8E0H$(DqVV>SpQ``A|KAEVmR|Ps(5WVW_vdy zM+kn#<75z~*sTuqu!_QDR6I+w7s!Cp%s;xACz^?R)wETm-a zNW`l-DWl&exyWzo7G{3sd(4P~02Up3%eR3mX`VOHV;ul%$gc8^rouQsArVVU`ubk2 z_!@%T9u=1S(exlMallO2%FFmmuTuD^Vk%&SAY``g{SeI| z0s@95BR>P>Y?Sa9_(eb;V$p#n*)T|7`dM6;jjN>=nRePXE9E`1N)%)n01Ia3Z>X!9#hy7QJ?~|Sb%yp!in##eRoQnR5bheCI?DTc_ zyGwh6#x<`Fro(_J?l4>0Qi%|osO*kbyxijnt@ABy3+}chy(iK zpIJk$freWou_H`Ask<(`p_qK}bim(WO{yHd+;4(3Woq&Q#~XC1zl0d)-R5s_nkE6> zc$v%aYygrg0MTK^(Xy<~INdu;FA_0jd8x4WXr09BrrDW-9YQaJvT87;c*o)BQkpV; zD45X2?SN4RGe6QvCBz6NJ4U~&ha(?#vYcnLeRx`B6!Z>DAs;`T?H2jtMTpkjsf7q=aOLQ7NKG*2@gpC(3Y#J51FzWe%tH? z+>`!P7RebSbZm~cWBWsiKP`xwJnzQr#tmL;x8%a|VJI82Mp)VkGolTJRodIp9HEL% zOF~peJL`OvF`ckO%%A&krmtA4%$aXhZdNzrAmh;Q6u@r4QPsABxji9ybYN{nOuGm7 z`|J}f6%H*HmIUu++5GXBpjmcFql&oC=$VBqjK&jpSD$Zun|YducF+A?VT_lx#FZ2F zlY!simfgv75Hv2Bg~9LI3s!fD`nSi+_-lHW?{Z)dT*Suk2pmQ1i+jCaQe1#^s5|9X z^%Nt#JkECObUA7zne3>+P3dD&2O;$jKmb|#yxu${e5bpN%e!Y$XOq_ImpT>oN9X*l+22=uk z+b6n80W1VOk_Z1mA{8;Oai04Ilu%{)^|5jkLY_ZiK=^TL7>$Y zs9HwzY9=|jTb+yFdyvVj3kUz3D5@IMCdWn63)1pbJ)5-i%_E|DO5dlN#dp#ZQ1RQ% zI1{8X+*-Ov(6*+7M9HFhCXC85wUyM&vI43YXF2*86wM5}cUEx>c24FJ%dyooitl(C zo43lQ#Q{_G&N$f_r5lMd_Tv$}Nb?NP)Bi+HTLsDw5%R0CeD|VlGhK`+1yAnjce7$? zw}-pTg&@COPywsN>T&ET8x~Qmu)S4}hvnGsok(5ncB5e(Iq+x3FPoM3rAtR}Y$w1{ zom((}t}mV{Q{~nDM`B(jh+i5O>3cEpn((_c6XL`*ssQfz&adFf_*#-KK2h;m4w8aR z)i%=Sf^X`_tnAE18<&GWhA(+$s#feV)N_P~U54%T=COy4iOwVoE-4QOUDO?A;Qe&8 zVu1}#v0aPxMAR%H?{0wFx-mnH8H5^zDwLw^q`P13XMY0^ilTN0gM-4r1N&&*!ZU1i zJ8dEN$_~ow;!Nv`mzk5o>P;o_94imYJ$sjPQU9iLs$-C4mXH#oSe*P94aOd+H95(g5K}@f=Pg1GPy<~3j0i5{0|I`w{)P@IKI3|46@5=W z%~A%ed1Ll92lj}KF;FRE9cV&J9Eq4aEN{U5`~j*q8Z#{@vxNhc-8?IbfP>O9t$$8% zc4E|>I)F6W?qw5!<(>Vab%+JDN}vu_LnD`k{J#j{e-5ldiS#U0XL%sLn7M&lym^j` z0a)UJau6EFM+uOfJrQ;l%C?Q-Ak~7~UE6F@MCtyP&9oeJV|<=?UV-O6wnVrW1n->j zcCthJslEavZy?qBx!&3|Pj-ri2D7I_D#`)V*sDO9Kq}?sz%qkTNu#3FIE2xNumvU# z40wte-pn9GZ1y&@Ac^Gz#j@Gv)mj(=*;@~X*V3wa?;W&R3Yvzcv@xrHLSQf&z1dFL z6XGZQpUduT4O`RF_w7lqkajRaAlwt{QdV(4pefs1ou|YPm zCcK<5xy8wV`|o1JnXEV-0P0>(3jr`?8?Ry4T?f)6>&yfX@0`dIdU?0w&v&wVdF9~k zd04w27Bqx24#?kT3*8mnGpDo_eMJu2^=Sb0MS!4}`e^ZH)BOi5 zmLSAO=ts{xwi28OmO3s?^n`D%9?CD!^-n8@yj7fpWD2AyBomu=c-|9_E~VkZLwn%9 z0<3i-!!LFjMtiX*<*pZRts^qxX)iHm25=@yZJIkK%9fEe-OuMl6H=)fRjmG_ESdG_ zbcO^{+xO?`9AYS}(GeqKGwBZUm?Na*-m6uOWSN|r?rUs&h}>)WwpL7mRZawqAE0>i z4WsHYupc{zx%*rmJ4ch$kS#Q_RpJD)-L>ioc)ZDcnc5Jhbz&XzQP3Fe!r1=fzr0#0KNdq=r`Uh!6|rsfmfXq@uMT?vct8Wnyuqb zi<%;tZ>XY`;DUJ?rCdoj!7tSzW z(5gX^Fr0icvRrYvI%FM+nro&SV8B$zx>cGq8~eEs?o)>P!H{t5bvdtU0_!yBUy<0* zbQ>DG1S8Lyw>ywZia)85gVmd_5}9402ptA;CUXe%^Ys6aMYY0L2$NPyR|oQ*l#C&v zRZ1d8srCf+bdI%&)`gk>H}DW6bUnkMAvZWcU*D`dR9J4K*cCkX17TGHg>+&C`N*y| z9QrjscDOJ0CO2#HF|ZLU7|+w{*n%or;EJD&SfqVH3Y2*YdFHYh0;fOaXsbDr(}q){ zuW=I~^=4=#*(L_eUNjqn$iedlJlV8wyx!P#7{7g+@?!Xvg42t7=e*r8^Wg5}d=)lX zniEMPdn}b@xo1e$Af2ZGY2(LrZVgWm2p`v!8tQH~3DQD#a`IHgt4hcm?4Z`j?4st? z06pEP@rW|yYiKf*ZFYD;1K14?_aD zd+8v4-&}$qSll%<{Na_pxvvCkGj;9)h)>5T#D)v=jaQfJ&})Q>*O+6Qf4kF@jAA3< z`@#Y;-ls*QsS)p!cZCy<+iZCT8VZJV37eQ@jE_}bRTG^iCmi@#-xtWvgA7xuhXTQN zFdqb0nEIQq9_2*4M(`hQ{X0%IRp-PXTha|YiIFH<(}>kg_| z)6@1~M>b~6yr@c*VlVcZKmOTM6!I}3wFAw7+PP1X@{gcPnE1xij&{L)ttF!7tevcxgd}LKs|Ivko zhWW_?EImWZFL0)CL2$4@u4!a$9f`L8H=sxn+mX^NhGxY-c)9n=a6@BSX{3pdFy z7Kmng+7Y}zqV=B6W=6A)fCtg8$gi>W=S8q1^ISEM!O_qC`fned_3-4Ixsv@NdlgnwVxg0sgk_mgB7&riu%FU5z%Atpc)Z+jNJ7ax;Mz?nR z_vQ+H6F#%xv55!3!kagOX%YO>t#0!IMB+jSi?nv*PKAVJmyciAKqu=92j9&Nd&<$8 zgQT0m#toedsoCLm>jT54Axg=Ni4M~ORo1a;ZDlPhso#PLUuBPMkDX#u9ly%K7Nu!9 zlSlyS_;b_EvztU8N@c6(YVGK3*{Cia>lhRqdinOB#&{!K4&%Tx)erS7oi9lNpkc{iXp~2x2R_s{zov<{p6 zu{usd_k62KFYFyGT=ox(Wbj%xK5$$)bJc6tYSgrlkgs#5%) zQwZuzL%6?GAm^yZRiEc{IUx)8s~91w?_UpJ_q=2(92P-?@0c2?gn=N7=Q->gPv8i| zGbax>NI6URkG5C$?FlvX%Qd8ZkQyvt^kfJUZiBsijV>)$-r|Iyt-(M#!8qM|_3Y== zeDt<{XQnIf=H6hc4QtT35NK6^BH?}DD!c7E`t$|an;U+x8{vrcxL0j`^bav|f*1_GS-5I(4k9-?3pOgh7oz@T; zxWNe#3>5kC9OMcE=X&maUeP6mclhaZF5q@?*ibt)uruFL()q;_HTA30IAJhHX2e(1 zk=I#J@z2rEkaK~QjFmFNGsQOsI>|JUkaMGYi(|u(7xNbZQ~lVFHMB-M)@k^>Q5(FK zQ3VUMudcJ>mz~$%D*qJKP$qD{Y{j6ME$^%Z(PXQV2DO>QUW5OrY(Xx}NEPV8&@V>cWuVk-%& zNRZ-u`s>$}P8W)l@_Ql|P7V(%+5q-hsQP**^9~WQt`6k#;anCpx``Y@G7S>cgjxC9?P${_J&R_080MhEUsipDzJs zh~rzqz=Q1f<=W~=^d{qn@QA+DWxIGXV!q6UXV&+_`s-)QjfM1LaZ&Kdx*f;UOE+xe z2JNrD6~pr8iy+e+XX^70Cr~%fRnr-aIU8vIWxVn+WB}ZAyR@#iL&>v_{E64S5qbYC z6xjvxGYq;2F4bIN^baHQrM|i)!)T>5k1hJP*_5szejeA$Bn3JNF{#B|D2T%89&;nB zbsG%hL-q|KKJ;0K_b|fSR}9J(`TN`#w>fykZ=-;CIOe2TyE1m&{(whSUZrK%l*j#m zq0%S2s$p(;=B>uK2OyBde+EgXuvNQf7$|ds&@S7nMW^$5C}IIURcu~=E7!pi#cjyi z+8wJ7LsB~grOT=Y(?*@KA{Y3m@gIY7Q}Wifx}!wnvrn+sVSS+}T(g&ID?>{FxXn_j z=vF=m#4#zU5gu97BOckj%-5bJW6TOILL%n^a=n;aC~#VLAy3ZBBW7eg1V^T1LXJO#*xUh)x!)?GZNsgIvf8> z&i^OpWBC9*K*GNju58;D^Y}T7mC54kiCjowpI+-qB|PtI2j|pYty0XzygL$%5m#%V zavDR?Z8A}wIwjuZ#V{gaCd*pN038lA3k~HUnR_k(=(3@JVnm3eh1aJI91>^3TdcKE z_?DdKJc=DQ|KH$+y-U$+eLe+CjP1ii>|x*yNbRlKAAF2}u91Y$%&df&ZFch-e4_kq zF%atgf2V`A{9p)J%TXBh)btXM;F=FMF90$36G_*zSILgk7_uyeoK9*Z0qb%o6yvoP zarysUeUZ`{PzaJr#`V)&Y%|x$(skBDz@ijMi&mRM<@R8P~vBc@t^%DAryyk zJTz@2%rLNK*M)+m2w08a0s&3yGs4i=OTlmjvt~Tgr6dbp^OO6#^ps_R**aev;$X%# z1Sa9jdkp3D)Vwls`^h-IB=T)Nc)34!s02j{rP3R^i5$=4kM6jUrEP1B{yTO0O%29? zNdH(OJ*}m8YK!d1cDAMviSmLPW6;vP4q)>eB`{u)=eRB~3I;mdRFpCFiAC(&@HJYw zw4w5cWj-MCp%|<4iaDnYGia>_8eA1m{j~eAwOTs^SU+em1^UFT9`-YmFNTVWCGN=~ zgOVhUjQRa}2F7go+5)CThkz!fAyx4l+GZW@JE8N{2=I4)LKEgjjIKRIl;kDD%};qx zoYfkxyx_moL%oyk+95s$Z*u=a7jxM1NzIj>Ss5QpPW<8Enwh*{Nla_7!h-DCyW+Y>O7O+*58J1Ag)EiR4oPC}LU0ex}#_zp1 zBYGH;<+jX3b?@WUy3D_)?>!n^#BCT8{JyvflOuC*9)6PtT9Rt?^g61y2N!~|QlUCz z6?ngj&egd19J%mP_CWLxPk0o_xcb8i=3ukV6t|14lhQKa4TcSn64cEON^RY$5br@W zjX@Druk3Tta+j3k3=Q%Uw~zIagB4|7P|Kido}x`&Q*rTFhW$26b_lbJxPNMMq9Xmu zXBGdll^#N^%S`vY;;oMQ<5CVi%JkRwy_ehLH_r1SXGPU`Wx2AA-wbV)r7#BDt<$A{dVtk^xr-k-99 zw-?Z4AjK+=*vbh&*4TA`D?$MBnUu$(w)R(4rsQKS|SI>hUN zx;aa6>|z*j6|gkQ4kcx<)N4f_PFLwJPJdIoviMUi71&;{Dq0G0@3QX$GrGcvXQD}W2~3-$;hDT5Ky@MlVA?h%~1`^35CvW3<8^07eHT zcL_iEFE?XjKYr2Hf}M4$@_-1XAE-5V;3(jutFSeOZ?_8io{`6ahaDTd9!WA5;>@I*)B77H56) zOZP+EeQ>H=oK#t_sv|XnkURC+(}bkSTacdX@(Nh83_a+iV)% z*>QOE*_^%*=*7dwD3KL^wmiS6n0`HP1@7=|2gtVXd!)xkN9hmGB7!sQD>+ zyr^=Wq>(VUBZfu*@n|)z>QsBJfu;3MGe}<;e8_3dV&{EIv4clTWbm|*IOW(~)J8ms z5`N3bhCl++nYIRFqB>TwQ@}Gkzq-y8R&UZ*f|QEEGJ08{Rd>C2Bh=3k^*Ziu3f(th zD#uHf^9kTyliMDw-zuaP#8}tcYXvV&ss=V4LZ%GXl79ZJIFu%>BY()CS?)8AG>|ss zw|hB)xWMlAX6U0A2cr#EN{Bztcl?_inHc|f{rs+9CEYl|Lla<-pn-?l&CXbqY_me| zeBCDg%QHsL?U?c%QzjU;l_Ruo$(htM z6nj1&fCpVk5Jr5S?A1=pbcrY7%$?)vSE#Mi(F*^7poVzmYM#n$>K!t2th8cTCV8V5 z6+9+z#k)%_*n$}!UCTi{ZWnsL_{A!15thf#QU!pS0lW0-%z;EHhjpq_`+Bp)zum#q zypjVYG#2;d!26Q=|IolhYAX>vD|Tl6ZxUGRv9Gv4_Smf&;Fz*E>;GdxC*4@n$os zt`@j*h$w2aP;=3Im1^aqP@%Nwxn|!Rkpmmqt}=3Lf#lFE54^Y7f8t-ChlM&BEQwAj z1rY`07dp!0%(UX9Qf@&G>;4w?qNzL{&B6KGeA^s|Q(-#}?!l+ug6HUi|9y7n4hTcR zHzFfqbE@Pa1bGJ3J(e@_j^@H0+NZxD5B25q>5Hc4%W|R^I`KCOapflUii&{;4ZIs0 z>kKMVf1NT4_iw>xXU)M8_pA!M+9lJu2n^+6GWvo^G^GhWc}3YOThFbpeakW?BxzHG zF^Koyw2bV|%S;(MO>uj50S@s+j zR9>krK1V?wxm|r4aUNF>CeAtK%IjtvpH42&@+TMxbXGDp(lzfUOk+V%75qg|v7WsD z|46~GJU>T{=tL6ZX~a^cf8^`Fr(-QNXQ~@h{8)8N&Rs_jcorhjEcQ>ZcU;&g0!+MOf%FQcQo%ySRH>` z`fP#jQw<7m14A7gvWY|-8z&!}O!Qi~9PaWjdXCRaD&wE%YYz9JqX0&b*ezkCdyYy% zLVZD!pM*U}wk_F073F7FC@|fW^>u*k2bP;xp-qIH8HBBv{|Wa8Y5jC1{4#s19f_ld z%$?$qu^k1!LvSjT49ZF-rT7r zV5ITD@r@$b3Gw+dKZ)N1{TAXeiq|d|zJaI#GbhjccDWc`!lJGleA#X_!R6Qk6s2L0o(Du)&De)9t^5^C~ zc6P14`}Ebf;_9jX!x`{Aj-U|%DKMC!<;RDbxtv=hkbC>nrx^?#I+6TWJ@hmjJ6g}< zNM1oJ!~h~P;_klSE}@E~6yerq_tmgRbrw`Bg|aezCi7po<>ROMjgKU3yC>=S`rGN~#tw=&tgCn2icPeiHh=Mu- zt?Y?N6aPS{Va2k0`Xb}Xm+0&5T+#`REj2JKwoBmB$%rcJUe15q$z$5R@;LF8z=DB2 zM}crhye!acST}+!#nn|9DO}M_F!>^mm!*w5pjiS*3Lzm+b$8oq5v0tp!p+mjx^|7VsGF=HPx%xw-ebSeJ&b9bnF!zO2EIOC9)a4;xaQqTQ6$!Z2yC z9|kzFt83QV-iT7VUMZ*wB4_3Pl5+?HrGzCzVEv7IZGM)>Y@2#q2+6uwvH8I?=Qp3Q*ns@a4VZKYd*v#}Cd?h9qgrBc^@}>j!hJ(xgu~{}J8PzEKLpmZ`x0%oTM*RZOLyzls#D4~C z=@$T)Yxw>Dz+sS@md;sALzNHCA*}V&6l(r21oUyYLmRU*L5kaTf#~`|LNNXms9`rM z2wUzA?CU0+GI1IetYH5j##Y1{aX)4M*#FSfWN~3|)%qogxk(sQ`r)5I+)0r6E&Yi$ znG#~w(h~HX8y5SI_d}Wi&jD%JKS0)3CI+O2^|ONdhmqv{&56+ZjWdDl&_>A2bAKF~oR= z>4mT(g5_lK@p@V7iub@Wge8*oQTpIrgVM{P0Lay54zT9MehXVz!VTAmM{UX2sI0pJ z#&l68ea`3DBC`4;qPMjWF?K9+5l>=X-v4)Uh3UKE%@o&C;TrzhULk}IJ&nBW8|vYo zeS)$bG-Q~OTlJM#S`)2y@auEDqW-undSue@h%8{&a!nZ^rgpc5w6Z%=&ECcyS;pIK zEtD(eg=yCa>}633ND8q4NE59%BP(>wv`8?9&S)u4dbl97#P{E7rd;j0gBhf2)azR_ zO-CF!dak3kM!Zj7idZEElqw89!$w9n*a>SSg*stobEzs>9V4!I4(JX% z-1R@McwT9Vs>iewEQqJ0<5ZtkGF{^BwQ{~HG+g715LVm`Qrs@+ngiGqO}c!Sm{D0>kFZaIUGL)vV<+`IDNne;*#ujyT09};M`v|J znMw2c`L<)Ojoh_$Y9X2e5KqzkZ^$XJup%t7JD8us=jh1+`uu#0M#w;&RpuX-8j!sQ z7xX;s4HJQd5UJS}ER}m%sxaOlWBuZM$V>XHusLV8Odw%b^OPtV%X%0~9vpxQrATkA z4lmDQ9s&W1Hs~`n40vOjr*}YB4|mn!xxhIV@)UT!T1Tvs}T ztnfg}UsDDrvVePZnpx16m*EOPhe}B}WvbPv523BvClzp7SqY6RLllxnjw0;?y>n=~ z695cOe;fyq<;qYv6(&{|$ngDlC3N9*mj$~qEESeXqr7F>%1-d92i;0{e?S?(T(Xlr zi`>$Vr!GYbYVM-3JU{x7*NW-LHC=<1FxEnV0lg?ZbmR}D*T!}hZ$8EL`&~D5wJ|1M zbsZ|f5)8lHo#7`9(zEkjP+BfiAnby5x_;l|B_Z>SNhsPq5z>6FK)kz zG$N@~LheL2E>NzRdk&kmKzw-@wY1oz+WU-?-!(=OydP(bU4ICJg6e}@wiPTlnAV*{ z^|WxyaL1}wUclwb!Ljo$eg5sz#v8D2kS1 zUU?WpDKW}Mk89Ck@Gc#&JpEtbqQt8FET4C(Gaf)SWDVlYasJ!8e7Jc(jD$Nx0C~FJ zK^BKzL?UmqlYejfhR}H0b_a5(*8g1Q@^$ha`^QDjDNGKcu3!3{Ov<`pPDXkGv(Q_W z#IhKPQ4)I}s5MVv_jxQ?SDT_os#qys#BT3jES|7A_9LsH;$xbs)L@cw0uT5c0~U=i z7R^j6hBc@%t=E27n~smv#+3(JX@$y_crD~9B1YjmZL;|!?T*ZPq5WIqIu13fgbti` z^(!Qr&nG}cE9|D&VLw34RZRwX1cjxSSHRB*fYOhN%ssQCo9X)o{7u;C3Io?S}FCu?Z;Gsc1SpSi*idT?E#U%hT zT8Gg`SZJ)8Doe7vDc}G6E?nMg`^iX)C#(yx%jLN1szO)f3oNw;a~8HNK=+GLOvxL- zeAe2?b!p0ac3BM@oaCli4hCoHrMpJM*O!dit1rb7AFwqyS|m`?$5+IE6~oE$^Ky4YETZ<36>|jk@ip1waCFOWx!sV=G;IA{0caWuO=ySfmFboM(oaazvk0sv%N%(uR3R z5WLtpT_kW4x7_QT`QmOqaM)ZX%N1MjYm#0Ww^T~GHgxbc>%v$d|GV3Q_Wj$O_$!X% zIJUL^IW*R^`AFKcx^CxvDW-oom8C|S`p=t3qanG88N<0{7M(lbL2PdsB=1B7uHi~R zP2u4{q$J5>igpV$*tb2gVx|EqYi8;J@KrvCsp$vULmTwsC3_)60TNmDhIZ1TrK0w1 zgY?ixM0EL(T4DM}qak!3-dbc00x^L-z_yR58@3@SU_38)N(x zq?C|U%pxFe_S;FQZdC(P^-L{FB}hlnPzc@Qqx+s`(h=NzuhE+}cpbZLT<8tvJ5YA> z4YTpi5Ss|aXTzeRlEL^w%6&2MJsYeJ4gWM4_M;?t{KzgKUhq@VPpM>6&({_w%u|cp<@A$G}9(U<( zk)^*b46}I!Hd}>tj#Z(EK*Y{KaAF3Bj*lL&zrF`bv2=C@JzLf!98=McF8gwWfBfJN=5i;NO6HBiVtmJ_&Mc6h~4n5TPG71WjogETFsglh%2#QfF=PrmBK%%V}ZPL;)BNgS@Pa-t78ag4xiEs?135-L`Z?7aO_Ulg+t48w3^9kVzsI z_sTe=Um=aH?Rm?v{?^dzbIh^XxI;h0ZQ)LYJjRx~rx2gHE>#`EK%hL?JOvGZTr>&} zLr60?x@jAzo1iM3b$J@Dfi#psDW&#ka&k&qLI%i8f=uGj9b3vS);Buwd?zZ>sPioli}ta#6v?eT z*kIX=VxrEt=vj%gW22Z9t-bM#top-rVjuiEBq8s(-_Jq%S-Y#2F8O&>AT7s8_)*I* z6(9)-EI6KrkAO=kc|{_`5(8kyrE>eMAhI7FQ!u3}Gmb@k?dHh8ld3E+%|P>MRW?H# zyY?dFCk(eS)=(-pA_ly&IJ8f^cb`L)dnn{iq`k#&4jQJlGEB+XlJq?Wkw%q;pWjk= zYMe7Kf5YPmxBL!K72eoeXkL?lz49(J3C!C9-J7cj%XoxO9Ml67W@)FsY>*c99oF{| z*8oCz)_PLb$V9@F$sU4qGLcsFt7)h0A8Cr4q%?yd zl=dm`srLuJW1IcycAphC%DN~?yj@=f5FGt3&SCJX8B6M|1$82v@5jK6Qw9519B~?d z>^CT#QR~!o<6Fj$>1O2fZ_%&`0CMGkaDRuBY1S)+3rVed&Fj4$s?{NlgH#XDM}r`K z$DV*+__uPA{AMDzb$2=wAygni~?cEa5sLr@%Fk_xlaL(a2{G;`GIqW}U&U0R& zSnE%~Qe@2p9AwIvq-<`&OkN~&Mr1j$MBluXKMh07s%c0zIxC=;?ZxfS9)h$n#W~bn zi;tve{DpmyWQKDYq&O7PdQ-$T^yS4^qcjozh!8#Eep2p%tX+HMk*g-aPJP+63SZn_ z(uZS9S8X;&DXybPlL}RDBwC;Mn~PnPov`)^<~aSP_323R!LB3QRyM$)SJ(bq4^1>vw!G}%q90gyJm~%2cX!xGUwD6#T=>Fl+yEZ&<&?TTj#EM&NGq0EkXFP6ToV`MU(KDo=_^DyaB$jwi z_+%6zUR6{TnYm|n>ZhCt>RBUZ5Q`p4Cm2vHK!r~~6u~`}!v0z^MD5fc#$F43;K$yR zQ0?2ljb56CIl`EC*{9r!TlaW@4jX9SxKBIn`E$}0k-5S5MZ4e>L@iF=y01-2%Bsv= zlG$FT1Pi!bN(Fkmu_OI%EL7m4Av2FVnOrcoFKHrang8t+UA38Vb!-SvgkW%GD_q4~ zwwE7Jnq)Sb-B~9S{X6zb3ois+3N8d|v*#P&XY)RY17Bd#8$``;N9nwXK4QRE~_LJ{578Ebr zW%EuEzH7#K{vsP>0w*~Yol?BEsQhoj#FN2?FqB`?{^>W}A%}SVb~$#eFbONPuqZG! zFGuBvRqA74TtZHAhRh@aK%%Lv^L$Q=%g4ljwx3Hh>c7i=OH~b7OwI-CzN{^QH zB=93mk+9L+6Xppush(qQ{lHYXU2l{idZnJ4SOJU@=iXBe`~6rsZR<1XyPDv=Zi?Dz zIsIYZmdydMoQK2yT;{^}P`iv_5hfEF$n7ynpsii3G@4m zUPE~U*s*-j1frVvUixCe8H6u;M~RjfJ7kaLe?`K43@c#cl*%bB^74ZxH+G1p0#gi3|Lf%T2;NVh@CEwaBl7hE_(8-X~!@0{WYw##F>&+{?d~7n3EwB_#olppnXQ)?dg` z-@~*G#r}Q^4m;!C^czDVEX?w;7$s;4NZ*O@l($3U7vliI4Ze9Ob*>~co8}V9ow@Ci zIoud?X2DI4h2Cj$HwEm$D+_hEdr<&NLCvEIp|Z{B@XJ2kgb=`mXnZ!>%S4XGX>B1A zWv*`u+IxB@yTHC7fr#x|PKK7(%{VyGZ@Z=G590Yz_aSc*>E4F&Y%2+&m=M6k zAqMxvBchj1$B|2!Dfmu`oG%egyn__eN+B${z`5S9cZ=QC0?F#O<||`}Ha;My$k@js z+!L}RV5}(#Eal9R*tmon3hc#CbUx}b71$GIC%THFe|F(*ebe~l!c{x+ETZy?7WV5a z0URThMPVs>gb8IltSj4lLb-9_FD%yg))5SZD+0oG0-d^MszMS$u^_3eLB|cHLrD_W zIe5)C;aIx#2ZoaXE8~HTiTuHadv>|xc-wBXtr(7_CPn3ja`;veL)<7JM$WJB%5Dkv zbL1=L(}IStOIeM(lD}QI&AO+}rY|4)ERiGurr057f*I3+R&bv_VKjkyy?p7lwAz)D zXjV(uf9viG21E6pC~l!zer=x4H~O5;wCwvBU};E!llw{q=$`PEfIR%_@;UgDhoX#? zt9kUk$~KZSUpcfrUk1=yW70qPS`d5qDEN%x#wx*~0-Dt>m4l-y?5Ab7mk@tKBrHoE zVDM7({o3Y`EtVz5jlqvbY!xvl3#Q+y`Bn$c@r22ekOs$BO(01m|E(f+$$B@I<{`gw z;LqYJV|g43GU@8PQY$O~?|rw>gqWZQb>Py~#-@_VC`puz43;BYkoNPKqPEFa3eJSD z>x2HV`-{>1*r7^?ug3_X1Tc7TC=Rm6OkMB)*7c&12Z($7m*vY~t}{ufFO)<>GL3-N z1M7Nr3>AhQtOS%ARk+!@wVS4t+$a@Pf8EVI{U6d296NfIgV$4{qx-i;9~T#y_UJAe1HXF& z#%wxY=kKmKYEbyzXY$6)Iu72ym(F$W!x56EYqy8)PdFPJqQ|P33H7?C669qBm72LC z@0TJA=|Ww2yw7=r7;V-NGwhSeGVt#yL!8GwcE#I41Me0T6a*5e(A8r~Lj#D65yp5G zQmcfG9fm(z_r=R3K`4aWh##(Qs_EHwsCBCfhvS$KR|DMWOP!~m&gV;T_oJac!es3n zM@DGy(gu3NF!~{|U;hNnDbu|w9GD^_2A^p3r6TZVFgsJG0eThzj_VubG=iBVTyrX- zUd{J)ZlY+a?ieIHR=z4jZg?G3Ef?i#7KBUBXVRnBfG-cdQ z5v4@x&J08*8ps=h^JmchS5&S+M=9AM>%)e2+i`843R4PAc=ZN%xqV zju*VpuzQ2>`KQDNYOk*E#tp3QR>$P!js2tT_SwqnG;8J;!qp|`Uy4nosY2<&;SYIW z|B(f^cXblHl&q$nYGR1o5#>VYi^L>+eR@PDzstb#X3Ty8g$=a7SnTB?0Al>DC%zz( z&fPM^74M9(ykB^JB4Y4H->u;~xy%cc_s2Dzn)aH?G8e=}G2iEdHiCrpM^VHJg9G3q zV+GvAKk|~OUhD+|yCa^IFQV^ekSAEkaoKg}B@=&>dj~DSx%{=$=LK%Tzk976+lTpm zjZ5-%T0v5Y5pk4Ud1V3m>;lm(` zDHS9ZQN-J8dJNKET_bzPXV`sN6;_j&YNDSok-$`gH`Um|dYfPZm4<3Xm!I;I=17X? z#e{s`d*^GaDa*g~E?xaU*yc(n>$Ps6WdWvT?v~feZ>!e~(`m!L>!wO>i#q2eY|R?! z+%f~Up7`Nc#P#GCZ*AGXsg4btG#};>n8DrwFcLOv9V^|yBr=?w=g7J!VUt;6x3_LL z4r~YL7cWBTotIHlZy@KOETqx)3ii{Us&6f<+5m6I6JK zyM%(yHInq$4C)<=KvJU?;KG4$50)-gS?Mku+H@y=z#QP;wDrS|c)+%!|1X8MR+!6F zQ(;Z$+QOD;Wj5mC@+KT`Gnzel#$CuIOy(>+C^rXhUS}_uvlvveu8@HfTUW{v-m~Be zDu`>Q&MOzBz2+hPrmO2ER|>tDJzjC6pAhe(s$0%gIe0!7wcJ-#&vfidKj0ejq%$1m zgL#k${hxC|0G+P&k&AZAP7^-vkoxYP1y5frmg}!)N?u##4r>+s?|)ReX{ZAkfcB^q zE^rjNUoE2+SW?HC?K%m3?yRM~51F)>0w@bdWGcBYe&Iyle)6PGbsIzn+B+}xM=tvV zW1?C6umiR*)zdlTVNb`Jw+|dA9Y9O&{&20!RPj3BiAGY+*x-$QMwRfark6F z&8bf30JFs#?qvyU1B2psXpL!e?NjvB&;dSz4sFN!=vmPJXGRy^C>%=7rmk67dKoC= z8+BKg)fYv9!p^>T+(_;BhsRNMKc%aZtBzMe7@~dWpLXIK9%m?dMytGpc_uwN?1=0D&u_)539A&19kqET)31sG zLM-ynJ7jP3)cBR%89#y?26YZuR?*{Q!fT6ITYZXBWn~%cA@ChDM;QJ$JmP)hs~Ofk z{}n@aG@7f@wI8GY>ZBvhW5>K`l~z1}p!qo6VS;nNjl60=Bt|W~)@+RraZ)kr=HhG& z4weL)HO1%C-Ih?CKe`=DAMLS0N^IOQxghEF9{idyGaP+p^it)>-O!Ei=<#Px1ZSNc z3KmG&%Fta7``6t`w^H*rpHA5Dz+#L;)|`e%Ke z_Qqn5kN4Ac5GW~JPz)@{DJgnMQ-u1Oz)|<3A*}B^!8G=oJo*VDM55Cn&4vxAP(CuI zWy=N2@!I}4KJ6NcZ4!G$X|I$vy^)-^AH(7jBC^TSBon(?{eO=(btKUuCzbg5%tmG%;xQI(NnWi0{~%j@yZLZ68E8D7v#GQ(k?Mte z*AZ>CfNh@KsM<>Who1W_hE$$|&h!G`5k4D%soY^;s!xAG2S#TLBlY>cRYTU7)I$B( zoe#r%lq}b?=8pGO)ZKhd#bDtNzs+dT4;()7q~*j9IRB#dFm5LW9}O<`k-O)f01L${ zt*MbSV&0SR^4*?wZ31|3AxJ@$E%4=zOpq#e)G zYENOOA%WSC5Qc!yGv7l5aDJKeusowYbndHX_3K4h#~-wI1&oFF?_~)EIM9uhFS@&4 zjT-O}lu`!WuYQ^tN`(gCNBJ+t6~0}dj@DFVYt8ira3>{j_Cu{r6!IjB&fw6Mia6tO zBpBvCkNegDb(aR)tNgzy7AdQrz30?Fk+d|uO?3#omp0&VBc*s~TEzt;2>QW$m{iz2 znF^4#*aa^k&!QoVfPb(tM4gRYR|c528PUlkg%<4J1a|8IQLMg$D)oA1$}`0J;B9R^ z9rDmT(stRWMbUwLB!8iCbZeebM&w-)KPLi2_oI@c$Dyc1edd(!hiedRKtD`F z$4lW2Rv)K|M2MeHJU*rXC)C3KC>zt5vhW4BjR5g~e36x))p3wNtK;T)p>|%v4>*$- z>$*yWsdFSe`4;p87k%)eXN_2bnz>(gsJxdni7Qq;s~r`!Wz)e~zf z$yu=%@JUAN3>TjgCAcw7AWRc&s>Or%Ym`c9Gu5Gdi! zzARnF@|vHXCkX%KXHI@_lU!(7mO~F5glkZixgF`U+8;RJSaVjN-SZH6z@;{_Gx*IQ z@dj|*76#UH%08`1t1S!~=y?gV6$V}$h%8?X)>9W3UCdz~;`W#TW(zt&@_3!=ZeBVy z1{KA{H8j$l0=y5w7jgvWzbTwT&uJCASMLGck~o|KlSB)z9R$S=enaBM4xf{Rg4BOr zGD9AH@4^Sv%ly7pE$qcZqs^k(ykS1{UZ2&!lEH-krh#x;l?A@wi$=#|_LN#d*Y{=} z)B^hBZfrq_SV^Y&wwmH0#H|hAG1|Rl`$F2A7<;Jyg1-I=Negimog(W*73SXjF)L&r zOCJ1O1i_L@B!MBvB{17OFSrwL$r;G2NY^+`Y9$_)iyhVGW}^|!Xua~Pi`uV0DY_V% zGtXJfCc;M1v%nkU(a!xz$NUXx96^^E<2DJ|7tf*FLfm4s!%#(hq();9+y-6zQjTp^ z1b@=sWm`T45j5r;^QenCvK2A*MhtwYEe=&(!AmUrnLwb1TCwb~wUCT_9ptF_xKKg5 zpjh?Wm-=NP1RDQj@-J}8zyvtHE-@;#1jjF|O!~VoFnyu!v$g1S={FUUVjPb7rIgB3 z9c7QsM3_n~_lMiujn*(Z-mVRrI3Z8&XLfQ|$!6t!1f@!YG%H8{1$3UXecV)9vunW9 zxZ#+x2sH_wl2T>u?+My#pUUUzYOT%mj1{neuf-Jer?2mF3v%-uswra?{HviO$L;8+ zu5VTjV9mITPcd}!Dlu^gJeEQ@c}8p|=7tS|g=k*X<>PeHEqkRDYA z94i|0Oe(oP5&q>S6K^!*g}7=_VmF9b|H*uAHM0 zp;ql_p-3fR$lqdc-2KzTc#pIXeA0Zd)MF?oh9fiKH;GKP6DoMG+k=Adv;67c0|Yt3 zS2Cg(GqX}|u0s|yp|g7PUQ{{L6<9ZA@3~Z{pR}urU@;dtd|24x5@L3b3$pCTMHe~z z93h@^+M>W=2f#z97hLfCvz}_%#WXuK-6r|>%n=^J3A?uDWrJgFN1%G4vnOcd!6`EJ zZs;KF!#E4^OodzRrElIb7=;sa{V@{#6MXS-n)`N@r0Wn)GI*57Tc+7pYK~n@UVWBr z@VuO75n|Mo8mW*CSjg}m=aP*L;GqrTXEK5Mdx0$AE6=T`-YNz-d9XVjusB19H0Fc* z6*G*=Q_TzUFtki zMZ{~ZSXRyLR>=?g)fsb<(|&j=?MAITuaJi*?Kln3x7W~mA*&yJRwS7%8ij78w{LX5 z1la&&L!Bd%W_@8~>JwbDiPKnjV0;ur5E)^?9~qYU(sA-U@u@cy}&oeC?l z0D3b}I#SfT)EqhZc7QR-npn1`?|v2!b>f1{%zW_B4iIOGRNA4))!GNU=Ia zZ@WM@Xl939+K<^x*x9Hdduk0Xjvu7aM_Oa)r8*1_Xfj1J#U~5ljxV$VpE?&e3H=>- z2x*H;d@5m)HmUz%sEP1hV6*ETyPBjrc0fJPPUJQlC!Lh_f58-^VhMtiIXBYrMK=S~(|{VvO|j=rM5&Bz z+#9?dcS&tB;BoAG`ATfcpq=ncP;e$y?c@|%MDxBz1nLHzzRn5#m*(Os4#BFbXd2V5 zE-!30xcYku1EU=~ay+XPcOWQ5lj)cfd;Qe}JlpBE*O_y9%qmRGYq3Z#Tw_<@E2jc_ z(&Yt@qr;@1-sX|JL!Co%NhwLq!{K@o%+>o2(i> zHshYt#kr8@Nh4-50w+all_-Oj@nc$GOXlf&%YkPkScXO;c-EkqZ~l82_y&93=tNk^*-8ve4T#VN*MOn783ttfm#%JTL!2*9_<|oyZ_HL15 zw^OAHF5STfq_IGh<~YuaaPWY$nguns_;bnU`M^GKLiA|IU5;jwmLg<6Qw>bmN;wUw z0lzx+AjHQPR!>F(v8ECX>8iOzpWiltY{|Ab^qgTx;->%+ zzUI-#4ZpxQ@9Yp#TB9R#Ns7L}7SubTW_UicAWS@E(JWK2+^zV-l#c3kkV^KHTa|Yo z{~bU)vCA8%wkz{Dp&^%6pg=59^ALo^LTR2Kk{01*W>1waf&v=!0CH_+Cr+8ut+(Fk zK7j!z!sKno4y9C^br`}88@;evN`rEVV%AJ8m&vJ!RRnS?e49~mNJ#NVitx&b%kbzL ztxwTu@?OnFMbi|kziz}fnQ^()C6LlD_Ly>7q5{TS0Kh{C85v4Jn8=XbFL%*H^1x~m z$N3Ccc$Fh`)_zH@T&YexJTF6NU8gB*Y_tHK-0=7AyAGE>6WrD26~`1c3P55uS_ckM zk7r%mHcPsurN(RhO}R`f#w^0)C7=K-lUxwMFaS2DEwjT{;A_=(F~c!tL{$CmBHN(# z6ruT;#u9ft|VUmMcBjjAfhJZ{6=I>=-iiTRFgjpv15WWjEzK;2Be5k3>?333?-Ju3Zt;I~AkJ z-4e+aM;jkAN7E>fx#}ne1Njg$A?%N-`E@_rrTeltZE!Gq(Yl&i5r*m9k5dW` z#3{GnhD0a;_`Mk4)DgJVJ}hL%1y0$P0GQp#2Uca@%Df?ZLGnf#vZx2ut?Xb1U@7B- zjqNE++xc|7YBDt%$DuA>x-oRCH~-wD`hl)L(4B$XELBgbPi}L}7wnAH zFMJ#q6Rrl0b5T01?fU>~HuBXKR6|ew+unPUWoEDWr$LJE((dr2l_~GZaRDy~{%Erz z8qLIc1(J28-#1mvwej7E*U7!QAwwyhf%|5u=1JR1UoG-NeKxF-WxY8`fG;=AF4QWb z^&lF~_m9006p%iS#a@}R&~F@}&1e9csqITNjj^m3Cb`C5h^V$li@-FHuA2AVURCV$ zK@zv_*Ob2GnDIKZc;C@Hp_~M4*6`7TQbyyCS^MWpt z*R@e_!RDalTXs`x)WjNgh3k=Q81|sE+vkkhRdQHQS_kA1wEg$9E(S5N_ zN1Y&xp{Mm$IxN~1KdMbk$=A}HvOc)ERb+#)2(->*V*V;vk>5XwXK@JhKT^xlGldUK ziF20_XB5x!;;OhLCc)*;?(;^KI@Zd|EU{r_fVr;U`ChMmw-9<-#G<)h@*ednrb*5h~BZsMxx#ou@I8CCLy??!;@!0KNMG+0|H?cY>IliN&&X)<4^(>l4$J3+K!z{Se+CamO;{ zf^8?b`p>(fw)R{jFtap3A)mmOqW*kRB}Xih<3i}1nyCR2`9OKTm$a_uI(VIQ z`J64F?548qjNtYLxWtamiy~Wo{j%t`U$6OEp^dJY$|48&&rbEL@;S+d>ANl&-xiNC zHVHj{GL#`z1;_bYfY-(dO@C%Jb5hz&pdcgY$l;gnwpw`b9mB6#6IeL7tG?RQ@g5kk z7c{QG3kqk3Nd<##spRpY(=$$>ogzt|ItIFm+(wz2pe67OIY|dN@o=ZhJ9r7u-{Phbo)%$nBdfX}CO2EitpXa(yy#@l{ES}OYeC5T)AO=1V8RR#FZV@N=@}-0xu4)-@QPRajzm?$6R%n6 z`!nt~0l-rdHp(m~gc@a$049F?^tpgNo zY=48wS-6j9Z&C%5{9V{H^Xa*5s*AIb$*?fM4I7~xuWc6keJMK_dB}GL$ni3hg9IK% zEJfXQsO(HF>4Fm5sbgLE4bp(QY$V@g?(vS)%FvR@liB=Nntf473aw~Z^9g))HG?7|mnDoS6>Z2k zGl1^9D6v@uKi$DDneuTELgK9BPJgZ)bxz@$y|V>G%h)Lcj}YTE98bvNy%NDc@2I^O z>a_FQI%Yd}jsd>b6dO_;XIEi{KKbsxqD2CX9r+Sa2~K!Skc}$HPQ!UI`j8Db06mY5 zEvR+qTq~ufwRKPRbz*5S2OpzJ0u8kOwcyUlNoir?)5Pqs00+EDkw^>dSpZ6Vc+Aet zfd_i2v%44^g%2-Cfd=W*?jCJ5Ki$v%@|Cffz{nEbhb$aRk(E^?LGN&HXuG>wK;}XCuBCQ0RoG@D93Vup@J&B>>S8o+ zfdgpk4A_pgdNL03;m8-VUOZrS(2@Wy6a$ZhBkIWh<|5C}7+mT@JIUWgkCuPn7M;qW z>VJ0xaxCUu)Ip^KR>5{*!|U4_=OKi$X=q*~IJ?t**CG=l{PPLR@dL_cSz^o!=J8_> zAX!NPg>pP0+XK_}pbLF`sNA;?XG!`s%S1S9wSc*i=2h58V1oI%<+HF0vy`b(Py%H( zhI$trZ9*zmP#X+81Mp(JpwvXF!bgtFGh(ZWj;Rj?8;N0`i@#*#hJ%KJI9$Gulfys{ z3iYz5Rd&IAQ1evpOBa}DnH$l%k0GwKlsKCjy7mhg+K8Oj{UmwmH4U$r4^c7e3JF@o zI$V_X2u1atQ7RV;-scG{H0KC!-j*2!vz{PJ_O>Fwe}ASJr#hyUC$ym^Vx3uBs^jwaA&h{*nW}M zs!4;x$m<(-RXCOwrjb1osYPp{Q*9X+RbH|k60W;_3yx7y=Xo{gzN6=d1?vaBS`Er- zRS=8~1>mQX_+5(uUb))%+$WEha&AmJI`TzwE*v8ZDv{{qu{QZ8Ba=5>%oaUdDC?Wd zo}~k*6E5d+e-Te0xl4Up=xz=d9J_VnGGT)!E(ie}}rYd%X`OQQqRmL}$*XU1z}W{%S=)3I*cH z`9+W4e`FGN7t^0~fnO$ohV8ur7m|!|JS|VSQpl0fy!b;=%078O2a*Z6Raj*K2R@V> zQ^8L4L9pe#-Pa1FK=26e0;Un3e)V_*5^~OoB*Z~8;ien$pc1vbx)Y{GY>V6RtyKo}?b7%{$4JX!Ig#D=GH8T_Z)UK^;_*aw0%p+@P zccCSsQ+DC@gi3c`aSjW&)Y;#K6Xsx*H#+!BM1{09r;l%EuPCO4i1*du$Cmj40cK)j zh(zouuF%7-Qk5NQf(tc##m>>yzlptF$RU*7c$pcZqnz%DgMFOIcFHlcW@ZmEMro$e z(s;zbd8ElYuqTV4@F(VTi{*OWTS|ltV=@!Vru~7Vi<=2Rl zsoXwzXevRE+K4FJ4hl+*H!VM7Kp_h(u(P*n00;K<6ljuoEk8EwB-z6ZSnqn%dl0L@kjou+p;`X)XV z5X~-n*QaeNAU7o!WDubYC4D6m$c3`luMv(=^JMIgd%bEzdi;FZ4zG$U!g&S5i*pJ{ z=NgCjr1P`bcgSrKitN%|(UnTxOsV}|MbkRH$^QdLf9yr*=H|j({55MM((A5nHt+`=)+Uc`Uo2{ zl~D*RZQTSak&GyB(MI;x1+}p|oEE(W zJOk&d4N;5;{^%?i2{ozeUE9!xs6q1coFst>j4yf`rU?dafPkqF#r+ZAvQ4Gr)HW_1 z{c5@FNm-QF^Uv#&b#g;I&n!8P$M|OrUy_2B8KZN)1~)$T@UE1j$P2x|N=Mnw=8Uxe!l!d+XHYgbKpaf!YkHk! z#-8YsBV6BZ5@Gt;38T$d`)jreRrBmN&;#RQ@(7ch{%>YJ6{qZoA6BhJI?2TdeBkD^ zK9`>#yOCq=KXoT8l`prx?odN|GfZNZ1}}Kd99e`XN(EOu?2p*|&`(#Cy&iWa5??-} zR`S(#!0@?fZQ4$6{44241CB%s1T}r`S<5%=w1E5X79V`T>-#Jxrs9Gssct-&5!O>x zHI0;W&)zT)sUKWXSL$D$WJpVAGt+$P-(dvq(CRCF-b7PxdHAP+)+hf`>rktDr&!vF za6Bq1#&@g4iQLL5%4m*om8g`+mZWU+@LamjPa`iKBujsLD&w=k=+Uj4w27G#0g$)` zaN$Af2e?F047KGLtR|7#ZxQZrtmpvN^bLsJOKm5vV(#~|{n2XsvdQ(dI6pZ`Su4HY zI(LyUvx})DyH4XdJ)*shz8?>iUVU%m;GP9Biq3(=whV1*6hj-_l@u4Z6Z+5b#LN3v zGjUd9&^-jidoUa~o9Tw9%(mRJ{h9YnccbtX(Lt$8gF8hqDF}xiy_`Qantx`sb=}4U zC>RImB1q`JSS$M+qF~ZC;fDoyU?qtS;)AAUk@C7EmAK{kBnW0&O0vnvodc{>ZR&FG zE@(37c6o|P+oRtiKt#0blp+HW-@Wc>DdsASsM1m1x;C|3MG&p5YL$Z5?qFWcwAZ=t zz#;&3EdX78*ohmZ^InG44ceg)A>Q)T4Eb-^D}iR*R?ILy0#ilZ#9GR$q?k;0rYB^? z&Xs5*VC$f##hT|_1j*pa<+lTk7kZ2 z30wlAqx%UZ-}=bh#2ts{(J(V|@5 zKn)Dt>D7mNat0!gKG?hAS84oK{P;n~X;A;L>oq(5aL}k!%VB}&oBTZNoj$iJ$4Mk1 zv9Vp$-3>92Pt=7yd2_?s;4m7TmstZuku3DJWj7(D#*QML_$a6MqG$E6b>k4{9V_y& zpK0hI&a^V(wo`KWcs4W&p_L>BZJq7_ggrv@+t=QeFrNA?hcg!I z{W8Pxtv6uoq;Ks**Y*a|pkcSrs$STt*Sg>ZHw)-XHJhX}@nWd^cHyO?HNk7~V+jp* zP0p|@UY?VkitI0a=n4sUMB(?eVm((sy1MqXl!>bOrxCd9((*@jL*s)}txSzM>@}q+ zWc|2&#o>#VuPN^uz*c^mFC_;pgEWvdQp%#exfsneUM(wx!G2vi%3$%q-DsGj9`;G@ zC7-HJtZn~mUlG}uOSA}(;8Mh9_=$)@R(R|$b4Bl438m)mNaZDl5CPN8{F-wv8u_Wk z8V~WHUf#JZZYLWA1!o!)71vW4LnrNraG(nqsl03g7z|2j3jJ&J>a9C$FvfTZ{2}Z8 z4@tA!K&^pJ`puT6oZQtOI+~BK5CrLh$_sZ`U1C#LcaE3zz$XgbjFFGP`n1l(TauSM z^gAy%g%)!-Qc7)M%dmQ3Z^< zS!9rNe%qL>nGJ~T84WVjb+|$C8)aHy1bKoc3*RkD4AoRILPc<(Vx3ggMP0!E60hKk zt)obAipo>+IYDkvuK_qhGU9x=3Qj6GU>ba$%@y?4vFE#WQ9mqp|8P@Ku%{Y3(l&Z` z1i4;HFM-N?nPVMRjaMU+o~A$_hn$~P`+mv#bEi`9Zxb8a8xBys0Ci=QY}9LGPw0Q( zlwR+fkw`wv5N@F^;`&{^vfIw zMTEQZy!no8%am^uA+6|=Pevz8%t3$LOEY(ENIB$B6 z@-i}Xmc{9(=o^6hs0Utf#OMpFyzv3s;G=0=H_*w!!qK8yxjzKwN=n7tET9sxN`Wo*j;FgWR3E?f&%Pp!duob*3KOq<@} zKv|~Dk_!^F=Dr%=j;$)#DMw}`d4NBybORxUBnYrQCN_GVlLud^~6URLq zZv|j99J?P!_6M};pY*qJbl&akb!Lyrwrh5#tWSKYUw&G%?HNfr$Oq+oe`^xj6A{}t zNFP4`bAPrm##@=0=oxt|0f!Z)xB&zTM$Atz5fB9jg8xWO%mRgyAOsG_+?x%6OY`7~ zPoj})90`E)F~u!Ek^jL1#(PbyT|tw$8=nR*%sZv91J@wAAqH_qvS74khd)Bz1 zlol7rE(~b^j*K6!sQ4Udg%0VDV%MdDXPNoRi79$Tux9oD>e|9sw46@z0s`cMmcmtB zg1){@U%b13Zo+~PwIW$N$Y#Qs)lG|cE*k|C*Q@9+%jQ?1EzCh9V14j;FdpgxdvVNK zVosFyTg@KB1!|p?ot0N?2Dn20`?L&w_*?8NekO*P9n^>(gG0JKB$&+wI4c)SACg#w&ofCHwE=!D7iK^48tx z(x0%1Q0Y%;D5r|5RI|@A8m$Q~@cZtVnF&km+XCZ6tGhE@|GWi8bqlO7blA_k`kS*F zzO;a;33o6A-vEW-z_nx-|9 zC?%xbMR*Cb4^hSs(=Nf@5#OzX`otL6qX_d<84oqVg!g!>GG(z3Fg#t7rc2f=DkO#_ z?sNW^-=bZop?;pi51W${a&B;)U6O!eMk2}F;hF&hzh@rc+0fHBn)GQT6B1s6R{FG#IEsspT~;!hi!A+JclUy*lcJM3`uM!wB#8tV}<-BlM})mCQVTCUN=t zM698QJyPxnbrHTpl|-WKZ15U}jdmB;$Pwb7HUSWLn8?h03hN2CcO6#A2E(}HbrrDy z>STj^xLYIj`^v$%W+8_9B5P`Vxrwe&H0zi;gEDop*m0nprw=*0b&jOjT+Oh*V`OHO zlvwKg)0Uy{7RO%n!{gwZdBlD>V$Ka3|Na8{I!Dnq9AHk<;%3&6^4u$T-5#bjH=;DH zO=GN^6=L)cmlDN{qXx8FRZwmr>l(t`dTiMyHgm<)h1b)U9*d6=Mpk`~g;xoOS#pzW zb_2b`!@g6N|DKB>&+_;!T=AcKclBrN7?rEy`NexCc1aly3|hS?vn1@9#Ch~%SY$-w zmQB>XA}~@64`|L$9c2Lkxa!VzhS2FsH!9`ow(ZnnT$FAZ^4V%!oDS)BbWX zA5`n^Z|`lv^udsaPcRp<%{D-)2uMqVj?(dhynbO}vE;uy zZ;$hF!X1rkYFCMGzZ5e5XLPuv%(lrZ5e&A`?s@SH_8k=PKMZu4YHOR8Cb76~+-NVw=tiqEyHW^gC%94rCq|(t z8IV(&aC8-m77casXZ8sT2dl$vUqe^Z#MA3LXP*BFFf_b5d4r&%@x3V_rTc!$miF71is<0B^MXZ-DoIV4pB}YjMweEbj0& z8atXapHCm>7;ZF0YvvQCYZbn)DYP^|@-}LP1b;zNMw>h~a92hoj7@F&`nsV+p1e!9 z{&xy3y-t+4*}=LsJc2vP^35+K+`57v%~43Glei2_4uY0nUB!`Qd>>=(A863qxW&+bTJsjpX z*pgAb89$N8R*q@a>khEI^5Rqv?G_+? z!I@4X1{^DOvJ0Q1;2TbA?ONRY?B;HVwNVah_^b6%zpp3GJkhS zcLu+P6i^ojK~jR4T7hR3ON@2A<*vd@Ik&GOA%J4$!lu{1w?aMLUonS1e*`$4Fwsg#ugc@W1 zyatK5S=T@oQHYW9NzK&hpAZuHO(3CNG-Xt>Hu zp}mESy;J_DcGl0t@RJ}b7KY;=IzQRSd1w}Y!X*iv&D$r7=nuZ~sHF5|& z#xP0EcpeM|O{JI_9|##3q+$o=n6x}uNYt!?^ZKiiQxeD^pXVB>{w!9HZ4@>xqqTu# z&s7yJfr1ha{ij@k^6*n|1;)6fwvC|O9mHYSITk7XIoK`zRE?A$b#3nv#&T@~elL88 z%ycc%?Y5*PDM6x0%66`I2)__gLC4K5RP-ShZJsdeRXvkZw55qFq-cJV6FEesA+z{g zy`PIDt5+5DFQs#Kd#uz>s;U`KJvoREIF&){Z;6&(3W`^5$2E#Vgo&~L zcn{NpIjh0Y;{}}YCw&KNkeT12sd6nuz8Q0Ucq$;hh{V<$O|XiOp+wNAKDqh%;>)LX zyU2Ae(Ss$d0odb+@<`=3zJ^ZvDf%FCY`Y&$+#AB*`%H+G66%4M`My7K1Ez5Tw_XF%qia`>H} z)1$e#BG1~?YN_3Dg%*p$iKAjX-aK+*d*`-9nnO9-an#m zZvzMx1Gw0WptG=u7hHGzW3>DsN(-=s1^l4F)1bLyStH(|i2!O5>2^_{egM^j{R0-I zniwl0hrOT32yZMfS=LS^v$(^I15$-{L{K=_HO+7~TyAC`K;^yp9!7@N2Q{PVyn(5JGC!>lgR(m~KY0_1InM~wog098^2JCo## zF;Q&TJurOv?;7R?mzXSj80dLN<>nYj#?1v5!Qhk_nb+(V+yo5N!BH@}FT)Z|0DDrw zZSk1B#?eSzuGhdK7koImy^CD+I}T6ieMoWFBQ?NtYQMy|$8@(--3me~9FR`)o(~0J z@IKv+#Vay0f9(exmx$A9(_yGA!pK3c?6N40GrzlJC|=<>Kj*w_PFzr#@Oiw>c*PT7 zm2^L^yGaDdkNk*2Bd=<{GDX!$#(hq((-cZOHp+?ffZTrHwn4Y6QR{!)h3_*{leq@L=mfRkAwJ_P z6B8p!XdBb_>1KggsU~t&(}2V=K%wg1)nA}hl)n*o%Q7>g3YVN=mgnd9)%|xczVi;|)+dp3 zh7T+Ls!Laf=^HNj1P;E`;-!Zn$uVxkPg*U`TWZRDLythp$||M0f-D+P$fyf{h$rw% zKi9wEP!#WaQsK>+rGLsKiT2(y+csJgzq{mIp$|Z)>Y$W_`5i@NG3zBn-|=u@@fxWM z)ns)1pG@|1VXF1;W^OlX(aq_kDs3-B_6)mO=Zz}(QTd8E?Uvzxq2%eJ5%QwjI1jiZ zW+>Qd_5Yj?=dngSB>&|lH2ReHt8J908Ck*1L(%)Z+^j|y?S^y10D@2x%p6U*1gceZ zJP~mE8&GdBd}!r@zGoX^mrbWJ2Op34;UXHcfFY+DzXTsk@<0bnK&a?b`WCfdn=!E1 zKOjY*XV>=}NO?RsH2qd;8^i}azF300jq3z8W*Ct_LccHJDd23ABJjDS!;}tRs;&)(mLU)u!i%*j2~p7_NC<1 z(0plfXterq^3{P0Ws6h(TjG@4PRd+-dHrM{gnQ=7r@7v;GiQ>Y+gLE3C9DH!th}t7RzHzhes#5!sV45i3k1ZK2Z|qP zN7Q%UgV~x|h;w!XIc-Fka!kdCN2SM9#zcT*YBt4~9O(G7J*R0dgMj|%ZYeHhTVev9 zYp+oF_mv(!U7QAjxzgb$Y}*RTPwHcN0Wup>GdW}6d;vz^!=*_e$4^Ry17ivnEBGJ2 zFV(kfYJ-2*QJ_HDrmSf(x+Yl$7wPcP#l8(jpgfsyi2<0q;H;&vp`bwu^TfFtQj7?mRcrf-~e=ANS0quTj z!1F`XDM?jYw&QjYqAI-`kdh1oKlLO%ldA+jZN11Y8pO2)p*?`fzBmJs@+uC5Q@B6l zbdmJ_@hbkkry7KM>Y75s98zB8!!!R>_`&b}hynsF5lR$gCw81D+(Q=Jo~z*${Lh@O z**WK?%3gj%XvJD=7>Bx6CXH;m?rbF}2S4QqbvLZd+@x6Puces$j_42m?9%oDfKY*f z8GTUdA9EY?-_(;^Keymr5D_^ZFpf4Jq8fJ;y>>8Eh~I6cS<%gK(B%|WKEKr=@@PGK zM4-axqDaC!o=1ZZ-!ft4V+OmB@(sPsFhR~Rf7edp=Vj@B)YKp%?f5XZo18L0yZ-_N5l z&JKzgy>E%ySvajss-Ameo;(@4+EiS08~AbRe{5SMu51vQ6Hc}27q4ifK@uCPcN;T? z2}>4dfCU?^&}?CwAdGJd!DAer6G&KZ!7#pvCHv=qGlhRsri5I7&!_{9lkmpLuchBK zSCxZr2v}E^b~#tckHf*FM+V?KA>IPs7PeT!R*k3fQ&tk&D|*&=es&e>0F>?{2%e z1eF^`{)=m*y^TmB8fRh%dfn03R_DO3h~l4CdJnfiAplAk(p+TsIB!9F}si>%}_xra;at$L&ir5 z=6Aaz7EE|DqJUx^x%FI$Pn+=0j!fcb6K%gJikbom)adFS5!!X{p}vXUoqHg{i%uW7 z9Z6&yf(V;QAIEV3pm#2I5T1@mYA*1hO~^6K=ASw~3VS zw{|k*%HMafKX0`eYOp>F`O)G*%4vD|Qf{-`(6^3a5=VxFI~4V}hK z41Vhs03Q7~IDd21(e?jz8FIvOGizP&+8Kv#lXC|#1URj~a#QU-Wr>4`4HETc0uHNR zHZ*J*GmQ}ekit&c)Uyt?T6`yebIY8MHgICOqoc^<_Pw@z|NnM` zH5fAlH>m{b;4~a#{))Z=9`calc&?)FB0AC^T}u@rOuOc6m!0&wKOvV1s>L9zycplQPzUp z)xugKV=yHdpE!}pOsRpzEu&qUD{9Wp;--b zDpohKKS#M8*@}*i71ZR|0^|z9kw5={+>vI9p(W4s5D4_)i18=X|MYaiJpy(jjM+ zWR%n+EpzVoAOK@I8!Ro#%@2G|B8Vrxc{!sHUv|Re>&g}UHB`2>ZA?g+?8D>=oS(7# zpx`a585X=3ABE}pd}Vjers%#2Ce_8Ux8L#rP~%7$_y&rvM`E$`$rF8C&dG4`15|GW0!ThQYvCZ{Vh$;0pX59-+yHQMEKfjYKP*0NOj_q!Cddlst#-*YAh%b21MYE0_+Dq{;Nn5b`iKlCMzcCz z)8i(X)%*P7?{%1yh8E-`6#d*sbuHk+e5-uE`=R72VhDL)?JIocq5Q^Dy3>y!;@2ey zx%ViuT9$Q+gnO3h7DWPy_~E-ld9rcdmpv9pyl6yKz*Eh7LF)-rESnmP#y20gos&}W z-LV1uXDWM`pBl?Sy=V$};LpnFW@xRQG;(v@lkDJs>l!MgIZhyo=l4T~TX|Oy;}*Uz zZx0Tw3m2g=Te9G0pt7h^y}m39tF|$x zQSRm){QHh;)h5ZdY>GEFz2au=*AWIcQp{+XB}Y;kFIr6^6zyuZjM$An&$W%-rxc0~ z!h6O^&}=FzS#G5cN`uI0YmUB-OwR=r%r#YXZq@foio5}hb5wom7{UPeVo$;fpyWyK zASWIq@8T~Kj8d9*iKtl2yOTaqTI0n2oB5s}F0%J9S;sf$?hFn$a=W}Kb~K@YuruwL zWxrNXW@o5U`;DyCaGw~Pd}6gt#`&Cw3%J^L;`f7kX)DRP3j}xNO^X)+spg*5e5AR7 z%B@SFTU1CYb>$(V16fh zmuT$$wmyO5?o7_vW|5klRERslh_8VBY)BoIUfj>}%3$OqY?5uwM4yxii0dY~l8Q)V zt~EJSH2H;2J{<6a0+vlG8B{zEQal}o@uG<7QH~m&s>}vOfVGE!xw_d%KcI@L`x=jz zS=s@uN{2(^P@gY@Z|zx+25p_3ogUMR?MdD@(6^g35Hl8*c4)fz3n=0{^j+RlJU)G0 zD-?YB%Y4T|D+r;#Q;gZeiJrEUr#J4dA#1O|Kua?+$^L18*OX@=5i}}q5AB|DxqMRb zoF~;Isy8=r{Fsm3vA+AO<{v{^yJrf%L^9ExBLdaCUtZXRL~(37_hqGjROPSsbujY$ z8|G6V>M7DD!TLcR`3SNS!?`%d?iusW&c#E@ee8{7I!UGYYcFmotHOzLBDgv;NYj&_ zMS+gj!LuYCkdfg-P;PSY7y0EvtV}%{czLSv(CCrKCSQCJK}v}t`JiGC85Ry@2aVS$i)fMwhj+`m>uvApV6?4{oBjW{10Xc~kKOZ{73KL zaMZ(kVsu!Ki!K++ip)H~*>g%FKX4b8U4>AWe-W5yhQ|Fm;yp|%Otboh10WYpO= zqd^o1juLJ{T)~L16aG#t#of~pF62p!hyx+lT59AbsN#*tmhEy%o_8CZp7JMfuh*JNZSvu z)=Cl2Gz>4A4;$(e5eQ97`*?qC3R27u2!u-@8a*Df)M_r6F;hp2!7-sxSiAL_fmJ!m z^>tK2X$R(D1ne!;e3o}`L2NmrCVZ_{S6F-qxYN>zHE{tD`8s-%4$gCF)?2DdF{{!mG(IU;*iHf8?r&cTN8k3(odD>^*H5V#&w@Cg z{po}xFDQb$!&CL*Hmw4Kh>Q~-OYXTELnwS9bM&~iYdtB2wJwz?%ck@a+<4z^xrI3Z;tA;{isf6Q87 z+e^?WBOxlzNIT95h#?7BFDT7gZvajMsQC=9<^cXzYv5>waRNtDOf^(Va@Aq+@X=RC zRm(5F)-KU!X;@}y$=qxY2*J=H+?m^j#c5F|;YOWpa7?-`42jV68x)KUmvp<|1?SXt zF9RQ;SdxS!*L`nPXe)k3m$eAPf2`^;bX9jvJwIv4!TS0r1wZ|yC)6edFJYdJN2Kn9-lhnnI zG}OYPG>1g_; zVk-Z|+2AvFu4ffH_U}89XZ!e4&t#WK{`c$Jb9|F!D8ZJ(49wOTx znyt%3p`-WP))c*R|1#fF(z!`Ydp@0Ku~o@65P+AkQPfUo4RO10?h?D%*1yXqC)BT^ zr71vo^LT5ONocT97!UbmeHl4ZFKq*rHr+8*Ejx5_f5+^vz+=-Cb$_89E7Mx}fAK6Q z+T(ql4_C5ZbT}lIj?+^!7 zfegemcanPEpg0M-`z5ruB5Y&H38 zAoWBdNUehiC9YLYL1dO7a!amaNuCmlpr7H0*EeFKRTTg&*LcLFN-=@;>vG=-#uYT^&&s&oLe9e)NBRWGw}+k&pqnh(YC!VAQ!ccHkP9nFM?&z(H_N(BGQ zd;`Hk4un6qB`k!_jly%;Jr-YCcs~ixzN0qP6CdlWpSG#OrcJEugG?$B9rOizt!b?G z2Qv5vLnlY#4?;S#T@fZ94SuXr>~D!RR|=#AXmvseO}ak?MVW=Anj>1#c?+)q!X4Nm zm>FxFX^IyBmp_@%4K!O_$5;Nq+Gz89z0#6;H{tr{G7@`eY0b>!BjZoJ0i~khZJpsa zTJ|{H8{^(;4;{L0mne1SW%t-cvzt_>kzcCUF zQ|&`*i@2P>7hpcxe2895(hsHUlS|47*+I9S$Of9 zgTVA7bnd6(gD5q)A84vQFW$fIL`^(@n;#l_0uTHvBk!7NxlccW!FyU8y0HJgB<;i~ zS&-%)PE7qKPUimDpDL`70rl&%%#v`wYg4{R0TTq;K43%utuyi(Y0ZE?=ehCecd z;D|NEwV2AL2np&g8gvj4hU#zzuT#Xi8+Ay&Wb9ubFF{wDGAEpzrC<}A!H!FVoI79kw&9_ZM#=^`+B8Yq+PMQSq8N5%x{}WOwqx*{;x5N%p8$(Ad(K@?m-;2=0 z6+5ByCxSC8n5EP-f}_bWZEGfb?(fj%{(OBk_?lYlgG}%^5Y{251|J%!*@MRiL!{_i zG$xs+#ZC{81N)NI$@V<>2V%z>qZT?+wOsYWye zRh=4q0jRS^?_7Eu8w+5MFd0{OkwXu zYa#brYyuFYY*xtarKkwU+=vhwf4gE*%k+=mP17{ReiSNDnAo2b!uYX%gOgIb2UvQN zdibm-BZpx$O~ZU6ZBRtI0!oFtEOPvmqZNh3Mg-hJ`l}C7EnlG<$ayB^E-A$u*_+jtAr`@Y|KT4ch%{{ok~){X`s2Csn|TwxuNMHL?Rb8 z>WMudS#e+o2>=~nU%-e1`fkXkYe7&EqdgwM>EX~a@dEITgFPMwsHHdhu!tO+ToYZD>Ssq#uzvitR!_Z0?z`(HN$Ab*LDzvljww%GnF^&%*Zo z@D$szW+Y2>>hgUV#r=^cEEq75FXMLlvhPxI%_TNEU&#|OLwYi-2e<$kMlq=CqDSdr ztkOt2{tkbP!O7F?5t=E%qHO_+NY@+oe$f(OjDMNmtH=`k0O^P3SX64rIF3lnef#^u z@B$KV934pp3dwR3Um-Gb5ZIQiA4_xc1ON9Lo?TSJY%}T9iAme!MEXZ97sK#fG4Nc2x>Tqa0u{LQ@dYSR2;m<(lkHNu|S!>#YAeNi~O&QLK#> zPe!D+9{2D2Od+#*v$!E?>TZCsW5CFv6q3!87z;~>xWjX?Fb$PiE?#Lb)G}%Y@_{0qCd<9 zhfdt)R0R%VvGE4QRj#n&2-iHftXMyH#rdmSIZhqL6?M!?y$@f2b|Hrdt8?()!*W|f z6b0PD^}-?09S1dL4d;vPq8aV3 zF7g@R_mW1S{$)aQE_f?*OnnxVW|324dFoc(s?P@OVFJTh9NUTy!pG}Nd+Q0q8Wrp3 z;YL>t>4@|aejh_Ok8~z~a3MXj5ODVA9>Eo&5x;$C%&XQ zr%j)fPMj_Q7TWj%B%2ct0pM$4%?UNi$SwaP^qTg!CNzz$0k;YbN|V8R zq^9p5Z3}C@cDRoVGA`)$3@S4}_w*5pUFPL5s`88&4I}nJE_-b_MVyE4P;#po`YMIV zn}>{Q)AdMD8{pt=)9^q@@ut1p+007)K;#feVHb#_>o(|-O1OfX%mKPdD@@)FlOZ&m zIbhO5IqO>pF)E-^{ZirTY}v?Xl|@9%=#~ojpu30=4YO?NtCF|L6uJP_|H`@Rdb-SM zE~2Ll&k#eQEY9ahEdAwKw$SY! z|LugowVFRkq3C(s_A8rGUPm*BbsbtYLpMM-{mTx;I)1o)4y(BV?ofjC+L4(=bC0+3%m_^$6&Y_%n{w)h& z0!a6X3p?s$J$qZkO&vwI)?U+HFDHL(&9U#@cAUr!O!N|>Y4mo8xu|Cf778Eff6DH0 zmQiMOik~^%_Db@g^~>OmI;+D&Sn{Vn#3t<5S*uBTzr3m9bGXs3__7Hn(as~4MHbziXTro&HG?Pm_Q0CKJcbY!6-E00luN7B`P zntl*zRk1gMI02WcX)Qhbum#CSFcSTl`O_<=Ox#+vU6nlv9(98Ock7|?uX znf>XXW4a&6fxIvLB{V)4F&~pi#@5y{#PQw~WD}uW^-@>re`^~W(mOwrEG+eYIpTHh z&`TY|fg)wNEG2VRkmvzKaM_3q++WjvXTjw9CY>T=F6>^IWNg!z86zrC&F;(pYR|5Z zpElrx(5~Ug`nMxYW$i^)ku^_Q9|&PM!HL(KWK`5ar)|m4WPGwg604seZf81zOuopm zH#d}nW9#dQG|qIW>dXLO<_QgdaJ76@^ zhjt!E4>GffzCFooIw}oh-SpC)3R2+?&6tmuLcZfX|Dq)b2k&-RFgm~A5U@^=fz$;b zO+Fi#YuPIQz?GA9OzmfVPjlG)!uK2SaKdx^@cg2k%Y-j{Ip_#dvkcw{2<9ovwoqho za0GO#6%yjYlP@m7oU5^=P$iwW4v7vA=LBf6Hc%`B`-nwa9;=?nTws7lVG*pq-AcOq zsWD^MQyzFwgcZmpm+$|~9FyR_%-+xs<7TtlC`Eyr3qgx-tqa2PzVC~ojeeoZQi}IL$XpvVe<%_*qjt1!E@j|3uvLYZC{zNGc zNmO)A!o>NNT-_x*pEhpSC(IqTLMj`86O)^o47~$H_0rUgiz5BiwM4sNq)em2IFmW2 zKe+M-;R|q?wdHV{@lLir<#KnBf0%b!)RSQaSnprTY&E1xEyqUWI4R6aMSg7Q8@QDkxyi+UIJaJNw6AjS>Sm<_ga_3ZnVvuBDNU~st z=d-N+Ta9`JOURN#c(1Dri^xrC_^^kEB|?Hc3%-WZAR$#iOa=Sc_KlQmSdUxAoVC4=QWxgz&_y;?H>k>z}hiDP4SAtc2 znImkC)ZoHAfcZJq_#xLLvBD_GY zuq6g|8i*M%pOY4&geTFw>%LwOc}44y%?x75g^;0Sm?t)Kl)3O$>2-kOYHK7Aho$lw zikkai@2$c;Bgy{;Np=1%Hzb+R2cXGT5;C;If`g)WB&wM)3<5PJb|@jY@m^b}@gB7D zOx`P^a8Zjl6cVqGS!ZDw!ua-+kZ!*|Q&=BdN2o^UKX0K1lG$c>aYysV4~n`zn+gxJ z5lN08+f=Ck<8e%G$vXMOQDvOMF+kaQAfF68XEI!E<@lY?{A%-uJy9B*Uxn!&<>Y!G zIL6l1_NTb#9HfkVp5>JB#)cxAu$uHiB)^A%(^arZVzJaBEVbVu0B(0(dkAUms5;iD z?vqjH(pX_(5i&f-#=<54udqf7Rl@H6P+I{Gysf`-EAFv0Sz-U(rufhhTp5! zDMQvAr7|7}tK!4hB1Tj+%y7d$b%Z&nVP%Bj9wBr&QylutuIqrMS&<3VzM9U^?i(fviNAH+e7$AHakBZn~L+)c; zfLye4RW){TGYLP_>=*s~1KXl6-n~xBN6wM<#Wy^TIjH|#<6R^+S*Lc^*7ZGi$1HJm zbkMK#b;x3UI%GVpKY^k~y>B#Z+`i9S}==*wPGFZ{7c_CP| zey(J;J#8SJUjz{ODglw@&O6S}Bf8Wl*FTh*e-p{X%N%jXoXt-L$_3gjx}|M0aLW%+ zq6hHn`?@x)J6-<5CPm#x$q=wK9*sXhir{kYXA=o}9?-odV2BLLlc)*YntJ zi|CS2$Dp2rD70hKp03j;x@2onrA6*nbO5(jNz9Q*U+b8WW`#;H+`O|sv30n2>*^|l zBtyToRP@I};~fnBSDJ%1WbTP?!8@?(eMCxQ?}k7QCLx6&=j?}^IXs*vszRM-WoKkN z)Lam5?o40Cfe@-NVDWgrpC_;zc#N6LYS%_9_YC0>cA#`JtBlB6(kQ;O-SL7@D6)16 zeEN{_T7!U<4~Dp=Y)GO0JN=fo8*EP*Rp-kW>=IWpWWFgem|7Lt#*aS0p=1<|XZ48{ zN}$oO_<{2HXuv(jw0zxDh#=uA@uA@NzzxX&*h*vMsrRSESl0Ghjv=fX(`Uix860le znK^fNjFBG%a7-++OOebMq}L}dH|>x`1ZbaY1$6o~q~ub^fsg^-xod|)?j%LsL4zJw zMs*AaOhCOoGsfJOZ~=}yPwBbERm%3BC`$o`V-&Yj;olcMJ^;&4Ge9(X@H+6U_D@EL zf{k*h=9mwn=95~#rk?~uybRbsuKJ%_BKr8&{ISAqPWFEsM)$HW`J;IjZqWNkg3M`( zlf8g(hVFubR?O&Fw$nQ;vwXK=;qXWPG)tPnoSfW6m^GB=rMnK>5c~!6>ZGPgsn4XG zNazDWc?Snm{iShV* zjypV6zf|3(O(5pt_C3%pR46+T(0m)>q5 zX`ln8FB(?8B}WW9++yG~Ihmt04-<0>q9id|_>yAT(hl8pdqllOOLyd+4Cr0b0O4-r zbkTka10Vm*sPvBDyRk$)eUp*VGvpzp?9Ni`wxRJSp5@6gk<&Xv??xa_&f8lu@g@}y zceaO{JsOqwXx*zuPb1v76;~{p=Fcz}A$3|g{iaPk-1loL)k_Iq+hp5(eAC7^y)@;v zr%=zV1n;dNRp-iOE|ovi6M7UCiH!feeHW3m90XNTsui21{w6CQlUuSzKN#x@@n}~1 zLBP>;k$5c}Cou!ub!h$`Ae z1@wcJS8aehS9|A-kGKvul~rzEcOsCeHtR(sMQ!?`IlS%lH2&v;KDC$Pc#IqM$le8o z8_ERY!@nlSdcYtc)&~%#F;HZ3Var@gW{m~S{L6kz5Ds`d9~4xc+_@KEhBo|@Ek2Me zP2J232+Ik+bqyIqbR;4&6l7-@ZDTSMdKf^JO(P|3;Da@<7202?Vy0b>uQ_39<`zkT zR=m?%6`amFLcfv$_=?> zKcCe;dY59eVH$^E%Ufo7dLqak#4P~BrBaqz1-r@olR_d z1|YRz0i-`8)G0=t+gbwF`tQ(bVk%{l^dY#7^|F{Q%-~X9%5EPJ)w;mvIe7>!X zqlov3A@0^;{eB0fy7k*0W?Z#0pjPdzDy>epN0n-yq5eWG$XM^T;tF)EBA@An+mHa2 z>GRahSWo)Euo|HRwWR!isbzO}+S{C#irAERO)%a2W8#eb8|#Y`ZibGoSrO8tN%8cM zS(JW1Z(QJH0Sr2_UK8uYa6hC$V*nPzv(Z}!tJE3@{^EYR`^o|TuDFD}X}zC&*!=1q zdGee|!soNDqW2s%&^90JC%0=xe>9d&_N$;Tcw!M6$7NU-lWG5xdeM~mk!i4qlsTv*O$uQhcMOufAiR zaBcDvw-@RNPUK7OL77zA^?l3YZxIxhseCrd)I>~<2j4@7ROeGnG4f*W9iYWvk#!RF z2<`Oder91D#}SE`K7y9YgF&%p`fHJ?O~S4 zzBkQz$mPik3I;@}s}-yWB)4(_kBFPbMFDR_@)5YS!`agoFM2~0tOiWQW;Kzs?c-2V zR(rl+h%2UMXBDt3k<9x-ol!kVBax+2O#l8;+l9L5HuG`#(T#v(J&b{ zgRLm<)q1K0=r?9s^+E`L9R@*e$Ro0q8DTiINtz}FLvwl<_uJW4pHGyT(CqEcB0D+% z3Ln=SzQl@IDB=7>MjjpveP?*8JctDQ<}(`+u*2_X0xD{*vo6KtEuYA%5Oor!Y%RtaVbP_vb;()#*Qod57^=gM z^fLHEY=twH$qZKJH3<}0mb_8-ZL1GxqCbv9nfCQyPU zKLY|WHTVi^G|%=t9{m%lX!Ox57bGu7=n1oa;4ZBu_v@g2dnn|lDmz| z0CVP^wIZ7Ezr*PKsGGbBi_e8-wypwzREa+D_g9p0w&FV?8AEIJ8^fgvItn+j;9uHe z!}BC(Kz3FsXH24MsENp)0{^#u`e(`U_xmoppl;w)Q+-%sdd*!WlQ|QW{CnNNC``Vf zghDclyezQB(k%o)mqPp}T!CZLA33~mbQwJuYOi>s`E~xwj~UdL{C)LFHwh5;xC56< zJ0tfRd}?3Vd0*-QCBYRd<7VRlZS^>HYM(e)5LY#z zk&xz@E8UdDHR^v!>!bWofNvl@HX9cG|NVGkRbMw2lw+5!p-gnkCF$VUjEw0Q92!eWW)p9QWlOJiaxxS zvh6*w%9crAK%x*`!zv{&5VViJ9!p)E)4E1)UUAgX8?2(zdC>#^7mfKj#I}_3zJlylMZcnHeG19YK*BZfd6TF!cs;{XRD-KDg-LyA@#3E}GGP$|XzD zM5o?_)(jDyz?V`;2RFwT8&4kH-G5jMt=78?>2`=HorNN&7gnJ;-2GxKPB*Y4L$N!k za!nPwchAc?;?I_gZV=HLog}ge<&_N7d$T=>RJP&<=6#$lmmkCu%%!8@S*j4ivnwtD z=J)G6<=FxL?Z`a!NP1Bk{zP?S<3wx`QtEE4`H>em66{YGcnDi8z$e(VZRWz;y2UHN zhe?=iy&ZI`4^}sg(C;g06*8u>B+f>^b^y`+~-9YGP zgPos8im3#HGduK$zNt;B54kD6UR)o#r)UZp=uS*!=!I8xoH+RQPY84)`Vj<8fGj93 zo2^kDp{V2OkLR{C)N?+wlu1fwNGb5{xIo2!rDovH4eVX3 zBkG~qdU(aAkV1SXT}fX-zBMC9@G$H218Xsk%8dGfBdE!am=36c5O$26eg*+SXPp?9 zL?uVR-kdfZ{(9rkgJ21|?nVv;qnD8^4VSgaEy$XX@@^+Ek{n-f+`|`oTRF~4tY7dC zU|v3vVyz%7CzeGn%u>~wwWy6Ue!SaJX#$Zn|0`|!^niW8p$^Pw_Q(+$FSiJ30c>_m zkVRH}(O^X>H$z|EUNrm-yCo9t&uP|~pYuw=i@gp+{i<_?7A1+! zY_u{=S=)?t!E8d343;EUn;dUKHNHqc|`Beooz8ASg+uR!d^9 zAzAqTvzz^$J!Z@t7L0|gJ@Es~ZwzUEEr1Dvi4O%1a>19NQPJDpA;tIS^eL*c$rD>6#0%SS3p&IBALjX=}Sew*m|H?FC5~xPI=Zm zQtyCmaFoFdO1$~hu5$kN67D_iiai*>30Nnp)lZsN;y3LGD3@ZDQcy3fsE^^XGIUD7&AZ>7=($7z^sYP}sSP_1QUF;oV%8!S?A)_zuBzzv~l z)kWmZ&UG%1-V-E$SE)acB!?%3C2h9f01?uebOO)OT#z()p54(afwRGzxj3qO>TO!R zZ=U=+D_3`zdP^An_u{*6&}` zzqV-koU0YG6JaW-W=UpFX+BEVfR|iTq$`#pWv+$Ip6eRC&MT#cB!cb)+l~Mlb5Zge z6JX7oBA!fde8s)&?ghBNlHzCY*6}~$0O8CY4oZSq#WcjAMKw$7q%fi*;W*Yr>9)6^ z6t)&EH(@9qD&rsdzdwhhQ#-YgsU|aMr;)e_O)~^mOCI+D&_fUfe88-aYL6d(S>rgA z4XNJ8)b4^^|fvM1^&Gk|B9m!I1c)g8~ zCi(;;DLrmQeXhj%A00~us>vmh!Zi&<_Yef#(6w46AmCbBFA%rjLh0}kLa-%E@fDIy zn;jbc(l0N!8j<~azJNCjXYU1a%Il|0qP1+eoIOUV_tpb4ref#DA1xA1+!q!ye{TyZ z;TGvP7o=ScltgQ`xtb1;?B?TA)d`gg5rKEOLjWR%xNMYrINlqkxW60Vu~)igY3k#1 zniS2^4^vUUykW@WZ2M58SPfut+@it$tY#yQW6@Ovqts-WaCqfL5rL`ELB$q+>7Bg| zKWtEqB0N!JLD8Z(yB$k_7j$0@2i2n4eq+T$K2t-(=`ZdJB_paf1oGM;as%IUv;1mV zbqljW@(|$JU4QZplb?Rtpr|BYma)5ACbY_O_Esr%W+6lBcf`TJJBX);hQ#9iUx9B5 zeG+(yLa;sI;cwuE^M+^Mn}L#bnjT>_DnX{0n=w&gunX?_P2t&xz;vPdO2<__VFx>V z5zs$LVy{|0gsIzFG*a$DuvjJL8se}Kz~DacgE0)b(=iW_>}CuqzTb;x`qJDt0MFjF z0Ls74eh#6y8x%-(olPi=#r<0!d$je9?<_yInkhzMIh8^|$i`di-eF~oMN^O9C?|$+$i{AD)L_M`ba+n~&5AoQ{xE8ny7NJoN=R6qiz?W71NC6ELOVZ9YoJ z;Kq}n{}!Ku(*$#w;T>P+A*SQ3KuEsAj&~zQd{t6xYzDLwBfu(ymRw$%yT&r|xC~mY zv2*b;TIdAFI41f3%_YZ^L+0YaPYsaX_D6I66BB@a#FE2Ka#SDXj~<4sgXUJIuI*TK z4};-8P@a3#+-)Z6BKEW%&K;$UWbDLe8!S^ZCvu0@E-G{{!{Wz|jSvhJ(e=lvhQdNu zcP6bToHUM>Tv~-ri>MC}3WA?`jQlOUF}SWh%tf4=ezm5M7-LH(j&)7SEjuv>S>*0g z9P&+As2Xa|C&t8QY4NR~CbWc))T<~4s(PdG2<&ADZWdt`6!Vv+BCjLBjHoCDXoJ%l zgJdN{8?S5Pd^GZ?2Fby{3q-4xU$}aq)@c&<*ci`0fj;dWlEJr1mt7OevKgOFmQqt8 z$DaX8poi?|mA;j`*hu8qH`oZU7gM-?J*ruxy^kw*5Jbfuens%T-R555S&GLrk` zdU~lc0<4$%M}pb40sx%b=Uu|H%><>cL+4vBOx6mN8%=( zQ63YTzz%tii%DG`1sXUcbZ+hgOn;37#ubB4<~)7zGuZl3rE zvU9%~ZJ>rl9I~YF=fr!-`NEsr8|e~n_`bg-%hEGoGNY&nW{wJ?pdJvn1(kw8KIgDv(H)6u`@h<0Detchfz}oUpFV^$gG|oBPcKIwy)Q4LuED1laJRkELE=-{ z7dc6VH`g;B_xa@on?XF;Gy2l%#NLnOP?JlW4$=*N*K57+^-1ne*^>`QMlDdIM@pE? z+2=@f%AS65@H0Pd%vzyirX(D!X@#jsg;!1AXYH{NKlw7P3~?9A%s>shu=!M)K!)kt zetNIc<-jr~k5%=&fzC&Ky*#(I>(R$n|H2KZgWH@kmfw&Q5fy)mYzSKuFrwR*HKpf1 z+pNe$#LJaQ8cmKze~@|nTrDb~!2+`SIuzyfEbWtJZxe=Y^R6W^lmE!gP~g#|>)78? z-2B88sv9lh63s9uwRsL5lT`UJ{!BXJPZp&A7DH{(5!MyMy3m3lD+!k`g2J~|shYeU z(@%05@a=wXm8zJP@OJd4bg^S6^ZV3tP(YICeo&hIAVGweOgxu=y)PrFKnir{tb2Yd zG{iW;AC;Bw38Tz3^`Y~FqAm;^l89rD-fx3sBnOqvu<2C^0xxFq2}%{H@j1x1_*)V3ifr{SspB!qI^vq~N32PtAPrKbhu}|Wa$cu^=G0_7?-h_6O{=hw+T2a`!b;= z9PVz{f#!_(60_Y27H*Rp#M^vNc0+k_#hR>G100=mQq{)Zu|u_e^hYe$vAAQc5wE6~)>fD3lav5vmIIP)8u|Zof=UE8Tcv`qQ z9_K-E&VJka$KK01t(Pn~1){^L_ZtCUqJQ+pgp&h-Df$U<@LxwIEGU*EVlN~IOsg14 zOkrrJ6_Zw#Lg8RsS>@SF@|@&_kfZ_XLL+*4Pz?__C5D;cw`se&w~usKemQk)*c%5+W2Y<4x+HYSnhvpkv9-Cp6J8_XDV2%c4!t2+vIZ#tN?c1dWWkhsOD=(%0Ws0*+0}k&HN^agYTR>)2ulC@#O; zVR)Xz=`kFh22Xgin~Nr+0xNd%`8UO7XKo#j<~J97Mim3BYBWkP?y_8U)bfLV0B}t% zy$r<{h-vP^e2|g2!6fnj>%(JFqatCh+aG#*3Glfgvh(G%j1zV|3;T$?VE%Jg$A2-1 z4t>nA6-K!)O;1`k#}Q-DW>740q)-~KP_5hPUA@uDiWN4)a*P1)|24$65_e8o&&VB+ zw!7VP7Hztbx`m9DjljXH7u2RZXN0}-w&Mk#nu3rKWbE`JzwiC)sJF*hWc&PbE904k zO>CFeXrw?IB~)c*2i*dBIL7x?ojEy)919)xj*~FoTw3%tHP~VHS{&9rVqO>Inv7HI zHDBG6YCCz(M_Nlwa1Dk>dIiZrWY}E@X2>p^>7JI&C+Y$%`+&Am`h!1lJyC$jzjf=E zzlDE0)d;R>pzWbTfbE5~ME+9w{h(zbw}`ole=TsNI>Gizrc>RV7^1O3HUQNEr%X9x zY;TcUBoScSX3(Omvbs=R+@|mVQW#1Z3^>TVJ~zz+WSrJ@1~Re~>jf z%CENBs~@P=0(s&J=I+j7N?d1Mkc+5|<87#JdVtNV$E=*Mk-p+Ei;(GPoc9l9R9e|} z%5WV#^qR)s`aYR$X{HbuF2WP(%q;WB)`?N?mO~K*9uCiAD1?)1Nx4SGOAZM?+$CRd zyG!Z%e-w5=-J)CeUv&4E+i6LVHc3dyWw5jsHRO(hww@k#Adz7;fFtm?Z{f;Ut$K=f zU!X`7iuMFm(Rn-s3h%l>-Gk!?xHqfbn?KqmM$udR!Ovyfl#^X9jw#G)L?&%Nkm5J`%!r@wx!) zIK0YFu@;jUC@OQS-LJpeLO+?@hX1{@nG>@`L29*4AimO9LNC!?u1v>(80H>Qprj!Q?1w5hi}RS^7-WC?fa zc|Zt=N7ORg0fd7$efKf(=EJ;1cL$p+)kbyF(0EeDlEyq< zDja{gmdnL$AB>hU!R-wFK~y}`ZCQ0g1Ql1bEvcwC541$XxX@fGw8JGv%)#ejf5Xte zo&rQ?^NDXJD%B14tOXo$3>`tzZ4;4MGcqJkZ&Y=#uq^V^!&qh#N9)D+ZkGE!u_@4L zn^r2SNivyA-vuAFHPSuoxTXz!S=j?8?-OW}pky!ySr-iddLV^uEygYoZtavFZg0D1FNwYe@%jJH)^t#yD)R8sV;tvYO z9j;OW8xoT0mCY6laq9)rl<4J)GGXneM!g^HJ_2lXw3<(Oi1v3)E%$XDs2%Qlq*kSx z(ecfTt8sh~VQ`~A^Y8yo z8!V3gNuWEkT1#-_tfVx|gcXpMlj<^p7{<4osAeQXhDnF`LVXh3XB=y}{AgO!_VyMa z%x$^EH`(q2?9%>5tDmppAZdtl^FcC$ZV3c=>sCleQFYUSFe0sMK_kd4O$XD% z0>2w8+^!<9tW@i-+r~wEYei$7pGkt@6h!UWT_7Vn<|!F1J9_17+ackJ7kgK`Uu(4S z$uz@YE%P<$KW4# z)a$EqmB8k6wf=qgjWYDh#tt{BA#Ox!joDDr9Jl3h#=$C{VLO4N>H-_+HobksPgE#` zpYoxs!bX@wZ$@mJbPMccDyvn*WSow#sZfMCQ-(M46!P=(rQeP(FjC5)AO~FV?PTal z7)U#(Ef*Q~B^Z9?mCabZf_k4sZD~&!gySVm=eev{Ycfrv;%Cq#oIv+iJruGJEy{fB zc{Yn!!)X1jWA;4aG*EzGD{FVF059vKF6KZKapV^I5L?)q1)E%PdL+}DizZi>jmfSe zpV(IOoORX^KK zT`>qLmkHpXJG~9}>AE?5Zl7g`e77PH(TGgy>1H0r9PrCg=(( z$sHxZe__VMq3+UOxsQ$9$n-&86A^~O7aBF2D$6S30HJTWpi3!j*p45pWeqtUe!;Ix zl-hz-zRCTV%IQc^un{OB^&l7D`NcPOZx@FS&DI+9HxE^t0@E<%pr$DGE`yg2jf8() zpManVC!8rk<3=t}VBiwd90&WGDbMDm_~G#NL!l~A){qnnXVl}4>!CN*nHji(b!9tB zIR1U(V&`wD+QI0+Tv^9^n^)CU($3gtGsz}g?+p>tuXAHv=( zGta;(Tkpi}_Ef`z4C%Y%=x@P<0RQ&5JWwY0bnaF(A+s0aPU2gLGYu{+(=j2t_xJ;^ zMNZJ0kt=}*317A7-s*Ksn_C?=4*8|SN(zGcfiynBIh6UQts>AD?Jc3Vy`u()2tGW4 zYHw7SlZuvbx-0mBq58fOxAS`~1ZUIMVF88BL`Hm|($eMUR7gBCPeBq>&ZQ6?DKp;R z>6t_`F-EHMQSiKDY+owXglm+mK_5Jws63Y=nZ7Y6{Os%sv?fDwV%c_q?~FF>m~3^^ z$-|*eE&j{&)cCU_rvwH$Z^s6uGyx&XH|~>#Nd4{Jn3lP_U4Xb4jugeVjCcCqI(*uO z-D=e&fV)8?5cTEpJYEPmH#L%jV{<0ik|2|)fyVjQ`k0}ScXlzSyK7H;KgDFI>>S*N zdg}0p&0p!!Ug*0i>bVR*F5JZiI{O1P^4=RXgua)mIKL@EZ_uzwOB5A7&d!Z+X&V#2z?{Qfa9O6P7%*N31(5+sFNww zKqf_bYLDTWAp*xo0G&#jdiQ?ELFUqoILabD*GPo%z^&%;Qc*WoO>p( zW-pVwN3JzRJ4qC+&ftmCmMj&e9cQXgN07<(#MP5n1|`7zFKDKNPN;6U61qN)86$c| zGl4Z#G>KLln}^xJO&7@wP+%^{KK^?M-bi3O*f#{zR|YX0GKz+ugTxFQ?08h-45UuF zWQa~WZ|JL<3Kl5>jWbfnx=0I!sM?W1>OhSrk%%$d5tosv=M4+Se|UW-TaY9f#_Wn+d~yI5;!mU+Tz~W23J8gSJIDE( z$qcL!5wU~$aYieR&d~?BDt7Q3T4v0pJy$0dYUz~rhG*mzbx7#%3RD!KKS5@tnh@ql zJJV2xpBA_RscDQ9bsUWxTobeKVfB0Vmoh3QT{nkOnpw8V=cq(;K(_kD-y-_ANhu#T zke0kXhC+n*OM;SIk~n$M*-WiPCfNvA;OG(hkk3Y@J&>{gEhrH>nyHvn`(k=IjM7GU zfP9{#o#g!#q|nmTMy-Ctag7)URfJxZm7W_ASxW>=wa2*58|9KIq6K}?wG$YlG04bM?VeX4u>EtpGIRGMDGF9!EL<|@UkB(PudA<<*kX`DUw@Uy) zK)%0t7c44}bSfI=dJhc>|H^wjeL7Nxx` zCD~Wkg8qVZdXveWs*tTCV%g%zB^!K!S>&vLWC+R#|MuBZ6dxCPOcbj@gGJ^9Rz#4U zkcJS<4K>B~3Y&6NSY*YHDBrsJW(a+HitPMs$Pq64jAWpn7OE&mQ1MoYM~z!*``%mbYj3UvZlBSE7l zz}N>7i$x3INhf$lt%$Bg(rd;d*z$*F_G_`{1sY|QvOZUsEbnm(@+@QC8b&CPwy-VL zX(2&Y0{_=5-Rjsz@bs3mS?9BQa@w4!qqdxvfw5v-^-()*%B?V#8!jfWyk11zKa-HU zP94T?s-NR+AYJI)2R;s>6s7Tryp$gS1RbO2#Vf_HOLuKL&dIXRWGt>zGy(F)2`7`O zpem=-2G!$w1AH-Kew!}>jTcSx3ttJpULapfrHZg)dTnnA3YC!`7`wn!E&f&`maWl4 z+=UA@4FHjMaPcgnQ9&^rkpm*U(Z`Vt0f2d05$Bs(UpE@}+`n>0H6`26`crRZAxe<0 z{&PyRkFz_efK=zOR{)|mUXMVZ9(?*T>3_upDWVKfa=4Hh0i2MtGGF19MgXD=lh1oK z`tnm=2A*dg8+Z%ct+3zMFU=#N60-QnonR2PC3t#w($*Yxafe2tfV)H)ZK6Ivne}wd z1F>@Bs^vMj6naYPcCs-HNQL%0cGFKse8dmU7fx(_ur!Yz{Iwb);PCambBk)L4c_mbw@keCZ8S`GJ{)heP3Mbt+!!J9++nM-H!RUGC>NWXE z>{0Tij4sUC@$)h|d8xD#*t!)o$GFh#ht%FE)|g=cMh-72S$v+sP}ZAIV0!*s_?N#$C%nquweIr0+*9fuYN2l z5y`Gn6h=Ka5yAWGhKelfl^chO!n*Q#E|Bd!BD#g()2|2r2|dJwFUg_UdfrbMPLNGJ zMrM;=7yyAdo!g}Dyts`us;;M?q)qBLBZ%7tSjHTqoVDLq;PBpa`9B$uIxejNxtHH^ ziX^U&F_L2K8mn2X(507C^Q(p;a{x|Fp!LNP@KyPRy8&9;RX>{=%b`Y%U$SlM*tZB8 z_ex=u{%Q*i0wEHH#FrO(u=ez!<{B+5&kSmBgm; zKrG8d2AYDPCb72I`Xt=Qjuj+mDn8(9nU49d=kXGbpRXA()_w`~tO*OUs0*cO34a9U za>N&$H+iVY^x_j(U0*(QQ7&vBx8(RMk)Nan(am%Z4+-U z()jT;EaRt!Qic?S3V*$_u0Bx!d3S9*D%;z(zgb#rEbFEoP8K;o=>`Bykx#VjS2IKK4@IwgpSYBk6P4LvVVOlX zRBf2VKZuIAB!S6S{T6M(!g>UbPWun`3Rx$_NGVDEW$I%uB(mZ6nG5m@OZwf!`Yq(; z??7Qjs*4y4u@|*-LFi_BGWfQl4285EKBv>H&er$9iYd_>d67>^b9WKF z__yA?9Bys#;P;osWw>P*rBXVyIIL_1K$V5ua}zL+{fq0CH5dl>Nbw?J5qVFC2KaCb z??|v#g*DeFDiGTDj&mWzy)1JlA40W2>;I0~A`Vhyxk?}jwM)wv%#*rL7MiM#Z zk1_*KNn1+Uw48lre^R^gSbsT-$RrR#%;>nTZ5&{gF|r8adG8Y zTd!_ZoCa>EZl$|ef=-RMn5nS4xz_@u!KKfY>yJvdI1W47a*_)2Mo(cwRz(h)fbrxJ zE+#vJ=-E>!C89#?);*redb(gF(Y`E@zdq=%1T>Ejl!`*w#7J!26{O$Po6*ckF~JL!-o`4N(fGg}!ts zWeO&$b!k-+SBHCeGy|ezZo~; zM|tof>lloCXwV)(g{Eu;t+>5%M$Z>gRxxF=xH{-p<%s1{5V}IXe0wJRvzV&UpE`(@ zfn;|MxPvdQYW8RggTvpg1r&q~Y}q zrizJwQlf@+lFjjwms*;LUMTos4hY3tZAwXxz~m{>7c0*+ZlKpgUz&;3iYt0_LSBwi zp}R58$-yb3_tWw%nO4%s%_qSiRJlL3Coz2(p^BSuzPPr&y>a9fNu=MY#$@3f^?Zi3 zGuvU-ry!tiOgG_VhnL=TN{H#7$_N;MM-ude46lHGb!?8oJ&zF}hsUN$_g~h{*F;FT z1jSJ_+9D+SDokQZX$I!xKaQVU+tm;+&zKZME*bsrQn#RY3gT3dLi&1|r=O}UzU+vy z{ezKR`z)MG5@2c{fcH*(o$C{do|P90{ja#DsnQFeExTLK)lMOnY3saFl;N9VP)n3& zC3A<*MHw`&kE+O;5)G2kItyV-ehK>K$b6iGZkYZ*0LoqZVyp0$Chx-b!eQrrWKK1O z2QSQ{wXkJqm=|E;2~;sJtMG^XL=>vt*~i`Ow*(&rRyB;8J=sK=Z<7t1u46orA%`JV zMxoTGlb_6>8J}rd+^&c==Or(fUXN!C4xiJFZWHXS%PyqA$l^ft2qN_mPTlzz>>lW9 zjLSX5D6@PG6qUnoj2>@=$d!pknotgMI!Z~I@73O>>WAUSpuV7vMPsV+x(ZxIRDsB| zOITk13fRahI0`oFtgs|AFC^qch}kcV@5`edy+~?TTm4ykxVtUd+{>qrubDb%g8ndA zy2-iOG*_MTL!R#NR~ip=9>%BBYDlEvGDKO<0ybBNg=I`bM(0t;fQI@+x!RZ=2tg3G zDgFp1P%K;={UgD2@`|i$s8o-}bXT0)(1jz|Ov?AmiO{8Vibrx0Mv6Z{wXvJDB5fQ! zdQNDviPuJuQow_H!GVzv-wq>$Dz<@msq}7isqERq6g|C_%AZUvbcB_uQ2whI$fMj22`n zYmfH~^62BF{KmuVS3BG+#fqn`@}n7NYUR*~*HKXld-vKmtMsQ<`N1(lo0|Czv_>bU zxaTy3q6%8Ui5hTDT%ItM_d_2yA`lTp<}j4W>HVkRGiZ6EeHZW6`5NVq70U&~ulNqp z>$>jm`x@HM*M1DxD8`5q&CIRAfec$}L`vqmuhm)sqSQJg@7MSsi~FDqF=(5N1teKZ z_^6lsgSVV|oCusYanzm0SG2p5ax+C~VnHOc&v)si(K+G~5C-bdaM zojJ%IC4t@3ZS(+tHQaJSF41U8&GjB^hU-qVq15Zmz5pz}2VzC`gA-{lz|^md;ugyt zvokb?kpu|*y;$o;mo_=GCaCcXpto4(k_ju>=alp^~V~`a& zaw&%mYHaR|;(vZJTE=n_EJpAP07X44vz7)w9~)Wf>KC_bf(nL@i-)x$51n%JNeT*q z;e?1XQS6ydtt&>l2}*{A#wn`Ct>&%I4-84R8OF<}l6UFP$!#cMjx47r;sxnAFpAsLee4pwqBDFJ5F*j) zYpuSC;eKKC1=rshGozpCg1pe%u)@wqJj9(J@UCj)xNoPZRy`rS7bun>p#2MPU3A_K z;!z+bKY#hAl+JtR)0^Z~1wC>DlSfCz)zH;4AYvO((t3r~d7`@@o;ppl(rb58V5M#pGb0GgpY-aQP}k7gQM zlMW#fzyL}GXf3wfIpXvt-GEzEucrR_csA&E@ixQJ$QnkrDKfrm#u-@TJ}br=((056 z3y8zs1?&rAYwPoGQMS$yF4%?ZXq4szG0;VR-kEgR|2vWN<(Zbs&)F9xwE31IG@bF* zj4?p%HvY`6%q~Yt-}b$PuRK}*6q}P)am97Bz&qJS_c$vRM;j zcNweyKUYdxtcE0Xvy(EXjds^AQrAc282JdEGkWd)0K()V+kAbJ6J6EqV;?&`#Hv2e zXmnFw-G}+>BTIV4UXt*J0 zy1q9mN{)|Nu80BtlRY%l#=GrqpCAE+3dUPneN@;DK8gqhR9zz2d;9?`sX~*x7M7g;K45 z&Nr?*p#2QceeCeHscDbCvOUOAca7!~sHzu5`g~2w@Y?Zid`J1Uu4+qHCZ~^?Ytbi~ z9|y5Wg5?SMt9d|Lqs1Bm)XOFWSwNs!ztPi0#H;nSynIL zMsSf6=)^%OGff65wy_C8aJyR%D39o$`|g_?&#n>3{VRof&oqztOk+dcwCgVSwF_5R9U{T5(stx-zAfYSE< zRiYd^2tRoVNtpeC0OLHlesylB42PN3?jx|s_9@+tXQDG0@$&wAz%r7F5RZM8mi2Yb zQS%IMxTzA0fu8^#?!(8+hqW)al<&=_LLTlch2JFBkq9rhlr8hZ@NhTe*%2UHaBx+8fSmTB3pli@+$X-S!O)R(VQM&Sot~fN zaW{x8c1*BPTLi2g)yo*iH*R6k|B$T*lw+~Ate?hr9}0OAVXCAuJ z#)S)x-B!8&{UH!wSiHh*(R+VUH;>KtL%Mh>oVc0}C!L!kpJ!YwpvJ60fs0`*WNJ(= z)>Mz$i^%J2%B$Rw1Qe5YqHtm%{z^38_RwL}H=&V1?%CvSR56k{Fg#kV^KM3@k=%>J zK5e#d+PkH~*68&$_-Hoz9ZkT`hH3Jk6mcz3cA-3Ti5X7|*X*u{x{3uBrg_SBx+Vs$|!q%(58xcqy+ zyfK`7kFAe?i|tL_zqPJmmMG-(_SA+=eDvn-pi`^rB2Cf(_X*)_#6QB|=}h8(hGD=l z$kP=f1y<>SC^R)@^uz-p@WgTY*CImF zpM$ioE=GClVwu^Nv+ksi=oNx^NvP;?7VeW){A%y9EUA{BzQnzIgl|3D1n=K8oMiL# zKeXvVn)m}T1|(Y_rKZ3PkdZ<|!^#s@+=jk7!czq3gI?)lbw|jVh~_vjxb5MKURVHM zulL4|9@Y6smmj+7f<%XfI-CTj@0!M?yRnXWL$1MuqXioY0VI7<8}ALViJFRS3Ih;s z$B$ve3~UP_@TW|7euc)C@X?+G?tgBjWsJ)MhhFohbjI!(YVTjMU|z&nDQsgs-X4U| zd-pvU6EqvOea0zHJ_%@l)`=mCE4<{ecel9NfNVmBCtLe8X=5-Qg@m0AdhCEocY}nk zEk<_loolWLr@_oRb|>-Cip-%HW%lLI@5^k&b(et`!%Pg)(2CkH(Yi{X_R@U=WS7t9 z!b!BhVUYKgaW^@5!c0dgv^$1TWp^%Ypx*?3%D7TB6lB2O|Dm*pYYus@1Y@a;vVx_@ z$mf#|d9SAv>=W*YWo7q@M?}%&9SLb_F@9!e@@H3~bfhk1sH(3aX!#xmktT;1zq zQf|u>8L8q^74ucao_NO5(U`G zjwKi(>lP(B}z0s3V6TD|^j+2H%plpoeKR17`sC68QoB8TcaPqukOSB;ybA^Q9`d zYSaZ&#sN@;lFe=}G9|I|zxr_kNBx!AH(2pMIBRWHdwU9MEOMhUu%YX-ueeM8F(c?l zuxQ|TuOc$- zFO|I)Fe+#^4u78Q8eD0p)70oX|3|ie!6ex56BmJUnWx%)RQ*TE%d1iHta)cPDkbde zqQMezJ*5*mk!^!W_oE*;{H+F;vnGWlc_>KH_OwF!VBHZ&U_Qc_d`f`?%e3?h**Y^LHg0gTr@NX_|E0C+e-~|(%4R>wTzR< z7P%o-=1MV=Ek6d|a}^O|e@Qc|D`IEDNV)$rpKx+~3bnVevvWlijsj{oq=_4IFnc@S47> z5)|}BMQ56SsQY_GNFQZOdy$t}-2+ zO>luiU?aL3hZJOC-OBNOp=ojTi>c&2{*+6FAV-qM+ImDBB8UNIv6sJ(dF-dRfEvk+ z%%B%utPZWxTKP3Y8c1bs+I9^=WET${lJ|=P&4`N^->t16e}f*JIO71I1LhHUGhQcK zcB?sOXG5HxA(^UO_UOYyc7Zh1=Em7BWg<->r3sU6shhGaMINgztJzT`J|(|b>|maS zH)mAIS+QKt@;m?!+Zsrfu*WRf&35?HUw#(xtK_sU^$|7~l0__5qvsh<5-ZCGy&(m& zz_uTjs&gFF(OmN7JqX_|IKZ4d=mXj_(=*IA%~5WrcL$6KjaWwS@uRGn`&+^LP0hlj zB^t{QWBV+LmBTcLwmI zvZ>MqNFicC)@fkq5o7FB(MG ziLH|SyR;DDg}RW#B0kW8L_18%gaXhseDJx5P*-vSIfZO|&vf;@fPD(mroA;fTSB{n zgkb*;68}dU3%azT8hiQZBcjj>NgSnr=~2GPs2FtZ-w6Z736(Su;aG;=R5dGSVJbx1 zr06-K$q*S)j2))yF;tCN!B2x;4YogDH9dX}J_Tk=^m-9RzGJM+nc)qlDE<(xQqX3J z0}8H%Q*tW@MymR?BP)90u@7D~K&yPDxiv_kQ@u3y-HdkHMEkqmC|ZLy*4Z!U=&t5c z20~#(e3I!iXk-ZjXDP;@0;R=$1#AuHdjLB>fflOSZRj)9P0S^|s11)!xk9MfGi+CN zs>A?r>H~2?$SlIP)zC=M!y=^cr2bijBjE+lVrCagel&%=nHb_?9%81N6OR39%9G@% zd9*l5z@_of!qjoaMV#2+Z1VasZJMDGw9f?g_o-erTj~A;e zf{jR_Ls7D4uQFWW_&ZYUHa*nUHN(p#_(T5{n}~M$9AHk+dgbPrAp!G4MZS&`7>^DK zMUh12psjt$g&xvna|17NUyvkinjfV0)pz;YC6BOjp)U>Q`4Gqr${v zs=1^dm-#SwNlJS`71wO?f3?MD{~C{SwrksR1Oz*`qMm@mZYW}$tRDax@uJyMQ?W*yUUcFcvkvT`%*ff?Iu1R8-lV%<@| zlWW9iOVBad`=(Xw$lya$#$(l7pe>k3DJZlp54%PobM%AN6g8iPfku zI)mO%&Q5kK;LR4+kpDZ;t|Z+dUDb@&g*0Yl{#>4{Pg~7f1l$Y#;TgA_d}Goqe)np9$ff{nhG$o@ErEX(Zwb zfzZ9!z+P$-6su;_C&HEvRkK>ZIrt=emq@MJrRfMX_nITe30AkX(QC19!Uq#T?vK;OMJ+#diiccS#YkC>w4g)4NUYdjOyO2TEcX@m$T4cE z+>X}!x3FE@{~pZAo3?X*0R;d951JT-Tr+|l8JsP&tlAjs&;vR_q+0TI$1xYRK8nKZ zI_jIcH_*)q152RX#b_^G7W98PPUKoi?k{!di4yuUs5w^Is{O z0%QUtao{Pu4srSUt(8-9|@i2--dLu$EO4`+r?*VKu0-_q~h}f8OX*C z9Jonx?kBKxgLuoTwh6N;dkXBm-giQTriHP#0 z?J=k12i7pKu;{F#H;I|1G#u_kkbkG6t&kH+1h_MXcdhjPg9YFKLwQ+`<+r(W;zkzW zQjH{-kkxO2dIYN@Ce%`J(k2{!ELylVb9d(Rb7T|M|yi>|0c6@jB8kWkIyGnllE$CnHeGtGdArBLIjdo_Z(53BthL)Uq=x-A3mr(z+KV zW~k{?eY1xgg52)Yce$2x*Lt}V03k&rG0rJk)8Fd=C>wpk#8>JKlzoPN@PLl7Uh_O$ z40l~zvbI@GJzZo9aB#+pMR;~UR_Co_6h%7+5F)_4b*T}$1tKC#48@UDTUt>dm(l~e zk62Zhr6Ee$Z>i@BTm8WJtx2swlDhgk1ecdOo%0gM9A9CZ*tD>z->Pc<>`m4*eaGi> z?supE22X~@jc|mN9HnF&*TE8?{{Vgj;XI*pBYK?K13)HXP0ugdMR;A8@Me4?O^0XW z;oFHQ*q@UJFg^^*pAMlpT18~$e#=Tha%HM)CLJ7%PQ*0)YD;}qF`K@zT00fvP8EvT z_Gz=O5qgkZ9Xm5owb_@rY84!K7%xkWXM>jx+wRA%uf6!GfG^u;Ji zNcW-(ykWlrV2l&3vUYQfNCf9^y+aD`Mi3hHQWiF3SGn6;xriHBY>%Q_k_pZ4-g6Nn z=Er78j`sLVE3@X}-%PqAKKT6qJ?B03CkH{!>{BM=!U-I7lP3kD6a zp?Ll~8EhB>{$s83P!qH@V6EKK;u*<0WzFBhImHv(6A2Jff9Dey0-AR4CJAqiK4X}O zoz}kgF@Q=>qQNmBz#O^+BhR$7zw zZ$7^Z2Y4{rULr%tWjEVm-1lh~iid$C?n)nTd_s-!x;{-~h=}&A)5zbi%$S-6JyChfSc}p5xNP2gHomQz_d@&a#t{~BJdiv%J#Vl9$+G6p%USa2G( z8AXl~n*hja&cCLEC!z^{S4L7v+>EHO`L2#^r!b%g^Zb&ATO7AUB9J@ z85WyWL^j)VYTl|1P?hIr&|IaX1FRP_PIo$Q97_dN6zJbZWknnwmINHo1Mg--=Y86s z2#yw72ov8RNI3h}l3FNTt=?<3+K|i4?Jyos#47FX)@mT4y;m z#}zyGlp3?krSTT9Lpfj@=8)t}*Eok@k1@sf%5x7*$ZLGN4~Xi({j;^^$(4tN4LTo| z_jRvo=Zs3<3}r>!LfL`0&uDRnqYEjw1f`;agO1o!p~oULRCMmcOO3Pf>>;@;I+Ul# zNL0%qvfg91??IyKqu4P@#qxIn&eYyD)QvQm2IN<~7cVeeAY;Xu3%T0!jLi&Dv5(e0 zP$Xw^w#|SaM(@z8k#&HNcO?dYsep~z_#(c3(@M1c7APuLo>;kPkboG@YXQ3E?oCZs zjm-mePQQxu@^7C_zX+|ndZVla*R&@nnO3;4ayM|vCMd(Rfq6q#%WT`LG3>H>{pTVd zRI>#98M|oFn(yqJX^i_}{J9B*^(P8Xhu=(p_%XEjdMB@={+k*Sd0Fy;*HpkhHAM5F z6&3mH8NzNH7yHP#Bpfr2;PT|B9nt~BejC*2*};--daUHv`KGnUP;n_U;X zarPoyJQ&b@V#Lxb@jj2V&GZJirx4-RrHQxKryDg>!0icAqo!3nN^G>Dc^7YRa);&z z1{=F5ST3I@SSm_Gc?_+s0$rIsDHWqr5`mMHY7>5D@^E*@hQE_QEbSuV!9!Rn0swIp zZTH&`^WkfuA}?F!UWlUl@4*%di=dM?A(zn+k0`sKhhffBkz27Q-q|zz1>(Qd1%(0&c-4tbTu*tQH(&Rhb81# z3E3$EiJj5vM<;qjn7UqZWdzi>SI){#(3HS3A|YRjETq#93qs zvjX^XX$17W4IG^O7K-6%{X$t=?rHT10Rz9w@V6WOA?50}5Eix=PvL1>w^)S z=~5wnQNZf6fZ^A_niV7$7k2XV`#6$dmz~deqqqD7B0t%tB_4^V4fi*x6+p81mlu4= zY#(~a7%Qgcrj6o0SF*6<90#&JZnP>{4VF$$ng>H2<6c=wq7w>J<)qjZ@x!>tcSWkf z^=$3rq&p-j>p@pGKt^RMHFV0{vBOsg3*M0e0)J^s(eY}BU+{{0NYBaRta4O<-V#-U zaZh+uVQ-t!2wQv<0QZaP9M70!1g>eAy{tL$l_%k}WvvA! zo;KRXnOy>P%8%0+8k;q{!f8CuDgpp9C>72kBR@z`+eT8oD>oW6-5gT70OXxKxlv^_ ze2}Wl00$*lc-m?PPNS$yUB@3BYTyzE&iNcHcx-G_AC!8VQfbrD`mnT7$`CwVYBV=R z75H|`RLfX;qAzuiM?XP)*T_KL9ge5fs{C?w=B8U~-|aEMj)oEjW*8YK8jN^v7O4bgKpcGi%~3uIeOZO0Y7o1GRk@<9))G~9;Um-r zF>^qY{L#t30PI=OD5l^_~_tN!V zi8hgvT3UPtFn=HabrmNPb48cy_cMHULoT@?X5)1jejmLgmL+j1QhM;9k98`wOm-n3 z|2OC!n_j!lQoCJ|iS-&73DG(+^n#XVzAQljPg)-_)%e+YW0wM=!V1O0?eCpP~au0-v$RihoqaELM>{xooW z3d~2+zUH(4n3;MJ+TT}E;9eVwCJCNiN7peB9c0w#uGZfROgf#T2Uu@SMAa|Xq4NCf zed^jV$hC=v{^p*-%67jN!Wdfy`MCoC1W^F>wMIpueG2~;iThz&$tl^;03^l2ZinA6 zLMZhjJi9rMx%R!)T4DCdWf4Lz3I|f{HA01!>#eX*2WIZN^!Cl z!|CeDV7%R?s`sb(T$_TJ5ml5|8jz`~c||97ucV4=@+q*oOh`t;J8CQH%3!VkSl1L{ zKH`R?Jt42+FmYXGMsv4@(-76Oat3>YiQO9@v_~&*DQs$|$4xHc2&8Rp(CUrX7-faU zp&U=fsU26vL-98;G8i%j^I%s=4d!VScUsM1_m9)pYu|$k(*OhUOGj8BWe~Kkt27oL zyzwEi-8De$z0rZVbQ47w_97{+qbWnYnjNR^Saesj37U<-WoN{&vg!L=PU$GT*=Z1n z!p+_E?BD!M<$Z3N&7C3G982|IcWz^=uRC8hW9RJNrLP{c&}YGK+*hs#I4xYWfKfEL z8DFarVia{6tl#MXE(p{cV3IEg4zxRrA(N(evgGWC{-4k5sg5x>#Mia3dDbxJpZ$8z zTfybmHexRE{5^7UJZ$hClVWo~z>ZVNJ~4hhe0rgUIMX-4Y@l+Q@%Ds)a&nOzr&94& z(2`Wp+w6(90vg{Cl5w;d0+fsvIxd35AkrU|knFfp?aTWct(f$V_u^k=l~fsL(+IZF zD8IcNQ({&Fc66<&@YGo=JO6l|wK?1?FfXBX{)2W!dK)+sYZY;qC*Ibzl%KTeZ-cgprP*}4DZuQH9T-)(yyzEVM5yglX2AT5qyak*lbGYlZ)YpXpbCw5+2BYTz;c$PHw z1s{Ts2acwGX?!zD07`vzK+cnVGjRf<#T^Gk)BqRKUs*0WBl*dIs|u!N5%V9MUUETY z3i8}zF0h43*5Ds<0gJ#|O=_l<)64K@FzCKi@S{>I#X+8gR(MpKxN|~rt=u`$X3Bhv62-X@*S{^*Re1eX~MS9?aVq{!|OcVQOEB0E)~FjQUZ9>gCzr?>6$7e*+?Lpw{w_6$iC1w64c4T8LeI{3(YK z8aQ?Q2sh-L`HH@UV94YSP=%As_NDD?9OL51iE$rk2PO|YW1`JHq*D}OGWAxScW~r5DLIOGVHf>{wR^+ z=IAl`D*Q!xRB62KxfT7?65SkwIB@%RPig#y+!b4&b3Z7$7NNoHG|+aFf(DDp|AGgh zs}!5$1=<=N_j<-MrmR3nU6O${6Dc0QfckukS^$0y!xqv1^n1@qoDkE6*vnO*$X3!0 z2j=twh|k5JBEikJfR8cQ-I*5#%p!R(j6=E3T5#zuN>E6p;Q zZ^djJNLF9j-Z!p&ONiFvz3OEWMlpd`f7uOG{m{?3qpLhuwp)QivX6%(MQI?aPw6xJ zA%b6a(`}97elJ!g^!gAxI_dkjAl;NMOf|v!JeXJW3IKDx`3RzgJsh~SO@3yg1fBsD z?bS?N7k1|T?#ze>crs;-yXmRGb3?HM^EIII%{Zc8|1C-(Y0cJ&k$(@(o4}sAfBa zTZMmd2?hWcK-OvO%8qDPo0XKBq?gisX=4Gveb&Dsj&nV@3u*4?BcV3bRgLhnQhML< zlKsr#;o6B3Ex8oP1=?xhZdUv{wKt9|tXDYmjjB2AuV-=3>SVd$)qqNPG)jHx-6wB& zf+Y{?z%PZWpZJmdecot(MN^;rGR`gOMMC9yIPa1jc`Fm+r3&~}&<#-GpUQa{CLbM+ zr?IM6$oIZMj)egUy>E4`@e>r3WY+H`_;_S zkNS(-gLZ_ESqHXO0E2YrjI;a_ASoWEtEe7c)sNmoQ9GS)o5{1&dYcem_{L*SL58vjhXsYE{1v?<~3~fRRU>&dEKdy)WRbM zQ7{#m?eCz~*0Y>&p6yzR^9)lC>A;}z#`>?KPvVc2Up|C#rlCjv+ker)L_zN1ikz*0 zdR>^dfF_4^Mptm`7TqczHp!1N=?cIfX8D%1xQGtdQAm>>(9xp%qsDKwic}X>x$5E^ zyK0;Wg7y|n*0mDgny`XG*%-~3GcwTp^{l$A2sgIN1`O1s1BaAik3d>qzRfX8IawQA zOMyXZ720^qwIKD#`tCijC^!X`UdWB>1)gmcftqX=xe*jRayjBqHk^r!G8uKCP2P)y z-3nTv#D`@ruTKwMYsDh0O|~%Wd|qE9Ukv&m`I><5YXj^QFyuw~Ej@rWS(a zDXaG4SNH0t3@u1}19|TO%*~Fwh3pbMxKTiYKj5oKUZuU1#SbBFPAoF-zk?7J+T14xdk^Dg3^r~cg|7VTF#jXVG8)erLG zCI@CL6{{DnHkvjkj?T*qH$kdKW@LC4P(Nd?q7f1M_Z0Dbl#T>f0L$@|=+y^0b<-2+ zjdyZ%&2%P$OQzp%s^>296>H2z;Uh)G#GAVBqQxGhS9a0^r4^H+Y#M?;1=7LXo9*IDTipoQ^Kznlgj;CBKMVD6I) zUKd^klDErjl;dXnx^_tz5WR9EsH5HBhwJDN#KhkBW8U^u;5-7I6H(eM)}6=l;Dk_x z8^OC6{Pwi{JSeYi5A%xc8u>3I&hRyihoM8wr8n%u?Zpz$P(2_ISSo@isW@;Iw;ziZ zSCgq>RZ+^bUvJwPaNxW^TqrwLz5AHbGl~!1> z0%x^T8a)_c3UTNbLW7a<=JxDBpRbDuU5T~l=G=*#6r&KSgzDSb^GAg0`b*0FD+3nq zu+`Am9gA9Bc6b?oh<|^1kh8NWP|Svp#0D3aFwWEI-GPg)Lofo(ML1Efe46Y_3%r47 zwIunzm3IDqaHo_0Juy1)Gu@XtzEl4lf#_1;S;vA)JBI$P6_ID#XQJ*ZcNfCaA@$+V z@JRc4V-_z(LE6w#3zB-sFwFpK0Fvv%O>g7Gta&gQGb3&9iKEJA4XEbjK}R(Q)(7Qq zHSYCSKwC{jNR&+rGqdBA=xAwEyPbksZAN~RiMj9ZwE2gcBOe&$aTR)Z34oChx~MwG zr5$utt8kI@W}Vv#xrw4=q4nOez3Sl3?cA#R5X5f(o)9TlL_7;U4Y$!*^QYG>XbYr| zHZ-84X`XpBb=qowV9_6wPc4@6>t!^$3<)d!%N>6lN%%WAf>*I2O2JJ{10Q;7_LyY< z{W$ny(?{9TFeia6AZI~T!#-|yQ3A)=L9|JUH_Ii)&n0UWt>MQgF?1wm_!>7u&^qbe zt~VM;`~)+WexN*=e=8h_N$Sr+!VN;sh%%i)aa8mZCo9OUmcbQ0V1&|WPI%^YS*)Ce zLebYM)m0_N=G?NbW=C5=*#g>nNh*bk&i68 zUAK5+Ewno`&RzHK6IkoT%#dw>Z|E=3;24ti7y+6mDXl#Z=WNa+Wru}2-_yt@39Mqy z&T{eqbloO`DK4J4o0Xy+g~Sz?C#P4(J*1Sf1b=kr$Z^!_Dg&jfnV93kTEnQrHq9?M zk_nJk`wFj+ZZ2@|oThOKu27su?aAzcTx<6UJ2XEen_s=$h)ERQC&Gha?NogMbJOa9 z@4(OO%i`{N0>9M=r^1G|-tV3dJP>MeA1_OL!8;O1pfW`rU65+K`f(Fv9x0PZ&Q17W z=kBjCQAnMdY)aaq#Q-ovanQQ~;0y4}A^#9ii2YWQZLKQFW8>ArXUwvFR=N!Vyi@ZX zd|ePw&UrI3oMetKlVoc}d^*Qb07pQ$zX{xgWcd{7Z#)emI4n)V($7O5HS5o;(p^Ud z%|u`L_L}W8wUgkeB!^NVJ)>7TFlAK?fp?N@20_szny9TtS`xwc zI0>ga8t952e|%LQ1^K$UM zWvR$aYd4`bi_ns^S1>k;w+c=o6_NIS5IAS1k(&m$f~v0=VSaaX1_pq$>zN9pjAF1? zH_rmS5k1eG%-W*qF`VAlx+UI>@~)3q^vmgue%4bakNztd$TNfL4R({7xZdxKDfKf!=)^=J2fj~S zEsgeLG8XAR^N-iEE{lREuGPeQO#y$Ked4XEzcK{V-4SA}BB-l);r} zLCbp{(%7*-8Kk#ft?qIP%d|C+19B^I!_-!fP^AZdbyxSvQQ?sNEyTOeNWU4(7!MqY z*%vlG>4^<@bfFS!xF>{E4$dWk@oU!+qmcSAz=HrW{cdy_J!)mp9Y9jFy& zAU#M`P1022IQmf`g}Fv_>=yG~dcp3<-cAlQaBzjR=h&x zPHpNbo6BEfjT`3Efo;AzO6jZvxzXbJ<}$3;Ny1s@}83;bf7{kvko$321EGF4%_SnIc1bDv#P5UR8E&`sDN)ci(~;FMml z*QWF?axTRTa)Qyfey$2&LOI2k=lTho#756pORle$3&Rc(EAOmBg@RCc_cEh- zE2BJPjqK@2(QNue5y9fF!9Ih=6{uch+F9-jBbRk_J@}adbtjN%UF9*4Mmu|c>aGBY zgLaJkH%M|0aMJWD-6JG^{K;PE=XnURQwVK2)2mJ5h4Zbdi*gLIv5*8j(Ycn04Yz~x z!l#D)Xzv7uhe&rDh#K2vE^Y~{$|al-M-+b;ZB+ja67atDEToL9?0)6yqoXm{q%by? zXRqfmtero07kE4rRKVGxrG*a+7C;6uruaU;TM$hI+V8cVe*>kyO!^P0hny%i23*kP zPZS^tqHuQH3E|`ExHPB)?C^J|b1c4A!wQihMw`gqfe~qZD$|T+>V^kt%P~4l8O0;Ph&ARveD(=^>-D@8>YMefZ+k&o z$MwRMr+xrP$LqW?M9>s3_=6WffgE$GisS?A(tW;5J7*u#wA^yBfz@r`D z_^kM%vIgBJKG7ve<15RV5?!^RT8%b zBZhojWc&usarYoQKgXjV{9(;$L>b{fAXne`{%m^@J4Yp2fOU~Cf)aO|H?NT^ZaIN= z#W}x@qPBTjZX=Q5WYvYgZV8XFZREJzx^2R5pkln% z+Om7ogUu?=c8y|1ZboHqZVFGjz{<&2*K-oUAVI#XT_ ze{6a=h4jtlP&R9tTl#S05x|!X?Oflh&$cJ^*679p@Wyq{d@?(mX7JrP7(&1iiVA>Z zGN|9RhsfgST5M-(8Sm-L+1XLhNLw3Q`}wgXR(wv>Y||6* zkR!9 zpq@?Cu%?atu|Wwfs2I;WDeSur-G2R(719uEAu^Gbd!h9Tk&gL;@$A=SUD5Y|JLh;g zzo@9;$QvXc-~B37?-4GQHc*9W>b0U$NBGGszk2U1Ilu#e8>3;q{X{+YO5!;z4}pSa zCI2r)Dw5HGQ8>ww^bzj`+P@BhwzCRg8K4nlSuqaLWrXL5*l~0VgO8Y?{E)Mc##d7Q zFBsd+>yXJdZY3`E)U+=5L5+uzf>e0TWh!yO96 zq-|VAF*)+I2)s=M<49qe`wZ2nDfQwkhj*Wn3Zxi> zTh2+552>@gGwL2Bpv)2;R7@tiXLO~xzGJVwJ z!VSCiQ~{Fq000$$h5|}22-tUkf1P`mi+QGA(T?j8GjakyXLp7h8tkh-VS#NYkv!(_ zXA*<{C%9^S0Mq|oje}mLQG|P6xQQiEDVsSXto3oeUQbZS5U#w2rE_{8Ca^@5ARE1u z6HZU$ME_NpjbH#n))6%^GOg*?gpwT&-bYT+C!sRUR=sg|?fr77Ddl-EtTJQ4@J&bF zEH4FdFtR%wCR>e2x3lDi@^E5fg;*F3$#ondv5}*e^Y^Je0ixaT$Aa3n;KGCZ9$VJ^ zwGo6j4Hyo_VEw?%d_ySPABhySMe_>=Na&gOsXfW20!a@);}Z_Q^hmeCNwZY=CNWNv zqS>RbT(aiBFTzxSq}DD!j@d}b|KwG(2Q1Ow+oX9iV0$J;p)#28AR#W%tO{xZc?bbE zI*(W$CeG%7jNRvETi{nB%`pHtqL3GvWrjZ+1Y+7p{OD%U9fW%ZhFl^LWSkeBk2oLu zUU1y(29_U58~EIr;S>vvwww1RH7>`ti7ukDth~J3hI}){)7HJvwoGWEdNQLfKTDOU z?8aIWBuYsntZHCyv{~`lY$59t~ja5{7ag@}YWEMY%VbVfp z88jO8w5<}Thj#c3(TmVxrj5o5417()JdW(&BRuD2<_2)BX%J4&jfL<^>Z)v$U#QJA z-bpWC_o2wTaVjDya+0-3mU>+bLHvq81(K#1+dpWzP@)8MY?(aJyu6jJ1TCYJYWzDc zK}#A|fyw5o!W&8g{!hCWZB5o-sG3vfH<0SiFGGe~^iMYGsKL140ClF6$=hSC` z@LKZZG@TbQ)7P?aY>+Hlb#Dmw&y>5g-E+7BbJi?xGdqGMtG{DgDZ`?@r71hIcL>DY zhwSm-uBs~B`C(ZxDKENZ#KwHlCvl~wI!wK1^Qw%EV7I<=md@OWWUrQZn?He9=7k=? z5ue2fg7L_ZCBbNN9MOZ3d|WumQaA+UeR>y{+#q2ho9u>|r?uQ_VPPw^#s`H*zvmq3 z)=LS<;qi_TI8EH^4Ep5kk$G2q6~e=LlCvw%#I3$ zHGE9v$7h|C(;aj=TFPeN24S&=`CUT8$Elad9k=1wn0|3^z01~W*W$mtCC|;zdQAvf zd1yRlZJ+kH?&Zp%I85)cT3M)v__Y9Yg*78;p+74TQvzDb(6X&;r@d&G6;kcuZZ`jF zd80pbiW@TC)35sEZcC1uhbG;@46b%)6<$p@-}ZxQyRSMvw3AB=gXB(W3&j7d6`elI zOA7oek!(>AE%tpfz!&?)9)TG`5D%}Pav|m|%_u#UqEP$IAy%k*iq$$vOq=f{r;qGM z(t~=w#@FjXm2i}@5PcNm<05-i|fE`<0=uhOsJ%L-GEUW`-+di;5G`qob~yi@L0yQ*|aM&luv)RYFx ztKdVMI)J`R;yj}U$VML1=s4)ig*ykzqU#}Rd>Cz#zwfyU+f9ki>nxW+sHhXM`Or0* z2aG~8xXg6xzKYJYf*d3#c+P9}$*9Hh1+2(ZNNU#tz(CDPsVt9JPXR}YwY*M@H{ za1CDaY#U{svj<1a)Odsj2+2Q zR~S(~r(Dgwt%yd!|$pIcxe{#5`!(A>L#%$1Dz;hcJ;=8H* zL5Uk12|Gd7yKSYWl7=5QrrUj5eiG~K;V(M1a?pWnWs9VsP3j!B*JJviFu&-^TnZI! zFQ>vbUZtzSL2~^M@Gn?z1HX+TY%bKQ$nAM)Vtvx8TlCrHePCfr*6@t?PmWTw#%L=m zFX`#s=htT`n8qjx(4R*N)m}gUXmr%xPqzQ5tzdOaq6lNX`|os|G#Kv=D_v4V&Mbdu z6S3#z#1DT45Gaym7~E|gE3CZjT)xHLhINDE!JLxwV``LK zym4_`g_RwIAlvq_cVQ5*V+BAHc!b-{5UH;6b$XW*k6af*u+pP5K{C^>eU)~22jlc8 zOB%*c?!x-Jy1Cfvl@!A{Nv$Wc=~{F`dOm!JR+^G?b|Np;Nl~@62!FKP^XKN-#-&?! z*?dLKWo6v-5Yhgzp|7WFwEB`<2m*XkJQXeAA3As%VGsk#iUGo@0jcsE6vrFc{G+u+p)HqBo3%sCL^Ov?2voRWBQTo17?xD|~AdACqp* z*U{&Z26cMoV21aU)tT?j>QP_akt}(hMf0EC_^HBeNpgwnM=INZowf!Dm?UB$DFY_t zJhGY&9TPqDFLQO^E3KYdQ-+#3lxlg@PB3D7?50+crU-j1ut^Tdz> zc_80?cI1e)pfZw%TIC+lgKRjEEg;DQIurl~R$ZBI>f5OT6?FJId#Y1DMYv8>xhz0=D)3?-Y(HmXd`CpG;Ln3XU6^%dVw3J}?#z zt0r{$P8{yTaAE@@(Btb4<7uX)!ReRJj1B0be;|`XT5OT@sVC8?<%V;SSGMH*2V z*$R4}wEIv8y~z_W>d?Y9%GL97+H)!CHnp=hl{5ost)kd4>XE#!i26OhJ|oI|4n2h& zOq{KnBh$cqIPIU*>ckm&YG$svQn9WK_&C+JD zKRO&lIt?fniEmtIo~<#OJeI|KlDpX#pEGSJq*zGMWc3kIm8$PX4E>Vp?4_z{?N}2ZF~2)o{pw^4)6_VY_W}*wsn6Pxp8AG z@GyNOU%)lHWc%cds>Py64Az3>&dh!SZKbdneG=oflisyiWk0m-CEj7Em$_!4-;Vbz zhyU}Qj7F|7QJ7()pM}>EDBNH%ibI>P53f8gX&Q3H3GfCd5J=I=dWr;>jt+g);@bml zob^|}!v|F0w3q{p-6)YDfKfCsX;=*2?Uivv7B0uk1uKFGn3IJPe%`i~mXqKsqv#1XO#hoSN;%*54zf_Hl%FIlUn0A5By73(p zz1ExnhRQh2PpO+)pt(>4&94+txtM1nH|+TO%r%IdL?gVq#xq5F-=%v! zXrNhzxKc1u3bLZ;!rz(dm8V_#Dgy2?LflH9Io%aBzX&{|gLwQSdwt?B5UUH(coBk9 z_}WE{l1`%B;g!eSxnpa1x9YvWB&_9iNkpFn%AflEawuD^;QKyC9}bt64XGhstHL3{ zK>@aks#K*u$Z-99{V0=fGQP7^?P-n6g}k+Dk;Zwr@HZrtjR@_pumRYzP2xe3Vc(%e zMs{4E1DF7>NN#(yNOhmu#9gXdnfSYczcr%g#OD>VOisQIsT0%bDpGm`2xP&%<+c2u9+Ill2lVSb1&E zZ42D1NVQ2;rpo0!NT?}9-zMk&*9e5K^uz)#PNS*w@JcPEV1y+SnutQ?&T`#1gSSP$(1J6-Stc z7gNZkr}@bq*x}u4uX;nJF=OBOy@R39D%9C)on$}fbVv~FA)yig44k5-%( z`@q_R7G*3w+*JXtQ`HB_RTw4XflE9?1+wHL(0yu%=;xZ$gginAl>X(Z!zjEct~q#B zBo*Eo+vWUA0B@5rGnUoBnLKg`c{L_kpebU6KV7ZUdmP*g%W*UH!!K%|7Ofxs{J#{R zP#cZeQL39}bEPV0%8{SB)#OqRjb(?MbZg*`S@5#0siZ|iqH~gLgAs(KziIobjC5w5 zQ?dnWsnk(cV$KT@DYebdgG_^+9|o1UYu?70{c~vARx0%kDQyc{WXc1gfot7=(zNq8 z2u*P0UZrZJR%^Wwvbx3?M+p*-FTCJRwDiP_2@m_d78WCdL~+9hG#^C&!+NyJnJ?buc>*u z?*0OmOCt zk>E}kF5_#KF}cK^qJi)EqQ1X{sJL?fJXOyRd_}u53~&=x%OVq|kD+ZD{KQyZ5@9IC zr-b&Qf7)Bm9$gTK&Oj-kDgTW}ZS&>RAPVGKjWi1!b)bz_*YrE}bo|C5eKo5iY8iRg z`eSE5*GZMez=rx4Oxk6YTqQ>We_ylJ0~lu*I*55^nFsxhZ&Wk|4fyEadDhk+q$)E; zPn@AA}T0LczjVR_lVpreq@_9 zTksqreVsOs{z<@|YUi?y%l$%GnC!wNvp`~&cid+&{ivEgAr=Z}osipAkgBi7fU28P zEF+*RAI66Oz<`#M@(KYZ&!ePLSK6Dp zky;;m)%;Hsr<%jYe8Lexij&WywY$Sa$pb^P%N;#?) z6fe|GiJ0LC(v}U$xg(_DTIpAg!*?7T@I@%|{=}3I(MSTE>6oo7Wg!cl)sK-aqu&PV zxJD8Hhk@Da;H25P?CA54$!C3XXZgnSw^?3EJFpIMjUpF1o3Y0VTPuGXmJ5>W_+U+!N!>938YkKAkF=3)u{ z=25)erU!WuQ>dG0xn$eVKn+v?vxRY?LJM9 z$wmwkw6?FKowRvUR5`j=UsINwJbHkwtG8R+}Wlyt*L6{Nea4c&Zxh$PDqh#QclZ8cp|P9reudL%P|t2JtHDgMJ0bBYVU( z%OwpxaFd|qx`>40tem8(UzzwKfKi4S-+YGp)T!9=+v9&f80L#|FZ3V<=+vDfx3a39 z39+xunhLM1|8AbQlOx77C8DFL7356I%AJk0ah)oie_ zyl%Bwr_ahEIeTG5UWoL5=L=SzaVEym7crZ(x!vB~1CA6`GqFszJ=<*aVI9lzj?8rg zB-*rg$4vEe4z=k;*mnyqU00|9Qi*}|PYfN4i5hF7wjgP=Z_isTw1pNK5{-?F71>>C zQv`M{I$lVQk^mP5+~@|7A!VcrYrJ}N0i5fX0KYBMDuI4^RDA~19=2tcyEgo$eFqS) z%H`_47*8iDX$404)jv4nnNs&%o6@@obQmKO2q}XkC&_lQ{s&^#qrcatn7RXM z%{5+El`oI$84{H4$tX-dN8xNFg*f^ibxMoIfXcjo6kieE1(iMQ<8}+#5`QBj!fG3| zeM2hkGqC99$t)pM%|4vY_t@CWyGI_`PksPG)bNJexB4F?^rVHI&3paevQdQBYUo-8 zb*B*=B_@M!{pK=3BXnCM^h+&+I!8mk1o(+6?TDpMni4>3sye}t%>P6N6Cp+m!jB`U zJ@y=4WL_44qKpvda-#5e^vMxJFwfX%!5CTG%u6T2+0kaJj&)@NIAG_DcJy&lZ0M}z z;FoXH#8=<;LZx~BKH7=my^p7c3m4ov4Vha5z$HU)RW6kNefw$A*AcV3KWX1Dw!C>Q zdyD!s<$tewmr+BDu8+Fz8dMf=`QMcpolU_|f0gH^;m~8iTq7^iGJm9OoWzZZKLuNz z#mTviSDOXQ!m%+7@@qxyXOttZ3RxLjh17@tq6y$dE^bnc$?`ePkrse{*JMjkl-Y{o zTT#r&f;&}iGSg|tf?7qbJXIVoEoKkQKl%q1bC(DTR?v*0Go7tTcnQwttm0liqEThZXs^TrO>e3)1E11ZOdeJ4#ET$cC!KJ_{ z&29@R$GIdkr%BB{-|wb`B;0V2_?vO(XX#44dCwiA>1b}1jhi6{(4v~A)oJKi1y#(w zd@zL(-_H3>q7_JLWK$b7_1EL*H9KM-sh1Es8wuhP!HsjK_0o1B_~px>nymgalB3pu zT0;TNt4i`G@ScEiIhk#sRhS`k%>AkO7G!Y8Z)O$563HV2KEl@v#Lbp|oj7e5$IjF< z=?edk{WoQuray5^?O02ubG>?fCP!V(B3o{~sN+{}*-Fw@{l&fPNJLN7MVe4yeuKk$ zSaq{(hi{^S7KpI*vC^!YDhzo^MC!Z5#&~oxo}rAs0USp2+G)KPxQLusWY#$HVp}X zHb+EPIA=eHBVD3r<9erW*Xg%)wW#&ydBsQ;ws}AF#NtZa_!rbx0F@FDqG`M419C2y z#CkJK5#1z%xJk%KM zyJsS_@dXNaaYJwXPz`QT#1aT->G)m!Y7>QUXAo?M_1IqBo|A z+Wo#0bi07cz#15oZmc430eRxt$?r#Xu4i_@&F~i{c1csu^Jx!du2sqR1O0%douX^o zzmSgYoINT0YWE{t1q9$5Nu7B@Ka8ZtEmxp=|3E?yV-rQ&$Kc);{pY@>ZB%P)CJeX{ zm2R+(H)uqQK=vdx*K0%5Q&PoA#)9|h*WmH4PA&Z>aF~H?S4hN*eb>M-J;0!k?QoTZ z+X?O8ee0Bsq@{N3tK8c)H_4Ya`da_78?gpL%mogU46-AzD$CK6=1pF`Da4{>#%{nyilxh;jR9*)|4G1}z)o3?QTmf#c{!3}jeFG@qyoNYp z7}^6I;R}2LoJhoRj2MWbjwHd1!`A4G+{M*INTfZS46{6Z!-AGPEUFi81gWO{HC;dF+cFKBkse(ih_SYUXYld2KjW7S{Qp>iiMbI^M0b;eeMg4>+3VlFwN zTwTI-*4{Hw`>C{bT@KBdSk=h+0E@UiFZ1$np`uh+xqj63b2mG%cHZhkdcGD<+EUWD z997$$FthAMj4Bn5RnV_jiH+iCthM$Xz%yrF&8ki(!f?xS{xx{^M_#H0gS1wfz0u2@ zYD7%VGk-f#pFbp+*fb7G#*@vh>p?K{MP;iB)9}j~`%SY#tDcq6Z~~2mNX$63j+o$R z?Qme5t8-%3afIedBaPpR7LSIG^z_8=v9nV;oT%J&>3|3hWGFSBsD*?%n4}+MfcIQ+ zQ%7;n4##7m{PPB-bXQ*hQSrbDzCu^BIr1Cd&xno^|(A>kw z;P0R}1ERgPPo@eBeu_5gzC9mWj>#)!`a5}xz)>#!?!F3Zx~%X0dG?b#Yl%<-y0r;P zF<8@LjO1msGhFUw6pE?EISK7^=XQAgiT>it>D9J}kQtGGShQr8ii?NcfA?5jeNeSO zCTtomE96C^F}D{pvH&1RWh2(<;NXPEZkNWBsimV$DwtR4Hv=IY1`-xqwmYq#u1GU< z6R=4d0c*DtxQm2>;`ssWzrU#lLBWt(mZ{WO`=d$YJ%79 zo*d;EtTRo@rks=(Z5Ln`yv1Zql7w_+1*%-O!JyL6i_Z@PnNJ>Ay?o_~3x!h8B6uKT z{(1Rz^JYJ5JG&e=L(qT(PM76zBP8d2qUAc>h!Ym9wINIn)C{T?Wlx|57p$j|P3%T~ zq{+6 z(tu6LV&duuk|B0`i7S6^kO@CQ$iu0dFowj6w$NjMa>TW=inwOj`tG zj}B(?_5kjbD2Nwls-+T#A3%)?gh$(G6-zu!)?l@Vl`OUU^+I`V5gYYM(jgX1y+dXi z+_2!$%c7q+1R9@p`M9zbZJ9Z> z;!u)v%3o^6%@Rdn>NxZ-wOkiWK2UgoVz(cXxW7PviX6P9_2#Kc(c!cKn6fb;L=*uF z2LR^1aW$aY$?Hz1*rQ2i%beX}T)KCkmDdo;6=kEJDUxO8T0pvn?y;u5hV4>+tsiFh z9&&sctcMEK@2LC*2E3J!+AG1yP2WbN)Xvnx<`ri-6{r3(Up8Kogvw8kivr&%N?_T;EmmI~j^RBrD4(bN1K{1x|%Um840U z3hvG(r!MVvCK6*DmFPCbdIfeiMAm6q6BLk`9BkxTx8# ziQToo1YUyc6n}whig@2A3T1>a{DD-vc6e%b1q{VsQ5YRO9A_8NHU{A;+xx0TpqTXb zp-X;~@1W0dxFjGgk;{t}i4hc7GN$vd0ys~DYT=BrmK*;hX62kcmX*PqfcB6P4NwAo zzvFN-Ae+w+^hQq;7;Pu5@oi`f8 zh0tA+KuZG{hvuJcPwP0l<%}$2uZbg?`-nkj?L2f7`1K<B@ ztFe6+sx zzGC)bAt|hoeD`?6PO$lknI8eL=@NqB;gO5!N-;^*X8J%d)KSn%@ETlANO5pw~q z%`Z*V3%71v(*XkGj^qjMyU|LJ!p)s#V4hI{&R()eKo8@11J8AkG<|(^21kLhE^8j( zij>+U(@`xyQ;$=RiJO7-j-l56IQ*guMB6$PKd*!{opArin9`XpUK*E=wc|2-ezU+c z&@}PsMZM2L;zW|JZL>GC237rL>VCh@U4!>ab3`=x?no zybBJr2qCZ93<7rx_!juCx3T4%8}hzotW$Qf^W|eo8&&mPh-~}rQ3>`gYPM#M)Wab% zAetAU6S4g#;OUb{=ehg#{3-t;%ylQVEl0gAM<0xH*=s_|{InoV_?E$5)y1Oh_vKap zuhuEjPllc*Z3Lw-c+%Oa4YZmHcTT5Wlw!yL&hB1&j!vXM zt7ELRltOn_hNm0I_uogy^Ls3=*0BO~PG&9Bbpd}an`eIMu@Agy4mT3pl^cXpGbLhX z9~W7kb9>Y(n;iYcT4Ql!tt;Tfp!0Z`^~8(~n9e!=&A2U|xhsFvtC3x>DcPh8-vq&7 z$XdJHh&??pSJcd2Za#yXWh5#eJXhVDJS`IGwPDsi-cY{!+nCp}za!~St<2u-!7(mt z@TApDHtdIopX#nj+#Z)o{jzlM%CKtyREHnV7vmM^wQ6FiVENWxrCxoE?ctJZR0_Yb z#Qhj`qiYHF8tPdf!HaAE&t~Bg+)WC9wlb@!J0r=C{JY9M?$nM4Y384AHfJ#h?49c- z3iUY^P>Grx|7>o38TUdkbjC`UjG)|(5zpCC6_0aMgnE-?uG+Gfj-dWYNYvfSc3%&Q z?&q=2k`MgoGMrJAg>jv7BY!GJh`i)frLZV-)7^90@}ci0n2fRo@x799a_9205Lbn132e!a{@b&wZgX6cU~r+9 zHPC7Q$eX|$yVGmSsMNB;J`fT}?{l9We$6#hS$7CCp0OGfIl?zM%a1VE><*GDu(bb4 zd~HSSG?3~8kZG2+HZ@hU-@mmgV&uo28(L5cIOBRk6EXekW)=YBWGXS_-?zJP8BDIZ zwKss2koGfo6w~S5LexTaq^;tfKj$Z{Ho-oGk3XYa;CxX@tmVfX2Z%4bold6!h5Bf8 z532hKMKp-mu{ZlNkI+JtRU}77NCYIWBYbO(z`KV(H2H1sM>Ps@Er;!v)!as`?i~k+ zV^SwcQzR_uBisn><)yfJZ5B9tu%qfK0Sg@8k1VLAB|U4!IsyPl5pmr8{q6gk?~ifu z#D}FD)m-tV7Y9t`zQhJgE?nws(GJXKF54)C#zRK1I4D|oO>LDmhl9Mu$@F>Ki>uO} zz80oW_RX1#c|^;~y4-N9mPv&kDV(!kEoF;z952wh7Zwa`KOqLu+FtoYkfV=Zr}T2R zIbhkB7?D!ukbwYt;juU-(+eq-2vQA-ySURWGf?F?^B*z9&;8FurSTrw(YBAd?#L6t_Q)S@-Lt-cDX@A>f)X?hGb@h9s<{;83PdXvpn6Uw}`q>xgobDUo+le5X&ga`sc zHtFtSwh0AI@myj0r6O#(5T+g@GAt-4HMfWgCEXQasz3s7j#8X>0Ty$M)9V&^PXcI% zfHAbcGTlgGKqvKw?N6nW$|Ohhm!a+spFpJJ8yVptlG)&m=w=GSqr=0mlo#g(rYc%k ziNd5G=J5Zi--1Ggxbf4%Xwe^ZIJzgOr_Qm78h9+^m{x#krB9Z=Q?V#k%`G{SNH>R* z5RX*Fag(xRqKLARI&LjGGdl5=v;N&w`y@eE0ue-{>w~whJLaCt;*2P{sG5U zfEGY}L|HS5U`U=|(oDy8d<$Gb(*kQ#(`MElgRFrC7%r>$!=`$|F#{zT?!VUyq%0f$l^-QK-CV0ozl zA!V)Fy2BZ7bBoRHKoRsfbi?aRx%vTqUB9~k7483TB9!@wLB;WfaK)`n61?Vv>nt<$ z7E<}Lg{q!A9MJx28{7vmG$}x}CpUGzVB7@zFM%X$CcN@yaGQ`txM-`tJ!(L6&mCs% z$j>s9H^I4SH1RzZLJ0%^&SKcKBpAU1;u1fUYGag^W?p@efV7+XU;sGy-%o07O+KoEfqX=IiA=U<5fOL!Mrr!aC-cl;;esLWz_REC>yGe}639A= zc8NRMcql}74D2F7f=KD5XA9(@>`BHQJ=DFR$LNTM8n!>%Qx9&xP-1|M+T`V)FGg(FCZTeEbn=9{!60D$c5## zLCiX+W!x*FiH5p{Y~WwZO!=0@Frb58-O-d0ntM{DHN_ZNz~h;L80# zb{MXf&nIOsz-5Y1vQ(LbwIsT7>xsk_KRckk!}l>%iwIfjOoGwc4s8lG3lJH`FCgnu zUJs(K%0vriyTMzVHzjsnq}ov*-C79axFPl-2UY_HrYvU@}Ad) z38h&j9^}Y;I^XYC1h5vc>>knWCWf>FEAqv9k%^+NIaevi>I)3=s0N>};EKU?8#^c` zDcf&jub(S~Ay!pe><(m@*RzH5!Dgg57-bpu?SMGfUPXxy@tN4J3l8#M4%jn!HdE8b zt|Ou>pF#bw{%y2$>}v3UvcZ!MO`e!C@m8VcY{#T=foO)6736!vz*-WU)`=+?HmK|R zKWn{s7LktQky`!kta#2;Ahb}=xKADmZPoY+qSk`>Uk}S;HOLGD)=A~*3|0~IJfP6D zOQJiW{M)Fgx!pRwdKpDg%}ThC4R#0u@33alA0UOykm*MCnW>AVH9y1SSfyF5!uwxA zdKvUQL{Q}$<*#UyVC@#pQkkYlWKmfu+Hi$~Hi{`9(aVOf1sM*q=o|LkasV2TjdLyW z2hfgoR#klNK;Yo2^I=nQ{lH46(6^GhCjf}fB#2Gh&U)b#{lBSHI*HFN?sO@0tbyj6W4M$@(e-UZ$?fH@STB&yh?SkGkMujmp zdP^g$>4!uk;Jo=ASFR?=JCYh;i)XZ?%!A zfG>yG;}4~V96N1eqHp-FlW_?CswF|5bT2GJK6Q%;OQJYDChu?;)`+R5%itOwr=0nP~8r>N}Nu#TCIgL)y5}c-&B4ShZ5+&$c&_yDH_1l?IrKh2wf&Uy+c7 zK~YNp6q*4ZMdj|<{fnDyWpR0al%Gdg%A7Kt zIC}HcChuL(N`mRyuT)o@tz8#Q!d>tgAr^D&7$*(AEPodR=_rq3lt^*=`#F(<*gSkS zSc(D*eEjphJ1brg;|Vot&!jQ{w2o{S-DgTSChUlxayUi4e#48(zZ-%xThNO*f+GS| z)pE@O#6&ylHg0%a%C*pRv%f@Vxq{w*GROL9sco9fx|a5Hje*8V^B~#eTgizanHLW5 z#=ztp)urZE&nGuKb9qo7BXc^L5<=NA)XI&2AUOBp-w84!(n%jK0^a$seZU?kv>q~v zZ9!oNOHZIQ6?t#@90cQm<~e+aRnzI}YWls$N*^tOVXl~TB22# zig)o`dkQ{ID`!lfnOQnCc5nLno{Ihbo!0|VkVLr7MExU|xmBq+j#= z@8a-36Ex4)ok?}zdgItTQAGRDs(ChY*AlRC&Wz4*h;~I-Au!8Qi^4 z;+mwpTbx1Qwk*ZZZT>4`a$74H#7pqmwl7j|U5(qV!T0)djI=cl6S_{?tmm%aJr;s} zXiJV4L`Yj2;rnarFIOUo1p<>#;C%r65AnY;)sx{uyvX#kHOYy#8BTb33s8RXA+bLU z^f*)9Pc~@d6Qhq@*Y6CO?T$X1TeOCG5{tteS9S5Si*t_SxjMOrT1hLxPE6XoViq@7 zOWSE=+&+bbWyu5AEZDq+R4u^y7;V)3!@{{d4BIVuK7o~2JzN2-x@^)P!|2l3;>FAp zpRFh(s@GCTC2Kkkcz=%@0MiBRO|x&5e_4n*2rE}&{*!4S7e(3qw0vb_(iB8D^MTtp z;{n65LHl>Sn<{!)*exY_Pu};3tc$|xh*ni??H@lFu!~p0U%~=9mkwhQwD`LAPs{>0 zcN(cxI!`26#c%^0NW#&l@e4_@dluI}I~4af%yWsUx{(`6!h;pWd~$Ix7J5)m-qbKF zdsOm=Q*k+K>}@V&Jt96814Yg_`LIQ`w4N15)OXM676 z%Vi6QY?9F+@-K)sI?tLQOxW89%jFNrrZ7MqY;8!t3(17A+!2!|I0Mle+#0?VQbdGA zXZ9-6VAhH0^_8Z*AMfcVvdx(K@9V((BWrVvy?@>P)`Vh#{B7rn|j6)oL#ScBxqL^o5UOpazgpyJI z1&;%(pr^#=2Zt*pg<*1a58^@qA4noOMiPN4Qq{N@?^_tp+iaD!7|hUslrf5gEWXC= zv`cXF?dV4P-V~6vvTKh69dD@xjBg|kJ2^_zgQQri-SxV-3i3+mAKV^<7!lcdkbfpT zQ|!l1m)$a{Hqn(%VF)_1nPa?dG{29R%Ry#eHDPtP?$Xiy8S^Ss4yUYz7st%@@?sT) zYYHlM{jxEM+9%Cnv6Ddl%+-Veu^FDy+5lM`P+zp7l|*Hgg`VsK)p!<*?YZTVUyBu3 z7izLe;_F-iIw!-`P57lc#e$T*BTtwoefigZ=$5CoA~eGgo(g8#>152ubI_)`d)h#V z0fzN){veLZit!|ELRRedgUrY-)7n>@K}EK1SFW^Uc|2tNi;=UzoPA>{`r<}7h9nwU z>F+4zQHOCayR>XMY)0HvmkhLLBbd-hi}wMp9k&cXrv@^2burdpGDq(8E{Q_FcLGC> zmtZ%G)Ne1aB4t^fy&atDA84sMgnJc(-glR(+ZsQnA<%nrG$B2!eX5A`#&YQ2-NV3} zEZXZ8L_)rE70hE5j?z3gS@>^L1Yx&He$S%T*;y_{Xa&M^Gh990Yz20|5L0qeK`REh zQZCXt(FU!7_?%2CxY1Ahuvby}?VUrI|C7tkslXyi+x4D~1X$C_ND`)dc52%YObN{< zc`3S)QhMoq#&RLft6h|2INV`ggidUn_~aDcwL*;Uv=;N9EIj&;gprHw1E7PI$HEt} zgOoqnCxdf|f_6f19zbYq#@E9oNuvb(>W^zD7%){GE)FQfz`^zxe^7!W^pb|KpK({RS60*QD0y*yv^24v~9 z*^-Bkj>NoBAR;5jzusa(AITNR9{gVJ&%9IH?e?k;;3jpJT*AG;r z&&zuV-7tkmy#Er#3?V-s#yN_`a6Sq**kJR0r?|W;QvLwhcH-L?hH<&OZyJY;ho0nw zTI?29%@N2WLm*?I#H?{iFo7of+A!u4Xqod&+F)Y>J9{<7_+ordpMpdMgTn4fCvW}` zcgFbt;QZ~S-B86*^=)Hl-+6m^_1G~0C%v-~8>_WI)*B!WahXge!RvSg@_~^{;QC7) z{i^E#^!_?_Xg$zQ@KAxE77)v-8*f9-F-5QfI(jR9`#B&I$c@GTtL|J79GL%`cFHGevldquirOWmBQx z*9#n*v2AlZVw7jpAubt4W)zIqg@e@p^jSw*izFB3+2G|{i15*ih)j3#A?Lz zv6I9It1fuitXL~`;sTC^4z)3`a0W}1-yeBUQR&%;lUN$%OtzJl4czO8ekc))<^@QG?VxZBM{u#@F4L>sn`sWDAv4QzvL7gUItSanGKJG`B z<^gfQ7q`^`YdwaY%TGaLE->ajMb{1CJUq~z5}y1n0zc$#CFO|WA&1yOwaWH_sreE= zY5_ht>W*GsbvC>^*i{$7a-8;#mi$Va#6XT{ikazbuAh$oCRkA=}*D+dwy^5LmpGQ{an1CN|6A5wO$<9_kRNg2hJNOq#K(hEFh4O zt+DPBP?G#!`&1OSHtRVpWPp*a4S;4JVLm<9tE04ZNbl>oGd>;0>fdA)3zYY?0iI&q z6u`w^Y}of%NrW{R$jHX<`-qx~)gwd=NTiUVQMT-wW%soeOKsz9Ka^~4^%YzZJv=gMUJRza+EjSd zxcY~Ik&BQI!<@ye4vl0xB$e_P6T#r)$`Z}V4kaiZmeX7jU0|}-e~}BOhT0Lz)9S2_ z)M()^}^kv=lcLpYrMj+;;xl^v9 zQ3Kio<&al0Ik@3O&9vzOH&!)8`?dF*<^0@snjAO%J?ta3b9fU7Wz|?q(=BQo}%0yctZ=8r(V}@m+*@4 z$Ln_4RX(M1=ryc0&5LVJuVy;Tp9)q6V_y;=XR_~C2lKZo~a)r+R_EZ-_)Aqpfn zvuhczw>jNea7S#4OSWU)i{+4f9cFgHGD)^o0>>bHjd<6-sGF^O-kG&i6mb*YE64{7 zyTlj`l9Lvflq+cxdV>O)SEYSc5}03keM?E>ea{<`r6y41fer*#kK>~JR7FqFN} zB|`*vzO6LAL#@+f{WMSaBYa2Uk3duDkm7lb4h=S~qCa!SXbG3OcKND)=4|t*7Srcf zcH}Mral-i9BNF1Z+8%%{)LwOmGyUaV>d3CHcbnj5 zRaL>96+t+XW-0*T)!Prj*8Yv?Z6kCR==7e`^0}s$Gp6Z7lBQR;t~6L6DDNvh2jM1n z1^t>YuMl7*e+G`9B-mhRwNpSkVwMqX=tQTdUw?``vAjePznDYN|^~7AbmR z-2m7*xbvH0*=Wcy6rY*b&s40#@UFexgq`ohKZGMpQEC_TnYQs!x&SEr+^u6zZh2Hb zz$iCYks-ladIY%uCc-)e*2tQlt`(`3W71=9QyQ#5X-iyxd-YT%KLND!1FdH*rz@m( zAJ3#>9V)WZFeUAj7q{JZX&au`5`>3W5bQWG4askstSssMrnYs#i*4R+lSQJr#lupe zk*4tM@R>ciR48#G9Mx?E1oLkIb{o^=;ikC%Rh5C-g zI1%^`2v@VN2a)yiEl`%YKD^nz#VTe31Mvbxiyh$F?1npT7E= z3QUzXvKUCkEO|5QBGT;^r!S?*YHrXS*PnyR?-0ww=ga0zyg=gC6cyv3s`8ngJ}8_f zsq!~sWhk6`ziQ$7P?(_Bf9FcKV2pOCR=9X#`g{57^Vw%IXBGSczMJ>NwQ4IK7Q}p7 zPS!_H4xjephENAuO=M*Q1stjY`mrW`Uf#oF5`4kHE`$1PDsRsfZ1X@f=ELPlWWM47 zhBYBh*2~Qel~KPRcQ;5Uf3Ev)TbLRO1(P9;_axsi7W+X)Qa3~+469+^V5#&)-Q>Ud zgx0OZ@n(nHAS-@EgB4X~H>l-o1L{S%UUEnM6)sO8ODQ&1RkW$SmU9g^`so`5ZK>?AIaa z(QkD#f0F0ErLZe#mI5qFaE$N7rPrPPL+A-+KuAmVxOHIsT|hngUx^pd|M=+O}5CON?gNs(SNd|Zxi2C~B^NIwv92`FFMRdgyRYYS<|Bb}TT0gjX5q z?mma2sC9DeW_@~O5`YS_le}Im?u1Yc&DDFW>XCuRuI~yN z_mbcw@Br$r-tn`(@zpS4evY-EJrG}Ch&XN5ZbzZ(3rf%#4iIOzqqZ5x8nm==1x%s> zwuD)}7Sh&m_ww_%UrY{u*6-1FC|^x59DS~Bam;?Esd6j5^mac(2_kJLF|u~DL>&1~ z1QaT_wm6#SbPLi0Ac^B2=84ziUQLN7caoe5E25b~=K&ZuKa zdN|>bE4VYitYt+=(3#$%xeXu*e{4mudB|F=OzsuBYy<{_AO|8x@);#=G6H}WWcv6<|16eM$vQ5ZdPMrS3H z;_On#V?rye#%D52JStqNO7x)*YVJpkqmOvfo0|6T0H>0usJSWaGeG%=__~p`8;x^F zQ!<3w`|jz(U>zEFAU8tFerO^@NFcQcl<`bS(W2|>Nv00{iNd8(h`5fHVNsLrltDbt zdc35(44-6jO7q`snp2G8*|m~YSJ)?AqDAtUc`YNTF|wCh6Uk&n{uqu_qb{~Zc34x7 zW@-&`3Q#pGkc-XR2Hh>>exq{W;OuBlaeLXx1|2+b1*@AlBd+(bDMOM%2s{qDea1+o&Zg(z=3P> z^oEZNz;6hMoBGxh_C89L5A?^E#ICTvDqaIm?!CvaCUQoyDMY)lOB)&xlPb(bj>ozo zOf#cKLJ2d^=E;HS2v3$eR{KP=S0okFid^oZf;kB?}{4T@{`%0HR2b z0}_PDn5o??J4x(8$Dp=O*BH5uQiS@J7)C*s>EeSUNasj9P*wnF{-<%01YTXI2{K03unt^jm{h7eF`)na z&ZZVdify=tyG~rolZ~l=JRgW34oX%FlC!Ie6x~VihR0`dy9J4u+jlu^F>x+WkUMVt zLZX)!Vj0cmkIwie*S|##=Qtwf-M2z`R%`k9xAFMFu90&1Em)AW79Mybr993SQv#Pr zvh0Ec6$qqoKQ-F~Dbq6#AQ2_wxW8bwr%X(ZtDf$%qUihL;n^F%ruX2C{sWu#HGJ(;scO{!VL<6cNfiCOEnC%ay>>jjv(+t!ah~?Y<-M*Dg_nC^1ISexd0VKTdr}08&GaZjo#*C6$fc!+?e`fcs27qr6D2e^Jz>Lf}JFvNt+QU~h%zwOK; zL!tg6nTzT^S*EBHiwvZ&!Lje@Qb&+vGAR2t$B_A^X5eB!3hDms)3Nf9R)2}PTF(-4 zL2+TZw*4(Ck*cgt*u$;@RMM)E;I%@WF8J5- znk-3IHIbuK#RUtW`XOO~uRa1T;!6;xRg~L#?MVR;Rl3DH7Ho+nx54UmNe#joQSu)^lpb?l=4+ z#N5PA_jKKsCe}yG$|ANA!mMR(Ls*ysejhd>RPl399MpCRc$!0B#>dg9y-yVNY(U8{ zcH}DL0-0p9kbfF!0LJhlj2SaYtr!`SV8NYMGhV?7la4~dgC?gqpfZG`mu4(1ELm>X z?z`b)TYA}e0x7^Gf3FdFuL*}{;47<&sDzy!mFn6ierxF*EVDE*e6lW^&L;B8L@2vux@HGh+G+QZ1?z2YfA)Uw0hoico3(b&>FLKx5#q4C5btaL>cb1-OtL_AGm2V zXJWP%4B%CU5}}p%rb~o+FXw=`Po-uJ>vN4eTJFRqH%JD56D%;VNO6rUDi+$Its-g_ z!y-Bs0x0Ry=q7~OqshaO^&7ja^`D|mV_;|(qfMHErtmV$fvttlJ>{=@v2@bw+uP=| zSOC*w_g+^+8&m5Gg$tD9v%de8j}Nj53isDx)C_J~AWDO~^5gCmRJvV@^(oLJqYUfs z_1>f(jtk=(*XFV-d)rhs+-!5Zf4B`ubjpwC+uJz%9MDb+6jst4q^Z6RyV9CmasoIG zxSh>6m-z+WY$W6{2uBMyTxU%>8E;zPb{SkBtAHpp?)JJfwJnkAVf-6^aT$)-i16pB z%-ev`+82Ly>F+Qm6$Wg$!_gmg8WeBqN_L6Od)nW}+o9aQ7~JjQ$W~9{B5HJ|R2=MT z%#YY)`$fsf%~C~Qdj+wlse)HRsK&0g(cK1%%hB-^xNrmw)yTyS+4s@fV|f%W4bA&a z!3yLy7&4!RIv75J;~WPmg(2{E!F{MA5Y8XeEbVcggSHeuP| z!MxlL$*sBdOuCsoIR_0fJ#*f{a*QBMuqyyiXynu`%GnRZ3{29EIRv8I<};RS5zzLk z(IJ5fvN9(EK)8r3J4EV;E48ye!L-~T&bZT>KMjt5l|>IX1C+S5?eT<911C52a^AR2 zr3&2pDhO}@j@)xX759UTrN^rDAaqvIIn~wVN!Mg_*V{Zw<6l4a+QLS*l(h7wQ{LZZ zf6AS_Piq^?j!tB3HDu)v&6qLeEKRSaI#XlwW?jfbGoVnlbhQwgt}XhsbZR%?fF85q z+sBQ39|`V)s3>kL4`vZWlU<(?RPL`}jp_Fzb_^gsZRaM{a;;k*-P%%L;*MC3`b&LV zl9r|vaQC3nVFR(blMOBSskser6+6LPeXD!db}u^=yeZLP12n*qVyG1ygyWs2?*3fd z-JU)|f;K8IVMIaNIcbk&eI``-+~4tB_q0Roj3ks?bZGhEQ>*CcPRA6;w)bRV2+qzm z2G;f&Ei-kb2u~!e8@|ORq;p6t5ttVeU$gp$wrv&~BR!@g{yEvRZ3_mSZF*WOrCrQ$ZhpUA_q3YSJ**R=tj1AFHO* zw_&wR*X{cY#26pITy3OJ@I>SF?|bW``4;=6D_d%B1iboa_|pP3l)^N3bnRj>9RD;N z7eHKLvC*-Ne*`m%R7-(Jf5OAFB0pHzC|U;4yU*Efl&g{0DnCgNZt?h^xWBkZ$TTby zpF0z`app^s;8XiPbBAIxWmH4L$7J%ZboSmbTMq{l#5#(mjF65^=@uw&^6 z!IZ;c;$EScKVZlGgdR^-y`f+RP#yH>dc8LZx;+^ShIJ~HJ*+u#xs|d zz;mf0UX~08)ssG9*|?2s++i*^{N*f+gMsgNI_?ViF;R~t@8zT@T~?H6WEezai3n;rvg&k+)L#_yKlVJEzJlbEvaR}TpxgMhWSScBX6)evBs*a)y( zFYn+5C&C|#cee#D0w1NCw|a%#Mc^Fmb|Ri2h(fEZi#|YoL!rWhqYzwAT6@YK3e<{S z1zN2vC%j1jl(>CYQBzyYTK*Ld4g*u)+rFU#S#!OV9#t*a6Z(S*k7E!Y9pCq=8PZp6 zmy74kq1^#`H?&qR1@SJfX}IYVJ%^ua@4#9tRZd;v-xAzGE)T?usH^>~VO0&fz7emHWMq9xor$riZ&`gsKO1{`x`A<#q1NWQ2lT2Xc=l!IL`2Ux|esO44N2@FJ z^0%K=nm|peq_JdIleOeZuBs-zn0PzYhMBaczAC3oOT4Q}ibw$2An82%<`Y6E!Vr$` zmy)6^A(y@qk;Tx_&Nvda2$A=cmEDUS6Oml9*m2CX8bMnm50fV>-inW+cSV2puF1k` z7EEFOCE}Sw^(HI#N37^d>#`J>s2bdYNZ2h)1(~%PyaIxzH<{Nut7MR<@RhHdsJ;LWg#zL5$39bsiykNnIcC+9%;g- zBibR|!XF4*;Y|{1;U#BD9Y9L#H2cJWG=e)u_bpVE2H_)eA-hjW-Av^fiW2{REjsXQ zma#p;-YzYr#|eBNV(1O_{u@UJl*o=Oa)iCV40%@iasg#Qd5&M*S`Xf0777zK1QiD| z43Sb+*`tZsFUexi-#owGrIQjq3vI`HiajOx^j2-b+HRxiy}YX4=}_pO z@H7?4uTzwg)u#wFL-mVUD@Z=%Ca{kSm0H}pSB{Be*mC;i;mIR-&oXRJgDrOyXpT!7 zPdh7pYYJW5VRch&2rLOK3r!haKLm!`t#yh%a0T`y0cc0?C0?S@(@IE4Z?F$*Tti(1 z;gbdFr`j!denXcuqTU*{ zZk5$Bwa!V!`PMb>;iO5w3hHrWhbDLQzULX3U%QfMHuV*kx~|{Yq1AH;U#_6|l`O2( z)KA7INQ!dgYWd3tm)sOX`QQrV8e_f4T7j5xv=|49)*^qJA}Ia?`Qj97r}sP~rG*}3 zuQir;e9K`^4~zr@Yz73b8jALJJa19=f|q7{J4B`HvuDm7aO0UjR$!>e@^c z_Gy-ADCF2mCgymd!0!Z#>3=wNG3if#_;ETiU+CmGoc&GtyNV(Y(JxkJo0`s@EvA1r za30Co>6M2498n*5wl>Kh&8>>`1Pob0ZxM!}u#rZW>$aNw+>+yz52GtFMzsBq%By4{ zs(a)a&1m#;Az$zpgisqilVz)fFQWd40J<*&tO{%ZgUN72a!Eh3ajsi#PHYMkLdZ&K zS70VA2=ZUL2i8mpJC>ZOD0uXQ$gbY%pYw`GsaIgyZyeeH=;@!n3}x1!bcoZ1Z1cxF zM=za#1$R@`z@$ptxRenz5aHO)#Dk{hYw_1kjVB9r$vH);Gh~4`B#C4!+CG`5?3vD$`SOlj(yD{0fw4ls_McB!B zY*q5)^+WdNT6R0Iqm2){W@d7n=sFnPD*WRUElE3Cxa4zp;LCa__}VAscx44Wxhs zsPT$qU5NI{IWo-3M-&Bu(nEzKx<-Sd2K)d-HZT>=jqs@GkuFofVp!R^_tv1FAZ54u z?ZaPQdmYsp>hag9R- z!oDVa<58MMnU!u2@ALIlpa+ql*SO2eXbX`dl)wo1+KmV%#PJ;CU`Jn_%FoOCv32Ue z_ZYex>4WOjI!V4lM8o?Zscha zV} zRbDPDmJ6Q)mtFX=&#hf_7~0B3wW*0Ri|J+3KEd%J%&_Q-oXJ8n)KK-wY>Fg>6p zZ>}csNMpoL5KE1QVQzuF-E9hiWqq5FboUf2oga|iHpo|iP&0~6Y008x^-(kyMv9@k z*IHl%*zmjOY=EcM_RrR+7E8!7%~jNFdtLz+*5!s_I)F}J=tcblD{;Lgc)||~760`X zHQ`1j6gg}u2^DM5>Q&q!V0ix)=`YjA(;P=snlCZ@(v2|w%d+xUw1F9|BGXcU)aOyX zv{u5$I)Zsy?SV2iP?9tTouf%I^g*ew-A6`OtvJ&noMD*kf(qUp-iW6xR!~TjFLupw zJLx#ec;lO$_9aJ}cNw6>{WWO)|uBS6Q^F93MYBmL~8AbdHAB0=(!7^7wA8r$( z?HYn~Szf78a}|Tj+pMqAb>WyM+D+Ph%>z9Yy}q9a!IQO8Y*;_CavPVnSlkm@z$~02 z$%mWn_rX{F5P2a>`oJYj=s+lylhIsxE2jk4GeyO6y7zLq=}5O2v8E6tmEL){7Ek0p zTOL-U9-|&@oPNuH&as?54nbbt6J4(1)jIZ5Dk$$(c(1yF!9hx|=L*}$H3L@-6)Woa zKw|_Oy$pi&lk8(yBUnS2+Tj%d#*29amiNYuER$H5 zOS6zZnnIc;j_Wv?$=pU-$Z_uofc@R+@BfwgWTt}Ts$NBbn~A9WJH0re^F^#QkCQ=@ z^UVWw_h!E2+zM)f2yukC9@JQKtzb#OZf_M<&afh|ICy=B$Oxu8P%bwGk7~Twk-5?Z z_boJt_;dQwJ>CQ_9M;~7GP$Hh9Js#1UD{soZ=G^wr~;i-w@lgu*y zdY8WgsdhRIJ>YvcyC$om;n>7zgh;GZ4!qI= zBTPaYb9N3t9(CMqRG7#+-Jt@1mzains^dF^?(qvtO+65t00W)3K2+&minhM->@kXs zNqu8{rP^sozgo>l%8QI#;KPW~;Ln_;Vn^V6k8dv6mwp$ix1UJ$oj&;ib0{Aqu4bs@ zu4gz;^hD0!96@n2E+j~wF8q-N=v-~mDB0rGd%67??X?>*R}a$$S)PIe9cKqL-YdZF zGlUiARSPhw;HT=!AdGtJ=H4btqj0Q45JaH2+zh;rv+S5w6!^Nr%&AMB1uH$#PG#^2 zzpp*h_iyu0zJc(X>#z*Sx^+_N5z~*QnOgSM<1Z%{=Hy2e`~u95Zt!)I30)cM=r;lR z>+&rr=c@snu`=9#ghZ?i0&u^VAzq3dfz3v-s(G(pE<@q67!ZoZWYJB40WpTTT=gYX zMTESwtBJ$c*jJlXPq~h36il+Rqx`Z$Jn=NBORAMTMKLUg)A~mnHz&jPL_K3UB^W1P zB&S898Q2W&g}t{>K`fEDuy~%1UdxUULrTR-jL$_KWF%PjCkF*idVTg zQK1Q^m@I`414m#S>0qJ`65GiG{rkin1p8KR82n{nBHB}l)BLV}bLwd0LLOt#;e&WY zrcEMmiidor8@UMbs`}XQ3QqS3u9JAiSG=(A{m{i5Wm64@fu^*Kh8mmA8LpO>O1oPk zfa5}^?63tg-JLT#2h7r7&MTFX*G3;rhROVPDUO;BT>)U?u8t9=eIf8=APx_L1f_zG zW#78jNRx~sWr`_DlRCDO2OTb8W~eT4R|#W!_@Day2b=;$o-P&&Hm3ZR|IWqGTzDI* zjctwi*f9tp?$Z~;OMh6mW`iB`tH}%+A2n|pum&%*oEwpj~B1e`>7+C^RN zMki_X4yoTP!9$zL{uTxPkGS_?Z_F{>w-70XO6du`yO&-%hViPLelt)_;7&ss1P$Mx z^=G0zbh)Xx#IG4+gbdK_B#VM+w0MgdG~PV_+a-jrWjcRXV@K;0pDPK1glqqDf|8f%nWX$N*E6{$!33RP zdyQWZynajmD5#N92i8rgnGFdBx-@lzi#`dVQ4zey_XIh|MAoT+f9+#AXxvkAp$PkG z=C>8G(4^QmF`q%L)41*8x4o4qf!_HI6>+!Y<4-5nB>)^x5)jlZr?ojb zl4D8yx>AvXe&%hb?xSUeh~yMdi#k7Nc$0ggnViH%uVt)I*7}81sQVVu{P4I|K%PJD z>j9|Xeii={_w*g+jN&ETAVXlJox%tl8L6aQrvU`57(qU#^_HwHsrPt&QyM{bcBMjD zgz$crt>A&irb`bLdDG;sXRH^HYYyQ-nIX}C2v(m^F3^O2<)e;cCj{wn>-bqmGpYCA%c@UO#&o| z!iH?ks_TjmwUW{Rk7%$;zckyOU_n_SZbHz)h3rLdyxwqkYzFxDT?6c3=p7L9qK>hk zk+_B6*XU3OI(~P<#T;J~fbC1iEr{)%FXs(E_4^P&S1S!8r)Rzl0t7sgK1EGFvgYj; z%HiTMk4X>$Jw;Le6(U+c={}pip$XQauiU|sImRR5%>#&8qSz=soN#Kph`N+sj>>_0 znl1FzDV;YelK68a=g}?MBd`kotu3naF{=o;MAV%#4ZdKr!+IAJ)qS0OlQX!MR$9Bl zkN=hTZ6!whj|FlBwfj3Ub2dIc2AIT~Mr^XIM&VyrF`rFUh@WWdZi46>;tuVIw#r7( zAGa{@#?(c$TgotY(8$HO85d4VR{i~VP`=t#pgFEXy>R#V{A;~wmT;&yk7(_b914n4 zysd>@SX3rMs~EVn9xFA3)n`2!_UR}QQ%ql8kc41H%T}zK&HPAc-U?_3Z~SMt7~|)2 zdYuGM60&z8Wodrw(whfQBtmiXDZE>Q#|R)~oN)HrPP?^y}NeLutTr^`1gH%|j_mPi5bKTpt1idGw#a2ipA% zc_E2zip}y7N9jVJtx>X$runMOMSZf5{0|^g){AAnsAG@l2B)XR5J%Sx=iy$Nd%FH( zcD2N5{?LJw((2i_`RQQY^g-UL$_9ruo+EIBA??cv#2wx~K=>7xm?RmejyS?xxBUIa zkhjdz6=MMVJ)|ob5yJX>T1B9U9z#$S%`L-Z(;tlZjbT*4q-+m|Agk?`NaTx0LYmO% zojf|1ilfZ2vlhZ|dZzuls6rzjoKiG#=fm=DaBnMY$=s3o(*b6h*jiMl1N^G#0T2jV zqZJ`|9_Ga523Ot6mEhgjYdjp$jwha5oMGYA$lG|x$h#AuC;pOkf)*Qv_yFsuXR|+7 z@#SKzzbeBznHA|V)80*2q3pi+7GbPy*H7C>+K@Ciq^uh?1=Bsrv~?BqNwePW;23XCPhCT`i+y zh16P?I=U=}$j>pJ*k%G3SK^L#nt~0ybG8V26?*Uf82cjAzax<8yYyrE>BPK7XZSygUcAFE^W*^nZIZkj-32f*j?tqN zNIUg4LiTw}@fyGS=U?ebz!ij1Q3^cgR@~silx$44e?+F&s8u_EQ098=>h&WFS*1Jt zPNF+^ubUR(lOOio{c{T3oNxO-0w!#-s(F|wg2O%fz(NRNsGuU3D$C%@mBT1h6QdV0KGa5)6nLkjjx3sCM_w-oCZF{ zi;++E%&d+Z45`s3g^cy6{Cq)pHU}u!+_Mx{i*uDj1#~>GayX4fH_E@owSf<*u%4$?R8TCrA-fG zO9cs>g#BEXV6Rts?j|Cgoj&l#=GAhLa*RXBfGKU>N*cImvBcFy1Fn}si&-r0fU@6_ zT@L8ohvwpF_xlO$nh~p?wr0Jy6_2{nOYj%l_5lI!WVC7n&%85{L~Rk(2s17%`N4T( z91sf=_ER(iepkvbiI7W`50OD0gi2(xBuX~pSo zq*0TX1(~I@pa5*M(iatnLQjt>BMzg@4o$f!4#YZ-1P&0C`vyA%Wq|Zoj%qUQAqYDj z_~M=m*ns{SseYRH2NbA^+AyCf40+pD_1y<^elwg3N4X>0imL+bUZglQiX@G{ zT*rn8ZF;FSV^kxQ)~<0gRO~!B5l`Iz&5Y6;%DIBfITJ)2n{n!Qc0uk0lCQ@@5`IPw z!%bFOiGgB3aOehwrM^;kJA#`XN&)WF$P_H(<-b+yaozRPx9k9;h^11Fz4F&~jvYR4 z$Y3Hrx*}I|5dfbY0OC|OOJrbXMKHKQ*WqQR%(A+^+8u_ub*}?e!GcT+d41fm%CvzW zNzmm7k389Xyl?%cb8dTBkQJFh7X*D~T$K%vYl~V@*mAI*lJnSx8YDp{sYnIP5yC~J zqQoe=3*DK;k8K-jy~Lm|ke>gL$p2|~Wh?XgoEH@v`^RW%4HmBRY)x4QjpH|W=0oq8 zhsIUB=|E(^@I|f|=Yra+GXw(CvyT|2qPBb>5PW4^dl;T~*_0)|)3fH{6$Qo}z~l7V z+D)IWN*ag$f3Xn^%D?iKVgwyMmDP!Cu^BJ8=t#(?JVTZm83FP6VRSL6H|JAQ^jv=Y zHs5B`pDYv^QMW!hH}`*u;S0rvNvrl!@U}epzAwHH3FORc`CyVhM+5~l`#s!CIhs%O zn-kIfV@;PHE`NSdHKci0(Hm@L1%#J?DNu$|!NgFL6kTz6KYH~Icfy??3(nNYx?QdN zISWX4g&EGjR`_Xa=xGNZJTd^yh=9s^&I{aHtO^yY0!w zZP)Gr@xB3$n5x2t=MHp6LlQzyF3UlL+G0Gj!N- zIOY6mOJu-HoU=9zIG$jxeME`jbc;2$>3z2b8Lh#N2)JnTJ~2B9!F24}z$&`DX`!^>U|`PP=Gr-vBE(Us$#Hr)~RxJ^M4W+;fmJltruXupnwMB`*B+4 z0IjCbj+w{12CcjGKz!|*YI&yWKP-{VqzFw!a5z87pfgXUseuZcZVq4NX<9ZO)drEh z4M^06^7bxh68D|j&}o3(z!*B@%BTi0*1YK62(1hsECQssxt5llD@mVT&14Y6@G%ontF( zXn!N!sSEfvPN_hHCGid7&!ITl0AOP|_C3c$aLKPJ{~Q95zk|Pyf^eo-X1C*`priVF=KE@%!Vm{d0mx{l6{=n?zH(dKEAXr zC0Otu@2~!>JDH8`xjZg;Y3Dd$U2otac46viLhR!xuNtn-VJp%4x4u&gOO5mB0P!$c)U>@&Qi*TjiEQh9@^S`@NDNe+|EJ}6#4Za!=jr+92A;6&0;OJ0GCw}3^b*Sk{{|P&6pZ!NImzcO zeb3P|#T$k{+(-i{-gmOXcZt*73;nH?4mC#PPPzB|+nQ|k9-(8rl>l$&k4}<7nK1eN zGZL)dfmOYp+dTNVZurmVGIj+nTo@TPc#1zwyJJ})WQ>_S3x7AYcCry|k(=>f~1l~GYm=76erMd@U~)_8oUfLZ=hQ=k`HKC6GvFI`9XNga@W`DYbJtZz|RrMLpp)gnBV9Vapx*c`rMV80}cS z9pAfYbq)C%!?|?;3dzSq0|VZ|!5xiBTtYZ*`@gUd?){?GhD#))WLFPMk&b!Xr8rSG zFG)oXufX@!vp%%_UNtM8=1fYIHCSL~I*rVufX)WvlS;vwppCFzfNvxUlhR%eEZjLMxM0n{Bzc7 zH`d=yEbh^x_bi?JZr9_c7@|zFl*G82tn>`9QQUAPU_PxKq ziPE4IJN2H|Ty|$#lVj8u%^tK*`@l8*jlt+3BpG^~WxG{7|C|m4m$voWmG=MCcotSl z6#NK}d8CCl6rc6*b6Eit>H1D4u*Q;yTa`GBIWTL!Bzr_SB#|(u5B7gG<}l%-kDX%I zr?qPz?eV;rQTvpL@B0u;Eq&i8NQxTQh-R%@40=X#cSUjrZ4B#!2o@m>YY}842l63( z3P>QJY`F(W2QsrYIq7fKlQZv#OG5Nw;I+i)jXlG-&YZb?oo_P1%TN3rg@eTx!wYcs zKz~=!`AUef;m4jv;W5UT2=^_39L-Am>lu zV9&KI9v{Fpyd~1rtOUq=M{%bLxBEl$K&EPp?y^Pqy+w?fD>V6Ej4M!yLdiRPW$9w2 z>R2Ze{Yyr%(@%$QJeO1n?Tvmn_MF@Xp0R>V6|Cki#7Jhf~OY7uYTO>{G+q3AH80!NEXsI``1;Jmx_K zp>)dpqN6P^vfxg1knr44NXT{YCn3-YSNhP|J;gYPJ^>+4PLZOgx-~|NC2+Z;p~?J+%zqP zl9Kp{Rbx>b6J!?wN(SM5t&y0lyS0WR{Q5coDlBi9Z*PB}Om}oGadf~ofef>(Cj9Vn z`M#cEg`h*PkkVc6y@pOe6y&3k&u4=-zy9(C;e(w{r4B4Pw$+Pz6Tk^B6#N^J(XpL% z5bzpc{LuPI}KlZz*kK3fSZlOu0J=bBIKPea{H^jzBfqAdLsi#CU4=i`Vs?+FwXYv z1kXBq1eI&x{+1n>T4R}Q8>FrbhU3WuA8N=-fC_F7JF zc*y?@Mu8!`J~0_cF-3!q)!D#fD70Z3We z_+8Umj+b+X+QI-~N5iX}k05$|vYfse8>&No>bm3TL#ad}C6g9@{5#*gvrK}fuQ4e} zJBZ15Yw?U^^{i2;-Eo#$6?MEgca)N%OGZOO9{d=_TdUh~S} zDK$+JhLm8=Sk}Ls>}CA>t;@Ti!oV~pzgYtP zCUlv>(k4Dax|NkFNk0HjIjL zfv6M=YX@6ZShwOP>s#4^`g5?E%6P;jA3a0%wVS|hmDFmOxy946i18dGq47r^56Vkk zMvbbXcqH6hhplHP3Bug(In#&TO~x0!^F4LhIvxXz4NmG&vHQ2cD9X(_+R55_yzmxR z%C1nW?Gr3M9tVt6j?ek>AF;oM7ewXGSGp)`i0Xwyi|4lQ3pHRI_g4OT?-IXaWpBJ? zSXX5x#~IoI-WtOZ9+@!JzIyiRReOx+zhc0!0QtqovR8lBz26&hJ~jKN*rEvNM2fcr z5L94=9or4sr~u_E+JB3>@K@maMNHNRJFY3vIDmjt!Hxmfi_$8%IG22ZQWw}43O8;m zLGu|M06sv$zjZH}J@8V?+dtWo??i<)K(|DvIqVn=YFn;uAPe^c2=E%N1_5#BIf#G_ zOjIFge*w+V^8;4c2%?;lX|qy>r4Ft;eKI!a5GHtzd4|n0^4otjRt)|jlX@Zhd~LNP z-;x%`QI+KC5h;9G8#Wnw_G@H9B06Ck5YS~HwjMX`sWqzOvt!XeH)dS9q>3e2jI+XV z!hdr}>7|j%}-uD)-Dg$|G3U)a&|PTp89f_U6J%iT>FQ|#)ti%Dfqto!I@y>=jh@X8 zi@ZI!)YTcVxZq1T9lGu|aN80Ke51C-{@H?U2W(oEx zVxEc`1{VX{<>l`q7Jz-QMp<`=q-t%o6;Ip|XXZ)mmS2(8Y8dm~Ib$>!DfPNK&O7{N zDFXpe&p@nin;Pxw;CacnyW@P1a(J+K~hR`WltTH=`+?o6UHF>5?wW^q1!2p31u**5~9+p3W9-m>fK|mp%|lbVhe_!fUn%6tjpW*;LNB#BB26x?%+8&`{6%CkILcu zo9~_H{TYi*u7Z-~-bX1yBo4pmmKRe(L789vK7d(5n%N!FOo%0SKE6$UMo4QBhYcgO z;bllI_be2IH-dL?u@4U(Khc3_oHp05+B_d~B*SFfHh7TJgMg5q*tr@N@5%LjveONf3@$eDT2?c z*otl0T}Ww&xJ8_zkrG1CKKO7FN0<1y{IV3C8!QA87%teo!Pu4HsQrXPL}4^=U=m*M z-ubegs=rD@gL>Is-qq_*70d|F|6bxjy4PN$CG9{Pnp^A=UaS5=RgLpW7f{qsOW4Nx zMRU{fy&h_R1Qe$j0C8Xw(SHe@PL*TAPhzsD)eSK1>X*TBS5%{>-6d+zDb{@U=7?M) zC5Re{?ROA;L@|Y?s%)-OuVI;z0$F(%G0w-^*Ntc>rZ(CetbSKA+>^{(8GnMJ?Jo{ER>Y)N;RY54FRU!4wp=lptc|zc ztG{PO{H2tec!A18ZuPDwLy(q{4uWuPZOjwecU@$yhxNBRD&zJ0Y|Gass27p@`}{e`K`={1K_N)-YZA9pf0=Z7X5%5 z?YqW~Vo!ALX6QK4wKU4AmquLvSRk+Y>3^vf&&RvQ4+VJ(Z+gCPX5c`~_yCp2?JST` z`i~#Wff>#s^3Em)Fg;v=&SOY*<2h#U`gn%%&t_vW~etD-)yV#*+{O1Xafti@M|X(T2-7K zWEUqWZf&Q}?8mriCy7Q>g5U>AV{;O}97gfdr5S;*HriFV*!#8P?Ks;sUHX`|;o7yZ z*<;F?cK__)BlVb}`}r0KqmLr?Y5g!?R!0gKRqV@jOYXG!jESi3aNJ~k;qkHE^s6yjX{UaYbG@RnG|D>hNzt14+kr?x&am@;d6n#?7%yBf)z{JJKm-ceiQ>?d>|U~ zn;TmLRvh@arX?*_YD|0qOSx5Ge{iH=WdTy|r8pq&m}FNG(Y_#F35$7;WZqSdz~%EW z4&|~5E*hdK0gJEqWoSdg)*}pMyO-{B>n(}{2%FBl6+3IM(nI<8k$th*8d{ zp|v?k<5?l|pzG12tKRV_ReJJH_bk|l$09lWi-8>iH76G{v5I8NpeAER=Pa&+W(21Y zdH`pcF)eT5H%ai72c_A%DE0zL0rcEe(Ui^$p3BYxr~O|nXS;)J>IcBQsDd9d%Xog< z+MWwxedDTraUhG?I;MR48Om$>wwX17vYuNFisc?rv=fDh7A1d&Ix8>sI4YW+6^*!{t3g?i> zX5eQy${kVXy%_3Mr2@kucYfy&Lny9n8=NK1{UV+RXxDz(V>-H5nx7#K;i+HeqfEH# z3=GF*Ou=D-VAKPYO{aRFcW!+CQoI&WH*YHXhsdPx1RNWi3)f{Dty$0D_L5|UilZBw zr)XvxZY03@_!?*~Z#qnr)wzQ9v;GFnS>)J~!Jhude5r+-xTXNLT4~bhRx%Y7qCUc{ zP)b4K4zbyPJod-@653_;kEqO$=x`q*h;?xMTBOs#q7-vi(;CUK_y{gpWqoGYEsxXB zfD->`%^Y^K4n?l9K)VLD5= zkudX42sHlXj)4izrKq01bdditdx^c{Zb?%I(Culd{AI5f!8t^r$uW01l;*RXu#79C z@UsJHaf5)8H$vK4Md|j8uq>7FxtDNelQy=QIWUmQcF>5e={qViHVbz;96iDJyZ7!+ zyEk0Y`E)cddd2>S*JyQw7GWKGbT<`2NSns*V*a)k2tFM1DeD7uIy9kx5?c*F{hH52 z=ps2sIQWEdB@JuT^uP2yBGF9#rfw6hfr1>YGQnL9N{)TOja>6WjN?bEmRDFAc90sn zGBwG(#b$}}z)+$HX?-?o?_C|C?FH@8Eshw%@f&`cs z|BSqU=oh2E(9Qd?Am9D(7WSX#ot9?Xn#jax>l9t2Tn;%GlEK6ig#|MFe}j^61*7q*+U*G%`g7-%%Lz(H_>Z;I!iSZR;r=B;kI>KeevA#+m0tD8xOJN z52;TqLgQv14(C7i?fPSfH*@JYexTI+;hi%gpBz=~4+=;1xdg=$0xk*c!@&8AM66CP zLfV@U!hFmz=!8PLB2>Gr#zlye zs09F>NcazM^b*!;PfL3fT-_zUXy1dqY**9D6`OA`@f@_|&P$@jtGY6%pT>^piRl3z zd@dh6law@m#o!gbev?kFP-6<;o(z5xj50S9a)sE&oaiYV-eO;!h6$V<3aKxweRun7 zoU@o-(4@S2sDd@@W51C#d8LDS+I5Y~R8pV}F{OiFwFYL|GfKF>OoAN(vr;FRlv>2F3|6s035|hniIOC%Guyh@STNdqy?ds_;pLt z3tlUWbznT^NZb|3TBu zrofD3_yC`j%pV<*o8H7L<G6^q!?HSLv}ndOdvmCGvF%@)(8hGY@nKA^^H^1R33UK%z!w}jQM)RS{A@X|1JsHM$ zZEuf5tz2y45@QE*__$@~`GONG#GO%Qxk-p#DVK(yVrIF4l0Nte)ju^QWds}sVfZ_+ z@U0K&O*B!`2obU_(1~%j@2Nx-=i6e54o9?Ju2H#vj9Z7TH3eH|Pc<<+;+x6)_^8Hh zg1jzs9uzhpw%O&DnTWDTba#WOdkB+uIjsIm7Hv%>foZ+j?f_&YxzsWBOj}2x}{K|xjBg4K?Sn9a< z0+b7%wN;=3>ThYFdz~r%%*(j!`$kaDKbCLhWX%JI(;GitbtFcWI2gZ%5wn4nbkHLc+uuvcJvbM?KG&;jC@(pNfU*=gF0i{UGx*# z&Ex#QgH`mwJH&r}egW0g9ViF0vQao@hBMwwC6@Pt=03N$U)?DLNS9@woV9!W00}zV zXwM%wd~G2RM#D8JmWse<;0yKZT|lD)8#<628zG$HQc>HYVnS`k21%u3UJ6<|EE!Ec z^>Y+U2d)wrOn}SOx~PwDxdT>%b4p+brNzSmK(18Mqq?}V>vTbK2nIDIY3xZ}P7+QW zCMD0kz6$D35}y0>-rcuRhBOlvIXm!^=Xnq_WR20VRU7Ftj{BFvKpP=(SulUyO|VV# z&CC*=23qeHjEqk!Ex@xiRD9=!C(Ee+cu#@8-d#F8vfv z)HJp8zzdoAu*gm|1VBor5nlU%G28gYe3d{?{S7oMQ+9Qx6g`M1KOm!GHG^}3nNWB` zXWS4G)=_{(PLv+_D@VBhr0l)f@&18Tz zb1|p`cly0d%0msIZ<0TGcJ172Qa{Z_aF%smiF@hl{}tSBw&-Pokhlhu;XyLckirps zb!@)*4$eGPrY_ABg;}#PUsxcbW?=H$VF6V0kNC>fo`5)lvWSB=?r9ikw5?e@$(3+t zPk}uU3HleH=nK}%PH1@3nUaac#YPf#lr9(&_7)}XLxg+g9p?{TkI=7O>dX4wTydUs~y~-#JTWxG5$}ME^6Hk^;5lSYM^*{1;e?cKb;lH z3x5h#jrT-8ib!`F)wl30V)2P^R_M@!6j|aBituMkZ%5_b8I|N_UxR6{n=wkaKH^X( z&rXxT4R8)7+GPDNSsr#Su-b0fDlXj@J8x;nJROOzgPzMrq^9@9eCd7Z*R5Qv;Zrt% zg~o#0g;+G-TM8<9wE-=+q)FSVA|^)3Vq>?8o!oyBgt|sCs(``e{cenbKqPoN zo^~rNuLHjRq~<|{s%Ct#6uYcd0hN7J^nlM!9}()JQ;|JA;^bh(FmGi594p|g8AKj^ zs$Jxg()ZcFvkY}-Wzequ9l_`O1w@^xx}Bsun=TA;NbY;7N)mwf(Rm%X{=dd&+Tp-S zhN=LNZFuE-0?~r`J~BP1#k#!E(rm#G?9HGk37tpc>ORb3wOHeqi1Cj5S?zbc%Xf6rT&35Fedy~Kj)GzusR>v#Cg76i_o%k%6v zW5Gc+R1j3-#iU!^*>3@OR*JYd(7G#*8PUAmj{_Q5%eQBDo?{uM%G$j)SmiBT0jw5# z5hi-BWdch#yGux7e5%3LVfzV0S4CQNdKR9oD|k?Y+$%2KUNe)cCuASSeoGCBqr>^d zluW0N2BwdU`BlXbW45wrgtkQ@`^x@Hr|82sByq#In z6sWM!CnAd3*-n}x$FB6fu^Z3^63H6EOQSN@-t5aCX^qNDoecuj=-i*p!H^%exeBq4 zTv9g|L#D_%RdJ_u@iW>~R*`jLlno+djsCfpx_e{$&&RmgNdoH2@(cchA34x~Ex4{^ z(%(j9>_`=L)d-+JJRqK?db0}bo}o55vn~{W)kLUfIkcLqB<=}A&80|(&|8mu0Y|}> z=zmPGDdP^96iRW;Kr6;hvh!IE`a4Zlfsj{ves+;ZSUO9>C{IE#sg#V!;Ah673&}Da zuGcB^oG}8@6Z+3g4UAujHbPllrfvC5@P+$&P#8{u&%O8O9-L6h@f& zfxmk=vq`W22|wG}R}Xp`O`baRAmaXnUAXr-<+`{rJ>rwIrn_HJ09afhibn^K`DL3| zQ;MDBlYk$}m|xq=-tKH_zAMD%=>bBawH9QMw!I0BJclqKL)K|gQU60U3Ay+Y4F%hC zBNv;X*FVibvN}_}GM?3C6nh}>n_3;+;_wyO5v)0oLijV6hZ|CxgO8c~o2t1P;H*^& zo^)FF4*QDm-scf4fe);ms50<@Oxl{48)@k_c(w#G+@1oa&MEHU>L5_RG^rWV{a+zA zuA_~Rgv|-Ng=bOz{$=s}NikKwlNG|=VhJy{xO8?j=XLsgkNc6bYc(VX zIvg)J$}Jt6XV8E32M&2P+joH0C=6?fzO)G1Rr-|3QA{&TL~k=B5g9OmiFV!Ou`UXg;3SLbQ-V;!vlA*pwx1P7R}$z->6n4-`t1rop94Q(*}$Z3$(Rs#VsHWNig*O~ww_q4 zdAn!hv*w*)#Sr;R_5ENY70_-;-n?^%?F&0YOt-h4kv#|OJpkZ{6Wn@aIa?D74SKex z7~hS=)O`-LEN%dweO+KZr_ZqV^e@{xVXh0N=5!#x;Eq*-a*@!3MvbY9(CJ+k0&#yz zfXw+j=>!#E>s$w%^XV(x<;qTI>Lg>-yftazdsl~$@ohLrfa#KU%9(mrQ8hG z*8E;2)ptvMC)O6%z4ECzai8`kFLEI6nCz+h=2gJP*RNbs>#{p&VZ>{;qJiq{A?hGZq*zRI*3K+8eL-7=|FjXM-1 zIqw=pTPaeB`cRV5;$i>e{_$IMK*Wz7F(A*7{Zm2nFeclXW` z_VXJEyOoA2aIS5^6emPdV@YY8r_uv{DI@7mMYIyf+1Hueu`9i1rjS13+(-R@} z&n}OC{}lqZVh9KJ(J$C2mU{(*x*aGBLbJfz|C&HMpg5`Bgpv|ke-#+>gqi7X<7X7?a0<0Kn34 zB=>=jnedc!n8u(lhSUuab%sVNy%uJSX>xc`#h~b65~U&?cPBkb*d_-I zL}PZi=7n3TK}d3E0u{)57uhH&o$}gSe|A~8L*8bG)5l|n(uut$E6StR(q*v@sXFOH zV^#ef?(&)vj^ryJZ5t>@VAYFoVeIGs>YZ#&`U%hAnp*>-%cxi+FL~UpH$ug{-a6|q zQVg*4wNs?0OOQeu@yK>^)n6nTIJv2W3U&3*`KscMi@9flsoB zzkqL6diInt@vX>jTx0fedYXFC)DzF^5CIQtX3U{U;;3H!5%qcmjb zAWzP;mWW6SYC~RTft@spI?iXFus8~NYFF&g7M8i7n$uPHj8T?@274bOIpCG~GNDR< z!uVYe(GhcOT{uw4VI5%f2cuin#HcfJmrb5f^_7!cAxZy_gV~Lg5^Q+nH{V z0Y&?gz%TwXJ>#vl(=YEpYc`3g~c|+h3#$Ra}ubsPwEkq z)hdM;jIwRM*C23aK-v1MwxeJ_J#$aZwR*!QGFj*<5Y)lmqdsku}4 zEDS8wg2b%kPo__c7xb?id5~8wAGbIRR7mIG}hsa9a^B7ed*pL#3A0B717#?}8^ z7uve(#1xcA9|&$GZc3^Q=!!<%w=rtOc=;-~`hB@&++yh-@&J^)*dsn1{i2WO0 zKewf(KC#PwFLll1GPQb}XGcP-VOsnZ6W&E9i5GqrX#<9V}v2l71U^Sh=o4Kz-MjfKHZ*Kg6RAVP?#T zIT+!-Wc8!TI0={#4sA%bBhhayP$5pbg(M+Y0{~kU&Z$jzAho7mE?^oFFE1d`Bu-CE zKxelTFQ2*JnNdVKsXJawN^rh*hYXrT{wOdZ5LDv(zYcgt0n$2x%FDX+KCoy+WDs7X<%abW`%cH?tARk~ z0!0YZA}8;b&DH}^lqCVHywxf{4^SFqNV>cz58J>`iT8 zN@pRCqHJC7%=)Kb`=s7^uR=Q8$Gex@l|`NDB1qzFDdl%*TLU?yk@lrkbuj+|kbP_> zK>3y^8wkYH#LZ7xWKBDcz<IR%A&$bKW-#vq5#-<3O~yLeq4p_((CdI2u+$2!&^--x>F~ z@8C*L?YM#Oel0ZxXO$1gXmK|+^4sfkI_O6&id=JXzZULzi5<}JWw$EETEx0Re!@s$ z8RM6*sZTlp3b{Vev7VM$X5M$opjh28coi$kuWPgIh^PMHuYYVr_E8V%lPOm?uPVCk zzW^6zUs&5G8PN%E{ROI_7w2}F>QIW-V9CXRT)}dFSTYcb2z#f5I2`4>y_HigC>;NC z7f(SC9nRMk1awf;t`nyZgivoiZlIm#{(N-xMx))&TuVtQKK^a8CQTJ7HPi3OX-$0N z9XvY8*CM$gt_sKwG2Q3;;8*@%tOEsQ8DGR55ANzva^|3Po_G7ek|_!+*l4Vx@%9u+Ob_hdWq2>Fo(67yuk-#TZoM#WU1D^2j<2fJ)#r5 zxV5&S1$WAqGEP!eZo;=S<5iaIJ^6ybPLp@djkIea>nFzFdXi6e08Y)heM5U6oltZu?{zY>M5jX z;rE%8AiS&{3x`lATj27j;4+^kNX*EfJBdB8=LJvkQ32<}FHJ9=TX97!(0CviZcHf7 z97+TflL6zL?1N#OH(HP>W_^i2X@SX+0#`dVbos8rGkuk|b+Uv^u^~3KXR;+^Wv{Dy z0sbrYV-u)MKJWxE)(qG8&7WZYX z76E>F^2;y_bF)dOu}#0Sm_jf}l9h?Mfx|k*C2ORPAif*|)d#IsBZ-a>5bQ@Y=tl2t z_OEB^Rr@${D|limSW~s#JA}%v>H3e$`jUiY810BEGk@J~G|D~#mqkoe`!Rm!m3&vH z3bvMkZxj{d%h-mn{s{#5FL*QaQFqd|rV2(^4)vyTP39$YLbK~*jlVlBz{-@vjgvww zfNxG={t%N<`S*OdFo{7B7$KQIZoj4S%PS(iBN4S(8A8jFxB(!zKDxm$%fp{V3gQv^ zSP%AoJBf&!6FdbNFT#1cZ5+7rmesl0mh2VF45r_Sji8o%!)=RMjB3_A8F_6gx>KAF zkN;k59K7AouruOq$2f|=_6<7h+-OF5xyJ4)sr)cam*#LVoND3Mk#)#BT1yXCjkVt& z)EZ7G#}@KG_T__gv2?d?e%*QeOp7`CS_9dn?Ej&tgZ&?6VmLK&@Fu2siaXt@q1QIc zd*NBggX^RjsnZ#h56cM~uhw|1zPf$1_&o)rms$+M+elFeSk43^Xy@IHzN>@BcN%bU z^^(V8l(0#sz7{#uK=M>yDEXgMsmRJ%U_AhmepTJzn{RI_PA0kV4x}?yGdMwtD!)#$ zpx^^D9CvIUp#kY`0cw*)x$K;o{5}NN8?Vy!VJ~qElx4ucQ$EuGooYFS1NkmOKY&S? zqO!m?kD#gX4C#((O)oxJAjTyXS2mUL_?=yh+Q$(_<$1C@kAZT>}H;DN4YzmnqYD>y#c#KA33Ob#lB%t5&ikI66O z>0&&#d4>a4+P2<>kD9q$&l^bF(aS+J|GeE8A{*A|39VVaA^LB0&q53^jOaYiE3zTM zrEFB`abB-gbOOv4o7^G%_fTThCNO%JA5z9+@<^7|w2iMN`bp44j79C_qpaZE!qV-7 zlusJ9Xr_3odQ)j508$QuB!Y}{if|smay+!g;Fo1o4CQaEl7KfJ1`M|KbhBm6Zw93_ z|DHpnc>s2P0 z7)y*Boga=B;PWq-M+zJvP`iD&G~kzZoOZ1<#4aBfXTAc-@cP_+q+`E<;$ioj+$Vbr z`L#gS9dBN75zuB(-7Fqa9uX+7$XqMCNF;n;8R=J-Fso`tccr$uOEuZMS?4;6oQVpg zn)7=K*a4<@Y=>2Y^bZgvf>mVAtq-eG?Fi~}f| zyc|1z2m$j zS3hRtQ}{Nf_uI{%TUjU$63js28gKbd#iYq%W2y^6`v$B8OV}$3yt@FhO z^|Zm_Phnl=RTAFa@o%C&XPQ94^7FRaLKzoZmVS)*-j*Ii>3+J#E?~OI%NhcI@v79& zi2ABxYZvbSeNG>g#cdX`>HJja+-7uhPoH*k4|B|7WtoWgdrZ&U(A82)s8B2fai2sf zDhHqBStckv2<@h$7+uki05)3M52c~sIU_o0<4$=97`h`t4n?~Zgrv3nq^A#3Mc-sW zrbt;ybhgTs4gG`jq)OCp`?r+7Ef`9;^ku$iOF;*om!~g7zyd_;@AAz^S&1}c!uj1? zvJ%stndfx3>`XuNkr~XUI#gB3g#TFLSG%v0#Kt=YfVYQDIH5Z$SO(}X6~J9}JP zoKsGNzzmOHPh->MK`5AU{an{LdT0j2sb?0LmibVcGcM|X!O ziv}pepgjhR0prMo9g}u+K|o&(aX_RUM8}rtQ&+wn-pz6YBViyg4#C9=0>_q1*c+Is zF}RA1Df^VBjnqd*gI|;%qjUSA0kF9Ld&2}BQNaOC8vdWjCF}V`VeAw@%;MtGvWDj1 zD@GZ}u~=&&RBy zMQ9P2`k0l2dX}iuZ`J*I!W#vOXeNSt;wfeD)&0GuHyGJwbZVHLaH_1MBtRj)HDWTa z8tedn<^ps-+COR-rFdJKVhd9yAD{~VzwQUF5+MzcmrHI7E2$Gn4qpEAyn^BvvkQ}U zUp&-#N=#CybbB{`@UubiChdd3_q_Bpsw*auH2_>+_B_uD=3-o50B)C${_zUL=`;?My4;dW7^~5fc}5p)-=8&#Q*A2Rj}Zlc>k`r5u6ayR=t4sd zO2x@;Hze}tom)f9WA!NJWWe}?TGi%1$n9+HwBbKEeQ*}S1wZa6yhTheL!jph-wx2^AyCLmep}WDrTWo4#}fi% zJ(kIm);o1G)$;MMiq~xmV6x~Qv(C3nvqCc|@P5f(|)Xw^56xt;s`&}(548R z`y9mbOQL1APO>zsTxv$d7Q=6nB;APefo8A*oXCur0l@WDNe;?8>R1eFMqVl+RQhrz zuIbgICcM`mjfJu5RZ+4v#CAgY>Fn5Ih`DgxgxP5lrzDO&bx0IqsMDWhtHDO-Tb$ z%dV=gBda9&bx~)4Xg{)Zd4rQa=`T6qvGx70bqSiSRD~fFHk24&RUzthHj(_R*C2QjOoXh>rZ#OW23nm19QPeKtN=IE zQWNEW|HhV{9YT&<)=Pawy8(Lhy^@>yLcVMjbD}WuvQM4mW>{GZ0{uBANJ0Ku(fhYa zprk8l_0%T8e9${(p%~^Jc}}c)#A+^r*Ar}dpwVB=4sK(9IR(=irR(otJ zU*h?>E-ce;PG^gJvR7-ukVvncU3C^7p$BpNv7~W9P?-7$i*ds`x47w$qg}RsfQHFy z7{kBZm2bAN;T0AfnbTxU_x`HtYxEYahA-0qQq#J1;<|XW&im(bvylhqjoDIrnnT(} z#4+9wf%Rwk$Q`U>@d?&F`R7IPdbgW!j+QA3oJ%TBGpJy<$cTG*;7~Uy<4Mv>n<71C-#YX z^${~(HdL{Kc=+j=wm-X^BkIoHE!(7Z=$KPS+=%!> zp_Ft#z+_>jF02W(2@1zb{ z-L6<)h;}G}e{|+{9NrL0;T1extocIfP3u%YD#JE)$`xfj(XSOtH(XYIwL#lV`Il!I zyhT|Da((jWPNtX3c3^w@N8y}8eT=YyW_f=w!2!V|<04@y;#EQtDa`h8i1-2PSkI9e zU8I4IQMLFgXL{k|W-(ZeIAX$?2Mm4#FPjN`uKhAM2Pf*g&iW@|cTi-4xh)cD@^>^h zz$i{X9MKuH%{uVUa9saPus-#b(|9_8Smk40{W3bpTD&?& z{8XZtO@6b_&)@+0Vc*87K2ynivIZlHnU|(4%9sv#LqZbhB|$m01HKOt5EIz(`pe#{ z(2O36s(GN<5&X4@$L%2EA`{nPFP(F-=za~v7L}v5yGXC7pDzzno&L}d* z=h>7m?k-=O30S5#*4~HSXOhywr}#q!a9#~7%lXiUTq;zxyy90>A)=9PaUk5p#hi+1 zi7nED%lTT_8c>%B^y3Ezp)u7tD1B|crgYJnx(Hy~17Xjh)WRpj#WySURXM%NkfS4L zP#jQ!K6C^Otf?xXYzCPZ+Bg_@oWn(sq@zQLUsKWuPIenTHi+jGzQ8Y&}g1`<1qeJWe!#i)=bso4kdxWJ6;0lb}~lHt9B4M zyb;(+T<*j#ygaq6tH92i*Z+1s@(12C6y{)_x_Nz_sa~o)P$wL@W?a#99z0ohLGKm_ z;+x_`O$pW=%BVe#*gC=wufu2so7-Sj)b)0(j}3ZY?1I48UjLFkM~DBz#G)0T&okqa zK6S10pzGlh5a~66U+&>|i(kTt36MM#KlRhc1B)~-p_zzC$;+2;DArfl=FUR!&Xv=e z;v&W|zz}w34CvfHZu)Mh=mE2KF=)^F$^KQ%3>|`W6wSjrUl$8;LHLQs2uR5c{JTb{ zmyap00BQg&xdOJM&%D4hn^P|jJiu0LIB^6uC@ltcVYJ5IBvL=T3sY&3{s0?R5tJft zg_?vS$Sz6elMx_m#T6&WY`JeWOL7nP8idno$Wp#X&qD;FqH_HEnHfN6BdbGw^H)Rv z|I4K3TKf=A%Yy+iZVvvPY&2?-iZy54*kJ6djPqX7L%W<_X^94*+g!Ld?5j5dN?s)GST@!%q)m&A&+AAc#($+HymTI$em^O9i|Fpj-8y0BPv9)+^3YoA-(x3T%owoL^shn}mZO^{ zKRwcrG~JR~FAU-5V80>UAVW8IA)CN3)aLBhXk2|zQ-IJ2&>Yu%kflNhTO;nCg)z< zn;Z>Tj)bKbCt~#JqIt?g4Fwm}@>PrkoAI6N_+Cq!s!_t+b=;~-zW$QFHvfyG6hQqLgWG?fE>P>2 zEE%4IeU+^QeT|S6rg{{wfe9t01~btWu+ez%6PO@o?MN+l#*(`N%JmeE+=p{D(^>n8 zccGSvn_jYC18e^H!3sT*l*p<8AjqO9)*>IcgTj)~q{Ecp0IfNAK|&ye1{`odcH1H* zdkh&_KK&C0x!ZIHJU5}%qZGY*rIhAD2@DFU#3Ik+TbT-@yIW+K3JC4|>e&oUBuNl2 z{|CbKwx-NMcZGx^jz^sXK!0o?Fm^1KfP){TU)S8$mVdVPWl4V1(cF(yM-(BpVeMj! z^R!=AIjxq=6>6}+SqNsnL{Aq85$$%URuv7qo|u7Y4ybQak}38gr!KpEH$uIZO+023 zweQmGjZ}`b64*yb;lH8Hf~r1i_W|ISW%BwkMsJ7`B&5uMB_l zxU-yE@{+YZt#E4yhm$4RZ=D)Wtb{sbeCrkMUHvZQ72jUW_EbcH|Z<%Z4x75KMr)|F{YJ+v2;m7JG z-}SP0#mW%g&q(lg#RJ>GKqUZ=%?IK z{T-4r0{za%N9H^6fcG;=>dFgmmAye6GpwhDuKGF|)|{?elNL^Gmrp5>v^n1wJtp z(E!mVIZ&JWRd~TN#j@6Mg7rJpb=DE(JATrj2=w9oF!}Y%?Qzhc z^RulS`fruPUUb6s-OAnFJFR#B_39cRvAW*-EQY-VKsweLhwGkACDbxlS#14TrW|Q z**?REO7@%PQ z@M5`g!rVw&R&U~d1V~@c`V=I9jTVl+(ef?}C z9Wl$s+4jeq6g2v~DpqMin{_0Q1PHNacb%Dc!UxQ(xSDe)YL_l*bOt2TUuQLbFKY?X zw5aU`Zs|n}iyQX`lHwj&q&{C|6w?`@^eiFUTzlZzH>wDc%0H@!hDtumdz5Gx`7X}m zn~9!34~m9!LsruA5;e*Q1;fAtb1@}b$Fv=25C-x541k#zIBWCx+-r$<(6^4#lup#d zE{fSOdJ&eZq0QW#=w4{2QVmxysZ+7%^}zQLuF6Q7CyH&h$7S>4CT@7hl@wKaNk@Nc?iQSYjX`7i1Hw_p=RWRvbHHCp0KYhm% z!j&(11c?rV`NS^aXTasnn%aG{$hZDCXD4M1AC5&D2mVlyypjAQbb&V+Wd<75Bwxpe;@;YeP z;Ggdvt)-OyM}#Cr?GOO{>qxx;x+@`Bb@G!#!bC3NfDzoT0fqIie||CKFNQ z^rg4-00W1jv$$6DE0KC4-++0X3%~cxt6Mi1?0NWPr|4gF0d-A{@a~a!bUE>VDmiZ9 z=tCc{ZN(QL7KF&rKbIyELH}f&NX$NPxpkOOE;oVan5hz*8Pw-u>uRIe|IQzc7EA}h z(Rr{fr2&*2YGGK)wiS zaG5HyFFHatm=Z+MPukOx%v8HvBppA-r?%R)gf8Mb`QRqEe|`%ldF2FVpdScoQWR`l zo!-gndy!Pc<$*+5Obr)G=Q+46bQcey?`ieYMwJo8o4m6HC-=PD3at;zZdx`~@IY)> zD1{-7TS7Tmx6lOXa5PJD_r-eY3&lim+;=BZNrDy&X#UW}`OBCXWs%xF_fUCL^K8o%&|V;=n2tLN_KdnZPnO)X`Y{?tNOUnl?&F`fi(2%TWT% z7h+=k!W1%d=mT&P!y9(6T#mt1hKpTot&LdX`L-t*6e7D6vd-kWMA%kK{ygI#OE7=_ zGiZPZi< zns0OZ!jQs6GMbl_aH!xI6Q`6I@~`~`<+QT?i(u4txqbdTD!MNecLcL;2_Bq4oIZ*t zXX~aVx4$~!g5bbAoDMfz4pwCdutigoydfPPORMt+$kMraCp%g|n|>RYgk(^r8dO(w zC>CU=rrZapp^X|#2ed>ynLtmGWf}keow5673E_DkOCj!{AX%|d9e7oG^`t)^S;gS$ zqXyV{?P0yv=QV5szwfad-P{!Mpe3%4F2}Ds_D4fFjz#g(M`{4EA(qI1ot%|ReallB z^-DE9_EtM;Z9Va0PZTR${jziInRuiSoYUkuOg#|nP7`x}T-8ikIn$NkuvOE%!!ejD z@8LS2bQar4{Cmi5ctSj#h<*KGk|~m4TU`zA>HYpQSs6A%Dv0=VCi@^6|M`S`^DNOp zBdWi5$!V!I4?z=l9KWcB=KL0N?i*e{MC$C+`;R@hpqa8B(?s{PqJy>HIo{Gf8DPdn zw4aWkE_Y6*3xap+##Bru)t`UiJwVz4RdDZkW+FPlvb)FFdGGV zp3v2uY`9015XuEDuT6S=x@NDqPq~QQPw2`Oh;8eHs~DocK~rFP>qACei@hhCp5Ww9 zN+$SyFjs3e8kK6mhuFYD4oBBrBL0)Ee#n5sqCk<#3%5m_7nP%g<{#8dv5Ge_$RITj~&dZE+ zqzQF30L%2Td)CF^@nxYTn(s~LaVsR3?S?Y3h~CCD1Bgr5U$(;p{T?+{FR6D@2oMD& z)=%lG_*H;NF!SY4ogy;OT5o&Yfhh_eo*XSIM=@k46-KQ4Xl+)ZL%QZdL%IY^j}L2) zQv*qQ4%araLB3a&EVy)+6v{gu2Ig<2A@w`X0d9%~Pp(}57N-@Q zmW$$)>_@%wkX0z%7|-O0>uZ9I0nFk|=R9?f1n72vhR1I4OG?>tPNH*^WGTM(Sz$fF zR-CR!4x&{^S2zomP1R?{BI)}Re$nI(c?WoGT1%07^>+~=|KDx}>&_J#zn+~X*v4nMjG{aay^ajldE+$s1IoELEIX-tHclb0D4qrNe ztPPjTRy9`a6mgN&mqKATvaunEyUmOli*DI%SEzEJb;pF_pt1q}7p;Yhp7^*S)?9K@ zf!8(^aD2loIO4iZb~6u}Jx9)CB$hDgGLk$Z4lAz?{7Q+fBjtLhIG?EXu~3!yeaN~P zC9ZVr++Hox8&OV>$R-7<1Ir_O#aFS*&TSV{|4qWBc%^YwDVp3YP~Ur&SsvDG} zWj0*05b;Is*1!4A<~jEh0bBH+v&NNA^N}dxF(~V5!R`Ip*J$3SBK(q%J<`0RtARWM zMDnu!c^Zq)^4!>mni+RdG(@B~dE7LS$|Gh+h+1B|J9&& zr(e3N=8pZ*Il0!ML=hAvp9k_nJLe2F-7aS;6~GL$T~l0H5h(pY?<*Yy-pQ3~JlFL$ zHHT)eNs=1eYs81ifykVP6}i6N0&ToP?IXxJj4zBRxVVT=Y>;I7Ska|3McX%k_;reqH$as=i?{Xqml%0Z% zmG7jz$1C`k3cy@c7=FnXowOoh@qOOOkXpg{xV)G_TdFh`v967(deje8XzHhPB`VXqW)cIn;k&h=+1>-=Uwd(EZV(y~Ma-fZPk8U-p7 z0bVE>5dE+eBWO8IT36ifaBff3D7s8&3;zbLN7ox4g=XJ3|2%!N#P2`Kb>f$O$6O)d z@XOlz2uQ8ANTrMa;N#&;7bp{6LN`%&ag^lBqFrL6y@S678_JQNAZwnNOsF$4S0v=}}htX)T2L5(skbE3JH?)G` z{q*yHxH{;qQB=O*(EDZr;i(l+d8W#7=>C4bMgq(A4KDWw5PgF>Y4;&+XvNw{E6`w&KVY{PCR z@aP;B)rxq<+(C_zXAKc-a6yS{)#W00w7U?GD#|eb6!heJ>JP08vJQb2Ax-LS4Ss6K zHCrV-i{`)s7mjtekEcy)5z0^g?taIJo z3K|l{kG!T_cL^r}q@I%$Yv@qBXd1v!YCBb3HyhQA*r!`K2gnHOljCcuxlW~&P-F8c zCn7eG52$Sk=P(%di)@pT%wei2#cW3a7$xZ}e_-H0<)-X+Ee^jB@A2;t{CgtMM1u0 zTQcMR2PQm1CY)O%_MJD2YKNMoxjBS(Z&O4r)RIAPp)9N^RcIcP{FIim@Y8ssPC)J1 zLCD3f?d9}JcIijRqpe%3q@O;%Vkx|OXaz25XI$njS1hI6yLz!~dX88WpN3`^Q1I4t zrBt%BrY=V!0m(&n!9&ualA={h4@}Wc%LD#wC|nR^5Q=^S@S}!zG3L`$$h0H=^6mO* zOA}x|eg~~@-Ib+CgTtZV{nPsLnmd~t#3p}|-v;Q*N>iHkpAbiQmZhPoFN{aLM92}c zjoIcmJQ05Pak!m6q+i1BkDT#caLVEuYNVI@#V3x`(RC=GmOF04;m4sZV0hEE%^jUr z&Aa1fEvOtT)-FckTM_s)a(#Qw&xM~qN(Zi>mY0iQB`CKf!U2K;CWy3BA0Lxaz)siO z925KveD-0-QnX&|nkN1)!>d3$>%Ir$v_Mg_TKmH2ist4?+$!5}mxV<-SFsrm231P? z(Z-Vhq-OBbH1BrQN+N-y>9A5@tO>-m^HLqBLWv5~EWY4`|L=zs>;93Ef|8BseD5(dM*rp+J!*)$^6uKZu zAj49&mxx}`xuPqj)58<+y7Q*Ht|kF0q0zMwH6z4#wj9Jq`jX^SfyUFS@=SbUg8bkw z_#Rwyr3F|0n||juxcR6O4cCc?4U0px`+kdvV&ar2cwh3HX|VCR3MMq}seocNLY=55 zOW{5A>OGiuKCkvGLzrIx*}r%AVo;6fh%&6M{o2sMSDl^;oHFigdk01q0%0u7CFHB{RWA{Ovn7^l=impIc{YZ0*qUCG zh9Rq$J8wkn^b=Xu1Upq+fHs&U7q2-?%`eGbh}I$}zCjROGAm+)G}5;G^4?VzJ2ZIk z3Q7KD^gV;v9Sa6xDw5TotW9$9!Hx>@)TsorAH`J_%4RHLo$-)6=G0vK9ls9<3?;yb z#B%4T(WP4%_VQK-e@??l zpZ)8Qhmxti@Ha|MAVXlpX;zHMMwOYI>K|n!?x!`+c^E;isJLy0oRc3N1VTUtg&SlJ zyRL)rx_Yg%kX*HOA^7BiqlVK<&n zaVUIuQ~$RX^UfKRw zK4sJ^Nc$tAc}1WHOPM(@FbIz$g!#QjAB3We`I^Qw0NBiQ{Db}ZaVg@g@0#-DcJHq7 zBjgs+W2c_lLxOfy&iydpH+5@WX%hWG3g9Mxz%qgXnli zQijZYGds7xM8kSt45$yEgoG@i(8It)!a$(Vk-~|d0x^#OO@O#`mn+&wFcM;jyNLD; z6YPe$l77enY97qSG3!rY*!U-G9%%kj87(A5fXb`=z|fn5w3a-ae9lA)wMHNoE4ca> zM5lng1ID-Yq1>vMQR~TVe9l)~81x_wspSZ>V($btGVHgK$XP|3wV@a9Hnx@ps~FI&vK5C-2yP4^ zkWY9nBR*5#(v&(&Q@{GjOU&UEG}nc*GXX%p;LEvrjqe99$LvXos;_1$DwQxC zvRa_9c%wD!*Ic>!(=8^Cq&?O{Q8Xyh?wxR0AE1dZ4+lR6-m!WEUmPn8P>_d*j``X7 z_ShP#-{gw!6E`IjPvC+7wul|Z$tLE*9e~E3{(@dgu=nf&HD+d5zO~?Ur8WnRW z9<`SeToQ>((6UL|5t*}ohQVw=vw{v)r{m>+u&HiX0vu>4=1-b2S;jzp`6tGC>`o~? zWyCmNZNC+P!VT8nw^6`kIZoIUrGLbOcFP9h6vXPZxtKT|FzFT}NL$S1Gdwf)zWUPJ*%-KkgSOLOwQUZQZhu>Dg7d!LU*&ZgGe2b#fCN4jq;Gv@kkn{|89H2#X!CzezIZe5< ztmucpeM-{(Jw<8}hc8a8B*n%%%W#(b zM|z}^8L<7lJt62joN}q=Kqf}w5R^OD@tnLOg}P)f+U>?jPeshx@dHgB?!xq$bZ{P0 z^mYIgFq6ynbXmjz(~JpTrIRRxa5bKNBx1tCx&tjf{X?Sz4AhDKJKK!MVpbiq5om_4LM6upq0|;{q{lu%w#68#C zQx`}D_&sc33Nj&}t59OQUAjh#*e`TmhLK4u5L98PLhi~PVL)-TRt+Q#;>DNr-W%^T zM6xO(4Oe$_oclJT(xR*`gVtkzz&=SWy8Ilfs6pAz!@OSl(+HXT88!i zC(DRny_?YH{EH*+@P|9V0<|U45l0r7i|~s!t6*fhfRtx!K3ffFG64eINp+_8>_oc6GhE zanT~ZRntrk#n+ISwWyF}PGS3GS{FW=I3Mit&baPJsGiRTN&sv|kf z)|XIPQ07qk(r~QX>?As4?)4b9m;$GD?Z|w*qbh(Ez|sxL456ihx$X9o2CWk$M~5Qw zj!vp9d$p7sUC$yD(M^IJ0nh*~XBzAp$A(5af zwFz6qw|{Z>vT!mUL81D)`#J4>Vk5+IO{dB93RA}FU%=?340)=mY9R|eblXs+?6058 z?GSVJP;@xboc(#DUon)gS*^XB-p}jowFu1CIS{AO45dZb55|mVFh%at85)TZ&$92kgoB zQp=56k28OE1b=6w5es#2JkKwt^@f2iRR!#4Nrs_Wfj2jJZOtAume_#y=QgYB87NgCoO9vq7*h)5 zp!_q_B}61qXKMY!*|I2)!5%me1boXc+D2_tWF40`V?32I_&ntldhQU$f!B-)2b@zh z!nW4;lEB$*S72qcpUd6vXmh6%DZr*iaB9#l0!>sR8r}dWoQUfl;bkC18@ca2V1X{f z#`#@wD>PCY*dQ|_@bGK7L zuUtTq2^;CkDc+^sD^x4BDv&6_4xD^yGI)K7wEK{k(KoIwdalqauq!o#n5>?4{4vxQ+ zF@aR4K{1m2iGZu(h|JiiX>Q8spQ~CLAv=|o;`bK)Uc_yrVSAoQOco_I2lD3fdVzi+ z;i^gfaIDtP7}1`5?_??VwyA%n4T!3!D%U@hu!J5D)RYu&!d3X3m6fY{V%9~<%>pJW z#3rO)Rd#`#Kp)oMIpCaEj6NO-i;(H_A=u@y7j$WGGA+J7w_W8NFxXw#7{b#?)Q&f_ z;Mt&ifiDW&_TUuOI|Qi$+FLHX4UwjSu})>tt{kz~MsSgwC<{5xKvb|ibfMZGl@D3t zah}~0Rb{V}{0f4xodr=<#sOcJkHgYevf!m=rRYnvQ+Qf>+7(^uw+WgO0Gg*_ffU;% zlcd~RO<>$Y<8%eLXSNNy!q2Ge8i$0ALI1DUgOd0%w$oU1xrm-N7#A?)G?LoKN0-Lq ztON}&fM71_EXtP6fdtI71^Qq4*2x|>g>pW< zl(aD{tZjK&?dZ70wjCE@upMKHQIDlSd4m6ACgizMK`GogGrogHXMs>}!4oHe2i4z2 zJZ9vwh9yzdKgq?*C}4#6$lyC>;;g%cy)g^v`*NfVu=v}s&bR8Wkpk>yFj&*^j*qkw zb%!XwVycQ^Y!nE7G!RvK0?q$tVZmlL<^42R$WaW|6i5+R&C78JJ(KsSG~sbhjz$g* zKP$vhv0n2G@Su$((z_Z_U2dZeJa!EQbzOVFh#qR_cY4iF5!?Q1KY>bx>idm>JM+Bj z@>#zX^o=z-rPYSR!%KbOPMZX_@w2goDpv9q{OS##UjUxJSIG2Q|KK0rd#M(Z>|L zUS9IArMvn(SjXN&{Ti!`XRp>ODd%KG_E&9yrXURqNUq`pp7za4Jq`7&T^6z9_QdWe zA-tU8#UGnN8>@?21sR|+9vRqu!JoQox#OUsfYP66J-(mbZ!-7KhQ9_NJg&(Uf=Gx; zd_8|8I>@y59E*u-nQ4=^G243-<_dW)3UXI#m-XoK(c3gw1)Oc1J8hCeL|I8&4{5&v zdJw)L+z>by^u?}Y8n(DlAe(+Lhm9XN?cUx5YS^|Yvy2=O%Ixs8O3zQg_G#fg_n+{< z5>AhPbC*BITj|qk)N-D1TbwA@{zQ_@Z9Ra)a<&d%W}p5OC(q$V*Y2J*>j-o~8PTec zsLeBS+O z-l(rTW7pR;ymYxKgbHO>@=62S@MF>e_I{AlCjhubL%ThE3LR(H_sZza{!z&(!JN=T z+#_n=%)mGJNP4vqN8#vbCQE~VC{nb~(p4BEGjAfo*jp=op;qW)5Ult+Ewl)~Unoj!N+C&NpJz!8E7WhTA~AN~?4=5% z6pNT6xhAKvVLjHtaF%%GIBO#6>mX=l&i&mAzXYCmWG6?hG81T82<=Cfq0%=>h-m01 z9_%*6-*wH=8*tZFJ>$^qVP^%~d)g3cbO!Tg3R#2n*UFy8YWu>N1))A4Fg_Vy+@Ji- zBPSj&5j8>cC0lWK5`U zY{8S0@$YYI;OXXH#vRTl@Y6o%T$pjtm?&|nEl@r}c+^ve{rfB^3XxuwY~B&eFQqcN zzi|x*F(;Xl+jAHZTGB=VDN0K7{lk$U9KO-$$$0)9ZL`gpX@wa+k}X1*}gV0 zwANmEA~?gMg(*rJj7_TkFhA}l(v*n24$X@y-imr&0~Ze|^&4;`ehO{u8c9BDtkjr* zUpqG|L!^^N!BNExD6^YTYzg1a%TQHVHaUMTOV{*w;Gyv_&w@ZuP_~+wdGfjif#?|_ z7HfbL8Sc5Vm~{aew;JRa8AmkY($L7xfH;y(0p4qbQL^oC>6(r>`>Rj+0$SoGlDfCV zr>tB-G}V1P5y}B3RCt5V$}aU-|Gy-cCP5<9NNrO`jNS^c@Pid~A3QEiOV=UB-s6N+ z?7D5lUy$E&vyM7}o`RA-ob2GSKLfwZVc)BJu4_lEjL@w*l7w8CB?FL7N#L6+{N@Ug z+oGCxfyp-{25UTIZcPxCsP`nqp#1jEJXfO;EFKvausX-n!uVP4OvLi_pYd3CA$uOe z7bJhqr`K2{kL~eI0M1;2mK3sv0}>Ruy{HKC@6D^(dmrhYz|A_}&j3xWwS4Un0AVT~ z7TNsU{PYw?htMrWC9KQC7Jb!mCfq#@%6(uyiI)g+cNlG^XrNDSn>vL3&2rN{Tk3R` z&@Kx&v`G8Zo#pcl5l{QiLG}x3kG~}**l&Y_(M~cC^Dnc3Pk%T>gJtLn3j(g-!z?YE z_tWZU$hV!iy($4>hvYvM4puCy3gzzH;t<#Rj=UFOvxI$TL(#Y>kp^nu&deGA$HLz+ zN;*En7q4w?2(xp%CHz;&bN@2+57~6eM*QAl1cVn>#6g1v=(O@gm6#ik6@f@5m1!Z5 z5l%RXUg`h@u8`k8eb+LA1g{JzHlEDiuPx4lMAL%mhs$2HOJiZVSCNAuKIMC)i_<&`X@>9SXj%=t&al$Z9Dn zFgvDEPE~p7&$RNyRR*{T*C%=# z2rCWYOo7QTCjLkKI&6t~cgbqYz4^e^Q)%Y*bcm!}?+O(cwdDHdn;|VlnvqKQ#IJR15U4Pu#T&wiSVm5h7{|xYQsI3OC4uM*(zAWjM&Y7 zhOtf!`w^Q6_%~t`A{@LCei&>-;7uZvsLKh?mnXqVtkN2J)1$4~EEInHVKG?&y95@S zaKisjKR=`8J=iyj%Xif4Zd$r3YO-03e`Kjmk8wf*A%D=>;3RgFyO9YTPO9UM-rpjN zKm7sZ<@a#?R6U7{4JTjh$;w7we3@F4>}6w(V;h&Q-Oz=S9vi0S9>NMvuNK0nSe3;7 z1+G?Bz5OAUt%pfHI1ooq)-9S~C&UXDQqD}pk*XLIDAf^?gz}eI5Cjb_hDv(PBMqn2 zQclBMGqQ7Fll$$5P|%|#80haL{nn@Ow}88+aO z5|TwKPX&x86X4hOn)vz2@}L7kv()Rq>_`xh#$t1%cM{Oz8WyCACz0uk2AgXqC5%)W z$?vcda&cm+@=usDfbOV{CDe*k8Mu_RU;&!t231JuFYG*n8~Y+Dy-Gi!f%zVCjR^*z z-VC7%$8`CVlr#->%)mwPMbf+N#snBKP%X=px4e>}5rKi@g!TXdfXV@o<*4?RLhWZL zdxGv{_2;0}=ljr!!aY9o*bs9oM>QF?0!=nzjQT;hJevw>o+t*=OeY};mmD`J=S->z z3E>C}Md z-S^I`W|RcJEmlTSCa#2! zX5D7)xgEYg3pL;Du>Ymw$A`er24n`poc9vo`MRR*UBd1)8+s?X)w!w`6RI$2WL+0q*Z0P{gb=fk zGZlP@R1pFigZfZeeqqF>w?k*ODup+~XA|Qm3Iaj%x_w+23hR#~SULj%nx^6`#ddK9 zf2Aa1v+~_)CnMgg>7k|jALJMN5LLewvlryu0E2pXkcfk1K}vh+m-#Hcie_U!i`00Dgp41W8ft<1?n2 z{!YIfLD_%k5=Pl>HG(N_U+t0td0y;T!w$|!qe}HXHiQ?i6l;?Y>-3?`bD5$&GVfqb zD?zV5^H5q)V?C+DXNNgKBD4XUw1>Ak9`jRA$KcgfG9Pv*!0I5KoBx3&!CmRk1cb#w}ByV4dDr*E|B8E_UYb=rLrU zdKQO2E?yafl9Xe4v4Xy!#GgkwXS$=bP_7tlP;nAfc!ZRz-Ku3j4P#4WT^7Bi{pJs1UbLhFv8q%F zbGZm(UNl<<-~H`wdsmJH*ma!Bgc#Ohyrx)_WIkM>gH^uxe0&q`V88U8@*xDVrack1 z_Ajb!;7wZo0%8W^DRiXo2k4@BhXQ^)823mKoxkYILu(JJWye(NHq<~QiwN0`N_0D* zL>9gyt12^Cw@1-QE0YWrPb!*wgu+{A1s~`r&faWc=jRM}8}M{{#4mZBLK9V{^r*%@ zl*Z@cG>v~&Vgjqu!jKL4d-SXM=w~%>1t!#C0$sGFs6xm8jtDmONg|Q^)}>Fj?cYD0 zg%{eI!a9?&q#Q)A)m3}3Vm(Z&u8N(w_6AaLkYGQ;8p#m{C64dXqYx}m-)fg=Fgz`j zaDpOAH@~(;Rj$M?e_WOpob(#61auKa`bk@7zM;*b_*JMd6kz9GXb`4jnEc#0HaBxGmfH|W_nvz?~*3kP&5Zb(T91Sd?T;D-3~w($%H8E!4{|mRF3pR(`#mdWxJ$@r9!+I$9Dmf2*;z z`yXc}?Z-!RUerv@q^553ba{ zXycdWi4V-otzlYYmS?z-5>p2)>Bh;itNbK>(TaE1#~p?C4Jo12gv6`(z@;k=7i=>3 zV+5=jzYGkXXouLQ&X+y@h+35+HO*aNg>L@K?T=}m+c#j<2*2NF&7j`DY#9i;VS!+c zWRYewn~jYy^kP!%+oRN(u^!?Vfl&F#8Pcli%(}XgrT^f>U|sm-IB?7U)}i^?&oS72 z5F**y>*=DP*qCf>mEDore0T+W1A1iO;5vW!NEJ+!DfwA8oxV)b@cgn*|=VcrsCM_zr>~RQEe%&}!?$SM;Wyj@2J`KSPMrnP; z#{@3m^jiM{g%AG}xtjr#VUdUlbIdrL81u(Mf184K*O!CqSE4O}wi2!|s7-va;?_l) zfnWh!){E{a;<~uXx*p#--hKW2xwx>uKQRI@qxt{RUOwOl84jk5c{+nW7Z%K^<5MCp z!>c)#TR)oHmjW~~-SKsd~#{R;KQ5e%pRO{BHGmybwipDi7kISI`ls# z{zj)qmEy`tSEHyXVhl4!&|&Ky^ud}AXtJpCN%J#a^=abU^)4jv``M|vm8>7A3k9X< zC=3HIhGEsdl^Z1kzv`$*rWR4ff=GZ5Ua(aFf*S8KfAi32ULT#DU}7is8nJhB;fy@t zuOE^5DJxsprK|V{1G*kuJGW!$3XToyzsJ=W3#zSEsp)@zSL|!f_y2*N?=Mf-NwQ^T zen4q+yI_xrd2ZF&FG`{X07*mAJX+%;X%Z`eddKlz{YfI>asfZRD+3sA4%f%~KE!md zVi0msjJ4@^V_rpy%90>LSi0WY+gt_Dh^IX`9XL~%Z3h!<4$T5dPT>))FdG6bZe52? z>WNA&z;(3u}JK?x)7QfdLPKJ%01 z>%}!Nz}m8r6!AjzO(#(YtFI^lMQG5_tV5F{TSsxJBa>WU3a6?t+S8R7aHa8Gyy<>q zQH_ik691WVNCWBmSckW~5eV&)POw|fV`Rt8s}T+JF2XqOR;^6%vEJ(=wN{ff!)8cL zO<(rETMSSQh^6zKp<&F-eQZO2PCE5K!Z0Y?!#_c^l`qV+sR?IxrOA$+V+RuzMhrW7 z)fFHX@&x=2xfi3ptiRBVRNha`aa6^J%7RqXjN!Qo6mymKRX?J0l3M%#?82*w%pGW)wB%)x{!uoiOM6T5q)YeWEc#S zt4mdrj6sx_Ldu_{05De1kKaJ{tX1EFF1fEqD95J63nT3>K*I?pw;9bDHwHw(M~ca;656^(?T-O=!3^aIC9 zSDDy_yxI??q`rLkhA99$*Xe*pl*7i9d}>9y2xxSZ+L;>G!fu;6&Vb)$ zC9DHQX+k2(j1L0Q74Op%o;4JR!HO3u{ z@A;Gjvn8QH4-lq**29peDitGKj?EGW?eB3}H^;2?#2|AKarqim^fK5a1LlgRuag!b zXPblmsI=-7vPA!3ki{Gd*x8Hqt$h2#?MuVS5skUHDltHnh;^jlZYVProe{#I_>ft& z7QB{ro$&Hlg;DQ1cWZ56?!gA{wQPqBnz0H-jxwTBFSw(f3yuR4%3!`P1!Xnk*WUZ6 z4WB&tTnO=Lqq;B^)>4l*cM7$jF5`yl%#QEc)3BI^wjdo?fsj#&PNv3pM0NNLbRcwi z(mxY6vZ;RVjOF&DLZER-!p7jQ-#ClU$Vo_-I;)o^!fIN%XB(SsU*_sF>H7jXPasqu z^ZgzH%vGl#fP=76n}^TEM`~_Q$&n>2fuxD9hESX)6NSUy2 zIoXZ#WE$3O^-P@P-Q4i~`}FzsEH0n#(c@_E0600EiRW5F`mPVl_y8>7lkjXOnZD-1 z>RPt?95V6s49yu~8^^=*h}Y$5?z?gHAF-=}_EmyFseZEpdq?5UWXi(glq^Jn?S>5= z*cLsT5rj#&f=n=66ZTeYEg6iAS;8HH#m|WTcvG`O^RN4slteu=+PkrB)AR>pUgUJv$h)F;W>y+H6-EsE+pL zwg70Om|%oK9{Ulcd|0Wt(H8>Gb z5yoJ*{+s=tT)os>;AB?<)lR+NOdYpovGKGE=^o_k$tK3Mp+O!RP|>K}U#F*7gi^qH za`qmnox%6Ow_{)#T_F@h-KI_^R@jPyHI$``1PIX5QCva3MBL#DeI%C}319R7Cy#72 zEYM7ypm~&+)JY|{d$&uR|7i@Y46Omi=qFxj=$wU$*Jrj(7Na&+I#96a$te;mOAINP z20)e)K=?Z@9}Q8nKd9rwnXFVPn8;a@x_LjYD6rv_^sFTK4HC8p?oJ^j#l8CsIaHv3lLH`b>E0 zfjpDcH(6oyR@zbAAELzh7|Ee0P(OHV!OGiDxZhzMO{b+>Xz|9ORVU7$ti1|!rqiS8 zU9p568`&9PHo87BpjpYI(bOE8FryuB?8LBU^A|d*ZL0O+%pZ|eI>1=m0!dI2&~lwr zgds^*dPx2ypQktrx#?5uy6bG{36C~@_nKTva?LH`o1hiYGNB(M@z49C>LtfZjIfWetYo-XN&-9Az0YiK{; zL7x=8skueo%m=*=5ugTyjaZU&lvc-F1Pi1Aq0YX&_t|i*=gO|{w>t9G444TOuKjI7 z+B>)cVo6!^FeX3((&va%;V8;T(3Od?x>eR4Cmr~(>e8{hH$r%pT^C1>)uPo1kW`ld z>_P1{*v?IZ6NQY*kQcctlaSbJ2vG)Y6^narpL+QbLM-#I@dPdcMF1Z-ASqLVkm_>e}YWBRVP5?`iP0H zMJm4(!3Q}oI8Ju|6cI$N!I7fxtql%}5Qa{lOqE4LD=J&$wmS<$MyGrABVs87uIO@_ zwQhl}ukPZDcTN-5&?Ow+fZa&+b}gyu;%Vzlmj~~17BF717)N0xX6QkD5gFw*7Xre! zUjCV~0CUzBn>SIcGJt<&0Zk=>$EbVz5G?Z2%VTzB(d}k4=!K6ffGnIq=Swiu1`+5b z_*M2}t16ENL1incf0hrIyI?@BV15HL-r^4ENk4`9d63qp&W#NHtNM@iUYP*ckJMig zf&-PJTu-UBdiQ!{48kIranPFOhmfmJ%3(sCnsMtdF5dxOuV#Q;c}QRG&VNd%)2`&i zYuI(al%aB)t31vb7x44dmt+YG!?_dS1R%$$aqzaA^kK_~Hcw3(H(VsdK2fV>54Ich zqs!)I5cBO3^3^AI?&gDW+wH@>##bQL%$kF9P@V#|@S=g$??(c~01Qn%IRX6V=;iJb z={E_>UOXi_Q|;*AIvpwioqDMNyC9Cud609=40A=>5GfK~$Z?9UIx!(+6*8z$hTf-+ z#{bY@i?KU&Hvl}N@3i=9oajIUOEjwGnzjgDIeoRFObnH6V-ooe%>(?6vMmP;apUwQ zGGMcWU7Deh6|HN}T*E%}rHkde9kNomj=bO3DraMEpqe|9hQMgX{hF-j&kGH-k91Z! z$KVG`;E#gg2BhAdlusO&wwPHqYN3OiEm6MIr+-rp?L#s= zgLY#?g)!S)43gQ{M_5JWyPKc7cXyuQX|O&J=i7u(muyDTnA*AI;v@DgvPem$N@M~# zbNWTLt^B)Y4I*lhIHPd+o~y`eeFrA*eS1-pbaUuzR_Z&iT&>%_<%(x1dlSEQ4;(Zz zq;}13NP0ICMP#kW+IT+prCzwv$)k2%!9-RBOFCyca0M|=Dw-@jTE%gDgPz(49*7)|cdq)-__?3<0_{!x?OdbWI`3kF-}VFiMptfFX$lhd-AO9=bkE%|B9yqyQ~I z(!ZSuwSzTR5WnjC{vfqKu+J=wf;TFw227wkk>a<~6OQ2KL zxPudNSQ3zjSHb@T+!k&$<5it$i-!FdwRE~?Y^%xQ_FOz#{Zi2}dq*~HDJju<>qm+= zqeDg_btgDA7i)OT(VI+iz4cTN?Q7Y1J@(ZrUeblN2kTEDq86Ws^kVO1N^G{@zBBP? znMU;d#g?Lf_2!XSqNZL$K9OHsPupRIlPt_jNwZ6-#5q{8`$rFZDoo5Nqs9Sj`uj?u zvj^_jgIl(b=kaB<>Gi>geGoy6tY>-$Of~M{fBJ{hn@kNf^cBzH#HY1=>uRgOE1gDx&RoIFx zau7p`^jVIJNAHxJI&ImifIbU4mT=6^R4S~j__Gcq@-`~CvNE_SH3$Q<%=6C3x0mK*Py%3PZwGZI>m~7;YY5Kp zE}XdKt<%g#bar5PR|gY=)evMv9}0PiY7{3+*P_y0#Z`X*njPAphfLeu@NE%%YH1zW zEX}W7Vx=QkD_=?KLqC$kL?K#20^lD;_1qq0@(-Z^hQY=^B+|R?7`e9U)OR*MfHgN` zT{A4-H}!jU)FXkm3b&!nK!g)IA+dB5Q~0oH_(H*`H0(IF0yyOE4chA6B2>eh%kcAI zITO-KlO*Plrz2+IRz@8%#0~lOPlaa}FB%M^0Pw2eDB6fvkt4{yvwelm%>_~+9j1>_ zfX!H2t9L0$;p5K+0`7;I@$&p|7qJo0#T+Xe zcWXZfRYF3WWL4s9#*E#z!`t1P4XQEcUNN`VwpiI-owo8n~1bk`^=v{@^v)a|8lUq`Jkbim%ER)1kiOHdqxBZmD=cG-9-i zn-#1>JTx>O(CY8W|C3NdkIjm}8dep^XXmCQ%#h1telhq@TJ|;Uejp3@6{L3{kS6zvg1c^4rv? zh9&jlU%(ip%@masvbUlsi<-<+QeVu?E0!%yqO1KV%-8#9>?(^94x}5!N@dv`hUb zq^|%#bNvw>I)H$ojHa8>+euVUjU8;c4R=oOT&6G^4z#9mJrv8RC6F(MC{o_+aNsq~ zdKX#eR7AfMROVal#|LaywCVgXJVOKGc6tV`SxpX^R1v-JbOC!au=rP=Isg7-op zk~$kr;xgxr-KMWv*_RzCCytS`%3k~x32h*_S(ko%)d@KX7Qg5%&JFSO%Xxd&U5&W9 z)-+&UNDWW}r{qKpanA9yhPia{DgAiB%JY3v31vUN9a%;s0t;8hnrel~A{ayTe$@}< zw65P|X}6I1Jwj(I=*f-qE+Ol7U2O-se;|@rHk+a6t<{87@sh@=1uB5OMIp&wfYoYk z0wqM!U#rMer!_bS*?-q)wluR5nHBLlzq_DnV-Sk^3mDKc<&-Jf&WW|fucuV58sN#0_N+g2$yISJu<^u=%yH-dT1ej zX6WC8>qi*O)cb81&S;yRzJQ-cte(o_ugftIphOHZb6GjGGE7iM5J$S?PNAm&t=Yy2 zY)(6guOQ?SiAi@BS3z|99%P30RhwE9p3lGTKD|y!A5Hdg_9ofe%fqKlGJ^{s8FF() zb2tvf0YDu6${uopwUgYz4ZrIl zjNU0X0=)e`AVv)*@)Ra~J(~iw%wWS*0T3VZmPn!AuWUS>IQdsChdZK}%X>y~5x%xJ zPa;7cV3W9`Pxux&mcAzV)trabd%O5Tuih4BjrZXp04c%U;h`V#6#kq6ev z4t<9nSwQ}xQsXJ9nm_;7z}k?5(3{Ch0QE1n3W?nuSBGTu!J#5^xCC3|1=_sz&>BUI z^TP5#OY*0Ng3%`?Yi8of)`fB@@5#$M3!1g`%WVn_$Gi)RoXI9bWCr{p4cP^~^?U() zVOE|uQ1!k9_6EV6Jd1c7a+*CZkS;2n>{H_qK2+=HzV{$Qv-NZ&f%gii!q*^V1HM+m z?CUMR_mf7@upM+2$ebsgkf1$0_KFp6(9{E#!8_*jw~5HcO%Z z)o%-_Utfu+Gj0?>23){Kf)`Duy8;B#y}YG*V~i_zOr# z<`z?Wh#IY$sTPdR6Ax9OK_Q`#8os0?xA%i-YT}i**5$Fv4mQtcDsU(eXD##!U(8g} zWddY*ndKOiPXM}TK3&G2uYtXOh?f^``74%Ae4$Y$ygyil2>Z9gA59zjaifQd>yr|m z&;;*~9>QuP6Kdl915ij8&tHoZD`5b6`4zQ1U3Dk4$u7HB(vP7sXZ*o2pxqdb6o2rh zB@AsVwb$92h{}=OmS}wxqjN@?0@KlFm@g=sAf}ER`j8?}qT2K8ylw7SNgoCtQ zo$mEl2(){`@BU6`61;gEzL?(wFpI0-b{@gDLa`^Hx#&y#!axTU8P9SooVN&# z#b!4=7y--{a_o{>ZuE|i<9`4aSeRI?=8cbM@rC=o(&aGuk)qzT8E2LbnlWO zyqB6(>b&f#61pyv;Z)-rw~p>p>Y33RGy*wk8Ov=0ERe)!|M^0Y9`hQXj=Lw9X9v49 zgm4`QE$!IZS?~k6_tsC03J4up;(+^_2v9kwc-U5BlN@fooUoK|DB5V0k3B7f4lF6l9sn&mdN(cVuNA^j>&?e<#s}1YwflEo zj}(BtB6P}X9EIyt1vsmzD|kqU21-NjPpE!Hk6IT7TDC=h=Ybm}@yqbGW1iWt8V`07 zw$k|UC{c$kw+~S`f;&I~>I)tr1}n~l5?5Ld=)BFyx9J}UZu|C5i#Py+M#-5MYNI(f z(O_Y7w-9kqw@avG7{awbZSQ?>Dj)iZ)wm>x&H}^`iOr^lV$||89R=XOkl97mcznM} zYc{=}I1x$HQontW%odj^+ANVY4_2w2)RF-^G`83MZS5G~A^%dcPt z0xKvV=kjVw*nrcVxJik8Ewuvh2CK)ACB(g~yjny)m}D8)Qr?WQj2DZKVcKKao>7|0 zrrQOOlwfA5XY*9jh(4p$v@;frxc??C!m%3V4E4P*AGD-m1t~f0`SD>_B&@}kByVHC z9-8VoafI|a)_)Yw8~NTy^tob^D|@u8sg~S#9c~RXBB2djx~;=X`**bTx$P+T7%Mb*hLFdKl5ZjR!BGIV@kROLgkD>f9Y zEb|1A*eK?yf%=|shZ^jXuDli&4O0xZ0@`No)0%p2;^Us|n%L!`bSb^eYGrKsqKrsA z#!R|$t}SQ}l7WwBAD(i3)#^WdGkLjBp@VY_=GO3KYPEMjSK3uZ9X5ckxqUl&mQrUe zFkj^U-q5!5Z=BUJkFP}x*W}3(^&9}_YXybP@=nut&a|OCs(jj2)`{D9Uo}+6e(DpD z1I&AFqtcK&Ip_+2d1Zz0M%|2rEPFAld$RblU2f7+^?4SZsCHNhVDjuw^LW8UNx1Rs z`v4(`qvyA|8)Rm{6Ol~xy$Xpo`-oWPb)CFBElao_5vR&gT|=tF3#mT17o8Y%DS?(Y zfth}3`(tA$5_@<`CT`&ty*GOIomSyO28>m*xv{n33@pMg$X#OiltyAO4Z=s_8DQW5 z!zn4E-TDd4Qhru_lvB@>zJQ=D2&k+Z6YQ0a<$6fO=T4orLu(K>yrqIW@cV{0X~%AP1}uTPF@=YLpo+(Tjks7FTxybF^V;+}CADG0Yz_c9;=da5Fed zR-J^5d^rYXFc{{DCW$0pN_>B9M<`F=e-}2JbEonfER&M!ew~R7rAx=}clNWcN;xZ| zMUt6}m6w2~*$q8=cz!zLneWHHX55{ShevqA1lY0wi1uVycuOB-B_|y{DOPqn6XE__ zEp(m<_!fjsx2COz4)rN^L7g5({#2c*>SP~jRfLw6G#7P2hLqC_w!X-(3FYCpg?1;N5 zvh7Zt2CP%A3%2^v&r5niWy^edl-X3}@D4Z;fb|?V9ZmC=0+FkfxqTD;{D@qX*77jT zST;Vdg$!0Pr%TpTbE#2JkIKeA0L#OYkP1`xS&5vfVya*HJ9zpDu;> z`P2IDPh7{;&}hdc}BY)nmf3urBQ%s;i~ zUzIYJ3-YFy8Q>=wnw=ZwgYCTQm@Q=?OvpU~Mr~$=TJnh5xF?TLqilk_tY96QGA>A-r>tFJd`+O)dnU=gOQfOf;INc*Id#_;>( z=`&S&D@bgFX`yB9`N(!lEPS3+*?oCUKh)`Zk-(0MI-?`J&Lc6va-4H-0>tv6p?|P_ z?I@k=!9dOkxs$E>ax|SoLPX_9v+o#vChu5m!r-r>m#?pa|8)TF#HA_ub1A&s zXfv)#o-n7T=ThQrh5xNjwg}L`!!k!a`-$Z(Z-wN|pRXTNf4nl$F~BkLGMdLZ^v`CG z;5IUvMWSMKLj|g+zr^Lk7?Ri85+rM9hV&&+>TEqYEFb_Q(bJ4huR@~Sx})QRwark$z5>k8sL;!y_270Uz7HRZ!gcvW(%~NRk<1{whUH zNF5OHai&OOtJ9)l#|meKFLFY0-&JW97dm98SrA|&?Q z(Mh_(>pWWm_j#=%F*t@r`_Fa3yekqN#bT6GdFYJ)OWCAkpmCH{Mv9^|yl^4A*LJZ-^%x6`kZFd}*%*{+B{>Q1 z0D!oAR1MRlt@FFM5B%M&YuLAuVO4<#T9ZFvGIvo9VY|C|u#SRyKO|51Iv>|J>I-EPb1-(ANjb(-J2{k$2)fnTCrWl^B(E9bg7rBl05X=)M@V0ogqk2!R z1(3dH6w_Adkth#|-I#F=Eg4cVYLhyZY1{SqOMead(NF6HmwbdU)lQ{C zR%Suoy77d^@;Cr@wr07`$H*R+p<+z1~5E`e^2n`UIH_Xu?nU7K@IL@cjfEj!P#dxDa)wgX7w%$ z@fsON5^6%SZ(s)u&0mIOg{m#xz9(?5yk`~jhoUO^5b03rdardtIx44OVJGcY_6(ou znc5s2w%)r;s0GNCFBZ$_g)=Zu1@zd+#rmIrK;r%aG^=MEf+iagnhEw7k32HgzT=ZG z6Ao)E$4d$HRRh2aZjLEg)G^sIS)*mRlhhMm-JE65POvFzW#z!AOym-}+nZgsYwVTbHJv3J6Qv6X|BKZmrlm?3Uaq9uKK|v9?qx;RJ9W8;!}Io)72P}=*sBu z=y-Na@JXv{5kn}|*~-l*AYi%iESK{3G{9^=ak;>kGag&r3A9}?o8YzzOx%lM8fd7s z6JnJq|DyEW9Cr^73dDP^hTGHGqReiu3WU}K>80w_WvQV9Iu^RzT)BuH!Ym5C*k94D zuqkn2&RXt)oz#TAQpfw)6EN-A9c!INPxCHlZcCrY%Ghc-;nl##ZwFGex_3!VoB>p< z-(<)qozF-3aOG|e6Z%x780^{dIv!@-47cgf+FnCqo%W90VMn#A0#=qgB0nD4lv7$G zCc~Hs?PNjC3Va-sR*ONPd2>!+`YTQERpW{4dg5;}%q;v*qo1UQAH?8c1)7y-#z~am zYe^;1P501aAmTc`)-7Q@O415^G3^Qjn?k4_THWoQvx;9AD zP9#~d!e+>N7T+>#I#HEP_mB>^L|aA=NByjEH>3nUTw-l(()Bmq9fHC<6dfc~Y672L zg-;hd^a~)Xaolb!X_D zjnw38o2pcbS8c>|k6ul=+rt$Vms_<^Md0rMWfyrl@T7O^SV$N91ePiWxA|8?2(ZQH z+N7~mO?ij+Rv1jE)xp-~Umb=_h2u>m6@p-xo$Mcyo-pAiOK$`$_ojo3bE%AX*&BnX zb5w0__bq3|D}M?2Uf|+ETAorLR4{h58z<}%AqFTUR1NcQ)?FMh$GCl(31Ml+__Zs- z9^_hOM6^sWj22L&H`oU_iyR+0**WgfNcAmT8&D9`3Y#^4mRx>wP4O zE!$_|A&HLMcD)I$Zaf(J%C|{rnga3HuH?D6iBfKuYhT}n zGhBYKK9!Gm$))X_=}Q8h=0(+lGHIIyS9i_1z6pRl0ABQ4P`9^Q1WeLqa4h|g{@}u< z{$ZN4bYk0>&Fep6zq%qpmKr3@e^NBq-CXERgX8!85;(*xeec_2cfml}%3OIv05hK0 z3lu;0*_1W4RYFwuQs){~x1QH#uZj@0SDosxA|-|-o`<2iIEE&L2Mb+=moOivbIJ&> z99_G*%jO0;x5R9JXs(oRn&TNiIP%^)f>CSW&)*j14deNp!d5T$_F=3etp!@Ucesac zzNasj2l_E&M-pV2h!bZC?(LUYdSFKQ&C7vx&$x5v@CLX=Co$-~w4?Oi$-F7#aHwMEGfO~?S5Hx3R<+$sqwWYGJ%Qu$DS zZr^uW--m}H}{G)NWy**$*u3lkb56E{*0 zF}05;CVb`-WNI5Hd6k2m>m-dL?!kaODMZJjx5tY*YIb^yFG61s{%aEJ#l@_=skD3j zxky3FySJP&(O!uXAhY#lHdnez%;c5Eop{K*fn&o4!^;iYH;P76&ZcwmcK{k(WeMC% z9`d`PNh!r|leJXO>l2pjRW1#)ZWYDiv*O_{r#ebSP33PPkSD@8vdJ{bFAft*WN`7hu>g{oMWo(|s{$;k0=+tUmoFACy zWPq4D=r6g~x@reZ!w+Gx!)sz=bw+9f-x-U|*vQyCeZYV@e6jB}8x$kjX-avA_}qi< z*=AlO!Llbqo566raU)lnbknbJ+MhCi5@-lrU{{5rQ%ZW-f@_*a;sKktt}g4OG9y50 zCO8_-ExBzBw?|WajNz3XZVygV9>k>mSM{cGzj<8V$vlV&^q;4{XYZC$z9@Cob&094 z&Jmu$WVoFs^c9qZVpv}!#>jv@mE{4777!jz|Ccb6@Bh)mp{QxksXOSEi$oa{{UD4( ztL@H{A&$I5lu?sMzBAS!#1GqA&}bHHx!KENu)JAEIJwL+#5NH2|JdEx-Bb6>M}v#ZS`LNMFN!M2yOhS?_B}i)DNEqzU5VO>mXN66v z$FXRRuvWFA8@lw!?yr4(?+@S>y;O!At>K+LhQK_$v6iIxR2-AqpUq8sf=SI*7?|Tq zU@3}06FN})sr!t%-Rcr=<=7y2E77pfeoicHCi0Yq*zC?^Nxl=bc%i`&dGYM>k+AdE z6R(8Q{4cjDHx=aY`W*u%^3G!yyi4SN(6l-6?bvSIHg0)bkk{oo`vR7G7+wIv_BH4Z zofzjik0)L^e)L>Vn5ZN2BYB$p_l(QrFL!y@oQmZ>u+FInpUAey2NmdGCj+9mYdGA1XTa)?RI><`L%_Q^QhVRzScs+68Uxl zPXO?IJH<3JDB9V4SG0(h+jz`v2~(Lg^=j+L7u208DBkiu2p_KgfJR>8EgA30#=)X5 zUMz4JmQ-9d4OR&G;QnTh@=`usqztkv+vYBBR`PiZOQtG_`<85s;w=?5iq%*D$Q$PN zecj&AGuOxURQi+6?!+0pvWRfyqQ+T66B{cLpwJOGx9K&k7~R%SfH*t$POmIR1ZSUREk* z1=#|mIZ^!hHr1s6ab+_F5sb)j@mo#*T4>Er`!|%K|N7GwsVy}f{uxkA!dHYYc>&B@ z>@DpngA}Mh{??io{hREynm!O?)&5x0van-9}nB?7`cw~8;D zJ9a+|!xRWKEt%L`_^Y>d|Dwbpcn7K+gF=Gb(j9BDTs&1i6)1fKjj$%XkRa;1uB3ih znZ$&CTA&VcdTPo)bKTmg&NwaZq7vw&3)ngTsXgsSSIN{UHAO5Kq^_Va+#4Q6>BThw zSK<$85GZL6@AIr$`=lZiwjZytc{4QB7QoyF;bLhhau^xjH^2^-pT^f0)L zT5Y9GUI`WuGhi|>N%07WHR0*p+R zwo27(_Px^C$7KL(7+=zSR*l4Jm$uiK95RoM2Hxk|RzBMUj_m-dA(DF{KYdu5WE&*h znOg>5!LP~~#AMZwXWo7>DsjTr9lDBiMwAdIbnScqQjHM}>J)DUo^(zrn;5cq1h@R{ z_-TsUAgna$h@G+BNi;D;SzE4DT~U~~vI?Y##6+uRcv;gf#Kyb3GQ50|{zpMw8(4nE z%@gIgNXPy{6B_X30?#y2w!+3aTlY_I*yu-=5{zt+cATOGXGX`V72SfHrTj=0js3+j z@NIK=jVFbU@~}*45+#Ac<2CdnhIvyR*b;JMAB8rqu?Ult5~o$ifdfvQf=baGs}Lgmi2%u+wi}`tgofnpb86 zYJ6ygI5OGov{3XPEDf88=yhk)L9x4Pkn+)ZZ5so^BB+?t*8!NS#r0g0e-DkO2f!R| zT9^T6e91$&Pn`QBuv?^OUXhk|D?@sgvxq-2zyC2C+cv?VZ&O&n3>h9LHR<0zQUBJ*4FeiBC@-I zM-KBpC;O9i&~6?l1@dwo%W*^56@ZYD!WzIA%V}twvhBsvb=23m92)YWlro{94h zM-ROGHy1icWO1zIfLxn6ue(tu&C}qBSlSbHEuY4f&OuG+tJPiXAsE+mRz!_ddaBM( zTp)A2vza*%tfkd=qd6`2h*Kj|eXO(ra->(^nKLiVQdWh#fQwUi%JYt|yTj zG)^pIdNrM$Oshrwr_Gkfauc~j4{V?a=)S6!4e3gopnr|CiekQ;N=O4Xd$e-qll62H z{W7}^*oM5+N!Fsez!4`5*D ztj%i1=agQdFgT#pqrl1eQbaqEA1P-gBEX{&hU2@jERl6nep(!C>qt^mVR*Pe3^+>=GG{Ufy60*?xA^$hAmP9ZY(O zxN)tdEl{D!+i2y8m0urOYWmLdzJCwHYU8fY`9g*EqAm+41~f2QM*oPY?q%J{j=zLZ z1<}|0^Zw+8!&)m`LNJOlan^h7Bf*cfYAfwW-3$EAvy9;OI*PCHl!3*xg7H6OFxi|Z zQ46Mg{11PDSoN;unhKMcz$$_0J66WrT9*=Lrf@Uj%dDpC`6yA}-AH87u^pmRLPYM& z(p?>I2@f{M>4;Z$psY}hPc4_TdyK06x4^7f{Xj@hh-f6`s28Hz7BA(L61R?R0IE-0 z<(3bF%o&FG5Snz7K$sTw6h1Bbcu(%OpgLdrq?&M1Ju7>mOf|W+oc7BW5-gaK6m=7t;R%;dg0d+Q%_KOKM_#Y|pP;7A2Ip*V6_JN3V;D_TfBPEtSJI;nyP1q>r@ z@I-s^Yt9bSBS0n)*co)RO2&R@1xiu}Ixe0#`rPUI3s!0ho>#4W3zoSxu1z^>VrTc0 z>jcx=k=maoL4vbgk-Ky4c6|xtH!FC!cFp-GyJa?}$+Xk8jX@B&+1N=e`7T~Mx3uRP z63uREG;yakM(51)JH5bo+ns zt{d!#*MNyEy0un=$dCA5t=g#hQA|rs3}W+Uv~eQkoZHVdXddnCWrZYhF$lJ`hTS~9 zM`+=q!kXX%sqFn+?C{(%NJ;@r@Q`T~zCJ4HNK!`v=-~PEMt82aP&o zzo!TGg@ZRj%AEL?F+w}o#+z;Yj;*N7AtbF?Tw3W1i95SAYr@N<H8FcGq39z9eAd zHHloW>9^<#33{%!rzN(}VNL49-45hU)~gl-N4nkdYy1dEJye&IgyY^!M;CMOmdZ-2 zW-tu%c9ghCWnjoLlu?*Gk}?&5Lc>3r*-~ubQR!KJg(P~)v@Hi4Xp5%~bmH{yD^lPv zse~eu*{Luj!(Mt2@WTSmX8FKHMD9VsR&&Lm-^mPQzg~nkT0i^S)@#jU0D1`kAqqT~ zu^`Z~#K}ZHia~GvvRiinxfkWgl z#L#gzt@i=_;U#VDUEWK)@1!sRLES_$@Qy`n4GnYD>(gDf_5i+uT_{$>;AyYk1Q18j zPbyCREqzY?m+-Q@JvIeZT+T*pEC@BE zSJQ1RPe50rdr%&vpfW=+k>+C~1cLRZkma>)-hhh&TqvJdZt{06)E#IMj?y*07>B=L z4hty6D=SX08nIyyic^bi}R*|Kih6s8Rx_JvmzIf{2a3$USO_< zdtVj)5!%?;b%NkQ)MMLE^mWeVZ-+olhyk8!iIJ zg424b#dj7i!snA~1~z`)GhYYf2gMp$xV>lF$ZYPO{K=2hpA_uE$7sk$gbSG=y-L2R z7=S1Avn5)7rPnsp`F&Vg5_kEn%Re@8EY86f#?oX390s{w(l!hH$iY1LM0sYvyiWSo z^QAtmaTifVDNISphwGD}JZsq;S?wTeNZkDPD&2>Ok`)5Mb?><8il!n6PO3pAkeD)J z$!vgp_jN5T#lwT|d-ocgeY6=P8pQ*9n!l@5yT_l}F6jh-@S`m;K{8%mhKY8tWJ=NVnVx2=M z4$ZBFLV^kWK1{W5X%Z0(F<6EkBjQcP0QfCYvmYP=)qhCyvq?PUYOy1Y#? zVJADzPJnU#$EBDVLGriUO?_%Bf_OG~1-kNUV25b-R~5a~GL}tp9uFc6yQBZ_w);q$ z;k%cqrZYtk_tij?AkChqOY4Khiz1xiEDuk)e%c)(iQ|<5Dl+}m6+b!MuA`|k75dJRRHk{63)A1boBu= z=OU~@rO$P)3!Kd(`<89bFKAm`eEm7cWj=jiB-&3;Nx^>paj|=|0CYaP6h2HVOA7ze zKJVo_t4r*0#T@>24hEI}K|bTNgA<-;pJpWW+(D|Hwb+@Fe%rbOgZ~N@E2HhB1Tf)1 zF&IfpoMS|-AexE($f7Zf}O_)ntekk;kF+=jDP zK;(vItbx`F=8kXtaR_2>JeO2ncJP-;2cNBk!;5^Rf)*{=(A#Lz#wa|^Mx9Z}RUbXX z)d1J5pugRg(D)fD(Uk^1Z0q|L5RrKmjE|^A)ZOf(+6h&nGFA0`~=;8oVE5G z7sE_>D~4k&;U@+~7O~~Jn@i6Nf!lnJ=S5ZxPAVK16bOxps$F|(tHaUWhO!zPZ~6F$ zm4RrAOucU(>cALbN2T_pgTVN3UrAe*8kV4CmugHkp~Np9rz9o^WKKmE(5F{@Y07=f zro1L48)Oe9%ftf-ZAkv^{6tzbLB`L%sIKvfAS0N*BxQAU+B@_%NW4nNX%Jo@N}ZUX z0Ug9DKlImm;>2qdT;z-}=BH~p1j81qCh2$7T`Kl+H*Sfi9nKi=bbgz4M;iCSQA5wn zQV7a4QIe#8^mCOGFck*!%-pkuiqCvew0cHXjB=huO>80n=dEo1d`*4T?y`{q*HZr- zfG}i!Tmg=1KC4utry{j3^7DiX34^LgY7^}Hy$%0M#t0!_u1iM-$FDv!$UOr#MpQiL z5TL^y^e@RueWctn?qkxK>Qk`;Ogc`Kw zL_a}^@$pfoMZwzW)-{e()XLRCiFN%xBV;5U1%y5q1Z2>+$6j-%P@U^yCKyv@J{InK zKo1V$iOWB@H?FtQT|!_(`qn_@!E_Uk57Aka`}(qoJ6X<+j;*4<0=@EKmF>U^1jU%_FAp77wzri5dpf()5Q165B0q@n2A&aS8^NCN9J2+Q zjQ{blo6ADKe}YrcP+Yx!7gs|=Ug{FCARSB<%I5$g{&E0E$Vs%Mx7fFmNHOvMkNN~a zhd*U+-M-pM-unkGi^BkSk_8*Ja|A^lBTt`~PXfWc14AVGj$_v4SMQMCG+T&%S+u2= za$0RPZtw=9^FRr^AX-NH;VS_1MY*EdoaXMWvyPNzK~Hwd{hyv-_`q?9dM9aUN7j$Y zF^01Tz3jsn4gR2tHQy_0Y(?h7X1e>;c;Z|zuQp!FTKlcRX`?vmm{2*xsqB(0}smCvkPDd@uv0Ro+MxHVy>CCcpx zLIg&;^YUcl$ka)`?&mQRK_J`u-{;UkFU5bQKaeF$0y_K0{$ki%Xbyh?(6Lojjlt{o z_pEL`_yzESc|~@O*jPf|Iyw1!F?so1I6+>+6BX2o1fNhP)r*&mlKv%>uYK(AmmEgc zz*r?rZFuvvJrV>Zh|grzQ3Pj&q0VEwh4Z%G&8Jv(sh*8#gG-%p15~%q(*qVmnn~TjYkMuy)fjebGIX}7>3ggExyu)ODzQit%kYp?VrX!Ng#%(p z%(xB(RFzj$DYn*GIFQ(Oah|Qo5702@!c>T2Sij)L!a`PHP>+-0^=cMi?~W!-_PFx( zF0+yCdzei)P3~$jry>7_X-0y`+h_&js+A;fpa7=Uo1T0M_^KqCV)4-LZ~WCe zDDM5P;9mz+pg2J`Ybhs(C@)!J@wt#f!Lu@wx?gWc0Zo%J`uSxg_Ie~2at*(jBy>McoSB{O9Cc~X; zlNMkx8gH?ej{70bnPt$ug`oasrBU7d#c$@?v~fRdE_ctNPTJvf@z8OFl3>Z=R&Un* z40Uvwon`5DM-^y%CH}AL!aVECigW`V1#WIGVipjRy~PHY84~{X{mqfS#K=Zbv?;)R z&>@ls{yNLZ-`iwbQ_NT_(49mUX(^uA+dUU;7-Yc;re^ivH{@yk_HXJuPwb91j0<+N z-~`Zw?mYud0|o)lW465RZnkb1PwH)zd#iB)Du125KgB`M_3i6mOtg*Z_ChRaMA9BD zhLvsaRXzd(hqZeDT?Ao8tIBwE>zmHq)t}RF!)+p{v`XL)5mMVvUqcSN{B2wr!Xu}c zpP079;7O1O+`3l}=`-kA=eE8*6A7t8r^?dUy=9J>xD%%OR(+O;%8m4Dv>UPV?DX@O z%3>qCCbRH?FnQlPk*R#g{ou>so7(iO7UHiNLj4w?tMkI!14Zl12~9j+g5l>9P~RNG z8!<%G)8|v_~k3-%=d{7}R8{jzphVEo{ zfR66RF+0i;c=Sy&rdq<%KG38Gzy?ETiZYtV>7Od>xTyfm<0`Ej02$7~R14)wJ#!oQ zhb536_^Kh*HiQez{W)v8ITpR&!NeNb{lxZdC7J6*-J)Z8tsi>@zxM>~zJ(*Y23Gp@ zvoTK0xzLa5c%^?Oe(e{Hq`kG(1qY$g9yS-^677xQP*6g8e;nx`kc&6;nS6oYBU zi!fG=Nfq!9653MV%+jULoyE(KSm83N`j1{+0rS#xCX`_3b(IHAlA&mcD}1^#KT?3% zY9*+to8h0SLN}kK-wx3x?0&i0U6NS2g*TLT;+LTNMGn);vePtYLBK;Z?EdA7&wKpFhnX)OIR5uJg+ zPB9U}DmjslIjhK?6v`5n28tTW#uqW+umQBlc~nt;Dnmt;DblA?^dR zVf9qyL);t*KF9HhBSy0!X%I;4+BG^cHKl!7sqv(g+OdRG%Tp=1HoZ?Y;!}ul$0uXh zXe}@L#t^o5Epbm-vhh z3XtkSX75=HmuVQN82aNaO%OUceoA?zAoyTySKCwKxcf+xt|{UgpDQFA!K9PY@{mrH zf|X~Fh{M>XzUfLxTBXU3^$dVuGQaSgZ_bvtYJVNdyEeJevJiZSI}yf?x|I@u1?AFi z%-vH7vF*(89mM}N2X5HC#!(PqLKHVJXy3XqU2Dx|7>;C>A2`cn)OnxMb8H33 zFgL#i?Q%P%k&`snfivMfMF6c&s;bkJH#aSl(pK>7JDlglP@c`7BbdYuI{7i}4@suw zZLO7M)px258f)yvN$a}ZLo0oVxN4WsQ4jc3;{H{z-ZbQ#us5)m-N073RQI-Wck*L& z#m^8L<3JGX-0*UucK3)JLo{;Pc*)G1VjcB$nN%&1Nb~*;1=W7;;0<}q`DwA%Op1OK z>bC7ISRe-tcXkBWFiYgK*#aZ~^e>P1oNIA3h=pg11cw}|X-3L2(*+9`UWS_MoLg77Zzs&taJ!RI&_bN-f>^43 zpedPQ=>JVkiv$nB@;A&@4z1&dAZM?KHfz}Sjcmjo$`gwtb(BElQ8iu7Z(XJuyhft0 z^mRe~TZi>GaQ2dh-8)mE$a;(Fm00Y4*!`}ipMY6VS$f+_X+cr+la&`K{-3+D?aqc* zpYKp}h=!%bL|Z^;>&$r2q64#=aSi%&o1#Q4xvA1YOf#6YGLD#>6=z|duRT9R5q8eI zQR&bBul!|I;TeJh1ND~YdX$i2ph37?ol1Z9O=PP0WN^l2&YcfMBgmunh&R7Vb36LE zOoZEfXFFqJ!_Xs(930i5{1Mvr3=y6l)GWU&Ojm^)DV_+l2~cWupa!%^iAH%?Ui!-4gKi#<1 zTjqOx)Y%uy^)l`l61n@%aebC`U!OCs*RM#rPj0Jl!R10gnD$c8MG0phq{4IQk2xSs zq$r)v8li#}_l`yk|5%8mcI1Fdy@MtES(Fs2NZrq0EKu;;F*sCt>V2;LhjNHd_w|~C&dQQl8|3i37X6WilKyGjG#mM9u*iaR%aPGwsZ*TXA`W~iN7V? znk>aH#HpL^c9cfMz7^beqXD`U{s%F&?(1i7B#7Gi2nuIAk)d|~zgaahh3&R_7f;MT zmNj&kP)}u#XpV(Yd!2z`0TKH@QHQGoXDl`wQ#ADYneG0f60O|?U$>-P0jPkIh7;Co zV{l;7BNMW1DdtCZTqr0&E#x5Mbw3Z5$sbUyLQZt~Imzk)-%urlXf&*gSM1f=x!wDQ zmx@fv;83ReM_$)1;aWO4+Wo_vq~)yiM&Wx{;73dH>+q%%de{zRxHjeZleEI9lwxN) zVkD1?G8tXWZZ$?@_kVpzM;vQ+sH3x9f^ua9eVA;aU`t}wkD>!{DM=t&Re1rzEDa>h zOj$J0^9@6^e}00&N05qPpbMXftmcJkkqv9<$$X)}?c7Y2UP+C_{|xHAZDV9Pl;}l* zV;GIT=G1>H(+8EPq!Zea5Q)uPSoCO{CEld~mRhMNHBU;sBrkqo`)qTBL}pD-ji#Xu zO)0`nOTG0BXLlzk0-i$lI{e`rjVSop? zO6nFQQ7zr`w?nY@jD5+$Yk#eO_HuCH9GF;BP)6pKr=hNawY4HZP^vtZ_YD|5$`ZlVzqA<9go)v<-v&ZB*maE3UEfGpUKyGz*Y0AOO-r|QV4%mEESWdV-F zu?1t&OBrsolGf1{ zmsu@GTzIOlP^t99tlhU3A^W~@!{VctIi?H)Vf@t5hEsUb87m%2cc5@N+63l_Ya2+ui zYyEjf>MHc5EgX*0CW@Pn09a;f^uS@N}wx5L+$(@th^ zg)`3Gu{{C-O+w^8I`1N50Z4niH&Zt6kQJLm95vJH1z%vxpyBlnkdm-Q#FFmi&NZ;X z^D1D8u5R@y+7zylaeW;^WH;kxwi_v?%4oQ&C>>@%>ajrXlL^@VV$T~Oeuf~9E}S>^ zL!}FN&0DEX(jDUP)GsqLcOovU4>6kPr(?{V15BgHToUJg(iF8RQ*SC;A7;%loo;?if4h_hT|3=mDX#%q@C}7>Tk+wH@YW%+vl%Wo;J)UTi3de~H0;%c9kqeRvI`w<1#_GFN zHNHh$Ai=^A$qq%11LEmyhgiW%O^0l4&(#qo!T}|!R$%5}tw|iNhCa*V>vh4U#&25o+YNozPzWil>t%bdR~YjTNo} z{@$_v3DBEo4@%V0E;?c&aO?n{&U5Q&~xib+h0ET@Fuo2F)<(jPTN z-ASm5`z8j%L)m>?XJv}{LJMhl`IKw}iGyG)rO27za1K2<(Wz1eL_gUN!1uvivjWGv zz(BFN&^e6$l*)K>jz9eRF(G+O(*gVf$3ZkbgpP>I(Uw*h7rNPs9;y%*##8~fv9My| zVQUAmuQAYRDAlH=%0F)dfVAu%eV2^OtKR;N@>5f;))2X&@BXsnsXRt`Sp{U9zwSmg ze}qO9(iKP010HISU#NauhCMsc_JWmk2o76IsR)iP%_~cTtLMUb(%|Z7fA9GeOV_*uYFjThLYZ=nZ$>V*&(8?8WYL#F@{Er~;J1_}>% zBi@hm&gX3Fe7f>>0|1Z9)uH(~ zA}I4oaiBmmRN&>W;21e1R30*Z5FwCVX*s6QEgsXFrPZtKbyVchN%}tBV)C=AVH6Br z*W|(4hJx&lbVLc|9D5j^pvqevMg8|%%XKmrjV4?gi-bhHty}aYxoz`0tlbx%--TIsVOY!dqJ51ccBy-!XM4_n~N`&8Gb; zZ6X`U7OwNnVbhg4G@wE4UmtBXON`h4s1;l8OFjn5O9fG`HnTa4Uc2Zq^-6{v^^xc0 z0GE=@1h9GB8OD9_TQA}QQFJ5)^P(8pkjp@LAF`Tc&T^pteV|K8}u;4;>HB_ zHD{BTCGQJ6`z~f@j{UXT`l8s`XGRM}Js<@@UVdsgy9iraW!qhoK2c|cIdy)#6a$m$ zX#BoCJ8P~~De*_y9+;=XN9tF5(z>0HcgU_bxg=aX#u~Q4#6JJk09}8xZKk}z;Ani1 zOz`vFf8wM?XWyTZm;=K8mxu^yA4o<3YBI}!7FX01>v({yfZiX-id+asby(V>eds1Gy+{T=I`2PSBb(Sd5qJ@hx0CEY`?Q9MX+5d4vS_C^sHm~kvkMBqfwSVi zPfEZKCAY9aRHQJlfjNJsKuKemO4hXR!qVz;(w}61)qPklJ1wtP!fuL7zR9 z0RunSj*s3>L?3QOAJp+GB=r=;4=oc&K$8cG{e@hisH|MBU8l&qhW8lQ6Ks}qK?BGU zIFC!bK}cOcPDDt$Xx`c#&SqV9D8BVRov&7Q4INKo!{;mheOCZwh02 zUy-#kd=i?7nsZ;}#!NDwxC+PKy4Tbof@|nqR0he_Is}`^n;va~G593Nmv*(bpuoYy zPr4^h7IqN-gw|)RV(G5Qd0hIFn;!;q`H8>pAN+^z@BD?q*MKd86d(KY)ZM$o>ad32 zJMFCV(LPWkl#n~ImWdFlBja;0vA{??!Xo5>wk5Qnf3u4%N{McF`wI-)AnylLeY^^m1%h^0Z!#6bd){4nSWki&r0B7>$}veH$i+t-(gI7S6^({L(kAkr5)R)~b| z|Gfl%zNw&NkXd;+C4R=1x^Rb1ewB*-+TL;xK(`*xq68{+E#3r();5-1R*?@cpchF# zIdnUGD#uB~s~J=mM8=EbY~k3}r;^uM9EK*~5_!hcn^h3MMRV?|qi67m{IFum-JWW{}r5iKMKos$N*D_kseY4_gh z88Ky>68fZ(#C+h6z*XJqekU38Z+jj-=h=XuPynt}E$8Sm=uk3b!^+HmdgQ6)QOjrd zgKJejL@Z&rq0F`y)h+t|b0e{YPd1}xd~0qYJF*mK8CMZuTnJ?|cA{qW z-Ec^#9JL4fE}%83`_X5_#2!FD8sYlFx{- zi_*}t$QIr|6d+z}e;3D8u@21F*E+VR66`8}alr=f^PML5XiF}j!@%l_H7#aY`v^4j zIO`cP&bn94{+^@oddrEPbC`(~Aj?6L9wVF)Yep+YpG{ol1Cis0KNmEp7Accj=EHq- z3DJF6XkX5(R^aC5p|@xcE=1X%V3z7xKakw&eBh$HHZNHDy%hX1V2Mi^FxiU30}8yy zbn@KB+Ro>m;Bqbtl+|S}IWO&6w%)$jKs3JV+F|P>sx}t`ija?2AB;>XZ}c5`>xjW@ z!y13uU8&opl#cIa6^Bt!!z|*B?Ffo)piZ_%?YY%t%1F)q#Be+V(nB|DB}rFLAQKl7 z+%vdrhP{h%5SotLwyR>4e~OlgOBOM&&8v@dPAIj0gfy%g*1BfxNWpdt&W@I;{_Vz3zXi&^1qz`8sNg7tLe=C6_3ms-0%|nkJ3Myi>5Jg-a-R$G(vB4$7a?mXp;YkW;R%J?O+d{GPhGJR zqm!?@*ncYNZSGPK$(j!_djy99jb_HZJ749?;m}|`Mo|;FI{c3x-oEYtCQ9gao|%`nYC;h zVUjVdPFZFqMXAC}Ac(t8?{0Yw-V%g=)E<(r@j+QgA;x#;e;I}Z)?xksdKIOiFcVwA z7JpL>*8}>%-4EIV_K3dYC1+Uf;(%ijVB?f>zy`hUT*z&=JpXXBjVFYZH9yE&h7_2g zxTF{*o|$o}DU=#YGS$Cm%$>4M6VZ_merXi}?ba$73Idpz6T?EKPX-#NYxyJoWkfD{Sp+SH@kqY7C0*$sTxtLcZ1{c5puMKm7_YI z!P8__vw7im(1hlsLRS-w+-*4SHOpV{i}KpfPih0W_!u?nyVfTG9w2D~&U4Cz zKEbnB^OSBMnM$|StKMn`f8&z%nUxZ~s(X12Ow|5Nb<&QR6K&Ki3WpN(xxGw~gmUVV zwSX)NauGj@wbw`a6#;+E@CO(v=~&BgP(Hn&yf z8R-dEw;W}&1nnT3M!Z}Gu`vx|m!sN(5c8Schn%02t-@`l-t)9j&C5H)a2-VkW1y!Nbyb8#2vE?)n z=}+)H(y*}j81Vk9m3f_7L{cw|!{&J9+=5tO4@hXRGR|$tSU88+K^Rmc^V&mwteMAo zF-*4GWBSd^X6onI-Rdn>G-kRiQxtK2;aT^|+|V&fu2hx-FXeZX?{AU_{4!}jsL0XTYz`owYQ~pl2SA5<4-dH6^sSPM*jZ+=JFh@ni>f>Q zn>dp_mInwug9911i}2oa^Fl9aWB&pw==T75cLl-(xSUFOhbUy2c`jFd6cVgm#7TkC zJ&^>DoZP|jj@#y(ZymK$Rs*$q0)K8qrPKTNT?LOsJ+9MVC!~TxS=paEP!alX9l-j+ zrFq4x376CSF}afuEX_YwIp0!&^^j7xf~fMTnLt}amCL0En33Nc9n4h^#YsNxNtMNQ zz&}wMZaK)gGOZ^(`P9^TdaKg`WXaBi>{+V3^_x-b%w~S`xxIU?-C6ed={z4Yhj?Ti zn|JWdy%0Q8XQhp6QSrnzu;|9wAZAGVYaGl|Y+7od>uvu7r+7mmpihMSTjl(htCqs; zmvSJwfD==YHcj^Z9jn50ud|LEvuKkPuCQDCDWtw6+?Hm~jER4s;ujR}|5C0+Ff^4C z_)Oa9c*vbVFn#jg$gB1XYlxI6mz3OqpDVYH%F!&RtBqSOEsg$YI;JrTSSzM|K{Wi7 zla*>FmP|ejc=^Sh4$%nKdeKXbh{a7|Vaq3`wCR&preW)TeMsRoUjm+hCg3`DBQOTa zM*Z9H$N?pk-N!yT5#8NtjjbNQ;k(m^C!~;4n7@c-P5&4k&2<0;R>ah^Wv-^7;PxN! zfO_Ua;o~d&X#YJqQNojcwVqeB6K4qm`GH1(G&kE}7s{fl$RqE3Spp^d#mLte)D`hD zax=wD9>%(^3ISP9Dv^ZI6_$};zi>z(>7(}$yoOA z5prYSx#1}1h_XBahoS=Z;foGter_Vo-A_n=o1vt$gNq+{VRaJ|+V>c7x_DcljN}8J zErbkfvh%;{I~a;boRhB)+v7Xr(J&OA`2K2#!kOHW#*>eor@3KlWy?RqY<3Q?%EZ&S z071t+i6+E5EA?mHO5Lw`DkMU$XJXh}xhu*lVJq{~-k&PujPVA+br3y<%Cg!vz0=&T zwcAt-+osNpE1;UCoC=I0N8`KOIicC8ot!1vrrm>>4eaPH2eoc1!dgcMpZDmdS>|~> zy5nMA)ieZx*8Y!~Fqi6GBc_dL<*(<3!8lED9xLC>S~u-aWPv$E9`EIHAf^vC5Foan z8B9y1-n-y{@eHk{s0@rlKq>zYqAHlk#1J}%NI#e1F{fd&lq5>M-E>4yZl2WDX?OPn zcL^E%es8;vT*=CiaqHPim4Nj_jtbNgEC~d!+E~IT(C{^eN~uQ)m?b0zeP)u*qptMQ z0ZeNs7v_VaRYeD0FxIxogdizuArq-It@rJ9J&peIty-p*rxU%V!mX;T*r;5DWQ)*g z|5pCO2XW>L*1c4EYjhp6*S`NpOKaOy8{%$it#B_ieDs4Jq8xC)7RmHC zakCI0)#~Vzb8s$Xmhgs0gkFeD;pL0t4*B5f#F0_14m`#voJ87?6LE1?e-|~NnspMO zt~fMI-3eFS8Z|yd-!mXBETDg>|CdzyYA|nPj6+@xYj|u@3F=@^Ow>=yD@pnVk7N{?*!Op3nZXBWO>(mom=+Q~}X!)SN&D)Bsxq|x{lg9*P z>{|N&`8(kp*&0z?PeOXDv9w=n-YgWZz-6?k)%nPhsq*t&2dl4=X)>CdP%^GU?(x4)Yy>@PEpYuY@Mb4B9o8m=xoB+Y6;nV!rDC*PbunE)1TewnbnBfrq9;$&aC}2yg5I%!gr@1rJY9ja8S)t zZ$#Bo$m6p5Lvd~fXE=1##MJBuUTBh_cWOfR40~Hosohr%IbIn=GlN=+(v9V9XLbje9_w;^Xjn-JLEZt|_6a|!o zENjrD8XplaCNe9pX%q^4GjkGRB#C-wZ2p=Rk-P=9Uy#kde9ohD2<@X3RP3*~7fo=` zlanuiR4qqpvQ>v{&W}n?dYfLnr8o589e-!{?XOxBD>fce|9r#Y1^JXQfd1$)QBd-6 z;5U(6^U*4pdXM%lrAe}yGg$k};Nb&Bx8{PFe#h-w!34Uc$C)MH=AR~;Z;?Yw{3mtC zj(=RAJf>?kISRbV9Z}6UfNxWs%bX!fD7n-^3u5uRT&UCoQwjIWE1Cz5P?Yy-Wo*?Fi>*%Hp7YX7GP-!LT z6~A_%v!dY^`xmkTDCyjaYtL{bgr~n{!!6;d)te?2<>6qVS+VdDK6|$k41!;D1FFQT`q$rW# z;U{9+<~c_YAqUG*DTDA#(gVVMM#|78UJk6BP{INmJ5b?D`r=gGcj0K;l+tAtP4A++&^JKzeQ7Z5+BtmC`-t3 zLS4ic!b5K<`~ZE%JI+l4FX!SErEYaIDnB@_4c2?^kCa?=hY;U`hqB|nMMzWQ;V>PBjm>eVTZq}fol}V_G z3PeSY<7U=q;YD!+ntM!cTTLa$T&N`c!jfZ<<8H7eaZ7vz^+)~!Peuo%4&IJ(*miT} zqm@trrwm7=VeE`r1ZEWZre1^wUxEN}f&aF}7$8@VlnxmA9x`5~a#SNqyH zmDV}h{QCDg6Db7aZr(7*oeo%q2#6O8Z^})ym?R>p4^Q&V_u5&gU$393J9)Dk;pYql zrkvuRUF)u0Ov{zHu*n5<1`4aWeJ%`Ws2AmSc%sm9v%%_gJFsL&3o@ras}w-4B}8!% z($@qS_g4zl&wat5_rDd#*#Fu3F=t0MAwppM?>`OhZZFNVdt2@R$Wln2o{m?U8y`_w zLFRVqF~1)os%e!a2^a&2qM^w5U$<_eP=XcDewnfn33gyO0e*dW?t;7K#QZXS>635? znbV64CsJd)fzEp`Y1dY6+l4FAY{Fie(h70_!V*2mIAhPXegpWAs6=c zQ&A#0#BSykt0Y28g2Qp157ur{#{n;za>0eD8%fTmKDSXN$Qr;x9PXyzb^o-YM~N_^?uF8fix@&XV)@_uxjaoiGD_ z=g@AW;>ZGS_)7c;ZS!@Qf3!Exa0bw7&FHA2}HXGi-i z0C_9ijpt#W!}vF{?B&Ki;$;eq;Mp8fin>_YZ*Ima)~=tpL_w@c-;=+s&u++59=trz zn}~t~@yaIP=Xx%8<6#C?+fz6~`llCKHP-~~p~Y8sGGf{x$#5&s`7iqPj5=Rsg_a$+1-K^o;fAc`zgXnVo0)qGQJw%Dpx(m!6@12KMz+oL`?%k|**%~V@J zo)NQ*`QxHy`ri7VxVQ4Dajt(?C)4oR+}KEY3gJRfa+HMWuZoORomq82-%jb#<`j$T7j>_10Daa)CSd^ZE46PZIC@wWyefp)U2 z^cH|JLHdg{17htUzH;xHl$t_U<-o%qZx9ExXuOK)NfKgU4RJi+_EiM zXKhpSdtTBHDzkTwcAV^sVIVO0otw}edyZexuu?~Z9)YP^j13ita}m+%p4ehL!UP%V z3Q^L(FZVOu2K_?+tjv$xAe;1;;Bc^*r&#;k;2EiT@PUJGY$~{|EH9!TOH1=-Q-bvFsoF0ipG53&;j#uNbUPDI>ER_<; zz+rJ!qs+f=&>crkUYDN!WZ~V@o@!h-lR|W@U-B~_ThF{*r-at9Ztx3D|2C=FlFa{csbFd{#+UWqveKPZ-UjHCVwsN7k)9526-F^i@a z{AS9qpBn02^=Kkoq6la>ys&A2o{Q3lT&~id;54RAmm0ohqJ&=T1EO&|`#Cn*`dR0D zDsZIBy_R|_F^~)Aq7i=H&8?EpGXC0+M})xI9!Ua?j{TDSnIVjOyr*}g*aph-Ji7wILp&5@ zm}K)0ovYp>W?Clv%N4%MsHz`RsZbAfr}V>#QU&^qvUsUfmO+Wboznn5j&Ee z;HGfWUhQ|X!%mei>;#}Uc*b42Dkx${$P4MkhC7Dlwhvjbk;tX1;enDGKfus(oon9Cwy zwS{H3)=u5ip3fA)Gws)N8?S0UPe_B9We{@X9R!+ z5SBfuI6c63?YE?}-g750h)Tf~p3Q9#!Hj$JHv*#Qj4J$He27m4Jj+Nv+cDRpBLoN}7Uv-euT zdUNj`Q$p(3K*6|>XlKbrcnB#-DOWW~laryRup98cZ;3|UjnjL$L&Y7Oeo-qz&moG? z3AJ}}AP9F350Mn8@>`5aG!3=$CmUar`m#R)JW9{aTw}|6L;CMxF+)n@}MR zk-1PvJAG2u-p^;cQa9XEc_8Hc=~&3XNA{<1jR|ANArdFO4YJ$yG?hvEZC+)Vx71rG z9%>zc(*)heFI51<+J1Y*6y>v@SM;mO%t*K+G zW+GL+uU7dsc-oG)8C=7M^EE|sVu2gLACJdKOTMW{ug!@#HePDdluj9K{2o1fJid=S(75~fQv_O{f&p_0TZ1JGxqvAH1`eT+`IGSe z&K$`oTyHNC*UR+?zskVY3gSFmiuT$xLgr~_uzfK=3k>EC0#%k=ZDvwA$WBcMR1o8G zaP98ejMem8T20Y-dIV~P%gW>90vGC5Bcm$jOnaQ0Ca3}7>b6ZQTHN4zhO!ne?EkPeVE}9y zXD-VQB5|{D=)79)Kwu@Oe9Yq)$eGg@Dpq6WD@YuDk4}d=^+a~XJ(NxRBN?5I%H=C$@5FuaX9N*eP1`8WCu)|yJ|Qae@HW;8u-%M8k;=#K6{DPHsR-yG%!uSxIBdR(j zZe??fZ#0=G)9>6BP^zZIXzi)Y$;4D7mm4NNG3 zm%8eiu)eQ%EN~uKGM1V@#xSM(bz&By?@%}2JZ89D_X6DAvA15B-5wNHO-`hQcOU*W zn&!*B``83J7Rga?{_I!vR$ovn$g3jA*ks!)@@mg8pMY|ueGkmMs#uUYQQsioSd-9v zly`t{f}J+y2GB?r4ny7n=uJGX&DENX*l$fA(!e^<(Dmis$(@pV#IiQJy08H;57jZO zw3xvJ#igDTl)+3&O9K$3Kq|_g*2}mDycQavgFg0Hr1Pq)!$HVn78&a@n%$OPk6{#q ztDqFPn3z=HwBAK?M10(6t8LrD4pFwg+JXPD!ZPEQ5vIL`2@Nwr-rhRoX?bQ#4~b&* z)gt^XrMOti$xp{1Y_W916NB(f_jPZaf{V=Om;JPo05#_FxcBuXCSkcJts3r%RAU-j z|CelRB60GE|1i=C-&}!c@FX335&Tw-EaL<*Dxy_eRQKQiH@-C`D;BSDH;yF}$~Sqv zluV9;`x*EPc^%ZQrvsoCeRq4@@OR zY{UK7(3LQlUfN1`!)ePUxS8AO%LUp^P?9En2w`z~u41Qs*tSU`amA}SEd8?J>!;FL z7>PaPU7QMB^xHLM$-$9mi=5)P^{y%B`M7>>S~Pf3=BX9J#9=sV9dIZ$zHSAS@frETEHQ@CT9>E+Z3XGV|)AgK;CJPH-da3$5uBF;~yJsOBq~d-JI$j z?~eF5NfPnms&)tYqUzMg;^ zbe|x|wbi3{kqR`00!}RjMxMp+a|6nuFyOHh1f-I1ej#I%HJf>P;9s3T;4te{yy}gB zKR{ZK{}wCELYkk1?|iG(6$el~Nl9t=cS|2f{s&Ux>4wwv&Fk@}P&&mrRgH*5UqG`{ zzRjDFt~$96N>kNZ^1v<7KtYHTwvGNnXpu6T(&q>Twk;|$I6Eiy8G_&6e0wA%Gkj^v z+5Vc+oQ*{Ry3Uq^jb&n)tS@w~ZJZuw`L5zDs(sLxp%o(_r<6;FW;?FqYi{$)yZ4QUt|( z$`n-TOcqUTFdaSfp4998BGoD;SO{cpH=CiKIpf~A5nA;t!QH|0KFEmj6YLTQ^j*G! zQ#Ab z+Y@@z8;1ygyx*jxlpmox zG(KPdh6yR+f2xl&p){mL`D0BrXe1ql%E^5ucRRPNDNF%82Zm>zGMZ|eviub~C#zs0 zNp|Yev*=u>cHEOu`&wc~*R!QuT?UrIH-nt5XO2qwd#kJN(bF4q^`@*1N3W*Rv4)KH z1h?#4i%3z2>E)`9u^*$UDLC9!f^=^arB&zfulTS&TDb;SMEKAK@ld8!&hI^Wp=R|r z>(^Gc`Y>3W!Tk~CkN30Lu$RJ}EK3YDmY9D*mEmFBtFcLgf5PgXGfhs{$c-`)96D+0 zD#cIV+OzP>K*$AKh4C_!sLfo%YK*r2h8;o%bp7Bh7E(-j2{LA(+Q}%oGd~eLsz_HM z2wa|@<-*cPzb(g)psu!F{(j@%fsa~Cw~@YplL6(_glnnFj<9<0nfBecJzDpTU4z;8 z2wsc(R%Oc?cn zd)-gaD^Df}7+1`>KNVP>W%?Q!Z`H0VPRXAgve#3wwu|I4Ws|4vNj6f8;JUW#`n~Ol zyp2Lb&)|e_M|h+l(lkDsz*h}A+A?o!a)J4vo(bPePG?Qq-w{E?GNsq(kc~D_ z(KZ!y>xo@_C0a-R4nnv^$;%J>U)}g9T}P^^y5bD$1BV`Cm*9Zbwdb0saNy z2p3_e?EeLkV3g1(alI*snwPXzVu^c$=x%h)3}?zG8-ZcxNc9E zXHmDN2oah}D*W?!jxUwzY%Vq#YV2SB;Tq@j>$_zxlReJ)UiRYP5JM? z41lBxi0^wkWJ-!c8{WmO;Zo$E9Zrne?qRuuwPW1uxxftGWE$ zn<|t1=cTGdGJ{*cU_Pc%euLQML!|p6f2Srp(*(mib^qQhl-NW56VNqAs&-NSgEma9 z#v%IlI@m5gWG&yKPE89eM>%u^z9%(XsWe;x;K;V%5#HcZNnb@unJ_tr!W1xHs~4SX zTcXAFFX@TQSFnwIR(ZvcazHWfuM0>OmLK;S)af^)PyaSV4cS+Mh1A24%~II)#;9Ws zGdUKAG18#>Z)jFUp|kkb8s~oF-zBKXF?Yi}Vg|mEwIT;t|H?xe)j7pU3CpihcoY-Q#YEEAq(~wQW=6wJb#1)2@d@M)F@oXx!*#SFJ+MMHZVe3#e z2E&E)X^O>2zRS5;T7IMqvA)<MHJjJB2=CuF*LgU%Q3HIQ5-qF_%G>~ z`A0uy3@kdrLu$B8@GaP#12_Gj%x6A8!5onR19PXy%ifectnxV<0I#h7xv*&gVa*B{&zyFP~7|&=^RnA2Fi4^ zM6)ZtARN_h{Td}Y${+!x6V<8Y{jDS=x{WB221(09W23GdeJqY)h;Oh1Py^*W@J7Jt zF8d)2nPL>yFpok1H)$kr4RqKS|I}7F+TLK!-}7vpYz-OWCsp%zTYc>+JOg2eijW2m zS=tkVZ|zD9Npu_*j0s@s%$#>l3rxWILy#>8%@ID3ZvcCKPc5J%rAIf*rHYBQIbkN) zN1MoqfAx|5)CuQwwefXiyR?HOT?VmDano54vM>)z8RZDT7(`mF5YBP^GI)cZO(%BKiM?n+UF^SjjWK)+CVix-aM zio$zVGJ|y6Km#o@Zr9_^5&^xBxyt!M`BwHt5_rl8%zZ)U zcn}j~Q?t+9w7LcO2}d+mBJ7`tb4ZGisT$(s=>$eil-=X zE^g0C%I0q-|43auY}L>^Ms0)XIMd|Q5dpC?=dX9UrM12xsmAGO%;Ekizfl9kx*>ZL zLLWbb?)vK#nw<42#3uSUcoek9q?QQ^>^n3E7Ftj14h&}r-Mq+aRTp6n0=qe0+CBcN zgh@aT_)|kU>9m^EhWay9j;n<)S7Yo8{*b_6)QY+-{Wj+br`4`^xwufZ9u=QpV17UN zS0^W}NNSXk;)RG(R<-9e>B$PpYWPpLzUHNX6rImIDt^piop=yUGktEzT){*gF+P*8 zj)?CjK0Bc;Gawy&$2G0AWC{}!6KU0$=?U-!(MO-5HlSA(kAzmH zFP2CDZ3N&hhACkaeVteD-+C$+orIorLo~X8cGFe@+DZx?`SPSgaDEv`9o3UHLS<|q zK}-d~n9HJOxBIAKSf*EBd32CK#d7=LYu&Y*Q=H>)}qU9*;w+hX*XYhhydbiXxn!FH>!T*18Gk6bT=#gomdN-y?7oFQ4OdI;cQo&M{Q+oXGtpR z`}}k72S%ns#krg&W|7?-s7A4-y9RYWlJaR}ISP<-*h|SV7h8&GAT#*-QM65yT^jC= z;TY&|FQ6edrO(k$(CTm(s}Om>SKM-p19XHVAq_*U+$WXL5-1nRw%JZ^AA~+~Xv0_y zemUJ`I*t7FJ0H9O*pc0Or$@Po?*Tv4GRIFzyK21#k7p@M5*eFr6s3!jM(VTPrcdsb@GbmPJ@5(1&)fJ9Bjmt2>FWHd>NEZ&#}oQSI} zl}NE&@A?kk=PkzT%Qgo@{SoZ3h(h~bfVkL)AALore473IDvL`WESG-}2$l8SbB zpPA4>w#b1gpiS&sUFZp&eQEHG13`fkqYkKH0ESBA2lOD5KrcU-$) zGrbYPQ1iBHb^06+0mn ziEtLwa6fvEM9TFu>aQ~|COM=f`rH5jliR0SQrE<^4l>@I2vuBR*aIW3$ zZ<8PPh|=3kj?04tIL>wctJfMgI?DPwu7hdhp)7Z1JG1$5QM%R#N_#%NNgdTLmHXjt zPPvT@Ab`WlHX-46*#2$X@o3pI=KdD1&fc8^m5tM#-ID)`0=FDe6 zE$;fEuf`r%eII&wPwM=-?}2h#ls((2X_l@_^aRU(>UpLR4CRItXT`$ubf-^)oUOdn>WwN?e0-t@+B&UYw~@gyBaY7y9!}l`gAH@!sURt86-j zvk+S@8-!$oq(%zC4%l)T_wD~~lYrQSTR>Cyw2kJiMAOxkYo7dQP=ovZ83JxMq76qC zu8=Mla3%OfTG}dZsw^;bbUX^Z!0cg=P(XOYZa78vOA| z;iO)Q$vdj@&R|i3f!NVI*z|1x{JeJ*ECn0Cme}dxMI+g$5-1PBNXSy?IiL%jIj{lE z)Hjg>1a}2{3Wqb^;ChfajC8OWO&G}t;VQ{v3A8=2a{25o_GejMl5d=wF(@7?^WgvHcg6)iPA2Sz|(3a`xl^*z{;hW~FUEvB1p1A06QNoD=<4_<5<@(&0fOL}87;50$%*L)BX!kl=dT0z? zgr3iw8`&GeFLz${A1I^5ai?8%XRc4ELpPu+ z!QV)5h38^-O)uFRs!JAh;mw_F5&NrTbrS?a^idis`qfYx&_M?Jm z=yi~>j!>136QEsb-5r0dT$T&nrmRB$y@N-_bWO74VWf`=Tr+mx1)xOK-Mc!UdCqMS zZ%dN{&{aeg)#D4-v_zj1MvFZ9-0SHkc8LU?&b~(!v$S5!ab>v-jlpdYaj6p`>gS^# zSopi`3j-Fk(@zrx`82V;dDzt*7IXfT;&nlPfpP`PucE} zphLH3(&jq7+5&KNyTw>)sMc|4ax-;Q z6%S0;a40|(7^AWOkl0W!dhLV4i}x-{5E^T!iRm6NWuTF=11M-boti$RAwq;~nvfkQ zu$36^<-%e*^{-z1tT;zNm{S*Y!VB~E39UkV2&ZyT+#T2(w9^819%tZ=RZ@Y|FHU~Sb^045bzFug!-EQjQU49ygk&S6&8pn zqT?xo9Q+af3sf3PE30XlNj3JQ;9?sq1c8Ud7GX8k$uar7b7 zU#o*E7@PVj9r+^OlmC;~{?fK}Zv7!}ORK3|qr?pU{^5G_$$Rh~a`KnWpEymt-_Ow| zvt#e!Xyl5po1Y9jf8KKezovUsWE+LyA40X(74zgbeabN8YdMBEX*fae#;?iy)W5U4 z=@uVQ(8I@jw9l6Rvr9O$$(c3kXedlNqvJ8eb;b%pG&TS3iM5gTYXYcf*m97yO_-!w zB(f!rlc@G9Bc$_W;PDJ1{_#FQ%+K!El-UkTM0NGy_&a1%LvHj%3N`A%m=$3pAWM52 z^6b({k&*l}9E9PDJMTjJLCHlf6eG8PoNAL!4phO|C|E;GSMz5nTJVeWI$dK+Z3k~^ zKp~x^-F#gBY?&v6*u<_mGkO-H$Kb5L{qiX*Es7uhLkGv_Lb|-I%wP|y=yOz?XGc6x z&qF@~X!i01w=Hb3XENgQ52nx`4ZKaLUhO$)R|CM{Q)H{RKpe0lkF4&5UckNq61i%1 zxmjDF4)y;?xqzBLEOCwN?XG-f5t{FGJp{u))Fm`yX^4e*@w&HCjcF=U=2tI@#m3F znn1=ziN2$JCV>XK34)*nzq4*!M65=cDxa1J?<>7id;%;uq=2j`|HD?d)`Tff+G60q zvk*Gv%e@152WeWJP?6C@QD<5d-3yNuQAjQef%N90h|1I1be%+`PrM{l-D!x@f=y|$ zP?15RSvf+bgSkxlr*n4%Y7IsQR95Z(YeX|pEPn|@7uh_kT!TbQ(J8G}Qc(B;{P5=@ zrO#emS~LdYku-@b2a9_v&Kee6=G2V-0hJJImiD0EjWG@CXRvhx8#n_I#5U>QYp_fo z2z2x$13mU|psQbC8?brOuBuO%j5FZwOB?x%++Z1tJbAwJhW)K(#?|Apzc)2y#U0js zJmPjtSS5cUOjOm<&hxlbVy+65YtrM!mgNl~IgxHI=~!Gr(WKgMhzldwXt+1?X#Pnb zh446LF31VUX_WJP8Rz(s=Hpy7N&#D_TS&!;q-8^Zj?Ekst-@%!QzRd|cjwe38~q1) zIQWDlFz0h*C)wGnDg@LwIHCbV_^)cZy*yz#-)T5$)3z z^d8)Xz@z`OIJU=fZc3t;IhH>$iT)QmgXIdaLy#U(gxE32Di!%W5Nh`W&xvVQ7 zU1?o<+?swH&FciD!n1-a)%vcjiNY;Sqo9oBR?iq1@GW4waR5?D0K6dRm_W_H`@``$ z9vGmM8M)0B=WSArT*){wA8s%-6KXvCheOXzE_py%KL4zkWq&;h@DOsXSG}%gNo|## z;jI=cn;5jPCZO+9k&gk9Zf2OLbimcEP@0vS9mo~<(+W=t#SotZoB5{?qbl@Zb5#<; zKlykSi!c&}Ae9KDBPJZm0rLM;D=Jy|MtWO=k=JDGN-1|B`?doP$CgpjJIdgjT7gFX z(MGAVZG-|A!lrQ0M4tfFUfY=I`maot~Lz@vv!Uzr(j5QZv<7ro+I>fEeIj$*5gzr%?&vd$bj&eTMoU2SSVnjiA7c0 z#npO3*;Sa(mC*dbtX=JtJQFUZxldXJFjC&bAMx=&8D$+eQp~KaN4N~8phNm#iZWA8 zqUAy`O7bFjv+$0!d8WBQ@k|+Vilba6nQ5coL3!A0a!xDr;3|-CCR+{zuSCu98U>fb zIbz4HP3s&8^lPW2A3~nj=~b=1u6dk;zHV^}-<=5vxb!Yy^Qq@$t{4q)9WIpnEg^>s zJ70&4pC=N-=cp>cM2ft6w4vhO=`KxLj1D>)1GFtEC4lFv6K3v8FugtJdP2)bSI|^$ zPEEID$_z4^DChA`-m)f%7d@-WGE5X>%krQRY7CiHcuq$;K<;9fj6nS0qbONoc-LTn zTvC>6)Hhe32>ZBTj|U;A)yWVYNVFFAjww}S(5P-&)etN$B;7K$l4{{-IE7#gj6gh+ z%tBZ(X%<)$+4Kn`Ai91z{Vq_aD)?Rf)&u`}i|!dEp5!P;Q>%9`L9ji9wry#`2`PtH z8sxUUFdU#%zKZXL%q#oXl3x-%Dd^-!WW3pCc9m~RFTOy_3hKcZhJKH}LNvlUJg-|H z`oJ>h>3A3ZSO%t2)Guyb6Y9a{!OMf?H3IEsgc(K4|DPu-52MHj8QMWaLcYg3j*9Y} z;B$tM!hd>#t01!l2Qh3dqELx$yV-`OM%A)jnTAf9?8<|a=cdHHAHc4q{C|7Lky*z$ z>xMp6L0Ze3s%?K#_$WfdE>~=r)Gimf#l7qe;qYsbMo@ifaWT=KIL`Kuq;#_+rD%G+pw&_Ynwd*&&Q)1XkH7*|BP<~d;(lz@zEWw=hAe< zSc`YDJ${yxeD#>-T>Y;3F+df-pfR>ByRbh!He$+Z#)$AAX-jl(!L{^Ho1It zTLC7y@)iZBfl25F>-!(e2!$7w6iEG72wT3}I{|Qc?G$aM@gFEqIoqo{D#gjV2zL&{ zehW*J^u)HlV;tPSqs9g-dUV;_Rgb^xxZn`upW>(*RZynh z3CJ|N3$DgER^6nNshVcyTWta0IE7VuQ8$>ABOKZ@AOzJ{zqwXR{kFPpVuYnzZXhXuQJ7JpWO^V7#^$>xux}$*WB-}pC zNWY+MB%15q2U5(blMj0Ed0K5Ys@CKTfoRU{b6!;$%(kMNpF-$4U!X7_;$ZcS;jyDH zuKM4)2nEuG^P7c&8(lM!0!>pGfyNgMZ-mkwEfOn6QzIr=I@EdKqpoW4jLBc2rX(PQ z3Ey=ZyZj-M=?euHatdsuq%>FG&I))Qk1T>_sNC$@8gmtiy6fxI>Gg|)yaVb?;V%pa zQs0zGF>2E(S4h!<%RN}SbwHWdCiQW!>u9BAPO6eZt8859&k>F8!K#($pKy=QE^knd_$hEu{cPIL=Jgxb9aznGbR z<4I0A8-r}pD`o~QTX>vYPh4g_G<39FfV+o;=Dw0)K^+r=9hTV+Q(9i!OEE0j?{ute znfqmcacmR542f(C*Dy+Ts)f!UWp&r6swco@qxB1L8G}L23oDJa5#-DE^r8;{g5Dj% z5WJL@Yme2_`7M>G`ACNe9Igm{#VHM>xPAQ%YW%GP2ACs4^*b*e)@DcDhR955cad(U zo}u3B<(((YP^Wexm0C=T_T$cK8x&O7{T#xcH38Kf<4Aae?ycU|T>-gc+$CKSEc@1K z+0_jd+PYP;PYV^#WesHEzr4m_zOG8lbESXg8xNakxM^{Dh?Vs=c(If=|3DrFzi$=u zv;@f<laDKNhEiMZpIF2s+4W-f_N>?23Dd#vyQOk@xu3m~J zM2@R(j;mA|J2gPa@6C4|qQZEk8DA@xjl8`IGxS8{sP7+Ixdc6h>SaHQE+JNfgf()bTw`v;q`aK{Ko}XzOyo8VuXTp(5fiQwKQ=UOOS28MV zg^Qk2x)~NG6-J!Kmhee`@&+9q&!mR()vCVyR*<3^_es)}UeyeyQ0z*N< z_GsKzBM6S0*9-GAeGx1@5`sHt@jkQ!T z6FKLg?x9pgy#g2NP0*trAfO;_uE2=X!xrwVs9M z%pHOA=1l|UbJT}|d>!~d-+i2a;`??KNpr*yP=U2nVv&r*{p&cDBl5o&MiX-<`6hSL zhdrWY(B?&yj2>1DvKirT5n7y&Csm#kKwFQ*lF@+YDH5#|_c2;;FU7S2ssLT~87{r{ zjM<4pmMkPniz#Qqjv1y~VvKfKSDj)nJam#}oq*CxS>f71u694_i-{E$2(d^^$h zW55e7VMledUK-;}6ABWoOevf10i;jtL%2V;8XvM&PQ;?o*Is9W@`uTFM7~NW@Ekw) zf%qF&r<%N+g*IkaF3z`+n3XJ$Oi#e>mJ$rp?A>*Jq(m?y#XcaD72^o{(B7GuKq=Sx z^;kCwbVCAWD=P-$MWJ;8^?9-ZO zrbww`8or|4?DA;xwReXRVtIp3!dpi^N$$gp9K)CQp_JT#TF!hQaH~(w*z0*-*pXLN zZDj5Kes$W&msdFbiu4k|afx%E_SCYTVk?|p?{{OMXB!T1Ox@#gkUZvR%&COrtUts3 z2laU9toVyM=m(ESX}n+e2Fg+Isv@P4h4nUj7#bfwN71iQ)3^8cy0=7u-eczZA!w$8 zwxWXoB~bWDi_?uIcIX&GEA7-2=K%hn?41fN>BInJ=h8oaP#R^GiPZ?}lYZ#!5wtC- zHA_{6N5#BMxoFxt@da?Eztr;?m&6%1D`)CWLXD^J5Thy&<6>oI^#UE>*zBetLnWBF zaf6=c_!lxOw(aG9@o57J+RON_wK{mF_lro(Zze5nLQd8lprquOx%S*rk!TfX==l2H zGWa@1l=t)Y;#&P2j+vkr_6yPfbM-pR!b43;#ump4uAhb3 zI6Q@8Om3D=2!`^OrwDVXO!#na!Lssh=gH8YXwkpryndj}?S4Riq-*}MlhaLJMKBSG4@*l)yk4U3hrO+Us+HdMu(E|3E387Z); zvd1J@i^%)|dDE~#UV z0!gyLnx3IE9q~B*r(YwbyOz>ntc&n9d+=pQG#b9`h~+gH5HdWhXiwzRm?o0)WOkk5 zpa@|5{#s?!^I-h?VrmmQFcz5_Ag3xzsTfiry#> z)kukJyhbYIZKb3EEex#+_rL=08AHW!QKv$MuLyfaj}=CQu;33ywj@p6wUw%RH46E) z*B(l*+0AYqGgzOY8gk$1t5b05L;o35;bX3ebUwATS+UU&|Jt4U?xzuNh@yWO)ne=z zpKF!N(4?@Um~X!v1F;M?ySC`8L4QiaBb{Lb@VYgn#XyHC_%RHq9r+}c~4UBH7 zAKaN~IT*izDaVjIYI?dKG|Q4mO&FX$7X!13^Y^-HpaNNp>`BvqO>83Xgpgh@vFDB| zptTm38}UNlc!K>ff+8yS3C*j#9hv$_ES%l2O5Tn7yGDp?;UX$3kGie-cD17C0g$F^bKY{0UO_wN3nbQg|PpgeOdF>73dSR6E%aB{KUYydEe)W^g+CV0N{Ni zd}ZKT8fnq!!!8Zwo)ddo>%myb-{Ph%H;G^LRc093aNfuzA6`Ex2oggQLha6qiCOuX zCilAX%RmBV`o`U`M2Dc&hcaU9ZJ*E_pEFB9gH76etXDl|Ot$Q-WnkcUM4=dU_?))e7^%evtKjhC~)z zt8`c@_&x+21*)NAUqUJNGqJ3^ji*ES?bS*2ap3%RUa0IfV(L|~Rd0B1?Z!-Te|qv# zpWwU_c5i6(F3{!;c~T0tQGSRlm#?h2TW~@@twYV?m;TJ>i-w?(^;;VyFUbj09F+F~ z_@(vi1mN@2X0v7Ot@DXVFAoWj+4W0P$GTC?BSd|W*i3R)Za)~o+(yT@tRqV(=S|Q*K)8a-~}Oi=gTbfGBn6!>lO1IzrPwp zJPGT#P5)8e=v@bYZ&5z727a7E?~k$=JvkS{N3;J?%V_8}#;RYcKCmhh*qVd7G%=tc z2#MozVZ}D87Omqqwng8)SZH{56nhmlxTe*gkHZH^nOm4Ef%Y6AqbzL6tT9mmn%Od?%WMlp9XhVyg2w0fIhEQ^`c<;r5V|QzGX8! zqwnt@YZk2hc(j`^U4nwW;c*QT42@@TvQ`9?Y!@hv?$>^SNgCwb#Avq#8+#P8H01`< zW&-~eY;Ab-TR=>)$mL(;8kXLk$1m%{{`wo&Nm^HbKKqXx6^^loWa~+*qfwTEv0=tB z=t`zti#x=$F|+l}bbBcwXVFqlPB4ojHY2%dT^4Hphp~6LzFqlYAsw~x-%3#-c`+3F z;qs`(YjzVB-DX~ws~h)5l3m?0*k|owUDT?VP}H>E_YExR`Al6?UmFo9&3$=C_KA{n zaaV#D5PVxB6aiy84GIpnJUkY?)O@cXeq8k#a3jHDfo)H$E_(<#=6g%T(= z(0!y9S7)J~NXx}${pj;bKU|#(n-^29xyu>Ejh(MJHvV!*kt7qm5JPu@UDSa-`|T(| zxWa}gVn>;?6r8`1t(5)6Pl4tud^+r84}Ge`XS0bF3Xjp8ZHRh0e01j;IW;bOgI~e- zkNxjzo-57HYaVtHCZI9UJY_Jk6U}SYenF-898xWkvJ1n`*;;aUpC|_RLV{HM#ykzf zVD*2h76U@x41AgrvuKM;YL2xB1eR>$OKs9K7n*4mrF$H5Mr!I=A8%JGQbQYu=2}sK zhJdj_)yn`HA?thcn6CONFez_7I!ld5BcO%xZeAdr=oXPKMDcM8aai<@df@lYi86M* zt&P6Ot5V~rgE|W7$)7&^r>Lh_y}PPm^R{fslEwNs_k|o-2~+1%3Y&QKHHA5WqUxE( z8vfaL=9w+OzCm!6ZAjFh#gHmuFP$1^e}Tv%`zqzk>*k5Q!uTOD8862Y%is{HS)H)ad(l62(`0*JvAlwDF94{Ot z%Q%upqOPQAPHB3a?US+!?RRtrGtd5&qvf&irQD9M!f)6Qx; zX}`0EJ13U-IaEKIom~3t=H{EwD^oMAiCX-%GToFK<_sl^?(2m0?*u z7z0Nz{{3|`ndUg15AS$$c5*2(B}TASid|qsuq|2u`1`6fmLDGaQY%Zmey@L9-1^Nm zFTVk|6loM{n^L##Kad19Wp6>h$W(iAoimlJUtCbk_F(eG5G;-SiI%Xl$%X`Kz4@~M zf;?#!TFVn$ohD@69tPtgW|h)?9O#nsZ!He1p@tv$nFB+#IfqROL5{}>A4zD*Z$+=# z^G{t}JOcw*qnXo_RKhT)p*g|mB@8I4WAUpOG%|p?)X?{h$9R#S>0>!0^zv}-DU_Du zIcE?_z2J_D$^WIF826NdG3KWIAUN-N-9Sbi(QVX1wi!}LidpG$xAdb_x3N@QTt$ya zU7o75g&NHSvLZ89qOKGPHGc839(9WrlyUJ##_$0={pW88WM~{bc{Bj)W#ZP7Y!gxb zt;At6S;r*wL*}_cI2n7raSS3-X1Ikd6z8jS>W}4w7?bF&*EJmFbFIeDRnhO6C zHjELTu1+MFW2_$AH_Q-(k7BLU8 zGnFI*=Q9{lIwj9ebv5S{)qwp)72YJH1h^l~6xAqf@|c9E@Ev%($OJ-7Y(d-k4)bsg z0k26qOiW2Zs2=+`=fn;vrNP{nMV$IQPt2R_JTgt8BnY6tdouy~t^Mf|);afP`9@} zwH6B@WvA238d#CpmqLUqW?|p7RJr3+*mk4b2fvn#8qYY(XvL{w|E z=(TkS=gd&yZ`3{uIlRr#XX{z4$g;Y! zd4v`Ze9Rum@+}8rG~mj`_(Zz0hmPnZW<`JG*19J%8~$_I5z#)|^Vq3@vM zS4CXEO&k9N<&7NVUhCwR7M%Bcg0(fq0D({vy`KkbOm^R}zKN3ahejMszuaUvcKi)}62c9g3-Z?dM(kkcHXJ5wQVLw?Nap?7MD{BdfOHX0LPny> zHB7;u1cCNVnclMz(bHS1=s4y5nvulbaL*^EfNn$T;IQGfVuBC~Sh! zUoxRv5va?&f3T2u4^8e+j~7(`fG<8XA)Ia@w8ZS)sK)=B&2EfslPIw@fvz_W6Cq%AG<0QFRg5ebH8zJCi^@=!PxrgDH}$W} z24Il@m9$Bg?sEpS5OUg5J{e_2+`kY@oN%`}NHWT}Tu0gFs($t#^`>ww?E?RrMv+M= zJCp>rZVjb3k>;pc-^Z2<@IVhI8pLMcp}BjuaB}oXt+RANydP|jl@cbX+__s_&q}wh zjgd&fWT-W+Yr0dGg7t+iLf~_-5p9*kYr(PKqO)vG>h^^ z;ayh7`gH`*lb^nU1j6%V{DXIQ5gQQURq0I4*TFfSAs6Rx0cHPpTm^&l;`7S)X{hZ3jAjj9o8Q8!MUYRqNnd+jzf9C zb`BI@t=N|9*lWq52hpYN)_gK0nhGP6vHU6BOZoqd=mdTCvF`GZ%G~9<01NmQMmvhZ za}PyE*#(07l3O|aF);K>Su8Gq=+hBpsrU+#4OG<9(VSqvsFtNf)FLCE=(l5O+r z7xpaouW$VXx}(bct}VukpnRhNiIx0I#}?CjPpnFN&{O*M?cf?h}UO4|6^Vv`FPIg2 zYQNvqp$TnMds@Kun%9Qe;LHx=R!RE$Vxz9N8xNolOOw$g&`U)Q+mPoZbh_nU*N}$XRM2diEk7c%_JGCqDS4NE#B8qtDvbvle91 z#7Gnjgwf!|%|2J}y4g`6a-sxZjIn@DBd#i^wwJ zzKSphu@K2p<%UBLRjRY%=@yWwRsd6VB*v}}LOy&mwsB?nhyK{?y}IeK7e}b)+wS#J z2NDs9#_58PmUy?RXL>JK5ZCw~lsYy0olsdhiioNvG3*b%X^YkAeKp_?K0@ z-|FuB4=Kr^u5jnvSyF@YCpMM58Qf^M2?c952|rTASbrv%>mfUWwa+yHs1=Qvbx}7; zAJvIcz-&_!yrS?nfEH?Rl0tL06|J_U^dC=d^9S)DRR8+(?R_385oQT&l==$%N{Z!Y@a zGpI*J4L^J4_-za3@=^iGrY(-oQA<6zpP$nU886JuRW+YJuI^KJInv?f#Bul;8O`{&kN>!6V}+`!t^sK zdfm9mTV*U>{${*}e$l}A7d-+P;>2qW!%nE}@M^quoG%4_2%=Z=j|11p@vtUvpy;Z4FNU-6 zfAwaH@DhwUEK0t3#-v5k6rCL>+QA5Bd_1XrHqd(1LA;pH+ed7rAyMsQhgXn!m*G)JZyyd|{SWKklF9PzoRf#zL#!>Hxtw%)!f)g!lR!mO zvgVk5lK^}~vm`<{4 z=BP{K^W=zAz$0t>CqnA(+9Eg8*suUx__H?RAwH?#*PdIb*8xX~ZQ}RCM><2XpPx^O zK=7%+5_&$@AYS(m%5AY-ECWnm zs6XOmi`{8Y6?i6w_RIM=5hCLErwv%TN31GHisn@{qnTt#V=TsrqVAs_i+AoL)X!fm z5wkvD8nC>qVW2k;VNizcX%_NY>)te{L42)N0cY`;o}%U0RDc|6>e3L2mShV?!yx0l z|C{uBk_q_m#ZDxZgeJwzo_mf1H^d69i%gejjnu|_;YR!0n+XtE{t8%A%6i(m#)fn& z%iYHoKNT^t1iIVa;wfy^K;Cd&k%c*!F!0_6zN{1^Ow!u`rD#+1?&z$~Lk|0XC?!2n zo8evJK&`o~GD9xlNy~kZNA1%BUM+b4usI__Mqr6ZWCw; zt5rXbb+bNdemm-4fn1&L;;=kf74NF;V6JxM&%>4?g<20>5P{NNZsZJf3Xy<$HzKN~G((73}NvX_LIOLPgNsXXT(_7qpFeBWJ2 zA#sC!DgQvTe)f_K3!hMt zG?giF#q0MXy{rdKg1XO&;X*@1y(#m@W-&6afD-u%O zMvJ?TGe=|XXamPMa_AQhIh!m+V!ZV8F*L^4|FSOV+nkZ#S(j7CHM{NNV6wuinOJ(J z9W)FJBTKJZnhDPcg5jxg<_mGWD$LV55ULnrb@enF_ZG*If{H;V0sm%~MQ-Kdc#q#h zAa?;*nniufvv}O{JO?$y@3?Qtnu0fjBg##iUza(hyH{HYF=b#(1j`;um{-n7p+yA_ z--ccN%_BoP>4LkhVhUaMc9HSmvb@AK8S`nlEvF$L4W)Sk^*3<5iV4Y}W_y(|KVx}` z6Q@VKO znOb|M$t<^#(fPSEv!@a)S^eFWQ>FGzk1Aj6<*#j>*k&6l$0o7CYS_1Fg5SHl1WJwE zbmfMFZP_Pw7CGi%cEW?q#|Nn?dB6Y6mPom%W&`yQ((DIcDO`dgcoyes)8*+%?X|<} zP9)2$r+bx?qU&I7qruFELygk#M`-8Be=^ToC9jp3RvSQJZnE_WOS{Ny zFVZ})*Y!;cJRxPjme-}<*ng_isJr)tM=;ysmPw@z4l_j_AN%5o=mMF-h_URLQtwV{yk>~^%wRYTuwRSt`S%~HVNQu$}F2fK3Tti zGxIAq(4r)hx!t%n{+BS6v8tCdIzR88*h0Yv@)=W1bqpKee$RW?bIB`&5@5}2Ij3l& z=mx0nm}uWU)-y()h#-iuR7uh4e#wxhSD_uSfpi~=RvQkk$&7>uJpQ(AT~ z@%e`eVuAETn?_$DP-OD$jqxRZ_nuY^Cpvob7=4_Z<3H-D=X+%rk*qPr!JP36hKX?aN$nIyCR&!33`Xkg)NvPGhlJ(($?_D~62 zJsg8lHS5G7dIx)`z~SF%$^X*t^S?G>Z>-h0({g*?!DNy$MsjEbuMG;lNg4q2UzsH8 zAME+G{f17jgL5JF!yh8ee0$OuJD+*2%>46jct@xGE&!SFxghko$b$YJE^?%-faEY9 z@g0bb+oM82$Z7DiJTieRv7gC>yE)k1pC%ET(ZV^Pt&<49=4w6Nj*5+d2+*kJ=%X(0 zgF=q3r3o1+;kG=6jy@$wJ+6+6KL{d}2s*^p)o0w`67&h{~Sa?zrkAScCC(D z4#EAfN(UumVrs8_`$%CYZGKh;h=;E;iDWx0PI90SLlhj(PqTkR%X^gAJGmyf!C%@E zA9!Xl{*H~m+Vf3fpe+OO-cEuop#rzzjQaB`_OZk871n0nYlnW9Td;2MQ* z7n;tQ$D{sVkjz?ePFXJ`Y{tJZP)DAq=4|w)@$FlMFif(h*Ijb#mZ5iLE_+#N?H;Ud ztxkS!X&?s9wqmHj43u?DqG9-#0Sv8K66A<4Dox)O^!2(=MdVVj^AcsJU8l3aQEj>F zyxl7jrRplPA_PIQ0A`)DXJFkbIsmKvu;G1xY(a=8iLgUO7_ese+mBKOE2vvdsu$M1 z%*HJ~mP+jxif{M_;E2&pUvMiyPBckOL zC#eBrt&kUg^o^-d)Gm>*Fud%_ICHU#8t0cPmeosrb(^|fhQ=AH-s=bk(|^XYg-d1oDj<`Ij0=VypF zC6?cJSIbGW87e;Wwy0osr6MkOyd;NN%n0CgAde9S2%UoLhA1-p5PLI>YF-Vp6HrsD zECvA;BDKUTwg@AH#EBT%!@DO<>rav=CJ)Qm@r}L@K^YsCXG+}dx0N}rgu>>Rm=m>~ zV2g&86So=Hii}UOCM@5Mh1A|?Q8(*}+BUSYASO=mHY)dHvAOj{h24t{h6yV3 z&NdD*gFSxAW(~2L4zZWN*GENnxaQGHpmSrL_gT4HUN1K~k%dgxt@nuEUI{a}*2Gn7 zX*>yazs`+F5j5ObsKdP9RS9qWh$FJ124#hnXbUsnp@S5Ll?aYzZzwU0kRfb%tFjoG zf%A<76|(|~I|ncVbv?;q^Fc&lZ;65{iBAGRHMcWwIgMt~N4!wh!Xj+x8D9f2TUpgx z*$;Gufg~w^Z?^zt$GD{eaJ~Q=-wpYb(tHrpf3d#56+t=J+}_rMZm5@f;F=^f+(2o~O; z+XCbO)LWbI8(kIl(3}A7ov^I@GP(Sa_%9U_-YpLNeBMVz2IUQfD*CpktPdnfcBF1> z&qun+*EkU>l`pida(tsj-9gTnnn`;N&`){1J8qCfc^tfMJbC)=0ZBY`k~14XNXjd+ z=%Dn6P*2g}wAV;umIIPtxnJ4vV{eLiftdnjfLd+v>iY9?q@wyVKhyM(MK}3x>mSHu z?LxI&%A+!&9y`Xn{`q*PV-g}5*+X=BL*KGpxI*;oF$UYk~hpOYgY{FuDeg;7d621; z(4y)=1w=D!)BbMA@V#r_E&xID6^B+~yBe=3-v98s&zuIBlO<^Y^!#@NKEY*)=wh0* z&wA`EAY|VSBpK0G7Edz1DbnwWF5p5fX0os5UGhfs8b}SU>L=4n}a3{uO-xK;Px2 ztt7u*YhR8TRZEmb=nG(jncjIRrnl2)Suk+(pFPMG@P?7CJ+pdFGHdn;eZy8x+18Nc zjZFZz+7PnyWAo9WsC)eFt%OddI@QpCLa0ztj%c#byBN>tB|i&GbvM`0SV4C@qJs3p zEf3S0xjOEZviMLQnM^;G1Zty%5o7k9dbNC5V~~&acD)$XxSna8RM$Llkf!+`IeFg< z{hRTX`+K;#D+L--MX!x`@?U~C>G3yFL}uCFK`#4*w9Fb8SCe|A$Tw9w>#bX<0D0A_ z-2R2rtEJs}BjJ@;lHQaOjt&m=bq0g60E>lMM&J#_{OKHPwbRsT&42$a>%ZPalE|;K zO7?_z6(iuhxK4iX)YPwMdG=~JL6nqPOJ(SW-)f)j2D>j4;}M&Y;Nh&$tSr~12$&j; zsEp{vyPDdXt9p-O$p2TW)qc)v1$0(CySTthh3lvL9ZHvvv_@19Cb7c^hCCXB%K|8R zVL7$!HAA-cR?tFO+3cD1?pHE1?6Tl7Ldc@0le2&$8ld5NC9dsWNXEHn2MxA=2GWO7< zfJCpsMTR&>{3_+9vU#$DaYu;Nq)SVK-C9(Y08L!&^^0?65UG!lvhQ`(BaGpN|E`03 zY8W0;gV)IuspYz}^W@O92BFYfi;#SkR>yD5Ato>AE5=O%j zK&hXH75Ha!DV5F`-P`Q(WXyO;d|}R-+Qc%p+%ZLS_0Y&{_`Ii}qZk*1y}NTOsFgqY zfW>(D-S#Ov7t-5up^MmaZxE(cO{GNM1cat)^0M7MsJ%QRnZz=#6{!XGO~+wmG%#sO zO2Bo5FhG3sDBc(K*D=C!T;7BN+mt+61r=riH9iFMOXe<`4M*C})>-<1YvdWgHfp<8 z!38>qn-@4DZ?zR1Cag3?E>SOu4x-|vRhLfy(CZ@$=3+0afc6a9lbeM1?r54(>YMCy z=3_aw62S%J1F4)BR3FLQM14zocg1O9cyQ3!EBHSlL0qeevhhTeX0aT@5`w8xb)}PE zIakio+nv7!w`Kpd3IA88jM8Xi`-mR@FYrj<%BtR!7+t%MxW~G)@;~38-=~o?STiXP zb<9Oet7K+6)SRI4qKvZ5h5Y2L{YAT_7JcSfT;Rxceqqrej~DO70;_(6PSn%t`=bhx ze3KL8Uq=)5k&hS!^TbhBQLRZ2_G`6eKr_B*BpX{8$eR{yq7krjjr6_kVZ`h{5I ze-X|Mopj4piH;7^+Y#8hK6Xko@FI7y8FdQa7MDwK z@!RK(bA!twOc(I@4r#xsCb>l&^0`aYMf*Nr5LK~rxPb6b&F?HaacF4Qi||j=mIipy zQXr$E;D>57ijNwnE#Rb3pVcDLwWXaV>>R;dn`*ir*gWCiezw8lU|a+)RkA082oV$P zU8TVv?*{pkiJ#OE0KMY35?8D&#BAVYz*b@3!8FlsnliH@XD6|aEbf*By-Tncz^uFR zdtU*oEGh|19~Sq)F=_mIK1p~x0u+Udn_Aix>6unEXHk)m%xYv>aXn0|tR09WS!FqK zWIkqOXE};SaT9IaBILX1HfM&!#;`RxH;zUXTk#=3fNuMIYb7|v`)Wv+>&ly9Qq=`0 zJD~(;$zI?SS_6annKyNmZ@Jy)33-wcWEhxEa`C)3j!Yl2CHVuNN|N>9f&@^!9?+_Lk|Y8$FE$ZSW|O5sJszpC*Nt#>ec5phS@)bQCn%ThN0n0Ov13y z+JmuuEY4iZbC9f~zY{%d0)Y}|5rPsI)`K`ouI3{|Np`Kf4h|4elp~yJ$Set{pE$&;LCcXA5P%#nisJ}Y z500!_0)uS~cMv}vyT~_P1#Vb0_BoW{lTv%?U9N+X9X!cNC)$D!f-uDjKFg_`%AGk{q=pe##DPb@@ZS&&mIF9Rg!1%cGX#<9t>|9 zu*Kg2DAId#=g7s}F|RCccBgzX$(Rw@7p}7SO&=zTO3kgv5BYK7Hp6sN! z*ihLy?0J;Us9D8lZd3Km3cL2;<>3;wk%_3*&&l_1h%9g~=3vUc&^mezxM1!I$g8|= zO5FPMk?hi7{D-*~%o}kxj0cxaz%fcwdt}jLG@)cY5-qFlQ()-fv*{-xvp0+~h5x+^=Q1&f)y!#Sf-%UTbAHbXn8Qr9h>VJm|X}P0p{;+j9r?c6* zNQRS?J?Kv}tDp2Yso+C9D|oEXShG}_o)H5D?-moF`jey%`URry>kJIpDl3687=p>K z;D<HBL=IfD!wTyU3bwpsN_&dX~0hvoaoUKee_90G)rM;Mdc6{!WNv<7Gh2U z0(n)~f{j7z`H8YI99GA3;Mv$FvLlrpYERyocF$!E(@!fRE7RGgH9&stC+sqO`Llkz zBLO-nl;)QyR%p7vyss=NpN$QAkmGY=WOa;vfMw_LODb7hz`+$WwX4ifz9+p(fT(30 zI|HKY9o^WK1L0Ycjl_Z4hN`2JahUq(iz^q*G4)Bq62H#^fhy$B0^;l`9k>@NWYf#m zoaQpaWu|xKMJ{Xgf}>SHW064mFC8V_gu0(I3V*K1t%1HFelgdd?;pJR3yH9812lW#|;AsdydLxbu#@c`;a9@~+^E4nNjH+`Hv^M&0j3 zkbqHmvEx2=G%qC(BnY@$t5!(3ad)8Wb^6}J6O8h5oq1Llz9&ih87n=#n24F`5>$5r zDlHa_O$w%Tl9*rH|m({^@WjoZ?s2QS@OdrH8sa4+K>&m zCXI%Z8`Cfsh$Y9S!Ad*=YafGSU>@xG5-U&(IW?#@j+&P#n-j5wJmF*CeYm>0CP^v2 zE#dNm;mg=GCMbv|y4kX}m6WFtIex0hGmbp4?{u{)%2e2TyFt6ejZVnF_*T-b5dAS6 zlhYejQnODJI$H979bGc0V76Os!Horkt^T zggaN=RCp?Hw4ppEh5iWI)rYx1)OIhD3)z+hp&h#AVZ)?R_#px!9>!b~vdSTZ3?+2g z-$CPYeB1;<5snN(UI?P3V%Wy^{?LTUH}ydX|LC4puW2I7#ylszVHk{B6l>@U;N=>6wOu1OU2HWgS*7PC+0Jx>8hQ5s&H6fZ_C77f;RLy42~Fu)aSUmRbk|+Ofd<9z1Lm6+=K`eTr_AKA z>0}P*)H-3mXX)$i)H~YBrW_2O{HP?%L0iH-F@p0NDR>PRJ=qd(y)&1PHl`=Ebz9#1 zY5$~*+sLov+FvM;G#6uG94jg3+@`rBy!Z#Hp}8WFZIO}cGw?y6b#Dn7g05#PW`}GI z{2|i_Mh01RzP|MQn!Z4oG$M`EsnyMb^@CVJu!69(b6czr z10*8}zq2mHcAJ&NIsnNST-)ZFL-;`Hp`tq^BXedEdbaqY=aPN}XDcK3+YMfx%FcSh zc$3Lm-)Eg7Y#$tAsyipVquT}THggk#5C{=915rUaagP;EX`WZ-&YI+L`32a@h=I=#Wk^Oow>=6-V3T*&<+`l( z`hUy^ngFK+7g?lIyHQG4nATKz??Sqs8I-!DHhtcEYDGxg5u78($`2wQ0n+*dz$hz{obpP z1K3r4?+WzVFa@ki;-I)D=JW4iNzU@W{K;)s8!AOx(*fEI6K-Y}FP>c=#CrB0oXHSU zAiWH(?zwC>9tKIImiOek%SWOPah;%aiba=174l7Ga-r(&!M?Zpunk&V2o9BF(zeU_ zX4bK)`e4$fgMF zgT|WO$Y&=%3q_S$bKd~0qF>ip-N@5>jP_TrPz%pmGL7Ahfjq0TYWyf~K=%I=%V9=0 zO{F?jG}c|U6FhvL!AYwe6e@d{0T76l%^bZyBg)wdL-)7CJsdCmIx-)Ez_>~B3fb6s zvj=F^b9J|v=dTh(AOU%GP_TwrfZjGLRCLaz$GN+PtY5=Mu)ODbo&0&;`J%r80U|un zOjYy04Y`HmP~=>n=6Cgb=0Gs(l|X^g{6%)!XDcJbztuG-b;-GObSij*cT!92u@-$8 zCYsoZKrQJnwQ+cFWw`3is(0>Ox)?AIwK{!Ln4d^zi$w{U%XH9Y8uG^=J7~yk-54ls z1zIVc)1J6{`)CSX#<$-z)b#N{x@#UirIL| zk}EJbTR3%48!wd$aW##NJ01*(^Y@$u5jKh_5;o*tYpcvXN`9_)C>)V^6;@X?VHdsELMD{|2b6D)Ds$kW|7mapp`8OhroZl+CBga=vz|W; zENJm5wTK8jTihX4pvHFk4CYL?LOoSuGS9xp4qb5J0e4kQwE_nAht3LpslJA;cm=!B zbOQyUc2X5ugN&W0eKYg~z~TX>E7;3p$~Pvzq|a}Q>kjZqzUVU)N;3yydPvSxKci=L zuMhzj|Aso~Mdb)pc|=-(KMRWRb56FzAZ34_4`hey_Am_^LD|_NDdAg)>*ME($Q<8y z*$gBS$R%-V#nPgGPq8IE@`|8o+l1ZhTE|4TQ0o-yYHaYvk;M}EN~MKxFxU>HoCj4M zKOxOL9jKZRw_qd4I^O%b#5aTcWq29ufe|2^eywjtjPo=aX8q@yn4Gb3PSNqxG`)il z;YpwS$myy|@&1HArD->YcbnG+6h;}AHM638pZ0+5`Rc9Vff;RzcKW`34miN4?)XQ6 zq>C6R$JC7~ezHMeP|GC%a?{L8t9V1<(bZ)wG_bhlFl%g?Xl!X5Kcks}97!%P+y9#i zZ@^3x=2H}R4SVfG$&`j}?vdE9?BG8=&hs5{Af_L-t@WkauBTet;yZwuQ0neY$1gt8 zI~&s(F>(&$y^>+y2D8M=!jeLoUA<&*Dp)m|dz8BW%T;j-`}DCjE!Il#wD^EUv>9K$ zFE^<@m9f$pJceNk?yjwmDr4ThaYadap&dNeSrGYj3esuLde92LCY`+jtWF>8FkV$T z784xK{e+B}3C}m)PIiSBji-I^PlHy`NL5mIvp@YaT3sX5L?)W50tFFI=WJJyb@`94 zrS>w=mxIz;QJ>ri|gOQ{whhk5SDutWchK809&e(}`_tZ0)!&%={$y^~;qG zTqCkWBCg0AoN8}fOyWiv2NM*B0XY3e zX}JuzMg|P1%;d=uqk%6wpBdZrk+C>?bFkHDsJVH*53i%cclYj~M3$r#ni*7r%0cx8_X~+dsqg~Bsy?BMVFI6^C_7fL^Wj#wQ(ASy zbpO-;a?J4cgKB$s4?o|G;brRXg?)sGD-&5iXjFnx4jSA4Dyw(nF0VL5Z58q>f<}ga zT&eX4&_lZyl2}W}uUTw{K<27Az}T>kh_!yk{68KCqdbb!68!AnVlwd^v^+uJNw<=2 zgMJN40V8fT0niz}ovy`8!pr#>h4 zy#<8A38%}*)UM(>=_|L6#TxMyH1W1{+JU<8k-9}v9$lVX!y&1sg8>swr1CO)2lj?| zLZzy%-(+guN*4F9Hgn=YGtcQlM;C9$j`HQaE-7AXN^f(Xm!{CwOIlH5U1jBkhQT6K z1R{myP9T!EmWYe9E2rDj8SG*eD1OX7oHRAHpu8B%f=&b}b~LF;FFYg=*A^q4#!!Xm zLlAJKEyHcma(g&26^Y1~Tj%DJV}LK&^u6X)h_g961br1Lf~|tPhxTY--1DoYN%pUB zxF0A^(hYV}bXHVU6Y#RH`f`a!-m9$Rd>Puv7pdod9tgdgJeFYjCyA-Iz_J9`1~0rv;OaAFTo5u;teS#h7kbzY1<+CRGj5Ig1gO= z*0EK~4+}i-KL5UNE=}kJL;k=t?bNoMK|BLWGJqYEsn6U=7f>x}geL)qk&wMn;-2zk zfHHM@Q5}wPqcbEtyifGKmOvIB94KDa*lAGMQCO2BBat4%zk6sqUB%OU6!Ac2akbp1 zW{5`G8(>SB^_GGzr4fCjsqk9(K#>o@6xcLGxAx#29@K>vp+@;P6!tR~29hTMm(+o= z(hb1(dDK40Vw?E&%^qPFtWm#~6$llq+5mTLUlqm8MH!q-;nN3QbWlWI-z0D(n)KK( zw^j*i^x|BCvRTIe3EJ%5s+m43#a<@BP-)?<)lbR)v3iBgX;IRn4Pv!@Vly4<8F_j|~sdjv_Fsqw_e+fYA@u1Z)I4txo5Rv%X?7>N@ z3Je4FPBqqLnz;Hi|B8rqn5+>n%RkIU)hmhmMxp&()#vAB@SWMdAakUJA(O9qLh9uGimw|N@vfF(_3~ygW zh7$}5>MO#1f_68ZN2>a%CGPRJ4J0frot(^q>(n#-mf%m=c^n-}TE zCiYWIb?ylp6(&ugCfY3 zk@ebz(AZXMfZ`mrNJIIt{ZWdrQIM9ye zU2KqH|8sHyvDWx&?RiAX*N+TXpCyT!h5ez#v+LaK^ctlS^-NWpCS0l?8ILVcZmzIv zE>MUsBm;Q4iPyA-sr{el<(Il`2Qs9c)jms(FY2#MY+LcYx!}WvbZRNu*iqyns>JR; zZIa38PM4hu5;Cw^CzGX7gceU&-QG}93KJ7KQHQ2B5E&&kzII+C2MNfJdsiC@;^-LO z5WxrP8iHr!bKVzED~1)7$gb#SJ-F)K zXEr{?5nj~sYn@#VVb81Bf}HshzHQ|dhw45=@5l*!Mk^E#{2=&MnAZ+Gt;BOI`s$OE z>yTaiBDKl>CN(C|jc3~iV!(wz7H6Z_^N!d%E)%zMkvT!t>;h>VnJ?^qSBOI% z`%x=|O`(FoF(OO~BX3o}6&C|fom8JSa6EfM@5{vtBX;TUEV8*+SWu%M66}nE(TRt# zdhl6}rdtOQf)`3+h_Ln9EkP+NJm0{Rg`=vnWI>Dn$w*si;^4mf7n~VH@}5dd?pDm5 z57H;M?V+o+^3YUvMgSP2QhMU9g?h!1p*c3!B}7V<7moR#`AQ51MfA3L-P~BMxJ<(@ zSxZ^w{xv8j=zZYwkYQZ}x9H0Bn#O!cC1ja)FFfruN{GE1K?Wv9Dqzc;Y79wu>o3#& zSG<_#T*<^wZ#2ZYJ=Ps;y1LG%RrVP_<4)G()njbPKo`|D$8lIZp}Zwpn^N>n~x75m{l zy6RqM$fRSGtEy#7lQLh2ZRW1-8qkLCOGo46q7AE_bd^E;%-wAH~mk-P_yL^ zG1Aj5c-@aRLa;Ca`eFVR%fk%72#I;St;Z?DlTeiOE9rsbtA967vjU~I79z0%wD*Aj z)eohK2*Zj6idS`@gRT-x4Nh{WCq1mcN6YW z7V|kcf;6B_I0W6Q@sf6!NL}_z{pT2-3ZS9^DmQE2zaE~t%Y}%EuYjgWMLqh(Wrt4; zRi14bzmr3#zyk5FtQBBM+bX6 z_VsJOs3x!(t*tuAyqHDHnhPe?W zh(J*I9S8zfUfE)ngc}EwGmc%mIC-qy zjX_E(UdkTrqQriOzdraSy@)yPb=D?eHfw=p9}9P0hiF+BupSA%$#~?5F@=~MJsMv& zHt|~(t?h%682<=0OEj%kI>mv$v%Rrl;y6&@tT%m$9DaU&Mb2Qe(Y|cjJ z$VL#&wv?}E`QB#u6WYiCqyzM$-+YHsm4(RXE#v zF&52b8utY}XGzOG)2BWVf?rAB2*S(P;E(|I==RleFjr8o0iBxVPKQZAJ}Os#1o<3J zyo$>v247>-x&3G5RDPSdRofWR(9&GR8^cbU~k8kmX3x6pF86d0wNr=dKkB)inl)JXuD3Io!yZTkpF4FV_m-A4Jahl z=1NL-n^*&}D*x`ZY(^}=?%?+cuM9>QOU$`r%n)KWbL>-I=CIwK^Ifc(xWNaav#N<spz-}+2% z3L>g=mPnQErDhK`zK^mXk-lTco=b~m`D%mKN zKpD^YB=%-Ie#aKksHtC-Z0$LV>9~B)S!9lm_uuRy+-uY+m zWA(jCMb7^vKx&IJ9`}E1z_H@w-iLaH{>dqL?j4e+k)<)VU#3OI1)4HoQOblw^*S(k zT9)9jAqpRKq`SOpF^IgUTafFJ(FM^+8IBA!S+R~#Y{5M1v7ZIW!{kI?I}mm&g3b8! z{!-LxMMw7~g!!igoF%aZE!7dw5f^k?at+46{EXh63sW{K(g&$#eNJ#WTd@mSPilvW zBjtz^`fR=kNbuFwR*ln)1q9c1SHn!?5bjhbb0`X`flvo^ELWgI{s$M|Q9&Jp;WN;B zA=%MS&BY`CHq0+!=mz}r1yGN92$3<-Wfda3`*xhOt>Z|lm@H2=O<$qAWyEP1q!8cR zQkTj;V(Sf>}+zfsP#=uuy^XN~jLjEuGAo`-ee+NvDNUVnGoL@vx&uAf^C?h|i zA9ybsXP+G)73lcd>Ep#xd26>@n<4YZ2VdMiAp6qkF;-qW&iX}r_GD$&j=qz*UVBX@ z!AC%R&V7>P5dS(g!al|dHNuC(22!>mf<|oaIo7je1dz_I+cL?k6;}ZFPK4uk;H4fG zKj98YuoiBGxZ_)Yz6L&it0NCqi4qr@^!D{VU>xDr{7l1Rsf0nHVFgUu-S+BWE4bu! zUCZhXeN0-Bp^XFjySb-o8hVQ(@zaV_Q^ z?y&04AQ`u$OlctLd|m7us%#1q{=z#9J=O(jM@@~5wdEM41k5Nlc@($g!b>o87$gLa zSbd=ZqtFGIY%@muVn>jz?8FS)`0 z8@6T;xqIbSl8ma(h92_CnwTh#ACaa2f%zs*YOErbbE4Bfi;8|BJ&8y1uzc1*Z$ukm zx2^>2KWYqThE3t>)PAg-Qz$NpmErI%y^G5iwZ_XofYs+W=-lkE;Y!TeXLM5$9Xf`g-uxl3% zO{EQIf1>EaDb?Vj<4NyaKK={N&0(nh?xf0OH0sPYP~%H<@#JkpQ=Ds($ZG=+b6T6zTn{&iDt?42#_nUFslYm` z&k~MCaZcN1b`TGu#0Wi3l<<`px^l%3?8T)*_dNaSC|^K)eh`TU5I0z7CRwPxNXq=t zr{Z1i-kDLn#JFK`+2_*FV;7V5gOhuzux+D+4jED0kSvcyu8O|P3@;zUwg~*;@woY+ zdgqaAk=RIX0$Fc9;aRgPsj98V9_*>!exxES{w3A61DpKQA(~C`8H_F|GQ0t`_MAlTpzB0 zTvQ!U5I6R32Ki%`bL-{CD$OX_$}q{EW|yrfFZ6^D=bh4}hVrD)IKH)``6%pqlx`R{ z&$4IxYwIaUZHTVO&yhgtZH4>Tvon%z!uWxLSE?6laIExmb(?+v^#6;{FS^7`j@}}1*;rD>x>;Q1B-+33A8Lf)4H-RnCu8AFDs3L z!{VpvQ5CfG5j9pCJw;0aUm=-I%IIRz@cmVLXdZ#1Q?;)Q{V9NeR4-}M8Lm-E_xO@KY z{^&QnJ7ifeqt7o~)|VwznZP`Qmy-V}l~kMZn5{d?*_Z9HnZ6BrhXY_Ld3`jZfD;)6rKLPXa4=BoyHM zLb}G>m*jW<{g25x{H7yR9PnbB4V?<`z51_RJt<_o_*Ipy->uO4uFZK}06J64+4AZZ z0d$H{&vbxd3eHopb$`O2?=!|-My6zR$ajxA?w=VLP0q(y3mVsG9y)YpdT32r8&sx{ z*C-!3cROd5CjleN#4Ay7=BLHUQI1+rj}>uq0PB zJ9-ln5?Jx7%K(-Y-N(dZjT4krjb-fKJhR1ZzUBhXw{gP6LDnyD$#L1@UgzbE!RQQTN zo_cbf2H*ajSz6;I86Iqcc@@VRIT+}MkPxv7U0v0r$|HOH_FbAY#&^KZJrI(nNz%NT z@~&U}&oF3(IGExd+kX1JyhAFQMIR01u;l}6TO?zvA8Ga$G&35q<-AT3skA@G(k3`+ z`MBiXj23BQHo+^1xbGWuOMiJU>_|$Z5{$XnCCn` zj(aI26om_nj#}VPXv1VY3$sUz{-e&7ZHamHE3b}iTU}9NwD8aRIWGWqjnsT;7H6tJ zuh+Eaa~8LTyUr?qQMpJtT|jn--H;U`UR(iS1OXK<sX{&7)SRKGpw;d&c;x|c+}CX zYFzfQ5q=&@#7lI^Q;vdz8$Lh33<1BF)Nd_7is+0I>hGWkS(cENFgqu{LjivjJry5? zdi}B^`;uK{a#}mDu}&&RX2m+n>*5^p&B5sL{Rm3|HN}kds2!i0R|-Ms(%U-r{y)_f z465tB-cKM8=nm$Ic81sMV7yO}NTaqSoS-oU1FmMcIDjeBcg#77Hi&fbaiFSwn$D1f7T&{HeH* zgh;qfw!Fq5hx<@b}H1(pnNAA z@cc0IDP6993aa~HPE?Xgufbe)n+7BfbEMTC9N+0V0q(zW#v*Kt!$a95onVs2V2qlt zrSTxvSlDd3b@|)=I6xY*1l)`xa$>c?HW{pqFTRbQ(4g9={8`S-A%J(asJFG6ta5jv zOZG~j^7pexaILfZ5)**e6P+2u6<@imUk$Coi_RLr$L$oYh;oTf=Yg7!Y4{hZBYiXp zpskW`#PT7O)`siLgeGTD+kRUN^$<>S{1H1~fXfMtCnwrWA!pJ{NR{M3>C@ml(ukHK zVcM+!>!`@vZ4`u%CP4QaMW=})U~1AAPOs_A7t(sif90T=zvRu&dABa@l4w^4l^vab z-RG3BRU>G5G|EKjc{_!k)s-)}MeC$obn>~7;d$B;RzFt^JvH*u}@+~OBbcVa@Fur9V{r|>4=7d%pesMwy zMz`S&59y^LIYPz$^eMm`O&jX?nHk6YCf74EcTE(w zi{8o)u-*T6RZszePDB^0H@!!?CL(?2T1>QRDUW?384tz6BG^ZrmjA<@)5hagE5bP! zP@A>^ahs2MpsLYQ@fY6j56LJ-Yqqld5;+D)XR=Hb4d+a~utjhT%j={?A8*Hd%HUmO zX4kjTLbl&ka~7vA5#VL{hun=F^O(Pbz>iL6Ixdy9lXdOhbQAh8gX&p;0Lb^IWb_Kr z6bPG^*t7)a3}UhQV#_t*wtz8CZw}Y`B$EjN3yTS%)IR)x5xQ+1bj+`lZYIyGr)9TP z2ldj&SQNL_D0b6saL%6nJ|Si?y%tTXGZ~>+1}eb|=nBW(`66`fQ~$OLd`1_=T+#)QrextxO8PKh^2r}!Zzwj= z18rjHMYYryM1?_mq-nBHz3pIf-lFAg+A`sN2m~>plD&dj0?37?G6i75d_T0Ldj$Z) zoDX%5q19-a+g{sz>19=t<0(2Ura!Plu1xq=!;Bo+7~KO})9|X@k>j+ZQ|YYtT?B?) zvDSH2$C)4hzKzTAN{7LXR7jF_pVq?E zTcKB(sYG}{UbCX3-j4L*{1Zaw!-VrZ2D>pDFH>K-UdJA_E|K5nc0!CsC`WG>z3!-~ znj_!{^CUT1>rKQ+9$upRQ{Ir&*4j=zuW_O0-?f~5UObYe`k(sFpm6_$KEp%|!&bU) zik)8mF$ROqB2Ui4P})}#-YeeT22c-YT;~nRHsv(1_OrGEy966#P>J1N_ZstV4U_rd zXjLm_7YnL&ABBC1$`byG3?T+uke1RYt9)?sv*gOL`7jB7v=4yLo-hnv!h%*JXLk}_ z8h5b0ecvu(Swy|a4h?w~l({iJE!}b!d^NM=`X`_9B*64oFeaAb?`(J)y^f-4TH~ic ztvk}!D@{-xk0)mvjDcpGiDZ}kcX|`X)RJL;C|GZbh_1H+QaK&Y%rj@li$^iAqZ?hI z^xT=0b7t7kzW>z&*Pca;O9Y~Py*8#3s-dRf|)38p6H0jFUx~?h!@dv2WcE# zeOn}NKCRgm%GGBFhfJ>GiCZHqm$K1gK2Uy?E>WE}$;dYUIBQ zKAm!;U1FU2R!_`EKE@S+0rDs#lc|L%dWtsB=t zL9eZ9-lLg3d)kA=)Y8W76|gOPUi*A1b3KRL3souCP`x{Tiu~88hFv;Bp2KQ0-gy<` zayz?avum?tP6tCh;#YYD{Eq`br02ZZC02M z%wkP|@Xg|gP^wLatR_$a%L`OV+ZmH;;}5y_trH4&*P~rU-c|1kyP*KpZE4t-+%f;` zxL5imu+b}{Xc#zgYNp3EglxRtLsEj(!1{~ukcsc{J+kJ2_7w2Y`>s6kqUrmWPF^iH z)O#Ery4pY|(k*qHtHh=fyS-V#PRKCkUd4H`vIrdZ&Unx;T*0NND^^I2x5$5vwP*Vw z{}R+yWk2nz8-$9II{*#MKujj|L92wfMyAisycHEBWD&(;-3vAzj~r zT+nB>)LRgPyI=NGRs7M{bi~7Y`qK*Wl}ek}?)OltW*`TpB8OY-OXySMc3dTuvCkS} z3nvY?DfLxo;D#3eDXCf=`?XvZfM8N$dcZ~5eggxMBYtt!J^ivvBT53EZOMRD^s!Iq zH8_lNgy`nK7vWP@!-{t>yiBg6OUNosGOCKzN6}#@K>=cE>@5+C8&WOI9JMb-$Ir3W9-+ zMbnL;KhtawIW!1_n_&Aj=rExac9o*C{M9YKnchFy6s>s7y_Ej%%I%$6 zFJ(GwQkz}=w^A!9N~US?*_K_Fc5hw{s_QWoM2cVh^ zPW#qFNe((M#x~a(!7D+3?09rW=8znPEr281T~~>t6Lv#DfW)p9E_+-^rk8Q*Nl#rS zO)_p$a5+EX!PPwyC)hLlJ7Xr7G(ajquZn++glvcTO$;r4sdsvgXP7crV zC&CWF2S_rKy#}3wZO*JF*dN6G%>7h7q`&J}9=Zt@4g^CZuP1C-FlMvq6FKqld-kR3 zV-wQM84RCrL{raWMk?Z8Jkym8p1)B-xj40Y{4;3?Bga~f2Men?^x$t8Y;r}1#2&W#UxdrDTh=6ig=w^r zL7=^tle7cHY1BSz9Gj}6n?6=N%_|QOCdBR=v~B7z)~G1Q9h`eHs7$qkKdiN?1>qgG z4F0jmo6GOabpJX76CM}66F-F-1&sx9DIX^T=kuqmNX7TWOPTEpYGVn85NG*Y`eLKqVf6b-jV2kSsGefvo)I(O>Fcalt%CtV&U5 zIFWy^FZa7Tf?F9@MGz;IxJdxXr@k0o2oA1aKcRpOzqFx$*;cIVLC&)_QjHQX)0`o_i%?^#%d;dyT=X+<)z8U0E z#QMwB*Ukkq?YPKqN zmz}MO!^*rvmG~t^c**UuI!=d zC~E02$Rjnr>cmIFvx`re>oy`=uRfps&w2fR;M>Q0oVopZtb+~A;8aVzPhCBt!lzF0 zew_1}pJmY}6d;&!59{7wY&muVl!#mO-L@R>_&Sd!T_=s2K(0Bz^e}Q(liBA1BizTO zEFu~IZ?7QK7)YB4Q+IMr{lS!uL0QY9Y17xHnOnDnV(Z{LC=MEmGOwStgH=+GKPgl+ zvC+C!HLaEpY&&x10BVkUZ{jO~SVzp}kvSAXt^i7B0bVOw2#g8JA7VxU@=dbQ0++^L z#EU6zR4J(4wBRzK&iwdci>?NV759DkVl#Zr&W?s z$w-)e%gx5ww(7+;a%r8M1KRE+yd$r(>96V%!Y_)gzsR1&z`jQi_|@?Ar)ycUF`2nW zAd;m^jx=rD!Y?BXu9rq`+hhr{BPWcnR?1lMjtUhF10%s!?8zLeC>*8KXcj!(*YPsrhNU+)9UC)*~0pk-i!a%-FmM8-;ac<>lAyreOCfI7+eJrD!b=6=;h0R6FwR z40c=)v|c|Mz%y7@j1DnoU6J58#H}F<(Mlb3t66o&B|KqO^`7|LuwBG#zREL#A}ko? zrR*tw+&IRJGn}fZil$PliDy@)zHrpi=Nv(o{4;(w?n^Ge8S zJyLIugwsf2?KJFnR(yt$%)Hy#|0E6%m2%%hM{-k#eB~k;J;d{K8VgnrS5k4Tim1DF znaORt5ZFE;PtI@9SIsn3#?Cap3I#eab}=bNe?7S0x@Mj!aVzF+`Ti1Ywb(tkT?eGIIjxMO;lUq!moYd< zP%j2)xQrL4GKu>$RyklWlyeDxR-P(gNSFK!Q-QwAZ{m1rq z!^K;fvNqxC;&wFXU_$TqGI~Z0US;*G@YSMEvOOJ1gx!SNZCy6-(`ON(_O+{iM#a4l zoDhoQGVu82W@(nz;Cf=_>HVB(R&tUAhpsrcVm~qp`Jm3J#9Rvpb2OxBArt5dzvsi=wcXK$OApiz^3kH>GNY$Ei2;Yh7*zg|aN3`Z%UBUb8nuY*d z)YjZ)%C`&U<-lt^|sF1M*brlFQ4n?JLn?7 z*}bdrYlKhNzh#A6CtU`Sb(q(rX6~UnX}puI0L}KiLQZ(bGgnDLLA&QIGA#s25EluK zB>1q>7M==4l)Ut6-3abar@n}=T><0-QB9p9sz3#Ekss(cHfR(XP%E)pquB;RLv`rY zPs)BDc@M^ZRJTVXJyXfl(}e7Xl)lu0X=ms6GM3L(qXZmuXZ>=lr7$=!{75#hOC?*9 zp3t5boaM8Y=>s?5?T$=4Xb^roXy*r7J&5@|z`0lq5yPG^id{Eo&-&h$21C=({POYr zTHvOsjQ*j^`HCG;=~Lrj=(f7jx6X_-WXLVn<%SCJcgWYVNMe7mSP-&5erkt-ETEt6 zc0;5J%?u@Xz>8ZhxEztVDe-x;uQ0u4y51XUe5}BHvglB0iqq&KrqOhqz25W3M45j zxbNFDLE}1ok5i?u$5(T7$mYNO1HfnuuFO(*=Dw`0C zeW_fsFf19R)H>liG;-@8-{Kv9_Cz@E%G~Ed$j|~$K${7MGMS9IjVhrfWZz2oPV9Gl zDk-EY{LZd-ymBLHO&>A<+Xn!Tx8*reLW zhnhlo-YM)+Px1vBC692RdQoENx;Ec1*BsdDbm?Yc;V!nptIf3R8C^l9+2oUY1Avdh zxsc5-mQ!t-g+~Lq+i}q2FAQ-8kHKS?h@+iar3v-}oT84J$mv)_tdq2k4@l(7;bB)f z!3!d#(}1&pgPt*mYUHD={+tRRw>B^bMf&uk zoFmHnqj(|>GIpboD@(`~y4U_!I|Dz@uGgh&_j@+D0VXg-d2rYTz&i(S|52NgNl4+| zMx%qD@=nfb+|%qjlv@7Hb_lU64MRmRGKAIrUf|I&CG9w|QF+s9QgpKicYp`3*Ki%O zGX(c9)P}BIxWK}aK_=ZK^G=~4rCz*9VJry+v-!;4E0FDqya89X)112#oqpwhl%@lRDKL#7PM)YiQ=ODpE$Wk zGaoY~gS&w=z-KsRuIq*-)k zl`8cDOo}jx$zA?&Yx6`7A}%8dLHc2+XncJ*Ef~Yw2J8*R>EN0qC37!W#aj)8vbir* z5NQ2~7Rq_DEpI52Wb`%gaT@9V*tpM%W}I6`2{2g4X~TwOZ}%H;FJV%jwBbe8W*y(D zA@%{T_lppces?PJ#p-MWe`CAbjC-Zh0hpCl`V&&JQPdY9(sszt%%5))*>fGfTxnJ} z#B0if<9KW2^skJ+$~!CVJI6=l^9MwwT6PI1!y@uyV@Nk7sjoSeFiCYupU36?7~L3Z z!DKq~_@aSxAV(untgNnErj|ytBubT(teQ84o&I_mhpw=t{b#kl&Kut%`+AmJIJY&% z4Ci3@M%T+mv!?Qyy9-KusW1>oerJ%~!jjW2#3Y?&I0uL_rDe(vpFW`kqVxF13%DCe z^IF4xte$NispwSIl!j0@KK62X_3S9VOV>k5i61>D^JeGG3v9271C?!wB{7aJ7YpX| z*(TbMYJg2Xp+<6wo+kC+1Lgp~KQbJcq-6O&IKsQJ9PD6J@6U&@R_kEl(^%4o1-T@4 zqB#cpn)#J-FYa`DcY7)RE}X%q0HD)sUm4d>pXGG2sS$8{tXn2v#--8tI=pgTLRhY0 zvJ7_NbV%kJcM5sVnbpia6vdhqxDd8>0as+2{i3Uq@u96a2PmFChP(kvAp|Dpb?7ip z)96>WB$8}~02#&*%$Jk>E&(6~q@4!Hy4jM*R7ok|s8NqDiuPJnnp6O83h>M9)VVow zVck5Y8c%Z)I6@d4p~bKT?Lp3#`M|f;wUMvp&X509K7aPeBoEq7T9vY16Jap*n?`w8 z8XVipgLwVan9Z-a59c5FgB|UYKz26Kt zFOPHcSZ@SDyU|U%iLDl=J6p6?uY};FoM>o$n?5WN$_kql?0=SuO{Dc*?X>tCHCCiQ zG}JYtc-eA211jV^rH*jc=SbUkaB%IPh?GcImSPYLjR#7x^F82fI3|l@<|)87jCe%; z@W&tn3pa&ahVWVeJ-fq};%0K|D*;Ua%4VT;ZPAlQs)59rk5a_F!yBWq%~5biQEMF` z?vSJrfPx(~z^H>Jn@>(Jg}>Y1d@^!S^Y)-HP)i+SnksZ~okt#5rRk#ur=+12suv;I z)0-sTBmA-r1$_I$0`1c$&okYw|AN*ZxhESP>L-CkpiPpGtx%xo!gf)Q}(jUp7 z*YXs1Jdnx&H8n_=0X0tl2!knjqZkEVvbPR-ryOS|4C~_ZRp^mS+@PaEe#^`g77j-c zC@4%7KQ{TfNnMnSkOnGlkXSM9O(^MJA);Y--veg98-jlz1|M+ym${>}>%wF-^n-dn zw-0=rf4u^Ji_97?mcm#yRUs7h&VeCyr1KY+qb1ZuCma_dTJY7Zbw`GTdE#q87v+P5 z04$*aD&aCMXT+X3i!w(yi>%?eR6!0OjF7QPy_u^&!7Do_=#DudxZGq=P%I0veMACT zsPDnDLVn_r_Sj$=G>y`nvtOV*9`a)B3i+$$`e4ah(O;LJ;4kxS!@SWWBH%@s#Yr)2 z@{Dc7XgNV%BDi22=VNu=jDJ)*tTmg4yx;|=@rzH1#fI|p%1nVet`ZU8Fufi*b{G+{%|&$(rY)TK*Ms{*lt<^VZnT@a|EiJ1=gx6q%qhD9uzV3vEpR$Sev7v!hRy+r z!iW7TyPyIyfCgBK9Bk|N?zGD+2?I2IK*5NVlii+5?cz~m-0cWM+FkxlN_vPHunyvQ zFl`X})1#55s<8~Wk7`hhxp*^hRSnj>)t!VJ%dPp6BMpY)D=Kc$VJW za10SoT>ca*WVu{kD%iKhi1YoYZJKIE*$M1i5geIkDvv3mu1PeifYoKH{Zma$10@- z`-6KNtVXDQ_CTcf8QF~a;B8yG2+)DPWF?|+Mi(8DUjlHM>p%BkXj>Eg z!^Xw>FtF(G=Do`>d4_)4)_PTPNMm2B=AKM!fl!P+X$oQ5$Tv?=rr36*{ zKBkBfPX1pb3HI(KpQU}5`wv4{K>kYNQ{twfd^epDA#0H9Cn0ycxm_^0xu$jV+IaA$ z#CX>lhUa!v2!i@il9ZCtPV|!G_NR~Vh{Q6L=kzd*Y&L{*npv|UOEN)>`aVqY9--#x z>f#qUO`zE6clbvUy>r&j*nG+Y404imlKrFveDwfu*n*#+EL+c$K3H~o6_$0&YUVi1 zc}T&xGWP~6`1kVNXZl$nHrGa3z@U<_^#(ZuJbV`K&1sW;te(5HT-OtLLXf7mPgb=7 zm28dGu5~zu8yKqBU7_|t+Ma#7*0z~YE1lVmnXR&N-H+&k2Ew=%700kXm2w2_KR48M z($<95-=`(T6AD^jBkZ%2P5!_~H5{EC*UI1jc&`~v+@$Tj+Y+voSLqIqF;Y4CT0`MC|J+LE29O`5(SS_$D zOTHr)x$#k3F5hG0YeL~&(!njEk*l|$v5m6UVuZ;akVzz~{MstnH_=mb4fbat@v-t$ zepXD2JPCf_EF@D+W1v*8^LiRrAH(?dotC~#`0{8=XsoA``-a%v-^2w80D=s}%Fq9H zL;B-KOnfO61#9Oj1e^cbGcSMts}82o2l~7Yp3ZrLR$#3ErD(U>BOW8&k7r(^qzeyO z`^?x+HbD=;rLY<>;b8c*cECaQT9;hX#f2H~3PAQtE9TFkM2n2A1Km+kb%TyL zCiLB2R`&xj!IR+WSDb72Gjl2+E!L!CBsn<3rWQSrZjA0TjUlrmnTM>%tFxT+Tn_n^ zYse^f?o>Kl3F28f+}PI@f6T-Bp?2Jo767QNbp}wUxve)25MS> zu$Nvwao1&njV_E%$ zD!@RX&k`1X6=d%I+#}&j1@pV{J8IL!Idwji697BDk8dPtuP4X6Ic9Y%ByiTg*LdwD^__ zzSec*-ZygizV`T@UJO15bS@@!eEarc1(y=0Mg!{PP5%>!`v=IFQXe{ve39juVVIx5#a@eMhE@EkQ$fx_yvgLQ`Ph?lx^B=7pW{U@iI0qU7<=0!jAq(3Wj zA1AMQ-X+yIef+;%<+oL_kHkD+Mdt|?06 zQSjXbH6%zbaPdm#v%*ATGy3d7vBlF*0tb=+{w!TLn zY;|pRXe)VnA^ZS{&w!)AS1T~H#z1f}Z;7?3Ixw0>`JO}wke5N*L~7SoPk|05(UsH+ z6xPZbj~5@=8c}GsWmkY=6h)J$pT1`dRMSZ#4ss2Z#?FfUXa92Lhg(daS9Vw$_*}8b zereEFmi@KMfT^@L%Xdj~PGtx);ngBXJjT%<1)ON^_A){alUOb>*7P15EcOhBn>cds zHB;-J*kC-#hz8Swn*Bznz2S+Q+ibFrsJs9sO0Tt7gfJf>tt@C|JDj0DH*`BX{RJ6I z|Dh7=7-#ufslkOc@N6E=P(8I`w=*%UkgEugi<^({7ACN>pyKrK5UDhc9G~LG-(!OI zRg@~vaF8VCQBtV=V6pTq&|r7t1i6;U`BdHSoJc&LBY;yw%$h$qV6r*cyPR^TU?8Q9 z^K_D3qs<5i@5b;#JZ%CETSZ#?jBA=tfVd^2-VqfqTZ=mmv+FlO5SwO5euIs@y7I>;F(!L?1{i#sEyz5lfpyFXM*~@=svB}eTnYSFAe1Y&PnvX1|M{OidQUx! zy92Ms-t*%hKB)o(^>^%2rmYgvqy{!lV=BFCkzX7~MHeE`29mTl+kOabksC&}+LANW zEs#WEN?Q26M4xgu$Cx!V=kZa_&x3$$?Wa=P()(Gp8wUeRF2&JcZif$yMxIq%TBxBP z?T0lCvi;!*u_A0FKa|**R67}u`WSrMbhK~-wfH&!fC@MCa!Hh(rG~(+*4oh#AtVTQ zej@AG_)*i6o*La;!Jl^qB+5iyX1S78e}X9sppndsJ4Y( z`JQK@1zSH&Mx(0ksPdLj@Hu$O+ikv`0sU_Se0t^Yu)KN{ywa!;+wC#I)m+foqlT+n z_@v2w#TO)9GA+BgEpXTUq!LkkuFH1i5$-G>JGMZ=Ge^xrOcVHy_12_p$ylq`RQD@?ob#f`>Fl_407<*`j| zJ5&5YfY3^#gUG3EwL$Rs_$kXGKdedX@!PYjJpXLd7!^kqV$oue6V+~Ow3rJ?^Y3I6T(Z>!v%8sfPdF7qf&U`8NTTgOuBvy$^cD3N6nYhNYK@_k{dLrb+(eZ8kk+_r5%fV-2qHMP67T>=zbkgj@tUW?n$Sztw~~H^dmjDPI{B)S%q=Z?wK?i&Am_mplFXn0D1O0zFq^twDDp( zj{R&YewPrxCxr;?uqnUlGz7{E*r2*^biu%9*h|kR~-yuT{OOz+@G6R{<(5v$mmc6U1ox@=|BNPsv&b;jJ{XdOJgh9F&ZyP4_guNwA zfu*amt;8HL5Y0aRuz+O@kZwu4!dM&lJ8{4k7>XS!R|=3Oycw0+I*NncIzUvG;uAFP zZQ9W_$c9?`TMiikdq54%(~~XX3lN_0!E(7o0Ud&y zMrjGKmJZcjsAPd6uk8Xcm~8s3(=?M`k`{$}6B8qoHeOl8$d-6)tr{;T-CEu1U4ih8 z_2*|s-NHdcz0e9@iSYKxKi4Q!z~`Yafmp+N;u7;-eO;k!g4`~3ijfq?ZI`UC)d{yk zD^V?I=CmmQk7ZAEUC$w4{=^sFZbI49?jfya@34E(XW`yyH_ValVm7ipJ6pl{+6>Cc zt}@TOaTr)1S*k?j5X{#oqtLXZa>#~eLnkzB(02L@WdfIGR~*J19(?*;TC)36S)X)e zSx58Re)~IvPYt@$ia`8{l`Rb?Jz_YqRe`H>*dj^VpoCdS`D$Fq{?)RCoDjyHVYrA0-9Gc>(ryO^Ob z8oA_5te0aGCGC-z+B@7D)h(G73ScC_-Ps%|`x~6NsD+=U)8=c#rOz}Hy9*W;DB=v+ zD28dPf<~F1!aL%lT|c&kkll8VzF601mGca`&(5AjkK+(_ZOp;%UxFA8N`kx-iWwMp zYxBxub(In`)=<~K?<^PDKOB(b#F&XwRd3sCVa4qhIA*MfK_aps#VgT||Ev5F4!F>! zdub+BD(=Qu;YP2;%G_3pXDaZ(eQSSI*PA|sMAFF&HMHt{S8J;FjChSf`l#^5@bZLX zNN)A;sM!Vb)4`LadBQPs-BrruGz97?sc5hN%_rkUSBPG_$;ery$%)UhnEGVaRK{1wWig?@J%NZeRyp)t5*eTl{#D zm^iDEcork`fn{|MpAs|~fe5&@&=epfXA$e*@cwypMKrJE0 zWV2L5W#BpVqT~(4i=>3A(KK$k3p6&hXw~Z^2~%aL)k?0sa#lfV_Z>HO$s-{*aOE0Y zUegAf&9;n|=HsqC@04R};5Dd8Hnv{9`<7JKV|q5XGw+jT<*tXf(qBl8q(X9aq7Fx= zC3|tQmpDl=q3YS$6&7G{+?(JyB1Jxe+q9T;kI|-`!Hayvgw|cd&4^abnGbz~gAstC zmVu~b3bP4!OvkNpk>Rp%k9 zKawYsS2Yte2o@}QGM@42I(<^cms(Uk)#G&P=RqKaxRE{F5Z{>B;M2ll5&vtlMciNO=)Nkg+8ZjSmxhQ2_*q}tA6lWX zyu5vJ8l!Wn?lKqD@)%xYPEQ5|@E~XlOONYaaKh-sZb{^9IUHRXh~&FRN>duD_KI{ZvDy2*kK*Jw&@_o@0*cK51c{Uy_T*k!H~gv{-_&lr}%( zUOV*@`SF`O*X0Z~n@JQ!Btn4$u+gU&H2>Gx(T*xDriWN=8@7O5Pl(umVidjwd@{sJuOwB5;Qz0TOWS=3 zAhUc)Y$@{=d^h5Y(R8=e{3|y4rhRdJY`46G7n1Ug^OlY_TEme(io%P zo_D%6b3cu5?%dMB?<_;e>dldEB91$``hiLP<1Z|i-?}+tOqc^WNf@_0h^)?Y z#oizd$7mq}ir?|}LGkIyfvEBR%JRZ-OyKBCTkH;A!E@#9VHN7L4E{P|>35Kl37#z_tqBogUQqiPS zgiTjb=y=~H>0XKD==6D*VaeEvK#Cw;fweG0HCi~0YKVL+Iw%8oW47F^BZGB00nRlR zL0f6tBddrdfsH}i#8<DO{OHV1r0h|{DcLb-gOH` z9B(%lVeY3+nF}s?rt*tx%!8i-yrJT+1S;FqUkZa#lF;Cf@juu;4g($P>mhNy@lv_) z&BBtQ#_be+^waKuP*YXU_wzIoYhnKaxzKUfLsDx=|2}80XQ*QEM|LQF-VwhR&>P9i z>#?eGRB#X&Clw^AXEY;kfe4!1IAsT~`LR8;Fk-WkGf9Y)49{Qt0 z+%)FlM+gOs@s;nS)3`u6&pDZ^k%Ez^BQ9>lGWoL9ko|$4R;&HbK#`e~0Ti4YJU(ma z4r)s7`d;YOwkEG6=ydL`2hY(&cLkr*5X+6Z!s^lL)w-Pe?$x2*=a8D=cIV~E1P_;7 zAf!dx;lE{%hZUe}fSYl{rFRBk9#8e)a@jYd9kPdj*G02{sAgq!HiNhav+d}yj&VdQ z*WiN3Z->E(=r33^t3!T3BgbmkfXp6fW%SxC)vitqnN&SU=@Z%!3i`1x<_ZOLij#Ou zo@Bkj91&lrTm*u7myx#?(jk%Kxf3YSjV&@0cHdMT*Lt0wY-iyeq_^?(=u(Z=JiVcD;b8t*&_Y=RCfj!Lg7qv zV9ulf(yIfx>DVstBKw}1@^AUg>Oe57Uivp?qEAMVmxmw&E?2uFh-K2D$p>|lo-m=WyYTRL1WG?+iJJq*V~HSDzLk^NtTz1J zRH<6ZNtLQAbl7U>V|{bWv;57MDrWw(7bgYSP6%^8qR!ZP;WXY}p@AE#8gOz)_a%cv zMF#y=4j%Y$ND?QNY1$pw|CzOY_e_?%r8ZuTy4m@EYamx1I{dYRbK{{kNiJf$aIoz$ zN(YO;DQW7xG#Q^1oo1C2l+@t-EOS>2R+-W9`t?J$N~7ff02dPx&SYtge!TNQow z`JME(Y=JNV8!%@J%)G@~pt}j{JB>1V*YX3NmMko5tyCS?uQzH#IBxdha{7{?@OfKap!GDY2c@wx4JgNHK1Q& zOox$FJ=zxmyETXTSq{TrZ>yAIRc1?8c!SI&1vP?kTsE+_j-_|S6Fom7_Cu%m2}B{2 zs4$-b2Ix~+ST|=iZb#gr=CGqhOuUN698tjR!buU5)LH}jB7WVsu5s5N{F#0T_)J$7 zh6zL@K~ZW~_sw<-X!nXM8a>enb?cKmCBSAB7a=ktfdc}`z&>j6deQp4AdNs!; z-pr~femt<7G`Ojdj>y`=Ff;DHzEB(=fL$4OHn~W25ehV0XxHh$n{fB4Z8ed|{2#+S zp_sLM9J_LZPISWp^C57OYmQ?XR>!5IFFOq17%T7yLlbX$&Ut%0ztu&@%~3$H?}ub(Uxp5;q)AUmoI=rO@^d8!^os$ z*8xO%woJv>BQpt#>3uSViK#1928goP;#twBLE?88u|AnKi|-BhWls6FyX|ip*^p=< zN`Zk3p4Q@f38Ov}1SWz9vtrbJQTi2<#BUffmj@sJxw>$Cuv7;2u%`~e@Zps$walA- z(IB*zSM_?O&%K+qi&Z-~P&tuhp$nq_7X*W!Lg-ZTdk4st2kk&Dzew^Q&y4gMM5*JQ zPCGv`mh7GmI=YSx{txFk&e|ezsD+91jMz}_A$kg^&WiBX-E3ty+hm`icHI~uspNMg z0P#L?E8JP6Z0}M8^&m({bgV6PN?9xhz%P}6=PEVTz3jM$VHAs0yO-tQK@!Itpu&5V zZo=NXLnLMrQ>MXJn3X|^QJ_Xd>1n;Cj!qbqFrkM_BkE}hc1*-*4E=#(pu(tK_bC@O zYW9Gszo7j@7Otz8>F(g(JsuIawq2%F@=pP*E|&F!2*uXuh`mE0a6scB%i@gc;U6zl zJ3^Q~baD!@t_!cZm!>%L6Mq9>U{xlmWBCq;z#5B(^9238i1A<#n|SS9O~n(<8V1(c z#AXNQn}JW&>|BfZH>5Dn#B!(cb^GO)m;6=cOT8t?6jEbUsY{|V0HFw;l@{854#B+} ztt#OqJuT;Nu^*zznLeaJx`bLtptfPA1jbg1`~2|`+OCY0ObuvM2QY@6>iEu!kFg5c z3XdCdiygYYur0`XJf=5iq%#b=Y_l}LagFrtm-b{4a4%x}cH1tyae2kowqie4L(+8P zp^j@5cXtWRxeCRhzPZ;)CWtRqT(@aoJR`8hjYyk~xr+=U7)TWH4S-ifP#!jNr2ZSY zd5%`w#Fx2`5;6)s1avfpotRJ3+ONY`FxAQU#Pj#b!9Bslx#^H#o+z3Ew#IYQN_yQhGR8^(&5 zZ+5M`6@%)4P&oM-$UPrGGK)sRtp#po6}_%wC9i;duna5Pq6*`Bjfo(5A&WZ zr}4#KSp6A*gxG{Og>JpgCf6XZ(%zn_ju;*yRX|5V{GBx^A&^ZwI|SH@I#^ChB_&T^ zlFZl2mpxQgtrbDRZKwEB&^<-X@<^js!jHzTQ80P*vTzNmj`N~51za5^!xf=P*?fPQ zKP3ybL)}q2o*0?89?L5^grCcl5s)@GAfFuTM%Knm~ZS&Hx|yQ3otQ!xzJ zg?AKW5xOn-aEYLy!n{5Uk_yCQ%jCjW<7>?=uao4{3V4WJ#NvAiyBkY}oq2~5rEi6y z)~RR;^ewHL`lMKLh&@(r0NP$Mmpvm_AdQluL2+Zz_VG-7f5*FFV=}Zv1oa+hA`O1` z!=<3<*)4ZMt&cg_8C#5)ibe*NLus`iItyVE2@F$+PQ9fipJLJUxExI@f1NvJ>ndh1 z^^dQp3Z#n$EQC79f6C^j+z5& z*|$$jc_)ktF+;m>$dIh}e@w4<0j?TvPG22z+@uBqZ^(QNfcBjTUFs8Y%2nv z1=XtKn}V)T8iOeGlD1n)s$h`!OH1gaPdq+UMj!C)oI&?eRB=%S2m3nNYG}rk5uw$(G?wwt`I(afTQf4Swy1 z{8lLM^oHT?5i&5Mnu%H@NG|X%&6Y|hKx}1PHR$mKh*cfx5Mb<$={NQp=tEm+Se6mF zj_Zr%uuWnjaZ(@ozW&MnwWVHU&uP!yA*J&FUJ=2Olv$@ur-J@PA3Y0>ghsa&f$DZE zL?#-vc#xS3bzuWYQh|MdX2EHtX{2_X>Y%}#MH%Brr=Bccmna2lgB3ZwQ^pLsEz_}2 z!y}H3{V42FjeZ*c=fA^NiE!b*X0Op?eNU+ZMuIw())^&KtYN|%g`xgjwU%^px?65I zk6pgVmoVCQ=Bw~`lpi>jUF*JYAvxCK<4&UT%D*W$4hpfJu5F9Dm3)y6Hgz21mpsWwz%Tt6c3On zt5KF3SOF73+lEAlsyZGOZ>NjkO342X8IBo8KkRWwTNhCDIei^ze60f0V@a8A z9<*XNfm@20^RZ0A%B4;w1XSwDPVpKz=19uO-1jqH(VBdl(c_$Mj?v}IdpP%0J*_9 z_Rl6fh$VY~g;rscK!Jk<)KM3@TrysTDGYS=?Lo#c>Wn{-=C`&=_SACnx@zaBAK}rf zW}boXB4d*sJUW0aC?jlw((#KqhJvb!U(vV3{9~JjN2K77&NMKjk{n9_{0O(jCpZ_$ zV=kA=96Un_f8=WG#|?u4cgp5$Df3P#bfe-K)xGee&o2kG_ymoc}HK@bf4l@{7!pVEh+*E?E49 z`%V45bfn4S-GQa5fXyEvb5|~NLe-N9D?t=q>rAcQ@6KP`pZA$W-X@a1w#{pYq z2L!o+&17h6gDDmoc)-5DK8kX%WCR4B3G)IMwj{?nxiC=$j#=uO=M+mEG1u8*@~LNY z92s-El)v2zYxY95J``_te_4r0C^*acUn7XCEDL|au<(S&O8=>pZOU(12&4Tv%F? zKy==f)J1&Xr_$`u%iU8CEVcpP?t>3gxOL8mvHYL= zB%}hvq49`K>**FSG=as!iFJc4AT@E0><$LMEs)9(N zxm!?_TT=?J=r7dWP{nS1EnOB*=+Kw}WVQYl*ui4wRGpI_Qp*|TQK*m947yGwgZ=SH zZk_pnf_20q5t5+y-=_u%N7560LN~(dlZR)ke&3;MMzB_9TQ%i+MPqI*69cf=3zej0VZ=Ggj_}VQw z8;+6eJitkg*_8kIa_0@~irN^LN1+Lb^&--W}eUOk9u+yp3;+>$&drk!00AzH}|O$Mcoa6CdZxJJ4QDo zE&qquto)1k{7V^sC}k(u%(j$hKM0$S+rt969;04Xu(tVkxJAAfg!_(nz-lOUR&nQB zkFw^~dnhcfh?wf?a3mW%uOar8f^rp&_5rUCy_2m4&K$(@To?jo`SyaVmMoioDV#Y7 z31$5O(%=SWsT`aQ19Z2>2s>f#IJUFXZxJF7t?u`4IR8;&H*cPTI;|8kL-*&})t~(A zCdT4bWqezm0vSuScR=R*N`)l6}hSVFkWIGS%*BA~wnV>z!d``=xUN}11u&_HB70QIZb+I!> zIXjtug>`&MK!^v~#mrL!s;PZhZszdm5IK;YqUFBmqR>0ys~YIx5+IYS6pkZh&aVgh znUhm!!y&)4iFUVf77!o3yI0IY=C)=U7wY)QZpZKE9Q!Wd59Jym{ykv6!3wG=Sjb#E zYQgo|1W70p)4oJFKM6Ndt?*&aZKYBB$xn_X-JK9;Vo}-4n1TR5K)}D7C$=PyHFWD8 zIgdG=G`yvWS#SJ)ugJ)tYh&*H4bE`j+RFF~30f?ja5G|M;1l>59mI-vOa_BmcB#BP zcMvqOiQ2KiwsM*W*b|u>fy*O*Z>GW2pc;3UwXgS@qP&KMzYMsUv#%!klD_g~;e3z1 zXm9IX`Epbf)=b1tr6{q}gia=2%g@yf5q%b!2;bGozbrSx3$W7#-Q-eV=H)qBc)XMr z)9-?Qt~xM+pdAK;aK9C`fDx`+LINNfM5Y0>glup4135h5J>d--hCVM4$P)#LbUB2@ z)&{0Ptgsmw08a?!NzCCzFo6xwisDXv>s3{=!?)MbUTqOb*uXwJ?PCv6((N@RlzGPe z+NpZy>}eZa0r&3Wf0Rv#bo&xA=wD=>yu?I^sJH-zReWt7r>!?BDEX) zQlpP1vxs?s-6vKz%J55quhY;V|JFg;lnOy5hTBrlotc&4ue%H(5a<8jU)0++sx_5g8*sLb!=ztk{VfXu1*=Qj_X; z2E86LkQW#rM{i@XW;}YsiY`&97W`?@nsw*gy3$NKZO_|ojlm3*{=+?`+S`S*qxM(X zx(RNfUJSnoiSoi%7oKLckirJ$%Ublvr=6MshkSOKqMhu!)i$w~$=APzUtB1Caqf#i zk=8f9HV*CL_!$QFm`2E z49h~9{)+#v{C!fRliFJ~+4)s8C7b&j27sidCIS%qwcZ|1`lL&Xq_@$y0!bSG*`VRB zGT>0as=2k6>zjG3GmL7fD#q=6079Iag$Q0A?&aqCR;$}n5*}1zMb~}E%u#nt7 zes`6qa0oT!mqs!C)ZA9NIh}82=wCvAJU}9^$v-809af~nf24Oa+EbATi=1)B@cZ>z z)+U&W2d1a<>lq1xF2D3%dre2AE`xSQJs}*s6A%dcvG6f(TBSv=k=qAoVTT4>N0+jK zq}a~W>~^Jhb2UOCm{YRZK)~GW_G0_uEECBa> zsa52jn^WeXVc7VZ)W!mo__J6AKi}{A4bfG+-?-K-=Q&SQ`o~c*Zm{Zhk$hjn zFSGUb^e*ZouV8sb?)Q$hiirH}H^JI+CMBu6Re8;?y3_}{}-BH1~NvC>{yq6!>IEL*9}k?u1pctIgC*rA6J_`71> zR3edtwh+ieH~?lj8-CP~8fjNJGZ(WXCR5`Kk!vW2FfqqLu0xAw(2Rsrooozlo)cn2 z+#rcU(LX1B0j6qAoRQW|mfgCTh>UOH06{woO})Qoff?{%w!C0Q$(vXh^o;7~&gLZW5;6lT?EdQmCoTg zS~g<`5bl4nKd3_~p(#}Lm0wmLqlO2Ccmw_w$pEHuf8tBQW6+w%GXvkbYE-hs!aq#= ztb4RVW@(e0Y%SX>*aD?3>bbGx|{#0rISfdAqG<1i~>Y=N|dytNX*lWb) z!xLgpUGT!(i4h>h<`c?);hwW7=@FJJXTXWroD=qEgY7t-OXqN*33xRQrcGOmQft5RP`5DI|&vZ3n7r*6)3Q)u%!QSCP~ zk{LofA;@?$4s=$@Z_6WqAhFIh|KQ}Do(Wkgh%nf9M|IEIp?Nb)GG27&01$c|U=Bxn z(xHkM!NlwUj%{NL71J)V*FTpDUoq!x1#*BL&rK0~{lrB2*jMH@I5<7zTGVxtRb?{L zK0fBZ(O3V>y?b#};ns0?F3;=x^1p#B34<#uT1z-xN`_wkI7jmnJmTEx&!`;bIdm6U zfG9W5O3pL+a&mCx z->e^t144!z)y4 z9z*kiS`To$(3VOIXFCmw*A3D7R2a`zP(JSh?2Q7eQM=};EZNzC9Up5H40B$k$@uV99V_nC4?rr@G zDaJ*C=!IY1GsOPDOvM?uyKIA=1P4*;44swYES8Yh8z!-I$;uPMoVL+B-2 zO4iQc7h)jK>rIa!Lpt^_)2`5ePa%;4M6oHbJ@cucm&&i8n`;##uiaHWHo-j7{5fzR z#9kO?NE^oOj4p}eR5WOBO{@=`Y0(P64g80(k4w$su_2+)yl96sqoH|8$0#AKDK&`9@v3@@7m6=V^bT}~b=Yy~}>Ps#L+4DMMaTZrwK zyE>Hg%-~Bcen-u;=LcvSn?n`wY8T6W!LUq{v{Cy!xX?AS33D5GDz7Il%?G%(kuX^`1vQ6jJ zP{BWu#k}7>L{O+J*DP;1uk&sji*+)n5lHSq$951aoGRJ0*Zj;y7H4AHl=gPQg@Xpk z2zru2MjKpFnl6w=fKfD?vJSs$wk<*vIx-KD2sE+`+r##A+1Of!%a)ctXR*yNnE|ZJ z2hw8o=Sa8Yh_eA-N4PB4-NJizaNK`Mxs5}BhoV}a@*Dd6vqQv>Lkn5x^!>mR{}@@) zRH&8!ghX(EB?C!yDKHFJQA|x~xtY=Q$`oOQ^?0 zJWZ5uK0zLQo!~K~BA>;4`(5@Fmi8r5-wGz3LWJGeeKmDaddNST=Vz@5{V8z76rl9x zIhTZMeCkDqAAIRxn8ps~5Y=1L>zsqp+Ql|1#TXP(cF|xcU19srAD|+*Z^FRbj`4~& zIZSTZW{>M)`={B9H>Sr_1q2<##S3;*uapFa8ni0?dLx6sVE?38v>bu>bON4pjd`Rv zx9R326g7x*IyWAFrr`Pqc~TUZ2VigOw$dbSuZC#ZD@3$YAJC4q+mf&dU;i6CF$ZfO zi@f`F!U$mAGQkQqxOC}iGkNql6uuCVyvBw-a(8u;D8#r5$eaed`mE)qCns|pap(m} z=JIoup;Wkq=i-VVBRqDnn`s#L9($#aO^!f3@}|vOlJ5TzWG8{>V#q}r*_1T=RgM|N zj?94jkr>HsJHaY#Y{5Z@#oQ#!H4@>jK|IZHOd3WjPMkWb>!aRQ+h}j_Kfs-2a3cWq z{V1D~E`$3)D=VW4!2iZ&V6o$aVW4n4nh_Rb z{WSE%zL=}cJ3=?!d|kz4oS!Umy``|22FWe9l@n%B>FSo3BSch@SvUs? z+h7`a_YYy^|8+HEjQ!lWGuhgfzUg|8fFP#ny z7&wuNE#LYvFA)t&z)!+BNwzMk3{U#l*QB5l(JYeQ@j3&qP zJcM<;uj_@qW_mScIDUkpvppoiB0a2{C#b-k@zEwzQFw__TTmkU;_4ZE@Ubdp-`S@G z-#`9gj)@$~pxhzl-1w*mwh`KjHoXPgHM!SpQ}rfbXIcH#?x{WTYM$*5WI*n^pRj=8 zOV61UXDort2?SRYvu9G`@rH7rw%R-fN*PiRl^H>uiR9n%TCU<%x?xF=lk)5+sN=Zt zpJ6Y>>AAf0bTseg96DryE{L3_y}5r5iMv%qC*7taRAL7=shd15LV`+h9in9pBc!4j zQ3pT!J8)6zlvvn?*DPJ^RV*+;6txG-H<}R$WF_@C+g*zFhb$ZVZ=*m{^JY1ybl>Tp zdWeIWd*X9M!H-_MrJwI+k%uEdvd6`8B?y^(r8Wo+vG);WbQf{RmWFrpHftsHDDHD| ztGK>DIWeBr$p140CzDuWd=9EmJzQHV%569JMX+F&+L1Y)h5@n|xt7F@@;N(Nj8AXf7pK0GiiK2e44H^&? zG*~KkD9xz0q1u9+@mIu$vxF3dbRL)0`Am@O00qU;(?Q&4IfnGacG;zJL8*8k%QBh? z`!xW!QdR&^y|7Rfsk{FCy-r)7F|ma?nA(j%PRXl0NXseZDqI~AqWyJ~^WBDdSyT_a z?glXwnLK%C5vZ5~wMWW(W^U6>3aOtR2pBD6;dip5jdr$Q->o9=dYG782^3Z^g*_ZZ zz3Qw_7rD6`;$*M|ZM>5b8l$#l2TW^t&rjuh{l) z45jM<_gNhO)J4fHHLwU(C6h{wC%s7;iKN+tzWK|n@-Mf9Wa1+>vnMj5N)U(XIJZ(+ zxK%`SAVbhQj%yA63?7h}3NsVCch@6=nZUVst>!^4RR#0|5`nBZ?3-zK=Z`k2Rzh6$ z&o!7RLwuSM`Z50@BcP#^{C|M}Hhqd+U{nLNopxxyA#z=(q^mZ0`UzBAt!VS!NwP%p zqnWU%8w}8uWmT~CE;rb;2`>{wV>{Iny*p;g-c%0bU3JA}SVQ0H)r>FZpfd)wf+Zk< zjT?)P0)1VXgyJZMg<|%BJ##6!#jD}EkU+RwAN-;deKKB->7{chS)qk4O5L~D=aAAE zoI+)TU8b_NsgN5l6r-|8ZF1K`r_h z-a7D6qX+cxhPp@eg;_`br|Sg9CTC29><*tLioe%&cRovNFa}Nzdp!8A;wYR-))92WXM^nE7Qzs1Ht0M17?a#R`HNEY?MxQ_tnOcUx^93zxz5( zh~;>#7|)v>Z~PHe7gulw-^><{mv8k)MSBs5iigw%eS_eg^-U~7YSN3fVCflk6bl#ooczD-{|Zp?-Hu?52GtjU4SUrFx0^)k{mPKK^<}n@u~d@n$(?KiRQ~tC|HZrC zoV+HgeWMvs|ud)+->;=DoGjB90zhlRP&{gp_g?b#S1&Jh}rWm zVGod8haP_~OyU(S_EB7bp2Ns)cxtZG@gA8uz&fj7wm6-$&=yPqW-28i zWV6Hq%Wu|~GYdElGs0W6E*VRpja0ZZN@UYSo!nrE2&FPM*Em0l{Oe1)hx{o4EtTnT z-2N#yuzkNOzLo`cUP^Om+}et{@sG!42;W(Xs9PKBXapRWf!F9)VYdRgM2HZUEuim) z&}~qOS6LfGS?8Y;=Qb@RR8X4`%EPx6nJkK&K7P#V;7XAF4zn|nfH>8`59!g4j%BXa zz5fHvDzap@5e!QX3|G}J^>UgIGQtW#nN{y1q1l;-mCZotF}xfK+ZaHXF3ew*#LwHs zUw(ApQAawu62ezF{0Z8s!E#dsbfmjIiYvO&^-I9AV@tmyc@&Is2d0i|u-ojesXHHp zyZe@QG4`%48IK5vR`S2T@8oUE;lWGn9Qs>p+;E_+tjbkUH;wNAJF|nWfM*LJx7sn< z0Wf11aBNvZm)P>|1P{$9P^#Vei%CrkYM9{#x;j+{s786tD+T2f{qP3naK$>mLQQDo zXWk8kEx<&YRi(Keu)n;&CMo{uGSLkuxXn=jO4PG9Wrur#^Fy0Rvr+m#WEF7p-2_XgV1>cZQ%?+08q9~V+Py2k&$09qk}6da`>R$?7i{y8i}FPLs>Z2BqjJpaPF^@8N) z7YUXw8o_W3oyLG7n*Ii;pPhMx8I6CEm1kyqK?zB1he3U2%uF$ zO~c>KP|VSNi`O7IylA+wk>a&fy2pufu=h&nD5u}<|CK)uAWW9xrI_Q&Eq8^}$#;fJ zJ>y%M_R#|X*d;|oz;l@wxp@T>n{#R;&m#F5B4tQpdvUlAAN@=$J^}K_W6~3FHsYDa zTXyR8IF))i9)OG744$9%&Jpm)_aI-{(Dhan_uFJD9pnN2sB7wbf?;Tt5=5lg;i%;i z+lRt~ZjZ2x1_8(gQUk8}wBK^VmpQzz9My zvG0$vIz|CyvpmCLA4kxgO4OA6#!V-@s4W%!tMiaDmx)n2YUt0}!~|Z&-q0g$>Mw*O z{B+K2r>TTt9}yFpS2(>```jW&MadzqDV+Q&Q9y9Y2 z8=kGt`2G^4KKAjbRQjykE^DaY_q6w!6!E{D`WL+jws)@YKZK!7La;A7@ib;6aNPFr zcT2VC2OxcPz6B=EIiSaFr(B~D5$yhKz$D4==LbWobbqlVO%Vf3vEmuS@tozZPCh|n z?$B1H?79x9OgJd;?`KAuX|lh)?x^Rzr|HaW){@))3R+5@R;-(f__xtQIG6p8`g`27Sd!6CzFiK6v-kjz4eN-6N?gI5dYO z$HuVglC$8{zKOPlR(55$$T%XypHe6718=zqB+RCpPAZ6?2&edy)%DwcP9GpMMNKBn zn1?Dst+1DtTr1zO`vw~yqV~MgT50=%umEU#ux(q;i#9>m*A=@E6QjzSApi11JS8(i zx?`DlY-w**QiU$2Z|<5{Fqs`{hv7N~#v^5Ed+5$$vr(U49`>4WXyH6md~??nhg zK`}tj=M#*d*vrMvA@S%z3b~mn23}aj=8gp3l$mcZim5^J4_(#G7?y(sJ-((}n_dcl%Y6dT8ezxO1(&BrfvhYNzSYvmKLmV^owdhNMB zpB&tm6>vy*KrjDA5p8RmyaAlegg|Ayg}Oyn25gQEe$e(Q3;@616WK);Ye75aNvulU zy3bP0*#v}jeIL~IJNS0eFo$j@Wen`p76B2fmqSJvSh@2=7nyWyVI|;f!mK$`aov~K8Y-&*-F3|aIw-h za1}A7L;i_NJCbf5hD=wVhrpJ$WYT@)f0b1`Em(w(>neZ9Rk>1cCv>n|j~!<8Pz_zt zgxJ}6n7W4`1~D^S@VvH-4pv~R8*PD zW%NMwNei4HjKB^nsx7h0e>sV0N=PU8)@|muqWxNG838Z1!hXxtSQHvw*-4w7F}XMl z!jMtEr4T2p6M1+Q!P-oAOC{W1bATy07@-~&>6{CA%K5xRz0rh|~>wZDSZf zIqFgNPm0-gaKk(63@+$jtpchz%vkr{6v48Il|N86806c5&{2hr?;NnY_P70T=x)S>!&kwa0G$vgs|132*wje|D{&2&~@X|#1M z1lPIdC~#A1w*-nckJS*i41+!%6&^TYE=aGW-02lCB_=xCdQ)>TC5`)w3W)mYv7veC z6#*d4(hS$mTgQzEq~HwowLQ6ufrJIb#SwkuVIIH)&bBFY;n&lH=}=ZqARzZTZyQq& z;hm@2;t%xJX76q2tPMUK-o*(#n&dvI#TL~9G14i6v7CSwds1&@@_cFTS)McaW_8n~ zBHIDu=aS7r$u{{9D{dW1hmIA|FSS$#bxz#?Wc6X1O|i89Iymnx5gzdGIAl5$U2%>9 zvyX7u(haflf5M=g1kctGg0BUhY62@pM2A3WdPYcW^mZ~$8tBk)Q_!asX1<@epG2Yf zZ}qIG;XQq$Eo>Zt02ZF|)#_;`yncjvHiilS3&+Ir2PUjo;mwajTy+`g^|d2L;R4Qh z#6VRr!?n$hRds=e!F>)D8J|Yhd8T77@_b)_)Of>{fMs@Ay(z?Nu*w2eVbMWd5MEi( zTrUEZ7h-BS!qgOX*ofrv@zN@Flp?De+r?<7ge};I4FK!>S8Q8cku& z(wC-dUTU7@ADW>(d0${JEw(kI9aR#7&U9WhcJo?ta(Z<1(a5F1+1*Hh-F;!avxGp9 zOXzl)tE-UKF&svLH<+U<1A)Efthbib$VW-U2AYCRpZRfH_#u&8w)~`?jBz8PKl?3& zw^w-RxPYoT-zwiJswZ4|`m;uAa*LI3soaWNyqbuuG=nOc&>o?($SRN+<`icul2j)H z&Ln#2WnK;K`;q&@p<{)k9#lb127X*mMcetmykTpRxVz9O`(86ZIlF+eR$#53NjnyL z3INA^b|mXl8hjo-l>u~Mj@c9x{eJ=8ETynRo3p`M6eNv1c0ML=UAtI8;$W1U)OK71*0SvMV+4V(bM@u}5}`w`h6yxEI0 zRpIscIHnolerkupR5uxppT84WofY17&1B7Pksw+Gg{tJpJ3*KKYADeuD1SwC!2%(U z^*Z3@@lgQV|B9y1=|jz;sFicvYDhv|o2Bz)Tw-MU(*N>S54+Q3*F3Zp_vlGiu&FxE zc$FS`*pNAEUKr?Qh+kXuxo0yV(VFNjI6BVq{t}OEh@QkHUSWE~Sya(HW6IV>w&~Mv zTMhh@ka#oX-#H=?37i*pif{|4dJpjpFHTzACsA z=&_O6Usp{7Us-&a1jA2g*&G94y4+W*I34Y>83B(TcAf9m0VEu}0-x+yfLfN%I1qZB zdo*MRI<1~7omYwH^rjwia)47aXWFd$e16L|^+QUQd+|Yd>bs`bJz5P+HQ%){o9cBi z3IgxL8XVZnGq`UQ9-wed>?U~&uh$Yv24z~gZKyLu=n3#=?I5=4Sm$M$GRJ7=8Wf?C z=d+HE_S15BL6E%P4$&!urV4A#O&%S z|AamK*hCqlPO!?g%%OTYg&WsZ6Ufss+iBwB7;p>P1MbnNKpwg3190S}WqS%I+`6>8 zp!zmYBE{UP#xqnggR_06kk#;H2m|G@U9b6xt?$wXevoqj<>7Zd72N<0*FjgJgJ@f|7O9jns~)$8TG#weShv!3-5*>9De^v5#>&zGxR?y8Ld0 zR{9C6SG3|Lfs6NaqY)n#{}SH!`@WEKCAQP(*!Q6ZW9Pu(Gx(MrjbZG1m_6-an~9lg z{ZxgGvLjps2nZZGn^K6vC0N!%V8%#ak9VO~Bp_{Do0Ooz-eu^f2?m$ip`BGxq0jO4D%^fH;FP0OO9+qvll4RY?AFRGw@Wps@;zH!?j<0ZgP5N4^hp#kSvuqWo zpul|({Qx*8yDPQPvseKGnQb|l2mNe-FiNAktJF-*2k!R$g-N~d_4WO^t}hfnlUQ#9K4{{2nb+j`S3C)YL^PvyomKO z?%!l53Gs~^V;Us^_d->2;%RhfkHtnSU+8s&^q#v1m&^g|RhO(~m?;pcfOQGS&GF)Q zzCxch4CC^07Sf%@N#97rZ@{*+`=*(S&MjW`0&KoZ6o|QjW-fO_9-rZ9lhs}Yjh(pv zUk!@4q8-}0e~Tv$MkixhbRKRwKYrzdGvk{8ucFMvPRN# z1{U%*;CQ#^{{h1PKHwXIIo@axm{Wg%{q5yfLVF10+-;LNZ}%2#6TW!A=yzjCA|&hT z9;(a}@r^*tDCe*S!i%IrDdu_k#QLO!ELLDu=tGx zs|ZuJcnbf{!ft69zq0SDM;RGE{JZ#=ZCa?qz9C|e@{am+vi@DM!nY)X4E z&-2733=nUZzpp-nK-@iHQ((+OxP%!21cC=@pk2sji1apVFbRR-rY<gg5D|{p<5ocZ%R*w zc~vcF9=zGm*lA1e5 zGqFU0f!$U%+;iF??HC(0Y*^76zbF->2OerT zOABt(E+-wf`4r=Tv6HCQt_eA*Qr4~e39kENzL|tiU$i&o@y;W%EEeVjJu#H}Wm^og z*-K@$-vsPlN>~V$fl521FIE8g15qhV!#fiJ@F}Z@ezCHZW&pnH(b#RQabzQ6$n|yE zNbinaTYV>7hy^EablYlX!!zysyhloUX$BUDTAq26#iD6jw-URp!Of~^Szcx!rp2>W z!KX5#WC)Y8ftJ>)((^eeqCxMB+RVnOLfOIa4LnlGn*~?;lTk|`y4#jygh6Y`8?_79NxEIC-uxxXVl zt8S$S6c+Cg|MM-ms41wbRXWU@)3d4vwe0W+;DOOgCTkbc&K?WS_psXpENY0x4M|L!GD*NX$90;Dmopqn3_t z0iNn7B%&C3iACMgY;%Qfccl=L^~f&H*`=NOjb!*oTX2YqDMR)zmNbBy&d{B$khu&m zL+rLM#33kyx^bViQ@ApeHaE{bXNdFx?zM8aifvzDYX3xo&&n#rAV6zGQ4b*mrxwh| zNFpg^$b*B0BI{_a0OWutjRBI7*GO0BGZI>tQwTNv{nsScM4$$LMTn$a=l@Ov%6%)G zgE!NgHFX(M{pj4NMWqwedC_WcOA#`I3WBuviluu8Py8zF+li(xpTy7dg04d4r0BF% zuyO)^<_D@Dpuy8zz~~EN!3-HM-MyvE7yjpmT8K^K*d%sl}5aF)UL% zpG6ZzO)|g%wY-48mtj{#i%|UKvxDOW9IGoEeH|<OuZSL_drkZ#RI2OoD~Fg(G49_NI3MW#=bkKoY~#rMAuN>d77~RJ)&28hKeU zLCr}CsGf#}<|Wb2B_cIUyZV*{;5E^zZ!z9cDPc9bzq$2xsQ{jtI)GdAXPrT-z?BWn zUFc)E)z5B}W~g{FpT#D~hE}A;vm(V&1y16DLR+?IK-%4iJYpOCNbT-i5ADh>mI#Kw zT%E_A{%tdkOJb4#M;AP@wiHI)RVk#PBU~i}iJ1>(W9IZtE1!FF=p#}8Y8R8L5e0CrmsmK4`iCVGT?nVnxErRfC4S~4pZR@7^I|pTp|21Vg%81T^U6jx&vR! zo$Jm9!U|2p|JtK4KVEL5)<=D#l=56!5P5*%lo}t~#5IZ8(O8CVr)K`rWil#Co5Ld@ z1{6kBz%0s(Pf`jN}Ts{K1gmf$LZ6|FF$ak4b zP0LfIEd9SNMz0a5W`JKf zJ{qBF90kT1hodzCN^hY^MW=Gbds0cxS|k0AqbUBGCr9&w*@_aZefjk}+V8_1u|A_G-2n<{{c4bcLfeLiP)xmoJ7@3!NNWzMZg zAAKR;)eBLq;Uz?dHuMvKdd0&;Ki*I)5*nBf&Y+(5vvgumwK5y(d|Olgjs}sV2Ihy+G!J~Z-=#)dRlNHx~U<@ z=bu`S!qt5)P7WiF_lxDKSFq}Efs=@>bnBe;#w;_RgdX3yU)rO&M(=cBgQFIh#Zi}}`0cxx8RQMu^&XnW3;`R!ht!OTq$p+u1 zkRp?mDUT561M`WG_k-j5ZE250v)Wu$+Egr3^s)u#i}mstAc9>PXvze)Iwt-C$i4#E zi&q{yRzc^=_p^-;S>dQE@^{fY;@Qyoxb+8c2k_Ak?A*E`%}?bFL_QW7v>uv#L4+!)>+$oldj?Y);1LM47cs3!8{RA1y^_ zb=HOqo4^ik^!2J=`d@NpK%1;2N;>Fl+7Ju?T)Q{ZiG(wXmrQmZE8^Ojn%%(!eBde} z4^zk_7Z^><|Dz=DuQF76=EW{&iJG(UpnLV{h%Td^Ns2kD`eKpho#bsEeX?rQ=xud3 zCgjM7z+X@}zs

XPaufBPtSh-sY`Lm3pu)Mwzg!)~Z@NUK8Yy-yfw`vD6wTj~Zy^ zKC*YWK?h%(rx-Regv=>>^s5k_Z@V=Vw9C^vo>Yq&+YiV_n8qx(?2zOfjJr(aZFStU zW)NpGdqp)my9{!&(aj&lzvS0Q@HAQhw`y$!6!cWS1?GRQTq#KRe-s^&>uZrrBxnU@ z)k&y~&}4c-nfdOQ7ov;XVDi-EW=K%@f9fio=xom@4)jRqisOrKfQPBQy$RsU##&Wy zpJu%4l%njJ031z1BA+c_Y^kyayhxCR10HkW!3zsCbN5c^WCta=k{&Aw|Iw`r{ff@< zP!)-fjr~J}9{0PXpSsDo3d%}UZoGKXF|~6*hL*kN3=d>Gax(njsB1MLHRP=%7(elmT7dq25D3@av;Uw%8>>}0{oY*N&Z)Csg}`p?SKZ`Kuz z#tHjQ@)$rGRr_I|AsW#^p+&kru-?zN23j zN1u$l0BP9)m|DoBr~EGh@mAwY_~4VQY65Zw%lkUYrQMNbenxo7UL?cj+dyd1>Yw!Z zlH6rANdYI&ktcV#4sJw5pQZAc`(V*sNHDfywgWgFi{e}u1-D9*0fCarviz)xqVBOb zr>RsH1Z*tbd$NR_phj>}3L^W0whApC`cydx7#~no0NW5Zz>jU>p9o3uCt2m<_Ux@o z>KG2N9H`sx5vayi7sse`T(!ggiXPGaetu3ek)YgiN0T&pXu>%}mJr;T5Q>c~@XJSy zwnm(W%vd5UwW)#rY=Djd+Nbp~Ah$Q@UV?6%219(e zfFQoDPRg2GQkpR(40|&v6imtW73KBs)p{*=_a%-RHs2AqO6b%q)d-<`{T-$lKRQXw zAF@o`m{3~(NjoP%l0#i^+uPAT|ERC)?+0rXK!GgfkF0lxY@Niyo>U+7d)6Oe8 zyA_kOm5G0bu~LRk=DBY9yH#0fy1eEo)oR}W0AtUECM5PArIlsvMt5z%=t8iLy!>wDafp#B`zDlj{`7QMM7!$g7t{T1m# zDEC6;&jFnph^1wvMq3Rl@+LORnmTiESO?8GoWzMi%Qf}O+Pzr`Gfs5Zop zGie^xX+aUl4kcY!ZI&4o|A3}SbK}~(?ce9(+poLj(4A)REBB@$XT;2K5Dbqne3!>_ zyaCQwgFL9Yq9(xSV`YB%NnHxv4h&9ROah?{A$AY71bHe?ew|iuSIZeFYu>Aufmald z9S<+$a&z08E9G?Uf>3|Y#a~$1@0v`?5);eu|Kt2jGrp+Pb2^CqB&PMj^Xa>mPfzjz zoW<8+gsR3_>tM5#vcy{zqbR0=j?{WKI_YY9Bq=F&Wt%f$c+tBJj8Ky1GSxS6$2yXu zN8f$ull0h6^*L5MN1!Ycys2I3NurQ%49|=#ks~)Ot(e1c`W4dGa(|zb#A4mCaUmuG zeX|IYn4eNQ@B?yA%FIaC&)tk673s}+%XM%1sG>Egu$8_X#Sx}pp`pSa_(<9l(@(+} z76H;E25gmI7}g-OZqJ#w-?q~zxLel!&QhagIae$g1O{?!&P>Ou_0S4t9qKADwu9?G z@S)9K@gfrN^b?EaSkEOIM3zK|8)rqmwPWWv;3^F;LpV&g+0Ce?_t54%A z={d|WYqky-Kh!`S#MO+a$hBrdQZ$z=B0Az&0%vZ4D=k<#A`$TaG%$Wj*Ld zBsx2Zg`=Q4sVCWfCfo+M83mYFUUGfb{pT)=Awx^H)#JSyW6#*`$QA? zbKz>U!rTa6Y|KV!qe!aObDbAtHPOl_qFFOM3wMMDri$vrVS<=Ku?ic<6aWe%hId*W znC0p^l?SiKJ`(wZhpOjSuj+d^{R zJIena8}@QfruDPzw#QjVu$uA4CMi!D+%rrn7UNg%Y3}81b@WdtdM$2y=L|@HKXJyd zk%FbERd-?YvliEYtEEuhIA6AxaUyL;Gf;88T4(B?w3uZxnsr@H$%J}aZRtc0E_p|w z(#|^E)WfV?5+Z1y2YNsl=mr}`?>Prb8P#gX7;-{G;S53o+_Q3=MuK%qu|lPy^~Odc z;S#Y3Z2#^TI7T_kgECw1>eo??q!=o(*nP>|GyMW`8Og()>F^$a2!54Eaj|!09~~$b z-*f)1lFJFRbr}AV{V!!^t@%D`GNqRRAsZl8aF*Ap=X(#gZ!ivIGnMncfcV z(tc#q-`wg;OYK;8guN};jaQ<)>ZAKqxoS*rD>dG0zKTA`L+5Qsvk%BCYq%fE-BD0l zu!4fo`f3K7@Gs7LqLylNCBjN+g#Vd`yWYtB30Tkr-^aQ~fW7bP4mmfv19Et-K!ofC zoS*<)#-tG9Y~hlLAI8IQT|jN5PT6JAmd!MFbBKKDiO?5$%18@57FIZkAQAHoyaZusn3JgVV7elc<@DxJJ=5A1OWVGQKO=SZTF;00 z9}}-l8mZlE?(*6QE`k0}tV4b&o^Jl&R0B}b?^ff(*4}M2EzZ22g@CW_$)rauz66EX zUz$@>bI^S_^6W>9Hap#qHIvJbEC=$%Jf}vekVfhJ>Ct-rw*K{Mo_Q@-p@6C6I32G3 zfpgm1uBcS9NN33mgvl2~+L=%E+Axhkh&mH&Mj^JH%FP`mw=YsKtf*!s+9D&wybzk; z$vU_j2crBYPUnJG~eTe)1FOmwsm)xl>Nz2R11w_Bt+!ZtKU> zPYW(4dJier^Olr;^F3y1nTCS`$;Y#GUyp7`Dw6ej95!apL_d3f@GVA+3E0JsA%9Wa zuy6t3;8&OBS#K><^lwJ5oCIC0gd;c|oX@h^^NQ$F|I{x)BrKiG)FuMh=nU2}HfUAs z2I>IdF{b9pOg-@q^+|h{@4-KgN4!jpcs)Zsv>8y5c!%_aNeI!ReSws)P_3eeJemZz zlFZYI3rWuoHu$Q&C`Mrgv!5Q#$gdR z97s?Q_C0z-@M-Uh@x^uIZc#BJGKu3P$x1!1)xnPey`tX4!D5xiI#V`a7`*o+{2Z|Y zuDy^x`uWqF|v4URTpN+K&J{W9?n1&GqCEWdv)z}7rWJ@ClQjn1nWZ5 z#+vrd-`8q;aD1UjTSs?Xu?4gdL-O*q0|E%APD0TpMhr4OA(d{vqTjAY1rHT;7f^-a0ugyc_%?X{53P27jL{qci z&7*PA3fTC_N|{6_q(|bU;e>5Qq)0Ad9ihIa+vLxPsR-jKu2YvPebk_&F9zgXrYabx z<4C*^TqN@Y4eerL;f}I>W|`Y>FLu%mh>(64U6-T*|7ZIuGh z&JzTBNgTleIuq{=k0~pVX;Xlaq`rYoLnNye}J;lC(rn&nZxXSQn2XNkj%W~R3#`UJ3l?-pWw!R>o zFWT$f%>cy4bVk43zO;o&nSU|l2!6X6zM$sX?4s+2bCqn4KItMRvm*+9C=5yhGZBdJ z5%972LahiIkTiPWAH<9$`>KqC;?Ol4FP8U6*`48qFDA+>d}S~8vZku`ztJ{n6TNK> z7Qij6-jz45f!D57NipLCii}j>ujcmKtPm5b{Y;=WWrxi(*AtErgQiCfJ^)N}#*xvSB8A-5PnQ`%p&Pym{cC6t%)^%EePjDmbF*nD!i@$WB ziMAyiu3t0akj)*~`7&H}du&ZDP!;>JKE37eXB3Atd4r4PqEH#pi|Z~jSqes1iD$|l z2=3KL>a3IL%ruG8mSI+$60Rw#vucI0A=~m}5%ZF^wT6~=QNfQ?t7tEHsY+ypORcld zA}h8S*%(XeSS%9~E^=)f9_0U$HuXdCRs?Pq7y|LHec{=vm`+XB5rpvqpJIo8C3ao| zxq%tp+-2lexK;G}zm2!o3sK`MJ?wjhz)U?L==HXK#!QayU{Dy}MYLy}RjHkK;0)>6 zhXsDlf60KG;YR^~It`9XpW}>at9xANYT>E!zh$g73!ef;@cTY92Oyq3i3vfa)zO`J zaA`GC&=4Mxl%r|5o{$5;TB*}{(0(L)zaj>*$oRr8&l)e6CU%B|ck8SIFwP`A( z@J5jBGpk(U&4~$D=#pk(?&|L5^}v@e#kj%r0Pvo5k15!VvPRuSU{ds)1hZ$+VdjE* z<`?Q|b-z;7V95+|giZxQr(6(m%LiOFJlU0+c57z11_?WA!vCbgQ+k`A7)Z#K8w?SU zu^V8YDev5F?ncIyLgnXgl7MM431F>L{1vpXVpIKBjHlcb(HT+NV)LdbYDX^TxtyHJeeA}liK(vG+Y~WT`9sWjR5kR= z8FfpDZIu*S+3X#y*t_UXVWTPNyPDU+y1nX*5G)}hp#Aj4nN!cE(z6$chM3RNA{9~m z-!y;dh}r;#sddix1qJdQP9~09OR@a5PbQI}o1)T7WzVKhLwc(}`SW%b;*UUYMsi$v ztL->Addsib4VE!f3J(BusMMaJM`Tgo{f3=O!H8wnWvP;)0p=7Tw|9bLWc{BovnzJG zvUN-hx~kqTYGtVW13*? z`3WTEm8d`a+h5ePl?*VOUHeR{l+9S#&F9MJVR!R?aW;6gR$0rNy^>ZU@#R3ghEjF= zaUf`&=*Lxzj{w=5T4dFQ<*8Zx7ZR$2z{DEG^b&v(Lryz%MU^(FP=cip`2@>`QVdO( z%oK%#N-xebi|n_q$uk1AzK#_v8Tej&Rd1`qbh3khv-eOYJ~sKRZp?w5>P0KbWknV> zpq?|J!Xqq{kDTtS{G-BQS16o(M1RUk?;aMs6RWomO5YI*b_4FBc^edzXE7djchxD_ z7@(+DGZEU6`L3pibM6^2^hvPW7>mOG!?-Kk8}&0XRT8X%h5-&LBOmjrQPdPQu@5y9 zu6h>n1fw{=MOeKgHmF{ijU={^khia3Ni(qSm$ThUCl-os>VA@0@8SG%S`5vR9_U?d zh)i|rM?)+7!O6u8s8QQSgB6*gCqft)q0E}W`irvhP1-1a-6#-E}X*MR;Rz>^ItV3CNi-#~rX`VUN|6B34;S-rtEHu6g{>@r;8f zmDeL7wuB9o%8O!24bZ@GuX2JJsuV_q%gAQ5((VBcJUdpxyT-h0mw16bj-lnidDdRI zbG03`6=6ZQHd53jMYLJwV43t*(IpVf zrE@S-qZ0_m%CqmuPZEcYjE~zqP$WC|2A?MSzpbDH{v}dxTBs9ZfWf=0h+o<4OW}07?`nVw6^&=kb_aGk&XVO* zASieQ++N^m>1ALdRGDci2jP<`dPWriSmLP1m)16E#K^=P`t*Lyhb`!dN)DdRL6#5J zO2pp6`O{2=mlZ>a%5&D?AA4W=MI&jeHMnQ^K=XU9e`Cms#ZLtMIF!dALOq?w*RQ`m zumqO`BPTSGTzUHY>uJhHO!9))I7ogl@+d1O4oBR%%#C9A{FWeoUQ*|x zflFT=;F@Y4T#C3X>)=jdHkC>^z1Hc2i2y>Q$=uEYrr34i05BP3cN2Vma6x*I+mDj; ziKc^q#-x^@Xc5fxO%(vCPSR1aUCvAf1-*07-H=c-)cGb#JcG-)_@PT}SPF>?i490K ztP`vjUQ`)DNU=`!#HD11Eax)!dI~U9gByFw!x-+-^6Hc)L0^mGe^_N#?HsJmw6yZ! zwWLq=x{?8V4Th)z3ij`LI$BnfC4#8T3!m4wi9q}?f`;>SC-*G>wN^7@S^K#*qn(*q zU54YhMS9*s*l0Gv45Uc#NgoA_3`@3Km3Jg^L7txC-OFXahMxMHn&J%Bn#F71#ERx*KmeUoWUN>*=R zF=%k;*WZUwuA)bQJ*Cs|F#fxR#1Y~FmIPd5@&(~us4RPPR3%?o(oHH@LS`E|WHV%_ z(emAT6}}4IWDT~Y5v@yahgvJ9`LD*iy9+JalQ#(0^qL?2!opAyL>w*#VOU z_8!PTeUHyWm)x*-b2J^?@Q;28v!z^a%vh3~6?vPf{(Fr^E9XTZn#*(%)#gy@H@>XD zXHcKLoZ0~(aja*znVl>%5kDHWWeylC zOOX{VvFo>+lsHZQ4#h+=>TrT=^1%5!j9(peBrJB%)=m2hP~FGzc)C>8CFcq z*-v33-LMEONam`w%|S#p$M@w)6r4oabLk4V6)(qDX35~x7$nMR@rY^jZcaLby?dF5 zCu68`C&=TGiMLFMzH_{P^y2qBsg&*1>k({0;oLr|qCh^o{Ts+0ld`+j0K_?9T( zlT`7~3^-+?H9yUy3yzRW(oXxOMXaHY28_%T5KXKlHn8B!O`E+BWUq}%VgJ=_YBO)S zD-DeNi4_EnQnqSY{#U+KHG77Z zU^~GKQby&EFiCwB*)=`Lo;PN>nhDaI8?Yin=HYd^u`STv%|J8D680|e@g#}8v?-D_ zF>_snZ8#2<_6C{{nfPN@(~Di#N#h`HJ&5cNi*r=ehL;BC6|!ydsdpAQ7Jv9581^*v zXnmKu6lrySH+WRmw51a5TP$-njeYgDRm?NmG+eMtnYU~X52>t*FOx^bX-Qj`gz4!t zlZ+KNiODnEmLGL{!=BF1Pbf-c<&XwCe_%7xHENX)=R+>sLmvvEq z&%NzOsno9BzN8N@M$TTH8-s`)k>)PQz^|VLU0q0}v3`LL;&$Q)ff)}}A@MWB$l1Vv z!q+0wpK`?};xguPh*?XsuC_!8{`N>CNqqd0E-pa75}%qNG)eaSe^A4H#Acvc1Zi^h zPXyJSQ+^0bu$5<|Sd6eM$g{DelDm2V-JAlv@KjU6d%tCduA=(9A$ISddIU^enw5Br zC9Yz~a3$?}ERI(SO?5?pG6xTgK0P3A5y^P}Ng5T7(XjEFu#!%6OtE};K}kb;?@|mB zb$TRs(z_C0p;c<^7XEUKv?mWuFvrSXi1~brXTyzLZ=!&q$PRT3T&gWs*#BW7XC59 zZw;s8_7BRFo7o4vbxF(4ddlLaUOji#J=D`TYgSv@HqW?hm}2d}f5P@DyVqHA;{XED z21!z|cbz;rKR(<5BEQH9>J2Oe$PQ>97H;JNZYBq)j%3f*9HZ&a>()wGL`WI&H zYQ8mh3}&66Jl#)*Ut?Ex(?~y0&*2w1S&wQ$N%&U$H3jX{rK>ii{GQmItXtXu;@^k@}6ZKOM`|(mq3VF+RL%w3E zVXvwp^^wrn4n&44mV7z6PyJJ$vxOUa!XcGpv5SV-tX!zbf4{? zi5C@Z3HuWC@y@rMx=Daj>=8)ARVLz1E5c`nLwaQ@t}GsEE&30&Ch>MCa;Tdvf2LOW zOVHWemyHlQF5|E5)DwvPtRESGmv9TR^cv7^l;YJXZrCP6*w?j*{(tzNOh217+@uRr zcl4}bzZ5_>u@ujf$TQ4z$SM9x4)Kvzs$C*wv+57aD|Ndiwp7R*F|i-HHTb6N zQzc^*pBUUk$Ce|;e4Zd}OPF2z#AAP*jzb|EXXp?v-)4M)_Qn`u;;9h<4b$;bYn--dainG3|3SBlO0pE3hkrUQ)r#r#cK`r3t=9Q z&H{wL^04wj?hfnuZBi7cB&M|PK9j*5JP7*-fDR+ik)1>4BM)jffshOK3wGwwl(mkZ z>D<;s7dp%O%!p2sulGfcXjLVsACM3Ig*g{$nT@7y!c747rW&2~M`oE58~Sq(QmnlX zT#gsBnIg4l{T!!;1iI#Nj~$Hx12jEtwkUsi z76i|a{ocu!(!F&K3zBp6dU#gR@x93f+btu!(l<4lQnO9DN!2yIc4w2I5F6NYFPF*g zOw6JB`k+n^At4`ofPX574a++W~`&jxBug- zK9tz)DFNnT!Ch45qC!{3V>tWFO1u;BtQ6iXICJ>uB_3@MmagI4lR#t#x z<1e>*;9TAf*l#S72~a(8(9ZBu4Zp*BgP(wS7WSUXz{hd`G7X-KCdeP`hgo}VD@UZuC4yEqSzN|h82amD zu5!eh_^6nG(_M13?oxNXZMsf24Zf+x-mrXM-pB5Rd|&{1{zXf1d3P`)AM6obQ@Mc- z%5sxFL@^X|!ucOC1Jsz$d3GKtdQuqL?pz1&9LwZ5J3)U)V&`ero@faSu+H?{`&t7m z_Vnc{f{-vCg6+HE+WKvyrQx$zJHD{P9}RF*%ge!0QO-at70>Q$_{xY(gB*Ro9Jy*6 zZGjbNu%L&-kc_P>!o1%0%VJ{~)$}OmadijeX%HqWQk`d0|JZSA?_?vmB zhnANAyvWyKulDzzJ=kFeTb1ED;*rsNNIMsLnF$$C)y*uicEv*;eTUKLVug*w41ppI z_-V@sWl+h$W{+jgV$1eC+!1>jUGx!Wh;_0!kbvOOgKfn!`tmq-%|}F+?+T#!P@|@Z z>=c`tHcg(qlwg@WgF*VW7(bIvnyoN7Tou%xH!(({^0f^Lq7rC?_|T!lzcIFqtKDr| z*$O}-P(uQ4z9Q9?YEY*JbZkv>?io`wLD$qqzZ~@^ozH8GloF)cxPQk>mcH_{ z+Qp&hOFG~8PC?URuQ|}+DCvsr^EC{-GocxH0iKQur8AZql<}1!KVg6{aTnYLKyWi7 zFkrS4@ghM1E&VqgC-M;dVq1)o1#g=k1OqbZG*;vFOEHM* zET)mbq`F-j0@Fn%@7R6WR-KIv8w9KhUfb@FT+~u--0qDLHIYI896tm|^v)Z0)$~_< z8@Rj)>F5&Qk5~ON2)`U>`Yov+;zp*uxUM^{`@rF>2ph!{-U{(^Q*r2#;Gwrl| z*eES`$}-5yf)(+o)8QLWxTvr?wXbNzny4mn9Uy~8*w~INt5nv2(DB4Hg8~vlp*2Q+ zY0-Hr)h6to+p4&BM6vbBm@Vr$dULL7cF#!85V9M4)IkG=K6ZLoEjR*~llWg+1~#j^ zaNm~Mv4*NE&wFVkf%RHf9=fl#pa;NlZ7AD&Fdgq4_wlzyVqN>iWoyYLH<-A(7OdfS zmsDc|PTqnFQTbyuV;+<(0v!**i>E#0f7^wZBTyowfG#R?B{;aLK9tz}ld<$gmgX7! zNTa6QxH`k>O*$tv$arK6_&FWXx6Y|$vqsLf&!acOxgq_r3wwA&b>3sy-G-Bwt` z+MUk8c2NgX_pPOfnNcK`Ktq5QCY;jTSml7=;vt`-5e8zy;`D~SlGePjDADjQ!{90t z;M6{LD|mYDqqJ_KAH6Yzy<4kkLmQg|w~8S&TWcLZeUhQFLmHZ}l9r%=ynjc`8-IUn zLyIRHxdBAVf2RGpa^c5k}X)aCO_kf6tY4-_Uga_tP5zBknaTJyriD#XS<894^( z^AH*n)k<0L##K_VXaB8~u{u7pZOo;OfxvzZb6FDCE0B@_$Yz2Bh2!-~V^J=}tm1HH zMI~a`IVmf_D-uK-6bKiTLN0O)~qT}1fRTdBHB5# zGuf5YJAuMknM>u90dcN$cPp;HbU{^a`vTI4dlN5Mc)|AbFREnj#u4)DxO;#QMkn&; z^z4iY18LY8IHxX`!;bh3?bwT~PSmpQ?1XDJ2^t(B$Z9L4BRmgBBOww)fF7Kd*2Zu7+Rs z4D(tD!Zc-coY!{AzT&c&5993U_*bOak4fM)>oS0>3votUu0lyU*|x^NS$wRo zeSNNV_k6Q9!?Y^fF(CyX8OI-qt`c z?YN)2j4D-U$vIMN+)n?7+RP;yOe194%1n!atIi5i;R^vqN;h%ZTcEHYRUAn?!U4igc&Xp*KmDP*L?>VG-m=VFe8p>0z8vf=7% z^LRH~fv%#VBp)r!_yxpu-fNLNE`5Qu4^TE+mrQ-0nqCE>J7E1V-850f#d{PPPL6I5 zN2)sdO8e^IP=U%)CMV2yXzW z5PN`mjB$@Htb`DBPe5VpUP-CKJDJL{%jOx>fv}o7l~+gOWE4juV|Ezk_wMCkOME(r zPC%I$0}i5rdnu7LC)`;`B`gv(mWMw7k{RKEcA)BW@jT5aL%MtPLy6e5!fn|(B-d$T z8?@d($&tWlEHgQF`ZouT_CoJvavwW9LO$XpP~UqX1e1VpiJfWVxQ$xYUK?z(YgaBj zgIlbTNpC;rCV$>ARW{O0&9GPuw}wOP=wYNOYw^-#D*MMaP}!&CO4M3bNx{bw{ok53 zSy&}yx_!GW#^4myrmKX$MTB$787FH7rLMPhRbyRHLYwKmA!-VL=D}`TH1G?U?){wk za}^N4<6ss;TSe4ObN!CHoa2T+?+89u=dzP?7%rMG!3YVPxAormn#DQ9-02af#K}h>C zT<~BW>2pj@n^Jj8G$^E`;6VD5>*JQurf?_h3bX?;I&Db&X@q|{hiODp^Vkh~Q_GSD z7i{V|cQ#+w=dC23A!tQ_0IRg#eFyVfcwPixLt8Wed8c4;Z^^wW+>&!~QOwJJL2fK3 z%?A`ow9Fd(iDftE9qVL#bVg8(%GLuL0q6`2`MX4mb$Y7PPM6l_cI)9`?O_dNzw&t_ zC!SnBa#Lq;K4{q-OZ_RG2T1D5IKV8bZhG~(HO->(gwE9j5k?sCKxTG_x5e<-Ybuex z=L$#Gg{24`WX*b>l}hkSZW!CX^z*5MqI6`htIY&+94PcU1Q|FwkU9SwX=j|x ziC3aZrCr+Tw&6|Zo`$tKPB|Z>#>^8NZV59N8UN`u2iiwyyfSJ!f8t|?yj+!#DC4c) z_Xgf!?B-<;MO1W)J4Sv;TF8xr&~CaD(Jdg=Kl&<~Mg~dq5xTzHuyAkAo(l&NP&YhM zjV}?D%sh5)6i{8w(eQRb76#aJ9`@xk?g1G+_6Md+o@95gijIF=@L2wMGguB07{`qVzddr%Q~sHs?(Yr=MPk(`wC%V5w@VTe7_h^C|C~J7T410 z=8sHiJ1Q)XbUP(j3(0I|iyiC9Bu1prjB&O;ObG!5q=i~xIl^|w&LDehibtVm0qT+udvuJmR!v%1P)BgV7 zHj{c|NQACDOXNo@tzZb&QtUccFE_NY8ajX@V^3}|+7kB7_BS?5tCJk75iZjc7xDT* zi7}Im2UU4I%>0}>f!J%^ECrfJP8anop2}KaY}xot>zcbOk%m{+ z<)8MO8wM4xab6K&P^4oDMuQXk*u07d31~7>emtWcH^`v>*`7K`n!DHZ%jizdW{|_Q zSxmicd)as_a)1ybPoN|@WEi+Vl%~Z3Og_JZM6nA&VT{CIBm?JN%_Yv(&U=lk63=x; z!jEi%2GbLB2sa=;doukL`|H8t@{*ifupYv$eja6C`>crkEmwuWn=h#nPa{iGAcYz# zo}n}c9Qrm+8Gi4S0!}}05Vbf-L_XH%AjVq6f@V`wb1*^Di^@1||NC0k*tD>GG=gOk zd-F?K1>3~c>QTl>MeygxiB~;jgboXMgKVS(d=8dD#OC^%$cth>Prtk`K<}96F?zmU z`2Og`I(5y~)~M#jW${LG-gc0ir!wXA8U{OuUltOQeQ0G7Y%){QMQKJnP59e~70PAR zIQxk8r}jtV`67h|oUf|=+4WnDsh{<3*iy|2nN z(s~J{?+~`*yK^oIL$(c`{T8Fl4bcWBg4-+j9^oMQ=lq51q3?jbMTg4)Gkq5e4QDV? zxikrXyfDp&U#%ZFy<4%2`icX{Ytwh?1w9i66gbmCB3@1^Yga2F94K14O?ZZrqkH>| zY5pOfzaAu_jd{g(*dpOAfA~9-scu0svqz$#P)^IN8U^F++c*yst7P+v2dW+_s3` zST(f z#6a+!Ms9Wnxc$V0pivJIZOmA{Iw=X%j~-7H!J4-ENv~9VD>TC;@&g>HS?V8iB{`rL zK47Xgtx{`NI%R6px}~k+QcSX3j0;HvayK>8h$IUl^_dUt&&5}kLx64kOLs5TX0YcZ z&*GB(X{q_6o5@M*e|yFTV9-BwPeLp`he~oLuE39Pq-ek5OLgE3T?Ry15|3&Od@8_D zPw~tI_t#0SYSnjX=INkigRUor`93MGFLB1owW;ahKQ@86a^=bHOc5bFW8R>cH3o9< zltVs~(xX``g$mq2+bnX*g0C`49P3y_s~oEAJFDIMIY1kUxGh}a1XkLpUe7`1sxHOn zjRX|uPlP%&uvwrr0H{5&zlmN4Nn*3uK;A?TsVWES24ZHqEbs5U8bcd_I(WDYhyKmvXBtXd?zar=>R!g%|~%FKUETS zH|JnjH=Yo?(T~fhI~Z}Zc_qG0owUo%Z)H$ZtWWR^P-Z}^RfmFJW?IlP;Sn{5l&h6|tkdBw#NW`` zvi1)tfg;w(M_W=|xDH~!>i`9~cjNubX!q@7>ilXFrq)fk7(C@+dzErHD`f^x8!WAH zWN=fCkM<&^^ylhG%fDJs>zH;-b(i-=0Y@mrmEXO11vPL87s3~g6ABQzi@t=c+@#HZ zw8%)QHzNNnWuH4{A6ln1;z}Zn`Jy>X8n4b;%+Xti7ICw^UJPuy<}r*@-d;k3%5_0$ zHkg{eQ1U)qBc$8md}8kyZ+_^vsv)ry#B%htt*&`cLPetv3>V6j)XjlWxx1Q{yl0s+ zL)=~@6@5w0IOe=EUF5>!l=ytx9_N1#U4yjGKieA9r%euRz9huV1joaH?%agDub4^u z#Ka~i7!5)VT+v9T!a^M zi6%^Ru~It2zczm`qXcKDcq8FBz!?a+Oeo3pQ=fJ;T&6JhMoN;m6_Wke+gdzTIUtjU zfa2gg10`d{hD2!2xnLhfl|e|^$QHufYXP=q3Px<~Lq6DsphHm)34p>V5}M<=fAErw zIPf-Jlj=S?OUZ>R?d-Hcj{Vr|7T$2le$qeK3vx9_Q~rjeHai3)kyo=If0WoEvhNu! z;8@(ooo`5+8O2a>aqNc@gu6==4E|jh=|8B=`?PmyP%V~QfP_dlFlA#he;()%;V$oGJY64$Kzn>eypZvQla!P^7`?cCTcVfe z!byJAz*laTUrt=e`lbZ|wIt5rVeLbTY&w==PF_c6i8S7IH3LQ7gch!Nsm(3F)_Q=b z?r%#chYwfYgedkSPu=qA5T&RWu|jkv5Elc(3z;|_=H3+Yu+Br&6Iz&W{0VS4-nW$NU zGZ}}G<*o_n~FP)sAI{!X%5>oeGfUWsAvkO;i&_afT~frT zWmo9+7%(Bm+l*SnqnCDoGgsitZgu@RBJ1WSTDzxuYVwduOjd#KX)U z=%46y^}7C@ud+FMQ>1D^@@H)~f`olKio+M{A94zC8W}CiKWkDXC~@%sF=(BaKP`;l zx(b`T-g*KF-7Ij7um-Sx&WzAUBul^4dzZ zJU-oacFCMx8T+LpCMq>tX#(*u4=>I7Fx&QEk|Z}E5D;aq;p@+#sm+hz-7$qfleNZI zh5Ps_&wqKN|I(sYEkWxV(##v713Wr+nX9&{L+fLAn3g(k`%tb@9>tR-{{g=~q2u0K z#V*u*RfPZw%@1?OtaQV~Qi^d0RrM=9SFLMCw3i?cmzQ;Hvlj;fzi$b)&1DO_c-SyK zM;Kqx4}&k9+)R}k{{Dr_AikQEhw4{+%1~t*cL_U1UpJIZ3caP44DJ|iNeK0VL(*?N zVMcp_vEMsYv)~PSnNlQaQ02i-A+Y(1C_)VZa>^voxLQbN>Dcvle9!5^eknM+0MvVs zN!jK3!l^<_o;u@_ZfEj12pAo>`j1DjszX%@-~WfA>o#f>HDVui#ToxG3*p_=HNAP! zvQpozs?eR}%b8B0h$P)hk}4?krwF0~A& z&7i@{#EvE`YO@_<5>Hg3z7za9nQU28Z-4wVY*bs1&c+%EkR%!QEQ0~POb8;8V8eMF z{0!mo14P5Gk6P_&yRp-wB=FOItu+Mr50M71feDF9XaLJ{!sRFGW(577+7;PgQd`}2 zT^YX;#8RpAt}Ct(@d#a{?62{W*RfW*nq=gXA~)JM^GhEJfC zu2*86jfc>4^LY804va(8dtghP33Xp&XILui&_U@xJURvL_?(!_PKCWwe z<5UvWydH5~^r#aB5`m@(3UofO(|lC}`@Z+_I`J@T5Rf;Rf&Dsupl(LF-{%+MB^8&H z_~C&Igy#>2hB9|~sIi9+2kL4&zs%?(hY%|(KZu|pNyyJmvfo4dVS=kgdVs=wf?s89 z!#c~+l-E3>HW6RvxBT~NEn(#WqNeGB$|A=7FI{-9>|lLZ2PWq2MKYW5=VD^^jZ0f0 zQ@`cgi6i_*oeP)wPNX;KxV;Ul9nhYvdk49NbkZentJA9Xn}H?l_dS%t3K{y4_|)@_ z`k@~0CpFm?9sm-N@rHXS0%ZN8(Cb1wDYt1y8lkk3c6YfByr$^C@>#ve{MlRMv~|Y= z{nO-1`l@St8R9K3im|$K$U04wYgezdD==`ZFR)~p;i_7X%T-XG-->9$>|V6uFN!;P zK>fm%G5U_V0cYrQJ-8+#P#y0^K8V;jR~!6Kn03I?Osip^sO0*ChwHS0L)E$^9E@)d zf2FRI*qsGWz-|6c#IT5+Gedb##JDHhUyuJZ9?=R#kU#`|W9lWC0;|^`9V{xig0WJ; zzg!mpoQAI`;~eGCN1-Y61wszF7#XyINXpkRpdvtA+Y3z)_yHVk{PvUi%Q!PtbBXQ+ zpinwmg#aWJ8#)1cV`l_Artp#pJJL7v$b2ae|b8TBLCJ*bD zpS0CfR1-wb>mz2ocom{89Rca3T2!dWkn`Qv&d#yp#iH@ zMtl*Xdb6p`XA&M0oZjHq+lLlH68&)=T~=+t*?nunMXp_LCBMIPq38l9Hv*R7$X9P` zm;D2hGktL7C1(3HYaAx4Tl1GuIxFr~%da~K&!Ugdsg(1^kz?P4hg9CFcSO$ceK-

d( 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 z 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

IoV}X5};r<`kaT}Cykt5wQZrL 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