Compare commits

...

5 Commits

Author SHA1 Message Date
bicarus-dev 4b21821aa4 Introduce builds for Linux, split archive into release and extras (#405)
## Link to GitHub Issue, if one exists
n/a

## Description of change
Add a "Linux" variant of spicecfg/spice/spice64.exe - currently these
are the same as Windows binaries but built without dependency on
WinSCard, which makes it easier to run on WINE.

Split dist archive into two, move api and extras into the new extras
zip.

## Testing
I only checked to see that Linux variants run fine on Windows, and
checked with dumpbin to confirm that the dependency on winscard DLL is
removed. No official support will be provided for Linux builds.
2025-10-16 16:19:10 -07:00
bicarus-dev 6b47b5db50 iidx: set CONNECT_CAMERA env var even when iidx module is not enabled (#404)
## Link to GitHub Issue, if one exists
Fixes #403 

## Description of change
Set CONNECT_CAMERA env var even when iidx module is not enabled, so that
camhook can work without -iidx being set with real IO

## Testing
tested with emulated i/o and real i/o by user (see linked issue)
2025-10-15 13:50:12 -07:00
kazakhstan-sila a10ca5236b add option to remove winscard dependency (#400)
## Link to GitHub Issue, if one exists
n/a

## Description of change
Add CMake option to disable SCard functionality. Needed by some builds
of WINE, where distributor opted to not enable scard functionality for
whatever reason

## Testing
Building with `cmake -DWITH_SCARD=OFF` does not link against winscard
Building without this option at all links against winscard
2025-10-13 14:13:51 -07:00
bicarus-dev be2dab9a1a Image duplication for screen resize (#401)
## Link to GitHub Issue, if one exists
#399 

## Description of change
Add image duplication option to screen resize, allowing overflow images
to wrap around the other side.

## Testing
Tested with DDR, IIDX (windowed and full screen TDJ), SDVX (orientation
swap)
2025-10-12 20:34:45 -07:00
AllanCat 02711cdee1 Fixed an issue where ext (release_code) wasn't detected and replaced correctly when using user specified bootstrap.xml path. (#398)
## Link to GitHub Issue, if one exists
#0

## Description of change
The original launcher::detect_bootstrap_release_code() wasn't detecting
user specified bootstrap.xml path, and was causing issues for
patch_manager and other ext check spots prior to ea3 init (as ea3 does
proper path check itself).
I've added the user path check and proper xml parsing from
detect_gameversion().

## Testing
Tested with prop/bootstrap.xml presents.
Tested with prop/bootstrap.xml not presents and -b
/path/to/bootstrap.xml
2025-10-10 21:35:34 -07:00
12 changed files with 225 additions and 40 deletions
+65 -9
View File
@@ -357,12 +357,12 @@ set(SOURCE_FILES ${SOURCE_FILES}
external/cardio/cardio_runner.cpp
# external misc
external/scard/scard.cpp
external/stackwalker/stackwalker.cpp
external/tinyxml2/tinyxml2.cpp
external/http-parser/http_parser.c
external/usbhidusage/usb-hid-usage.c
external/toojpeg/toojpeg.cpp
external/scard/scard.cpp
# games
games/game.cpp
@@ -622,8 +622,9 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX "Source Files" FILES ${SOUR
set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc)
add_executable(spicetools_spice ${SOURCE_FILES} ${RESOURCE_FILES})
target_link_libraries(spicetools_spice
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
target_link_libraries(spicetools_spice PUBLIC winscard)
set_target_properties(spicetools_spice PROPERTIES PREFIX "")
set_target_properties(spicetools_spice PROPERTIES OUTPUT_NAME "spice")
@@ -637,8 +638,9 @@ endif()
set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc)
add_executable(spicetools_spice_laa ${SOURCE_FILES} ${RESOURCE_FILES})
target_link_libraries(spicetools_spice_laa
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
target_link_libraries(spicetools_spice_laa PUBLIC winscard)
set_target_properties(spicetools_spice_laa PROPERTIES PREFIX "")
set_target_properties(spicetools_spice_laa PROPERTIES OUTPUT_NAME "spice_laa")
target_compile_definitions(spicetools_spice_laa PRIVATE SPICE32_LARGE_ADDRESS_AWARE=1)
@@ -647,6 +649,22 @@ IF(NOT MSVC)
set_target_properties(spicetools_spice_laa PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32 -Wl,--large-address-aware")
endif()
# spice_linux.exe
###########
set(RESOURCE_FILES build/manifest.manifest build/manifest.rc build/icon.rc cfg/Win32D.rc)
add_executable(spicetools_spice_linux ${SOURCE_FILES} ${RESOURCE_FILES})
target_link_libraries(spicetools_spice_linux
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
set_target_properties(spicetools_spice_linux PROPERTIES PREFIX "")
set_target_properties(spicetools_spice_linux PROPERTIES OUTPUT_NAME "spice_linux")
target_compile_definitions(spicetools_spice_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1)
IF(NOT MSVC)
set_target_properties(spicetools_spice_linux PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
endif()
# spice64.exe
#############
@@ -655,9 +673,9 @@ add_executable(spicetools_spice64 ${SOURCE_FILES} ${RESOURCE_FILES})
# do NOT link against: mf, mfplat, mfreadwrite; otherwise unity games will break
target_link_libraries(spicetools_spice64
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp mfuuid strmiids dxva2
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp mfuuid strmiids dxva2
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
target_link_libraries(spicetools_spice64 PUBLIC winscard)
set_target_properties(spicetools_spice64 PROPERTIES PREFIX "")
set_target_properties(spicetools_spice64 PROPERTIES OUTPUT_NAME "spice64")
target_compile_definitions(spicetools_spice64 PRIVATE SPICE64=1)
@@ -666,6 +684,25 @@ IF(NOT MSVC)
set_target_properties(spicetools_spice64 PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-m64")
endif()
# spice64_linux.exe
#############
set(RESOURCE_FILES build/manifest.manifest build/manifest64.rc build/icon.rc cfg/Win32D.rc)
add_executable(spicetools_spice64_linux ${SOURCE_FILES} ${RESOURCE_FILES})
# do NOT link against: mf, mfplat, mfreadwrite; otherwise unity games will break
target_link_libraries(spicetools_spice64_linux
PUBLIC d3d9 ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp mfuuid strmiids dxva2
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
set_target_properties(spicetools_spice64_linux PROPERTIES PREFIX "")
set_target_properties(spicetools_spice64_linux PROPERTIES OUTPUT_NAME "spice64_linux")
target_compile_definitions(spicetools_spice64_linux PRIVATE SPICE64=1)
target_compile_definitions(spicetools_spice64_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1)
IF(NOT MSVC)
set_target_properties(spicetools_spice64_linux PROPERTIES COMPILE_FLAGS "-m64" LINK_FLAGS "-m64")
endif()
# spicecfg.exe
##############
@@ -673,8 +710,9 @@ set(SOURCE_FILES ${SOURCE_FILES} launcher/options.h launcher/options.cpp)
set(RESOURCE_FILES cfg/manifest.manifest cfg/manifest.rc cfg/icon.rc cfg/Win32D.rc)
add_executable(spicetools_cfg WIN32 ${SOURCE_FILES} ${RESOURCE_FILES})
target_link_libraries(spicetools_cfg
PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winscard winhttp strmiids
PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp strmiids
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
target_link_libraries(spicetools_cfg PUBLIC winscard)
set_target_properties(spicetools_cfg PROPERTIES PREFIX "")
set_target_properties(spicetools_cfg PROPERTIES OUTPUT_NAME "spicecfg")
target_compile_definitions(spicetools_cfg PRIVATE SPICETOOLS_SPICECFG_STANDALONE=1)
@@ -683,6 +721,24 @@ if(NOT MSVC)
set_target_properties(spicetools_cfg PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
endif()
# spicecfg_linux.exe
##############
set(SOURCE_FILES ${SOURCE_FILES} launcher/options.h launcher/options.cpp)
set(RESOURCE_FILES cfg/manifest.manifest cfg/manifest.rc cfg/icon.rc cfg/Win32D.rc)
add_executable(spicetools_cfg_linux WIN32 ${SOURCE_FILES} ${RESOURCE_FILES})
target_link_libraries(spicetools_cfg_linux
PUBLIC ws2_32 version comctl32 shlwapi iphlpapi hid secur32 setupapi psapi winmm winhttp strmiids
PRIVATE fmt-header-only discord-rpc imgui hash-library minhook imm32 dwmapi CpuFeatures::cpu_features)
set_target_properties(spicetools_cfg_linux PROPERTIES PREFIX "")
set_target_properties(spicetools_cfg_linux PROPERTIES OUTPUT_NAME "spicecfg_linux")
target_compile_definitions(spicetools_cfg_linux PRIVATE SPICETOOLS_SPICECFG_STANDALONE=1)
target_compile_definitions(spicetools_cfg_linux PRIVATE NO_SCARD=1 PRIVATE SPICE_LINUX=1)
if(NOT MSVC)
set_target_properties(spicetools_cfg_linux PROPERTIES COMPILE_FLAGS "-m32" LINK_FLAGS "-m32")
endif()
# stubs
#######
@@ -776,19 +832,19 @@ endif()
####################
# output config
set_target_properties(spicetools_cfg
set_target_properties(spicetools_cfg spicetools_cfg_linux
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools")
# output 32bit
set_target_properties(spicetools_spice spicetools_spice_laa spicetools_stubs_kbt spicetools_stubs_kld spicetools_stubs_cpusbxpkm
set_target_properties(spicetools_spice spicetools_spice_laa spicetools_spice_linux spicetools_stubs_kbt spicetools_stubs_kld spicetools_stubs_cpusbxpkm
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/archive32"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/32"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/32")
# output 64bit
set_target_properties(spicetools_spice64 spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvcuda spicetools_stubs_nvcuvid spicetools_stubs_nvEncodeAPI64
set_target_properties(spicetools_spice64 spicetools_spice64_linux spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvcuda spicetools_stubs_nvcuvid spicetools_stubs_nvEncodeAPI64
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/archive64"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/spicetools/64"
+26 -8
View File
@@ -49,6 +49,7 @@ BUILDDIR_64_RELEASE="./cmake-build-release-64"
BUILDDIR_64_DEBUG="./cmake-build-debug-64"
DEBUG=0
OUTDIR="./bin/spice2x"
OUTDIR_EXTRAS="./bin/spice2x_extras"
# disabled UPX since it tends to falsely trigger malware detection
UPX_ENABLE=0
@@ -60,8 +61,9 @@ DIST_ENABLE=1
DIST_FOLDER="./dist"
DIST_NAME="spice2x-$(date +%y)-$(date +%m)-$(date +%d).zip"
DIST_COMMENT=${DIST_NAME}$'\n'"$GIT_BRANCH - $GIT_HEAD"$'\nThank you for playing.'
TARGETS_32="spicetools_stubs_kbt spicetools_stubs_kld spicetools_cfg spicetools_spice spicetools_spice_laa spicetools_stubs_cpusbxpkm"
TARGETS_64="spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvEncodeAPI64 spicetools_stubs_nvcuvid spicetools_stubs_nvcuda spicetools_spice64"
DIST_NAME_EXTRAS="spice2x-$(date +%y)-$(date +%m)-$(date +%d)-extras.zip"
TARGETS_32="spicetools_stubs_kbt spicetools_stubs_kld spicetools_cfg spicetools_cfg_linux spicetools_spice spicetools_spice_laa spicetools_spice_linux spicetools_stubs_cpusbxpkm"
TARGETS_64="spicetools_stubs_kbt64 spicetools_stubs_kld64 spicetools_stubs_nvEncodeAPI64 spicetools_stubs_nvcuvid spicetools_stubs_nvcuda spicetools_spice64 spicetools_spice64_linux"
# determine build type
BUILD_TYPE="Release"
@@ -179,11 +181,17 @@ fi
# copy to output directory
echo "Copy files to output directory..."
rm -rf ${OUTDIR}
mkdir -p ${OUTDIR}
mkdir -p ${OUTDIR}/stubs/32
mkdir -p ${OUTDIR}/stubs/64
mkdir -p ${OUTDIR}/extras/largeaddressaware
rm -rf ${OUTDIR_EXTRAS}
mkdir -p ${OUTDIR_EXTRAS}
mkdir -p ${OUTDIR_EXTRAS}/largeaddressaware
mkdir -p ${OUTDIR_EXTRAS}/linux
if false # ((DEBUG > 0))
then
# debug files
@@ -204,11 +212,14 @@ then
else
# release files
cp ${BUILDDIR_32}/spicetools/spicecfg.exe ${OUTDIR} 2>/dev/null
cp ${BUILDDIR_32}/spicetools/spicecfg_linux.exe ${OUTDIR_EXTRAS}/linux/spicecfg.exe 2>/dev/null
cp ${BUILDDIR_32}/spicetools/32/spice.exe ${OUTDIR} 2>/dev/null
cp ${BUILDDIR_32}/spicetools/32/spice_laa.exe ${OUTDIR}/extras/largeaddressaware/spice.exe 2>/dev/null
cp ${BUILDDIR_32}/spicetools/32/spice_laa.exe ${OUTDIR_EXTRAS}/largeaddressaware/spice.exe 2>/dev/null
cp ${BUILDDIR_32}/spicetools/32/spice_linux.exe ${OUTDIR_EXTRAS}/linux/spice.exe 2>/dev/null
#cp ${BUILDDIR_32}/spicetools/32/kbt.dll ${OUTDIR}/stubs/32 2>/dev/null
#cp ${BUILDDIR_32}/spicetools/32/kld.dll ${OUTDIR}/stubs/32 2>/dev/null
cp ${BUILDDIR_64}/spicetools/64/spice64.exe ${OUTDIR} 2>/dev/null
cp ${BUILDDIR_64}/spicetools/64/spice64_linux.exe ${OUTDIR_EXTRAS}/linux/spice64.exe 2>/dev/null
#cp ${BUILDDIR_64}/spicetools/64/kbt.dll ${OUTDIR}/stubs/64 2>/dev/null
#cp ${BUILDDIR_64}/spicetools/64/kld.dll ${OUTDIR}/stubs/64 2>/dev/null
cp ${BUILDDIR_64}/spicetools/64/nvEncodeAPI64.dll ${OUTDIR}/stubs/64 2>/dev/null
@@ -220,18 +231,21 @@ fi
# pack source files to output directory
rm -rf ${OUTDIR}/src
mkdir -p ${OUTDIR}/src
rm -rf ${OUTDIR_EXTRAS}/src
mkdir -p ${OUTDIR_EXTRAS}/src
if ((INCLUDE_SRC > 0))
then
echo "Generating source file archive..."
git archive --format tar.gz --prefix=spice2x/ HEAD ./ > ${OUTDIR}/src/spice2x-${GIT_BRANCH}.tar.gz 2>/dev/null || \
echo "WARNING: Couldn't get git to create the archive. Is this a git repository?"
cp -r ${OUTDIR}/src/* ${OUTDIR_EXTRAS}/src
fi
# copy resources
rm -rf ${OUTDIR}/api
mkdir ${OUTDIR}/api
rm -rf ${OUTDIR_EXTRAS}/api
mkdir ${OUTDIR_EXTRAS}/api
find ./api/resources/python -name "__pycache__" -exec rm -rf {} +
cp -r ./api/resources/* ${OUTDIR}/api
cp -r ./api/resources/* ${OUTDIR_EXTRAS}/api
# build distribution archive
if ((DIST_ENABLE > 0))
@@ -240,7 +254,11 @@ then
mkdir -p ${DIST_FOLDER}
rm -rf ${DIST_FOLDER}/${DIST_NAME}
pushd ${OUTDIR}/.. > /dev/null
zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME} . -z <<< "$DIST_COMMENT"
zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME} spice2x -z <<< "$DIST_COMMENT"
popd > /dev/null
echo "Building extras..."
pushd ${OUTDIR_EXTRAS}/.. > /dev/null
zip -qrXT9 $OLDPWD/${DIST_FOLDER}/${DIST_NAME_EXTRAS} spice2x_extras -z <<< "$DIST_COMMENT"
popd > /dev/null
fi
+5
View File
@@ -87,6 +87,10 @@ namespace cfg {
load_float_value(doc, root + prefix + "scale_x", scene.scale_x);
load_float_value(doc, root + prefix + "scale_y", scene.scale_y);
load_bool_value(doc, root + prefix + "keep_aspect_ratio", scene.keep_aspect_ratio);
int duplicate = 0;
load_int_value(doc, root + prefix + "duplicate", duplicate);
scene.duplicate = static_cast<cfg::ScreenDuplicateMode>(duplicate);
}
// windowed settings are always under game settings
@@ -201,6 +205,7 @@ namespace cfg {
rapidjson::Pointer(root + prefix + "scale_x").Set(doc, scene.scale_x);
rapidjson::Pointer(root + prefix + "scale_y").Set(doc, scene.scale_y);
rapidjson::Pointer(root + prefix + "keep_aspect_ratio").Set(doc, scene.keep_aspect_ratio);
rapidjson::Pointer(root + prefix + "duplicate").Set(doc, scene.duplicate);
}
// windowed mode settings
+7
View File
@@ -14,12 +14,19 @@ namespace cfg {
ResizableFrame = 2
};
enum ScreenDuplicateMode {
None = 0,
CopyLeft = 1,
CopyRight = 2,
};
struct fullscreen_setting {
int offset_x = 0;
int offset_y = 0;
float scale_x = 1.0;
float scale_y = 1.0;
bool keep_aspect_ratio = true;
ScreenDuplicateMode duplicate = ScreenDuplicateMode::None;
};
extern std::optional<std::string> SCREEN_RESIZE_CFG_PATH_OVERRIDE;
+3
View File
@@ -23,6 +23,7 @@
* Modified version.
*/
#ifndef NO_SCARD
#include "scard.h"
#include <windows.h>
@@ -409,3 +410,5 @@ void scard_threadstart() {
void scard_fini() {
should_exit = true;
}
#endif
-4
View File
@@ -420,10 +420,6 @@ namespace games::iidx {
// environment variables must be set before the DLL is loaded as the VC++ runtime copies all
// environment variables at startup
if (DISABLE_CAMS) {
SetEnvironmentVariable("CONNECT_CAMERA", "0");
}
if (SCREEN_MODE.has_value()) {
SetEnvironmentVariable("SCREEN_MODE", SCREEN_MODE.value().c_str());
}
@@ -733,6 +733,16 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
const int rectTop = param.BackBufferHeight;
const int w = param.BackBufferWidth;
const int h = param.BackBufferHeight;
if (cfg::SCREENRESIZE->enable_screen_resize) {
RECT rect {
0,
0,
(LONG)topSurface_width,
(LONG)topSurface_height,
};
pReal->ColorFill(topSurface, &rect, D3DCOLOR_XRGB(0, 0, 0));
}
D3DLOCKED_RECT rect;
HRESULT hr;
@@ -750,6 +760,7 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
(LONG)(rectLeft + w),
(LONG)(rectTop + h),
};
if (GRAPHICS_FS_ORIENTATION_SWAP) {
originRect.left = (topSurface_width / 2) - (GRAPHICS_FS_ORIGINAL_WIDTH / 2);
originRect.top = (topSurface_height / 2) - (GRAPHICS_FS_ORIGINAL_HEIGHT / 2);
@@ -757,6 +768,21 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
originRect.bottom = originRect.top + GRAPHICS_FS_ORIGINAL_HEIGHT;
}
bool duplicate = false;
RECT originRect2 = originRect;
if (cfg::SCREENRESIZE->enable_screen_resize) {
auto& scene = cfg::SCREENRESIZE->scene_settings[cfg::SCREENRESIZE->screen_resize_current_scene];
if (scene.duplicate == cfg::ScreenDuplicateMode::CopyLeft) {
duplicate = true;
originRect2.right = originRect.left;
originRect2.left = (LONG)(originRect2.left - (originRect.right - originRect.left));
} else if (scene.duplicate == cfg::ScreenDuplicateMode::CopyRight) {
duplicate = true;
originRect2.left = originRect.right;
originRect2.right = (LONG)(originRect2.left + (originRect.right - originRect.left));
}
}
// log_misc(
// "graphics::d3d9", "originRect: {} {} {} {}",
// originRect.left, originRect.top, originRect.right, originRect.bottom);
@@ -768,9 +794,21 @@ void SurfaceHook(IDirect3DDevice9 *pReal) {
if (hr != D3D_OK) {
log_warning(
"graphics::d3d9",
"SurfaceHook - StretchRect backbuffer failed, rect: {} {} {} {}",
"SurfaceHook - StretchRect backbuffer failed for main image, rect: {} {} {} {}",
originRect.left, originRect.top, originRect.right, originRect.bottom);
}
if (duplicate) {
hr = pReal->StretchRect(
backbuffer, nullptr,
topSurface, &originRect2,
D3DTEXF_LINEAR);
if (hr != D3D_OK) {
log_warning(
"graphics::d3d9",
"SurfaceHook - StretchRect backbuffer failed for the duplicate, rect: {} {} {} {}",
originRect2.left, originRect2.top, originRect2.right, originRect2.bottom);
}
}
topSurface->UnlockRect();
// phase 2 - viewport calculation - do the actual zoom / offset math
+25 -6
View File
@@ -20,7 +20,9 @@
#include "cfg/screen_resize.h"
#include "easrv/easrv.h"
#include "external/cardio/cardio_runner.h"
#ifndef NO_SCARD
#include "external/scard/scard.h"
#endif
#include "games/game.h"
#include "games/io.h"
#include "games/bbc/bbc.h"
@@ -263,7 +265,8 @@ int main_implementation(int argc, char *argv[]) {
// detect model used to load option overrides
auto options_version = launcher::detect_gameversion(
LAUNCHER_OPTIONS->at(launcher::Options::PathToEa3Config).value
LAUNCHER_OPTIONS->at(launcher::Options::PathToEa3Config).value,
LAUNCHER_OPTIONS->at(launcher::Options::PathToBootstrap).value
);
if (!options_version.model.empty() && options_version.model.size() < 4) {
if (options_version.dest.size() == 1) {
@@ -479,6 +482,9 @@ int main_implementation(int argc, char *argv[]) {
// Disable legacy behaviour to avoid conflict
games::iidx::DISABLE_CAMS = true;
}
if (games::iidx::DISABLE_CAMS) {
SetEnvironmentVariable("CONNECT_CAMERA", "0");
}
if (options[launcher::Options::IIDXCamHookOverride].is_active()) {
games::iidx::TDJ_CAMERA_OVERRIDE = options[launcher::Options::IIDXCamHookOverride].value_text();
}
@@ -816,6 +822,7 @@ int main_implementation(int argc, char *argv[]) {
for (auto &sextet : options[launcher::Options::SextetStreamPort].values_text()) {
sextet_devices.emplace_back(sextet);
}
#ifndef NO_SCARD
if (options[launcher::Options::HIDSmartCard].value_bool()) {
WINSCARD_CONFIG.cardinfo_callback = eamuse_scard_callback;
scard_threadstart();
@@ -835,6 +842,7 @@ int main_implementation(int argc, char *argv[]) {
WINSCARD_CONFIG.add_padding_to_felica = true;
}
}
#endif
if (options[launcher::Options::CardIOHIDReaderOrderFlip].value_bool()) {
CARDIO_RUNNER_FLIP = true;
}
@@ -1200,13 +1208,22 @@ int main_implementation(int argc, char *argv[]) {
}
// log
#ifdef SPICE64
log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x)");
#elif SPICE32_LARGE_ADDRESS_AWARE
log_info("launcher", "SpiceTools Bootstrap (x32) (Large Address Aware) (spice2x)");
#ifndef SPICE_LINUX
#ifdef SPICE64
log_info("launcher", "SpiceTools Bootstrap (x64) (spice2x)");
#elif SPICE32_LARGE_ADDRESS_AWARE
log_info("launcher", "SpiceTools Bootstrap (x32 - Large Address Aware) (spice2x)");
#else
log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x)");
#endif
#else
log_info("launcher", "SpiceTools Bootstrap (x32) (spice2x)");
#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);
// log command line arguments
@@ -2314,8 +2331,10 @@ int main_implementation(int argc, char *argv[]) {
// debug hook
debughook::detach();
#ifndef NO_SCARD
// scard
scard_fini();
#endif
// stop reader thread in case it was running
stop_reader_thread();
+34 -10
View File
@@ -6,6 +6,12 @@
#include <fstream>
#ifdef NO_SCARD
#define WITH_SCARD 0
#else
#define WITH_SCARD 1
#endif
static const std::vector<std::string> CATEGORY_ORDER_API = {
"SpiceCompanion and API",
"API (Serial)",
@@ -1385,21 +1391,27 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
.name = "scard",
.desc = "Detects and uses HID smart card readers for card input. Developed for ACR122U reader",
.type = OptionType::Bool,
.hidden = !WITH_SCARD,
.category = "NFC Card Readers",
.disabled = !WITH_SCARD,
},
{
.title = "HID SmartCard Order Flip",
.name = "scardflip",
.desc = "Flips the order of detection for P1/P2",
.type = OptionType::Bool,
.hidden = !WITH_SCARD,
.category = "NFC Card Readers",
.disabled = !WITH_SCARD,
},
{
.title = "HID SmartCard Order Toggle",
.name = "scardtoggle",
.desc = "Toggles reader between P1/P2 using the NumLock key state",
.type = OptionType::Bool,
.hidden = !WITH_SCARD,
.category = "NFC Card Readers",
.disabled = !WITH_SCARD,
},
{
// HIDSmartCardIdConvert
@@ -1413,12 +1425,14 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
"For example, abcd56780123 is converted to e00401abcd567801 on card in. This results in different card numbers so "
"be careful when connecting to servers!",
.type = OptionType::Enum,
.hidden = !WITH_SCARD,
.category = "NFC Card Readers",
.elements = {
{"legacy", "Use cards as-is"},
{"fix", "Fix bad cards only"},
{"all", "Force all cards"},
},
.disabled = !WITH_SCARD,
},
{
// SextetStreamPort
@@ -2608,8 +2622,19 @@ std::vector<Option> launcher::merge_options(
return merged;
}
std::string launcher::detect_bootstrap_release_code() {
std::string bootstrap_path = "prop/bootstrap.xml";
std::string launcher::detect_bootstrap_release_code(const std::string& bootstrap_user) {
std::string bootstrap_path;
if (!bootstrap_user.empty()) {
bootstrap_path = bootstrap_user;
} else if (fileutils::file_exists("prop/bootstrap.xml")) {
bootstrap_path = "prop/bootstrap.xml";
}
if (bootstrap_path.empty()) {
log_warning("options", "unable to detect bootstrap.xml file");
return "";
}
// load XML
tinyxml2::XMLDocument bootstrap;
@@ -2632,7 +2657,7 @@ std::string launcher::detect_bootstrap_release_code() {
return "";
}
static launcher::GameVersion detect_gameversion_ident() {
static launcher::GameVersion detect_gameversion_ident(const std::string& bootstrap_user) {
// detect ea3-ident path
std::string ident_path;
@@ -2678,7 +2703,7 @@ static launcher::GameVersion detect_gameversion_ident() {
auto node_ext = node_soft->FirstChildElement("ext");
if (node_ext) {
version.ext = node_ext->GetText();
auto bootstrap_ext = launcher::detect_bootstrap_release_code();
auto bootstrap_ext = launcher::detect_bootstrap_release_code(bootstrap_user);
if (version.ext.size() != 10 && bootstrap_ext.size() == 10) {
version.ext = bootstrap_ext;
} else if (bootstrap_ext.size() == 10) {
@@ -2714,8 +2739,7 @@ static launcher::GameVersion detect_gameversion_ident() {
return launcher::GameVersion();
}
launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user) {
launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user, const std::string& bootstrap_user) {
// detect ea3-config path
std::string ea3_path;
if (!ea3_user.empty()) {
@@ -2729,7 +2753,7 @@ launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user)
}
if (ea3_path.empty()) {
log_warning("options", "unable to detect EA3 configuration file");
return detect_gameversion_ident();
return detect_gameversion_ident(bootstrap_user);
}
// load XML
@@ -2769,7 +2793,7 @@ launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user)
if (ea3_config.Parse(xml_str.c_str()) != tinyxml2::XML_SUCCESS) {
// if we still failed, give up
log_warning("options", "unable to parse fixed xml");
return detect_gameversion_ident();
return detect_gameversion_ident(bootstrap_user);
}
}
@@ -2800,7 +2824,7 @@ launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user)
auto node_ext = node_soft->FirstChildElement("ext");
if (node_ext) {
version.ext = node_ext->GetText();
auto bootstrap_ext = launcher::detect_bootstrap_release_code();
auto bootstrap_ext = launcher::detect_bootstrap_release_code(bootstrap_user);
if (version.ext.size() != 10 && bootstrap_ext.size() == 10) {
version.ext = bootstrap_ext;
} else if (bootstrap_ext.size() == 10) {
@@ -2833,5 +2857,5 @@ launcher::GameVersion launcher::detect_gameversion(const std::string &ea3_user)
// error
log_warning("options", "unable to find /ea3/soft/model in {}", ea3_path);
return detect_gameversion_ident();
return detect_gameversion_ident(bootstrap_user);
}
+2 -2
View File
@@ -279,6 +279,6 @@ namespace launcher {
std::string ext;
};
std::string detect_bootstrap_release_code();
GameVersion detect_gameversion(const std::string& ea3_user);
std::string detect_bootstrap_release_code(const std::string& bootstrap_user);
GameVersion detect_gameversion(const std::string& ea3_user, const std::string& bootstrap_user);
}
+7
View File
@@ -2904,10 +2904,17 @@ namespace overlay::windows {
}
void Config::build_about() {
#ifndef SPICE_LINUX
ImGui::TextUnformatted(std::string(
"spice2x (a fork of SpiceTools)\r\n"
"=========================\r\n" +
to_string(VERSION_STRING)).c_str());
#else
ImGui::TextUnformatted(std::string(
"spice2x (a fork of SpiceTools) for Linux\r\n"
"=========================\r\n" +
to_string(VERSION_STRING)).c_str());
#endif
ImGui::TextUnformatted("");
if (ImGui::Button(PROJECT_URL)) {
@@ -55,6 +55,7 @@ namespace overlay::windows {
scene.offset_y = 0;
scene.scale_x = 1.f;
scene.scale_y = 1.f;
scene.duplicate = cfg::ScreenDuplicateMode::None;
}
cfg::SCREENRESIZE->enable_window_resize = false;
@@ -149,6 +150,17 @@ namespace overlay::windows {
ImGui::HelpMarker("Hint: ctrl + click on the slider to type in a numeric value.");
}
static const char* dupe_items[] = { "None", "Copy Left", "Copy Right" };
ImGui::Combo(
"Duplicate",
reinterpret_cast<int *>(&scene.duplicate),
dupe_items,
ARRAYSIZE(dupe_items));
ImGui::SameLine();
ImGui::HelpMarker(
"Show an identical copy of the image on the left or right, allowing you to achieve "
"wrap-around effect when an offset is set.");
ImGui::EndDisabled();
}