diff --git a/lang/en-gb.xml b/lang/en-gb.xml
index 5ade102ba..50f9ec830 100644
--- a/lang/en-gb.xml
+++ b/lang/en-gb.xml
@@ -341,6 +341,7 @@ Do not power off the system or close the application.
By Type
Commercial
Homebrew
+ By Compatibility State
Ver
Cat
Comp
diff --git a/lang/en.xml b/lang/en.xml
index 5ade102ba..50f9ec830 100644
--- a/lang/en.xml
+++ b/lang/en.xml
@@ -341,6 +341,7 @@ Do not power off the system or close the application.
By Type
Commercial
Homebrew
+ By Compatibility State
Ver
Cat
Comp
diff --git a/lang/fr.xml b/lang/fr.xml
index e673a515c..e951e44fb 100644
--- a/lang/fr.xml
+++ b/lang/fr.xml
@@ -282,6 +282,26 @@ Ne pas éteindre le système, ni fermer l'application.
Données à supprimer :
+
+ Filtre
+ Trier les applications par
+ Toutes
+ Par région
+ USA
+ Europe
+ Japon
+ Asie
+ Par type
+ Commercial
+ Homebrew
+ Par état de compatibilité
+ Ver
+ Cat
+ Comp
+ Dernière fois
+ Rafraîchir
+
+
L'application a été ajoutée à l'écran d'accueil.
Supprimer tout
diff --git a/lang/ja.xml b/lang/ja.xml
index 363f1c8bc..9d5606d76 100644
--- a/lang/ja.xml
+++ b/lang/ja.xml
@@ -336,6 +336,7 @@ SDL2に対応したコントローラーを接続してください。種類
商用ゲーム
自作ゲーム
+ 互換性状態別
Ver
カテゴリー
互換性
diff --git a/vita3k/compat/include/compat/state.h b/vita3k/compat/include/compat/state.h
index 29416aec1..9c6cbc043 100644
--- a/vita3k/compat/include/compat/state.h
+++ b/vita3k/compat/include/compat/state.h
@@ -24,19 +24,19 @@
namespace compat {
enum CompatibilityState {
- Unknown = -1,
- Nothing,
- Bootable,
- Intro,
- Menu,
- Ingame_Less,
- Ingame_More,
- Playable,
+ UNKNOWN = -1,
+ NOTHING,
+ BOOTABLE,
+ INTRO,
+ MENU,
+ INGAME_LESS,
+ INGAME_MORE,
+ PLAYABLE,
};
struct Compatibility {
uint32_t issue_id;
- CompatibilityState state = Unknown;
+ CompatibilityState state = UNKNOWN;
time_t updated_at;
};
@@ -44,14 +44,14 @@ struct CompatState {
bool compat_db_loaded = false;
std::map app_compat_db;
std::map compat_color{
- { Unknown, ImVec4(0.54f, 0.54f, 0.54f, 1.f) },
- { Nothing, ImVec4(1.00f, 0.00f, 0.00f, 1.f) }, // #ff0000
- { Bootable, ImVec4(0.39f, 0.12f, 0.62f, 1.f) }, // #621fa5
- { Intro, ImVec4(0.77f, 0.08f, 0.52f, 1.f) }, // #c71585
- { Menu, ImVec4(0.11f, 0.46f, 0.85f, 1.f) }, // #1d76db
- { Ingame_Less, ImVec4(0.88f, 0.54f, 0.12f, 1.f) }, // #e08a1e
- { Ingame_More, ImVec4(1.00f, 0.84f, 0.00f, 1.f) }, // #ffd700
- { Playable, ImVec4(0.05f, 0.54f, 0.09f, 1.f) }, // #0e8a16
+ { UNKNOWN, ImVec4(0.54f, 0.54f, 0.54f, 1.f) },
+ { NOTHING, ImVec4(1.00f, 0.00f, 0.00f, 1.f) }, // #ff0000
+ { BOOTABLE, ImVec4(0.39f, 0.12f, 0.62f, 1.f) }, // #621fa5
+ { INTRO, ImVec4(0.77f, 0.08f, 0.52f, 1.f) }, // #c71585
+ { MENU, ImVec4(0.11f, 0.46f, 0.85f, 1.f) }, // #1d76db
+ { INGAME_LESS, ImVec4(0.88f, 0.54f, 0.12f, 1.f) }, // #e08a1e
+ { INGAME_MORE, ImVec4(1.00f, 0.84f, 0.00f, 1.f) }, // #ffd700
+ { PLAYABLE, ImVec4(0.05f, 0.54f, 0.09f, 1.f) }, // #0e8a16
};
};
diff --git a/vita3k/compat/src/compat.cpp b/vita3k/compat/src/compat.cpp
index 05705acc5..d024eb3f5 100644
--- a/vita3k/compat/src/compat.cpp
+++ b/vita3k/compat/src/compat.cpp
@@ -80,19 +80,19 @@ bool load_compat_app_db(GuiState &gui, EmuEnvState &emuenv) {
continue;
}
- auto state = CompatibilityState::Unknown;
+ auto state = CompatibilityState::UNKNOWN;
const auto labels = app.child("labels");
if (!labels.empty()) {
for (const auto &label : labels) {
const auto label_id = static_cast(label.text().as_uint());
switch (label_id) {
- case LabelIdState::Nothing: state = Nothing; break;
- case LabelIdState::Bootable: state = Bootable; break;
- case LabelIdState::Intro: state = Intro; break;
- case LabelIdState::Menu: state = Menu; break;
- case LabelIdState::Ingame_Less: state = Ingame_Less; break;
- case LabelIdState::Ingame_More: state = Ingame_More; break;
- case LabelIdState::Playable: state = Playable; break;
+ case LabelIdState::Nothing: state = NOTHING; break;
+ case LabelIdState::Bootable: state = BOOTABLE; break;
+ case LabelIdState::Intro: state = INTRO; break;
+ case LabelIdState::Menu: state = MENU; break;
+ case LabelIdState::Ingame_Less: state = INGAME_LESS; break;
+ case LabelIdState::Ingame_More: state = INGAME_MORE; break;
+ case LabelIdState::Playable: state = PLAYABLE; break;
default: break;
}
}
@@ -100,7 +100,7 @@ bool load_compat_app_db(GuiState &gui, EmuEnvState &emuenv) {
const auto updated_at = app.child("updated_at").text().as_llong();
// Check if app missing a status label
- if (state == Unknown)
+ if (state == UNKNOWN)
LOG_WARN("App with title ID {} has an issue but no status label. Please check GitHub issue {} and request a status label to be added.", title_id, issue_id);
// Check if app already exists in compatibility database
@@ -112,7 +112,7 @@ bool load_compat_app_db(GuiState &gui, EmuEnvState &emuenv) {
// Update compatibility status of all user apps
for (auto &app : gui.app_selector.user_apps)
- app.compat = gui.compat.app_compat_db.contains(app.title_id) ? gui.compat.app_compat_db[app.title_id].state : CompatibilityState::Unknown;
+ app.compat = gui.compat.app_compat_db.contains(app.title_id) ? gui.compat.app_compat_db[app.title_id].state : CompatibilityState::UNKNOWN;
return !gui.compat.app_compat_db.empty();
}
diff --git a/vita3k/gui/src/about_dialog.cpp b/vita3k/gui/src/about_dialog.cpp
index 655a2dbea..09380287a 100644
--- a/vita3k/gui/src/about_dialog.cpp
+++ b/vita3k/gui/src/about_dialog.cpp
@@ -47,7 +47,7 @@ static std::vector contributors_list = {
void draw_about_dialog(GuiState &gui, EmuEnvState &emuenv) {
const ImVec2 display_size(emuenv.viewport_size.x, emuenv.viewport_size.y);
const auto RES_SCALE = ImVec2(display_size.x / emuenv.res_width_dpi_scale, display_size.y / emuenv.res_height_dpi_scale);
-
+
auto lang = gui.lang.about;
ImGui::SetNextWindowPos(ImVec2(display_size.x / 2.f, display_size.y / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::Begin(lang["title"].c_str(), &gui.help_menu.about_dialog, ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize);
diff --git a/vita3k/gui/src/app_context_menu.cpp b/vita3k/gui/src/app_context_menu.cpp
index 5b8181228..3c950d6fb 100644
--- a/vita3k/gui/src/app_context_menu.cpp
+++ b/vita3k/gui/src/app_context_menu.cpp
@@ -297,9 +297,9 @@ void draw_app_context_menu(GuiState &gui, EmuEnvState &emuenv, const std::string
const auto is_commercial_app = title_id.find("PCS") != std::string::npos;
const auto has_state_report = gui.compat.compat_db_loaded ? gui.compat.app_compat_db.contains(title_id) : false;
- const auto compat_state = has_state_report ? gui.compat.app_compat_db[title_id].state : compat::Unknown;
+ const auto compat_state = has_state_report ? gui.compat.app_compat_db[title_id].state : compat::UNKNOWN;
const auto compat_state_color = gui.compat.compat_color[compat_state];
- const auto compat_state_str = has_state_report ? lang_compat.states[compat_state] : lang_compat.states[compat::Unknown];
+ const auto compat_state_str = has_state_report ? lang_compat.states[compat_state] : lang_compat.states[compat::UNKNOWN];
// App Context Menu
if (ImGui::BeginPopupContextItem("##app_context_menu")) {
diff --git a/vita3k/gui/src/gui.cpp b/vita3k/gui/src/gui.cpp
index e711f8c3a..87e6dd809 100644
--- a/vita3k/gui/src/gui.cpp
+++ b/vita3k/gui/src/gui.cpp
@@ -638,24 +638,23 @@ std::map get_date_time(GuiState &gui, EmuEnvState &emuenv
const auto days_str = gui.lang.common.mday[date_time.tm_mday];
const auto year = date_time.tm_year + 1900;
const auto month = date_time.tm_mon + 1;
- const auto days = date_time.tm_mday;
+ const auto day = date_time.tm_mday;
switch (emuenv.cfg.sys_date_format) {
case SCE_SYSTEM_PARAM_DATE_FORMAT_YYYYMMDD:
date_time_str[DateTime::DATE_DETAIL] = fmt::format("{} {} ({})", month_str, days_str, day_str);
- date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", year, month, days);
+ date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", year, month, day);
break;
case SCE_SYSTEM_PARAM_DATE_FORMAT_DDMMYYYY: {
const auto small_month_str = gui.lang.common.small_ymonth[date_time.tm_mon];
- const auto small_days_str = gui.lang.common.small_mday[date_time.tm_mon];
+ const auto small_days_str = gui.lang.common.small_mday[day];
date_time_str[DateTime::DATE_DETAIL] = fmt::format("{} {} ({})", small_days_str, small_month_str, day_str);
- date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", days, month, year);
+ date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", day, month, year);
break;
}
case SCE_SYSTEM_PARAM_DATE_FORMAT_MMDDYYYY:
date_time_str[DateTime::DATE_DETAIL] = fmt::format("{} {} ({})", month_str, days_str, day_str);
- date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", month, days, year);
+ date_time_str[DateTime::DATE_MINI] = fmt::format("{}/{}/{}", month, day, year);
break;
- default: break;
}
}
const auto is_afternoon = date_time.tm_hour > 12;
diff --git a/vita3k/gui/src/home_screen.cpp b/vita3k/gui/src/home_screen.cpp
index 4465f9c8a..cd306c94b 100644
--- a/vita3k/gui/src/home_screen.cpp
+++ b/vita3k/gui/src/home_screen.cpp
@@ -242,43 +242,48 @@ enum AppRegion {
HOMEBREW,
};
+constexpr compat::CompatibilityState ALL_COMPAT_STATE = static_cast(7);
+
static AppRegion app_region = ALL;
+static compat::CompatibilityState app_compat_state = ALL_COMPAT_STATE;
+
static bool app_filter(const std::string &app) {
- const auto filter_app_region = [&](const std::vector &app_region) {
- const auto app_region_index = std::find_if(app_region.begin(), app_region.end(), [&](const std::string &a) {
+ const auto filter_app = [&](const std::vector &app_region) {
+ const auto app_index = std::find_if(app_region.begin(), app_region.end(), [&](const std::string &a) {
return app.find(a) != std::string::npos;
});
- return app_region_index == app_region.end();
+ return app_index == app_region.end();
};
switch (app_region) {
case ALL:
break;
case USA:
- if (filter_app_region({ "PCSA", "PCSE" }))
+ if (filter_app({ "PCSA", "PCSE" }))
return true;
break;
case EURO:
- if (filter_app_region({ "PCSF", "PCSB" }))
+ if (filter_app({ "PCSF", "PCSB" }))
return true;
break;
case JAPAN:
- if (filter_app_region({ "PCSC", "PCSG" }))
+ if (filter_app({ "PCSC", "PCSG" }))
return true;
break;
case ASIA:
- if (filter_app_region({ "PCSD", "PCSH" }))
+ if (filter_app({ "PCSD", "PCSH" }))
return true;
break;
case COMMERCIAL:
- if (filter_app_region({ "PCS" }))
+ if (filter_app({ "PCS" }))
return true;
break;
case HOMEBREW:
- if (!filter_app_region({ "PCS" }))
+ if (!filter_app({ "PCS" }))
return true;
break;
}
+
return false;
}
@@ -528,11 +533,11 @@ void draw_home_screen(GuiState &gui, EmuEnvState &emuenv) {
}
}
if (ImGui::BeginPopup("app_filter")) {
+ ImGui::SetWindowFontScale(1.1f * VIEWPORT_RES_SCALE.x);
ImGui::PushStyleColor(ImGuiCol_Text, GUI_COLOR_TEXT);
- if (ImGui::MenuItem(lang["all"].c_str(), nullptr, app_region == ALL))
- app_region = ALL;
+ if (ImGui::MenuItem(lang["all"].c_str(), nullptr, app_region == ALL && app_compat_state == ALL_COMPAT_STATE))
+ app_region = AppRegion::ALL, app_compat_state = ALL_COMPAT_STATE;
if (ImGui::BeginMenu(lang["by_region"].c_str())) {
- ImGui::SetWindowFontScale(1.1f * VIEWPORT_RES_SCALE.x);
if (ImGui::MenuItem(lang["usa"].c_str(), nullptr, app_region == USA))
app_region = USA;
if (ImGui::MenuItem(lang["europe"].c_str(), nullptr, app_region == EURO))
@@ -550,6 +555,29 @@ void draw_home_screen(GuiState &gui, EmuEnvState &emuenv) {
app_region = HOMEBREW;
ImGui::EndMenu();
}
+ if (ImGui::BeginMenu(lang["by_compatibility_state"].c_str())) {
+ if (ImGui::MenuItem(lang["all"].c_str(), nullptr, app_compat_state == ALL_COMPAT_STATE))
+ app_compat_state = ALL_COMPAT_STATE;
+ auto lang_compat = gui.lang.compatibility.states;
+ if (ImGui::MenuItem(lang_compat[compat::UNKNOWN].c_str(), nullptr, app_compat_state == compat::UNKNOWN))
+ app_compat_state = compat::UNKNOWN;
+ if (ImGui::MenuItem(lang_compat[compat::NOTHING].c_str(), nullptr, app_compat_state == compat::NOTHING))
+ app_compat_state = compat::NOTHING;
+ if (ImGui::MenuItem(lang_compat[compat::BOOTABLE].c_str(), nullptr, app_compat_state == compat::BOOTABLE))
+ app_compat_state = compat::BOOTABLE;
+ if (ImGui::MenuItem(lang_compat[compat::INTRO].c_str(), nullptr, app_compat_state == compat::INTRO))
+ app_compat_state = compat::INTRO;
+ if (ImGui::MenuItem(lang_compat[compat::MENU].c_str(), nullptr, app_compat_state == compat::MENU))
+ app_compat_state = compat::MENU;
+ if (ImGui::MenuItem(lang_compat[compat::INGAME_LESS].c_str(), nullptr, app_compat_state == compat::INGAME_LESS))
+ app_compat_state = compat::INGAME_LESS;
+ if (ImGui::MenuItem(lang_compat[compat::INGAME_MORE].c_str(), nullptr, app_compat_state == compat::INGAME_MORE))
+ app_compat_state = compat::INGAME_MORE;
+ if (ImGui::MenuItem(lang_compat[compat::PLAYABLE].c_str(), nullptr, app_compat_state == compat::PLAYABLE))
+ app_compat_state = compat::PLAYABLE;
+
+ ImGui::EndMenu();
+ }
ImGui::PopStyleColor();
ImGui::EndPopup();
}
@@ -604,9 +632,15 @@ void draw_home_screen(GuiState &gui, EmuEnvState &emuenv) {
bool selected = false;
const auto is_not_sys_app = app.title_id.find("NPXS") == std::string::npos;
- // Filter app by region and type
- if (is_not_sys_app && app_filter(app.title_id))
- continue;
+ if (is_not_sys_app) {
+ // Filter app by region and type
+ if (app_filter(app.title_id))
+ continue;
+
+ // Filter commercial app by compatibility
+ if ((app_region != HOMEBREW) && (app_compat_state != ALL_COMPAT_STATE) && (app_compat_state != app.compat))
+ continue;
+ }
// Search app by title or title id
if (!gui.app_search_bar.PassFilter(app.title.c_str()) && !gui.app_search_bar.PassFilter(app.title_id.c_str()))
@@ -650,7 +684,7 @@ void draw_home_screen(GuiState &gui, EmuEnvState &emuenv) {
// Draw the compatibility badge for commercial apps when they are within the visible area.
if (element_is_within_visible_area && (app.title_id.find("PCS") != std::string::npos)) {
- const auto compat_state = (gui.compat.compat_db_loaded ? gui.compat.app_compat_db.contains(app.title_id) : false) ? gui.compat.app_compat_db[app.title_id].state : compat::Unknown;
+ const auto compat_state = (gui.compat.compat_db_loaded ? gui.compat.app_compat_db.contains(app.title_id) : false) ? gui.compat.app_compat_db[app.title_id].state : compat::UNKNOWN;
const auto compat_state_vec4 = gui.compat.compat_color[compat_state];
const ImU32 compat_state_color = IM_COL32((int)(compat_state_vec4.x * 255.0f), (int)(compat_state_vec4.y * 255.0f), (int)(compat_state_vec4.z * 255.0f), (int)(compat_state_vec4.w * 255.0f));
const auto current_pos = ImGui::GetCursorPos();
diff --git a/vita3k/gui/src/welcome_dialog.cpp b/vita3k/gui/src/welcome_dialog.cpp
index 53ae6515b..a6330457c 100644
--- a/vita3k/gui/src/welcome_dialog.cpp
+++ b/vita3k/gui/src/welcome_dialog.cpp
@@ -27,7 +27,7 @@ namespace gui {
void draw_welcome_dialog(GuiState &gui, EmuEnvState &emuenv) {
const ImVec2 display_size(emuenv.viewport_size.x, emuenv.viewport_size.y);
const auto RES_SCALE = ImVec2(display_size.x / emuenv.res_width_dpi_scale, display_size.y / emuenv.res_height_dpi_scale);
-
+
auto lang = gui.lang.welcome;
ImGui::SetNextWindowPos(ImVec2(display_size.x / 2.f, display_size.y / 2.f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::PushStyleColor(ImGuiCol_Text, GUI_COLOR_TEXT_MENUBAR);
diff --git a/vita3k/https/src/https.cpp b/vita3k/https/src/https.cpp
index 0dbf4c661..f76f50923 100644
--- a/vita3k/https/src/https.cpp
+++ b/vita3k/https/src/https.cpp
@@ -192,7 +192,7 @@ static Https init(const std::string url, const std::string method = "GET", const
return {};
}
- // Free address info and ssl ctx
+ // Free address info and ssl ctx
freeaddrinfo(result);
SSL_CTX_free(ctx);
@@ -409,7 +409,7 @@ bool download_file(std::string url, const std::string output_file_path, Progress
// Close the output file
outfile.close();
-
+
// Close SSL and socket connection
close_ssl(https.ssl);
close_socket(https.sockfd);
diff --git a/vita3k/lang/include/lang/state.h b/vita3k/lang/include/lang/state.h
index ccb68764c..5f6a378d6 100644
--- a/vita3k/lang/include/lang/state.h
+++ b/vita3k/lang/include/lang/state.h
@@ -175,14 +175,14 @@ struct LangState {
struct Compatibility {
std::string name = "Compatibility";
std::map states = {
- { compat::Unknown, "Unknown" },
- { compat::Nothing, "Nothing" },
- { compat::Bootable, "Bootable" },
- { compat::Intro, "Intro" },
- { compat::Menu, "Menu" },
- { compat::Ingame_Less, "Ingame -" },
- { compat::Ingame_More, "Ingame +" },
- { compat::Playable, "Playable" }
+ { compat::UNKNOWN, "Unknown" },
+ { compat::NOTHING, "Nothing" },
+ { compat::BOOTABLE, "Bootable" },
+ { compat::INTRO, "Intro" },
+ { compat::MENU, "Menu" },
+ { compat::INGAME_LESS, "Ingame -" },
+ { compat::INGAME_MORE, "Ingame +" },
+ { compat::PLAYABLE, "Playable" }
};
};
Compatibility compatibility;
@@ -272,6 +272,7 @@ struct LangState {
{ "by_type", "By Type" },
{ "commercial", "Commercial" },
{ "homebrew", "Homebrew" },
+ { "by_compatibility_state", "By Compatibility State" },
{ "ver", "Ver" },
{ "cat", "Cat" },
{ "comp", "Comp" },