diff options
Diffstat (limited to 'src/core/core.cpp')
| -rw-r--r-- | src/core/core.cpp | 89 |
1 files changed, 57 insertions, 32 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp index b7f4b4532..28038ff6f 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -5,6 +5,7 @@ #include <memory> #include <utility> #include "common/logging/log.h" +#include "common/string_util.h" #include "core/core.h" #include "core/core_timing.h" #include "core/gdbstub/gdbstub.h" @@ -15,11 +16,11 @@ #include "core/hle/service/service.h" #include "core/hle/service/sm/controller.h" #include "core/hle/service/sm/sm.h" -#include "core/hw/hw.h" #include "core/loader/loader.h" -#include "core/memory_setup.h" #include "core/settings.h" +#include "file_sys/vfs_concat.h" #include "file_sys/vfs_real.h" +#include "video_core/renderer_base.h" #include "video_core/video_core.h" namespace Core { @@ -63,7 +64,6 @@ System::ResultStatus System::RunLoop(bool tight_loop) { // execute. Otherwise, get out of the loop function. if (GDBStub::GetCpuHaltFlag()) { if (GDBStub::GetCpuStepFlag()) { - GDBStub::SetCpuStepFlag(false); tight_loop = false; } else { return ResultStatus::Success; @@ -79,6 +79,10 @@ System::ResultStatus System::RunLoop(bool tight_loop) { } } + if (GDBStub::IsServerEnabled()) { + GDBStub::SetCpuStepFlag(false); + } + return status; } @@ -86,8 +90,39 @@ System::ResultStatus System::SingleStep() { return RunLoop(false); } -System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& filepath) { - app_loader = Loader::GetLoader(std::make_shared<FileSys::RealVfsFile>(filepath)); +static FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, + const std::string& path) { + // To account for split 00+01+etc files. + std::string dir_name; + std::string filename; + Common::SplitPath(path, &dir_name, &filename, nullptr); + if (filename == "00") { + const auto dir = vfs->OpenDirectory(dir_name, FileSys::Mode::Read); + std::vector<FileSys::VirtualFile> concat; + for (u8 i = 0; i < 0x10; ++i) { + auto next = dir->GetFile(fmt::format("{:02X}", i)); + if (next != nullptr) + concat.push_back(std::move(next)); + else { + next = dir->GetFile(fmt::format("{:02x}", i)); + if (next != nullptr) + concat.push_back(std::move(next)); + else + break; + } + } + + if (concat.empty()) + return nullptr; + + return FileSys::ConcatenateFiles(concat, dir->GetName()); + } + + return vfs->OpenFile(path, FileSys::Mode::Read); +} + +System::ResultStatus System::Load(Frontend::EmuWindow& emu_window, const std::string& filepath) { + app_loader = Loader::GetLoader(GetGameFileFromPath(virtual_filesystem, filepath)); if (!app_loader) { LOG_CRITICAL(Core, "Failed to obtain loader for {}!", filepath); @@ -100,19 +135,11 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file LOG_CRITICAL(Core, "Failed to determine system mode (Error {})!", static_cast<int>(system_mode.second)); - switch (system_mode.second) { - case Loader::ResultStatus::ErrorEncrypted: - return ResultStatus::ErrorLoader_ErrorEncrypted; - case Loader::ResultStatus::ErrorInvalidFormat: - return ResultStatus::ErrorLoader_ErrorInvalidFormat; - case Loader::ResultStatus::ErrorUnsupportedArch: - return ResultStatus::ErrorUnsupportedArch; - default: + if (system_mode.second != Loader::ResultStatus::Success) return ResultStatus::ErrorSystemMode; - } } - ResultStatus init_result{Init(emu_window, system_mode.first.get())}; + ResultStatus init_result{Init(emu_window)}; if (init_result != ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to initialize system (Error {})!", static_cast<int>(init_result)); @@ -125,15 +152,9 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast<int>(load_result)); System::Shutdown(); - switch (load_result) { - case Loader::ResultStatus::ErrorEncrypted: - return ResultStatus::ErrorLoader_ErrorEncrypted; - case Loader::ResultStatus::ErrorInvalidFormat: - return ResultStatus::ErrorLoader_ErrorInvalidFormat; - case Loader::ResultStatus::ErrorUnsupportedArch: - return ResultStatus::ErrorUnsupportedArch; - default: - return ResultStatus::ErrorLoader; + if (load_result != Loader::ResultStatus::Success) { + return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + + static_cast<u32>(load_result)); } } status = ResultStatus::Success; @@ -163,11 +184,15 @@ Cpu& System::CpuCore(size_t core_index) { return *cpu_cores[core_index]; } -System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { +System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { LOG_DEBUG(HW_Memory, "initialized OK"); CoreTiming::Init(); + // Create a default fs if one doesn't already exist. + if (virtual_filesystem == nullptr) + virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); + current_process = Kernel::Process::Create("main"); cpu_barrier = std::make_shared<CpuBarrier>(); @@ -176,19 +201,20 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) { cpu_cores[index] = std::make_shared<Cpu>(cpu_exclusive_monitor, cpu_barrier, index); } - gpu_core = std::make_unique<Tegra::GPU>(); telemetry_session = std::make_unique<Core::TelemetrySession>(); service_manager = std::make_shared<Service::SM::ServiceManager>(); - HW::Init(); - Kernel::Init(system_mode); - Service::Init(service_manager); + Kernel::Init(); + Service::Init(service_manager, virtual_filesystem); GDBStub::Init(); - if (!VideoCore::Init(emu_window)) { + renderer = VideoCore::CreateRenderer(emu_window); + if (!renderer->Init()) { return ResultStatus::ErrorVideoCore; } + gpu_core = std::make_unique<Tegra::GPU>(renderer->Rasterizer()); + // Create threads for CPU cores 1-3, and build thread_to_cpu map // CPU core 0 is run on the main thread thread_to_cpu[std::this_thread::get_id()] = cpu_cores[0]; @@ -220,11 +246,10 @@ void System::Shutdown() { perf_results.frametime * 1000.0); // Shutdown emulation session - VideoCore::Shutdown(); + renderer.reset(); GDBStub::Shutdown(); Service::Shutdown(); Kernel::Shutdown(); - HW::Shutdown(); service_manager.reset(); telemetry_session.reset(); gpu_core.reset(); |
