diff --git a/src/core-tests/CMakeLists.txt b/src/core-tests/CMakeLists.txt index 7feca55fe..3b02999cf 100644 --- a/src/core-tests/CMakeLists.txt +++ b/src/core-tests/CMakeLists.txt @@ -2,23 +2,11 @@ # SPDX-License-Identifier: CC-BY-NC-ND-4.0 + Packaging Restriction add_executable(core-tests - ../core/cheats.cpp - ../core/cpu_disasm.cpp - ../core/cpu_types.cpp - ../util/zip_helpers.cpp cheats_tests.cpp cpu_disasm_tests.cpp spu_tests.cpp - stub_cpu.cpp + stub_host.cpp ) target_include_directories(core-tests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") -target_link_libraries(core-tests PRIVATE common imgui libzip::zip gtest gtest_main) - -if(APPLE) - target_compile_options(core-tests PRIVATE -ffunction-sections -fdata-sections) - target_link_options(core-tests PRIVATE -Wl,-dead_strip) -elseif(NOT MSVC) - target_compile_options(core-tests PRIVATE -ffunction-sections -fdata-sections) - target_link_options(core-tests PRIVATE -Wl,--gc-sections) -endif() +target_link_libraries(core-tests PRIVATE core gtest gtest_main) diff --git a/src/core-tests/core-tests.vcxproj b/src/core-tests/core-tests.vcxproj index 4b2943e39..4e555f4b0 100644 --- a/src/core-tests/core-tests.vcxproj +++ b/src/core-tests/core-tests.vcxproj @@ -3,13 +3,10 @@ - - - - - + + @@ -21,21 +18,28 @@ {ee054e08-3799-4a59-a422-18259c105ffd} + + {868b98c8-65a1-494b-8346-250a73a48c0a} + + + {57f6206d-f264-4b07-baf8-11b9bbe1f455} + + + + {93D9300C-B64A-4B21-A4B5-30173DE88747} - + %(AdditionalIncludeDirectories);$(SolutionDir)dep\googletest\include - true Console - true - + \ No newline at end of file diff --git a/src/core-tests/core-tests.vcxproj.filters b/src/core-tests/core-tests.vcxproj.filters index feaa366ba..fb8c94920 100644 --- a/src/core-tests/core-tests.vcxproj.filters +++ b/src/core-tests/core-tests.vcxproj.filters @@ -2,12 +2,12 @@ - - - - - + + - + + + + \ No newline at end of file diff --git a/src/core-tests/spu_tests.cpp b/src/core-tests/spu_tests.cpp index a7a7437ae..c95eecc99 100644 --- a/src/core-tests/spu_tests.cpp +++ b/src/core-tests/spu_tests.cpp @@ -338,7 +338,7 @@ static ADPCMDecodeResult DecodeADPCMPaired(const std::array& edata, u8 r s16* output = result.samples.data(); for (u32 i = 0; i < static_cast(edata.size()); i++) { - const u8 data = edata.data[i]; + const u8 data = edata[i]; // extend 4-bit to 16-bit, apply shift from header and mix in previous samples // this is interleaved and whacky to try to maximize instruction-level parallelism, but basically, it's: diff --git a/src/core-tests/stub_cpu.cpp b/src/core-tests/stub_cpu.cpp deleted file mode 100644 index 677ecc375..000000000 --- a/src/core-tests/stub_cpu.cpp +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin -// SPDX-License-Identifier: CC-BY-NC-ND-4.0 - -#include "core/cpu_core.h" -#include "core/system.h" - -CPU::State CPU::g_state; - -bool CPU::SafeReadMemoryByte(VirtualMemoryAddress addr, u8* value) -{ - (void)addr; - *value = 0; - return false; -} - -bool CPU::SafeReadMemoryHalfWord(VirtualMemoryAddress addr, u16* value) -{ - (void)addr; - *value = 0; - return false; -} - -bool CPU::SafeReadMemoryWord(VirtualMemoryAddress addr, u32* value) -{ - (void)addr; - *value = 0; - return false; -} - -bool CPU::SafeWriteMemoryByte(VirtualMemoryAddress addr, u8 value) -{ - return false; -} - -bool CPU::SafeWriteMemoryHalfWord(VirtualMemoryAddress addr, u16 value) -{ - return false; -} - -bool CPU::SafeWriteMemoryWord(VirtualMemoryAddress addr, u32 value) -{ - return false; -} - -void CPU::InvalidateICacheAt(VirtualMemoryAddress address) -{ -} - -u32 System::GetFrameNumber() -{ - return 0; -} - -Controller* System::GetController(u32 slot) -{ - return nullptr; -} diff --git a/src/core-tests/stub_host.cpp b/src/core-tests/stub_host.cpp new file mode 100644 index 000000000..2564a060a --- /dev/null +++ b/src/core-tests/stub_host.cpp @@ -0,0 +1,394 @@ +// SPDX-FileCopyrightText: 2019-2026 Connor McLaughlin +// SPDX-License-Identifier: CC-BY-NC-ND-4.0 + +#include "core/achievements_private.h" +#include "core/core.h" +#include "core/core_private.h" +#include "core/cpu_core_private.h" +#include "core/fullscreenui.h" +#include "core/fullscreenui_widgets.h" +#include "core/game_list.h" +#include "core/gdb_server.h" +#include "core/gpu_backend.h" +#include "core/host.h" +#include "core/performance_counters.h" +#include "core/system_private.h" +#include "core/video_thread_private.h" + +#include "util/http_downloader.h" +#include "util/imgui_manager.h" +#include "util/input_manager.h" +#include "util/translation.h" +#include "util/window_info.h" + +#include "common/log.h" +#include "common/time_helpers.h" + +LOG_CHANNEL(Host); + +void Host::OnSettingsReloaded() +{ +} + +void Host::CommitBaseSettingChanges() +{ +} + +bool Host::ResourceFileExists(std::string_view filename, bool allow_override) +{ + return false; +} + +std::optional> Host::ReadResourceFile(std::string_view filename, bool allow_override, Error* error) +{ + return std::nullopt; +} + +std::optional Host::ReadResourceFileToString(std::string_view filename, bool allow_override, Error* error) +{ + return std::nullopt; +} + +std::optional Host::GetResourceFileTimestamp(std::string_view filename, bool allow_override) +{ + return std::nullopt; +} + +void Host::ReportFatalError(std::string_view title, std::string_view message) +{ + ERROR_LOG("ReportFatalError: {}", message); + abort(); +} + +void Host::ReportErrorAsync(std::string_view title, std::string_view message) +{ + if (!title.empty() && !message.empty()) + ERROR_LOG("ReportErrorAsync: {}: {}", title, message); + else if (!message.empty()) + ERROR_LOG("ReportErrorAsync: {}", message); +} + +void Host::ReportStatusMessage(std::string_view message) +{ + INFO_LOG("ReportStatusMessage: {}", message); +} + +void Host::ConfirmMessageAsync(std::string_view icon, std::string_view title, std::string_view message, + ConfirmMessageAsyncCallback callback, std::string_view yes_text, + std::string_view no_text) +{ + if (!title.empty() && !message.empty()) + ERROR_LOG("ConfirmMessage: {}: {}", title, message); + else if (!message.empty()) + ERROR_LOG("ConfirmMessage: {}", message); + + callback(true); +} + +void Host::ReportDebuggerEvent(CPU::DebuggerEvent event, std::string_view message) +{ + ERROR_LOG("ReportDebuggerEvent: {}", message); +} + +std::span> Host::GetAvailableLanguageList() +{ + return {}; +} + +const char* Host::GetLanguageName(std::string_view language_code) +{ + return ""; +} + +bool Host::ChangeLanguage(const char* new_language) +{ + return false; +} + +s32 Host::Internal::GetTranslatedStringImpl(std::string_view context, std::string_view msg, + std::string_view disambiguation, char* tbuf, size_t tbuf_space) +{ + if (msg.size() > tbuf_space) + return -1; + else if (msg.empty()) + return 0; + + std::memcpy(tbuf, msg.data(), msg.size()); + return static_cast(msg.size()); +} + +std::string Host::TranslatePluralToString(const char* context, const char* msg, const char* disambiguation, int count) +{ + TinyString count_str = TinyString::from_format("{}", count); + + std::string ret(msg); + for (;;) + { + std::string::size_type pos = ret.find("%n"); + if (pos == std::string::npos) + break; + + ret.replace(pos, pos + 2, count_str.view()); + } + + return ret; +} + +TinyString Host::TranslatePluralToTinyString(const char* context, const char* msg, const char* disambiguation, + int count) +{ + TinyString ret(msg); + ret.replace("%n", TinyString::from_format("{}", count)); + return ret; +} + +SmallString Host::TranslatePluralToSmallString(const char* context, const char* msg, const char* disambiguation, + int count) +{ + SmallString ret(msg); + ret.replace("%n", TinyString::from_format("{}", count)); + return ret; +} + +static TinyString FormatDateOrTime(const char* format, std::time_t timestamp) +{ + TinyString ret; + if (const std::optional ltime = Common::LocalTime(timestamp)) + ret.resize(static_cast(std::strftime(ret.data(), ret.buffer_size(), format, <ime.value()))); + else + ret = "Invalid"; + + return ret; +} + +TinyString Host::FormatDate(std::time_t timestamp, bool long_format) +{ + return FormatDateOrTime(long_format ? "%A %B %e %Y" : "%x", timestamp); +} + +TinyString Host::FormatTime(std::time_t timestamp, bool long_format) +{ + return FormatDateOrTime("%X", timestamp); +} + +TinyString Host::FormatDateTime(std::time_t timestamp, bool long_format) +{ + return FormatDateOrTime(long_format ? "%c" : "%X %x", timestamp); +} + +void Host::OnSystemStarting() +{ +} + +void Host::OnSystemStarted() +{ +} + +void Host::OnSystemStopping() +{ +} + +void Host::OnSystemDestroyed() +{ +} + +void Host::OnSystemPaused() +{ +} + +void Host::OnSystemResumed() +{ +} + +void Host::OnSystemAbnormalShutdown(const std::string_view reason) +{ +} + +void Host::OnVideoThreadRunIdleChanged(bool is_active) +{ +} + +bool Host::SetScreensaverInhibit(bool inhibit, Error* error) +{ + return false; +} + +void Host::OnPerformanceCountersUpdated(const GPUBackend* gpu_backend) +{ +} + +void Host::OnSystemGameChanged(const std::string& disc_path, const std::string& game_serial, + const std::string& game_name, GameHash hash) +{ +} + +void Host::OnSystemUndoStateAvailabilityChanged(bool available, u64 timestamp) +{ +} + +void Host::OnMediaCaptureStarted(MediaCaptureMode mode) +{ +} + +void Host::OnMediaCaptureStopped() +{ +} + +void Host::OnHTTPDownloaderActiveChanged(bool active) +{ +} + +void Host::OnGDBServerActiveClientsChanged(bool has_clients) +{ +} + +void Host::PumpMessagesOnCoreThread() +{ +} + +void Host::RunOnCoreThread(std::function function, bool block /* = false */) +{ + function(); +} + +void Host::RunOnUIThread(std::function function, bool block /* = false */) +{ + function(); +} + +void Host::RequestResizeHostDisplay(s32 width, s32 height) +{ +} + +void Host::SetDefaultSettings(SettingsInterface& si) +{ +} + +void Host::OnSettingsResetToDefault(bool host, bool system, bool controller) +{ +} + +void Host::RequestExitApplication(bool save_state_if_running) +{ +} + +void Host::RequestExitBigPicture() +{ +} + +void Host::RequestSystemShutdown(bool allow_confirm, bool save_state, bool check_memcard_busy) +{ +} + +std::optional Host::AcquireRenderWindow(RenderAPI render_api, bool fullscreen, bool exclusive_fullscreen, + Error* error) +{ + return std::nullopt; +} + +WindowInfoType Host::GetRenderWindowInfoType() +{ + return WindowInfoType::Surfaceless; +} + +void Host::ReleaseRenderWindow() +{ +} + +bool Host::CanChangeFullscreenMode(bool new_fullscreen_state) +{ + return false; +} + +bool Host::CreateAuxiliaryRenderWindow(s32 x, s32 y, u32 width, u32 height, std::string_view title, + std::string_view icon_name, AuxiliaryRenderWindowUserData userdata, + AuxiliaryRenderWindowHandle* handle, WindowInfo* wi, Error* error) +{ + return false; +} + +void Host::DestroyAuxiliaryRenderWindow(AuxiliaryRenderWindowHandle handle, s32* pos_x /* = nullptr */, + s32* pos_y /* = nullptr */, u32* width /* = nullptr */, + u32* height /* = nullptr */) +{ +} + +void Host::FrameDoneOnVideoThread(GPUBackend* gpu_backend, u32 frame_number) +{ +} + +void Host::OpenURL(std::string_view url) +{ +} + +std::string Host::GetClipboardText() +{ + return {}; +} + +bool Host::CopyTextToClipboard(std::string_view text) +{ + return false; +} + +void Host::SetMouseMode(bool relative, bool hide_cursor) +{ +} + +void Host::OnAchievementsLoginRequested(Achievements::LoginRequestReason reason) +{ +} + +void Host::OnAchievementsLoginSuccess(const char* username, u32 points, u32 casual_points, u32 unread_messages) +{ +} + +void Host::OnAchievementsActiveChanged(bool active) +{ +} + +void Host::OnAchievementsHardcoreModeChanged(bool enabled) +{ +} + +#ifdef RC_CLIENT_SUPPORTS_RAINTEGRATION + +void Host::OnRAIntegrationMenuChanged() +{ +} + +#endif + +const char* Host::GetDefaultFullscreenUITheme() +{ + return ""; +} + +void Host::AddFixedInputBindings(const SettingsInterface& si) +{ +} + +void Host::OnInputDeviceConnected(InputBindingKey key, std::string_view identifier, std::string_view device_name) +{ +} + +void Host::OnInputDeviceDisconnected(InputBindingKey key, std::string_view identifier) +{ +} + +std::optional Host::GetTopLevelWindowInfo() +{ + return std::nullopt; +} + +void Host::RefreshGameListAsync(bool invalidate_cache) +{ +} + +void Host::CancelGameListRefresh() +{ +} + +void Host::OnGameListEntriesChanged(std::span changed_indices) +{ +} diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 52f5c5d6d..a7786f69f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -163,7 +163,7 @@ set(RECOMPILER_SRCS target_precompile_headers(core PRIVATE "pch.h") target_include_directories(core PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/..") -target_link_libraries(core PUBLIC Threads::Threads common util) +target_link_libraries(core PUBLIC Threads::Threads common util scmversion) target_link_libraries(core PRIVATE xxhash imgui rapidyaml rcheevos cpuinfo::cpuinfo ZLIB::ZLIB zstd::libzstd_shared speex_resampler_headers) if(CPU_ARCH_X64)