Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,24 @@ add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/utf-8>)
add_compile_options($<$<CXX_COMPILER_ID:MSVC>:/Zc:preprocessor>)

if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(NOT CMAKE_VS_PLATFORM_NAME)
set(CMAKE_VS_PLATFORM_NAME "x64")
endif()

if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$")
set(SOH_WINDOWS_ARM64 TRUE)
else()
set(SOH_WINDOWS_ARM64 FALSE)
endif()

include(CMake/automate-vcpkg.cmake)

set(VCPKG_TRIPLET x64-windows-static)
set(VCPKG_TARGET_TRIPLET x64-windows-static)
if(SOH_WINDOWS_ARM64)
set(VCPKG_TRIPLET arm64-windows-static)
set(VCPKG_TARGET_TRIPLET arm64-windows-static)
endif()

vcpkg_bootstrap()
vcpkg_install_packages(zlib bzip2 libzip libpng sdl2 sdl2-net glew glfw3 nlohmann-json tinyxml2 spdlog libogg libvorbis opus opusfile)
Expand All @@ -103,7 +117,8 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")

if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"
OR SOH_WINDOWS_ARM64))
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
endif()
endif()
Expand Down
25 changes: 18 additions & 7 deletions soh/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,21 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if(NOT CMAKE_VS_PLATFORM_NAME)
set(CMAKE_VS_PLATFORM_NAME "x64")
endif()
if("${CMAKE_VS_PLATFORM_NAME}" MATCHES "^[Aa][Rr][Mm]64$")
set(SOH_WINDOWS_ARM64 TRUE)
else()
set(SOH_WINDOWS_ARM64 FALSE)
endif()
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64" OR SOH_WINDOWS_ARM64)
set(SOH_WINDOWS_64BIT TRUE)
else()
set(SOH_WINDOWS_64BIT FALSE)
endif()
message("${CMAKE_VS_PLATFORM_NAME} architecture in use")

