UnitTests: Compile with PCSX2 core library

Instead of shoehorning GS source files into the unit tests, we link with
the full PCSX2 core library. We stub out all the Host functions, as,
well, there isn't one, and they may be indirectly referenced.
This commit is contained in:
Stenzek 2023-01-03 22:23:10 +10:00 committed by refractionpcsx2
parent c44266eb82
commit 33e7bcbdb8
9 changed files with 448 additions and 150 deletions

View File

@ -131,6 +131,7 @@ jobs:
done
- name: Run Tests
if: inputs.gui == 'Qt'
working-directory: build
run: make -j$(getconf _NPROCESSORS_ONLN) unittests

View File

@ -105,6 +105,13 @@ jobs:
msbuild "PCSX2_qt.sln" /m /v:m /p:Configuration="${{ inputs.configuration }}" /p:Platform="${{ inputs.platform }}"
)
- name: Run Tests
if: inputs.configuration == 'CMake'
shell: cmd
run: |
call "%ProgramFiles%\Microsoft Visual Studio\2022\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
cmake --build build --config Release --target unittests
- name: Upload artifact
uses: actions/upload-artifact@v3
with:

View File

@ -1,60 +1,19 @@
option(ENABLE_UNSUPPORTED_TESTS "Include tests that require instructions not supported by this computer" OFF)
add_library(unittests-stub-host STATIC
StubHost.cpp
)
target_link_libraries(unittests-stub-host PUBLIC
PCSX2_FLAGS
PCSX2
common
)
set(avxdetect_code "
#ifdef __GNUC__
#include <cpuid.h>
void cpuid(int result[4], int leaf, int subleaf) {
__cpuid_count(leaf, subleaf, result[0], result[1], result[2], result[3]);
}
#else
#include <intrin.h>
#define cpuid __cpuidex
#endif
int test(int leaf, int subleaf, int reg, int bit) {
int res[4];
cpuid(res, 0, 0);
if (res[0] < leaf) { return 0; }
cpuid(res, leaf, subleaf);
return !!(res[reg] & (1 << bit));
}
int main() {
if (test(7, 0, 1, 5) /* AVX2 */) return 51;
if (test(1, 0, 2, 28) /* AVX */) return 50;
if (test(1, 0, 2, 19) /* SSE41 */) return 41;
return 0;
}
")
if(ENABLE_UNSUPPORTED_TESTS)
set(native_vector_isa 99)
else()
set(cc_backup ${CMAKE_CROSSCOMPILING})
set(CMAKE_CROSSCOMPILING 0)
file(WRITE "${CMAKE_BINARY_DIR}/avxdetect.c" "${avxdetect_code}")
try_run(
native_vector_isa
compile_result_unused
"${CMAKE_BINARY_DIR}"
"${CMAKE_BINARY_DIR}/avxdetect.c"
if(APPLE)
# For some reason this doesn't get pulled in implicitly...
target_link_libraries(unittests-stub-host PUBLIC
"-framework Foundation"
"-framework Cocoa"
)
set(CMAKE_CROSSCOMPILING ${cc_backup})
endif()
if (MSVC)
set(compile_options_avx /arch:AVX)
set(compile_options_avx2 /arch:AVX2)
set(definitions_sse4 __SSE4_1__)
set(definitions_avx __SSE4_1__)
set(definitions_avx2 __SSE4_1__)
else()
set(compile_options_sse4 -msse4.1)
set(compile_options_avx -mavx)
set(compile_options_avx2 -mavx2 -mbmi -mbmi2)
endif()
set(isa_number_sse4 41)
set(isa_number_avx 50)
set(isa_number_avx2 51)
enable_testing()
add_custom_target(unittests)
@ -62,8 +21,66 @@ add_custom_command(TARGET unittests POST_BUILD COMMAND ${CMAKE_CTEST_COMMAND})
macro(add_pcsx2_test target)
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN})
target_link_libraries(${target} PRIVATE gtest_main common)
target_compile_definitions(${target} PRIVATE "PCSX2_CORE")
target_link_libraries(${target} PRIVATE gtest_main unittests-stub-host)
add_dependencies(unittests ${target})
add_test(NAME ${target} COMMAND ${target})
endmacro()
macro(add_pcsx2_multi_isa_test target)
if(DISABLE_ADVANCE_SIMD)
# CMake pukes if there's no sources for an executable..
add_executable(${target} EXCLUDE_FROM_ALL "../StubHost.cpp")
target_link_libraries(${target} PUBLIC
PCSX2_FLAGS
PCSX2
common
gtest
gtest_main
)
if(APPLE)
target_link_libraries(${target} PUBLIC
"-framework Foundation"
"-framework Cocoa"
)
endif()
if(WIN32)
set(compile_options_avx2 /arch:AVX2)
set(compile_options_avx /arch:AVX)
elseif(USE_GCC)
# GCC can't inline into multi-isa functions if we use march and mtune, but can if we use feature flags
set(compile_options_avx2 -msse4.1 -mavx -mavx2 -mbmi -mbmi2 -mfma)
set(compile_options_avx -msse4.1 -mavx)
set(compile_options_sse4 -msse4.1)
else()
set(compile_options_avx2 -march=haswell -mtune=haswell)
set(compile_options_avx -march=sandybridge -mtune=sandybridge)
set(compile_options_sse4 -msse4.1 -mtune=nehalem)
endif()
# ODR violation time!
# Everything would be fine if we only defined things in cpp files, but C++ tends to like inline functions (STL anyone?)
# Each ISA will bring with it its own copies of these inline header functions, and the linker gets to choose whichever one it wants! Not fun if the linker chooses the avx2 version and uses it with everything
# Thankfully, most linkers don't choose at random. When presented with a bunch of .o files, most linkers seem to choose the first implementation they see, so make sure you order these from oldest to newest
# Note: ld64 (macOS's linker) does not act the same way when presented with .a files, unless linked with `-force_load` (cmake WHOLE_ARCHIVE).
set(is_first_isa "1")
foreach(isa "sse4" "avx" "avx2")
add_library(${target}-${isa} STATIC ${ARGN})
target_link_libraries(${target}-${isa} PRIVATE PCSX2_FLAGS gtest)
target_compile_definitions(${target}-${isa} PRIVATE MULTI_ISA_UNSHARED_COMPILATION=isa_${isa} MULTI_ISA_IS_FIRST=${is_first_isa} ${pcsx2_defs_${isa}})
target_compile_options(${target}-${isa} PRIVATE ${compile_options_${isa}})
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL 3.24)
target_link_libraries(${target} PRIVATE $<LINK_LIBRARY:WHOLE_ARCHIVE,${target}-${isa}>)
elseif(APPLE)
message(FATAL_ERROR "MacOS builds with DISABLE_ADVANCE_SIMD=ON require CMake 3.24")
else()
target_link_libraries(${target} PRIVATE ${target}-${isa})
endif()
set(is_first_isa "0")
endforeach()
else()
add_executable(${target} EXCLUDE_FROM_ALL ${ARGN})
endif()
target_link_libraries(${target} PRIVATE gtest_main unittests-stub-host)
add_dependencies(unittests ${target})
add_test(NAME ${target} COMMAND ${target})
endmacro()

