mirror of
https://github.com/Dark98/threeSD.git
synced 2026-07-03 00:38:58 +00:00
build system updates and other fixes
add preset config import qt separate core and frontend
This commit is contained in:
@@ -1,8 +1,20 @@
|
|||||||
# CMake 3.8 required for 17 to be a valid value for CXX_STANDARD
|
# CMake 3.8 required for 17 to be a valid value for CXX_STANDARD
|
||||||
cmake_minimum_required(VERSION 3.8)
|
cmake_minimum_required(VERSION 3.8)
|
||||||
|
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||||
|
include(DownloadExternals)
|
||||||
|
include(CMakeDependentOption)
|
||||||
|
|
||||||
|
if (POLICY CMP0076)
|
||||||
|
# TODO: set this to NEW
|
||||||
|
cmake_policy(SET CMP0076 OLD)
|
||||||
|
endif()
|
||||||
|
|
||||||
project(threeSD)
|
project(threeSD)
|
||||||
|
|
||||||
|
option(WARNINGS_AS_ERRORS "Treat warnings as errors" ON)
|
||||||
|
CMAKE_DEPENDENT_OPTION(USE_BUNDLED_QT "Download bundled Qt binaries" ON "MSVC" OFF)
|
||||||
|
CMAKE_DEPENDENT_OPTION(COMPILE_WITH_DWARF "Add DWARF debugging information" ON "MINGW" OFF)
|
||||||
|
|
||||||
# Sanity check : Check that all submodules are present
|
# Sanity check : Check that all submodules are present
|
||||||
# =======================================================================
|
# =======================================================================
|
||||||
function(check_submodules_present)
|
function(check_submodules_present)
|
||||||
@@ -26,6 +38,55 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|||||||
# set up output paths for executable binaries
|
# set up output paths for executable binaries
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
||||||
|
|
||||||
|
# System imported libraries
|
||||||
|
# ======================
|
||||||
|
|
||||||
|
# TODO: Is this necessary?
|
||||||
|
|
||||||
|
# Prefer the -pthread flag on Linux.
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
|
if (USE_BUNDLED_QT)
|
||||||
|
if ((MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) AND ARCHITECTURE_x86_64)
|
||||||
|
set(QT_VER qt-5.10.0-msvc2017_64)
|
||||||
|
else()
|
||||||
|
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (DEFINED QT_VER)
|
||||||
|
download_bundled_external("qt/" ${QT_VER} QT_PREFIX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(QT_PREFIX_HINT HINTS "${QT_PREFIX}")
|
||||||
|
else()
|
||||||
|
# Passing an empty HINTS seems to cause default system paths to get ignored in CMake 2.8 so
|
||||||
|
# make sure to not pass anything if we don't have one.
|
||||||
|
set(QT_PREFIX_HINT)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_package(Qt5 REQUIRED COMPONENTS Widgets ${QT_PREFIX_HINT})
|
||||||
|
|
||||||
|
# Platform-specific library requirements
|
||||||
|
# ======================================
|
||||||
|
# TODO: Check the necessity of these
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
# Umbrella framework for everything GUI-related
|
||||||
|
find_library(COCOA_LIBRARY Cocoa)
|
||||||
|
set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY})
|
||||||
|
elseif (WIN32)
|
||||||
|
# WSAPoll and SHGetKnownFolderPath (AppData/Roaming) didn't exist before WinNT 6.x (Vista)
|
||||||
|
add_definitions(-D_WIN32_WINNT=0x0600 -DWINVER=0x0600)
|
||||||
|
set(PLATFORM_LIBRARIES winmm ws2_32)
|
||||||
|
if (MINGW)
|
||||||
|
# PSAPI is the Process Status API
|
||||||
|
set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version)
|
||||||
|
endif()
|
||||||
|
elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$")
|
||||||
|
set(PLATFORM_LIBRARIES rt)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Include source code
|
# Include source code
|
||||||
# ===================
|
# ===================
|
||||||
add_subdirectory(externals)
|
add_subdirectory(externals)
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
function(copy_Qt5_deps target_dir)
|
||||||
|
include(WindowsCopyFiles)
|
||||||
|
set(DLL_DEST "${CMAKE_BINARY_DIR}/bin/$<CONFIG>/")
|
||||||
|
set(Qt5_DLL_DIR "${Qt5_DIR}/../../../bin")
|
||||||
|
set(Qt5_PLATFORMS_DIR "${Qt5_DIR}/../../../plugins/platforms/")
|
||||||
|
set(Qt5_STYLES_DIR "${Qt5_DIR}/../../../plugins/styles/")
|
||||||
|
# set(Qt5_IMAGEFORMATS_DIR "${Qt5_DIR}/../../../plugins/imageformats/")
|
||||||
|
set(PLATFORMS ${DLL_DEST}platforms/)
|
||||||
|
set(STYLES ${DLL_DEST}styles/)
|
||||||
|
# set(IMAGEFORMATS ${DLL_DEST}imageformats/)
|
||||||
|
windows_copy_files(${target_dir} ${Qt5_DLL_DIR} ${DLL_DEST}
|
||||||
|
icudt*.dll
|
||||||
|
icuin*.dll
|
||||||
|
icuuc*.dll
|
||||||
|
Qt5Core$<$<CONFIG:Debug>:d>.*
|
||||||
|
Qt5Gui$<$<CONFIG:Debug>:d>.*
|
||||||
|
Qt5Widgets$<$<CONFIG:Debug>:d>.*
|
||||||
|
)
|
||||||
|
windows_copy_files(citra-qt ${Qt5_PLATFORMS_DIR} ${PLATFORMS} qwindows$<$<CONFIG:Debug>:d>.*)
|
||||||
|
windows_copy_files(citra-qt ${Qt5_STYLES_DIR} ${STYLES} qwindowsvistastyle$<$<CONFIG:Debug>:d>.*)
|
||||||
|
# windows_copy_files(${target_dir} ${Qt5_IMAGEFORMATS_DIR} ${IMAGEFORMATS}
|
||||||
|
# qgif$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qicns$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qico$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qjpeg$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qsvg$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qtga$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qtiff$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qwbmp$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# qwebp$<$<CONFIG:Debug>:d>.dll
|
||||||
|
# )
|
||||||
|
endfunction(copy_citra_Qt5_deps)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
|
||||||
|
# This function downloads a binary library package from our external repo.
|
||||||
|
# Params:
|
||||||
|
# remote_path: path to the file to download, relative to the remote repository root
|
||||||
|
# prefix_var: name of a variable which will be set with the path to the extracted contents
|
||||||
|
function(download_bundled_external remote_path lib_name prefix_var)
|
||||||
|
set(prefix "${CMAKE_BINARY_DIR}/externals/${lib_name}")
|
||||||
|
if (NOT EXISTS "${prefix}")
|
||||||
|
message(STATUS "Downloading binaries for ${lib_name}...")
|
||||||
|
file(DOWNLOAD
|
||||||
|
https://github.com/citra-emu/ext-windows-bin/raw/master/${remote_path}${lib_name}.7z
|
||||||
|
"${CMAKE_BINARY_DIR}/externals/${lib_name}.7z" SHOW_PROGRESS)
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E tar xf "${CMAKE_BINARY_DIR}/externals/${lib_name}.7z"
|
||||||
|
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/externals")
|
||||||
|
endif()
|
||||||
|
message(STATUS "Using bundled binaries at ${prefix}")
|
||||||
|
set(${prefix_var} "${prefix}" PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
# Copyright 2016 Citra Emulator Project
|
||||||
|
# Licensed under GPLv2 or any later version
|
||||||
|
# Refer to the license.txt file included.
|
||||||
|
|
||||||
|
# This file provides the function windows_copy_files.
|
||||||
|
# This is only valid on Windows.
|
||||||
|
|
||||||
|
# Include guard
|
||||||
|
if(__windows_copy_files)
|
||||||
|
return()
|
||||||
|
endif()
|
||||||
|
set(__windows_copy_files YES)
|
||||||
|
|
||||||
|
# Any number of files to copy from SOURCE_DIR to DEST_DIR can be specified after DEST_DIR.
|
||||||
|
# This copying happens post-build.
|
||||||
|
function(windows_copy_files TARGET SOURCE_DIR DEST_DIR)
|
||||||
|
# windows commandline expects the / to be \ so switch them
|
||||||
|
string(REPLACE "/" "\\\\" SOURCE_DIR ${SOURCE_DIR})
|
||||||
|
string(REPLACE "/" "\\\\" DEST_DIR ${DEST_DIR})
|
||||||
|
|
||||||
|
# /NJH /NJS /NDL /NFL /NC /NS /NP - Silence any output
|
||||||
|
# cmake adds an extra check for command success which doesn't work too well with robocopy
|
||||||
|
# so trick it into thinking the command was successful with the || cmd /c "exit /b 0"
|
||||||
|
add_custom_command(TARGET ${TARGET} POST_BUILD
|
||||||
|
COMMAND if not exist ${DEST_DIR} mkdir ${DEST_DIR} 2> nul
|
||||||
|
COMMAND robocopy ${SOURCE_DIR} ${DEST_DIR} ${ARGN} /NJH /NJS /NDL /NFL /NC /NS /NP || cmd /c "exit /b 0"
|
||||||
|
)
|
||||||
|
endfunction()
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
threeSD
|
||||||
|
========
|
||||||
|
|
||||||
|
threeSD is a tool to help prepare your system for the Nintendo 3DS emulator [Citra](https://citra-emu.org).
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
First of all, of course, you should download a [release](https://github.com/zhaowenlan1779/threeSD/releases) of threeSD and extract the archive somewhere.
|
||||||
|
|
||||||
|
### What you'll need
|
||||||
|
|
||||||
|
* Nintendo 3DS with access to CFW and [GodMode9](https://github.com/d0k3/GodMode9)
|
||||||
|
* If your 3DS is not yet hacked, you can do so by following the instructions [here](https://3ds.hacks.guide).
|
||||||
|
* You can install GodMode9 by downloading it and copying the `firm` file to `luma/payloads` on your 3DS. You can rename it to begin with `[BUTTON]_` (e.g. `X_GodMode9.firm`) to set a convenicence button to hold during boot to enter GodMode9.
|
||||||
|
* PC compatible with Citra
|
||||||
|
* You will need a graphics card compatible with OpenGL 3.3 and install the latest graphics drivers from your vendor's website.
|
||||||
|
* Operating system requirements: **64-bit** Windows (7+), Linux (flatpak) or macOS (10.13+). Note that Citra on macOS 10.13 is currently broken. It is recommended to update to 10.14.
|
||||||
|
* SD / microSD card reader
|
||||||
|
|
||||||
|
### On Your 3DS
|
||||||
|
|
||||||
|
You will need to run a GodMode9 script. If you are unsure about the script's safety (which is good!), check the source code yourself [here](https://github.com/zhaowenlan1779/threeSD/blob/master/dist/threeSDumper.gm9).
|
||||||
|
|
||||||
|
1. Copy the gm9 script (`threeSDumper.gm9`) in `dist` to the `gm9/scripts` folder on your SD card.
|
||||||
|
1. Power up your 3DS to launch GodMode9 (you will need to hold a button corresponding to your `firm` file's name, or hold `START` to enter the chainloader). Press the `Home` button to bring up GodMode9's `HOME Menu`. Use the d-pad and the `A` button to select `Scripts...`.
|
||||||
|
1. Use the d-pad and the `A` button to select `threeSDumper`. You will be prompted with a question "Execute threeSD Dumper?". Press `A` to confirm.
|
||||||
|
1. After a moment or two you will see the message "Successfully dumped necessary files for threeSD." Your 3DS SD card is now prepared for use with threeSD and Citra. Press `A` to exit the script.
|
||||||
|
1. Power off your 3DS with `R+START`. Remove the SD card from your 3DS and insert it into your PC (with a card reader).
|
||||||
|
|
||||||
|
### On your PC
|
||||||
|
|
||||||
|
Make sure the SD card is properly recognized and shows up as a disk.
|
||||||
|
|
||||||
|
1.
|
||||||
+89
-3
@@ -1,9 +1,95 @@
|
|||||||
|
# Enable modules to include each other's files
|
||||||
include_directories(.)
|
include_directories(.)
|
||||||
|
|
||||||
add_executable(threeSD)
|
# CMake seems to only define _DEBUG on Windows
|
||||||
|
set_property(DIRECTORY APPEND PROPERTY
|
||||||
|
COMPILE_DEFINITIONS $<$<CONFIG:Debug>:_DEBUG> $<$<NOT:$<CONFIG:Debug>>:NDEBUG>)
|
||||||
|
|
||||||
|
# Set compilation flags
|
||||||
|
if (MSVC)
|
||||||
|
set(CMAKE_CONFIGURATION_TYPES Debug Release CACHE STRING "" FORCE)
|
||||||
|
|
||||||
|
# Silence "deprecation" warnings
|
||||||
|
add_definitions(-D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS)
|
||||||
|
|
||||||
|
# Avoid windows.h junk
|
||||||
|
add_definitions(-DNOMINMAX)
|
||||||
|
|
||||||
|
# Avoid windows.h from including some usually unused libs like winsocks.h, since this might cause some redefinition errors.
|
||||||
|
add_definitions(-DWIN32_LEAN_AND_MEAN)
|
||||||
|
|
||||||
|
# Ensure that projects build with Unicode support.
|
||||||
|
add_definitions(-DUNICODE -D_UNICODE)
|
||||||
|
|
||||||
|
# /W3 - Level 3 warnings
|
||||||
|
# /MP - Multi-threaded compilation
|
||||||
|
# /Zi - Output debugging information
|
||||||
|
# /Zo - Enhanced debug info for optimized builds
|
||||||
|
# /permissive- - Enables stricter C++ standards conformance checks
|
||||||
|
# /EHsc - C++-only exception handling semantics
|
||||||
|
# /volatile:iso - Use strict standards-compliant volatile semantics.
|
||||||
|
# /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
|
||||||
|
# /Zc:inline - Let codegen omit inline functions in object files
|
||||||
|
# /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
|
||||||
|
add_compile_options(
|
||||||
|
/W3
|
||||||
|
/MP
|
||||||
|
/Zi
|
||||||
|
/Zo
|
||||||
|
/permissive-
|
||||||
|
/EHsc
|
||||||
|
/std:c++latest
|
||||||
|
/volatile:iso
|
||||||
|
/Zc:externConstexpr
|
||||||
|
/Zc:inline
|
||||||
|
/Zc:throwingNew
|
||||||
|
)
|
||||||
|
|
||||||
|
# /GS- - No stack buffer overflow checks
|
||||||
|
add_compile_options("$<$<CONFIG:Release>:/GS->")
|
||||||
|
|
||||||
|
if (WARNINGS_AS_ERRORS)
|
||||||
|
add_compile_options(/WX)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG /MANIFEST:NO" CACHE STRING "" FORCE)
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
|
||||||
|
else()
|
||||||
|
add_compile_options(
|
||||||
|
-Wall
|
||||||
|
-Wno-attributes
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WARNINGS_AS_ERRORS)
|
||||||
|
add_compile_options(-Werror -Wfatal-errors)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (APPLE AND CMAKE_CXX_COMPILER_ID STREQUAL Clang)
|
||||||
|
add_compile_options("-stdlib=libc++")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set file offset size to 64 bits.
|
||||||
|
#
|
||||||
|
# On modern Unixes, this is typically already the case. The lone exception is
|
||||||
|
# glibc, which may default to 32 bits. glibc allows this to be configured
|
||||||
|
# by setting _FILE_OFFSET_BITS.
|
||||||
|
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR MINGW)
|
||||||
|
add_definitions(-D_FILE_OFFSET_BITS=64)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MINGW)
|
||||||
|
add_definitions(-DMINGW_HAS_SECURE_API)
|
||||||
|
if (COMPILE_WITH_DWARF)
|
||||||
|
add_compile_options("-gdwarf")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (MINGW_STATIC_BUILD)
|
||||||
|
add_definitions(-DQT_STATICPLUGIN)
|
||||||
|
add_compile_options("-static")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(common)
|
add_subdirectory(common)
|
||||||
add_subdirectory(core)
|
add_subdirectory(core)
|
||||||
add_subdirectory(frontend)
|
add_subdirectory(frontend)
|
||||||
|
|
||||||
target_link_libraries(threeSD PRIVATE cryptopp fmt)
|
|
||||||
|
|||||||
+15
-13
@@ -1,14 +1,16 @@
|
|||||||
target_sources(threeSD PRIVATE
|
add_library(common STATIC
|
||||||
common/assert.h
|
assert.h
|
||||||
common/bit_field.h
|
bit_field.h
|
||||||
common/common_funcs.h
|
common_funcs.h
|
||||||
common/common_paths.h
|
common_paths.h
|
||||||
common/common_types.h
|
common_types.h
|
||||||
common/file_util.cpp
|
file_util.cpp
|
||||||
common/file_util.h
|
file_util.h
|
||||||
common/logging/log.h
|
logging/log.h
|
||||||
common/misc.cpp
|
misc.cpp
|
||||||
common/string_util.cpp
|
string_util.cpp
|
||||||
common/string_util.h
|
string_util.h
|
||||||
common/swap.h
|
swap.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(common PUBLIC fmt)
|
||||||
|
|||||||
+15
-13
@@ -1,14 +1,16 @@
|
|||||||
target_sources(threeSD PRIVATE
|
add_library(core STATIC
|
||||||
core/data_container.cpp
|
data_container.cpp
|
||||||
core/data_container.h
|
data_container.h
|
||||||
core/decryptor.cpp
|
decryptor.cpp
|
||||||
core/decryptor.h
|
decryptor.h
|
||||||
core/importer.cpp
|
importer.cpp
|
||||||
core/importer.h
|
importer.h
|
||||||
core/inner_fat.cpp
|
inner_fat.cpp
|
||||||
core/inner_fat.h
|
inner_fat.h
|
||||||
core/key/arithmetic128.cpp
|
key/arithmetic128.cpp
|
||||||
core/key/arithmetic128.h
|
key/arithmetic128.h
|
||||||
core/key/key.cpp
|
key/key.cpp
|
||||||
core/key/key.h
|
key/key.h
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(core PRIVATE common cryptopp)
|
||||||
|
|||||||
+74
-1
@@ -2,6 +2,7 @@
|
|||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include <regex>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/common_paths.h"
|
#include "common/common_paths.h"
|
||||||
#include "common/file_util.h"
|
#include "common/file_util.h"
|
||||||
@@ -17,7 +18,7 @@ SDMCImporter::SDMCImporter(const Config& config_) : config(config_) {
|
|||||||
SDMCImporter::~SDMCImporter() = default;
|
SDMCImporter::~SDMCImporter() = default;
|
||||||
|
|
||||||
bool SDMCImporter::Init() {
|
bool SDMCImporter::Init() {
|
||||||
ASSERT_MSG(config.is_good && !config.sdmc_path.empty() && !config.user_path.empty() &&
|
ASSERT_MSG(!config.sdmc_path.empty() && !config.user_path.empty() &&
|
||||||
!config.bootrom_path.empty() && !config.movable_sed_path.empty(),
|
!config.bootrom_path.empty() && !config.movable_sed_path.empty(),
|
||||||
"Config is not good");
|
"Config is not good");
|
||||||
|
|
||||||
@@ -245,3 +246,75 @@ void SDMCImporter::ListSysdata(std::vector<ContentSpecifier>& out) const {
|
|||||||
|
|
||||||
#undef CHECK_CONTENT
|
#undef CHECK_CONTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<Config> LoadPresetConfig(std::string mount_point) {
|
||||||
|
if (mount_point.back() != '/' && mount_point.back() != '\\') {
|
||||||
|
mount_point += '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not a Nintendo 3DS sd card at all
|
||||||
|
if (!FileUtil::Exists(mount_point + "Nintendo 3DS/")) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
Config config_template{};
|
||||||
|
config_template.user_path = FileUtil::GetUserPath(FileUtil::UserPath::UserDir);
|
||||||
|
|
||||||
|
// Load dumped data paths if using our dumper
|
||||||
|
if (FileUtil::Exists(mount_point + "threeSD/")) {
|
||||||
|
#define LOAD_DATA(var, path) \
|
||||||
|
if (FileUtil::Exists(mount_point + "threeSD/" + path)) { \
|
||||||
|
config_template.var = mount_point + "threeSD/" + path; \
|
||||||
|
}
|
||||||
|
|
||||||
|
LOAD_DATA(movable_sed_path, MOVABLE_SED);
|
||||||
|
LOAD_DATA(bootrom_path, BOOTROM9);
|
||||||
|
LOAD_DATA(safe_mode_firm_path, "firm/");
|
||||||
|
LOAD_DATA(seed_db_path, SEED_DB);
|
||||||
|
LOAD_DATA(secret_sector_path, SECRET_SECTOR);
|
||||||
|
#undef LOAD_DATA
|
||||||
|
}
|
||||||
|
|
||||||
|
// Regex for 3DS ID0 and ID1
|
||||||
|
const std::regex id_regex{"[0-9a-f]{32}"};
|
||||||
|
|
||||||
|
// Load SDMC dir
|
||||||
|
std::vector<Config> out;
|
||||||
|
const auto ProcessDirectory = [&id_regex, &config_template, &out](const std::string& path) {
|
||||||
|
return FileUtil::ForeachDirectoryEntry(
|
||||||
|
nullptr, path,
|
||||||
|
[&id_regex, &config_template, &out](u64* /*num_entries_out*/,
|
||||||
|
const std::string& directory,
|
||||||
|
const std::string& virtual_name) {
|
||||||
|
if (!FileUtil::IsDirectory(directory + virtual_name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::regex_match(virtual_name, id_regex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Config config = config_template;
|
||||||
|
config.sdmc_path = directory + virtual_name + "/";
|
||||||
|
out.push_back(config);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
FileUtil::ForeachDirectoryEntry(
|
||||||
|
nullptr, mount_point + "Nintendo 3DS/",
|
||||||
|
[&id_regex, &ProcessDirectory](u64* /*num_entries_out*/, const std::string& directory,
|
||||||
|
const std::string& virtual_name) {
|
||||||
|
if (!FileUtil::IsDirectory(directory + virtual_name)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!std::regex_match(virtual_name, id_regex)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ProcessDirectory(directory + virtual_name);
|
||||||
|
});
|
||||||
|
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|||||||
+6
-3
@@ -51,9 +51,6 @@ struct Config {
|
|||||||
std::string safe_mode_firm_path; ///< Path to safe mode firm (A folder) (Sysdata 1)
|
std::string safe_mode_firm_path; ///< Path to safe mode firm (A folder) (Sysdata 1)
|
||||||
std::string seed_db_path; ///< Path to seeddb.bin (Sysdata 2)
|
std::string seed_db_path; ///< Path to seeddb.bin (Sysdata 2)
|
||||||
std::string secret_sector_path; ///< Path to secret sector (New3DS only) (Sysdata 3)
|
std::string secret_sector_path; ///< Path to secret sector (New3DS only) (Sysdata 3)
|
||||||
|
|
||||||
// Whether this config has all necessary information
|
|
||||||
bool is_good;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SDMCImporter {
|
class SDMCImporter {
|
||||||
@@ -96,3 +93,9 @@ private:
|
|||||||
Config config;
|
Config config;
|
||||||
std::unique_ptr<SDMCDecryptor> decryptor;
|
std::unique_ptr<SDMCDecryptor> decryptor;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look for and load preset config for a SD card mounted at mount_point.
|
||||||
|
* @return a list of preset config available. can be empty
|
||||||
|
*/
|
||||||
|
std::vector<Config> LoadPresetConfig(std::string mount_point);
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ struct KeyDesc {
|
|||||||
bool same_as_before;
|
bool same_as_before;
|
||||||
};
|
};
|
||||||
|
|
||||||
AESKey HexToKey(const std::string& hex) {
|
// TODO: Use this to support manual input of keys
|
||||||
|
[[maybe_unused]] AESKey HexToKey(const std::string& hex) {
|
||||||
if (hex.size() < 32) {
|
if (hex.size() < 32) {
|
||||||
throw std::invalid_argument("hex string is too short");
|
throw std::invalid_argument("hex string is too short");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,54 @@
|
|||||||
target_sources(threeSD PRIVATE
|
set(CMAKE_AUTOMOC ON)
|
||||||
frontend/main.cpp
|
set(CMAKE_AUTORCC ON)
|
||||||
|
set(CMAKE_AUTOUIC ON)
|
||||||
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
if (POLICY CMP0071)
|
||||||
|
cmake_policy(SET CMP0071 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_executable(threeSD
|
||||||
|
main.cpp
|
||||||
|
main.h
|
||||||
|
main.ui
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_libraries(threeSD PRIVATE common core)
|
||||||
|
target_link_libraries(threeSD PRIVATE Qt5::Widgets)
|
||||||
|
target_link_libraries(threeSD PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
# TODO: support macOS
|
||||||
|
# set(MACOSX_ICON "../../dist/citra.icns")
|
||||||
|
# set_source_files_properties(${MACOSX_ICON} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
# target_sources(threeSD PRIVATE ${MACOSX_ICON})
|
||||||
|
# set_target_properties(threeSD PROPERTIES MACOSX_BUNDLE TRUE)
|
||||||
|
# set_target_properties(threeSD PROPERTIES MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/Info.plist)
|
||||||
|
elseif(WIN32)
|
||||||
|
# compile as a win32 gui application instead of a console application
|
||||||
|
target_link_libraries(threeSD PRIVATE Qt5::WinMain)
|
||||||
|
if(MSVC)
|
||||||
|
set_target_properties(threeSD PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||||
|
elseif(MINGW)
|
||||||
|
set_target_properties(threeSD PROPERTIES LINK_FLAGS_RELEASE "-mwindows")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_compile_definitions(threeSD PRIVATE
|
||||||
|
# Use QStringBuilder for string concatenation to reduce
|
||||||
|
# the overall number of temporary strings created.
|
||||||
|
-DQT_USE_QSTRINGBUILDER
|
||||||
|
|
||||||
|
# Disable implicit type narrowing in signal/slot connect() calls.
|
||||||
|
-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT
|
||||||
|
|
||||||
|
# Disable unsafe overloads of QProcess' start() function.
|
||||||
|
-DQT_NO_PROCESS_COMBINED_ARGUMENT_START
|
||||||
|
|
||||||
|
# Disable implicit QString->QUrl conversions to enforce use of proper resolving functions.
|
||||||
|
-DQT_NO_URL_CAST_FROM_STRING
|
||||||
|
)
|
||||||
|
|
||||||
|
if (MSVC)
|
||||||
|
include(CopyQt5Deps)
|
||||||
|
copy_Qt5_deps(threeSD)
|
||||||
|
endif()
|
||||||
|
|||||||
+34
-10
@@ -1,14 +1,38 @@
|
|||||||
// Dummy
|
// Copyright 2014 Citra Emulator Project / 2019 threeSD Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <iostream>
|
#include <QApplication>
|
||||||
#include "common/logging/log.h"
|
#include "frontend/main.h"
|
||||||
|
#include "ui_main.h"
|
||||||
|
|
||||||
int main() {
|
#ifdef __APPLE__
|
||||||
|
#include <string>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include "common/common_paths.h"
|
||||||
|
#include "common/file_util.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
LOG_ERROR(Frontend, "test");
|
MainDialog::MainDialog(QWidget* parent) : QDialog(parent), ui(std::make_unique<Ui::MainDialog>()) {
|
||||||
_sleep(1000);
|
ui->setupUi(this);
|
||||||
LOG_WARNING(Frontend, "test2");
|
}
|
||||||
system("pause");
|
|
||||||
|
MainDialog::~MainDialog() = default;
|
||||||
return 0;
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
// Init settings params
|
||||||
|
QCoreApplication::setOrganizationName("zhaowenlan1779");
|
||||||
|
QCoreApplication::setApplicationName("threeSD");
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
std::string bin_path = FileUtil::GetBundleDirectory() + DIR_SEP + "..";
|
||||||
|
chdir(bin_path.c_str());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
MainDialog main_dialog;
|
||||||
|
main_dialog.show();
|
||||||
|
|
||||||
|
return app.exec();
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2019 threeSD Project
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <QDialog>
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class MainDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MainDialog : public QDialog {
|
||||||
|
Q_OBJECT;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MainDialog(QWidget* parent = nullptr);
|
||||||
|
~MainDialog() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<Ui::MainDialog> ui;
|
||||||
|
};
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>MainDialog</class>
|
||||||
|
<widget class="QDialog" name="MainDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>450</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>threeSD</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto-detected Configuration:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="configSelect">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="advancedButton">
|
||||||
|
<property name="text">
|
||||||
|
<string>Advanced...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QGroupBox">
|
||||||
|
<property name="title">
|
||||||
|
<string>Custom</string>
|
||||||
|
</property>
|
||||||
|
<property name="visible">
|
||||||
|
<bool>false</bool>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout">
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>SDMC:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="sdmcPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="sdmcPathExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>User Directory:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="userPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="userPathExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>movable.sed:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="movableSedPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="movableSedExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>boot9.bin:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="bootrom9Path"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="bootrom9Explore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Safe mode firm Path:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="safeModeFirmPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="safeModeFirmExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>seeddb.bin:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="seeddbPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="seeddbExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>sector0x96.bin:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="secretSectorPath"/>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QPushButton" name="secretSectorExplore">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Ok|QDialogButtonBox::Reset</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer>
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Vertical</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>0</width>
|
||||||
|
<height>0</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections/>
|
||||||
|
</ui>
|
||||||
Reference in New Issue
Block a user