diff options
| author | 2018-01-11 19:21:20 -0700 | |
|---|---|---|
| committer | 2018-01-12 19:11:03 -0700 | |
| commit | ebf9a784a9f7f4148a669dbb39e7cd50df779a14 (patch) | |
| tree | d585685a1c0a34b903af1d086d62560bf56bb29f /src/yuzu_cmd | |
| parent | config: Default CPU core to Unicorn. (diff) | |
| download | yuzu-ebf9a784a9f7f4148a669dbb39e7cd50df779a14.tar.gz yuzu-ebf9a784a9f7f4148a669dbb39e7cd50df779a14.tar.xz yuzu-ebf9a784a9f7f4148a669dbb39e7cd50df779a14.zip | |
Massive removal of unused modules
Diffstat (limited to 'src/yuzu_cmd')
| -rw-r--r-- | src/yuzu_cmd/CMakeLists.txt | 35 | ||||
| -rw-r--r-- | src/yuzu_cmd/citra.cpp | 175 | ||||
| -rw-r--r-- | src/yuzu_cmd/citra.rc | 17 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.cpp | 160 | ||||
| -rw-r--r-- | src/yuzu_cmd/config.h | 24 | ||||
| -rw-r--r-- | src/yuzu_cmd/default_ini.h | 179 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | 177 | ||||
| -rw-r--r-- | src/yuzu_cmd/emu_window/emu_window_sdl2.h | 59 | ||||
| -rw-r--r-- | src/yuzu_cmd/resource.h | 16 |
9 files changed, 842 insertions, 0 deletions
diff --git a/src/yuzu_cmd/CMakeLists.txt b/src/yuzu_cmd/CMakeLists.txt new file mode 100644 index 000000000..c6c527eb6 --- /dev/null +++ b/src/yuzu_cmd/CMakeLists.txt | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/CMakeModules) | ||
| 2 | |||
| 3 | set(SRCS | ||
| 4 | emu_window/emu_window_sdl2.cpp | ||
| 5 | citra.cpp | ||
| 6 | config.cpp | ||
| 7 | citra.rc | ||
| 8 | ) | ||
| 9 | set(HEADERS | ||
| 10 | emu_window/emu_window_sdl2.h | ||
| 11 | config.h | ||
| 12 | default_ini.h | ||
| 13 | resource.h | ||
| 14 | ) | ||
| 15 | |||
| 16 | create_directory_groups(${SRCS} ${HEADERS}) | ||
| 17 | |||
| 18 | add_executable(yuzu-cmd ${SRCS} ${HEADERS}) | ||
| 19 | target_link_libraries(yuzu-cmd PRIVATE common core input_common) | ||
| 20 | target_link_libraries(yuzu-cmd PRIVATE inih glad) | ||
| 21 | if (MSVC) | ||
| 22 | target_link_libraries(yuzu-cmd PRIVATE getopt) | ||
| 23 | endif() | ||
| 24 | target_link_libraries(yuzu-cmd PRIVATE ${PLATFORM_LIBRARIES} SDL2 Threads::Threads) | ||
| 25 | |||
| 26 | if(UNIX AND NOT APPLE) | ||
| 27 | install(TARGETS yuzu-cmd RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}/bin") | ||
| 28 | endif() | ||
| 29 | |||
| 30 | if (MSVC) | ||
| 31 | include(CopyCitraSDLDeps) | ||
| 32 | include(CopyYuzuUnicornDeps) | ||
| 33 | copy_citra_SDL_deps(yuzu-cmd) | ||
| 34 | copy_yuzu_unicorn_deps(yuzu-cmd) | ||
| 35 | endif() | ||
diff --git a/src/yuzu_cmd/citra.cpp b/src/yuzu_cmd/citra.cpp new file mode 100644 index 000000000..e524c5535 --- /dev/null +++ b/src/yuzu_cmd/citra.cpp | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <iostream> | ||
| 6 | #include <memory> | ||
| 7 | #include <string> | ||
| 8 | #include <thread> | ||
| 9 | |||
| 10 | // This needs to be included before getopt.h because the latter #defines symbols used by it | ||
| 11 | #include "common/microprofile.h" | ||
| 12 | |||
| 13 | #ifdef _MSC_VER | ||
| 14 | #include <getopt.h> | ||
| 15 | #else | ||
| 16 | #include <getopt.h> | ||
| 17 | #include <unistd.h> | ||
| 18 | #endif | ||
| 19 | |||
| 20 | #ifdef _WIN32 | ||
| 21 | // windows.h needs to be included before shellapi.h | ||
| 22 | #include <windows.h> | ||
| 23 | |||
| 24 | #include <shellapi.h> | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #include "citra/config.h" | ||
| 28 | #include "citra/emu_window/emu_window_sdl2.h" | ||
| 29 | #include "common/logging/backend.h" | ||
| 30 | #include "common/logging/filter.h" | ||
| 31 | #include "common/logging/log.h" | ||
| 32 | #include "common/scm_rev.h" | ||
| 33 | #include "common/scope_exit.h" | ||
| 34 | #include "common/string_util.h" | ||
| 35 | #include "core/core.h" | ||
| 36 | #include "core/gdbstub/gdbstub.h" | ||
| 37 | #include "core/loader/loader.h" | ||
| 38 | #include "core/settings.h" | ||
| 39 | |||
| 40 | static void PrintHelp(const char* argv0) { | ||
| 41 | std::cout << "Usage: " << argv0 | ||
| 42 | << " [options] <filename>\n" | ||
| 43 | "-g, --gdbport=NUMBER Enable gdb stub on port NUMBER\n" | ||
| 44 | "-h, --help Display this help and exit\n" | ||
| 45 | "-v, --version Output version information and exit\n"; | ||
| 46 | } | ||
| 47 | |||
| 48 | static void PrintVersion() { | ||
| 49 | std::cout << "Citra " << Common::g_scm_branch << " " << Common::g_scm_desc << std::endl; | ||
| 50 | } | ||
| 51 | |||
| 52 | /// Application entry point | ||
| 53 | int main(int argc, char** argv) { | ||
| 54 | Config config; | ||
| 55 | int option_index = 0; | ||
| 56 | bool use_gdbstub = Settings::values.use_gdbstub; | ||
| 57 | u32 gdb_port = static_cast<u32>(Settings::values.gdbstub_port); | ||
| 58 | char* endarg; | ||
| 59 | #ifdef _WIN32 | ||
| 60 | int argc_w; | ||
| 61 | auto argv_w = CommandLineToArgvW(GetCommandLineW(), &argc_w); | ||
| 62 | |||
| 63 | if (argv_w == nullptr) { | ||
| 64 | LOG_CRITICAL(Frontend, "Failed to get command line arguments"); | ||
| 65 | return -1; | ||
| 66 | } | ||
| 67 | #endif | ||
| 68 | std::string filepath; | ||
| 69 | |||
| 70 | static struct option long_options[] = { | ||
| 71 | {"gdbport", required_argument, 0, 'g'}, | ||
| 72 | {"help", no_argument, 0, 'h'}, | ||
| 73 | {"version", no_argument, 0, 'v'}, | ||
| 74 | {0, 0, 0, 0}, | ||
| 75 | }; | ||
| 76 | |||
| 77 | while (optind < argc) { | ||
| 78 | char arg = getopt_long(argc, argv, "g:hv", long_options, &option_index); | ||
| 79 | if (arg != -1) { | ||
| 80 | switch (arg) { | ||
| 81 | case 'g': | ||
| 82 | errno = 0; | ||
| 83 | gdb_port = strtoul(optarg, &endarg, 0); | ||
| 84 | use_gdbstub = true; | ||
| 85 | if (endarg == optarg) | ||
| 86 | errno = EINVAL; | ||
| 87 | if (errno != 0) { | ||
| 88 | perror("--gdbport"); | ||
| 89 | exit(1); | ||
| 90 | } | ||
| 91 | break; | ||
| 92 | case 'h': | ||
| 93 | PrintHelp(argv[0]); | ||
| 94 | return 0; | ||
| 95 | case 'v': | ||
| 96 | PrintVersion(); | ||
| 97 | return 0; | ||
| 98 | } | ||
| 99 | } else { | ||
| 100 | #ifdef _WIN32 | ||
| 101 | filepath = Common::UTF16ToUTF8(argv_w[optind]); | ||
| 102 | #else | ||
| 103 | filepath = argv[optind]; | ||
| 104 | #endif | ||
| 105 | optind++; | ||
| 106 | } | ||
| 107 | } | ||
| 108 | |||
| 109 | #ifdef _WIN32 | ||
| 110 | LocalFree(argv_w); | ||
| 111 | #endif | ||
| 112 | |||
| 113 | Log::Filter log_filter(Log::Level::Debug); | ||
| 114 | Log::SetFilter(&log_filter); | ||
| 115 | |||
| 116 | MicroProfileOnThreadCreate("EmuThread"); | ||
| 117 | SCOPE_EXIT({ MicroProfileShutdown(); }); | ||
| 118 | |||
| 119 | if (filepath.empty()) { | ||
| 120 | LOG_CRITICAL(Frontend, "Failed to load ROM: No ROM specified"); | ||
| 121 | return -1; | ||
| 122 | } | ||
| 123 | |||
| 124 | log_filter.ParseFilterString(Settings::values.log_filter); | ||
| 125 | |||
| 126 | // Apply the command line arguments | ||
| 127 | Settings::values.gdbstub_port = gdb_port; | ||
| 128 | Settings::values.use_gdbstub = use_gdbstub; | ||
| 129 | Settings::Apply(); | ||
| 130 | |||
| 131 | std::unique_ptr<EmuWindow_SDL2> emu_window{std::make_unique<EmuWindow_SDL2>()}; | ||
| 132 | |||
| 133 | Core::System& system{Core::System::GetInstance()}; | ||
| 134 | |||
| 135 | SCOPE_EXIT({ system.Shutdown(); }); | ||
| 136 | |||
| 137 | const Core::System::ResultStatus load_result{system.Load(emu_window.get(), filepath)}; | ||
| 138 | |||
| 139 | switch (load_result) { | ||
| 140 | case Core::System::ResultStatus::ErrorGetLoader: | ||
| 141 | LOG_CRITICAL(Frontend, "Failed to obtain loader for %s!", filepath.c_str()); | ||
| 142 | return -1; | ||
| 143 | case Core::System::ResultStatus::ErrorLoader: | ||
| 144 | LOG_CRITICAL(Frontend, "Failed to load ROM!"); | ||
| 145 | return -1; | ||
| 146 | case Core::System::ResultStatus::ErrorLoader_ErrorEncrypted: | ||
| 147 | LOG_CRITICAL(Frontend, "The game that you are trying to load must be decrypted before " | ||
| 148 | "being used with Citra. \n\n For more information on dumping and " | ||
| 149 | "decrypting games, please refer to: " | ||
| 150 | "https://citra-emu.org/wiki/dumping-game-cartridges/"); | ||
| 151 | return -1; | ||
| 152 | case Core::System::ResultStatus::ErrorLoader_ErrorInvalidFormat: | ||
| 153 | LOG_CRITICAL(Frontend, "Error while loading ROM: The ROM format is not supported."); | ||
| 154 | return -1; | ||
| 155 | case Core::System::ResultStatus::ErrorNotInitialized: | ||
| 156 | LOG_CRITICAL(Frontend, "CPUCore not initialized"); | ||
| 157 | return -1; | ||
| 158 | case Core::System::ResultStatus::ErrorSystemMode: | ||
| 159 | LOG_CRITICAL(Frontend, "Failed to determine system mode!"); | ||
| 160 | return -1; | ||
| 161 | case Core::System::ResultStatus::ErrorVideoCore: | ||
| 162 | LOG_CRITICAL(Frontend, "VideoCore not initialized"); | ||
| 163 | return -1; | ||
| 164 | case Core::System::ResultStatus::Success: | ||
| 165 | break; // Expected case | ||
| 166 | } | ||
| 167 | |||
| 168 | Core::Telemetry().AddField(Telemetry::FieldType::App, "Frontend", "SDL"); | ||
| 169 | |||
| 170 | while (emu_window->IsOpen()) { | ||
| 171 | system.RunLoop(); | ||
| 172 | } | ||
| 173 | |||
| 174 | return 0; | ||
| 175 | } | ||
diff --git a/src/yuzu_cmd/citra.rc b/src/yuzu_cmd/citra.rc new file mode 100644 index 000000000..c490ef302 --- /dev/null +++ b/src/yuzu_cmd/citra.rc | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | #include "winresrc.h" | ||
| 2 | ///////////////////////////////////////////////////////////////////////////// | ||
| 3 | // | ||
| 4 | // Icon | ||
| 5 | // | ||
| 6 | |||
| 7 | // Icon with lowest ID value placed first to ensure application icon | ||
| 8 | // remains consistent on all systems. | ||
| 9 | CITRA_ICON ICON "../../dist/citra.ico" | ||
| 10 | |||
| 11 | |||
| 12 | ///////////////////////////////////////////////////////////////////////////// | ||
| 13 | // | ||
| 14 | // RT_MANIFEST | ||
| 15 | // | ||
| 16 | |||
| 17 | 1 RT_MANIFEST "../../dist/citra.manifest" | ||
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp new file mode 100644 index 000000000..94d1a9f1c --- /dev/null +++ b/src/yuzu_cmd/config.cpp | |||
| @@ -0,0 +1,160 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | #include <SDL.h> | ||
| 7 | #include <inih/cpp/INIReader.h> | ||
| 8 | #include "citra/config.h" | ||
| 9 | #include "citra/default_ini.h" | ||
| 10 | #include "common/file_util.h" | ||
| 11 | #include "common/logging/log.h" | ||
| 12 | #include "common/param_package.h" | ||
| 13 | #include "core/settings.h" | ||
| 14 | #include "input_common/main.h" | ||
| 15 | |||
| 16 | Config::Config() { | ||
| 17 | // TODO: Don't hardcode the path; let the frontend decide where to put the config files. | ||
| 18 | sdl2_config_loc = FileUtil::GetUserPath(D_CONFIG_IDX) + "sdl2-config.ini"; | ||
| 19 | sdl2_config = std::make_unique<INIReader>(sdl2_config_loc); | ||
| 20 | |||
| 21 | Reload(); | ||
| 22 | } | ||
| 23 | |||
| 24 | Config::~Config() = default; | ||
| 25 | |||
| 26 | bool Config::LoadINI(const std::string& default_contents, bool retry) { | ||
| 27 | const char* location = this->sdl2_config_loc.c_str(); | ||
| 28 | if (sdl2_config->ParseError() < 0) { | ||
| 29 | if (retry) { | ||
| 30 | LOG_WARNING(Config, "Failed to load %s. Creating file from defaults...", location); | ||
| 31 | FileUtil::CreateFullPath(location); | ||
| 32 | FileUtil::WriteStringToFile(true, default_contents, location); | ||
| 33 | sdl2_config = std::make_unique<INIReader>(location); // Reopen file | ||
| 34 | |||
| 35 | return LoadINI(default_contents, false); | ||
| 36 | } | ||
| 37 | LOG_ERROR(Config, "Failed."); | ||
| 38 | return false; | ||
| 39 | } | ||
| 40 | LOG_INFO(Config, "Successfully loaded %s", location); | ||
| 41 | return true; | ||
| 42 | } | ||
| 43 | |||
| 44 | static const std::array<int, Settings::NativeButton::NumButtons> default_buttons = { | ||
| 45 | SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, | ||
| 46 | SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, | ||
| 47 | SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, | ||
| 48 | }; | ||
| 49 | |||
| 50 | static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs{{ | ||
| 51 | { | ||
| 52 | SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SDL_SCANCODE_D, | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | SDL_SCANCODE_I, SDL_SCANCODE_K, SDL_SCANCODE_J, SDL_SCANCODE_L, SDL_SCANCODE_D, | ||
| 56 | }, | ||
| 57 | }}; | ||
| 58 | |||
| 59 | void Config::ReadValues() { | ||
| 60 | // Controls | ||
| 61 | for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { | ||
| 62 | std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); | ||
| 63 | Settings::values.buttons[i] = | ||
| 64 | sdl2_config->Get("Controls", Settings::NativeButton::mapping[i], default_param); | ||
| 65 | if (Settings::values.buttons[i].empty()) | ||
| 66 | Settings::values.buttons[i] = default_param; | ||
| 67 | } | ||
| 68 | |||
| 69 | for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { | ||
| 70 | std::string default_param = InputCommon::GenerateAnalogParamFromKeys( | ||
| 71 | default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], | ||
| 72 | default_analogs[i][3], default_analogs[i][4], 0.5f); | ||
| 73 | Settings::values.analogs[i] = | ||
| 74 | sdl2_config->Get("Controls", Settings::NativeAnalog::mapping[i], default_param); | ||
| 75 | if (Settings::values.analogs[i].empty()) | ||
| 76 | Settings::values.analogs[i] = default_param; | ||
| 77 | } | ||
| 78 | |||
| 79 | Settings::values.motion_device = sdl2_config->Get( | ||
| 80 | "Controls", "motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01"); | ||
| 81 | Settings::values.touch_device = | ||
| 82 | sdl2_config->Get("Controls", "touch_device", "engine:emu_window"); | ||
| 83 | |||
| 84 | // Core | ||
| 85 | Settings::values.cpu_core = | ||
| 86 | static_cast<Settings::CpuCore>(sdl2_config->GetInteger("Core", "cpu_core", 0)); | ||
| 87 | |||
| 88 | // Renderer | ||
| 89 | Settings::values.use_hw_renderer = sdl2_config->GetBoolean("Renderer", "use_hw_renderer", true); | ||
| 90 | Settings::values.use_shader_jit = sdl2_config->GetBoolean("Renderer", "use_shader_jit", true); | ||
| 91 | Settings::values.resolution_factor = | ||
| 92 | (float)sdl2_config->GetReal("Renderer", "resolution_factor", 1.0); | ||
| 93 | Settings::values.use_vsync = sdl2_config->GetBoolean("Renderer", "use_vsync", false); | ||
| 94 | Settings::values.toggle_framelimit = | ||
| 95 | sdl2_config->GetBoolean("Renderer", "toggle_framelimit", true); | ||
| 96 | |||
| 97 | Settings::values.bg_red = (float)sdl2_config->GetReal("Renderer", "bg_red", 0.0); | ||
| 98 | Settings::values.bg_green = (float)sdl2_config->GetReal("Renderer", "bg_green", 0.0); | ||
| 99 | Settings::values.bg_blue = (float)sdl2_config->GetReal("Renderer", "bg_blue", 0.0); | ||
| 100 | |||
| 101 | // Layout | ||
| 102 | Settings::values.layout_option = | ||
| 103 | static_cast<Settings::LayoutOption>(sdl2_config->GetInteger("Layout", "layout_option", 0)); | ||
| 104 | Settings::values.swap_screen = sdl2_config->GetBoolean("Layout", "swap_screen", false); | ||
| 105 | Settings::values.custom_layout = sdl2_config->GetBoolean("Layout", "custom_layout", false); | ||
| 106 | Settings::values.custom_top_left = | ||
| 107 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_left", 0)); | ||
| 108 | Settings::values.custom_top_top = | ||
| 109 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_top", 0)); | ||
| 110 | Settings::values.custom_top_right = | ||
| 111 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_right", 400)); | ||
| 112 | Settings::values.custom_top_bottom = | ||
| 113 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_top_bottom", 240)); | ||
| 114 | Settings::values.custom_bottom_left = | ||
| 115 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_left", 40)); | ||
| 116 | Settings::values.custom_bottom_top = | ||
| 117 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_top", 240)); | ||
| 118 | Settings::values.custom_bottom_right = | ||
| 119 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_right", 360)); | ||
| 120 | Settings::values.custom_bottom_bottom = | ||
| 121 | static_cast<u16>(sdl2_config->GetInteger("Layout", "custom_bottom_bottom", 480)); | ||
| 122 | |||
| 123 | // Audio | ||
| 124 | Settings::values.sink_id = sdl2_config->Get("Audio", "output_engine", "auto"); | ||
| 125 | Settings::values.enable_audio_stretching = | ||
| 126 | sdl2_config->GetBoolean("Audio", "enable_audio_stretching", true); | ||
| 127 | Settings::values.audio_device_id = sdl2_config->Get("Audio", "output_device", "auto"); | ||
| 128 | |||
| 129 | // Data Storage | ||
| 130 | Settings::values.use_virtual_sd = | ||
| 131 | sdl2_config->GetBoolean("Data Storage", "use_virtual_sd", true); | ||
| 132 | |||
| 133 | // System | ||
| 134 | Settings::values.is_new_3ds = sdl2_config->GetBoolean("System", "is_new_3ds", false); | ||
| 135 | Settings::values.region_value = | ||
| 136 | sdl2_config->GetInteger("System", "region_value", Settings::REGION_VALUE_AUTO_SELECT); | ||
| 137 | |||
| 138 | // Miscellaneous | ||
| 139 | Settings::values.log_filter = sdl2_config->Get("Miscellaneous", "log_filter", "*:Info"); | ||
| 140 | |||
| 141 | // Debugging | ||
| 142 | Settings::values.use_gdbstub = sdl2_config->GetBoolean("Debugging", "use_gdbstub", false); | ||
| 143 | Settings::values.gdbstub_port = | ||
| 144 | static_cast<u16>(sdl2_config->GetInteger("Debugging", "gdbstub_port", 24689)); | ||
| 145 | |||
| 146 | // Web Service | ||
| 147 | Settings::values.enable_telemetry = | ||
| 148 | sdl2_config->GetBoolean("WebService", "enable_telemetry", true); | ||
| 149 | Settings::values.telemetry_endpoint_url = sdl2_config->Get( | ||
| 150 | "WebService", "telemetry_endpoint_url", "https://services.citra-emu.org/api/telemetry"); | ||
| 151 | Settings::values.verify_endpoint_url = sdl2_config->Get( | ||
| 152 | "WebService", "verify_endpoint_url", "https://services.citra-emu.org/api/profile"); | ||
| 153 | Settings::values.citra_username = sdl2_config->Get("WebService", "citra_username", ""); | ||
| 154 | Settings::values.citra_token = sdl2_config->Get("WebService", "citra_token", ""); | ||
| 155 | } | ||
| 156 | |||
| 157 | void Config::Reload() { | ||
| 158 | LoadINI(DefaultINI::sdl2_config_file); | ||
| 159 | ReadValues(); | ||
| 160 | } | ||
diff --git a/src/yuzu_cmd/config.h b/src/yuzu_cmd/config.h new file mode 100644 index 000000000..abc90f642 --- /dev/null +++ b/src/yuzu_cmd/config.h | |||
| @@ -0,0 +1,24 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | |||
| 10 | class INIReader; | ||
| 11 | |||
| 12 | class Config { | ||
| 13 | std::unique_ptr<INIReader> sdl2_config; | ||
| 14 | std::string sdl2_config_loc; | ||
| 15 | |||
| 16 | bool LoadINI(const std::string& default_contents = "", bool retry = true); | ||
| 17 | void ReadValues(); | ||
| 18 | |||
| 19 | public: | ||
| 20 | Config(); | ||
| 21 | ~Config(); | ||
| 22 | |||
| 23 | void Reload(); | ||
| 24 | }; | ||
diff --git a/src/yuzu_cmd/default_ini.h b/src/yuzu_cmd/default_ini.h new file mode 100644 index 000000000..b7b8abe1e --- /dev/null +++ b/src/yuzu_cmd/default_ini.h | |||
| @@ -0,0 +1,179 @@ | |||
| 1 | // Copyright 2014 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | namespace DefaultINI { | ||
| 8 | |||
| 9 | const char* sdl2_config_file = R"( | ||
| 10 | [Controls] | ||
| 11 | # The input devices and parameters for each 3DS native input | ||
| 12 | # It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." | ||
| 13 | # Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values | ||
| 14 | |||
| 15 | # for button input, the following devices are available: | ||
| 16 | # - "keyboard" (default) for keyboard input. Required parameters: | ||
| 17 | # - "code": the code of the key to bind | ||
| 18 | # - "sdl" for joystick input using SDL. Required parameters: | ||
| 19 | # - "joystick": the index of the joystick to bind | ||
| 20 | # - "button"(optional): the index of the button to bind | ||
| 21 | # - "hat"(optional): the index of the hat to bind as direction buttons | ||
| 22 | # - "axis"(optional): the index of the axis to bind | ||
| 23 | # - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right" | ||
| 24 | # - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is | ||
| 25 | # triggered if the axis value crosses | ||
| 26 | # - "direction"(only used for axis): "+" means the button is triggered when the axis value | ||
| 27 | # is greater than the threshold; "-" means the button is triggered when the axis value | ||
| 28 | # is smaller than the threshold | ||
| 29 | button_a= | ||
| 30 | button_b= | ||
| 31 | button_x= | ||
| 32 | button_y= | ||
| 33 | button_up= | ||
| 34 | button_down= | ||
| 35 | button_left= | ||
| 36 | button_right= | ||
| 37 | button_l= | ||
| 38 | button_r= | ||
| 39 | button_start= | ||
| 40 | button_select= | ||
| 41 | button_zl= | ||
| 42 | button_zr= | ||
| 43 | button_home= | ||
| 44 | |||
| 45 | # for analog input, the following devices are available: | ||
| 46 | # - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters: | ||
| 47 | # - "up", "down", "left", "right": sub-devices for each direction. | ||
| 48 | # Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00" | ||
| 49 | # - "modifier": sub-devices as a modifier. | ||
| 50 | # - "modifier_scale": a float number representing the applied modifier scale to the analog input. | ||
| 51 | # Must be in range of 0.0-1.0. Defaults to 0.5 | ||
| 52 | # - "sdl" for joystick input using SDL. Required parameters: | ||
| 53 | # - "joystick": the index of the joystick to bind | ||
| 54 | # - "axis_x": the index of the axis to bind as x-axis (default to 0) | ||
| 55 | # - "axis_y": the index of the axis to bind as y-axis (default to 1) | ||
| 56 | circle_pad= | ||
| 57 | c_stick= | ||
| 58 | |||
| 59 | # for motion input, the following devices are available: | ||
| 60 | # - "motion_emu" (default) for emulating motion input from mouse input. Required parameters: | ||
| 61 | # - "update_period": update period in milliseconds (default to 100) | ||
| 62 | # - "sensitivity": the coefficient converting mouse movement to tilting angle (default to 0.01) | ||
| 63 | motion_device= | ||
| 64 | |||
| 65 | # for touch input, the following devices are available: | ||
| 66 | # - "emu_window" (default) for emulating touch input from mouse input to the emulation window. No parameters required | ||
| 67 | touch_device= | ||
| 68 | |||
| 69 | [Core] | ||
| 70 | # Which CPU core to use for CPU emulation | ||
| 71 | # 0 (default): Unicorn (slow), 1: Dynarmic (faster) | ||
| 72 | cpu_core = | ||
| 73 | |||
| 74 | [Renderer] | ||
| 75 | # Whether to use software or hardware rendering. | ||
| 76 | # 0: Software, 1 (default): Hardware | ||
| 77 | use_hw_renderer = | ||
| 78 | |||
| 79 | # Whether to use the Just-In-Time (JIT) compiler for shader emulation | ||
| 80 | # 0: Interpreter (slow), 1 (default): JIT (fast) | ||
| 81 | use_shader_jit = | ||
| 82 | |||
| 83 | # Resolution scale factor | ||
| 84 | # 0: Auto (scales resolution to window size), 1: Native 3DS screen resolution, Otherwise a scale | ||
| 85 | # factor for the 3DS resolution | ||
| 86 | resolution_factor = | ||
| 87 | |||
| 88 | # Whether to enable V-Sync (caps the framerate at 60FPS) or not. | ||
| 89 | # 0 (default): Off, 1: On | ||
| 90 | use_vsync = | ||
| 91 | |||
| 92 | # The clear color for the renderer. What shows up on the sides of the bottom screen. | ||
| 93 | # Must be in range of 0.0-1.0. Defaults to 1.0 for all. | ||
| 94 | bg_red = | ||
| 95 | bg_blue = | ||
| 96 | bg_green = | ||
| 97 | |||
| 98 | [Layout] | ||
| 99 | # Layout for the screen inside the render window. | ||
| 100 | # 0 (default): Default Top Bottom Screen, 1: Single Screen Only, 2: Large Screen Small Screen | ||
| 101 | layout_option = | ||
| 102 | |||
| 103 | # Toggle custom layout (using the settings below) on or off. | ||
| 104 | # 0 (default): Off , 1: On | ||
| 105 | custom_layout = | ||
| 106 | |||
| 107 | # Screen placement when using Custom layout option | ||
| 108 | # 0x, 0y is the top left corner of the render window. | ||
| 109 | custom_top_left = | ||
| 110 | custom_top_top = | ||
| 111 | custom_top_right = | ||
| 112 | custom_top_bottom = | ||
| 113 | custom_bottom_left = | ||
| 114 | custom_bottom_top = | ||
| 115 | custom_bottom_right = | ||
| 116 | custom_bottom_bottom = | ||
| 117 | |||
| 118 | #Whether to toggle frame limiter on or off. | ||
| 119 | # 0: Off , 1 (default): On | ||
| 120 | toggle_framelimit = | ||
| 121 | |||
| 122 | # Swaps the prominent screen with the other screen. | ||
| 123 | # For example, if Single Screen is chosen, setting this to 1 will display the bottom screen instead of the top screen. | ||
| 124 | # 0 (default): Top Screen is prominent, 1: Bottom Screen is prominent | ||
| 125 | swap_screen = | ||
| 126 | |||
| 127 | [Audio] | ||
| 128 | # Which audio output engine to use. | ||
| 129 | # auto (default): Auto-select, null: No audio output, sdl2: SDL2 (if available) | ||
| 130 | output_engine = | ||
| 131 | |||
| 132 | # Whether or not to enable the audio-stretching post-processing effect. | ||
| 133 | # This effect adjusts audio speed to match emulation speed and helps prevent audio stutter, | ||
| 134 | # at the cost of increasing audio latency. | ||
| 135 | # 0: No, 1 (default): Yes | ||
| 136 | enable_audio_stretching = | ||
| 137 | |||
| 138 | # Which audio device to use. | ||
| 139 | # auto (default): Auto-select | ||
| 140 | output_device = | ||
| 141 | |||
| 142 | [Data Storage] | ||
| 143 | # Whether to create a virtual SD card. | ||
| 144 | # 1 (default): Yes, 0: No | ||
| 145 | use_virtual_sd = | ||
| 146 | |||
| 147 | [System] | ||
| 148 | # The system model that Citra will try to emulate | ||
| 149 | # 0: Old 3DS (default), 1: New 3DS | ||
| 150 | is_new_3ds = | ||
| 151 | |||
| 152 | # The system region that Citra will use during emulation | ||
| 153 | # -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan | ||
| 154 | region_value = | ||
| 155 | |||
| 156 | [Miscellaneous] | ||
| 157 | # A filter which removes logs below a certain logging level. | ||
| 158 | # Examples: *:Debug Kernel.SVC:Trace Service.*:Critical | ||
| 159 | log_filter = *:Info | ||
| 160 | |||
| 161 | [Debugging] | ||
| 162 | # Port for listening to GDB connections. | ||
| 163 | use_gdbstub=false | ||
| 164 | gdbstub_port=24689 | ||
| 165 | |||
| 166 | [WebService] | ||
| 167 | # Whether or not to enable telemetry | ||
| 168 | # 0: No, 1 (default): Yes | ||
| 169 | enable_telemetry = | ||
| 170 | # Endpoint URL for submitting telemetry data | ||
| 171 | telemetry_endpoint_url = https://services.citra-emu.org/api/telemetry | ||
| 172 | # Endpoint URL to verify the username and token | ||
| 173 | verify_endpoint_url = https://services.citra-emu.org/api/profile | ||
| 174 | # Username and token for Citra Web Service | ||
| 175 | # See https://services.citra-emu.org/ for more info | ||
| 176 | citra_username = | ||
| 177 | citra_token = | ||
| 178 | )"; | ||
| 179 | } | ||
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp new file mode 100644 index 000000000..e65b04e4b --- /dev/null +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.cpp | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <algorithm> | ||
| 6 | #include <cstdlib> | ||
| 7 | #include <string> | ||
| 8 | #define SDL_MAIN_HANDLED | ||
| 9 | #include <SDL.h> | ||
| 10 | #include <glad/glad.h> | ||
| 11 | #include "citra/emu_window/emu_window_sdl2.h" | ||
| 12 | #include "common/logging/log.h" | ||
| 13 | #include "common/scm_rev.h" | ||
| 14 | #include "common/string_util.h" | ||
| 15 | #include "core/settings.h" | ||
| 16 | #include "input_common/keyboard.h" | ||
| 17 | #include "input_common/main.h" | ||
| 18 | #include "input_common/motion_emu.h" | ||
| 19 | #include "network/network.h" | ||
| 20 | |||
| 21 | void EmuWindow_SDL2::OnMouseMotion(s32 x, s32 y) { | ||
| 22 | TouchMoved((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); | ||
| 23 | InputCommon::GetMotionEmu()->Tilt(x, y); | ||
| 24 | } | ||
| 25 | |||
| 26 | void EmuWindow_SDL2::OnMouseButton(u32 button, u8 state, s32 x, s32 y) { | ||
| 27 | if (button == SDL_BUTTON_LEFT) { | ||
| 28 | if (state == SDL_PRESSED) { | ||
| 29 | TouchPressed((unsigned)std::max(x, 0), (unsigned)std::max(y, 0)); | ||
| 30 | } else { | ||
| 31 | TouchReleased(); | ||
| 32 | } | ||
| 33 | } else if (button == SDL_BUTTON_RIGHT) { | ||
| 34 | if (state == SDL_PRESSED) { | ||
| 35 | InputCommon::GetMotionEmu()->BeginTilt(x, y); | ||
| 36 | } else { | ||
| 37 | InputCommon::GetMotionEmu()->EndTilt(); | ||
| 38 | } | ||
| 39 | } | ||
| 40 | } | ||
| 41 | |||
| 42 | void EmuWindow_SDL2::OnKeyEvent(int key, u8 state) { | ||
| 43 | if (state == SDL_PRESSED) { | ||
| 44 | InputCommon::GetKeyboard()->PressKey(key); | ||
| 45 | } else if (state == SDL_RELEASED) { | ||
| 46 | InputCommon::GetKeyboard()->ReleaseKey(key); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | bool EmuWindow_SDL2::IsOpen() const { | ||
| 51 | return is_open; | ||
| 52 | } | ||
| 53 | |||
| 54 | void EmuWindow_SDL2::OnResize() { | ||
| 55 | int width, height; | ||
| 56 | SDL_GetWindowSize(render_window, &width, &height); | ||
| 57 | UpdateCurrentFramebufferLayout(width, height); | ||
| 58 | } | ||
| 59 | |||
| 60 | EmuWindow_SDL2::EmuWindow_SDL2() { | ||
| 61 | InputCommon::Init(); | ||
| 62 | Network::Init(); | ||
| 63 | |||
| 64 | SDL_SetMainReady(); | ||
| 65 | |||
| 66 | // Initialize the window | ||
| 67 | if (SDL_Init(SDL_INIT_VIDEO) < 0) { | ||
| 68 | LOG_CRITICAL(Frontend, "Failed to initialize SDL2! Exiting..."); | ||
| 69 | exit(1); | ||
| 70 | } | ||
| 71 | |||
| 72 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3); | ||
| 73 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 3); | ||
| 74 | SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE); | ||
| 75 | SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); | ||
| 76 | SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8); | ||
| 77 | SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8); | ||
| 78 | SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8); | ||
| 79 | SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, 0); | ||
| 80 | |||
| 81 | std::string window_title = Common::StringFromFormat("yuzu %s| %s-%s ", Common::g_build_name, | ||
| 82 | Common::g_scm_branch, Common::g_scm_desc); | ||
| 83 | render_window = | ||
| 84 | SDL_CreateWindow(window_title.c_str(), | ||
| 85 | SDL_WINDOWPOS_UNDEFINED, // x position | ||
| 86 | SDL_WINDOWPOS_UNDEFINED, // y position | ||
| 87 | Layout::ScreenUndocked::Width, Layout::ScreenUndocked::Height, | ||
| 88 | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); | ||
| 89 | |||
| 90 | if (render_window == nullptr) { | ||
| 91 | LOG_CRITICAL(Frontend, "Failed to create SDL2 window! Exiting..."); | ||
| 92 | exit(1); | ||
| 93 | } | ||
| 94 | |||
| 95 | gl_context = SDL_GL_CreateContext(render_window); | ||
| 96 | |||
| 97 | if (gl_context == nullptr) { | ||
| 98 | LOG_CRITICAL(Frontend, "Failed to create SDL2 GL context! Exiting..."); | ||
| 99 | exit(1); | ||
| 100 | } | ||
| 101 | |||
| 102 | if (!gladLoadGLLoader(static_cast<GLADloadproc>(SDL_GL_GetProcAddress))) { | ||
| 103 | LOG_CRITICAL(Frontend, "Failed to initialize GL functions! Exiting..."); | ||
| 104 | exit(1); | ||
| 105 | } | ||
| 106 | |||
| 107 | OnResize(); | ||
| 108 | OnMinimalClientAreaChangeRequest(GetActiveConfig().min_client_area_size); | ||
| 109 | SDL_PumpEvents(); | ||
| 110 | SDL_GL_SetSwapInterval(Settings::values.use_vsync); | ||
| 111 | |||
| 112 | DoneCurrent(); | ||
| 113 | } | ||
| 114 | |||
| 115 | EmuWindow_SDL2::~EmuWindow_SDL2() { | ||
| 116 | SDL_GL_DeleteContext(gl_context); | ||
| 117 | SDL_Quit(); | ||
| 118 | |||
| 119 | Network::Shutdown(); | ||
| 120 | InputCommon::Shutdown(); | ||
| 121 | } | ||
| 122 | |||
| 123 | void EmuWindow_SDL2::SwapBuffers() { | ||
| 124 | SDL_GL_SwapWindow(render_window); | ||
| 125 | } | ||
| 126 | |||
| 127 | void EmuWindow_SDL2::PollEvents() { | ||
| 128 | SDL_Event event; | ||
| 129 | |||
| 130 | // SDL_PollEvent returns 0 when there are no more events in the event queue | ||
| 131 | while (SDL_PollEvent(&event)) { | ||
| 132 | switch (event.type) { | ||
| 133 | case SDL_WINDOWEVENT: | ||
| 134 | switch (event.window.event) { | ||
| 135 | case SDL_WINDOWEVENT_SIZE_CHANGED: | ||
| 136 | case SDL_WINDOWEVENT_RESIZED: | ||
| 137 | case SDL_WINDOWEVENT_MAXIMIZED: | ||
| 138 | case SDL_WINDOWEVENT_RESTORED: | ||
| 139 | case SDL_WINDOWEVENT_MINIMIZED: | ||
| 140 | OnResize(); | ||
| 141 | break; | ||
| 142 | case SDL_WINDOWEVENT_CLOSE: | ||
| 143 | is_open = false; | ||
| 144 | break; | ||
| 145 | } | ||
| 146 | break; | ||
| 147 | case SDL_KEYDOWN: | ||
| 148 | case SDL_KEYUP: | ||
| 149 | OnKeyEvent(static_cast<int>(event.key.keysym.scancode), event.key.state); | ||
| 150 | break; | ||
| 151 | case SDL_MOUSEMOTION: | ||
| 152 | OnMouseMotion(event.motion.x, event.motion.y); | ||
| 153 | break; | ||
| 154 | case SDL_MOUSEBUTTONDOWN: | ||
| 155 | case SDL_MOUSEBUTTONUP: | ||
| 156 | OnMouseButton(event.button.button, event.button.state, event.button.x, event.button.y); | ||
| 157 | break; | ||
| 158 | case SDL_QUIT: | ||
| 159 | is_open = false; | ||
| 160 | break; | ||
| 161 | } | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | void EmuWindow_SDL2::MakeCurrent() { | ||
| 166 | SDL_GL_MakeCurrent(render_window, gl_context); | ||
| 167 | } | ||
| 168 | |||
| 169 | void EmuWindow_SDL2::DoneCurrent() { | ||
| 170 | SDL_GL_MakeCurrent(render_window, nullptr); | ||
| 171 | } | ||
| 172 | |||
| 173 | void EmuWindow_SDL2::OnMinimalClientAreaChangeRequest( | ||
| 174 | const std::pair<unsigned, unsigned>& minimal_size) { | ||
| 175 | |||
| 176 | SDL_SetWindowMinimumSize(render_window, minimal_size.first, minimal_size.second); | ||
| 177 | } | ||
diff --git a/src/yuzu_cmd/emu_window/emu_window_sdl2.h b/src/yuzu_cmd/emu_window/emu_window_sdl2.h new file mode 100644 index 000000000..3664d2fbe --- /dev/null +++ b/src/yuzu_cmd/emu_window/emu_window_sdl2.h | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | // Copyright 2016 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <utility> | ||
| 9 | #include "core/frontend/emu_window.h" | ||
| 10 | |||
| 11 | struct SDL_Window; | ||
| 12 | |||
| 13 | class EmuWindow_SDL2 : public EmuWindow { | ||
| 14 | public: | ||
| 15 | EmuWindow_SDL2(); | ||
| 16 | ~EmuWindow_SDL2(); | ||
| 17 | |||
| 18 | /// Swap buffers to display the next frame | ||
| 19 | void SwapBuffers() override; | ||
| 20 | |||
| 21 | /// Polls window events | ||
| 22 | void PollEvents() override; | ||
| 23 | |||
| 24 | /// Makes the graphics context current for the caller thread | ||
| 25 | void MakeCurrent() override; | ||
| 26 | |||
| 27 | /// Releases the GL context from the caller thread | ||
| 28 | void DoneCurrent() override; | ||
| 29 | |||
| 30 | /// Whether the window is still open, and a close request hasn't yet been sent | ||
| 31 | bool IsOpen() const; | ||
| 32 | |||
| 33 | private: | ||
| 34 | /// Called by PollEvents when a key is pressed or released. | ||
| 35 | void OnKeyEvent(int key, u8 state); | ||
| 36 | |||
| 37 | /// Called by PollEvents when the mouse moves. | ||
| 38 | void OnMouseMotion(s32 x, s32 y); | ||
| 39 | |||
| 40 | /// Called by PollEvents when a mouse button is pressed or released | ||
| 41 | void OnMouseButton(u32 button, u8 state, s32 x, s32 y); | ||
| 42 | |||
| 43 | /// Called by PollEvents when any event that may cause the window to be resized occurs | ||
| 44 | void OnResize(); | ||
| 45 | |||
| 46 | /// Called when a configuration change affects the minimal size of the window | ||
| 47 | void OnMinimalClientAreaChangeRequest( | ||
| 48 | const std::pair<unsigned, unsigned>& minimal_size) override; | ||
| 49 | |||
| 50 | /// Is the window still open? | ||
| 51 | bool is_open = true; | ||
| 52 | |||
| 53 | /// Internal SDL2 render window | ||
| 54 | SDL_Window* render_window; | ||
| 55 | |||
| 56 | using SDL_GLContext = void*; | ||
| 57 | /// The OpenGL context associated with the window | ||
| 58 | SDL_GLContext gl_context; | ||
| 59 | }; | ||
diff --git a/src/yuzu_cmd/resource.h b/src/yuzu_cmd/resource.h new file mode 100644 index 000000000..df8e459e4 --- /dev/null +++ b/src/yuzu_cmd/resource.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | //{{NO_DEPENDENCIES}} | ||
| 2 | // Microsoft Visual C++ generated include file. | ||
| 3 | // Used by pcafe.rc | ||
| 4 | // | ||
| 5 | #define IDI_ICON3 103 | ||
| 6 | |||
| 7 | // Next default values for new objects | ||
| 8 | // | ||
| 9 | #ifdef APSTUDIO_INVOKED | ||
| 10 | #ifndef APSTUDIO_READONLY_SYMBOLS | ||
| 11 | #define _APS_NEXT_RESOURCE_VALUE 105 | ||
| 12 | #define _APS_NEXT_COMMAND_VALUE 40001 | ||
| 13 | #define _APS_NEXT_CONTROL_VALUE 1001 | ||
| 14 | #define _APS_NEXT_SYMED_VALUE 101 | ||
| 15 | #endif | ||
| 16 | #endif | ||