View File

@ -1,33 +1,3 @@
foreach(isa "sse4" "avx" "avx2")
set(GSDir ${CMAKE_SOURCE_DIR}/pcsx2/GS)
if(${native_vector_isa} LESS ${isa_number_${isa}})
# Skip unsupported tests
continue()
endif()
add_pcsx2_test(swizzle_test_${isa}
swizzle_test_main.cpp
swizzle_test_nops.cpp
${GSDir}/GSBlock.cpp
${GSDir}/GSBlock.h
${GSDir}/GSClut.cpp
${GSDir}/GSClut.h
${GSDir}/GSTables.cpp
${GSDir}/GSTables.h)
target_include_directories(swizzle_test_${isa} PRIVATE ${GSDir} ${CMAKE_SOURCE_DIR}/pcsx2/ ${CMAKE_SOURCE_DIR}/pcsx2/gui)
if(WIN32)
target_include_directories(swizzle_test_${isa} PRIVATE ${CMAKE_SOURCE_DIR}/3rdparty)
endif()
target_compile_options(swizzle_test_${isa} PRIVATE ${compile_options_${isa}})
target_compile_definitions(swizzle_test_${isa} PRIVATE ${definitions_${isa}})
if(WIN32)
target_compile_definitions(swizzle_test_${isa} PRIVATE
WINVER=0x0603
_WIN32_WINNT=0x0603
WIN32_LEAN_AND_MEAN
)
endif()
endforeach()
add_pcsx2_multi_isa_test(swizzle_test
swizzle_test_main.cpp
)

View File

