diff --git a/src/Application.cpp b/src/Application.cpp index 755f17a..76b73ca 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -1823,6 +1823,25 @@ void Application::aboutDialog() ::aboutDialog(_logger.contents().c_str()); } +static void buildSystemMenu(HMENU parentMenu, int system, std::string systemName) +{ + std::set systemCores; + getAvailableSystemCores(system, systemCores); + + std::map systemItems; + for (const auto& systemCore : systemCores) + { + int id = encodeCoreName(systemCore, system); + systemItems.emplace(getEmulatorName(systemCore, system), id); + } + + HMENU systemMenu = CreateMenu(); + for (const auto& systemItem : systemItems) + AppendMenu(systemMenu, MF_STRING, IDM_SYSTEM_FIRST + systemItem.second, systemItem.first.c_str()); + + AppendMenu(parentMenu, MF_POPUP | MF_STRING, (UINT_PTR)systemMenu, systemName.c_str()); +} + void Application::buildSystemsMenu() { std::set availableSystems; @@ -1833,9 +1852,14 @@ void Application::buildSystemsMenu() // use map to sort labels std::set systemCores; std::map systemMap; - std::map systemItems; + for (auto system : availableSystems) - systemMap.emplace(getSystemName(system), system); + { + systemCores.clear(); + getAvailableSystemCores(system, systemCores); + if (!systemCores.empty()) + systemMap.emplace(getSystemName(system), system); + } HMENU fileMenu = GetSubMenu(_menu, 0); HMENU systemsMenu = GetSubMenu(fileMenu, 0); @@ -1843,26 +1867,40 @@ void Application::buildSystemsMenu() while (GetMenuItemCount(systemsMenu) > 0) DeleteMenu(systemsMenu, 0, MF_BYPOSITION); - for (const auto& pair : systemMap) + if (systemMap.size() > 20) { - int system = pair.second; - systemCores.clear(); - getAvailableSystemCores(system, systemCores); - if (systemCores.empty()) - continue; - - systemItems.clear(); - for (const auto& systemCore : systemCores) + std::map> manufacturerMap; + for (const auto& pair : systemMap) { - int id = encodeCoreName(systemCore, pair.second); - systemItems.emplace(getEmulatorName(systemCore, system), id); + int system = pair.second; + std::string manufacturer = getSystemManufacturer(system); + manufacturerMap[manufacturer].push_back(system); } - HMENU systemMenu = CreateMenu(); - for (const auto& systemItem : systemItems) - AppendMenu(systemMenu, MF_STRING, IDM_SYSTEM_FIRST + systemItem.second, systemItem.first.c_str()); + for (const auto& pair : manufacturerMap) + { + HMENU manufacturerMenu = CreateMenu(); + + for (const auto& systemPair : systemMap) + { + int system = systemPair.second; + for (const auto manufacturerSystem : pair.second) + { + if (manufacturerSystem == system) + { + buildSystemMenu(manufacturerMenu, system, systemPair.first); + break; + } + } + } - AppendMenu(systemsMenu, MF_POPUP | MF_STRING, (UINT_PTR)systemMenu, pair.first.c_str()); + AppendMenu(systemsMenu, MF_POPUP | MF_STRING, (UINT_PTR)manufacturerMenu, pair.first.c_str()); + } + } + else + { + for (const auto& pair : systemMap) + buildSystemMenu(systemsMenu, pair.second, pair.first); } } diff --git a/src/Emulator.cpp b/src/Emulator.cpp index 7ce1a07..00acddc 100644 --- a/src/Emulator.cpp +++ b/src/Emulator.cpp @@ -300,6 +300,62 @@ const char* getSystemName(int system) return rc_console_name(system); } +const char* getSystemManufacturer(int system) +{ + switch (system) + { + case RC_CONSOLE_GAMEBOY: + case RC_CONSOLE_GAMEBOY_COLOR: + case RC_CONSOLE_GAMEBOY_ADVANCE: + case RC_CONSOLE_NINTENDO: + case RC_CONSOLE_SUPER_NINTENDO: + case RC_CONSOLE_NINTENDO_64: + case RC_CONSOLE_NINTENDO_DS: + case RC_CONSOLE_NINTENDO_3DS: + case RC_CONSOLE_POKEMON_MINI: + case RC_CONSOLE_VIRTUAL_BOY: + case RC_CONSOLE_WII: + case RC_CONSOLE_WII_U: + return "Nintendo"; + + case RC_CONSOLE_PLAYSTATION: + case RC_CONSOLE_PLAYSTATION_2: + case RC_CONSOLE_PSP: + return "Sony"; + + case RC_CONSOLE_ATARI_2600: + case RC_CONSOLE_ATARI_5200: + case RC_CONSOLE_ATARI_7800: + case RC_CONSOLE_ATARI_JAGUAR: + case RC_CONSOLE_ATARI_JAGUAR_CD: + case RC_CONSOLE_ATARI_LYNX: + case RC_CONSOLE_ATARI_ST: + return "Atari"; + + case RC_CONSOLE_PC_ENGINE: + case RC_CONSOLE_PC_ENGINE_CD: + case RC_CONSOLE_PC6000: + case RC_CONSOLE_PC8800: + case RC_CONSOLE_PC9800: + case RC_CONSOLE_PCFX: + return "NEC"; + + case RC_CONSOLE_SG1000: + case RC_CONSOLE_MASTER_SYSTEM: + case RC_CONSOLE_GAME_GEAR: + case RC_CONSOLE_MEGA_DRIVE: + case RC_CONSOLE_PICO: + case RC_CONSOLE_SEGA_32X: + case RC_CONSOLE_SEGA_CD: + case RC_CONSOLE_SATURN: + case RC_CONSOLE_DREAMCAST: + return "Sega"; + + default: + return "Other"; + } +} + #ifdef _WINDOWS class CoreDialog : public Dialog diff --git a/src/Emulator.h b/src/Emulator.h index 5a7aa8f..04919a1 100644 --- a/src/Emulator.h +++ b/src/Emulator.h @@ -27,6 +27,7 @@ along with RALibretro. If not, see . const std::string& getEmulatorName(const std::string& coreName, int system); const char* getEmulatorExtensions(const std::string& coreName, int system); const char* getSystemName(int system); +const char* getSystemManufacturer(int system); class Config; class Logger;