diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index daa0365f..e042aed0 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -182,6 +182,11 @@ jobs:
mingw-w64-clang-aarch64-openssl
mingw-w64-clang-aarch64-zlib
mingw-w64-clang-aarch64-ffmpeg
+ mingw-w64-clang-aarch64-unicorn
+ mingw-w64-clang-aarch64-vulkan-loader
+ mingw-w64-clang-aarch64-vulkan-headers
+ mingw-w64-clang-aarch64-shaderc
+ mingw-w64-clang-aarch64-stormlib
git
- name: Configure
@@ -237,6 +242,10 @@ jobs:
mingw-w64-x86_64-zlib
mingw-w64-x86_64-ffmpeg
mingw-w64-x86_64-unicorn
+ mingw-w64-x86_64-vulkan-loader
+ mingw-w64-x86_64-vulkan-headers
+ mingw-w64-x86_64-shaderc
+ mingw-w64-x86_64-stormlib
mingw-w64-x86_64-nsis
git
diff --git a/.gitignore b/.gitignore
index 1ece92da..263a4a0d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -64,7 +64,7 @@ cache/
saves/
wowee_[0-9][0-9][0-9][0-9]
-# Extracted assets (run ./extract_assets.sh to generate)
+# Extracted assets (run ./extract_assets.sh or .\extract_assets.ps1 to generate)
Data/db/
Data/character/
Data/creature/
diff --git a/BUILD_INSTRUCTIONS.md b/BUILD_INSTRUCTIONS.md
index bd1a09a7..b8192d95 100644
--- a/BUILD_INSTRUCTIONS.md
+++ b/BUILD_INSTRUCTIONS.md
@@ -49,15 +49,104 @@ cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j"$(nproc)"
```
+### Asset Extraction (Linux)
+
+After building, extract assets from your WoW client:
+
+```bash
+./extract_assets.sh /path/to/WoW/Data wotlk
+```
+
+Supports `classic`, `tbc`, `wotlk` targets (auto-detected if omitted).
+
+---
+
+## 🍎 macOS
+
+### Install Dependencies
+
+```bash
+brew install cmake pkg-config sdl2 glew glm openssl@3 zlib ffmpeg unicorn stormlib
+```
+
+### Clone & Build
+
+```bash
+git clone --recurse-submodules https://github.com/Kelsidavis/WoWee.git
+cd WoWee
+
+BREW=$(brew --prefix)
+export PKG_CONFIG_PATH="$BREW/lib/pkgconfig:$(brew --prefix ffmpeg)/lib/pkgconfig:$(brew --prefix openssl@3)/lib/pkgconfig"
+cmake -S . -B build -DCMAKE_BUILD_TYPE=Release \
+ -DCMAKE_PREFIX_PATH="$BREW" \
+ -DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"
+cmake --build build -j"$(sysctl -n hw.logicalcpu)"
+```
+
+### Asset Extraction (macOS)
+
+```bash
+./extract_assets.sh /path/to/WoW/Data wotlk
+```
+
+---
+
+## 🪟 Windows (MSYS2 — Recommended)
+
+MSYS2 provides all dependencies as pre-built packages.
+
+### Install MSYS2
+
+Download and install from , then open a **MINGW64** shell.
+
+### Install Dependencies
+
+```bash
+pacman -S --needed \
+ mingw-w64-x86_64-cmake \
+ mingw-w64-x86_64-gcc \
+ mingw-w64-x86_64-ninja \
+ 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 \
+ mingw-w64-x86_64-vulkan-loader \
+ mingw-w64-x86_64-vulkan-headers \
+ mingw-w64-x86_64-shaderc \
+ mingw-w64-x86_64-stormlib \
+ git
+```
+
+### Clone & Build
+
+```bash
+git clone --recurse-submodules https://github.com/Kelsidavis/WoWee.git
+cd WoWee
+cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
+cmake --build build --parallel $(nproc)
+```
+
---
## 🪟 Windows (Visual Studio 2022)
+For users who prefer Visual Studio over MSYS2.
+
### Install
-- Visual Studio 2022
-- Desktop development with C++
-- CMake tools for Windows
+- Visual Studio 2022 with **Desktop development with C++** workload
+- CMake tools for Windows (included in VS workload)
+- [LunarG Vulkan SDK](https://vulkan.lunarg.com/) (provides Vulkan headers, loader, and glslc)
+
+### vcpkg Dependencies
+
+```powershell
+vcpkg install sdl2 glew glm openssl zlib ffmpeg stormlib --triplet x64-windows
+```
### Clone
@@ -68,16 +157,29 @@ cd WoWee
### Build
-Open the folder in Visual Studio (it will detect CMake automatically)
+Open the folder in Visual Studio (it will detect CMake automatically)
or build from Developer PowerShell:
```powershell
-cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
+cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE="[vcpkg root]/scripts/buildsystems/vcpkg.cmake"
cmake --build build --config Release
```
---
+## 🪟 Asset Extraction (Windows)
+
+After building (via either MSYS2 or Visual Studio), extract assets from your WoW client:
+
+```powershell
+.\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data"
+```
+
+Or double-click `extract_assets.bat` and provide the path when prompted.
+You can also specify an expansion: `.\extract_assets.ps1 "C:\Games\WoW\Data" wotlk`
+
+---
+
## ⚠️ Notes
- Case matters on Linux (`WoWee` not `wowee`).
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ff956973..aa9cc256 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -592,12 +592,18 @@ add_custom_command(TARGET wowee POST_BUILD
# which does NOT include System32. Copy vulkan-1.dll into the output directory so
# SDL_Vulkan_LoadLibrary can locate it without needing a full system PATH search.
if(WIN32)
- add_custom_command(TARGET wowee POST_BUILD
- COMMAND ${CMAKE_COMMAND} -E copy_if_different
- "$ENV{SystemRoot}/System32/vulkan-1.dll"
- "$/vulkan-1.dll"
- COMMENT "Copying vulkan-1.dll to output directory"
- )
+ find_file(VULKAN_DLL vulkan-1.dll
+ PATHS "$ENV{SystemRoot}/System32" "$ENV{VULKAN_SDK}/Bin"
+ NO_DEFAULT_PATH)
+ if(VULKAN_DLL)
+ add_custom_command(TARGET wowee POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "${VULKAN_DLL}" "$/vulkan-1.dll"
+ COMMENT "Copying vulkan-1.dll to output directory"
+ )
+ else()
+ message(STATUS " vulkan-1.dll not found — skipping copy (MSYS2 provides it via PATH)")
+ endif()
endif()
# Install targets
@@ -659,7 +665,14 @@ if(STORMLIB_LIBRARY AND STORMLIB_INCLUDE_DIR)
Threads::Threads
)
if(WIN32)
- target_link_libraries(asset_extract PRIVATE wininet bz2)
+ find_library(WININET_LIB wininet)
+ find_library(BZ2_LIB bz2)
+ if(WININET_LIB)
+ target_link_libraries(asset_extract PRIVATE ${WININET_LIB})
+ endif()
+ if(BZ2_LIB)
+ target_link_libraries(asset_extract PRIVATE ${BZ2_LIB})
+ endif()
endif()
set_target_properties(asset_extract PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
diff --git a/README.md b/README.md
index debe3d16..347bcc13 100644
--- a/README.md
+++ b/README.md
@@ -36,7 +36,7 @@ Protocol Compatible with **Vanilla (Classic) 1.12 + TBC 2.4.3 + WotLK 3.3.5a**.
### Asset Pipeline
- Extracted loose-file **`Data/`** tree indexed by **`manifest.json`** (fast lookup + caching)
- Optional **overlay layers** for multi-expansion asset deduplication
-- `asset_extract` + `extract_assets.sh` for MPQ extraction (StormLib tooling)
+- `asset_extract` + `extract_assets.sh` (Linux/macOS) / `extract_assets.ps1` (Windows) for MPQ extraction (StormLib tooling)
- File formats: **BLP** (DXT1/3/5), **ADT**, **M2**, **WMO**, **DBC** (Spell/Item/Faction/etc.)
### Gameplay Systems
@@ -101,8 +101,12 @@ Wowee loads assets via an extracted loose-file tree indexed by `manifest.json` (
#### 1) Extract MPQs into `./Data/`
```bash
-# WotLK 3.3.5a example
+# Linux / macOS
./extract_assets.sh /path/to/WoW/Data wotlk
+
+# Windows (PowerShell)
+.\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data" wotlk
+# Or double-click extract_assets.bat
```
```
@@ -117,7 +121,7 @@ Data/
Notes:
- `StormLib` is required to build/run the extractor (`asset_extract`), but the main client does not require StormLib at runtime.
-- `extract_assets.sh` supports `classic`, `tbc`, `wotlk` targets.
+- `extract_assets.sh` / `extract_assets.ps1` support `classic`, `tbc`, `wotlk` targets.
#### 2) Point wowee at the extracted data
@@ -206,7 +210,7 @@ make -j$(nproc)
## Technical Details
-- **Platform**: Linux (primary), C++20, CMake 3.15+
+- **Platform**: Linux (primary), Windows (MSYS2/MSVC), macOS — C++20, CMake 3.15+
- **Dependencies**: SDL2, Vulkan, GLM, OpenSSL, ImGui, FFmpeg, Unicorn Engine (StormLib for asset extraction tooling)
- **Architecture**: Modular design with clear separation (core, rendering, networking, game logic, asset pipeline, UI, audio)
- **Networking**: Non-blocking TCP, SRP6a authentication, RC4 encryption, WoW 3.3.5a protocol
diff --git a/extract_assets.bat b/extract_assets.bat
new file mode 100644
index 00000000..27a181b9
--- /dev/null
+++ b/extract_assets.bat
@@ -0,0 +1,4 @@
+@echo off
+REM Convenience wrapper — launches the PowerShell asset extraction script.
+REM Usage: extract_assets.bat C:\Games\WoW\Data [expansion]
+powershell -ExecutionPolicy Bypass -File "%~dp0extract_assets.ps1" %*
diff --git a/extract_assets.ps1 b/extract_assets.ps1
new file mode 100644
index 00000000..9bcce87e
--- /dev/null
+++ b/extract_assets.ps1
@@ -0,0 +1,120 @@
+<#
+.SYNOPSIS
+ Extracts WoW MPQ archives for use with wowee (Windows equivalent of extract_assets.sh).
+
+.DESCRIPTION
+ Builds the asset_extract tool (if needed) and runs it against a WoW Data directory.
+
+.PARAMETER MpqDir
+ Path to the WoW client's Data directory containing .MPQ files.
+
+.PARAMETER Expansion
+ Expansion hint: classic, turtle, tbc, wotlk. Auto-detected if omitted.
+
+.EXAMPLE
+ .\extract_assets.ps1 "C:\Games\WoW-3.3.5a\Data"
+ .\extract_assets.ps1 "C:\Games\WoW-1.12\Data" classic
+ .\extract_assets.ps1 "D:\TurtleWoW\Data" turtle
+#>
+
+param(
+ [Parameter(Mandatory=$true, Position=0)]
+ [string]$MpqDir,
+
+ [Parameter(Position=1)]
+ [string]$Expansion = "auto"
+)
+
+$ErrorActionPreference = "Stop"
+
+$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
+$BuildDir = Join-Path $ScriptDir "build"
+$Binary = Join-Path $BuildDir "bin\asset_extract.exe"
+$OutputDir = Join-Path $ScriptDir "Data"
+
+# --- Validate arguments ---
+if (-not (Test-Path $MpqDir -PathType Container)) {
+ Write-Error "Error: Directory not found: $MpqDir"
+ exit 1
+}
+
+# Check for .MPQ files
+$mpqFiles = Get-ChildItem -Path $MpqDir -Filter "*.MPQ" -ErrorAction SilentlyContinue
+$mpqFilesLower = Get-ChildItem -Path $MpqDir -Filter "*.mpq" -ErrorAction SilentlyContinue
+if (-not $mpqFiles -and -not $mpqFilesLower) {
+ Write-Error "Error: No .MPQ files found in: $MpqDir`nMake sure this is the WoW Data/ directory (not the WoW root)."
+ exit 1
+}
+
+# Note about existing CSV DBCs
+if (Test-Path (Join-Path $OutputDir "expansions")) {
+ $csvPattern = $null
+ if ($Expansion -ne "auto") {
+ $csvPattern = Join-Path $OutputDir "expansions\$Expansion\db\*.csv"
+ } else {
+ $csvPattern = Join-Path $OutputDir "expansions\*\db\*.csv"
+ }
+ if ($csvPattern -and (Get-ChildItem -Path $csvPattern -ErrorAction SilentlyContinue)) {
+ Write-Host "Note: Found CSV DBCs. DBC extraction is optional; visual assets are still required.`n"
+ }
+}
+
+# --- Build asset_extract if needed ---
+if (-not (Test-Path $Binary)) {
+ Write-Host "Building asset_extract..."
+
+ # Check for cmake
+ if (-not (Get-Command cmake -ErrorAction SilentlyContinue)) {
+ Write-Error "Error: cmake not found. Install CMake and ensure it is on your PATH."
+ exit 1
+ }
+
+ if (-not (Test-Path $BuildDir)) {
+ & cmake -S $ScriptDir -B $BuildDir -DCMAKE_BUILD_TYPE=Release
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+ }
+
+ $numProcs = $env:NUMBER_OF_PROCESSORS
+ if (-not $numProcs) { $numProcs = 4 }
+ & cmake --build $BuildDir --target asset_extract --parallel $numProcs
+ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+
+ Write-Host ""
+}
+
+if (-not (Test-Path $Binary)) {
+ Write-Error "Error: Failed to build asset_extract"
+ exit 1
+}
+
+# --- Run extraction ---
+Write-Host "Extracting assets from: $MpqDir"
+Write-Host "Output directory: $OutputDir"
+Write-Host ""
+
+$extraArgs = @("--mpq-dir", $MpqDir, "--output", $OutputDir)
+
+if ($Expansion -ne "auto") {
+ $extraArgs += "--expansion"
+ $extraArgs += $Expansion
+}
+
+# Skip DBC extraction if CSVs already present
+$skipDbc = $false
+if ($Expansion -ne "auto") {
+ $csvPath = Join-Path $OutputDir "expansions\$Expansion\db\*.csv"
+ if (Get-ChildItem -Path $csvPath -ErrorAction SilentlyContinue) { $skipDbc = $true }
+} else {
+ $csvPath = Join-Path $OutputDir "expansions\*\db\*.csv"
+ if (Get-ChildItem -Path $csvPath -ErrorAction SilentlyContinue) { $skipDbc = $true }
+}
+if ($skipDbc) {
+ $extraArgs += "--skip-dbc"
+}
+
+& $Binary @extraArgs
+if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
+
+Write-Host ""
+Write-Host "Done! Assets extracted to $OutputDir"
+Write-Host "You can now run wowee."