@ -14,13 +14,53 @@
*/
#include "PrecompiledHeader.h"
#include "GSBlock.h"
#include "GSClut.h"
#include "MultiISA.h"
#include "pcsx2/GS/GSBlock.h"
#include "pcsx2/GS/GSClut.h"
#include "pcsx2/GS/MultiISA.h"
#include <gtest/gtest.h>
#include <string.h>
using namespace CURRENT_ISA;
#ifdef MULTI_ISA_UNSHARED_COMPILATION
enum class TestISA
{
isa_sse4,
isa_avx,
isa_avx2,
isa_native,
};
static bool CheckCapabilities(TestISA required_caps)
{
x86caps.Identify();
if (required_caps == TestISA::isa_avx && !x86caps.hasAVX)
return false;
if (required_caps == TestISA::isa_avx2 && !x86caps.hasAVX2)
return false;
return true;
}
#define MULTI_ISA_STRINGIZE_(x) #x
#define MULTI_ISA_STRINGIZE(x) MULTI_ISA_STRINGIZE_(x)
#define MULTI_ISA_CONCAT_(a, b) a##b
#define MULTI_ISA_CONCAT(a, b) MULTI_ISA_CONCAT_(a, b)
#define MULTI_ISA_TEST(group, name) TEST(MULTI_ISA_CONCAT(MULTI_ISA_CONCAT(MULTI_ISA_UNSHARED_COMPILATION, _), group), name)
#define SKIP_IF_UNSUPPORTED() \
if (!CheckCapabilities(TestISA::MULTI_ISA_UNSHARED_COMPILATION)) { \
GTEST_SKIP() << "Host CPU does not support " MULTI_ISA_STRINGIZE(MULTI_ISA_UNSHARED_COMPILATION); \
}
#else
#define MULTI_ISA_TEST(group, name) TEST(group, name)
#define SKIP_IF_UNSUPPORTED()
#endif
MULTI_ISA_UNSHARED_START
static void swizzle(const u8* table, u8* dst, const u8* src, int bpp, bool deswizzle)
{
@ -272,8 +312,10 @@ static void assertEqual(const TestData& expected, const TestData& actual, const
EXPECT_STREQ(estr.c_str(), astr.c_str()) << "Unexpected " << name;
}
TEST(ReadTest, Read32)
MULTI_ISA_TEST(ReadTest, Read32)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -282,8 +324,10 @@ TEST(ReadTest, Read32)
});
}
TEST(WriteTest, Write32)
MULTI_ISA_TEST(WriteTest, Write32)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, false);
@ -292,8 +336,10 @@ TEST(WriteTest, Write32)
});
}
TEST(ReadTest, Read16)
MULTI_ISA_TEST(ReadTest, Read16)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable16[0][0], data, 16, true);
@ -302,8 +348,10 @@ TEST(ReadTest, Read16)
});
}
TEST(ReadAndExpandTest, Read16)
MULTI_ISA_TEST(ReadAndExpandTest, Read16)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
GIFRegTEXA texa = {0};
@ -316,8 +364,10 @@ TEST(ReadAndExpandTest, Read16)
});
}
TEST(ReadAndExpandTest, Read16AEM)
MULTI_ISA_TEST(ReadAndExpandTest, Read16AEM)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
// Actually test AEM
@ -335,8 +385,10 @@ TEST(ReadAndExpandTest, Read16AEM)
});
}
TEST(WriteTest, Write16)
MULTI_ISA_TEST(WriteTest, Write16)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable16[0][0], data, 16, false);
@ -345,8 +397,10 @@ TEST(WriteTest, Write16)
});
}
TEST(ReadTest, Read8)
MULTI_ISA_TEST(ReadTest, Read8)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable8[0][0], data, 8, true);
@ -355,8 +409,10 @@ TEST(ReadTest, Read8)
});
}
TEST(ReadAndExpandTest, Read8)
MULTI_ISA_TEST(ReadAndExpandTest, Read8)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable8[0][0], data, 8, true);
@ -366,8 +422,10 @@ TEST(ReadAndExpandTest, Read8)
});
}
TEST(WriteTest, Write8)
MULTI_ISA_TEST(WriteTest, Write8)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable8[0][0], data, 8, false);
@ -376,8 +434,10 @@ TEST(WriteTest, Write8)
});
}
TEST(ReadTest, Read8H)
MULTI_ISA_TEST(ReadTest, Read8H)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -387,8 +447,10 @@ TEST(ReadTest, Read8H)
});
}
TEST(ReadAndExpandTest, Read8H)
MULTI_ISA_TEST(ReadAndExpandTest, Read8H)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -398,8 +460,10 @@ TEST(ReadAndExpandTest, Read8H)
});
}
TEST(WriteTest, Write8H)
MULTI_ISA_TEST(WriteTest, Write8H)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzleH(&columnTable32[0][0], data, 8, 24);
@ -408,8 +472,10 @@ TEST(WriteTest, Write8H)
});
}
TEST(ReadTest, Read4)
MULTI_ISA_TEST(ReadTest, Read4)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle4(&columnTable4[0][0], data, true);
@ -418,8 +484,10 @@ TEST(ReadTest, Read4)
});
}
TEST(ReadTest, Read4P)
MULTI_ISA_TEST(ReadTest, Read4P)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle4(&columnTable4[0][0], data, true);
@ -429,8 +497,10 @@ TEST(ReadTest, Read4P)
});
}
TEST(ReadAndExpandTest, Read4)
MULTI_ISA_TEST(ReadAndExpandTest, Read4)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle4(&columnTable4[0][0], data, true);
@ -440,8 +510,10 @@ TEST(ReadAndExpandTest, Read4)
});
}
TEST(WriteTest, Write4)
MULTI_ISA_TEST(WriteTest, Write4)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle4(&columnTable4[0][0], data, false);
@ -450,8 +522,10 @@ TEST(WriteTest, Write4)
});
}
TEST(ReadTest, Read4HH)
MULTI_ISA_TEST(ReadTest, Read4HH)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -461,8 +535,10 @@ TEST(ReadTest, Read4HH)
});
}
TEST(ReadAndExpandTest, Read4HH)
MULTI_ISA_TEST(ReadAndExpandTest, Read4HH)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -472,8 +548,10 @@ TEST(ReadAndExpandTest, Read4HH)
});
}
TEST(WriteTest, Write4HH)
MULTI_ISA_TEST(WriteTest, Write4HH)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzleH(&columnTable32[0][0], data, 4, 28);
@ -482,8 +560,10 @@ TEST(WriteTest, Write4HH)
});
}
TEST(ReadTest, Read4HL)
MULTI_ISA_TEST(ReadTest, Read4HL)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -493,8 +573,10 @@ TEST(ReadTest, Read4HL)
});
}
TEST(ReadAndExpandTest, Read4HL)
MULTI_ISA_TEST(ReadAndExpandTest, Read4HL)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzle(&columnTable32[0][0], data, 32, true);
@ -504,8 +586,10 @@ TEST(ReadAndExpandTest, Read4HL)
});
}
TEST(WriteTest, Write4HL)
MULTI_ISA_TEST(WriteTest, Write4HL)
{
SKIP_IF_UNSUPPORTED();
runTest([](TestData data)
{
TestData expected = swizzleH(&columnTable32[0][0], data, 4, 24);
@ -513,3 +597,5 @@ TEST(WriteTest, Write4HL)
assertEqual(expected, data, "Write4HL", 8, 8, 32);
});
}
MULTI_ISA_UNSHARED_END

