WL
SKSE Plugin Desktop Screenshot Capture
CMakeLists.txt
189 lines
txt
CMakePresets.json
73 lines
json
logger.h
95 lines
txt
PapyrusInterface.cpp
296 lines
txt
PapyrusInterface.h
39 lines
txt
pch.h
69 lines
txt
plugin.cpp
66 lines
txt
ScreenCapture.cpp
958 lines
txt
ScreenCapture.h
91 lines
txt
WL
I am trying to create a SKSE plugin for SKYRIM which will capture the desktop image in various file formats. The program is based on windows desktop Duplication with WIC fro file saving and directXtk/direcrxTEK for DDS file saving. I an having trouble with compiler errors seemingly related to SKSE. My SKSE is located in C:/CodePackages/SKSE_2_02_06/src/SKSE64 . Please review the attached files and determine the source of the errors and how they can be fixed. Do not present recomended fixes by writing files but rather use artifacts. The compiler errors are listed below: 'MAKE_SKSE_VERSION': identifier not found missing type specifier - int assumed. Note: C++ does not support default-int syntax error: missing ';' before identifier 'TakePhoto' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' 'StaticFunctionTag': undeclared identifier 'base': undeclared identifier 'StaticFunctionTag': undeclared identifier 'base': undeclared identifier syntax error: missing ')' before identifier 'path' 'RUNTIME_VERSION_1_5_39': undeclared identifier missing type specifier - int assumed. Note: C++ does not support default-int syntax error: missing ';' before identifier 'TakePhoto' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' 'StaticFunctionTag': undeclared identifier syntax error: ')' 'StaticFunctionTag': undeclared identifier syntax error: ',' missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'TakePhoto' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) missing type specifier - int assumed. Note: C++ does not support default-int 'int PrintScreenPapyrus::BSFixedString': redefinition syntax error: missing ';' before identifier 'Get_Result' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) 'PrintScreenPapyrus::Cancel': redefinition; multiple initialization 'bool PrintScreenPapyrus::Cancel': redefinition 'StaticFunctionTag': undeclared identifier syntax error: ')' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) 'PrintScreenPapyrus::CheckPath': redefinition; multiple initialization 'bool PrintScreenPapyrus::CheckPath': redefinition 'StaticFunctionTag': undeclared identifier syntax error: ',' syntax error: missing ';' before '{' '{': missing function header (old-style formal list?) use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction1' use of undefined type 'VMClassRegistry' use of undefined type 'VMClassRegistry' 'kFunctionFlag_NoWait': undeclared identifier use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction0' use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction0' use of undefined type 'VMClassRegistry' 'StaticFunctionTag': undeclared identifier syntax error: identifier 'NativeFunction1'
Edit
Looking at the compilation errors, the main issue is that your SKSE headers aren't being properly included or found. The errors indicate that fundamental SKSE types like BSFixedString, StaticFunctionTag, VMClassRegistry, and macros like MAKE_SKSE_VERSION are not defined.
Let me analyze the issues and provide fixes:
SKSE Plugin Compilation Fixes
Document
# SKSE Plugin Compilation Issues and Fixes ## Root Cause Analysis The compilation errors stem from several issues: 1. **Incorrect SKSE path in PCH.h**: The path `C:/CodePackages/skse64_2_02_06/src/common/ITypes.h` doesn't match your actual SKSE lo
Now let me provide the corrected files. I'll start with the most critical fixes:
Fixed PCH.h with Correct SKSE Headers
Code
// PCH.h - Fixed Precompiled Header with correct SKSE paths #pragma once // Windows SDK Headers FIRST #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include <windows.h> // Standard C++ Library Headers (before SKSE) #include <string> #include <string
Fixed plugin.cpp with Correct SKSE Implementation
Code
// plugin.cpp - Fixed for SKSE 2.02.06 compatibility #include "PCH.h" #include "logger.h" // Plugin information static PluginHandle g_pluginHandle = kPluginHandle_Invalid; static SKSEPapyrusInterface* g_papyrus = nullptr; // Plugin namespace namesp
Fixed CMakeLists.txt with Correct Paths
Code
cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linki
The main issues and their fixes are:
- Path corrections: Fixed the SKSE path from
C:/CodePackaes/skse64_2_2_6toC:/CodePackages/SKSE_2_02_06(correcting both the typo "CodePackaes" and the version format) - Header include fixes: Updated PCH.h to include the correct SKSE headers from your actual SKSE installation directory
- Version macro fix: Replaced
MAKE_SKSE_VERSIONwith a manual hex version since this macro may not be available in your SKSE version - Runtime version fix: Replaced
RUNTIME_VERSION_1_5_39with the actual hex value0x010539F0
Next steps to try compilation:
- Replace your
PCH.hfile with the fixed version - Replace your
plugin.cppfile with the fixed version - Replace your
CMakeLists.txtfile with the fixed version - Ensure your SKSE directory actually exists at
C:/CodePackages/SKSE_2_02_06/src/skse64and contains the expected header files
If you continue to have issues, you might want to consider switching to CommonLibSSE approach (which I outlined in the analysis artifact) as it's more modern and handles SKSE compatibility automatically.
Retry
WL
I agree that we ahould use Commonlibssepng headers instead of the current skse. My concern is that the code may become confused and try to use both systems thus generating spurious errors. I prefer simple code when possible. Can you make these changes?
Edit
You're absolutely right - mixing two different SKSE systems will cause conflicts and confusion. Let me create clean, simple files that use only CommonLibSSE throughout.
Clean PCH.h Using Only CommonLibSSE
Code
// PCH.h - Clean implementation using only CommonLibSSE #pragma once // Windows SDK Headers FIRST #define WIN32_LEAN_AND_MEAN #define NOMINMAX #include <windows.h> // Standard C++ Library Headers #include <string> #include <string_view> #include <v
Clean plugin.cpp Using Only CommonLibSSE
Code
// plugin.cpp - Clean implementation using only CommonLibSSE #include "PCH.h" #include "logger.h" // Plugin namespace namespace Plugin { constexpr const char* NAME = "PrintScreen"; constexpr REL::Version VERSION{1, 0, 0}; } // Forward decla
Clean PapyrusInterface.cpp Using Only CommonLibSSE
Code
#include "PCH.h" #include "PapyrusInterface.h" #include "ScreenCapture.h" #include "logger.h" namespace PrintScreenPapyrus { // Global state std::atomic<bool> g_isRunning{false}; std::atomic<bool> g_cancelFlag{false}; std::atomi
Clean PapyrusInterface.h Using Only CommonLibSSE
Code
#pragma once #include "PCH.h" #include <string> #include <atomic> #include <mutex> namespace PrintScreenPapyrus { // Function declarations for Papyrus registration - Using CommonLibSSE types RE::BSFixedString TakePhoto( RE::Sta
Simplified CMakeLists.txt for CommonLibSSE Only
Code
cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linki
Perfect! I've created completely clean implementations that use only CommonLibSSE throughout. Here's what I changed:
Key Changes Made:
- PCH.h: Removed all raw SKSE includes and paths, using only CommonLibSSE headers (
RE/Skyrim.h,SKSE/SKSE.h,REL/Relocation.h) - plugin.cpp:
- Uses modern CommonLibSSE plugin structure
SKSEPlugin_Versioninstead of oldSKSEPlugin_Query- Proper CommonLibSSE initialization with
SKSE::Init() - All types prefixed with
RE::namespace
- PapyrusInterface.cpp & .h:
- All SKSE types now use
RE::prefix (RE::BSFixedString,RE::StaticFunctionTag) - Registration uses
RE::BSScript::IVirtualMachine*instead of oldVMClassRegistry* - Simplified registration syntax
- All SKSE types now use
- CMakeLists.txt:
- Removed all SKSE path references
- Removed SKSE-specific includes
- Much cleaner and simpler
Benefits:
- No mixing of systems - purely CommonLibSSE
- Future-proof - CommonLibSSE handles SKSE compatibility
- Simpler - fewer manual paths and includes
- Better type safety - modern C++ features
- Automatic version handling - no manual runtime version checks
The code is now much cleaner and should compile without the previous SKSE-related errors. CommonLibSSE will handle all the SKSE compatibility details automatically.
Retry
Claude can make mistakes. Please double-check responses.
Research
Sonnet 4
Copy
Publish
cmake_minimum_required(VERSION 3.24) project(PrintScreen VERSION 2.0.0 LANGUAGES CXX) # Ensure we're building for x64 if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) message(FATAL_ERROR "This project requires x64 architecture") endif() # Force static linking of runtime libraries set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") # policies... cmake_policy(SET CMP0091 NEW) if(POLICY CMP0135) cmake_policy(SET CMP0135 NEW) endif() list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") # C++ standard, build type, CRT set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE) endif() set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>") # find all packages find_package(CommonLibSSE CONFIG REQUIRED) find_package(directxtex CONFIG REQUIRED) find_package(directxtk CONFIG REQUIRED) # plugin target add_library(${PROJECT_NAME} SHARED plugin.cpp ScreenCapture.cpp PapyrusInterface.cpp printscreen.rc ) # precompiled headers target_precompile_headers(${PROJECT_NAME} PRIVATE PCH.h) # includes - Only CommonLibSSE needed now target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ) # link everything (only _after_ add_library) target_link_libraries(${PROJECT_NAME} PRIVATE CommonLibSSE::CommonLibSSE Microsoft::DirectXTex Microsoft::DirectXTK d3d11 dxgi dxguid windowscodecs ole32 oleaut32 ) # MSVC compiler flags & definitions if(MSVC) target_compile_options(${PROJECT_NAME} PRIVATE /W4 /permissive- /Zc:preprocessor /Zc:__cplusplus ) target_compile_definitions(${PROJECT_NAME} PRIVATE _UNICODE UNICODE WINVER=0x0601 _WIN32_WINNT=0x0601 ) endif() # Auto-deployment to mod folder # Debug: Print the environment variable message(STATUS "SKYRIM_MODS_FOLDER environment variable: $ENV{SKYRIM_MODS_FOLDER}") if(DEFINED ENV{SKYRIM_MODS_FOLDER}) message(STATUS "Environment variable is defined") if(IS_DIRECTORY "$ENV{SKYRIM_MODS_FOLDER}") message(STATUS "Directory exists: $ENV{SKYRIM_MODS_FOLDER}") set(OUTPUT_FOLDER "$ENV{SKYRIM_MODS_FOLDER}/${PROJECT_NAME}") set(DLL_FOLDER "${OUTPUT_FOLDER}/SKSE/Plugins") message(STATUS "Will copy to: ${DLL_FOLDER}") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${DLL_FOLDER}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_FILE_NAME:${PROJECT_NAME}>" COMMAND "${CMAKE_COMMAND}" -E echo "Copied DLL to ${DLL_FOLDER}" VERBATIM ) # Copy PDB files for debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_PDB_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_PDB_FILE_NAME:${PROJECT_NAME}>" COMMAND "${CMAKE_COMMAND}" -E echo "Copied pdb to ${DLL_FOLDER}" VERBATIM ) endif() else() message(STATUS "Directory does not exist: $ENV{SKYRIM_MODS_FOLDER}") endif() else() message(STATUS "SKYRIM_MODS_FOLDER environment variable not defined") # Alternative deployment methods if SKYRIM_MODS_FOLDER is not set message(STATUS "SKYRIM_MODS_FOLDER environment variable not set") # Try common Skyrim installation paths set(POSSIBLE_SKYRIM_PATHS "C:/Program Files (x86)/Steam/steamapps/common/Skyrim Special Edition" "C:/Program Files/Steam/steamapps/common/Skyrim Special Edition" "C:/Games/Steam/steamapps/common/Skyrim Special Edition" "C:/SteamLibrary/steamapps/common/Skyrim Special Edition" ) foreach(SKYRIM_PATH ${POSSIBLE_SKYRIM_PATHS}) if(IS_DIRECTORY "${SKYRIM_PATH}") set(SKYRIM_DATA_FOLDER "${SKYRIM_PATH}/Data") if(IS_DIRECTORY "${SKYRIM_DATA_FOLDER}") set(DLL_FOLDER "${SKYRIM_DATA_FOLDER}/SKSE/Plugins") message(STATUS "Found Skyrim installation: ${SKYRIM_PATH}") message(STATUS "Auto-deploying to: ${DLL_FOLDER}") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory "${DLL_FOLDER}" COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_FILE_NAME:${PROJECT_NAME}>" VERBATIM ) # Copy PDB files for debug builds if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo") add_custom_command( TARGET "${PROJECT_NAME}" POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy_if_different "$<TARGET_PDB_FILE:${PROJECT_NAME}>" "${DLL_FOLDER}/$<TARGET_PDB_FILE_NAME:${PROJECT_NAME}>" VERBATIM ) endif() break() endif() endif() endforeach() # Manual deployment instructions if(NOT DEFINED DLL_FOLDER) message(STATUS "") message(STATUS "=== MANUAL DEPLOYMENT REQUIRED ===") message(STATUS "Copy the built DLL to your Skyrim SKSE plugins folder:") message(STATUS "From: ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${PROJECT_NAME}.dll") message(STATUS "To: [Skyrim]/Data/SKSE/Plugins/${PROJECT_NAME}.dll") message(STATUS "") message(STATUS "Or set the SKYRIM_MODS_FOLDER environment variable for automatic deployment") message(STATUS "Example: set SKYRIM_MODS_FOLDER=C:/ModOrganizer2/mods") message(STATUS "") endif() endif() # Print configuration info message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "C++ standard: ${CMAKE_CXX_STANDARD}") message(STATUS "CommonLibSSE found: ${CommonLibSSE_FOUND}") if(DEFINED OUTPUT_FOLDER) message(STATUS "Output folder: ${OUTPUT_FOLDER}") endif()