mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
Add Windows build support via MSYS2 and fix platform-specific code
Guard X11 display crash handler with __linux__, add Windows GlobalMemoryStatusEx path in memory_monitor, guard warden cache paths with APPDATA on Windows, and make pkg-config optional in CMakeLists with a find_library fallback. Add Windows x86-64 CI job using MSYS2 MINGW64 to the build workflow.
This commit is contained in:
parent
02fd0166e9
commit
cb01821d89
6 changed files with 125 additions and 16 deletions
44
.github/workflows/build.yml
vendored
44
.github/workflows/build.yml
vendored
|
|
@ -64,3 +64,47 @@ jobs:
|
|||
name: wowee-${{ matrix.arch }}
|
||||
path: build/bin/
|
||||
if-no-files-found: error
|
||||
|
||||
build-windows:
|
||||
name: Build (windows-x86-64)
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up MSYS2
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: MINGW64
|
||||
update: false
|
||||
install: >-
|
||||
mingw-w64-x86_64-cmake
|
||||
mingw-w64-x86_64-gcc
|
||||
mingw-w64-x86_64-pkgconf
|
||||
mingw-w64-x86_64-SDL2
|
||||
mingw-w64-x86_64-glew
|
||||
mingw-w64-x86_64-glm
|
||||
mingw-w64-x86_64-openssl
|
||||
mingw-w64-x86_64-zlib
|
||||
mingw-w64-x86_64-ffmpeg
|
||||
mingw-w64-x86_64-unicorn
|
||||
git
|
||||
|
||||
- name: Clone ImGui
|
||||
shell: msys2 {0}
|
||||
run: git clone --depth 1 https://github.com/ocornut/imgui.git extern/imgui
|
||||
|
||||
- name: Configure
|
||||
shell: msys2 {0}
|
||||
run: cmake -S . -B build -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
|
||||
|
||||
- name: Build
|
||||
shell: msys2 {0}
|
||||
run: cmake --build build --parallel $(nproc)
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: wowee-windows-x86-64
|
||||
path: build/bin/
|
||||
if-no-files-found: error
|
||||
|
|
|
|||
|
|
@ -22,8 +22,25 @@ find_package(GLEW REQUIRED)
|
|||
find_package(OpenSSL REQUIRED)
|
||||
find_package(Threads REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
pkg_check_modules(FFMPEG REQUIRED libavformat libavcodec libswscale libavutil)
|
||||
if(WIN32)
|
||||
find_package(PkgConfig QUIET)
|
||||
else()
|
||||
find_package(PkgConfig REQUIRED)
|
||||
endif()
|
||||
if(PkgConfig_FOUND)
|
||||
pkg_check_modules(FFMPEG REQUIRED libavformat libavcodec libswscale libavutil)
|
||||
else()
|
||||
# Fallback for MSVC/vcpkg — find FFmpeg libraries manually
|
||||
find_path(FFMPEG_INCLUDE_DIRS libavformat/avformat.h)
|
||||
find_library(AVFORMAT_LIB NAMES avformat)
|
||||
find_library(AVCODEC_LIB NAMES avcodec)
|
||||
find_library(AVUTIL_LIB NAMES avutil)
|
||||
find_library(SWSCALE_LIB NAMES swscale)
|
||||
set(FFMPEG_LIBRARIES ${AVFORMAT_LIB} ${AVCODEC_LIB} ${AVUTIL_LIB} ${SWSCALE_LIB})
|
||||
if(NOT AVFORMAT_LIB)
|
||||
message(FATAL_ERROR "FFmpeg not found. On Windows install via MSYS2: mingw-w64-x86_64-ffmpeg")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Unicorn Engine (x86 emulator for cross-platform Warden module execution)
|
||||
find_library(UNICORN_LIBRARY NAMES unicorn)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,16 @@
|
|||
#include <fstream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
||||
namespace wowee {
|
||||
namespace core {
|
||||
|
||||
#ifndef _WIN32
|
||||
namespace {
|
||||
size_t readMemAvailableBytesFromProc() {
|
||||
std::ifstream meminfo("/proc/meminfo");
|
||||
|
|
@ -26,6 +31,7 @@ size_t readMemAvailableBytesFromProc() {
|
|||
return 0;
|
||||
}
|
||||
} // namespace
|
||||
#endif
|
||||
|
||||
MemoryMonitor& MemoryMonitor::getInstance() {
|
||||
static MemoryMonitor instance;
|
||||
|
|
@ -33,6 +39,16 @@ MemoryMonitor& MemoryMonitor::getInstance() {
|
|||
}
|
||||
|
||||
void MemoryMonitor::initialize() {
|
||||
#ifdef _WIN32
|
||||
ULONGLONG totalKB = 0;
|
||||
if (GetPhysicallyInstalledSystemMemory(&totalKB)) {
|
||||
totalRAM_ = static_cast<size_t>(totalKB) * 1024ull;
|
||||
LOG_INFO("System RAM detected: ", totalRAM_ / (1024 * 1024 * 1024), " GB");
|
||||
} else {
|
||||
totalRAM_ = 16ull * 1024 * 1024 * 1024;
|
||||
LOG_WARNING("Could not detect system RAM, assuming 16GB");
|
||||
}
|
||||
#else
|
||||
struct sysinfo info;
|
||||
if (sysinfo(&info) == 0) {
|
||||
totalRAM_ = static_cast<size_t>(info.totalram) * info.mem_unit;
|
||||
|
|
@ -42,9 +58,18 @@ void MemoryMonitor::initialize() {
|
|||
totalRAM_ = 16ull * 1024 * 1024 * 1024;
|
||||
LOG_WARNING("Could not detect system RAM, assuming 16GB");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t MemoryMonitor::getAvailableRAM() const {
|
||||
#ifdef _WIN32
|
||||
MEMORYSTATUSEX status;
|
||||
status.dwLength = sizeof(status);
|
||||
if (GlobalMemoryStatusEx(&status)) {
|
||||
return static_cast<size_t>(status.ullAvailPhys);
|
||||
}
|
||||
return totalRAM_ / 2;
|
||||
#else
|
||||
// Best source on Linux for reclaimable memory headroom.
|
||||
if (size_t memAvailable = readMemAvailableBytesFromProc(); memAvailable > 0) {
|
||||
return memAvailable;
|
||||
|
|
@ -59,6 +84,7 @@ size_t MemoryMonitor::getAvailableRAM() const {
|
|||
return (totalRAM_ > 0 && available > totalRAM_) ? totalRAM_ : available;
|
||||
}
|
||||
return totalRAM_ / 2; // Fallback: assume 50% available
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t MemoryMonitor::getRecommendedCacheBudget() const {
|
||||
|
|
|
|||
|
|
@ -2397,11 +2397,15 @@ bool GameHandler::loadWardenCRFile(const std::string& moduleHashHex) {
|
|||
wardenCREntries_.clear();
|
||||
|
||||
// Look for .cr file in warden cache
|
||||
std::string homeDir;
|
||||
if (const char* h = std::getenv("HOME")) homeDir = h;
|
||||
else homeDir = ".";
|
||||
|
||||
std::string crPath = homeDir + "/.local/share/wowee/warden_cache/" + moduleHashHex + ".cr";
|
||||
std::string cacheBase;
|
||||
#ifdef _WIN32
|
||||
if (const char* h = std::getenv("APPDATA")) cacheBase = std::string(h) + "\\wowee\\warden_cache";
|
||||
else cacheBase = ".\\warden_cache";
|
||||
#else
|
||||
if (const char* h = std::getenv("HOME")) cacheBase = std::string(h) + "/.local/share/wowee/warden_cache";
|
||||
else cacheBase = "./warden_cache";
|
||||
#endif
|
||||
std::string crPath = cacheBase + "/" + moduleHashHex + ".cr";
|
||||
|
||||
std::ifstream crFile(crPath, std::ios::binary);
|
||||
if (!crFile) {
|
||||
|
|
@ -2581,10 +2585,15 @@ void GameHandler::handleWardenData(network::Packet& packet) {
|
|||
|
||||
// Cache raw module to disk
|
||||
{
|
||||
std::string homeDir;
|
||||
if (const char* h = std::getenv("HOME")) homeDir = h;
|
||||
else homeDir = ".";
|
||||
std::string cacheDir = homeDir + "/.local/share/wowee/warden_cache";
|
||||
#ifdef _WIN32
|
||||
std::string cacheDir;
|
||||
if (const char* h = std::getenv("APPDATA")) cacheDir = std::string(h) + "\\wowee\\warden_cache";
|
||||
else cacheDir = ".\\warden_cache";
|
||||
#else
|
||||
std::string cacheDir;
|
||||
if (const char* h = std::getenv("HOME")) cacheDir = std::string(h) + "/.local/share/wowee/warden_cache";
|
||||
else cacheDir = "./warden_cache";
|
||||
#endif
|
||||
std::filesystem::create_directories(cacheDir);
|
||||
|
||||
std::string hashHex;
|
||||
|
|
|
|||
|
|
@ -906,13 +906,18 @@ bool WardenModule::initializeModule() {
|
|||
// ============================================================================
|
||||
|
||||
WardenModuleManager::WardenModuleManager() {
|
||||
// Set cache directory: ~/.local/share/wowee/warden_cache/
|
||||
const char* home = std::getenv("HOME");
|
||||
if (home) {
|
||||
// Set cache directory
|
||||
#ifdef _WIN32
|
||||
if (const char* appdata = std::getenv("APPDATA"))
|
||||
cacheDirectory_ = std::string(appdata) + "\\wowee\\warden_cache";
|
||||
else
|
||||
cacheDirectory_ = ".\\warden_cache";
|
||||
#else
|
||||
if (const char* home = std::getenv("HOME"))
|
||||
cacheDirectory_ = std::string(home) + "/.local/share/wowee/warden_cache";
|
||||
} else {
|
||||
else
|
||||
cacheDirectory_ = "./warden_cache";
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create cache directory if it doesn't exist
|
||||
std::filesystem::create_directories(cacheDirectory_);
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <exception>
|
||||
#include <csignal>
|
||||
#include <SDL2/SDL.h>
|
||||
#ifdef __linux__
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
// Keep a persistent X11 connection for emergency mouse release in signal handlers.
|
||||
|
|
@ -16,6 +17,9 @@ static void releaseMouseGrab() {
|
|||
XFlush(g_emergencyDisplay);
|
||||
}
|
||||
}
|
||||
#else
|
||||
static void releaseMouseGrab() {}
|
||||
#endif
|
||||
|
||||
static void crashHandler(int sig) {
|
||||
releaseMouseGrab();
|
||||
|
|
@ -24,7 +28,9 @@ static void crashHandler(int sig) {
|
|||
}
|
||||
|
||||
int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
|
||||
#ifdef __linux__
|
||||
g_emergencyDisplay = XOpenDisplay(nullptr);
|
||||
#endif
|
||||
std::signal(SIGSEGV, crashHandler);
|
||||
std::signal(SIGABRT, crashHandler);
|
||||
std::signal(SIGFPE, crashHandler);
|
||||
|
|
@ -46,7 +52,9 @@ int main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) {
|
|||
app.shutdown();
|
||||
|
||||
LOG_INFO("Application exited successfully");
|
||||
#ifdef __linux__
|
||||
if (g_emergencyDisplay) { XCloseDisplay(g_emergencyDisplay); g_emergencyDisplay = nullptr; }
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue