diff --git a/src/spice2x/build_all.sh b/src/spice2x/build_all.sh index da2909a..0ff92c8 100755 --- a/src/spice2x/build_all.sh +++ b/src/spice2x/build_all.sh @@ -1,4 +1,4 @@ -#!/bin/bash +#!/usr/bin/env bash # set to EN-US for consistency LANG=en_us_8859_1 @@ -43,10 +43,16 @@ GIT_BRANCH=$(git rev-parse --abbrev-ref HEAD 2> /dev/null || echo "none") GIT_HEAD=$(git rev-parse HEAD || echo "none") TOOLCHAIN_32="${TOOLCHAIN_32:-"/usr/share/mingw/toolchain-i686-w64-mingw32.cmake"}" TOOLCHAIN_64="${TOOLCHAIN_64:-"/usr/share/mingw/toolchain-x86_64-w64-mingw32.cmake"}" +TOOLCHAIN_WINXP_32="${TOOLCHAIN_WINXP_32:-"/opt/llvm-mingw-xp/toolchain-files/cmake/i686-mingw32-clang.cmake"}" +TOOLCHAIN_WINXP_64="${TOOLCHAIN_WINXP_64:-"/opt/llvm-mingw-xp/toolchain-files/cmake/x86_64-mingw32-clang.cmake"}" BUILDDIR_32_RELEASE="./cmake-build-release-32" BUILDDIR_32_DEBUG="./cmake-build-debug-32" BUILDDIR_64_RELEASE="./cmake-build-release-64" BUILDDIR_64_DEBUG="./cmake-build-debug-64" +BUILDDIR_WINXP_32_RELEASE="./cmake-build-release-winxp-32" +BUILDDIR_WINXP_32_DEBUG="./cmake-build-debug-winxp-32" +BUILDDIR_WINXP_64_RELEASE="./cmake-build-release-winxp-64" +BUILDDIR_WINXP_64_DEBUG="./cmake-build-debug-winxp-64" DEBUG=0 OUTDIR="./bin/spice2x" OUTDIR_EXTRAS="./bin/spice2x/extras" @@ -69,14 +75,29 @@ TARGETS_64="spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvEnc BUILD_TYPE="Release" BUILDDIR_32=${BUILDDIR_32_RELEASE} BUILDDIR_64=${BUILDDIR_64_RELEASE} +BUILDDIR_WINXP_32=${BUILDDIR_WINXP_32_RELEASE} +BUILDDIR_WINXP_64=${BUILDDIR_WINXP_64_RELEASE} if ((DEBUG > 0)) then BUILD_TYPE="Debug" BUILDDIR_32=${BUILDDIR_32_DEBUG} BUILDDIR_64=${BUILDDIR_64_DEBUG} + BUILDDIR_WINXP_32=${BUILDDIR_WINXP_32_DEBUG} + BUILDDIR_WINXP_64=${BUILDDIR_WINXP_64_DEBUG} DIST_NAME=$(echo "${DIST_NAME}" | sed 's/\.[^.]*$/-dbg&/') fi +# is the XP-compatible toolchain installed? +XP_MUST_BUILD=0 +BUILD_XP=0 +if [ -f "$TOOLCHAIN_WINXP_32" ] && [ -f "$TOOLCHAIN_WINXP_64" ]; then + BUILD_XP=1; +elif ((XP_MUST_BUILD > 0)) +then + echo "WinXP toolchain not available, aborting" + exit 1 +fi + # determine number of cores CORES=$(nproc) @@ -90,6 +111,13 @@ echo "Git Branch: $GIT_BRANCH" echo "Git Head: $GIT_HEAD" echo "Toolchain for 32bit targets: $TOOLCHAIN_32" echo "Toolchain for 64bit targets: $TOOLCHAIN_64" +if ((BUILD_XP > 0)) +then + echo "Toolchain for WinXP 32bit targets: $TOOLCHAIN_WINXP_32" + echo "Toolchain for WinXP 64bit targets: $TOOLCHAIN_WINXP_64" +else + echo "WinXP toolchain not available, skipping WinXP builds" +fi echo "Distribution Name: $DIST_NAME" echo "Build Type: $BUILD_TYPE" echo "Cores: $CORES" @@ -130,11 +158,58 @@ time ( cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_64} popd > /dev/null + if ((BUILD_XP > 0)) + then + # 32 bit Windows XP + echo "Building 32bit targets (WinXP toolchain)..." + echo "=========================" + if ((CLEAN_BUILD > 0)) + then + rm -rf ${BUILDDIR_WINXP_32} + fi + mkdir -p ${BUILDDIR_WINXP_32} + pushd ${BUILDDIR_WINXP_32} > /dev/null + CXXFLAGS="$CXXFLAGS -DSPICE_XP=1" cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_WINXP_32} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_32} + popd > /dev/null + + # 64 bit Windows XP + echo "" + echo "Building 64bit targets (WinXP toolchain)..." + echo "=========================" + if ((CLEAN_BUILD > 0)) + then + rm -rf ${BUILDDIR_WINXP_64} + fi + mkdir -p ${BUILDDIR_WINXP_64} + pushd ${BUILDDIR_WINXP_64} > /dev/null + CXXFLAGS="$CXXFLAGS -DSPICE_XP=1" cmake -G "Ninja" -DCMAKE_TOOLCHAIN_FILE=${TOOLCHAIN_WINXP_64} -DCMAKE_BUILD_TYPE=${BUILD_TYPE} "$OLDPWD" && ninja ${TARGETS_64} + popd > /dev/null + else + echo "Skipping WinXP builds, toolchain not specified" + fi + echo "" echo "Compilation process done :)" echo "===========================" ) +if ((BUILD_XP > 0)) +then + echo "" + echo "Checking XP compatibility..." + echo "=============================" + if ! command -v windows_dll_compat_checker &> /dev/null; then + echo "WARNING: windows_dll_compat_checker not found, skipping XP compatibility check" + else + windows_dll_compat_checker -s PREMADE/winxp_x86_64.ini \ + ${BUILDDIR_WINXP_64}/spicetools/64/spice64.exe + windows_dll_compat_checker -s PREMADE/winxp_x86_64_32bit_dlls.ini \ + ${BUILDDIR_WINXP_32}/spicetools/spicecfg.exe \ + ${BUILDDIR_WINXP_32}/spicetools/32/spice.exe \ + ${BUILDDIR_WINXP_32}/spicetools/32/spice_laa.exe + fi +fi + # generate PDBs if false # ((DEBUG > 0)) then @@ -226,6 +301,12 @@ else cp ${BUILDDIR_64}/spicetools/64/nvcuda.dll ${OUTDIR}/stubs/64 2>/dev/null cp ${BUILDDIR_64}/spicetools/64/nvcuvid.dll ${OUTDIR}/stubs/64 2>/dev/null cp ${BUILDDIR_32}/spicetools/32/cpusbxpkm.dll ${OUTDIR}/stubs/32 2>/dev/null + if ((BUILD_XP > 0)) + then + cp ${BUILDDIR_WINXP_32}/spicetools/spicecfg.exe ${OUTDIR_EXTRAS}/winxp 2>/dev/null + cp ${BUILDDIR_WINXP_32}/spicetools/32/spice.exe ${OUTDIR_EXTRAS}/winxp 2>/dev/null + cp ${BUILDDIR_WINXP_64}/spicetools/64/spice64.exe ${OUTDIR_EXTRAS}/winxp 2>/dev/null + fi fi # pack source files to output directory diff --git a/src/spice2x/build_docker.sh b/src/spice2x/build_docker.sh index 33bc441..96a9d10 100755 --- a/src/spice2x/build_docker.sh +++ b/src/spice2x/build_docker.sh @@ -1,4 +1,12 @@ -#!/bin/bash +#!/usr/bin/env bash + +set -eu + docker build --pull "$PWD/external/docker" -t spicetools/deps --platform linux/x86_64 docker build --build-context gitroot="$PWD/../../.git" . -t spicetools/spice:latest -docker run --rm -v "$PWD/dist:/src/src/spice2x/dist" -v "$PWD/bin:/src/src/spice2x/bin" -v "$PWD/.ccache:/src/src/spice2x/.ccache" spicetools/spice "$@" + +# Interactive TTY if available, so docker build can be Ctrl+C'd +DOCKER_FLAGS="" +[ -t 0 ] && DOCKER_FLAGS="-it" + +docker run $DOCKER_FLAGS --rm -v "$PWD/dist:/src/src/spice2x/dist" -v "$PWD/bin:/src/src/spice2x/bin" -v "$PWD/.ccache:/src/src/spice2x/.ccache" spicetools/spice "$@" diff --git a/src/spice2x/external/docker/Dockerfile b/src/spice2x/external/docker/Dockerfile index 4c5db15..29a6476 100644 --- a/src/spice2x/external/docker/Dockerfile +++ b/src/spice2x/external/docker/Dockerfile @@ -15,3 +15,11 @@ RUN pacman --noconfirm -Syu git \ ccache RUN useradd user -m && echo "ALL ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers RUN su user -c "cd /tmp/ && git clone https://aur.archlinux.org/yay-bin.git --depth=1 && cd yay-bin && makepkg --noconfirm -si && yay --noconfirm -S mingw-w64-cmake" + +RUN mkdir -p /opt/llvm-mingw-xp \ + && curl -fsSL "https://github.com/mon/llvm-mingw-xp/releases/download/llvm-mingw-xp-22.1.0/llvm-mingw-llvm-mingw-xp-22.1.0-msvcrt-ubuntu-22.04-x86_64.tar.xz" \ + | tar -xJ --strip-components=1 -C /opt/llvm-mingw-xp +ENV PATH="$PATH:/opt/llvm-mingw-xp/bin" + +RUN curl -fsSL "https://github.com/mon/windows-dll-compat-checker/releases/download/v1.3/windows_dll_compat_checker-linux-x86_64.tar.xz" \ + | tar -xJ -C /usr/local/bin diff --git a/src/spice2x/games/iidx/camera.cpp b/src/spice2x/games/iidx/camera.cpp index 334b54b..6d0ccaf 100644 --- a/src/spice2x/games/iidx/camera.cpp +++ b/src/spice2x/games/iidx/camera.cpp @@ -1,6 +1,6 @@ #include "camera.h" -#if SPICE64 +#if SPICE64 && !SPICE_XP #include #include "mf_wrappers.h" @@ -84,7 +84,7 @@ namespace games::iidx { bool find_camera_hooks() { std::string dll_name = avs::game::DLL_NAME; - dll_path = MODULE_PATH / dll_name; + dll_path = MODULE_PATH / dll_name; iidx_module = libutils::try_module(dll_path); if (!iidx_module) { @@ -149,7 +149,7 @@ namespace games::iidx { "E800000000488BC8488BD34883C420", "X????XXXXXXXXXX", 0, 0)); - + if (addr_textures_ptr == nullptr) { log_warning("iidx:camhook", "failed to find hook: addr_textures (part 1)"); return FALSE; @@ -232,7 +232,7 @@ namespace games::iidx { } static void **__fastcall camera_hook_a(PBYTE a1) { - std::call_once(hook_a_init, [&]{ + std::call_once(hook_a_init, [&]{ device = *reinterpret_cast(a1 + addr_device_offset); auto const preview = *reinterpret_cast((uint8_t*)iidx_module + addr_textures); auto const manager = reinterpret_cast((uint8_t*)iidx_module + addr_camera_manager); @@ -298,11 +298,11 @@ namespace games::iidx { // Ask for source type = video capture devices. if (SUCCEEDED(hr)) { hr = pAttributes->SetGUID( - MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, + MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE, MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_GUID ); } - + // Enumerate devices. if (SUCCEEDED(hr)) { hr = WrappedMFEnumDeviceSources(pAttributes, &ppDevices, &numDevices); @@ -478,7 +478,7 @@ namespace games::iidx { init_mf_library(); } } - + return result; } diff --git a/src/spice2x/games/iidx/camera.h b/src/spice2x/games/iidx/camera.h index a2d5846..0b4755e 100644 --- a/src/spice2x/games/iidx/camera.h +++ b/src/spice2x/games/iidx/camera.h @@ -1,6 +1,6 @@ #pragma once -#if SPICE64 +#if SPICE64 && !SPICE_XP #include #include "games/iidx/local_camera.h" diff --git a/src/spice2x/games/iidx/local_camera.cpp b/src/spice2x/games/iidx/local_camera.cpp index dc33f0c..4e01d42 100644 --- a/src/spice2x/games/iidx/local_camera.cpp +++ b/src/spice2x/games/iidx/local_camera.cpp @@ -1,6 +1,6 @@ #include "games/iidx/local_camera.h" -#if SPICE64 +#if SPICE64 && !SPICE_XP #include "util/logging.h" #include "util/utils.h" @@ -128,7 +128,7 @@ namespace games::iidx { // TODO: Color space conversion // if (SUCCEEDED(hr)) { // hr = pAttributes->SetUINT32(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, TRUE); - // } + // } // if (SUCCEEDED(hr)) { // hr = pAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, FALSE); // } @@ -189,11 +189,11 @@ namespace games::iidx { &pType ); - if (FAILED(hr)) { + if (FAILED(hr)) { if (hr != MF_E_NO_MORE_TYPES) { log_warning("iidx:camhook", "[{}] Cannot get media type {} {:#x}", m_name, i, (ULONG)hr); } - break; + break; } hr = TryMediaType(pType, &bestWidth, &bestFrameRate); @@ -246,7 +246,7 @@ namespace games::iidx { pSelectedMediaType = m_pAutoMediaType; } - if (SUCCEEDED(hr)) { + if (SUCCEEDED(hr)) { hr = ChangeMediaType(pSelectedMediaType); } @@ -281,7 +281,7 @@ namespace games::iidx { m_cameraHeight = info.height; UpdateDrawRect(); } - + return hr; } @@ -395,7 +395,7 @@ namespace games::iidx { m_device->ColorFill(m_pDestSurf, &targetRect, D3DCOLOR_XRGB(0, 0, 0)); } - + void IIDXLocalCamera::CreateThread() { // Create thread m_drawThread = new std::thread([this]() { @@ -411,7 +411,7 @@ namespace games::iidx { if (accumulator > 1.0) { accumulator -= 1.0; floorFrameTimeMicroSec += 1; - } + } std::this_thread::sleep_for(std::chrono::microseconds(floorFrameTimeMicroSec)); } }); @@ -430,12 +430,12 @@ namespace games::iidx { log_misc("iidx:camhook", "[{}] Init camera control", m_name); - hr = m_pSource->QueryInterface(IID_IAMCameraControl, (void**)&m_pCameraControl); - if (FAILED(hr)) { - // The device does not support IAMCameraControl + hr = m_pSource->QueryInterface(IID_IAMCameraControl, (void**)&m_pCameraControl); + if (FAILED(hr)) { + // The device does not support IAMCameraControl log_warning("iidx:camhook", "[{}] Camera control not supported", m_name); return E_FAIL; - } + } for (size_t i = 0; i < CAMERA_CONTROL_PROP_SIZE; i++) { long minValue = 0; @@ -472,9 +472,9 @@ namespace games::iidx { CameraControlProp prop = m_controlProps.at(i); log_misc( - "iidx:camhook", "[{}] >> {} range=({}, {}) default={} delta={} dFlags={} value={} vFlags={}", + "iidx:camhook", "[{}] >> {} range=({}, {}) default={} delta={} dFlags={} value={} vFlags={}", m_name, - CAMERA_CONTROL_LABELS[i], + CAMERA_CONTROL_LABELS[i], prop.minValue, prop.maxValue, prop.defaultValue, prop.delta, @@ -570,9 +570,9 @@ namespace games::iidx { // Get frame rate hr = MFGetAttributeRatio( - pType, - MF_MT_FRAME_RATE, - (UINT32*)&frameRate.Numerator, + pType, + MF_MT_FRAME_RATE, + (UINT32*)&frameRate.Numerator, (UINT32*)&frameRate.Denominator ); if (FAILED(hr)) { goto done; } @@ -580,7 +580,7 @@ namespace games::iidx { info.frameRate = frameRate.Numerator / frameRate.Denominator; info.description = fmt::format( - "{}x{} @{}FPS {}", + "{}x{} @{}FPS {}", info.width, info.height, (int)info.frameRate, @@ -606,7 +606,7 @@ namespace games::iidx { return "Unknown"; } - /** + /** * Return values: * S_OK: this is a "better" media type than the existing one * S_FALSE: valid media type, but not "better" @@ -620,17 +620,17 @@ namespace games::iidx { hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype); - if (FAILED(hr)) { + if (FAILED(hr)) { log_warning("iidx:camhook", "[{}] Failed to get subtype: {:#x}", m_name, (ULONG)hr); - return hr; + return hr; } hr = MFGetAttributeSize(pType, MF_MT_FRAME_SIZE, &width, &height); - if (FAILED(hr)) { + if (FAILED(hr)) { log_warning("iidx:camhook", "[{}] Failed to get frame size: {:#x}", m_name, (ULONG)hr); return hr; } - + // Only support format with converters // TODO: verify conversion support with DXVA if (subtype != MFVideoFormat_YUY2 && subtype != MFVideoFormat_NV12) { @@ -639,12 +639,12 @@ namespace games::iidx { // Frame rate hr = MFGetAttributeRatio( - pType, - MF_MT_FRAME_RATE, - (UINT32*)&frameRate.Numerator, + pType, + MF_MT_FRAME_RATE, + (UINT32*)&frameRate.Numerator, (UINT32*)&frameRate.Denominator ); - if (FAILED(hr)) { + if (FAILED(hr)) { log_warning("iidx:camhook", "[{}] Failed to get frame rate: {:#x}", m_name, (ULONG)hr); return hr; } @@ -667,7 +667,7 @@ namespace games::iidx { // Check if this format has better resolution / frame rate if ((width > *pBestWidth) || (width >= (UINT32)TARGET_SURFACE_WIDTH && frameRateValue >= *pBestFrameRate)) { // log_misc( - // "iidx:camhook", "Better media type {} ({}x{}) @({} FPS)", + // "iidx:camhook", "Better media type {} ({}x{}) @({} FPS)", // GetVideoFormatName(subtype), // width, // height, @@ -730,7 +730,7 @@ namespace games::iidx { HRESULT IIDXLocalCamera::FlushDrawCommands() { IDirect3DQuery9* pEventQuery = nullptr; - // It is necessary to flush the command queue + // It is necessary to flush the command queue // or the data is not ready for the receiver to read. // Adapted from : https://msdn.microsoft.com/en-us/library/windows/desktop/bb172234%28v=vs.85%29.aspx // Also see : http://www.ogre3d.org/forums/viewtopic.php?f=5&t=50486 @@ -784,8 +784,8 @@ namespace games::iidx { for (int y = 0; y < TARGET_SURFACE_HEIGHT; y++) { for (int x = 0; x < TARGET_SURFACE_WIDTH; x++) { memcpy( - pDest + x * pixelSize, - pSrc + (flip_h ? (TARGET_SURFACE_WIDTH - x - 1) : x) * pixelSize, + pDest + x * pixelSize, + pSrc + (flip_h ? (TARGET_SURFACE_WIDTH - x - 1) : x) * pixelSize, pixelSize ); } diff --git a/src/spice2x/games/iidx/local_camera.h b/src/spice2x/games/iidx/local_camera.h index f1e7e7a..f096082 100644 --- a/src/spice2x/games/iidx/local_camera.h +++ b/src/spice2x/games/iidx/local_camera.h @@ -1,6 +1,6 @@ #pragma once -#if SPICE64 +#if SPICE64 && !SPICE_XP #include #include diff --git a/src/spice2x/hooks/graphics/graphics.cpp b/src/spice2x/hooks/graphics/graphics.cpp index 9796b7c..4d6821b 100644 --- a/src/spice2x/hooks/graphics/graphics.cpp +++ b/src/spice2x/hooks/graphics/graphics.cpp @@ -1,3 +1,6 @@ +// GetDisplayConfigBufferSizes etc is Vista+ +#define _WIN32_WINNT 0x0601 + #include #include "graphics.h" @@ -232,9 +235,9 @@ static LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM l // This allows touches received on subscreen window to be translated correctly. update_spicetouch_window_dimensions(hWnd); // log_misc( - // "graphics", "detected window change ({}x{} @ {}, {}), updating touch coord-space to match", + // "graphics", "detected window change ({}x{} @ {}, {}), updating touch coord-space to match", // SPICETOUCH_TOUCH_WIDTH, SPICETOUCH_TOUCH_HEIGHT, SPICETOUCH_TOUCH_X, SPICETOUCH_TOUCH_Y); - + // Update SPICETOUCH window if present if (SPICETOUCH_TOUCH_HWND) { SetWindowPos( @@ -371,7 +374,7 @@ static HWND WINAPI CreateWindowExA_hook(DWORD dwExStyle, LPCSTR lpClassName, LPC if (is_tdj_sub_window) { // TDJ windowed mode: remember the subscreen window handle for later TDJ_SUBSCREEN_WINDOW = result; - + // hook for preventing the closing of subscreen window if (GRAPHICS_IIDX_WSUB) { graphics_hook_subscreen_window(TDJ_SUBSCREEN_WINDOW); @@ -530,7 +533,7 @@ static BOOL WINAPI MoveWindow_hook(HWND hWnd, int X, int Y, int nWidth, int nHei if (GRAPHICS_IIDX_WSUB) { // (Experimental) Show subscreen in windowed mode graphics_load_windowed_subscreen_parameters(); - + RECT rect {}; DWORD dwStyle; @@ -1085,7 +1088,7 @@ static std::string get_dmdo_string(DWORD dmdo) { } void change_primary_monitor(const std::string &monitor_name) { - log_misc("graphics", "try changing primary monitor to {}...", monitor_name); + log_misc("graphics", "try changing primary monitor to {}...", monitor_name); // for WinXP, since these are Vista+ or 7+ APIs const auto user32 = LoadLibraryA("user32.dll"); @@ -1116,7 +1119,7 @@ void change_primary_monitor(const std::string &monitor_name) { std::vector paths; std::vector modes; bool succeeded = false; - + // in a retry loop, try to query for display config // retry loop is needed because it can fail with ERROR_INSUFFICIENT_BUFFER for (int attempt = 0; attempt < 5; ++attempt) { @@ -1323,4 +1326,4 @@ void update_monitor_on_boot(std::optional target_orientati // sleep for a little bit after changing monitor settings to delay game launch Sleep(1000); -} \ No newline at end of file +} diff --git a/src/spice2x/launcher/launcher.cpp b/src/spice2x/launcher/launcher.cpp index 47c13f6..af72096 100644 --- a/src/spice2x/launcher/launcher.cpp +++ b/src/spice2x/launcher/launcher.cpp @@ -351,7 +351,7 @@ int main_implementation(int argc, char *argv[]) { GRAPHICS_FORCE_SINGLE_ADAPTER = true; GRAPHICS_PREVENT_SECONDARY_WINDOW = true; } - if (options[launcher::Options::DXDisplayAdapter].is_active() && + if (options[launcher::Options::DXDisplayAdapter].is_active() && options[launcher::Options::DXDisplayAdapter].value_uint32() != D3DADAPTER_DEFAULT) { D3D9_ADAPTER = options[launcher::Options::DXDisplayAdapter].value_uint32(); @@ -1227,7 +1227,7 @@ int main_implementation(int argc, char *argv[]) { acio::MDXF_BUFFER_FILL_MODE = acio::MDXFBufferFillMode::THREAD_MODE; } else if (options[launcher::Options::DDRP4IOBufferMode].value_text() == "backfill") { acio::MDXF_BUFFER_FILL_MODE = acio::MDXFBufferFillMode::BACKFILL_MODE; - } + } } if (options[launcher::Options::MidiAlgoVer].is_active()) { @@ -1294,7 +1294,19 @@ int main_implementation(int argc, char *argv[]) { } // log -#ifndef SPICE_LINUX +#if SPICE_LINUX + #ifdef SPICE64 + log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x) for Linux"); + #else + log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x) for Linux"); + #endif +#elif SPICE_XP + #ifdef SPICE64 + log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x) for WinXP"); + #else + log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x) for WinXP"); + #endif +#else #ifdef SPICE64 log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x)"); #elif SPICE32_LARGE_ADDRESS_AWARE @@ -1302,12 +1314,6 @@ int main_implementation(int argc, char *argv[]) { #else log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x)"); #endif -#else - #ifdef SPICE64 - log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x) for Linux"); - #else - log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x) for Linux"); - #endif #endif log_info("launcher", "{}", VERSION_STRING); @@ -1364,7 +1370,7 @@ int main_implementation(int argc, char *argv[]) { log_warning( "launcher", "multiple values for -{}, command line args take precedence: {}", - option.get_definition().name, + option.get_definition().name, value); } else { log_warning( @@ -1379,7 +1385,7 @@ int main_implementation(int argc, char *argv[]) { if (launcher::USE_CMD_OVERRIDE) { log_info( "launcher", - "user specified -cmdoverride, therefore command line args took precedence over spicecfg"); + "user specified -cmdoverride, therefore command line args took precedence over spicecfg"); } else { log_warning( "launcher", @@ -2226,7 +2232,7 @@ int main_implementation(int argc, char *argv[]) { game->attach(); } -#ifdef SPICE64 +#if SPICE64 && !SPICE_XP if (!cfg::CONFIGURATOR_STANDALONE) { if (games::iidx::TDJ_CAMERA) { games::iidx::init_camera_hooks(); @@ -2507,7 +2513,7 @@ int main_implementation(int argc, char *argv[]) { // disable poke games::iidx::poke::disable(); -#ifdef SPICE64 +#if SPICE64 && !SPICE_XP games::iidx::camera_release(); #endif diff --git a/src/spice2x/overlay/overlay.cpp b/src/spice2x/overlay/overlay.cpp index 60532c1..a6a934f 100644 --- a/src/spice2x/overlay/overlay.cpp +++ b/src/spice2x/overlay/overlay.cpp @@ -69,7 +69,7 @@ namespace overlay { } return ImVec2(apply_scaling(x), apply_scaling(y)); } - + ImVec2 apply_scaling_to_vector(const ImVec2& input) { return apply_scaling_to_vector(input.x, input.y); } @@ -350,7 +350,7 @@ void overlay::SpiceOverlay::init() { this->window_add(window_config = new overlay::windows::Config(this)); this->window_add(window_control = new overlay::windows::Control(this)); this->window_add(window_log = new overlay::windows::Log(this)); -#ifdef SPICE64 +#if SPICE64 && !SPICE_XP if (avs::game::is_model("LDJ")) { this->window_add(window_camera = new overlay::windows::CameraControl(this)); } @@ -738,4 +738,4 @@ void overlay::SpiceOverlay::add_font(const char* font, ImFontConfig* config, con } else { log_misc("overlay", "font not found: {}", full_path.string()); } -} \ No newline at end of file +} diff --git a/src/spice2x/overlay/windows/camera_control.cpp b/src/spice2x/overlay/windows/camera_control.cpp index b4b7c8a..8d2d7cb 100644 --- a/src/spice2x/overlay/windows/camera_control.cpp +++ b/src/spice2x/overlay/windows/camera_control.cpp @@ -1,6 +1,6 @@ #include "camera_control.h" -#if SPICE64 +#if SPICE64 && !SPICE_XP #include #include @@ -193,7 +193,7 @@ namespace overlay::windows { } ImGui::Separator(); - + // reset button if (ImGui::Button("Reset")) { selectedCamera->ResetCameraControlProps(); diff --git a/src/spice2x/overlay/windows/camera_control.h b/src/spice2x/overlay/windows/camera_control.h index a5e3fc3..8b106cb 100644 --- a/src/spice2x/overlay/windows/camera_control.h +++ b/src/spice2x/overlay/windows/camera_control.h @@ -1,6 +1,6 @@ #pragma once -#if SPICE64 +#if SPICE64 && !SPICE_XP #include "overlay/window.h" #include diff --git a/src/spice2x/overlay/windows/card_manager.cpp b/src/spice2x/overlay/windows/card_manager.cpp index 9693d32..732ea9e 100644 --- a/src/spice2x/overlay/windows/card_manager.cpp +++ b/src/spice2x/overlay/windows/card_manager.cpp @@ -144,7 +144,7 @@ namespace overlay::windows { " xxxx xxxx xxxx xxxx "); ImGui::EndDisabled(); } - + ImGui::PopID(); return clicked; } @@ -152,8 +152,8 @@ namespace overlay::windows { void CardManager::open_card_editor() { if (this->current_card) { const auto card = this->current_card; - strcpy_s(this->name_buffer, std::size(this->name_buffer), card->name.c_str()); - strcpy_s(this->card_buffer, std::size(this->card_buffer), card->id.c_str()); + snprintf(this->name_buffer, std::size(this->name_buffer), "%s", card->name.c_str()); + snprintf(this->card_buffer, std::size(this->card_buffer), "%s", card->id.c_str()); this->color_buffer[0] = card->color[0]; this->color_buffer[1] = card->color[1]; this->color_buffer[2] = card->color[2]; @@ -227,7 +227,7 @@ namespace overlay::windows { }; generate_search_string(&card); this->cards.emplace_back(card); - + // mark this card as the selected one this->current_card = &this->cards.back(); } @@ -301,7 +301,7 @@ namespace overlay::windows { // search for card // - // setting ImGuiInputTextFlags_CallbackCharFilter and pressing escape doesn't cause below + // setting ImGuiInputTextFlags_CallbackCharFilter and pressing escape doesn't cause below // to return true, making it necessary to provide a callback... ImGui::SetNextItemWidth(overlay::apply_scaling(240)); if (ImGui::InputTextWithHint("", "Type here to search..", &this->search_filter)) { @@ -399,11 +399,11 @@ namespace overlay::windows { // cards from card manager JSON for (auto &card : this->cards) { - + if (!this->search_filter_in_lower_case.empty() && !card.search_string.empty()) { const bool matched = card.search_string.find(this->search_filter_in_lower_case) != std::string::npos; - + if (!matched) { continue; } diff --git a/src/spice2x/overlay/windows/config.cpp b/src/spice2x/overlay/windows/config.cpp index 257a4b0..1b099f7 100644 --- a/src/spice2x/overlay/windows/config.cpp +++ b/src/spice2x/overlay/windows/config.cpp @@ -61,7 +61,7 @@ namespace overlay::windows { constexpr ImVec4 TEXT_COLOR_GREEN(0.f, 1.f, 0.f, 1.f); constexpr ImVec4 TEXT_COLOR_RED(1.f, 0.f, 0.f, 1.f); constexpr uint32_t OPTION_INPUT_TEXT_WIDTH = 512; - + std::unique_ptr asio_driver_list; Config::Config(overlay::SpiceOverlay *overlay) : Window(overlay) { @@ -515,7 +515,7 @@ namespace overlay::windows { ImGui::BeginChild("SearchOptions", ImVec2( 0, ImGui::GetWindowContentRegionMax().y - page_offset), false); - + // search from all options ImGui::Spacing(); ImGui::SetNextItemWidth(420.f); @@ -633,14 +633,14 @@ namespace overlay::windows { reset_button_to_default(&button, get_keypad_top_row(button)); } ImGui::CloseCurrentPopup(); - } + } ImGui::SameLine(); if (ImGui::Button("Remove All")) { for (auto &button : *buttons) { reset_button_to_default(&button, 0xFF); } ImGui::CloseCurrentPopup(); - } + } } else { if (ImGui::Button("Yes")) { for (auto &button : *buttons) { @@ -789,7 +789,7 @@ namespace overlay::windows { // clear button if (button_display.size() > 0 || alt_index > 0) { ImGui::SameLine(); - if (ImGui::DeleteButton(button_display.size() > 0 ? "Unbind" : "Delete")) { + if (ImGui::DeleteButton(button_display.size() > 0 ? "Unbind" : "Delete")) { clear_button(button, alt_index); } } @@ -1069,7 +1069,7 @@ namespace overlay::windows { {"P1 Keypad 00", VK_OEM_MINUS}, {"P1 Keypad Decimal", VK_OEM_PLUS}, {"P1 Keypad Insert Card", VK_BACK}}; - + for (const auto &[key, value] : keypad_top_row_defaults) { if (button.getName() == key) { return value; @@ -1423,7 +1423,7 @@ namespace overlay::windows { } for (unsigned short ch = 0; ch < midi->pitch_bend.size(); ch++) { - // check pitch bend down + // check pitch bend down if (midi->pitch_bend[ch] < 0) { // bind control @@ -1629,7 +1629,7 @@ namespace overlay::windows { if (ImGui::Selectable("Empty (Naive)", button->isNaive())) { button->setDeviceIdentifier(""); dirty = true; - } + } if (button->isNaive()) { ImGui::SetItemDefaultFocus(); } @@ -1713,7 +1713,7 @@ namespace overlay::windows { button->setVelocityThreshold(0); dirty = true; } - + type = button->getAnalogType(); int midi_channel = 0; @@ -1760,7 +1760,7 @@ namespace overlay::windows { } else if (0x20 <= midi_index && midi_index < 0x3F) { midi_index = 0x40; - // skip range [0x60, 0x65] + // skip range [0x60, 0x65] } else if (midi_index == 0x65) { midi_index = 0x5F; } else if (0x60 <= midi_index && midi_index < 0x65) { @@ -1844,7 +1844,7 @@ namespace overlay::windows { ImGui::TextDisabled("Min. %d%%", velocity_threshold * 100 / 127); } else if (type == ButtonAnalogType::BAT_MIDI_CTRL_PRECISION || - type == ButtonAnalogType::BAT_MIDI_CTRL_SINGLE) { + type == ButtonAnalogType::BAT_MIDI_CTRL_SINGLE) { ImGui::TextUnformatted("\n"); ImGui::AlignTextToFramePadding(); @@ -1912,7 +1912,7 @@ namespace overlay::windows { "Direction", is_up ? "Pitch Up" : "Pitch Down", ImGuiComboFlags_HeightSmall)) { - + if (ImGui::Selectable("Pitch Up", is_up)) { button->setAnalogType(ButtonAnalogType::BAT_MIDI_PITCH_UP); dirty = true; @@ -2213,7 +2213,7 @@ namespace overlay::windows { ImGui::SameLine(); ImGui::HelpMarker(device->name.c_str()); } - + switch (device->type) { case rawinput::MOUSE: { @@ -2283,7 +2283,7 @@ namespace overlay::windows { if (device->midiInfo->pitch_bend_set[ch]) { control_names.push_back(fmt::format("Pitch Ch.{}", ch + 1)); analogs_midi_indices.push_back( - ch + + ch + precision.size() + single.size() + onoff.size()); @@ -2428,7 +2428,7 @@ namespace overlay::windows { if (invert != analog.getInvert()) { analog.setInvert(invert); } - + if (this->analogs_devices_selected >= 0) { const auto device = this->analogs_devices.at(this->analogs_devices_selected); if (device->type == rawinput::HID) { @@ -2783,7 +2783,7 @@ namespace overlay::windows { bool table_begin = false; for (size_t i = 0; i < lights->size(); i++) { auto &light = lights->at(i); - + if (current_section != light.getCategory()) { current_section = light.getCategory(); if (table_begin) { @@ -2791,7 +2791,7 @@ namespace overlay::windows { } render_section_header(current_section.empty() ? "Uncategorized" : current_section); - + table_begin = begin_lights_table(); if (!table_begin) { break; @@ -2813,7 +2813,7 @@ namespace overlay::windows { alt_index++; } - + } if (table_begin) { ImGui::EndTable(); @@ -2834,7 +2834,7 @@ namespace overlay::windows { // progress bar ImGui::TableNextColumn(); - + // light name if (alt_index == 0) { ImGui::ProgressBar(light_state, ImVec2(32.f, 0)); @@ -2865,7 +2865,7 @@ namespace overlay::windows { // clear light if (light_display.size() > 0 || alt_index > 0) { ImGui::SameLine(); - if (ImGui::DeleteButton(light_display.size() > 0 ? "Unbind" : "Delete")) { + if (ImGui::DeleteButton(light_display.size() > 0 ? "Unbind" : "Delete")) { clear_light(light, alt_index); } } @@ -2948,7 +2948,7 @@ namespace overlay::windows { games_list[games_selected], *light, alt_index - 1); } - + void Config::edit_light_popup(Light &primary_light, Light *light, const int alt_index) { if (ImGui::BeginPopupModal("Light Binding", NULL, ImGuiWindowFlags_AlwaysAutoResize)) { @@ -3748,7 +3748,7 @@ namespace overlay::windows { return detected_controller; } - + void Config::build_cards() { constexpr float TEXT_INPUT_WIDTH = 240.f; @@ -4078,12 +4078,12 @@ namespace overlay::windows { // verify card number this->keypads_card_file_contents_valid[player] = true; if (this->keypads_card_number[player][0] != 0) { - this->keypads_card_file_contents_valid[player] = + this->keypads_card_file_contents_valid[player] = validate_ea_card(this->keypads_card_number[player]); } // card number box - + ImGui::SetNextItemWidth(TEXT_INPUT_WIDTH); ImGui::BeginDisabled(); if (this->keypads_card_number[player][0] != 0) { @@ -4289,7 +4289,9 @@ namespace overlay::windows { ImGui::TextUnformatted("Requires restart! Showing all procs in Group 0."); ImGui::TextUnformatted(""); ImGui::TextUnformatted("Pick CPU cores to use:"); - const uint64_t cpu_count = GetActiveProcessorCount(0); + SYSTEM_INFO info; + GetSystemInfo(&info); + const uint64_t cpu_count = info.dwNumberOfProcessors; uint64_t affinity = 0; if (!option.value.empty()) { try { @@ -4333,7 +4335,7 @@ namespace overlay::windows { option.value = fmt::format("0x{:X}", affinity); } } - + ImGui::EndChild(); if (option.value.empty()) { ImGui::TextUnformatted("Using all CPUs (option default)."); @@ -4499,7 +4501,7 @@ namespace overlay::windows { void Config::build_options( std::vector