if(NOT ("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64"
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"))
OR "${CMAKE_VS_PLATFORM_NAME}" STREQUAL "Win32"
OR SOH_WINDOWS_ARM64))
message(FATAL_ERROR "${CMAKE_VS_PLATFORM_NAME} arch is not supported!")
endif()
endif()
Expand Down Expand Up @@ -235,7 +246,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
set_target_properties(${PROJECT_NAME} PROPERTIES
VS_GLOBAL_KEYWORD "Win32Proj"
)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
set_target_properties(${PROJECT_NAME} PROPERTIES
INTERPROCEDURAL_OPTIMIZATION_RELEASE "TRUE"
)
Expand All @@ -259,7 +270,7 @@ endif()
################################################################################
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
get_property(MSVC_RUNTIME_LIBRARY_DEFAULT TARGET ${PROJECT_NAME} PROPERTY MSVC_RUNTIME_LIBRARY)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
string(CONCAT "MSVC_RUNTIME_LIBRARY_STR"
$<$<CONFIG:Debug>:
MultiThreadedDebug
Expand Down Expand Up @@ -329,7 +340,7 @@ target_include_directories(${PROJECT_NAME} PRIVATE assets
)

if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_compile_definitions(${PROJECT_NAME} PRIVATE
"$<$<CONFIG:Debug>:"
"_DEBUG;"
Expand Down Expand Up @@ -410,7 +421,7 @@ endif()
# Compile and link options
################################################################################
if(MSVC)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_compile_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/w;
Expand Down Expand Up @@ -447,7 +458,7 @@ if(MSVC)
${DEFAULT_CXX_EXCEPTION_HANDLING}
)
endif()
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
target_link_options(${PROJECT_NAME} PRIVATE
$<$<CONFIG:Debug>:
/INCREMENTAL
Expand Down Expand Up @@ -635,7 +646,7 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
link_libraries(Opus::opus)
find_package(OpusFile CONFIG REQUIRED)
link_libraries(OpusFile::opusfile CONFIG REQUIRED)
if("${CMAKE_VS_PLATFORM_NAME}" STREQUAL "x64")
if(SOH_WINDOWS_64BIT)
set(ADDITIONAL_LIBRARY_DEPENDENCIES
"libultraship;"
"ZAPDLib;"
Expand Down
31 changes: 25 additions & 6 deletions soh/soh/Extractor/FastCrc32C.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@
#pragma GCC target("sse4.2")
#endif

// Include headers for the CRC32 intrinsic and cpuid instruction on windows. No need to do any other checks because it
// assumes the target will support CRC32
// Include headers for the CRC32 intrinsic and CPU feature checks on Windows x86/x64/ARM64.
#ifdef _WIN32
#include <immintrin.h>
#if defined(_M_X64) || defined(_M_IX86) || defined(_M_ARM64)
#include <intrin.h>
#if defined(_M_X64) || defined(_M_IX86)
#include <immintrin.h>
#elif defined(_M_ARM64)
#include <Windows.h>
#endif
#else
#define NO_CRC_INTRIN
#endif
// Same as above but these platforms use slightly different headers
#elif ((defined(__GNUC__) && (defined(__x86_64__) || defined(__i386__))))
#include <nmmintrin.h>
Expand All @@ -27,12 +34,18 @@
#define NO_CRC_INTRIN
#endif

#if defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
#if defined(_MSC_VER) && defined(_M_ARM64)
#define INTRIN_CRC32_64(crc, data) crc = __crc32cd(crc, data)
#define INTRIN_CRC32_32(crc, data) crc = __crc32cw(crc, data)
#define INTRIN_CRC32_16(crc, data) crc = __crc32ch(crc, data)
#define INTRIN_CRC32_8(crc, data) crc = __crc32cb(crc, data)
#elif defined(__aarch64__) && defined(__ARM_FEATURE_CRC32)
#define INTRIN_CRC32_64(crc, value) __asm__("crc32cx %w[c], %w[c], %x[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_32(crc, value) __asm__("crc32cw %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_16(crc, value) __asm__("crc32ch %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#define INTRIN_CRC32_8(crc, value) __asm__("crc32cb %w[c], %w[c], %w[v]" : [c] "+r"(crc) : [v] "r"(value))
#elif defined(__GNUC__) || defined(_MSC_VER)
#elif ((defined(__GNUC__) || defined(_MSC_VER)) && \
(defined(_M_X64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__)))
#define INTRIN_CRC32_64(crc, data) crc = _mm_crc32_u64(crc, data)
#define INTRIN_CRC32_32(crc, data) crc = _mm_crc32_u32(crc, data)
#define INTRIN_CRC32_16(crc, data) crc = _mm_crc32_u16(crc, data)
Expand Down Expand Up @@ -78,7 +91,7 @@ static uint32_t CRC32IntrinImpl(unsigned char* data, size_t dataSize) {
uint32_t ret = 0xFFFFFFFF;
int64_t sizeSigned = dataSize;
// Only 64bit platforms support doing a CRC32 operation on a 64bit value
#if defined(_M_X64) || defined(__x86_64__) || defined(__aarch64__)
#if defined(_M_X64) || defined(_M_ARM64) || defined(__x86_64__) || defined(__aarch64__)
while ((sizeSigned -= sizeof(uint64_t)) >= 0) {
INTRIN_CRC32_64(ret, *(uint64_t*)data);
data += sizeof(uint64_t);
Expand Down Expand Up @@ -122,6 +135,11 @@ static uint32_t CRC32TableImpl(unsigned char* data, size_t dataSize) {
uint32_t CRC32C(unsigned char* data, size_t dataSize) {
#ifndef NO_CRC_INTRIN
// Test to make sure the CPU supports the CRC32 intrinsic
#if defined(_WIN32) && defined(_M_ARM64)
if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) {
return CRC32IntrinImpl(data, dataSize);
}
#else
unsigned int cpuidData[4];
#ifdef _WIN32
__cpuid(cpuidData, 1);
Expand All @@ -135,6 +153,7 @@ uint32_t CRC32C(unsigned char* data, size_t dataSize) {
if (cpuidData[2] & (1 << 20)) { // bit_SSE4_2
return CRC32IntrinImpl(data, dataSize);
}
#endif
#endif // NO_CRC_INTRIN
return CRC32TableImpl(data, dataSize);
}
Expand Down
1 change: 1 addition & 0 deletions soh/soh/ShipUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <libultraship/libultraship.h>

#ifdef __cplusplus
#include <set>

void LoadGuiTextures();

Expand Down
Loading