View File

@ -1,33 +0,0 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
// This file defines functions that are linked to by files used in swizzle tests but not actually used in swizzle tests, in order to make linkers happy
#include "PrecompiledHeader.h"
#include "GSBlock.h"
#include "GSClut.h"
#include "GSLocalMemory.h"
GSLocalMemory::psm_t GSLocalMemory::m_psm[64];
void* vmalloc(size_t size, bool code)
{
abort();
}
void vmfree(void* ptr, size_t size)
{
abort();
}

243
tests/ctest/StubHost.cpp Normal file
View File

@ -0,0 +1,243 @@
/* PCSX2 - PS2 Emulator for PCs
* Copyright (C) 2002-2021 PCSX2 Dev Team
*
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with PCSX2.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "pcsx2/Frontend/CommonHost.h"
#include "pcsx2/Frontend/ImGuiManager.h"
#include "pcsx2/Frontend/InputManager.h"
#include "pcsx2/GS.h"
#include "pcsx2/Host.h"
#include "pcsx2/HostDisplay.h"
#include "pcsx2/HostSettings.h"
#include "pcsx2/VMManager.h"
#ifdef ENABLE_ACHIEVEMENTS
#include "pcsx2/Frontend/Achievements.h"
#endif
void Host::CommitBaseSettingChanges()
{
}
void Host::LoadSettings(SettingsInterface& si, std::unique_lock<std::mutex>& lock)
{
}
void Host::CheckForSettingsChanges(const Pcsx2Config& old_config)
{
}
bool Host::RequestResetSettings(bool folders, bool core, bool controllers, bool hotkeys, bool ui)
{
return false;
}
void Host::SetDefaultUISettings(SettingsInterface& si)
{
}
std::optional<std::vector<u8>> Host::ReadResourceFile(const char* filename)
{
return std::nullopt;
}
std::optional<std::string> Host::ReadResourceFileToString(const char* filename)
{
return std::nullopt;
}
std::optional<std::time_t> Host::GetResourceFileTimestamp(const char* filename)
{
return std::nullopt;
}
void Host::ReportErrorAsync(const std::string_view& title, const std::string_view& message)
{
}
bool Host::ConfirmMessage(const std::string_view& title, const std::string_view& message)
{
return true;
}
void Host::OpenURL(const std::string_view& url)
{
}
bool Host::CopyTextToClipboard(const std::string_view& text)
{
return false;
}
void Host::BeginTextInput()
{
}
void Host::EndTextInput()
{
}
std::optional<WindowInfo> Host::GetTopLevelWindowInfo()
{
return std::nullopt;
}
void Host::OnInputDeviceConnected(const std::string_view& identifier, const std::string_view& device_name)
{
}
void Host::OnInputDeviceDisconnected(const std::string_view& identifier)
{
}
void Host::SetRelativeMouseMode(bool enabled)
{
}
bool Host::AcquireHostDisplay(RenderAPI api, bool clear_state_on_fail)
{
return false;
}
void Host::ReleaseHostDisplay(bool clear_state)
{
}
bool Host::BeginPresentFrame(bool frame_skip)
{
return false;
}
void Host::EndPresentFrame()
{
}
void Host::ResizeHostDisplay(u32 new_window_width, u32 new_window_height, float new_window_scale)
{
}
void Host::UpdateHostDisplay()
{
}
void Host::RequestResizeHostDisplay(s32 width, s32 height)
{
}
void Host::OnVMStarting()
{
}
void Host::OnVMStarted()
{
}
void Host::OnVMDestroyed()
{
}
void Host::OnVMPaused()
{
}
void Host::OnVMResumed()
{
}
void Host::OnGameChanged(const std::string& disc_path, const std::string& elf_override, const std::string& game_serial,
const std::string& game_name, u32 game_crc)
{
}
void Host::OnPerformanceMetricsUpdated()
{
}
void Host::OnSaveStateLoading(const std::string_view& filename)
{
}
void Host::OnSaveStateLoaded(const std::string_view& filename, bool was_successful)
{
}
void Host::OnSaveStateSaved(const std::string_view& filename)
{
}
void Host::InvalidateSaveStateCache()
{
}
void Host::RunOnCPUThread(std::function<void()> function, bool block /* = false */)
{
}
void Host::RefreshGameListAsync(bool invalidate_cache)
{
}
void Host::CancelGameListRefresh()
{
}
bool Host::IsFullscreen()
{
return false;
}
void Host::SetFullscreen(bool enabled)
{
}
void Host::RequestExit(bool save_state_if_running)
{
}
void Host::RequestVMShutdown(bool allow_confirm, bool allow_save_state, bool default_save_state)
{
}
void Host::CPUThreadVSync()
{
}
#ifdef ENABLE_ACHIEVEMENTS
void Host::OnAchievementsRefreshed()
{
}
#endif
std::optional<u32> InputManager::ConvertHostKeyboardStringToCode(const std::string_view& str)
{
return std::nullopt;
}
std::optional<std::string> InputManager::ConvertHostKeyboardCodeToString(u32 code)
{
return std::nullopt;
}
SysMtgsThread& GetMTGS()
{
throw std::exception();
}
//////////////////////////////////////////////////////////////////////////
// Interface Stuff
//////////////////////////////////////////////////////////////////////////
const IConsoleWriter* PatchesCon = &Console;
BEGIN_HOTKEY_LIST(g_host_hotkeys)
END_HOTKEY_LIST()

View File

@ -1 +1,4 @@
add_pcsx2_test(common_test path_tests.cpp string_util_tests.cpp)
add_pcsx2_test(common_test
path_tests.cpp
string_util_tests.cpp
)

View File

@ -1 +1,5 @@
add_pcsx2_test(x86emitter_test codegen_tests.cpp codegen_tests_main.cpp codegen_tests.h)
add_pcsx2_test(x86emitter_test
codegen_tests.cpp
codegen_tests_main.cpp
codegen_tests.h
)