Compare commits
8 Commits
pre-0.2.2-
...
v0.3.1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4371618a9b | ||
|
|
e32ac75b9c | ||
|
|
8ce29e1436 | ||
|
|
18b7fb9abf | ||
|
|
75bf38fa71 | ||
|
|
92cc574e15 | ||
|
|
546093360f | ||
|
|
d94b7a3e81 |
83
.clang-format
Normal file
83
.clang-format
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# Google C/C++ Code Style settings
|
||||||
|
# https://clang.llvm.org/docs/ClangFormatStyleOptions.html
|
||||||
|
# Author: Kehan Xue, kehan.xue (at) gmail.com
|
||||||
|
|
||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: Google
|
||||||
|
AccessModifierOffset: -1
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignConsecutiveAssignments: None
|
||||||
|
AlignOperands: Align
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllConstructorInitializersOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: false
|
||||||
|
AllowShortBlocksOnASingleLine: Empty
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortFunctionsOnASingleLine: Inline
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never # To avoid conflict, set this "Never" and each "if statement" should include brace when coding
|
||||||
|
AllowShortLambdasOnASingleLine: Inline
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AlwaysBreakAfterReturnType: None
|
||||||
|
AlwaysBreakTemplateDeclarations: Yes
|
||||||
|
BinPackArguments: true
|
||||||
|
BreakBeforeBraces: Custom
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterUnion: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: false
|
||||||
|
SplitEmptyRecord: false
|
||||||
|
SplitEmptyNamespace: false
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
ColumnLimit: 80
|
||||||
|
CompactNamespaces: false
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false # Make sure the * or & align on the left
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
FixNamespaceComments: true
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IndentCaseLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentWidth: 2
|
||||||
|
KeepEmptyLinesAtTheStartOfBlocks: true
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
PointerAlignment: Left
|
||||||
|
ReflowComments: false
|
||||||
|
# SeparateDefinitionBlocks: Always # Only support since clang-format 14
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyParentheses: false
|
||||||
|
SpacesBeforeTrailingComments: 2
|
||||||
|
SpacesInAngles: false
|
||||||
|
SpacesInCStyleCastParentheses: false
|
||||||
|
SpacesInContainerLiterals: false
|
||||||
|
SpacesInParentheses: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: c++11
|
||||||
|
TabWidth: 4
|
||||||
|
UseTab: Never
|
||||||
53
.clang-tidy
Normal file
53
.clang-tidy
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# YAZE clang-tidy configuration
|
||||||
|
# More lenient configuration for easier compliance
|
||||||
|
|
||||||
|
Checks: >
|
||||||
|
-*-,
|
||||||
|
clang-analyzer-*,
|
||||||
|
-clang-analyzer-alpha*,
|
||||||
|
performance-*,
|
||||||
|
-performance-unnecessary-value-param,
|
||||||
|
readability-*,
|
||||||
|
-readability-magic-numbers,
|
||||||
|
-readability-braces-around-statements,
|
||||||
|
-readability-named-parameter,
|
||||||
|
-readability-function-cognitive-complexity,
|
||||||
|
-readability-avoid-const-params-in-decls,
|
||||||
|
modernize-*,
|
||||||
|
-modernize-use-trailing-return-type,
|
||||||
|
-modernize-use-auto,
|
||||||
|
-modernize-avoid-c-arrays,
|
||||||
|
-modernize-use-default-member-init,
|
||||||
|
bugprone-*,
|
||||||
|
-bugprone-easily-swappable-parameters,
|
||||||
|
-bugprone-exception-escape,
|
||||||
|
-bugprone-narrowing-conversions,
|
||||||
|
-bugprone-implicit-widening-of-multiplication-result,
|
||||||
|
misc-*,
|
||||||
|
-misc-no-recursion,
|
||||||
|
-misc-non-private-member-variables-in-classes,
|
||||||
|
-misc-const-correctness
|
||||||
|
|
||||||
|
CheckOptions:
|
||||||
|
- key: readability-identifier-naming.VariableCase
|
||||||
|
value: lower_case
|
||||||
|
- key: readability-identifier-naming.FunctionCase
|
||||||
|
value: lower_case
|
||||||
|
- key: readability-identifier-naming.ClassCase
|
||||||
|
value: CamelCase
|
||||||
|
- key: readability-identifier-naming.StructCase
|
||||||
|
value: CamelCase
|
||||||
|
- key: readability-identifier-naming.NamespaceCase
|
||||||
|
value: lower_case
|
||||||
|
- key: readability-identifier-naming.MacroCase
|
||||||
|
value: UPPER_CASE
|
||||||
|
- key: readability-function-size.LineThreshold
|
||||||
|
value: 150
|
||||||
|
- key: readability-function-size.StatementThreshold
|
||||||
|
value: 100
|
||||||
|
- key: performance-unnecessary-value-param.AllowedTypes
|
||||||
|
value: 'std::function;std::unique_ptr;std::shared_ptr'
|
||||||
|
|
||||||
|
WarningsAsErrors: ''
|
||||||
|
HeaderFilterRegex: '(src|test)\/.*\.(h|hpp|hxx)$'
|
||||||
|
FormatStyle: google
|
||||||
35
.clangd
Normal file
35
.clangd
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
CompileFlags:
|
||||||
|
Add:
|
||||||
|
- -std=c++23
|
||||||
|
- -Wall
|
||||||
|
- -Wextra
|
||||||
|
Remove:
|
||||||
|
- -mllvm
|
||||||
|
- -xclang
|
||||||
|
|
||||||
|
Index:
|
||||||
|
Background: Build
|
||||||
|
StandardLibrary: Yes
|
||||||
|
|
||||||
|
InlayHints:
|
||||||
|
Enabled: Yes
|
||||||
|
ParameterNames: Yes
|
||||||
|
DeducedTypes: Yes
|
||||||
|
|
||||||
|
Hover:
|
||||||
|
ShowAKA: Yes
|
||||||
|
|
||||||
|
Diagnostics:
|
||||||
|
ClangTidy:
|
||||||
|
Add:
|
||||||
|
- readability-*
|
||||||
|
- modernize-*
|
||||||
|
- performance-*
|
||||||
|
Remove:
|
||||||
|
- modernize-use-trailing-return-type
|
||||||
|
- readability-braces-around-statements
|
||||||
|
- readability-magic-numbers
|
||||||
|
- readability-implicit-bool-conversion
|
||||||
|
- readability-identifier-naming
|
||||||
|
- readability-function-cognitive-complexity
|
||||||
|
- readability-function-size
|
||||||
151
.github/workflows/build-windows-fallback.yml
vendored
Normal file
151
.github/workflows/build-windows-fallback.yml
vendored
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
name: Windows Build Fallback
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_call:
|
||||||
|
inputs:
|
||||||
|
build_type:
|
||||||
|
description: 'Build type (Debug/Release)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'Release'
|
||||||
|
platform:
|
||||||
|
description: 'Platform (x64/x86)'
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
default: 'x64'
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: ${{ inputs.build_type }}
|
||||||
|
PLATFORM: ${{ inputs.platform }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-windows-fallback:
|
||||||
|
name: Windows ${{ inputs.platform }} ${{ inputs.build_type }} (Fallback)
|
||||||
|
runs-on: windows-2022
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# Try vcpkg first
|
||||||
|
- name: Set up vcpkg (Primary)
|
||||||
|
id: vcpkg_primary
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
VCPKG_DEFAULT_TRIPLET: '${{ inputs.platform }}-windows'
|
||||||
|
VCPKG_INSTALL_OPTIONS: '--x-install-root="${{ github.workspace }}/vcpkg_installed"'
|
||||||
|
|
||||||
|
# Fallback to newer baseline if primary fails
|
||||||
|
- name: Set up vcpkg (Fallback)
|
||||||
|
if: steps.vcpkg_primary.outcome == 'failure'
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: '2024.01.12'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json.backup'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
VCPKG_DEFAULT_TRIPLET: '${{ inputs.platform }}-windows'
|
||||||
|
VCPKG_INSTALL_OPTIONS: '--x-install-root="${{ github.workspace }}/vcpkg_installed"'
|
||||||
|
|
||||||
|
# Fallback to manual dependency installation if both vcpkg attempts fail
|
||||||
|
- name: Install dependencies manually
|
||||||
|
if: steps.vcpkg_primary.outcome == 'failure'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Installing dependencies manually using Chocolatey and pre-built libraries..."
|
||||||
|
|
||||||
|
# Install Chocolatey if not present
|
||||||
|
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
|
||||||
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||||
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||||
|
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install basic dependencies
|
||||||
|
choco install -y cmake ninja
|
||||||
|
|
||||||
|
# Create a minimal build configuration
|
||||||
|
Write-Host "Creating minimal build configuration for CI..."
|
||||||
|
|
||||||
|
# Set up environment variables for minimal build
|
||||||
|
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
|
||||||
|
echo "CMAKE_PREFIX_PATH=$env:GITHUB_WORKSPACE\vcpkg_installed\${{ inputs.platform }}-windows" >> $env:GITHUB_ENV
|
||||||
|
|
||||||
|
- name: Configure CMake
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
if exist "${{ github.workspace }}\vcpkg_installed" (
|
||||||
|
echo "Using vcpkg installation..."
|
||||||
|
cmake -B build ^
|
||||||
|
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 ^
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" ^
|
||||||
|
-DYAZE_BUILD_TESTS=OFF ^
|
||||||
|
-DYAZE_BUILD_EMU=OFF ^
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF ^
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF ^
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF ^
|
||||||
|
-DYAZE_INSTALL_LIB=OFF ^
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON ^
|
||||||
|
-G "Visual Studio 17 2022" ^
|
||||||
|
-A %PLATFORM%
|
||||||
|
) else (
|
||||||
|
echo "Using minimal build configuration..."
|
||||||
|
cmake -B build ^
|
||||||
|
-DCMAKE_BUILD_TYPE=%BUILD_TYPE% ^
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 ^
|
||||||
|
-DYAZE_BUILD_TESTS=OFF ^
|
||||||
|
-DYAZE_BUILD_EMU=OFF ^
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF ^
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF ^
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF ^
|
||||||
|
-DYAZE_INSTALL_LIB=OFF ^
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON ^
|
||||||
|
-G "Visual Studio 17 2022" ^
|
||||||
|
-A %PLATFORM%
|
||||||
|
)
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build build --config %BUILD_TYPE% --parallel
|
||||||
|
|
||||||
|
- name: Test executable
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$exePath = "build\bin\$env:BUILD_TYPE\yaze.exe"
|
||||||
|
if (Test-Path $exePath) {
|
||||||
|
Write-Host "✓ Executable created: $exePath" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
$testResult = & $exePath --help 2>&1
|
||||||
|
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
|
||||||
|
Write-Error "Executable is running test main instead of app main!"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable runs correctly" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Error "Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: yaze-${{ inputs.platform }}-${{ inputs.build_type }}-fallback
|
||||||
|
path: |
|
||||||
|
build/bin/${{ inputs.build_type }}/
|
||||||
|
retention-days: 7
|
||||||
428
.github/workflows/ci.yml
vendored
Normal file
428
.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,428 @@
|
|||||||
|
name: CI/CD Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master", "develop" ]
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- 'test/**'
|
||||||
|
- 'cmake/**'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- '.github/workflows/**'
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master", "develop" ]
|
||||||
|
paths:
|
||||||
|
- 'src/**'
|
||||||
|
- 'test/**'
|
||||||
|
- 'cmake/**'
|
||||||
|
- 'CMakeLists.txt'
|
||||||
|
- '.github/workflows/**'
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||||
|
BUILD_TYPE: RelWithDebInfo
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-test:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Ubuntu 22.04 (GCC-12)"
|
||||||
|
os: ubuntu-22.04
|
||||||
|
cc: gcc-12
|
||||||
|
cxx: g++-12
|
||||||
|
vcpkg_triplet: x64-linux
|
||||||
|
|
||||||
|
- name: "Ubuntu 22.04 (Clang)"
|
||||||
|
os: ubuntu-22.04
|
||||||
|
cc: clang-15
|
||||||
|
cxx: clang++-15
|
||||||
|
vcpkg_triplet: x64-linux
|
||||||
|
|
||||||
|
- name: "macOS 13 (Clang)"
|
||||||
|
os: macos-13
|
||||||
|
cc: clang
|
||||||
|
cxx: clang++
|
||||||
|
vcpkg_triplet: x64-osx
|
||||||
|
|
||||||
|
- name: "macOS 14 (Clang)"
|
||||||
|
os: macos-14
|
||||||
|
cc: clang
|
||||||
|
cxx: clang++
|
||||||
|
vcpkg_triplet: arm64-osx
|
||||||
|
|
||||||
|
- name: "Windows 2022 (MSVC x64)"
|
||||||
|
os: windows-2022
|
||||||
|
cc: cl
|
||||||
|
cxx: cl
|
||||||
|
vcpkg_triplet: x64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: x64
|
||||||
|
|
||||||
|
- name: "Windows 2022 (MSVC x86)"
|
||||||
|
os: windows-2022
|
||||||
|
cc: cl
|
||||||
|
cxx: cl
|
||||||
|
vcpkg_triplet: x86-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: Win32
|
||||||
|
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Export GitHub Actions cache environment variables
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || '');
|
||||||
|
core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || '');
|
||||||
|
|
||||||
|
- name: Set up vcpkg cache
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ github.workspace }}/vcpkg
|
||||||
|
${{ github.workspace }}/vcpkg_installed
|
||||||
|
key: vcpkg-${{ matrix.vcpkg_triplet }}-${{ hashFiles('vcpkg.json') }}
|
||||||
|
restore-keys: |
|
||||||
|
vcpkg-${{ matrix.vcpkg_triplet }}-
|
||||||
|
|
||||||
|
# Linux-specific setup
|
||||||
|
- name: Install Linux dependencies
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libabsl-dev \
|
||||||
|
libboost-all-dev \
|
||||||
|
libboost-python-dev \
|
||||||
|
libpng-dev \
|
||||||
|
python3-dev \
|
||||||
|
libpython3-dev \
|
||||||
|
libasound2-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libaudio-dev \
|
||||||
|
libx11-dev \
|
||||||
|
libxrandr-dev \
|
||||||
|
libxcursor-dev \
|
||||||
|
libxinerama-dev \
|
||||||
|
libxi-dev \
|
||||||
|
libxss-dev \
|
||||||
|
libxxf86vm-dev \
|
||||||
|
libxkbcommon-dev \
|
||||||
|
libwayland-dev \
|
||||||
|
libdecor-0-dev \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libdbus-1-dev \
|
||||||
|
gcc-12 \
|
||||||
|
g++-12 \
|
||||||
|
clang-15
|
||||||
|
|
||||||
|
- name: Set up Linux compilers
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/${{ matrix.cc }} 100
|
||||||
|
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/${{ matrix.cxx }} 100
|
||||||
|
|
||||||
|
# macOS-specific setup
|
||||||
|
- name: Install macOS dependencies
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
# Install Homebrew dependencies if needed
|
||||||
|
# brew install pkg-config libpng boost abseil
|
||||||
|
|
||||||
|
# Windows-specific setup (skip vcpkg for CI builds)
|
||||||
|
- name: Set up vcpkg (non-CI builds only)
|
||||||
|
if: runner.os == 'Windows' && github.event_name != 'push' && github.event_name != 'pull_request'
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
- name: Configure CMake (Linux/macOS)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
cmake -B ${{ github.workspace }}/build \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
|
-DCMAKE_C_COMPILER=${{ matrix.cc }} \
|
||||||
|
-DCMAKE_CXX_COMPILER=${{ matrix.cxx }} \
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_UI_TESTS=OFF \
|
||||||
|
-Wno-dev \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
- name: Configure CMake (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: cmd
|
||||||
|
run: |
|
||||||
|
cmake -B ${{ github.workspace }}/build -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} -DCMAKE_POLICY_VERSION_MINIMUM=3.16 -DYAZE_MINIMAL_BUILD=ON -DYAZE_ENABLE_ROM_TESTS=OFF -DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF -DYAZE_ENABLE_UI_TESTS=OFF -Wno-dev -G "${{ matrix.cmake_generator }}" -A ${{ matrix.cmake_generator_platform }}
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --parallel
|
||||||
|
|
||||||
|
# Test (stable core functionality only for CI)
|
||||||
|
- name: Run Core Tests
|
||||||
|
working-directory: ${{ github.workspace }}/build
|
||||||
|
run: ctest --build-config ${{ env.BUILD_TYPE }} --output-on-failure -j1 -R "AsarWrapperTest|SnesTileTest|CompressionTest|SnesPaletteTest|HexTest"
|
||||||
|
|
||||||
|
# Run experimental tests separately (allowed to fail for information only)
|
||||||
|
- name: Run Additional Tests (Informational)
|
||||||
|
working-directory: ${{ github.workspace }}/build
|
||||||
|
continue-on-error: true
|
||||||
|
run: ctest --build-config ${{ env.BUILD_TYPE }} --output-on-failure --parallel -E "AsarWrapperTest|SnesTileTest|CompressionTest|SnesPaletteTest|HexTest|CpuTest|Spc700Test|ApuTest|MessageTest|.*IntegrationTest"
|
||||||
|
|
||||||
|
# Package (only on successful builds)
|
||||||
|
- name: Package artifacts
|
||||||
|
if: success()
|
||||||
|
run: |
|
||||||
|
cmake --build ${{ github.workspace }}/build --config ${{ env.BUILD_TYPE }} --target package
|
||||||
|
|
||||||
|
# Upload artifacts
|
||||||
|
- name: Upload build artifacts
|
||||||
|
if: success()
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: yaze-${{ matrix.name }}-${{ github.sha }}
|
||||||
|
path: |
|
||||||
|
${{ github.workspace }}/build/bin/
|
||||||
|
${{ github.workspace }}/build/lib/
|
||||||
|
retention-days: 7
|
||||||
|
|
||||||
|
# Upload packages for release candidates
|
||||||
|
- name: Upload package artifacts
|
||||||
|
if: success() && (github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/'))
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
with:
|
||||||
|
name: yaze-package-${{ matrix.name }}-${{ github.sha }}
|
||||||
|
path: |
|
||||||
|
${{ github.workspace }}/build/*.tar.gz
|
||||||
|
${{ github.workspace }}/build/*.zip
|
||||||
|
${{ github.workspace }}/build/*.dmg
|
||||||
|
${{ github.workspace }}/build/*.msi
|
||||||
|
retention-days: 30
|
||||||
|
|
||||||
|
code-quality:
|
||||||
|
name: Code Quality Checks
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
# Relaxed requirements for releases and master branch:
|
||||||
|
# - Formatting errors become warnings
|
||||||
|
# - Fewer cppcheck categories enabled
|
||||||
|
# - Reduced clang-tidy file count
|
||||||
|
# - Job failure won't block releases
|
||||||
|
continue-on-error: ${{ github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/') }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
clang-format-14 \
|
||||||
|
clang-tidy-14 \
|
||||||
|
cppcheck
|
||||||
|
|
||||||
|
- name: Check code formatting
|
||||||
|
run: |
|
||||||
|
# Relaxed formatting check for releases and master branch
|
||||||
|
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]] || [[ "${{ github.event_name }}" == "pull_request" && "${{ github.base_ref }}" == "master" ]]; then
|
||||||
|
echo "🔄 Running relaxed formatting check for release/master branch..."
|
||||||
|
find src test -name "*.cc" -o -name "*.h" | \
|
||||||
|
xargs clang-format-14 --dry-run --Werror || {
|
||||||
|
echo "⚠️ Code formatting issues found, but allowing for release builds"
|
||||||
|
echo "📝 Consider running 'make format' to fix formatting before next release"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
else
|
||||||
|
echo "🔍 Running strict formatting check for development..."
|
||||||
|
find src test -name "*.cc" -o -name "*.h" | \
|
||||||
|
xargs clang-format-14 --dry-run --Werror
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Run cppcheck
|
||||||
|
run: |
|
||||||
|
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||||
|
echo "🔄 Running relaxed cppcheck for release/master branch..."
|
||||||
|
cppcheck --enable=warning \
|
||||||
|
--error-exitcode=0 \
|
||||||
|
--suppress=missingIncludeSystem \
|
||||||
|
--suppress=unusedFunction \
|
||||||
|
--suppress=unmatchedSuppression \
|
||||||
|
--suppress=variableScope \
|
||||||
|
--suppress=cstyleCast \
|
||||||
|
--suppress=unreadVariable \
|
||||||
|
--suppress=unusedStructMember \
|
||||||
|
--suppress=constParameter \
|
||||||
|
--suppress=constVariable \
|
||||||
|
--suppress=useStlAlgorithm \
|
||||||
|
--suppress=noExplicitConstructor \
|
||||||
|
--suppress=passedByValue \
|
||||||
|
--suppress=functionStatic \
|
||||||
|
src/ || echo "Cppcheck completed (non-blocking for releases)"
|
||||||
|
else
|
||||||
|
echo "🔍 Running standard cppcheck for development..."
|
||||||
|
cppcheck --enable=warning,style,performance \
|
||||||
|
--error-exitcode=0 \
|
||||||
|
--suppress=missingIncludeSystem \
|
||||||
|
--suppress=unusedFunction \
|
||||||
|
--suppress=unmatchedSuppression \
|
||||||
|
--suppress=variableScope \
|
||||||
|
--suppress=cstyleCast \
|
||||||
|
--suppress=unreadVariable \
|
||||||
|
--suppress=unusedStructMember \
|
||||||
|
--suppress=constParameter \
|
||||||
|
--suppress=constVariable \
|
||||||
|
--suppress=useStlAlgorithm \
|
||||||
|
--inconclusive \
|
||||||
|
src/ || echo "Cppcheck completed with warnings (non-blocking)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Run clang-tidy (lenient)
|
||||||
|
run: |
|
||||||
|
if [[ "${{ github.ref }}" == "refs/heads/master" ]] || [[ "${{ github.ref }}" == refs/tags/* ]]; then
|
||||||
|
echo "🔄 Running minimal clang-tidy for release/master branch..."
|
||||||
|
# Only check a small subset of critical files for releases
|
||||||
|
find src -name "*.cc" -not -path "*/lib/*" -not -path "*/gui/*" | head -10 | \
|
||||||
|
xargs clang-tidy-14 --config-file=.clang-tidy \
|
||||||
|
--header-filter='src/.*\.(h|hpp)$' || echo "Clang-tidy completed (non-blocking for releases)"
|
||||||
|
else
|
||||||
|
echo "🔍 Running standard clang-tidy for development..."
|
||||||
|
# Run clang-tidy on a subset of files to avoid overwhelming output
|
||||||
|
find src -name "*.cc" -not -path "*/lib/*" | head -20 | \
|
||||||
|
xargs clang-tidy-14 --config-file=.clang-tidy \
|
||||||
|
--header-filter='src/.*\.(h|hpp)$' || echo "Clang-tidy completed with warnings (non-blocking)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
memory-sanitizer:
|
||||||
|
name: Memory Sanitizer (Linux)
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
clang-14 \
|
||||||
|
libc++-14-dev \
|
||||||
|
libc++abi-14-dev \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libdbus-1-dev
|
||||||
|
|
||||||
|
- name: Configure with AddressSanitizer
|
||||||
|
run: |
|
||||||
|
cmake -B ${{ github.workspace }}/build \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DCMAKE_C_COMPILER=clang-14 \
|
||||||
|
-DCMAKE_CXX_COMPILER=clang++-14 \
|
||||||
|
-DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
|
||||||
|
-DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer" \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address" \
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{ github.workspace }}/build --parallel
|
||||||
|
|
||||||
|
- name: Test with AddressSanitizer
|
||||||
|
working-directory: ${{ github.workspace }}/build
|
||||||
|
env:
|
||||||
|
ASAN_OPTIONS: detect_leaks=1:abort_on_error=1
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
|
coverage:
|
||||||
|
name: Code Coverage
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
if: github.event_name == 'pull_request'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
gcov \
|
||||||
|
lcov \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libpng-dev \
|
||||||
|
libgtk-3-dev \
|
||||||
|
libdbus-1-dev
|
||||||
|
|
||||||
|
- name: Configure with coverage
|
||||||
|
run: |
|
||||||
|
cmake -B ${{ github.workspace }}/build \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug \
|
||||||
|
-DCMAKE_CXX_FLAGS="--coverage" \
|
||||||
|
-DCMAKE_C_FLAGS="--coverage" \
|
||||||
|
-DCMAKE_EXE_LINKER_FLAGS="--coverage" \
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: cmake --build ${{ github.workspace }}/build --parallel
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
working-directory: ${{ github.workspace }}/build
|
||||||
|
run: ctest --output-on-failure
|
||||||
|
|
||||||
|
- name: Generate coverage report
|
||||||
|
run: |
|
||||||
|
lcov --capture --directory ${{ github.workspace }}/build --output-file coverage.info
|
||||||
|
lcov --remove coverage.info '/usr/*' --output-file coverage.info
|
||||||
|
lcov --remove coverage.info '**/test/**' --output-file coverage.info
|
||||||
|
lcov --remove coverage.info '**/lib/**' --output-file coverage.info
|
||||||
|
|
||||||
|
- name: Upload coverage to Codecov
|
||||||
|
uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
file: ./coverage.info
|
||||||
|
flags: unittests
|
||||||
|
name: codecov-umbrella
|
||||||
|
fail_ci_if_error: false
|
||||||
41
.github/workflows/cmake.yml
vendored
41
.github/workflows/cmake.yml
vendored
@@ -1,41 +0,0 @@
|
|||||||
name: CMake
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "master" ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "master" ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
|
||||||
BUILD_TYPE: Debug
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
# The CMake configure and build commands are platform agnostic and should work equally well on Windows or Mac.
|
|
||||||
# You can convert this to a matrix build if you need cross-platform coverage.
|
|
||||||
# See: https://docs.github.com/en/free-pro-team@latest/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v3
|
|
||||||
with:
|
|
||||||
submodules: recursive
|
|
||||||
|
|
||||||
- name: Install Video Libs
|
|
||||||
run: sudo apt install libglew-dev
|
|
||||||
|
|
||||||
- name: Configure CMake
|
|
||||||
# Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make.
|
|
||||||
# See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type
|
|
||||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
# Build your program with the given configuration
|
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
|
||||||
|
|
||||||
- name: Test
|
|
||||||
working-directory: ${{github.workspace}}/build
|
|
||||||
# Execute tests defined by the CMake configuration.
|
|
||||||
# See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail
|
|
||||||
run: ${{github.workspace}}/build/bin/yaze_test
|
|
||||||
81
.github/workflows/doxy.yml
vendored
Normal file
81
.github/workflows/doxy.yml
vendored
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
name: Doxygen Documentation
|
||||||
|
|
||||||
|
# Only run when documentation-related files are modified
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ master ]
|
||||||
|
paths:
|
||||||
|
- 'src/**/*.h'
|
||||||
|
- 'src/**/*.cc'
|
||||||
|
- 'src/**/*.cpp'
|
||||||
|
- 'docs/**'
|
||||||
|
- 'Doxyfile'
|
||||||
|
- '.github/workflows/doxy.yml'
|
||||||
|
pull_request:
|
||||||
|
branches: [ master ]
|
||||||
|
paths:
|
||||||
|
- 'src/**/*.h'
|
||||||
|
- 'src/**/*.cc'
|
||||||
|
- 'src/**/*.cpp'
|
||||||
|
- 'docs/**'
|
||||||
|
- 'Doxyfile'
|
||||||
|
- '.github/workflows/doxy.yml'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||||
|
jobs:
|
||||||
|
generate-docs:
|
||||||
|
name: Generate Documentation
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y doxygen graphviz
|
||||||
|
|
||||||
|
- name: Check if documentation build is needed
|
||||||
|
id: changes
|
||||||
|
run: |
|
||||||
|
# Check if this is the first commit or if docs-related files changed
|
||||||
|
if git show --name-only HEAD | grep -E '\.(h|cc|cpp|md)$|Doxyfile'; then
|
||||||
|
echo "docs_changed=true" >> $GITHUB_OUTPUT
|
||||||
|
echo "📝 Documentation-related files have changed"
|
||||||
|
else
|
||||||
|
echo "docs_changed=false" >> $GITHUB_OUTPUT
|
||||||
|
echo "ℹ️ No documentation changes detected"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Clean previous build
|
||||||
|
if: steps.changes.outputs.docs_changed == 'true'
|
||||||
|
run: rm -rf html
|
||||||
|
|
||||||
|
- name: Generate Doxygen documentation
|
||||||
|
if: steps.changes.outputs.docs_changed == 'true'
|
||||||
|
uses: mattnotmitt/doxygen-action@v1.9.8
|
||||||
|
with:
|
||||||
|
doxyfile-path: "./Doxyfile"
|
||||||
|
working-directory: "."
|
||||||
|
|
||||||
|
- name: Deploy to GitHub Pages
|
||||||
|
if: steps.changes.outputs.docs_changed == 'true'
|
||||||
|
uses: peaceiris/actions-gh-pages@v3
|
||||||
|
with:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
publish_dir: ./html
|
||||||
|
commit_message: 'docs: update API documentation'
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
run: |
|
||||||
|
if [[ "${{ steps.changes.outputs.docs_changed }}" == "true" ]]; then
|
||||||
|
echo "✅ Documentation generated and deployed successfully"
|
||||||
|
echo "📖 View at: https://${{ github.repository_owner }}.github.io/${{ github.event.repository.name }}"
|
||||||
|
else
|
||||||
|
echo "⏭️ Documentation build skipped - no relevant changes detected"
|
||||||
|
fi
|
||||||
712
.github/workflows/release-complex.yml
vendored
Normal file
712
.github/workflows/release-complex.yml
vendored
Normal file
@@ -0,0 +1,712 @@
|
|||||||
|
name: Release-Complex
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+-*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Release tag (must start with v and follow semantic versioning)'
|
||||||
|
required: true
|
||||||
|
default: 'v0.3.0'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-and-prepare:
|
||||||
|
name: Validate Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
tag_name: ${{ steps.validate.outputs.tag_name }}
|
||||||
|
release_notes: ${{ steps.notes.outputs.content }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Validate tag format
|
||||||
|
id: validate
|
||||||
|
run: |
|
||||||
|
# Debug information
|
||||||
|
echo "Event name: ${{ github.event_name }}"
|
||||||
|
echo "Ref: ${{ github.ref }}"
|
||||||
|
echo "Ref name: ${{ github.ref_name }}"
|
||||||
|
echo "Ref type: ${{ github.ref_type }}"
|
||||||
|
|
||||||
|
# Determine the tag based on trigger type
|
||||||
|
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||||
|
if [[ "${{ github.ref_type }}" != "tag" ]]; then
|
||||||
|
echo "❌ Error: Release workflow triggered by push to ${{ github.ref_type }} '${{ github.ref_name }}'"
|
||||||
|
echo "This workflow should only be triggered by pushing version tags (v1.2.3)"
|
||||||
|
echo "Use: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TAG="${{ github.ref_name }}"
|
||||||
|
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||||
|
TAG="${{ github.event.inputs.tag }}"
|
||||||
|
if [[ -z "$TAG" ]]; then
|
||||||
|
echo "❌ Error: No tag specified for manual workflow dispatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Error: Unsupported event type: ${{ github.event_name }}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Validating tag: $TAG"
|
||||||
|
|
||||||
|
# Check if tag follows semantic versioning pattern
|
||||||
|
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
|
||||||
|
echo "❌ Error: Tag '$TAG' does not follow semantic versioning format (v1.2.3 or v1.2.3-beta)"
|
||||||
|
echo "Valid examples: v0.3.0, v1.0.0, v2.1.3-beta, v1.0.0-rc1"
|
||||||
|
echo ""
|
||||||
|
echo "To create a proper release:"
|
||||||
|
echo "1. Use the helper script: ./scripts/create_release.sh 0.3.0"
|
||||||
|
echo "2. Or manually: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Tag format is valid: $TAG"
|
||||||
|
echo "VALIDATED_TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
echo "tag_name=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate release notes
|
||||||
|
id: release_notes
|
||||||
|
run: |
|
||||||
|
# Extract release version from validated tag
|
||||||
|
VERSION="${VALIDATED_TAG}"
|
||||||
|
VERSION_NUM=$(echo "$VERSION" | sed 's/^v//')
|
||||||
|
|
||||||
|
# Generate release notes using the dedicated script
|
||||||
|
echo "Extracting changelog for version: $VERSION_NUM"
|
||||||
|
if python3 scripts/extract_changelog.py "$VERSION_NUM" > release_notes.md; then
|
||||||
|
echo "Changelog extracted successfully"
|
||||||
|
echo "Release notes content:"
|
||||||
|
cat release_notes.md
|
||||||
|
else
|
||||||
|
echo "Failed to extract changelog, creating default release notes"
|
||||||
|
echo "# Yaze $VERSION Release Notes\n\nPlease see the full changelog at docs/C1-changelog.md" > release_notes.md
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Store release notes
|
||||||
|
id: notes
|
||||||
|
run: |
|
||||||
|
# Store release notes content for later use
|
||||||
|
echo "content<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
cat release_notes.md >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
build-release:
|
||||||
|
name: Build Release
|
||||||
|
needs: validate-and-prepare
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Windows x64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: x64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: x64
|
||||||
|
artifact_name: "yaze-windows-x64"
|
||||||
|
artifact_path: "build/bin/Release/"
|
||||||
|
package_cmd: |
|
||||||
|
mkdir -p package
|
||||||
|
cp -r build/bin/Release/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
|
||||||
|
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cd package && zip -r ../yaze-windows-x64.zip *
|
||||||
|
|
||||||
|
- name: "Windows ARM64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: arm64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: ARM64
|
||||||
|
artifact_name: "yaze-windows-arm64"
|
||||||
|
artifact_path: "build/bin/Release/"
|
||||||
|
package_cmd: |
|
||||||
|
mkdir -p package
|
||||||
|
cp -r build/bin/Release/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
|
||||||
|
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cd package && zip -r ../yaze-windows-arm64.zip *
|
||||||
|
|
||||||
|
- name: "macOS Universal"
|
||||||
|
os: macos-14
|
||||||
|
vcpkg_triplet: arm64-osx
|
||||||
|
artifact_name: "yaze-macos"
|
||||||
|
artifact_path: "build/bin/"
|
||||||
|
package_cmd: |
|
||||||
|
# Debug: List what was actually built
|
||||||
|
echo "Contents of build/bin/:"
|
||||||
|
ls -la build/bin/ || echo "build/bin/ does not exist"
|
||||||
|
|
||||||
|
# Check if we have a bundle or standalone executable
|
||||||
|
if [ -d "build/bin/yaze.app" ]; then
|
||||||
|
echo "Found macOS bundle, using it directly"
|
||||||
|
# Use the existing bundle and just update it
|
||||||
|
cp -r build/bin/yaze.app ./Yaze.app
|
||||||
|
# Add additional resources to the bundle
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Update Info.plist with correct version
|
||||||
|
if [ -f "cmake/yaze.plist.in" ]; then
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No bundle found, creating manual bundle"
|
||||||
|
# Create bundle structure manually
|
||||||
|
mkdir -p "Yaze.app/Contents/MacOS"
|
||||||
|
mkdir -p "Yaze.app/Contents/Resources"
|
||||||
|
cp build/bin/yaze "Yaze.app/Contents/MacOS/"
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Create Info.plist with correct version
|
||||||
|
if [ -f "cmake/yaze.plist.in" ]; then
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
|
||||||
|
else
|
||||||
|
# Create a basic Info.plist
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>' > "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<plist version="1.0">' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<dict>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleExecutable</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>yaze</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleIdentifier</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>com.yaze.editor</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleName</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>Yaze</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleVersion</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleShortVersionString</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundlePackageType</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>APPL</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '</dict>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '</plist>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create DMG
|
||||||
|
mkdir dmg_staging
|
||||||
|
cp -r Yaze.app dmg_staging/
|
||||||
|
cp LICENSE dmg_staging/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md dmg_staging/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cp -r docs dmg_staging/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
hdiutil create -srcfolder dmg_staging -format UDZO -volname "Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}" yaze-macos.dmg
|
||||||
|
|
||||||
|
- name: "Linux x64"
|
||||||
|
os: ubuntu-22.04
|
||||||
|
artifact_name: "yaze-linux-x64"
|
||||||
|
artifact_path: "build/bin/"
|
||||||
|
package_cmd: |
|
||||||
|
mkdir package
|
||||||
|
cp build/bin/yaze package/
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp -r docs package/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
tar -czf yaze-linux-x64.tar.gz -C package .
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# Clean up any potential vcpkg issues (Windows only)
|
||||||
|
- name: Clean vcpkg state (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Cleaning up any existing vcpkg state..."
|
||||||
|
if (Test-Path "vcpkg") {
|
||||||
|
Remove-Item -Recurse -Force "vcpkg" -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
if (Test-Path "vcpkg_installed") {
|
||||||
|
Remove-Item -Recurse -Force "vcpkg_installed" -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
Write-Host "Cleanup completed"
|
||||||
|
|
||||||
|
# Platform-specific dependency installation
|
||||||
|
- name: Install Linux dependencies
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libabsl-dev \
|
||||||
|
libboost-all-dev \
|
||||||
|
libpng-dev \
|
||||||
|
python3-dev \
|
||||||
|
libpython3-dev \
|
||||||
|
libasound2-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libx11-dev \
|
||||||
|
libxrandr-dev \
|
||||||
|
libxcursor-dev \
|
||||||
|
libxinerama-dev \
|
||||||
|
libxi-dev
|
||||||
|
|
||||||
|
- name: Install macOS dependencies
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
# Install Homebrew dependencies needed for UI tests and full builds
|
||||||
|
brew install pkg-config libpng boost abseil ninja gtk+3
|
||||||
|
|
||||||
|
- name: Setup build environment
|
||||||
|
run: |
|
||||||
|
echo "Using streamlined release build configuration for all platforms"
|
||||||
|
echo "Linux/macOS: UI tests enabled with full dependency support"
|
||||||
|
echo "Windows: Full build with vcpkg integration for proper releases"
|
||||||
|
echo "All platforms: Emulator and developer tools disabled for clean releases"
|
||||||
|
|
||||||
|
# Configure CMake
|
||||||
|
- name: Configure CMake (Linux/macOS)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
cmake -B build \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
|
||||||
|
-DYAZE_BUILD_TESTS=OFF \
|
||||||
|
-DYAZE_BUILD_EMU=OFF \
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF \
|
||||||
|
-DYAZE_ENABLE_UI_TESTS=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-DYAZE_INSTALL_LIB=OFF \
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
# Set up vcpkg for Windows builds with fallback
|
||||||
|
- name: Set up vcpkg (Windows)
|
||||||
|
id: vcpkg_setup
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
VCPKG_DISABLE_METRICS: 1
|
||||||
|
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
|
||||||
|
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||||
|
|
||||||
|
# Debug vcpkg failure (Windows only)
|
||||||
|
- name: Debug vcpkg failure (Windows)
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "=== vcpkg Setup Failed - Debug Information ===" -ForegroundColor Red
|
||||||
|
Write-Host "vcpkg directory exists: $(Test-Path 'vcpkg')"
|
||||||
|
Write-Host "vcpkg_installed directory exists: $(Test-Path 'vcpkg_installed')"
|
||||||
|
if (Test-Path "vcpkg") {
|
||||||
|
Write-Host "vcpkg directory contents:"
|
||||||
|
Get-ChildItem "vcpkg" | Select-Object -First 10
|
||||||
|
}
|
||||||
|
Write-Host "Git status:"
|
||||||
|
git status --porcelain
|
||||||
|
Write-Host "=============================================" -ForegroundColor Red
|
||||||
|
|
||||||
|
# Fallback: Install dependencies manually if vcpkg fails
|
||||||
|
- name: Install dependencies manually (Windows fallback)
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "vcpkg setup failed, installing dependencies manually..."
|
||||||
|
|
||||||
|
# Install Chocolatey if not present
|
||||||
|
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
|
||||||
|
Write-Host "Installing Chocolatey..."
|
||||||
|
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||||
|
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||||
|
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install basic build tools and dependencies
|
||||||
|
Write-Host "Installing build tools and dependencies..."
|
||||||
|
try {
|
||||||
|
choco install -y cmake ninja git python3
|
||||||
|
Write-Host "Successfully installed build tools via Chocolatey"
|
||||||
|
} catch {
|
||||||
|
Write-Host "Chocolatey installation failed, trying individual packages..."
|
||||||
|
choco install -y cmake || Write-Host "CMake installation failed"
|
||||||
|
choco install -y ninja || Write-Host "Ninja installation failed"
|
||||||
|
choco install -y git || Write-Host "Git installation failed"
|
||||||
|
choco install -y python3 || Write-Host "Python3 installation failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up basic development environment
|
||||||
|
Write-Host "Setting up basic development environment..."
|
||||||
|
$env:Path += ";C:\Program Files\Git\bin"
|
||||||
|
|
||||||
|
# Verify installations
|
||||||
|
Write-Host "Verifying installations..."
|
||||||
|
cmake --version
|
||||||
|
ninja --version
|
||||||
|
git --version
|
||||||
|
|
||||||
|
# Set environment variable to indicate minimal build
|
||||||
|
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
|
||||||
|
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
|
||||||
|
|
||||||
|
Write-Host "Manual dependency installation completed"
|
||||||
|
Write-Host "Build will proceed with minimal configuration (no vcpkg dependencies)"
|
||||||
|
|
||||||
|
# Set vcpkg availability flag when vcpkg succeeds
|
||||||
|
- name: Set vcpkg availability flag
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'success'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
|
||||||
|
Write-Host "vcpkg setup successful"
|
||||||
|
|
||||||
|
- name: Configure CMake (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Configuring CMake for Windows build..."
|
||||||
|
|
||||||
|
# Check if vcpkg is available
|
||||||
|
if ((Test-Path "${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake") -and ($env:VCPKG_AVAILABLE -ne "false")) {
|
||||||
|
Write-Host "Using vcpkg toolchain..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
} else {
|
||||||
|
Write-Host "Using minimal build configuration (vcpkg not available)..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "CMake configuration completed successfully"
|
||||||
|
|
||||||
|
# Verify CMake configuration (Windows only)
|
||||||
|
- name: Verify CMake configuration (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Verifying CMake configuration..."
|
||||||
|
if (Test-Path "build/CMakeCache.txt") {
|
||||||
|
Write-Host "✓ CMakeCache.txt found"
|
||||||
|
Write-Host "Build type: $(Select-String -Path 'build/CMakeCache.txt' -Pattern 'CMAKE_BUILD_TYPE' | ForEach-Object { $_.Line.Split('=')[1] })"
|
||||||
|
Write-Host "Minimal build: $(Select-String -Path 'build/CMakeCache.txt' -Pattern 'YAZE_MINIMAL_BUILD' | ForEach-Object { $_.Line.Split('=')[1] })"
|
||||||
|
} else {
|
||||||
|
Write-Error "CMakeCache.txt not found - CMake configuration failed!"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
echo "Building YAZE for ${{ matrix.name }}..."
|
||||||
|
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
|
||||||
|
echo "Build completed successfully!"
|
||||||
|
|
||||||
|
# Validate Visual Studio project builds (Windows only)
|
||||||
|
# Generate yaze_config.h for Visual Studio builds
|
||||||
|
- name: Generate yaze_config.h
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$version = "${{ needs.validate-and-prepare.outputs.tag_name }}" -replace '^v', ''
|
||||||
|
$versionParts = $version -split '\.'
|
||||||
|
$major = if ($versionParts.Length -gt 0) { $versionParts[0] } else { "0" }
|
||||||
|
$minor = if ($versionParts.Length -gt 1) { $versionParts[1] } else { "0" }
|
||||||
|
$patch = if ($versionParts.Length -gt 2) { $versionParts[2] -split '-' | Select-Object -First 1 } else { "0" }
|
||||||
|
|
||||||
|
Write-Host "Generating yaze_config.h with version: $major.$minor.$patch"
|
||||||
|
Copy-Item "src\yaze_config.h.in" "yaze_config.h"
|
||||||
|
(Get-Content 'yaze_config.h') -replace '@yaze_VERSION_MAJOR@', $major -replace '@yaze_VERSION_MINOR@', $minor -replace '@yaze_VERSION_PATCH@', $patch | Set-Content 'yaze_config.h'
|
||||||
|
Write-Host "Generated yaze_config.h:"
|
||||||
|
Get-Content 'yaze_config.h'
|
||||||
|
|
||||||
|
- name: Validate Visual Studio Project Build
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "Validating Visual Studio Project Build" -ForegroundColor Cyan
|
||||||
|
Write-Host "Platform: ${{ matrix.cmake_generator_platform }}" -ForegroundColor Yellow
|
||||||
|
Write-Host "Configuration: ${{ env.BUILD_TYPE }}" -ForegroundColor Yellow
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if (-not (Test-Path "yaze.sln")) {
|
||||||
|
Write-Error "yaze.sln not found. Please run this script from the project root directory."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ yaze.sln found" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Build using MSBuild
|
||||||
|
Write-Host "Building with MSBuild..." -ForegroundColor Yellow
|
||||||
|
$msbuildArgs = @(
|
||||||
|
"yaze.sln"
|
||||||
|
"/p:Configuration=${{ env.BUILD_TYPE }}"
|
||||||
|
"/p:Platform=${{ matrix.cmake_generator_platform }}"
|
||||||
|
"/p:VcpkgEnabled=true"
|
||||||
|
"/p:VcpkgManifestInstall=true"
|
||||||
|
"/m" # Multi-processor build
|
||||||
|
"/verbosity:minimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "MSBuild command: msbuild $($msbuildArgs -join ' ')" -ForegroundColor Gray
|
||||||
|
& msbuild @msbuildArgs
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "MSBuild failed with exit code $LASTEXITCODE"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Visual Studio build completed successfully" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Verify executable was created
|
||||||
|
$exePath = "build\bin\${{ env.BUILD_TYPE }}\yaze.exe"
|
||||||
|
if (-not (Test-Path $exePath)) {
|
||||||
|
Write-Error "Executable not found at expected path: $exePath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable created: $exePath" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Test that the executable runs (basic test)
|
||||||
|
Write-Host "Testing executable startup..." -ForegroundColor Yellow
|
||||||
|
$testResult = & $exePath --help 2>&1
|
||||||
|
$exitCode = $LASTEXITCODE
|
||||||
|
|
||||||
|
# Check if it's the test main or app main
|
||||||
|
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
|
||||||
|
Write-Error "Executable is running test main instead of app main!"
|
||||||
|
Write-Host "Output: $testResult" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable runs correctly (exit code: $exitCode)" -ForegroundColor Green
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "✓ Visual Studio build validation PASSED" -ForegroundColor Green
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Test executable functionality (Windows)
|
||||||
|
- name: Test executable functionality (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
# Debug: List build directory contents
|
||||||
|
Write-Host "Build directory contents:" -ForegroundColor Cyan
|
||||||
|
if (Test-Path "build") {
|
||||||
|
Get-ChildItem -Recurse build -Name | Select-Object -First 20
|
||||||
|
} else {
|
||||||
|
Write-Host "build directory does not exist" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine executable path for Windows
|
||||||
|
$exePath = "build\bin\${{ env.BUILD_TYPE }}\yaze.exe"
|
||||||
|
|
||||||
|
if (Test-Path $exePath) {
|
||||||
|
Write-Host "✓ Executable found: $exePath" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
$testResult = & $exePath --help 2>&1
|
||||||
|
$exitCode = $LASTEXITCODE
|
||||||
|
|
||||||
|
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
|
||||||
|
Write-Error "Executable is running test main instead of app main!"
|
||||||
|
Write-Host "Output: $testResult" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable runs correctly (exit code: $exitCode)" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
$exeInfo = Get-Item $exePath
|
||||||
|
Write-Host "Executable size: $([math]::Round($exeInfo.Length / 1MB, 2)) MB" -ForegroundColor Cyan
|
||||||
|
} else {
|
||||||
|
Write-Error "Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Test executable functionality (macOS)
|
||||||
|
- name: Test executable functionality (macOS)
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Build directory contents:"
|
||||||
|
if [ -d "build" ]; then
|
||||||
|
find build -name "*.app" -o -name "yaze" | head -10
|
||||||
|
else
|
||||||
|
echo "build directory does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine executable path for macOS
|
||||||
|
exePath="build/bin/yaze.app/Contents/MacOS/yaze"
|
||||||
|
|
||||||
|
if [ -f "$exePath" ]; then
|
||||||
|
echo "✓ Executable found: $exePath"
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
testResult=$($exePath --help 2>&1 || true)
|
||||||
|
exitCode=$?
|
||||||
|
|
||||||
|
if echo "$testResult" | grep -q "Google Test\|gtest"; then
|
||||||
|
echo "ERROR: Executable is running test main instead of app main!"
|
||||||
|
echo "Output: $testResult"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Executable runs correctly (exit code: $exitCode)"
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
fileSize=$(stat -f%z "$exePath")
|
||||||
|
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l)
|
||||||
|
echo "Executable size: ${fileSizeMB} MB"
|
||||||
|
else
|
||||||
|
echo "ERROR: Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test executable functionality (Linux)
|
||||||
|
- name: Test executable functionality (Linux)
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Build directory contents:"
|
||||||
|
if [ -d "build" ]; then
|
||||||
|
find build -type f -name "yaze" | head -10
|
||||||
|
else
|
||||||
|
echo "build directory does not exist"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Determine executable path for Linux
|
||||||
|
exePath="build/bin/yaze"
|
||||||
|
|
||||||
|
if [ -f "$exePath" ]; then
|
||||||
|
echo "✓ Executable found: $exePath"
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
testResult=$($exePath --help 2>&1 || true)
|
||||||
|
exitCode=$?
|
||||||
|
|
||||||
|
if echo "$testResult" | grep -q "Google Test\|gtest"; then
|
||||||
|
echo "ERROR: Executable is running test main instead of app main!"
|
||||||
|
echo "Output: $testResult"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Executable runs correctly (exit code: $exitCode)"
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
fileSize=$(stat -c%s "$exePath")
|
||||||
|
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l)
|
||||||
|
echo "Executable size: ${fileSizeMB} MB"
|
||||||
|
else
|
||||||
|
echo "ERROR: Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verify build artifacts
|
||||||
|
- name: Verify build artifacts
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
echo "Verifying build artifacts for ${{ matrix.name }}..."
|
||||||
|
if [ -d "build/bin" ]; then
|
||||||
|
echo "Build directory contents:"
|
||||||
|
find build/bin -type f -name "yaze*" -o -name "*.exe" -o -name "*.app" | head -10
|
||||||
|
else
|
||||||
|
echo "ERROR: build/bin directory not found!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Package
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "Packaging for ${{ matrix.name }}..."
|
||||||
|
${{ matrix.package_cmd }}
|
||||||
|
echo "Packaging completed successfully!"
|
||||||
|
|
||||||
|
# Create release with artifacts (will create release if it doesn't exist)
|
||||||
|
- name: Upload to Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
name: Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
|
||||||
|
draft: false
|
||||||
|
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
|
||||||
|
files: |
|
||||||
|
${{ matrix.artifact_name }}.*
|
||||||
|
fail_on_unmatched_files: false
|
||||||
|
|
||||||
|
publish-packages:
|
||||||
|
name: Publish Packages
|
||||||
|
needs: [validate-and-prepare, build-release]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: success()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Update release status
|
||||||
|
run: |
|
||||||
|
echo "Release has been published successfully"
|
||||||
|
echo "All build artifacts have been uploaded"
|
||||||
|
|
||||||
|
- name: Announce release
|
||||||
|
run: |
|
||||||
|
echo "🎉 Yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
|
||||||
|
echo "📦 Packages are now available for download"
|
||||||
|
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"
|
||||||
414
.github/workflows/release-simplified.yml
vendored
Normal file
414
.github/workflows/release-simplified.yml
vendored
Normal file
@@ -0,0 +1,414 @@
|
|||||||
|
name: Release-Simplified
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+-*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Release tag (must start with v and follow semantic versioning)'
|
||||||
|
required: true
|
||||||
|
default: 'v0.3.0'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-and-prepare:
|
||||||
|
name: Validate Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
tag_name: ${{ steps.validate.outputs.tag_name }}
|
||||||
|
release_notes: ${{ steps.notes.outputs.content }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Validate tag format
|
||||||
|
id: validate
|
||||||
|
run: |
|
||||||
|
# Determine the tag based on trigger type
|
||||||
|
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||||
|
if [[ "${{ github.ref_type }}" != "tag" ]]; then
|
||||||
|
echo "❌ Error: Release workflow triggered by push to ${{ github.ref_type }} '${{ github.ref_name }}'"
|
||||||
|
echo "This workflow should only be triggered by pushing version tags (v1.2.3)"
|
||||||
|
echo "Use: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TAG="${{ github.ref_name }}"
|
||||||
|
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||||
|
TAG="${{ github.event.inputs.tag }}"
|
||||||
|
if [[ -z "$TAG" ]]; then
|
||||||
|
echo "❌ Error: No tag specified for manual workflow dispatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Error: Unsupported event type: ${{ github.event_name }}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Validating tag: $TAG"
|
||||||
|
|
||||||
|
# Check if tag follows semantic versioning pattern
|
||||||
|
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
|
||||||
|
echo "❌ Error: Tag '$TAG' does not follow semantic versioning format (v1.2.3 or v1.2.3-beta)"
|
||||||
|
echo "Valid examples: v0.3.0, v1.0.0, v2.1.3-beta, v1.0.0-rc1"
|
||||||
|
echo ""
|
||||||
|
echo "To create a proper release:"
|
||||||
|
echo "1. Use the helper script: ./scripts/create_release.sh 0.3.0"
|
||||||
|
echo "2. Or manually: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Tag format is valid: $TAG"
|
||||||
|
echo "VALIDATED_TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
echo "tag_name=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate release notes
|
||||||
|
id: release_notes
|
||||||
|
run: |
|
||||||
|
# Extract release version from validated tag
|
||||||
|
VERSION="${VALIDATED_TAG}"
|
||||||
|
VERSION_NUM=$(echo "$VERSION" | sed 's/^v//')
|
||||||
|
|
||||||
|
# Generate release notes using the dedicated script
|
||||||
|
echo "Extracting changelog for version: $VERSION_NUM"
|
||||||
|
if python3 scripts/extract_changelog.py "$VERSION_NUM" > release_notes.md; then
|
||||||
|
echo "Changelog extracted successfully"
|
||||||
|
echo "Release notes content:"
|
||||||
|
cat release_notes.md
|
||||||
|
else
|
||||||
|
echo "Failed to extract changelog, creating default release notes"
|
||||||
|
echo "# Yaze $VERSION Release Notes\n\nPlease see the full changelog at docs/C1-changelog.md" > release_notes.md
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Store release notes
|
||||||
|
id: notes
|
||||||
|
run: |
|
||||||
|
# Store release notes content for later use
|
||||||
|
echo "content<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
cat release_notes.md >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
build-release:
|
||||||
|
name: Build Release
|
||||||
|
needs: validate-and-prepare
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Windows x64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: x64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: x64
|
||||||
|
artifact_name: "yaze-windows-x64"
|
||||||
|
|
||||||
|
- name: "Windows ARM64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: arm64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: ARM64
|
||||||
|
artifact_name: "yaze-windows-arm64"
|
||||||
|
|
||||||
|
- name: "macOS Universal"
|
||||||
|
os: macos-14
|
||||||
|
vcpkg_triplet: arm64-osx
|
||||||
|
artifact_name: "yaze-macos"
|
||||||
|
|
||||||
|
- name: "Linux x64"
|
||||||
|
os: ubuntu-22.04
|
||||||
|
artifact_name: "yaze-linux-x64"
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# Platform-specific dependency installation
|
||||||
|
- name: Install Linux dependencies
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libabsl-dev \
|
||||||
|
libboost-all-dev \
|
||||||
|
libpng-dev \
|
||||||
|
python3-dev \
|
||||||
|
libpython3-dev \
|
||||||
|
libasound2-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libx11-dev \
|
||||||
|
libxrandr-dev \
|
||||||
|
libxcursor-dev \
|
||||||
|
libxinerama-dev \
|
||||||
|
libxi-dev
|
||||||
|
|
||||||
|
- name: Install macOS dependencies
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
# Install Homebrew dependencies needed for UI tests and full builds
|
||||||
|
brew install pkg-config libpng boost abseil ninja gtk+3
|
||||||
|
|
||||||
|
# Set up vcpkg for Windows builds with fallback
|
||||||
|
- name: Set up vcpkg (Windows)
|
||||||
|
id: vcpkg_setup
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
VCPKG_DISABLE_METRICS: 1
|
||||||
|
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
|
||||||
|
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||||
|
|
||||||
|
# Set vcpkg availability flag when vcpkg succeeds
|
||||||
|
- name: Set vcpkg availability flag
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'success'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
|
||||||
|
Write-Host "vcpkg setup successful"
|
||||||
|
|
||||||
|
# Fallback: Set minimal build flag when vcpkg fails
|
||||||
|
- name: Set minimal build flag (Windows fallback)
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
|
||||||
|
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
|
||||||
|
Write-Host "vcpkg setup failed, using minimal build configuration"
|
||||||
|
|
||||||
|
# Configure CMake
|
||||||
|
- name: Configure CMake (Linux/macOS)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
cmake -B build \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
|
||||||
|
-DYAZE_BUILD_TESTS=OFF \
|
||||||
|
-DYAZE_BUILD_EMU=OFF \
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF \
|
||||||
|
-DYAZE_ENABLE_UI_TESTS=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-DYAZE_INSTALL_LIB=OFF \
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
- name: Configure CMake (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Configuring CMake for Windows build..."
|
||||||
|
|
||||||
|
# Check if vcpkg is available
|
||||||
|
if ((Test-Path "${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake") -and ($env:VCPKG_AVAILABLE -ne "false")) {
|
||||||
|
Write-Host "Using vcpkg toolchain..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
} else {
|
||||||
|
Write-Host "Using minimal build configuration (vcpkg not available)..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "CMake configuration completed successfully"
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
echo "Building YAZE for ${{ matrix.name }}..."
|
||||||
|
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
|
||||||
|
echo "Build completed successfully!"
|
||||||
|
|
||||||
|
# Test executable functionality
|
||||||
|
- name: Test executable functionality
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Testing executable for ${{ matrix.name }}..."
|
||||||
|
|
||||||
|
# Determine executable path based on platform
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
exePath="build/bin/${{ env.BUILD_TYPE }}/yaze.exe"
|
||||||
|
elif [[ "${{ runner.os }}" == "macOS" ]]; then
|
||||||
|
exePath="build/bin/yaze.app/Contents/MacOS/yaze"
|
||||||
|
else
|
||||||
|
exePath="build/bin/yaze"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$exePath" ]; then
|
||||||
|
echo "✓ Executable found: $exePath"
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
testResult=$($exePath --help 2>&1 || true)
|
||||||
|
exitCode=$?
|
||||||
|
|
||||||
|
if echo "$testResult" | grep -q "Google Test\|gtest"; then
|
||||||
|
echo "ERROR: Executable is running test main instead of app main!"
|
||||||
|
echo "Output: $testResult"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Executable runs correctly (exit code: $exitCode)"
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
fileSize=$(stat -c%s "$exePath" 2>/dev/null || echo "0")
|
||||||
|
else
|
||||||
|
fileSize=$(stat -f%z "$exePath" 2>/dev/null || stat -c%s "$exePath" 2>/dev/null || echo "0")
|
||||||
|
fi
|
||||||
|
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l 2>/dev/null || echo "0")
|
||||||
|
echo "Executable size: ${fileSizeMB} MB"
|
||||||
|
else
|
||||||
|
echo "ERROR: Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Package
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "Packaging for ${{ matrix.name }}..."
|
||||||
|
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
# Windows packaging
|
||||||
|
mkdir -p package
|
||||||
|
cp -r build/bin/${{ env.BUILD_TYPE }}/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
|
||||||
|
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cd package && zip -r ../${{ matrix.artifact_name }}.zip *
|
||||||
|
|
||||||
|
elif [[ "${{ runner.os }}" == "macOS" ]]; then
|
||||||
|
# macOS packaging
|
||||||
|
if [ -d "build/bin/yaze.app" ]; then
|
||||||
|
echo "Found macOS bundle, using it directly"
|
||||||
|
cp -r build/bin/yaze.app ./Yaze.app
|
||||||
|
# Add additional resources to the bundle
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Update Info.plist with correct version
|
||||||
|
if [ -f "cmake/yaze.plist.in" ]; then
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No bundle found, creating manual bundle"
|
||||||
|
mkdir -p "Yaze.app/Contents/MacOS"
|
||||||
|
mkdir -p "Yaze.app/Contents/Resources"
|
||||||
|
cp build/bin/yaze "Yaze.app/Contents/MacOS/"
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Create Info.plist with correct version
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
echo '<?xml version="1.0" encoding="UTF-8"?>' > "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<plist version="1.0">' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<dict>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleExecutable</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>yaze</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleIdentifier</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>com.yaze.editor</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleName</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>Yaze</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleVersion</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundleShortVersionString</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo "<string>$VERSION_NUM</string>" >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<key>CFBundlePackageType</key>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '<string>APPL</string>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '</dict>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
echo '</plist>' >> "Yaze.app/Contents/Info.plist"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create DMG
|
||||||
|
mkdir dmg_staging
|
||||||
|
cp -r Yaze.app dmg_staging/
|
||||||
|
cp LICENSE dmg_staging/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md dmg_staging/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cp -r docs dmg_staging/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
hdiutil create -srcfolder dmg_staging -format UDZO -volname "Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}" ${{ matrix.artifact_name }}.dmg
|
||||||
|
|
||||||
|
else
|
||||||
|
# Linux packaging
|
||||||
|
mkdir package
|
||||||
|
cp build/bin/yaze package/
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp -r docs package/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
tar -czf ${{ matrix.artifact_name }}.tar.gz -C package .
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Packaging completed successfully!"
|
||||||
|
|
||||||
|
# Create release with artifacts
|
||||||
|
- name: Upload to Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
name: Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
|
||||||
|
draft: false
|
||||||
|
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
|
||||||
|
files: |
|
||||||
|
${{ matrix.artifact_name }}.*
|
||||||
|
|
||||||
|
publish-packages:
|
||||||
|
name: Publish Packages
|
||||||
|
needs: [validate-and-prepare, build-release]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: success()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Announce release
|
||||||
|
run: |
|
||||||
|
echo "🎉 Yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
|
||||||
|
echo "📦 Packages are now available for download"
|
||||||
|
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"
|
||||||
369
.github/workflows/release.yml
vendored
Normal file
369
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,369 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+'
|
||||||
|
- 'v[0-9]+.[0-9]+.[0-9]+-*'
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'Release tag (must start with v and follow semantic versioning)'
|
||||||
|
required: true
|
||||||
|
default: 'v0.3.0'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: Release
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-and-prepare:
|
||||||
|
name: Validate Release
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
outputs:
|
||||||
|
tag_name: ${{ steps.validate.outputs.tag_name }}
|
||||||
|
release_notes: ${{ steps.notes.outputs.content }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Validate tag format
|
||||||
|
id: validate
|
||||||
|
run: |
|
||||||
|
# Determine the tag based on trigger type
|
||||||
|
if [[ "${{ github.event_name }}" == "push" ]]; then
|
||||||
|
if [[ "${{ github.ref_type }}" != "tag" ]]; then
|
||||||
|
echo "❌ Error: Release workflow triggered by push to ${{ github.ref_type }} '${{ github.ref_name }}'"
|
||||||
|
echo "This workflow should only be triggered by pushing version tags (v1.2.3)"
|
||||||
|
echo "Use: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
TAG="${{ github.ref_name }}"
|
||||||
|
elif [[ "${{ github.event_name }}" == "workflow_dispatch" ]]; then
|
||||||
|
TAG="${{ github.event.inputs.tag }}"
|
||||||
|
if [[ -z "$TAG" ]]; then
|
||||||
|
echo "❌ Error: No tag specified for manual workflow dispatch"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "❌ Error: Unsupported event type: ${{ github.event_name }}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Validating tag: $TAG"
|
||||||
|
|
||||||
|
# Check if tag follows semantic versioning pattern
|
||||||
|
if [[ ! "$TAG" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
|
||||||
|
echo "❌ Error: Tag '$TAG' does not follow semantic versioning format (v1.2.3 or v1.2.3-beta)"
|
||||||
|
echo "Valid examples: v0.3.0, v1.0.0, v2.1.3-beta, v1.0.0-rc1"
|
||||||
|
echo ""
|
||||||
|
echo "To create a proper release:"
|
||||||
|
echo "1. Use the helper script: ./scripts/create_release.sh 0.3.0"
|
||||||
|
echo "2. Or manually: git tag v0.3.0 && git push origin v0.3.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Tag format is valid: $TAG"
|
||||||
|
echo "VALIDATED_TAG=$TAG" >> $GITHUB_ENV
|
||||||
|
echo "tag_name=$TAG" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
|
||||||
|
- name: Generate release notes
|
||||||
|
id: release_notes
|
||||||
|
run: |
|
||||||
|
# Extract release version from validated tag
|
||||||
|
VERSION="${VALIDATED_TAG}"
|
||||||
|
VERSION_NUM=$(echo "$VERSION" | sed 's/^v//')
|
||||||
|
|
||||||
|
# Generate release notes using the dedicated script
|
||||||
|
echo "Extracting changelog for version: $VERSION_NUM"
|
||||||
|
if python3 scripts/extract_changelog.py "$VERSION_NUM" > release_notes.md; then
|
||||||
|
echo "Changelog extracted successfully"
|
||||||
|
echo "Release notes content:"
|
||||||
|
cat release_notes.md
|
||||||
|
else
|
||||||
|
echo "Failed to extract changelog, creating default release notes"
|
||||||
|
echo "# Yaze $VERSION Release Notes\n\nPlease see the full changelog at docs/C1-changelog.md" > release_notes.md
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Store release notes
|
||||||
|
id: notes
|
||||||
|
run: |
|
||||||
|
# Store release notes content for later use
|
||||||
|
echo "content<<EOF" >> $GITHUB_OUTPUT
|
||||||
|
cat release_notes.md >> $GITHUB_OUTPUT
|
||||||
|
echo "EOF" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
build-release:
|
||||||
|
name: Build Release
|
||||||
|
needs: validate-and-prepare
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Windows x64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: x64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: x64
|
||||||
|
artifact_name: "yaze-windows-x64"
|
||||||
|
|
||||||
|
- name: "Windows ARM64"
|
||||||
|
os: windows-2022
|
||||||
|
vcpkg_triplet: arm64-windows
|
||||||
|
cmake_generator: "Visual Studio 17 2022"
|
||||||
|
cmake_generator_platform: ARM64
|
||||||
|
artifact_name: "yaze-windows-arm64"
|
||||||
|
|
||||||
|
- name: "macOS Universal"
|
||||||
|
os: macos-14
|
||||||
|
vcpkg_triplet: arm64-osx
|
||||||
|
artifact_name: "yaze-macos"
|
||||||
|
|
||||||
|
- name: "Linux x64"
|
||||||
|
os: ubuntu-22.04
|
||||||
|
artifact_name: "yaze-linux-x64"
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
# Platform-specific dependency installation
|
||||||
|
- name: Install Linux dependencies
|
||||||
|
if: runner.os == 'Linux'
|
||||||
|
run: |
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y \
|
||||||
|
build-essential \
|
||||||
|
ninja-build \
|
||||||
|
pkg-config \
|
||||||
|
libglew-dev \
|
||||||
|
libxext-dev \
|
||||||
|
libwavpack-dev \
|
||||||
|
libabsl-dev \
|
||||||
|
libboost-all-dev \
|
||||||
|
libpng-dev \
|
||||||
|
python3-dev \
|
||||||
|
libpython3-dev \
|
||||||
|
libasound2-dev \
|
||||||
|
libpulse-dev \
|
||||||
|
libx11-dev \
|
||||||
|
libxrandr-dev \
|
||||||
|
libxcursor-dev \
|
||||||
|
libxinerama-dev \
|
||||||
|
libxi-dev
|
||||||
|
|
||||||
|
- name: Install macOS dependencies
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
run: |
|
||||||
|
# Install Homebrew dependencies needed for UI tests and full builds
|
||||||
|
brew install pkg-config libpng boost abseil ninja gtk+3
|
||||||
|
|
||||||
|
# Set up vcpkg for Windows builds with fallback
|
||||||
|
- name: Set up vcpkg (Windows)
|
||||||
|
id: vcpkg_setup
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
continue-on-error: true
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
VCPKG_DISABLE_METRICS: 1
|
||||||
|
VCPKG_DEFAULT_TRIPLET: ${{ matrix.vcpkg_triplet }}
|
||||||
|
VCPKG_ROOT: ${{ github.workspace }}/vcpkg
|
||||||
|
|
||||||
|
# Set vcpkg availability flag when vcpkg succeeds
|
||||||
|
- name: Set vcpkg availability flag
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'success'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
echo "VCPKG_AVAILABLE=true" >> $env:GITHUB_ENV
|
||||||
|
Write-Host "vcpkg setup successful"
|
||||||
|
|
||||||
|
# Fallback: Set minimal build flag when vcpkg fails
|
||||||
|
- name: Set minimal build flag (Windows fallback)
|
||||||
|
if: runner.os == 'Windows' && steps.vcpkg_setup.outcome == 'failure'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
echo "VCPKG_AVAILABLE=false" >> $env:GITHUB_ENV
|
||||||
|
echo "YAZE_MINIMAL_BUILD=ON" >> $env:GITHUB_ENV
|
||||||
|
Write-Host "vcpkg setup failed, using minimal build configuration"
|
||||||
|
|
||||||
|
# Configure CMake
|
||||||
|
- name: Configure CMake (Linux/macOS)
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
run: |
|
||||||
|
cmake -B build \
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 \
|
||||||
|
-DYAZE_BUILD_TESTS=OFF \
|
||||||
|
-DYAZE_BUILD_EMU=OFF \
|
||||||
|
-DYAZE_BUILD_Z3ED=OFF \
|
||||||
|
-DYAZE_ENABLE_UI_TESTS=ON \
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF \
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF \
|
||||||
|
-DYAZE_INSTALL_LIB=OFF \
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF \
|
||||||
|
-GNinja
|
||||||
|
|
||||||
|
- name: Configure CMake (Windows)
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
Write-Host "Configuring CMake for Windows build..."
|
||||||
|
|
||||||
|
# Check if vcpkg is available
|
||||||
|
if ((Test-Path "${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake") -and ($env:VCPKG_AVAILABLE -ne "false")) {
|
||||||
|
Write-Host "Using vcpkg toolchain..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DCMAKE_TOOLCHAIN_FILE="${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake" `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=OFF `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
} else {
|
||||||
|
Write-Host "Using minimal build configuration (vcpkg not available)..."
|
||||||
|
cmake -B build `
|
||||||
|
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} `
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.16 `
|
||||||
|
-DYAZE_BUILD_TESTS=OFF `
|
||||||
|
-DYAZE_BUILD_EMU=OFF `
|
||||||
|
-DYAZE_ENABLE_ROM_TESTS=OFF `
|
||||||
|
-DYAZE_ENABLE_EXPERIMENTAL_TESTS=OFF `
|
||||||
|
-DYAZE_INSTALL_LIB=OFF `
|
||||||
|
-DYAZE_MINIMAL_BUILD=ON `
|
||||||
|
-G "${{ matrix.cmake_generator }}" `
|
||||||
|
-A ${{ matrix.cmake_generator_platform }}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "CMake configuration completed successfully"
|
||||||
|
|
||||||
|
# Build
|
||||||
|
- name: Build
|
||||||
|
run: |
|
||||||
|
echo "Building YAZE for ${{ matrix.name }}..."
|
||||||
|
cmake --build build --config ${{ env.BUILD_TYPE }} --parallel
|
||||||
|
echo "Build completed successfully!"
|
||||||
|
|
||||||
|
# Test executable functionality
|
||||||
|
- name: Test executable functionality
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
|
||||||
|
echo "Testing executable for ${{ matrix.name }}..."
|
||||||
|
|
||||||
|
# Determine executable path based on platform
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
exePath="build/bin/${{ env.BUILD_TYPE }}/yaze.exe"
|
||||||
|
elif [[ "${{ runner.os }}" == "macOS" ]]; then
|
||||||
|
exePath="build/bin/yaze.app/Contents/MacOS/yaze"
|
||||||
|
else
|
||||||
|
exePath="build/bin/yaze"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$exePath" ]; then
|
||||||
|
echo "✓ Executable found: $exePath"
|
||||||
|
|
||||||
|
# Test that it's not the test main
|
||||||
|
testResult=$($exePath --help 2>&1 || true)
|
||||||
|
exitCode=$?
|
||||||
|
|
||||||
|
if echo "$testResult" | grep -q "Google Test\|gtest"; then
|
||||||
|
echo "ERROR: Executable is running test main instead of app main!"
|
||||||
|
echo "Output: $testResult"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✓ Executable runs correctly (exit code: $exitCode)"
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
fileSize=$(stat -c%s "$exePath" 2>/dev/null || echo "0")
|
||||||
|
else
|
||||||
|
fileSize=$(stat -f%z "$exePath" 2>/dev/null || stat -c%s "$exePath" 2>/dev/null || echo "0")
|
||||||
|
fi
|
||||||
|
fileSizeMB=$(echo "scale=2; $fileSize / 1024 / 1024" | bc -l 2>/dev/null || echo "0")
|
||||||
|
echo "Executable size: ${fileSizeMB} MB"
|
||||||
|
else
|
||||||
|
echo "ERROR: Executable not found at: $exePath"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Package
|
||||||
|
- name: Package
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
set -e
|
||||||
|
echo "Packaging for ${{ matrix.name }}..."
|
||||||
|
|
||||||
|
if [[ "${{ runner.os }}" == "Windows" ]]; then
|
||||||
|
# Windows packaging
|
||||||
|
mkdir -p package
|
||||||
|
cp -r build/bin/${{ env.BUILD_TYPE }}/* package/ 2>/dev/null || echo "No Release binaries found, trying Debug..."
|
||||||
|
cp -r build/bin/Debug/* package/ 2>/dev/null || echo "No Debug binaries found"
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cd package && zip -r ../${{ matrix.artifact_name }}.zip *
|
||||||
|
|
||||||
|
elif [[ "${{ runner.os }}" == "macOS" ]]; then
|
||||||
|
# macOS packaging using dedicated script
|
||||||
|
VERSION_NUM=$(echo "${{ needs.validate-and-prepare.outputs.tag_name }}" | sed 's/^v//')
|
||||||
|
./scripts/create-macos-bundle.sh "$VERSION_NUM" "${{ matrix.artifact_name }}"
|
||||||
|
|
||||||
|
else
|
||||||
|
# Linux packaging
|
||||||
|
mkdir package
|
||||||
|
cp build/bin/yaze package/
|
||||||
|
cp -r assets package/ 2>/dev/null || echo "assets directory not found"
|
||||||
|
cp -r docs package/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
cp LICENSE package/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md package/ 2>/dev/null || echo "README.md not found"
|
||||||
|
tar -czf ${{ matrix.artifact_name }}.tar.gz -C package .
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Packaging completed successfully!"
|
||||||
|
|
||||||
|
# Create release with artifacts
|
||||||
|
- name: Upload to Release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
tag_name: ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
name: Yaze ${{ needs.validate-and-prepare.outputs.tag_name }}
|
||||||
|
body: ${{ needs.validate-and-prepare.outputs.release_notes }}
|
||||||
|
draft: false
|
||||||
|
prerelease: ${{ contains(needs.validate-and-prepare.outputs.tag_name, 'beta') || contains(needs.validate-and-prepare.outputs.tag_name, 'alpha') || contains(needs.validate-and-prepare.outputs.tag_name, 'rc') }}
|
||||||
|
files: |
|
||||||
|
${{ matrix.artifact_name }}.*
|
||||||
|
|
||||||
|
publish-packages:
|
||||||
|
name: Publish Packages
|
||||||
|
needs: [validate-and-prepare, build-release]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: success()
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Announce release
|
||||||
|
run: |
|
||||||
|
echo "🎉 Yaze ${{ needs.validate-and-prepare.outputs.tag_name }} has been released!"
|
||||||
|
echo "📦 Packages are now available for download"
|
||||||
|
echo "🔗 Release URL: https://github.com/${{ github.repository }}/releases/tag/${{ needs.validate-and-prepare.outputs.tag_name }}"
|
||||||
157
.github/workflows/validate-vs-build.yml
vendored
Normal file
157
.github/workflows/validate-vs-build.yml
vendored
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
name: Validate Visual Studio Builds
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master", "develop" ]
|
||||||
|
paths:
|
||||||
|
- 'vcpkg.json'
|
||||||
|
- 'src/**'
|
||||||
|
- 'scripts/generate-vs-projects.py'
|
||||||
|
- 'scripts/validate-vs-build.ps1'
|
||||||
|
- '.github/workflows/validate-vs-build.yml'
|
||||||
|
pull_request:
|
||||||
|
branches: [ "master", "develop" ]
|
||||||
|
paths:
|
||||||
|
- 'vcpkg.json'
|
||||||
|
- 'src/**'
|
||||||
|
- 'scripts/generate-vs-projects.py'
|
||||||
|
- 'scripts/validate-vs-build.ps1'
|
||||||
|
- '.github/workflows/validate-vs-build.yml'
|
||||||
|
|
||||||
|
env:
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
validate-vs-builds:
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: "Windows x64 Debug"
|
||||||
|
platform: x64
|
||||||
|
configuration: Debug
|
||||||
|
|
||||||
|
- name: "Windows x64 Release"
|
||||||
|
platform: x64
|
||||||
|
configuration: Release
|
||||||
|
|
||||||
|
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
runs-on: windows-2022
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
|
||||||
|
- name: Set up vcpkg
|
||||||
|
uses: lukka/run-vcpkg@v11
|
||||||
|
with:
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
runVcpkgInstall: true
|
||||||
|
vcpkgJsonGlob: '**/vcpkg.json'
|
||||||
|
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
|
||||||
|
env:
|
||||||
|
VCPKG_FORCE_SYSTEM_BINARIES: 1
|
||||||
|
VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite"
|
||||||
|
|
||||||
|
- name: Validate Visual Studio Build
|
||||||
|
shell: pwsh
|
||||||
|
run: |
|
||||||
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "YAZE Visual Studio Build Validation" -ForegroundColor Cyan
|
||||||
|
Write-Host "Platform: ${{ matrix.platform }}" -ForegroundColor Yellow
|
||||||
|
Write-Host "Configuration: ${{ matrix.configuration }}" -ForegroundColor Yellow
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if (-not (Test-Path "yaze.sln")) {
|
||||||
|
Write-Error "yaze.sln not found. Please run this script from the project root directory."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ yaze.sln found" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Ensure build directory exists
|
||||||
|
if (-not (Test-Path "build")) {
|
||||||
|
New-Item -ItemType Directory -Path "build" | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build using MSBuild
|
||||||
|
Write-Host "Building with MSBuild..." -ForegroundColor Yellow
|
||||||
|
$msbuildArgs = @(
|
||||||
|
"yaze.sln"
|
||||||
|
"/p:Configuration=${{ matrix.configuration }}"
|
||||||
|
"/p:Platform=${{ matrix.platform }}"
|
||||||
|
"/p:VcpkgEnabled=true"
|
||||||
|
"/p:VcpkgManifestInstall=true"
|
||||||
|
"/m" # Multi-processor build
|
||||||
|
"/verbosity:minimal"
|
||||||
|
)
|
||||||
|
|
||||||
|
Write-Host "MSBuild command: msbuild $($msbuildArgs -join ' ')" -ForegroundColor Gray
|
||||||
|
& msbuild @msbuildArgs
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Error "MSBuild failed with exit code $LASTEXITCODE"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Build completed successfully" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Verify executable was created
|
||||||
|
$exePath = "build\bin\${{ matrix.configuration }}\yaze.exe"
|
||||||
|
if (-not (Test-Path $exePath)) {
|
||||||
|
Write-Error "Executable not found at expected path: $exePath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable created: $exePath" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Verify assets were copied
|
||||||
|
$assetsPath = "build\bin\${{ matrix.configuration }}\assets"
|
||||||
|
if (-not (Test-Path $assetsPath)) {
|
||||||
|
Write-Error "Assets directory not found at expected path: $assetsPath"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Assets copied to: $assetsPath" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Test that the executable runs (basic test)
|
||||||
|
Write-Host "Testing executable startup..." -ForegroundColor Yellow
|
||||||
|
$testResult = & $exePath --help 2>&1
|
||||||
|
$exitCode = $LASTEXITCODE
|
||||||
|
|
||||||
|
# Check if it's the test main or app main
|
||||||
|
if ($testResult -match "Google Test" -or $testResult -match "gtest") {
|
||||||
|
Write-Error "Executable is running test main instead of app main!"
|
||||||
|
Write-Host "Output: $testResult" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "✓ Executable runs correctly (exit code: $exitCode)" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
$exeInfo = Get-Item $exePath
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Build Summary:" -ForegroundColor Cyan
|
||||||
|
Write-Host " Executable: $($exeInfo.FullName)" -ForegroundColor White
|
||||||
|
Write-Host " Size: $([math]::Round($exeInfo.Length / 1MB, 2)) MB" -ForegroundColor White
|
||||||
|
Write-Host " Created: $($exeInfo.CreationTime)" -ForegroundColor White
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "✓ Visual Studio build validation PASSED" -ForegroundColor Green
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
- name: Upload build artifacts
|
||||||
|
uses: actions/upload-artifact@v4
|
||||||
|
if: always()
|
||||||
|
with:
|
||||||
|
name: yaze-${{ matrix.platform }}-${{ matrix.configuration }}
|
||||||
|
path: |
|
||||||
|
build/bin/${{ matrix.configuration }}/
|
||||||
|
retention-days: 7
|
||||||
28
.gitignore
vendored
28
.gitignore
vendored
@@ -1,19 +1,21 @@
|
|||||||
|
.favorites.json
|
||||||
build/
|
build/
|
||||||
.cache/
|
.cache/
|
||||||
.vscode/
|
.vscode/
|
||||||
src/lib/SDL2
|
disasm/
|
||||||
src/lib/cmake
|
src/etc
|
||||||
src/lib/GL
|
src/lib/
|
||||||
src/lib/abseil-cpp
|
|
||||||
src/lib/libGLEW.2.2.0.dylib
|
|
||||||
src/lib/libGLEW.2.2.dylib
|
|
||||||
src/lib/libGLEW.a
|
|
||||||
src/lib/libGLEW.dylib
|
|
||||||
src/lib/libSDL2_test.a
|
|
||||||
src/lib/libSDL2-2.0.0.dylib
|
|
||||||
src/lib/libSDL2.a
|
|
||||||
src/lib/libSDL2.dylib
|
|
||||||
src/lib/libSDL2main.a
|
|
||||||
checks.json
|
checks.json
|
||||||
assets/lib/libasar.dll
|
assets/lib/libasar.dll
|
||||||
cmake/yaze.plist.in
|
cmake/yaze.plist.in
|
||||||
|
etc/
|
||||||
|
latex/
|
||||||
|
html/
|
||||||
|
docs/zarby_algos.md
|
||||||
|
docs/overworld-expansion.md
|
||||||
|
assets/asm/EditorCore.asm
|
||||||
|
src/app/emu/cpu/internal/old_cpu.cc
|
||||||
|
build-windows
|
||||||
|
src/lib/libpng
|
||||||
|
src/lib/zlib
|
||||||
|
assets/layouts/ow_toolset.zeml
|
||||||
24
.gitmodules
vendored
24
.gitmodules
vendored
@@ -1,15 +1,6 @@
|
|||||||
[submodule "src/lib/imgui"]
|
[submodule "src/lib/imgui"]
|
||||||
path = src/lib/imgui
|
path = src/lib/imgui
|
||||||
url = https://github.com/ocornut/imgui.git
|
url = https://github.com/ocornut/imgui.git
|
||||||
[submodule "src/lib/ImGuiFileDialog"]
|
|
||||||
path = src/lib/ImGuiFileDialog
|
|
||||||
url = https://github.com/aiekick/ImGuiFileDialog.git
|
|
||||||
[submodule "src/lib/ImGuiColorTextEdit"]
|
|
||||||
path = src/lib/ImGuiColorTextEdit
|
|
||||||
url = https://github.com/BalazsJako/ImGuiColorTextEdit.git
|
|
||||||
[submodule "src/lib/sneshacking"]
|
|
||||||
path = src/lib/sneshacking
|
|
||||||
url = https://github.com/Skarsnik/sneshacking.git
|
|
||||||
[submodule "assets/asm/alttp-hacker-workspace"]
|
[submodule "assets/asm/alttp-hacker-workspace"]
|
||||||
path = assets/asm/alttp-hacker-workspace
|
path = assets/asm/alttp-hacker-workspace
|
||||||
url = https://github.com/scawful/alttp-hacker-workspace.git
|
url = https://github.com/scawful/alttp-hacker-workspace.git
|
||||||
@@ -22,9 +13,12 @@
|
|||||||
[submodule "src/lib/asar"]
|
[submodule "src/lib/asar"]
|
||||||
path = src/lib/asar
|
path = src/lib/asar
|
||||||
url = https://github.com/RPGHacker/asar.git
|
url = https://github.com/RPGHacker/asar.git
|
||||||
[submodule "src/lib/snes_spc"]
|
[submodule "src/lib/imgui_test_engine"]
|
||||||
path = src/lib/snes_spc
|
path = src/lib/imgui_test_engine
|
||||||
url = https://github.com/blarggs-audio-libraries/snes_spc.git
|
url = https://github.com/ocornut/imgui_test_engine.git
|
||||||
[submodule "src/lib/SDL_mixer"]
|
[submodule "src/lib/nativefiledialog-extended"]
|
||||||
path = src/lib/SDL_mixer
|
path = src/lib/nativefiledialog-extended
|
||||||
url = https://github.com/libsdl-org/SDL_mixer.git
|
url = https://github.com/btzy/nativefiledialog-extended.git
|
||||||
|
[submodule "assets/asm/usdasm"]
|
||||||
|
path = assets/asm/usdasm
|
||||||
|
url = https://github.com/spannerisms/usdasm.git
|
||||||
|
|||||||
277
CMakeLists.txt
277
CMakeLists.txt
@@ -1,81 +1,222 @@
|
|||||||
# CMake Specifications --------------------------------------------------------
|
|
||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
|
|
||||||
# Yet Another Zelda3 Editor
|
# Yet Another Zelda3 Editor
|
||||||
# by scawful
|
# by scawful
|
||||||
project(yaze VERSION 0.01)
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
# C++ Standard Specifications -------------------------------------------------
|
# Set policy version to handle compatibility issues
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
if(POLICY CMP0091)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
cmake_policy(SET CMP0091 NEW)
|
||||||
set(CMAKE_CXX_EXTENSIONS ON)
|
|
||||||
set(CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
|
||||||
set(CMAKE_MODULE_LINKER_FLAGS \"-Wl,--no-undefined -Wl,--no-undefined\")
|
|
||||||
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
|
||||||
set(BUILD_SHARED_LIBS ON)
|
|
||||||
|
|
||||||
# Abseil Standard Specifications ----------------------------------------------
|
|
||||||
include(cmake/absl.cmake)
|
|
||||||
add_subdirectory(src/lib/abseil-cpp)
|
|
||||||
|
|
||||||
include(cmake/openssl.cmake)
|
|
||||||
set(Protobuf_PROTOC_EXECUTABLE "/Users/scawful/code/protobuf/bin/protoc")
|
|
||||||
set(Protobuf_INCLUDE_DIRS "/Users/scawful/code/protobuf/include/")
|
|
||||||
set(PROTOBUF_INCLUDE_PATH ${CMAKE_CURRENT_BINARY_DIR}
|
|
||||||
CACHE INTERNAL "Path to generated protobuf files.")
|
|
||||||
include_directories(${PROTOBUF_INCLUDE_PATH})
|
|
||||||
|
|
||||||
# Video Libraries -------------------------------------------------------------
|
|
||||||
find_package(PNG REQUIRED)
|
|
||||||
find_package(OpenGL REQUIRED)
|
|
||||||
find_package(GLEW REQUIRED)
|
|
||||||
|
|
||||||
# SDL2 ------------------------------------------------------------------------
|
|
||||||
if (UNIX)
|
|
||||||
add_subdirectory(src/lib/SDL)
|
|
||||||
else()
|
|
||||||
find_package(SDL2)
|
|
||||||
endif()
|
endif()
|
||||||
set(SDL2MIXER_OPUS OFF)
|
|
||||||
set(SDL2MIXER_FLAC OFF)
|
|
||||||
set(SDL2MIXER_MOD OFF)
|
|
||||||
set(SDL2MIXER_MIDI_FLUIDSYNTH OFF)
|
|
||||||
find_library(SDL_MIXER_LIBRARY
|
|
||||||
NAMES SDL_mixer
|
|
||||||
HINTS
|
|
||||||
ENV SDLMIXERDIR
|
|
||||||
ENV SDLDIR
|
|
||||||
PATH_SUFFIXES lib ${VC_LIB_PATH_SUFFIX}
|
|
||||||
)
|
|
||||||
add_subdirectory(src/lib/SDL_mixer)
|
|
||||||
|
|
||||||
# Asar ------------------------------------------------------------------------
|
# Set additional policies to handle submodule compatibility
|
||||||
add_subdirectory(src/lib/asar/src)
|
if(POLICY CMP0048)
|
||||||
|
cmake_policy(SET CMP0048 NEW)
|
||||||
|
endif()
|
||||||
|
if(POLICY CMP0077)
|
||||||
|
cmake_policy(SET CMP0077 NEW)
|
||||||
|
endif()
|
||||||
|
if(POLICY CMP0091)
|
||||||
|
cmake_policy(SET CMP0091 NEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Suppress deprecation warnings from submodules
|
||||||
|
set(CMAKE_WARN_DEPRECATED OFF CACHE BOOL "Suppress deprecation warnings")
|
||||||
|
|
||||||
|
# Handle pthread issues on Windows
|
||||||
|
if(WIN32)
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
project(yaze VERSION 0.3.1
|
||||||
|
DESCRIPTION "Yet Another Zelda3 Editor"
|
||||||
|
LANGUAGES CXX C)
|
||||||
|
|
||||||
|
# Set project metadata
|
||||||
|
set(YAZE_VERSION_MAJOR 0)
|
||||||
|
set(YAZE_VERSION_MINOR 3)
|
||||||
|
set(YAZE_VERSION_PATCH 1)
|
||||||
|
|
||||||
|
configure_file(src/yaze_config.h.in yaze_config.h @ONLY)
|
||||||
|
|
||||||
|
# Build Flags
|
||||||
|
set(YAZE_BUILD_APP ON)
|
||||||
|
set(YAZE_BUILD_LIB ON)
|
||||||
|
set(YAZE_BUILD_EMU ON)
|
||||||
|
set(YAZE_BUILD_Z3ED ON)
|
||||||
|
set(YAZE_BUILD_TESTS ON)
|
||||||
|
set(YAZE_INSTALL_LIB OFF)
|
||||||
|
|
||||||
|
# Testing and CI Configuration
|
||||||
|
option(YAZE_ENABLE_ROM_TESTS "Enable tests that require ROM files" OFF)
|
||||||
|
option(YAZE_ENABLE_EXPERIMENTAL_TESTS "Enable experimental/unstable tests" ON)
|
||||||
|
option(YAZE_ENABLE_UI_TESTS "Enable ImGui Test Engine UI testing" ON)
|
||||||
|
option(YAZE_MINIMAL_BUILD "Minimal build for CI (disable optional features)" OFF)
|
||||||
|
|
||||||
|
# Configure minimal builds for CI/CD
|
||||||
|
if(YAZE_MINIMAL_BUILD)
|
||||||
|
set(YAZE_ENABLE_UI_TESTS OFF CACHE BOOL "Disabled for minimal build" FORCE)
|
||||||
|
set(YAZE_BUILD_Z3ED OFF CACHE BOOL "Disabled for minimal build" FORCE)
|
||||||
|
# Keep EMU and LIB enabled for comprehensive testing
|
||||||
|
set(YAZE_BUILD_EMU ON CACHE BOOL "Required for test suite" FORCE)
|
||||||
|
set(YAZE_BUILD_LIB ON CACHE BOOL "Required for test suite" FORCE)
|
||||||
|
set(YAZE_INSTALL_LIB OFF CACHE BOOL "Disabled for minimal build" FORCE)
|
||||||
|
endif()
|
||||||
|
set(YAZE_TEST_ROM_PATH "${CMAKE_BINARY_DIR}/bin/zelda3.sfc" CACHE STRING "Path to test ROM file")
|
||||||
|
|
||||||
|
# libpng features in bitmap.cc - conditional for minimal builds
|
||||||
|
if(PNG_FOUND)
|
||||||
|
add_definitions("-DYAZE_LIB_PNG=1")
|
||||||
|
else()
|
||||||
|
add_definitions("-DYAZE_LIB_PNG=0")
|
||||||
|
message(STATUS "Building without PNG support for minimal build")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Modern CMake standards
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_C_STANDARD 99)
|
||||||
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
|
# Output directories
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
set(BUILD_SHARED_LIBS OFF)
|
||||||
|
set(CMAKE_FIND_FRAMEWORK LAST)
|
||||||
|
|
||||||
|
# Platform detection
|
||||||
|
if(CMAKE_SYSTEM_NAME MATCHES "Darwin")
|
||||||
|
set(YAZE_PLATFORM_MACOS ON)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||||
|
set(YAZE_PLATFORM_LINUX ON)
|
||||||
|
elseif(CMAKE_SYSTEM_NAME MATCHES "Windows")
|
||||||
|
set(YAZE_PLATFORM_WINDOWS ON)
|
||||||
|
# Enable vcpkg integration for Windows builds
|
||||||
|
if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
CACHE STRING "Vcpkg toolchain file")
|
||||||
|
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake" AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_CURRENT_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake"
|
||||||
|
CACHE STRING "Vcpkg toolchain file")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Create a common interface target for shared settings
|
||||||
|
add_library(yaze_common INTERFACE)
|
||||||
|
target_compile_features(yaze_common INTERFACE cxx_std_23)
|
||||||
|
|
||||||
|
# Platform-specific configurations
|
||||||
|
if(YAZE_PLATFORM_LINUX)
|
||||||
|
target_compile_definitions(yaze_common INTERFACE linux stricmp=strcasecmp)
|
||||||
|
elseif(YAZE_PLATFORM_MACOS)
|
||||||
|
set(CMAKE_INSTALL_PREFIX /usr/local)
|
||||||
|
target_compile_definitions(yaze_common INTERFACE MACOS)
|
||||||
|
elseif(YAZE_PLATFORM_WINDOWS)
|
||||||
|
include(cmake/vcpkg.cmake)
|
||||||
|
target_compile_definitions(yaze_common INTERFACE WINDOWS)
|
||||||
|
|
||||||
|
# Windows-specific architecture detection and configuration
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
|
||||||
|
target_compile_definitions(yaze_common INTERFACE YAZE_ARCH_ARM64)
|
||||||
|
message(STATUS "Building for Windows ARM64")
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64")
|
||||||
|
target_compile_definitions(yaze_common INTERFACE YAZE_ARCH_X64)
|
||||||
|
message(STATUS "Building for Windows x64")
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86")
|
||||||
|
target_compile_definitions(yaze_common INTERFACE YAZE_ARCH_X86)
|
||||||
|
message(STATUS "Building for Windows x86")
|
||||||
|
else()
|
||||||
|
message(WARNING "Unknown Windows architecture: ${CMAKE_SYSTEM_PROCESSOR}")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Compiler-specific settings
|
||||||
|
if(MSVC)
|
||||||
|
target_compile_options(yaze_common INTERFACE
|
||||||
|
/W4 /permissive-
|
||||||
|
/bigobj # Support large object files
|
||||||
|
/utf-8 # Use UTF-8 encoding
|
||||||
|
)
|
||||||
|
target_compile_definitions(yaze_common INTERFACE
|
||||||
|
_CRT_SECURE_NO_WARNINGS
|
||||||
|
_CRT_NONSTDC_NO_WARNINGS
|
||||||
|
SILENCE_CXX23_DEPRECATIONS
|
||||||
|
_SILENCE_CXX23_DEPRECATION_WARNING
|
||||||
|
_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS
|
||||||
|
NOMINMAX # Disable min/max macros
|
||||||
|
WIN32_LEAN_AND_MEAN # Reduce Windows header bloat
|
||||||
|
strncasecmp=_strnicmp
|
||||||
|
strcasecmp=_stricmp
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
target_compile_options(yaze_common INTERFACE
|
||||||
|
-Wall -Wextra -Wpedantic
|
||||||
|
-Wno-deprecated-declarations # Silence deprecation warnings
|
||||||
|
-Wno-c++23-compat # Silence C++23 compatibility warnings
|
||||||
|
)
|
||||||
|
# Add C++23 deprecation silencing for GCC/Clang
|
||||||
|
target_compile_definitions(yaze_common INTERFACE
|
||||||
|
_SILENCE_CXX23_DEPRECATION_WARNING
|
||||||
|
_SILENCE_ALL_CXX23_DEPRECATION_WARNINGS
|
||||||
|
ABSL_HAVE_INTRINSIC_INT128=1 # Enable intrinsic int128 support
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Abseil Standard Specifications
|
||||||
|
include(cmake/absl.cmake)
|
||||||
|
|
||||||
|
# SDL2 and PNG
|
||||||
|
include(cmake/sdl2.cmake)
|
||||||
|
|
||||||
|
# Asar
|
||||||
include(cmake/asar.cmake)
|
include(cmake/asar.cmake)
|
||||||
|
|
||||||
# snes-spc --------------------------------------------------------------------
|
# Google Test (if needed for main app integration)
|
||||||
ADD_DEFINITIONS(-DSNES_SPC_EXPORTS)
|
if (YAZE_BUILD_TESTS)
|
||||||
set(SNES_SPC_SOURCES
|
include(cmake/gtest.cmake)
|
||||||
"../src/lib/snes_spc/snes_spc/spc.cpp"
|
endif()
|
||||||
"../src/lib/snes_spc/snes_spc/SNES_SPC.cpp"
|
|
||||||
"../src/lib/snes_spc/snes_spc/SNES_SPC_misc.cpp"
|
|
||||||
"../src/lib/snes_spc/snes_spc/SNES_SPC_state.cpp"
|
|
||||||
"../src/lib/snes_spc/snes_spc/SPC_DSP.cpp"
|
|
||||||
"../src/lib/snes_spc/snes_spc/dsp.cpp"
|
|
||||||
"../src/lib/snes_spc/snes_spc/SPC_Filter.cpp"
|
|
||||||
"../src/lib/snes_spc/demo/wave_writer.c"
|
|
||||||
"../src/lib/snes_spc/demo/demo_util.c"
|
|
||||||
)
|
|
||||||
include_directories(src/lib/snes_spc/snes_spc)
|
|
||||||
ADD_LIBRARY(snes_spc STATIC ${SNES_SPC_SOURCES} src/app/spc700/spc700.def)
|
|
||||||
|
|
||||||
# ImGui -----------------------------------------------------------------------
|
# ImGui (after minimal build flags are set)
|
||||||
include(cmake/imgui.cmake)
|
include(cmake/imgui.cmake)
|
||||||
|
|
||||||
# Project Files
|
# Project Files
|
||||||
|
# Copy theme files to build directory (for development)
|
||||||
|
file(GLOB THEME_FILES "${CMAKE_SOURCE_DIR}/assets/themes/*.theme")
|
||||||
|
file(COPY ${THEME_FILES} DESTINATION "${CMAKE_BINARY_DIR}/assets/themes/")
|
||||||
|
|
||||||
|
# IMPORTANT: Also ensure themes are included in macOS bundles
|
||||||
|
# This is handled in src/CMakeLists.txt via YAZE_RESOURCE_FILES
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
|
# Tests
|
||||||
|
if (YAZE_BUILD_TESTS)
|
||||||
add_subdirectory(test)
|
add_subdirectory(test)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Code quality targets
|
||||||
|
find_program(CLANG_FORMAT NAMES clang-format clang-format-14 clang-format-15 clang-format-16 clang-format-17 clang-format-18)
|
||||||
|
if(CLANG_FORMAT)
|
||||||
|
file(GLOB_RECURSE ALL_SOURCE_FILES
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/*.cc"
|
||||||
|
"${CMAKE_SOURCE_DIR}/src/*.h"
|
||||||
|
"${CMAKE_SOURCE_DIR}/test/*.cc"
|
||||||
|
"${CMAKE_SOURCE_DIR}/test/*.h")
|
||||||
|
|
||||||
|
add_custom_target(format
|
||||||
|
COMMAND ${CLANG_FORMAT} -i --style=Google ${ALL_SOURCE_FILES}
|
||||||
|
COMMENT "Running clang-format on source files"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(format-check
|
||||||
|
COMMAND ${CLANG_FORMAT} --dry-run --Werror --style=Google ${ALL_SOURCE_FILES}
|
||||||
|
COMMENT "Checking code format"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Packaging configuration
|
||||||
|
include(cmake/packaging.cmake)
|
||||||
|
|
||||||
|
|||||||
470
CMakePresets.json
Normal file
470
CMakePresets.json
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
{
|
||||||
|
"version": 6,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 16,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"displayName": "Default Config",
|
||||||
|
"description": "Default build configuration",
|
||||||
|
"generator": "Unix Makefiles",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
|
"YAZE_BUILD_TESTS": "ON",
|
||||||
|
"YAZE_BUILD_APP": "ON",
|
||||||
|
"YAZE_BUILD_LIB": "ON",
|
||||||
|
"YAZE_BUILD_EMU": "ON",
|
||||||
|
"YAZE_BUILD_Z3ED": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"displayName": "Debug",
|
||||||
|
"description": "Debug build with full debugging symbols",
|
||||||
|
"inherits": "default",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_CXX_FLAGS_DEBUG": "-g -O0 -DDEBUG",
|
||||||
|
"CMAKE_C_FLAGS_DEBUG": "-g -O0 -DDEBUG",
|
||||||
|
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"displayName": "Release",
|
||||||
|
"description": "Optimized release build",
|
||||||
|
"inherits": "default",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Release",
|
||||||
|
"YAZE_BUILD_TESTS": "OFF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"displayName": "Development",
|
||||||
|
"description": "Development build with ROM testing enabled",
|
||||||
|
"inherits": "debug",
|
||||||
|
"cacheVariables": {
|
||||||
|
"YAZE_ENABLE_ROM_TESTS": "ON",
|
||||||
|
"YAZE_TEST_ROM_PATH": "${sourceDir}/build/bin/zelda3.sfc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-dev",
|
||||||
|
"displayName": "macOS Development (ARM64)",
|
||||||
|
"description": "macOS ARM64 development build with ROM testing",
|
||||||
|
"inherits": "macos-debug",
|
||||||
|
"cacheVariables": {
|
||||||
|
"YAZE_ENABLE_ROM_TESTS": "ON",
|
||||||
|
"YAZE_TEST_ROM_PATH": "${sourceDir}/build/bin/zelda3.sfc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ci",
|
||||||
|
"displayName": "Continuous Integration",
|
||||||
|
"description": "CI build without ROM-dependent tests",
|
||||||
|
"inherits": "default",
|
||||||
|
"cacheVariables": {
|
||||||
|
"YAZE_ENABLE_ROM_TESTS": "OFF",
|
||||||
|
"YAZE_BUILD_TESTS": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-debug",
|
||||||
|
"displayName": "macOS Debug (ARM64)",
|
||||||
|
"description": "macOS ARM64-specific debug configuration",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Darwin"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0",
|
||||||
|
"CMAKE_OSX_ARCHITECTURES": "arm64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-release",
|
||||||
|
"displayName": "macOS Release (ARM64)",
|
||||||
|
"description": "macOS ARM64-specific release configuration",
|
||||||
|
"inherits": "release",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Darwin"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_OSX_DEPLOYMENT_TARGET": "11.0",
|
||||||
|
"CMAKE_OSX_ARCHITECTURES": "arm64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-debug-universal",
|
||||||
|
"displayName": "macOS Debug (Universal)",
|
||||||
|
"description": "macOS universal binary debug configuration",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Darwin"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_OSX_DEPLOYMENT_TARGET": "10.15",
|
||||||
|
"CMAKE_OSX_ARCHITECTURES": "x86_64;arm64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-release-universal",
|
||||||
|
"displayName": "macOS Release (Universal)",
|
||||||
|
"description": "macOS universal binary release configuration",
|
||||||
|
"inherits": "release",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Darwin"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_OSX_DEPLOYMENT_TARGET": "10.15",
|
||||||
|
"CMAKE_OSX_ARCHITECTURES": "x86_64;arm64"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "linux-debug",
|
||||||
|
"displayName": "Linux Debug",
|
||||||
|
"description": "Linux-specific debug configuration",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Linux"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_CXX_COMPILER": "g++",
|
||||||
|
"CMAKE_C_COMPILER": "gcc"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "linux-clang",
|
||||||
|
"displayName": "Linux Clang",
|
||||||
|
"description": "Linux build with Clang",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Linux"
|
||||||
|
},
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_CXX_COMPILER": "clang++",
|
||||||
|
"CMAKE_C_COMPILER": "clang"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-debug",
|
||||||
|
"displayName": "Windows Debug",
|
||||||
|
"description": "Windows-specific debug configuration with vcpkg",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Windows"
|
||||||
|
},
|
||||||
|
"generator": "Visual Studio 17 2022",
|
||||||
|
"architecture": "x64",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||||
|
"VCPKG_TARGET_TRIPLET": "x64-windows",
|
||||||
|
"VCPKG_MANIFEST_MODE": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-release",
|
||||||
|
"displayName": "Windows Release",
|
||||||
|
"description": "Windows-specific release configuration with vcpkg",
|
||||||
|
"inherits": "release",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Windows"
|
||||||
|
},
|
||||||
|
"generator": "Visual Studio 17 2022",
|
||||||
|
"architecture": "x64",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||||
|
"VCPKG_TARGET_TRIPLET": "x64-windows",
|
||||||
|
"VCPKG_MANIFEST_MODE": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-dev",
|
||||||
|
"displayName": "Windows Development",
|
||||||
|
"description": "Windows development build with vcpkg and testing enabled",
|
||||||
|
"inherits": "debug",
|
||||||
|
"condition": {
|
||||||
|
"type": "equals",
|
||||||
|
"lhs": "${hostSystemName}",
|
||||||
|
"rhs": "Windows"
|
||||||
|
},
|
||||||
|
"generator": "Visual Studio 17 2022",
|
||||||
|
"architecture": "x64",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_TOOLCHAIN_FILE": "${sourceDir}/vcpkg/scripts/buildsystems/vcpkg.cmake",
|
||||||
|
"VCPKG_TARGET_TRIPLET": "x64-windows",
|
||||||
|
"VCPKG_MANIFEST_MODE": "ON",
|
||||||
|
"YAZE_BUILD_TESTS": "ON",
|
||||||
|
"YAZE_ENABLE_ROM_TESTS": "ON"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asan",
|
||||||
|
"displayName": "AddressSanitizer",
|
||||||
|
"description": "Debug build with AddressSanitizer",
|
||||||
|
"inherits": "debug",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer -g",
|
||||||
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer -g",
|
||||||
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "coverage",
|
||||||
|
"displayName": "Code Coverage",
|
||||||
|
"description": "Debug build with code coverage",
|
||||||
|
"inherits": "debug",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_CXX_FLAGS": "--coverage -g -O0",
|
||||||
|
"CMAKE_C_FLAGS": "--coverage -g -O0",
|
||||||
|
"CMAKE_EXE_LINKER_FLAGS": "--coverage"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"configurePreset": "default",
|
||||||
|
"displayName": "Default Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"configurePreset": "debug",
|
||||||
|
"displayName": "Debug Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"configurePreset": "release",
|
||||||
|
"displayName": "Release Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"configurePreset": "dev",
|
||||||
|
"displayName": "Development Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-dev",
|
||||||
|
"configurePreset": "macos-dev",
|
||||||
|
"displayName": "macOS Development Build (ARM64)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ci",
|
||||||
|
"configurePreset": "ci",
|
||||||
|
"displayName": "CI Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-debug",
|
||||||
|
"configurePreset": "macos-debug",
|
||||||
|
"displayName": "macOS Debug Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-release",
|
||||||
|
"configurePreset": "macos-release",
|
||||||
|
"displayName": "macOS Release Build (ARM64)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-debug-universal",
|
||||||
|
"configurePreset": "macos-debug-universal",
|
||||||
|
"displayName": "macOS Debug Build (Universal)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-release-universal",
|
||||||
|
"configurePreset": "macos-release-universal",
|
||||||
|
"displayName": "macOS Release Build (Universal)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fast",
|
||||||
|
"configurePreset": "debug",
|
||||||
|
"displayName": "Fast Debug Build",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-debug",
|
||||||
|
"configurePreset": "windows-debug",
|
||||||
|
"displayName": "Windows Debug Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-release",
|
||||||
|
"configurePreset": "windows-release",
|
||||||
|
"displayName": "Windows Release Build"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "windows-dev",
|
||||||
|
"configurePreset": "windows-dev",
|
||||||
|
"displayName": "Windows Development Build"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"testPresets": [
|
||||||
|
{
|
||||||
|
"name": "stable",
|
||||||
|
"configurePreset": "default",
|
||||||
|
"displayName": "Stable Tests (Release Ready)",
|
||||||
|
"execution": {
|
||||||
|
"noTestsAction": "error",
|
||||||
|
"stopOnFailure": true
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"include": {
|
||||||
|
"label": "STABLE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dev",
|
||||||
|
"configurePreset": "dev",
|
||||||
|
"displayName": "Development Tests (with ROM)",
|
||||||
|
"execution": {
|
||||||
|
"noTestsAction": "error",
|
||||||
|
"stopOnFailure": false
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"exclude": {
|
||||||
|
"label": "EXPERIMENTAL"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ci",
|
||||||
|
"configurePreset": "ci",
|
||||||
|
"displayName": "CI Tests (stable only)",
|
||||||
|
"execution": {
|
||||||
|
"noTestsAction": "error",
|
||||||
|
"stopOnFailure": true
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"include": {
|
||||||
|
"label": "STABLE"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "experimental",
|
||||||
|
"configurePreset": "debug",
|
||||||
|
"displayName": "Experimental Tests",
|
||||||
|
"execution": {
|
||||||
|
"noTestsAction": "ignore",
|
||||||
|
"stopOnFailure": false
|
||||||
|
},
|
||||||
|
"filter": {
|
||||||
|
"include": {
|
||||||
|
"label": "EXPERIMENTAL"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "asar-only",
|
||||||
|
"configurePreset": "default",
|
||||||
|
"displayName": "Asar Tests Only",
|
||||||
|
"filter": {
|
||||||
|
"include": {
|
||||||
|
"name": "*Asar*"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "unit-only",
|
||||||
|
"configurePreset": "default",
|
||||||
|
"displayName": "Unit Tests Only",
|
||||||
|
"filter": {
|
||||||
|
"include": {
|
||||||
|
"label": "UNIT_TEST"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packagePresets": [
|
||||||
|
{
|
||||||
|
"name": "default",
|
||||||
|
"configurePreset": "release",
|
||||||
|
"displayName": "Default Package"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos",
|
||||||
|
"configurePreset": "macos-release",
|
||||||
|
"displayName": "macOS Package (ARM64)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "macos-universal",
|
||||||
|
"configurePreset": "macos-release-universal",
|
||||||
|
"displayName": "macOS Package (Universal)"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"workflowPresets": [
|
||||||
|
{
|
||||||
|
"name": "dev-workflow",
|
||||||
|
"displayName": "Development Workflow",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "configure",
|
||||||
|
"name": "dev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "build",
|
||||||
|
"name": "dev"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test",
|
||||||
|
"name": "dev"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ci-workflow",
|
||||||
|
"displayName": "CI Workflow",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "configure",
|
||||||
|
"name": "ci"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "build",
|
||||||
|
"name": "ci"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test",
|
||||||
|
"name": "ci"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release-workflow",
|
||||||
|
"displayName": "Release Workflow",
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "configure",
|
||||||
|
"name": "macos-release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "build",
|
||||||
|
"name": "macos-release"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "package",
|
||||||
|
"name": "macos"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
6
LICENSE
6
LICENSE
@@ -1,4 +1,4 @@
|
|||||||
Copyright (C) 2022 Justin Scofield
|
Copyright (C) 2024 Justin Scofield
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -13,3 +13,7 @@ GNU General Public License for more details.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Dependencies:
|
||||||
|
- SDL2 <https://www.libsdl.org/license.php>
|
||||||
|
- ImGui <https://github.com/ocornut/imgui/blob/master/LICENSE.txt>
|
||||||
|
- Abseil <https://github.com/abseil/abseil-cpp/blob/master/LICENSE>
|
||||||
140
README.md
140
README.md
@@ -1,38 +1,134 @@
|
|||||||
# Yet Another Zelda3 Editor
|
# YAZE - Yet Another Zelda3 Editor
|
||||||
|
|
||||||
- Platform: Windows, macOS, GNU/Linux
|
A modern, cross-platform editor for The Legend of Zelda: A Link to the Past ROM hacking, built with C++23 and featuring complete Asar 65816 assembler integration.
|
||||||
- Dependencies: SDL2, ImGui
|
|
||||||
|
|
||||||
## Description
|
[](https://github.com/scawful/yaze/actions)
|
||||||
|
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||||
|
|
||||||
General purpose editor for The Legend of Zelda: A Link to the Past for the Super Nintendo.
|
## Version 0.3.1 - Release
|
||||||
|
|
||||||
Takes heavy inspiration from ALTTP community efforts such as [Hyrule Magic](https://www.romhacking.net/utilities/200/) and [ZScream](https://github.com/Zarby89/ZScreamDungeon)
|
#### Asar 65816 Assembler Integration
|
||||||
|
- **Cross-platform ROM patching** with assembly code support
|
||||||
|
- **Symbol extraction** with addresses and opcodes from assembly files
|
||||||
|
- **Assembly validation** with comprehensive error reporting
|
||||||
|
- **Modern C++ API** with safe memory management
|
||||||
|
|
||||||
Building and installation
|
#### ZSCustomOverworld v3
|
||||||
-------------------------
|
- **Enhanced overworld editing** capabilities
|
||||||
[CMake](http://www.cmake.org "CMake") is required to build yaze
|
- **Advanced map properties** and metadata support
|
||||||
|
- **Custom graphics support** and tile management
|
||||||
|
- **Improved compatibility** with existing projects
|
||||||
|
|
||||||
1. Clone the repository
|
#### Advanced Features
|
||||||
|
- **Theme Management**: Complete theme system with 5+ built-in themes and custom theme editor
|
||||||
|
- **Multi-Session Support**: Work with multiple ROMs simultaneously in docked workspace
|
||||||
|
- **Enhanced Welcome Screen**: Themed interface with quick access to all editors
|
||||||
|
- **Message Editing**: Enhanced text editing interface with real-time preview
|
||||||
|
- **GUI Docking**: Flexible workspace management with customizable layouts
|
||||||
|
- **Modern CLI**: Enhanced z3ed tool with interactive TUI and subcommands
|
||||||
|
- **Cross-Platform**: Full support for Windows, macOS, and Linux
|
||||||
|
|
||||||
git clone --recurse-submodules https://github.com/scawful/yaze.git
|
### 🛠️ Technical Improvements
|
||||||
|
- **Modern CMake 3.16+**: Target-based configuration and build system
|
||||||
|
- **CMakePresets**: Development workflow presets for better productivity
|
||||||
|
- **Cross-platform CI/CD**: Automated builds and testing for all platforms
|
||||||
|
- **Professional packaging**: NSIS, DMG, and DEB/RPM installers
|
||||||
|
- **Enhanced testing**: ROM-dependent test separation for CI compatibility
|
||||||
|
|
||||||
2. Create the build directory and configuration
|
## Quick Start
|
||||||
|
|
||||||
cmake -S . -B build
|
### Build
|
||||||
|
```bash
|
||||||
|
# Clone with submodules
|
||||||
|
git clone --recursive https://github.com/scawful/yaze.git
|
||||||
|
cd yaze
|
||||||
|
|
||||||
3. Build and run.
|
# Build with CMake
|
||||||
|
cmake --preset debug # macOS
|
||||||
|
cmake -B build && cmake --build build # Linux/Windows
|
||||||
|
```
|
||||||
|
|
||||||
cmake --build build
|
### Applications
|
||||||
|
- **yaze**: Complete GUI editor for Zelda 3 ROM hacking
|
||||||
|
- **z3ed**: Command-line tool with interactive interface
|
||||||
|
- **yaze_test**: Comprehensive test suite for development
|
||||||
|
|
||||||
License
|
## Usage
|
||||||
--------
|
|
||||||
YAZE is distributed under the [GNU GPLv3](https://www.gnu.org/licenses/gpl-3.0.txt) license.
|
|
||||||
|
|
||||||
SDL2, ImGUI and Abseil are subject to respective licenses.
|
### GUI Editor
|
||||||
|
Launch the main application to edit Zelda 3 ROMs:
|
||||||
|
- Load ROM files using native file dialogs
|
||||||
|
- Edit overworld maps, dungeons, sprites, and graphics
|
||||||
|
- Apply assembly patches with integrated Asar support
|
||||||
|
- Export modifications as patches or modified ROMs
|
||||||
|
|
||||||
Screenshots
|
### Command Line Tool
|
||||||
--------
|
```bash
|
||||||

|
# Apply assembly patch
|
||||||
|
z3ed asar patch.asm --rom=zelda3.sfc
|
||||||
|
|
||||||
|
# Extract symbols from assembly
|
||||||
|
z3ed extract patch.asm
|
||||||
|
|
||||||
|
# Interactive mode
|
||||||
|
z3ed --tui
|
||||||
|
```
|
||||||
|
|
||||||
|
### C++ API
|
||||||
|
```cpp
|
||||||
|
#include "yaze.h"
|
||||||
|
|
||||||
|
// Load ROM and apply patch
|
||||||
|
yaze_project_t* project = yaze_load_project("zelda3.sfc");
|
||||||
|
yaze_apply_asar_patch(project, "patch.asm");
|
||||||
|
yaze_save_project(project, "modified.sfc");
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
- [Getting Started](docs/01-getting-started.md) - Setup and basic usage
|
||||||
|
- [Build Instructions](docs/02-build-instructions.md) - Building from source
|
||||||
|
- [API Reference](docs/04-api-reference.md) - Programming interface
|
||||||
|
- [Contributing](docs/B1-contributing.md) - Development guidelines
|
||||||
|
|
||||||
|
**[Complete Documentation](docs/index.md)**
|
||||||
|
|
||||||
|
## Supported Platforms
|
||||||
|
|
||||||
|
- **Windows** (MSVC 2019+, MinGW)
|
||||||
|
- **macOS** (Intel and Apple Silicon)
|
||||||
|
- **Linux** (GCC 13+, Clang 16+)
|
||||||
|
## ROM Compatibility
|
||||||
|
|
||||||
|
- Original Zelda 3 ROMs (US/Japan versions)
|
||||||
|
- ZSCustomOverworld v2/v3 enhanced overworld features
|
||||||
|
- Community ROM hacks and modifications
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
See [Contributing Guide](docs/B1-contributing.md) for development guidelines.
|
||||||
|
|
||||||
|
**Community**: [Oracle of Secrets Discord](https://discord.gg/MBFkMTPEmk)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
GNU GPL v3 - See [LICENSE](LICENSE) for details.
|
||||||
|
|
||||||
|
## 🙏 Acknowledgments
|
||||||
|
|
||||||
|
Takes inspiration from:
|
||||||
|
- [Hyrule Magic](https://www.romhacking.net/utilities/200/) - Original Zelda 3 editor
|
||||||
|
- [ZScream](https://github.com/Zarby89/ZScreamDungeon) - Dungeon editing capabilities
|
||||||
|
- [Asar](https://github.com/RPGHacker/asar) - 65816 assembler integration
|
||||||
|
|
||||||
|
## 📸 Screenshots
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Ready to hack Zelda 3? [Get started now!](docs/01-getting-started.md)**
|
||||||
3563
assets/asm/ZSCustomOverworld.asm
Normal file
3563
assets/asm/ZSCustomOverworld.asm
Normal file
File diff suppressed because it is too large
Load Diff
5770
assets/asm/ZSCustomOverworld_v3.asm
Normal file
5770
assets/asm/ZSCustomOverworld_v3.asm
Normal file
File diff suppressed because it is too large
Load Diff
Submodule assets/asm/alttp-hacker-workspace updated: ea81eb3425...2520fb70c3
1
assets/asm/usdasm
Submodule
1
assets/asm/usdasm
Submodule
Submodule assets/asm/usdasm added at d53311a54a
22
assets/asm/yaze.asm
Normal file
22
assets/asm/yaze.asm
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
; =========================================================
|
||||||
|
; yaze custom assembly code
|
||||||
|
; =========================================================
|
||||||
|
|
||||||
|
namespace yaze
|
||||||
|
{
|
||||||
|
|
||||||
|
!YAZE_CUSTOM_MOSAIC = 1
|
||||||
|
|
||||||
|
|
||||||
|
if !YAZE_CUSTOM_MOSAIC != 0
|
||||||
|
incsrc "mosaic_change.asm"
|
||||||
|
endif
|
||||||
|
|
||||||
|
!ZS_CUSTOM_OVERWORLD = 1
|
||||||
|
|
||||||
|
if !ZS_CUSTOM_OVERWORLD != 0
|
||||||
|
incsrc "ZSCustomOverworld_v3.asm"
|
||||||
|
endif
|
||||||
|
|
||||||
|
}
|
||||||
|
namespace off
|
||||||
BIN
assets/font/IBMPlexSansJP-Bold.ttf
Normal file
BIN
assets/font/IBMPlexSansJP-Bold.ttf
Normal file
Binary file not shown.
BIN
assets/font/NotoSansJP.ttf
Normal file
BIN
assets/font/NotoSansJP.ttf
Normal file
Binary file not shown.
62
assets/themes/cyberpunk.theme
Normal file
62
assets/themes/cyberpunk.theme
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Cyberpunk Theme
|
||||||
|
# Neon-inspired futuristic theme
|
||||||
|
name=Cyberpunk
|
||||||
|
description=Neon-inspired futuristic theme
|
||||||
|
author=YAZE Team
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Primary colors (neon cyberpunk)
|
||||||
|
primary=255,20,147,255
|
||||||
|
secondary=0,255,255,255
|
||||||
|
accent=255,0,128,255
|
||||||
|
background=10,10,20,255
|
||||||
|
surface=20,20,40,255
|
||||||
|
|
||||||
|
# Status colors
|
||||||
|
error=255,50,100,255
|
||||||
|
warning=255,255,0,255
|
||||||
|
success=0,255,100,255
|
||||||
|
info=100,200,255,255
|
||||||
|
|
||||||
|
# Text colors
|
||||||
|
text_primary=255,255,255,255
|
||||||
|
text_secondary=200,200,255,255
|
||||||
|
text_disabled=100,100,150,255
|
||||||
|
|
||||||
|
# Window colors
|
||||||
|
window_bg=15,15,30,240
|
||||||
|
child_bg=10,10,25,200
|
||||||
|
popup_bg=20,20,40,250
|
||||||
|
|
||||||
|
# Interactive elements
|
||||||
|
button=40,20,60,255
|
||||||
|
button_hovered=120,20,120,255
|
||||||
|
button_active=160,40,160,255
|
||||||
|
frame_bg=30,30,50,255
|
||||||
|
frame_bg_hovered=40,40,70,255
|
||||||
|
frame_bg_active=60,20,80,255
|
||||||
|
|
||||||
|
# Navigation
|
||||||
|
header=30,10,50,255
|
||||||
|
header_hovered=80,20,100,255
|
||||||
|
header_active=120,40,140,255
|
||||||
|
tab=25,15,45,255
|
||||||
|
tab_hovered=60,30,80,255
|
||||||
|
tab_active=100,20,120,255
|
||||||
|
menu_bar_bg=20,10,40,255
|
||||||
|
title_bg=25,15,45,255
|
||||||
|
title_bg_active=30,10,50,255
|
||||||
|
title_bg_collapsed=25,15,45,255
|
||||||
|
|
||||||
|
[style]
|
||||||
|
window_rounding=10.0
|
||||||
|
frame_rounding=8.0
|
||||||
|
scrollbar_rounding=10.0
|
||||||
|
grab_rounding=6.0
|
||||||
|
tab_rounding=6.0
|
||||||
|
window_border_size=1.0
|
||||||
|
frame_border_size=1.0
|
||||||
|
enable_animations=true
|
||||||
|
enable_glow_effects=true
|
||||||
|
animation_speed=1.5
|
||||||
73
assets/themes/forest.theme
Normal file
73
assets/themes/forest.theme
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Forest Theme
|
||||||
|
# Enhanced forest theme with better readability
|
||||||
|
name=Forest
|
||||||
|
description=Deep forest theme with enhanced readability
|
||||||
|
author=YAZE Team
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Primary colors (enhanced forest with better contrast)
|
||||||
|
primary=100,180,120,255 # Brighter forest green
|
||||||
|
secondary=70,130,85,255 # Mid forest green
|
||||||
|
accent=130,220,150,255 # Light accent green
|
||||||
|
background=15,25,15,255 # Darker background for contrast
|
||||||
|
surface=25,35,25,255
|
||||||
|
|
||||||
|
# Status colors
|
||||||
|
error=255,120,120,255
|
||||||
|
warning=255,220,120,255
|
||||||
|
success=100,180,120,255
|
||||||
|
info=120,200,180,255
|
||||||
|
|
||||||
|
# Text colors (enhanced for readability)
|
||||||
|
text_primary=250,255,250,255 # Very light for contrast
|
||||||
|
text_secondary=220,240,220,255 # Light green tint
|
||||||
|
text_disabled=150,170,150,255 # Brighter disabled text
|
||||||
|
|
||||||
|
# Window colors (better contrast)
|
||||||
|
window_bg=20,30,20,240
|
||||||
|
child_bg=15,25,15,200
|
||||||
|
popup_bg=25,35,25,250
|
||||||
|
|
||||||
|
# Interactive elements (better visibility)
|
||||||
|
button=70,110,80,255
|
||||||
|
button_hovered=100,150,115,255
|
||||||
|
button_active=130,180,145,255
|
||||||
|
frame_bg=40,60,45,200
|
||||||
|
frame_bg_hovered=55,80,60,220
|
||||||
|
frame_bg_active=70,110,80,240
|
||||||
|
|
||||||
|
# Navigation (better contrast)
|
||||||
|
header=55,85,60,255
|
||||||
|
header_hovered=100,150,115,255
|
||||||
|
header_active=130,180,145,255
|
||||||
|
tab=45,75,50,255
|
||||||
|
tab_hovered=70,110,80,255
|
||||||
|
tab_active=100,150,115,255
|
||||||
|
menu_bar_bg=40,70,45,255
|
||||||
|
title_bg=50,80,55,255
|
||||||
|
title_bg_active=55,85,60,255
|
||||||
|
title_bg_collapsed=45,75,50,255
|
||||||
|
|
||||||
|
# Separators (better visibility)
|
||||||
|
separator=120,160,130,180
|
||||||
|
separator_hovered=150,200,160,220
|
||||||
|
separator_active=180,240,190,255
|
||||||
|
|
||||||
|
# Scrollbars (better visibility)
|
||||||
|
scrollbar_bg=40,60,45,180
|
||||||
|
scrollbar_grab=80,120,90,200
|
||||||
|
scrollbar_grab_hovered=100,150,115,230
|
||||||
|
scrollbar_grab_active=130,180,145,255
|
||||||
|
|
||||||
|
[style]
|
||||||
|
window_rounding=6.0
|
||||||
|
frame_rounding=4.0
|
||||||
|
scrollbar_rounding=6.0
|
||||||
|
grab_rounding=3.0
|
||||||
|
tab_rounding=3.0
|
||||||
|
window_border_size=0.0
|
||||||
|
frame_border_size=0.0
|
||||||
|
enable_animations=true
|
||||||
|
enable_glow_effects=false
|
||||||
|
animation_speed=1.0
|
||||||
73
assets/themes/midnight.theme
Normal file
73
assets/themes/midnight.theme
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
# Midnight Theme
|
||||||
|
# Enhanced midnight theme with better readability
|
||||||
|
name=Midnight
|
||||||
|
description=Deep blue midnight theme with enhanced readability
|
||||||
|
author=YAZE Team
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Primary colors (enhanced midnight with better contrast)
|
||||||
|
primary=100,160,230,255 # Brighter blue
|
||||||
|
secondary=70,120,180,255 # Mid blue
|
||||||
|
accent=140,200,255,255 # Light blue accent
|
||||||
|
background=10,15,25,255 # Darker background for contrast
|
||||||
|
surface=20,25,35,255
|
||||||
|
|
||||||
|
# Status colors
|
||||||
|
error=255,120,120,255
|
||||||
|
warning=255,220,120,255
|
||||||
|
success=120,255,180,255
|
||||||
|
info=140,200,255,255
|
||||||
|
|
||||||
|
# Text colors (enhanced for readability)
|
||||||
|
text_primary=245,250,255,255 # Very light blue-white
|
||||||
|
text_secondary=200,220,240,255 # Light blue tint
|
||||||
|
text_disabled=140,160,180,255 # Brighter disabled text
|
||||||
|
|
||||||
|
# Window colors (better contrast)
|
||||||
|
window_bg=15,20,30,240
|
||||||
|
child_bg=10,15,25,200
|
||||||
|
popup_bg=20,25,35,250
|
||||||
|
|
||||||
|
# Interactive elements (better visibility)
|
||||||
|
button=50,80,120,255
|
||||||
|
button_hovered=80,120,160,255
|
||||||
|
button_active=110,150,190,255
|
||||||
|
frame_bg=30,45,65,200
|
||||||
|
frame_bg_hovered=40,60,85,220
|
||||||
|
frame_bg_active=60,90,130,240
|
||||||
|
|
||||||
|
# Navigation (better contrast)
|
||||||
|
header=40,65,100,255
|
||||||
|
header_hovered=70,110,150,255
|
||||||
|
header_active=100,140,180,255
|
||||||
|
tab=30,55,90,255
|
||||||
|
tab_hovered=50,80,120,255
|
||||||
|
tab_active=70,110,150,255
|
||||||
|
menu_bar_bg=25,50,85,255
|
||||||
|
title_bg=35,60,95,255
|
||||||
|
title_bg_active=40,65,100,255
|
||||||
|
title_bg_collapsed=30,55,90,255
|
||||||
|
|
||||||
|
# Separators (better visibility)
|
||||||
|
separator=100,140,180,180
|
||||||
|
separator_hovered=130,170,210,220
|
||||||
|
separator_active=160,200,240,255
|
||||||
|
|
||||||
|
# Scrollbars (better visibility)
|
||||||
|
scrollbar_bg=30,45,65,180
|
||||||
|
scrollbar_grab=70,110,150,200
|
||||||
|
scrollbar_grab_hovered=100,140,180,230
|
||||||
|
scrollbar_grab_active=130,170,210,255
|
||||||
|
|
||||||
|
[style]
|
||||||
|
window_rounding=8.0
|
||||||
|
frame_rounding=6.0
|
||||||
|
scrollbar_rounding=8.0
|
||||||
|
grab_rounding=4.0
|
||||||
|
tab_rounding=6.0
|
||||||
|
window_border_size=0.0
|
||||||
|
frame_border_size=0.0
|
||||||
|
enable_animations=true
|
||||||
|
enable_glow_effects=true
|
||||||
|
animation_speed=1.2
|
||||||
62
assets/themes/sunset.theme
Normal file
62
assets/themes/sunset.theme
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Sunset Theme
|
||||||
|
# Warm orange and purple sunset theme
|
||||||
|
name=Sunset
|
||||||
|
description=Warm orange and purple sunset theme
|
||||||
|
author=YAZE Team
|
||||||
|
version=1.0
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Primary colors (sunset)
|
||||||
|
primary=255,140,60,255
|
||||||
|
secondary=200,100,150,255
|
||||||
|
accent=255,180,100,255
|
||||||
|
background=30,20,35,255
|
||||||
|
surface=40,30,45,255
|
||||||
|
|
||||||
|
# Status colors
|
||||||
|
error=255,100,120,255
|
||||||
|
warning=255,200,100,255
|
||||||
|
success=150,255,150,255
|
||||||
|
info=150,200,255,255
|
||||||
|
|
||||||
|
# Text colors
|
||||||
|
text_primary=255,245,235,255
|
||||||
|
text_secondary=220,200,180,255
|
||||||
|
text_disabled=150,130,120,255
|
||||||
|
|
||||||
|
# Window colors
|
||||||
|
window_bg=35,25,40,240
|
||||||
|
child_bg=30,20,35,200
|
||||||
|
popup_bg=40,30,45,250
|
||||||
|
|
||||||
|
# Interactive elements
|
||||||
|
button=60,40,70,255
|
||||||
|
button_hovered=120,80,100,255
|
||||||
|
button_active=150,100,120,255
|
||||||
|
frame_bg=45,35,50,255
|
||||||
|
frame_bg_hovered=55,45,60,255
|
||||||
|
frame_bg_active=80,60,90,255
|
||||||
|
|
||||||
|
# Navigation
|
||||||
|
header=50,35,60,255
|
||||||
|
header_hovered=100,70,90,255
|
||||||
|
header_active=130,90,110,255
|
||||||
|
tab=40,30,50,255
|
||||||
|
tab_hovered=70,50,70,255
|
||||||
|
tab_active=100,70,90,255
|
||||||
|
menu_bar_bg=35,25,45,255
|
||||||
|
title_bg=40,30,50,255
|
||||||
|
title_bg_active=50,35,60,255
|
||||||
|
title_bg_collapsed=40,30,50,255
|
||||||
|
|
||||||
|
[style]
|
||||||
|
window_rounding=12.0
|
||||||
|
frame_rounding=8.0
|
||||||
|
scrollbar_rounding=12.0
|
||||||
|
grab_rounding=6.0
|
||||||
|
tab_rounding=8.0
|
||||||
|
window_border_size=0.0
|
||||||
|
frame_border_size=0.0
|
||||||
|
enable_animations=true
|
||||||
|
enable_glow_effects=false
|
||||||
|
animation_speed=1.0
|
||||||
115
assets/themes/yaze_tre.theme
Normal file
115
assets/themes/yaze_tre.theme
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
# YAZE Tre Theme - Enhanced Edition
|
||||||
|
# Premium theme resource edition with improved colors and contrast
|
||||||
|
name=YAZE Tre
|
||||||
|
description=Enhanced YAZE theme with improved readability and modern colors
|
||||||
|
author=YAZE Team
|
||||||
|
version=2.0
|
||||||
|
|
||||||
|
[colors]
|
||||||
|
# Primary colors (enhanced ALTTP colors with better contrast)
|
||||||
|
primary=105,135,105,255 # Brighter green for better visibility
|
||||||
|
secondary=85,110,85,255 # Mid-tone green with more saturation
|
||||||
|
accent=110,145,110,255 # Vibrant accent green for highlights
|
||||||
|
background=12,12,15,255 # Slightly blue-tinted dark background
|
||||||
|
surface=18,18,22,255 # Warmer surface color
|
||||||
|
|
||||||
|
# Status colors (enhanced for better visibility)
|
||||||
|
error=235,75,75,255 # Brighter red for better visibility
|
||||||
|
warning=255,200,50,255 # Warmer yellow-orange
|
||||||
|
success=105,135,105,255 # Match primary green
|
||||||
|
info=70,170,255,255 # Brighter blue
|
||||||
|
|
||||||
|
# Text colors (enhanced contrast)
|
||||||
|
text_primary=245,245,245,255 # Brighter white for better readability
|
||||||
|
text_secondary=200,200,200,255 # Higher contrast secondary text
|
||||||
|
text_disabled=140,140,140,255 # Slightly brighter disabled text
|
||||||
|
|
||||||
|
# Window colors (enhanced backgrounds)
|
||||||
|
window_bg=12,12,15,230 # Slightly blue-tinted with transparency
|
||||||
|
child_bg=0,0,0,0 # Transparent child backgrounds
|
||||||
|
popup_bg=20,20,25,240 # Warmer popup background
|
||||||
|
|
||||||
|
# Interactive elements (enhanced for better UX)
|
||||||
|
button=85,110,85,255 # Enhanced mid-green for better visibility
|
||||||
|
button_hovered=135,160,135,255 # Brighter hover state
|
||||||
|
button_active=105,135,105,255 # Active state matches primary
|
||||||
|
frame_bg=25,25,30,150 # Darker frames with transparency
|
||||||
|
frame_bg_hovered=85,110,85,120 # Green tint on hover
|
||||||
|
frame_bg_active=105,135,105,180 # Primary green when active
|
||||||
|
|
||||||
|
# Navigation (enhanced contrast)
|
||||||
|
header=55,75,55,255 # Slightly brighter header
|
||||||
|
header_hovered=105,135,105,255 # Primary green on hover
|
||||||
|
header_active=85,110,85,255 # Secondary green when active
|
||||||
|
tab=45,60,45,255 # Darker tab background
|
||||||
|
tab_hovered=85,110,85,255 # Secondary green on hover
|
||||||
|
tab_active=110,145,110,255 # Accent green for active tab
|
||||||
|
menu_bar_bg=55,75,55,255 # Match header background
|
||||||
|
title_bg=85,110,85,255 # Secondary green
|
||||||
|
title_bg_active=55,75,55,255 # Darker when active
|
||||||
|
title_bg_collapsed=85,110,85,255 # Secondary green when collapsed
|
||||||
|
|
||||||
|
# Borders and separators (exact from original)
|
||||||
|
border=92,115,92,255 # allttpLightGreen
|
||||||
|
border_shadow=0,0,0,0 # No shadow in original
|
||||||
|
separator=127,127,127,153 # 0.50f, 0.50f, 0.50f, 0.60f
|
||||||
|
separator_hovered=153,153,178,255 # 0.60f, 0.60f, 0.70f
|
||||||
|
separator_active=178,178,230,255 # 0.70f, 0.70f, 0.90f
|
||||||
|
|
||||||
|
# Scrollbars (exact from original)
|
||||||
|
scrollbar_bg=92,115,92,153 # 0.36f, 0.45f, 0.36f, 0.60f
|
||||||
|
scrollbar_grab=92,115,92,76 # 0.36f, 0.45f, 0.36f, 0.30f (exact)
|
||||||
|
scrollbar_grab_hovered=92,115,92,102 # 0.36f, 0.45f, 0.36f, 0.40f
|
||||||
|
scrollbar_grab_active=92,115,92,153 # 0.36f, 0.45f, 0.36f, 0.60f
|
||||||
|
|
||||||
|
# Resize grips (exact from original - these are light blue, not white!)
|
||||||
|
resize_grip=255,255,255,26 # 1.00f, 1.00f, 1.00f, 0.10f
|
||||||
|
resize_grip_hovered=199,209,255,153 # 0.78f, 0.82f, 1.00f, 0.60f (light blue!)
|
||||||
|
resize_grip_active=199,209,255,230 # 0.78f, 0.82f, 1.00f, 0.90f (light blue!)
|
||||||
|
|
||||||
|
# Additional controls (enhanced)
|
||||||
|
check_mark=245,245,245,200 # Brighter check marks for visibility
|
||||||
|
slider_grab=180,180,180,120 # More visible slider grab
|
||||||
|
slider_grab_active=110,145,110,200 # Accent color when active
|
||||||
|
|
||||||
|
# Table colors (enhanced)
|
||||||
|
table_header_bg=55,75,55,255 # Slightly brighter header
|
||||||
|
table_border_strong=85,110,85,255 # Secondary green borders
|
||||||
|
table_border_light=70,70,75,255 # Better contrast light borders
|
||||||
|
table_row_bg=0,0,0,0 # Transparent
|
||||||
|
table_row_bg_alt=255,255,255,25 # Slightly more visible alternating rows
|
||||||
|
|
||||||
|
# Link colors (high contrast for better visibility)
|
||||||
|
text_link=120,200,255,255 # Bright blue for links - high contrast against dark backgrounds
|
||||||
|
|
||||||
|
# Navigation and special elements
|
||||||
|
input_text_cursor=245,245,245,255
|
||||||
|
nav_cursor=110,145,110,255
|
||||||
|
nav_windowing_highlight=110,145,110,255
|
||||||
|
nav_windowing_dim_bg=0,0,0,128
|
||||||
|
modal_window_dim_bg=0,0,0,89
|
||||||
|
text_selected_bg=89,119,89,89
|
||||||
|
drag_drop_target=110,145,110,255
|
||||||
|
docking_preview=92,115,92,180
|
||||||
|
docking_empty_bg=46,66,46,255
|
||||||
|
|
||||||
|
# Tree lines
|
||||||
|
tree_lines=127,127,127,153
|
||||||
|
|
||||||
|
# Tab variations for unfocused windows
|
||||||
|
tab_dimmed=37,52,37,255
|
||||||
|
tab_dimmed_selected=62,83,62,255
|
||||||
|
tab_dimmed_selected_overline=110,145,110,255
|
||||||
|
tab_selected_overline=110,145,110,255
|
||||||
|
|
||||||
|
[style]
|
||||||
|
window_rounding=0.0
|
||||||
|
frame_rounding=5.0
|
||||||
|
scrollbar_rounding=5.0
|
||||||
|
grab_rounding=3.0
|
||||||
|
tab_rounding=0.0
|
||||||
|
window_border_size=0.0
|
||||||
|
frame_border_size=0.0
|
||||||
|
enable_animations=true
|
||||||
|
enable_glow_effects=false
|
||||||
|
animation_speed=1.0
|
||||||
BIN
assets/yaze.icns
Normal file
BIN
assets/yaze.icns
Normal file
Binary file not shown.
BIN
assets/yaze.png
Normal file
BIN
assets/yaze.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.4 KiB |
@@ -1,11 +1,41 @@
|
|||||||
|
if (MINGW OR WIN32)
|
||||||
|
add_subdirectory(src/lib/abseil-cpp)
|
||||||
|
elseif(YAZE_MINIMAL_BUILD)
|
||||||
|
# For CI builds, always use submodule to avoid dependency issues
|
||||||
|
add_subdirectory(src/lib/abseil-cpp)
|
||||||
|
else()
|
||||||
|
# Try system package first, fallback to submodule
|
||||||
|
find_package(absl QUIET)
|
||||||
|
if(NOT absl_FOUND)
|
||||||
|
message(STATUS "System Abseil not found, using submodule")
|
||||||
|
add_subdirectory(src/lib/abseil-cpp)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
set(ABSL_PROPAGATE_CXX_STD ON)
|
set(ABSL_PROPAGATE_CXX_STD ON)
|
||||||
set(ABSL_CXX_STANDARD 17)
|
set(ABSL_CXX_STANDARD 23)
|
||||||
set(ABSL_USE_GOOGLETEST_HEAD ON)
|
set(ABSL_USE_GOOGLETEST_HEAD ON)
|
||||||
set(ABSL_ENABLE_INSTALL ON)
|
set(ABSL_ENABLE_INSTALL ON)
|
||||||
|
|
||||||
|
# Silence C++23 deprecation warnings for Abseil int128
|
||||||
|
if(MSVC)
|
||||||
|
add_definitions(-DSILENCE_CXX23_DEPRECATIONS)
|
||||||
|
else()
|
||||||
|
add_definitions(-D_SILENCE_CXX23_DEPRECATION_WARNING)
|
||||||
|
endif()
|
||||||
|
# Define base Abseil targets
|
||||||
set(
|
set(
|
||||||
ABSL_TARGETS
|
ABSL_TARGETS
|
||||||
absl::strings
|
absl::strings
|
||||||
|
absl::str_format
|
||||||
absl::flags
|
absl::flags
|
||||||
|
absl::flags_parse
|
||||||
|
absl::flags_usage
|
||||||
|
absl::flags_commandlineflag
|
||||||
|
absl::flags_marshalling
|
||||||
|
absl::flags_private_handle_accessor
|
||||||
|
absl::flags_program_name
|
||||||
|
absl::flags_config
|
||||||
|
absl::flags_reflection
|
||||||
absl::status
|
absl::status
|
||||||
absl::statusor
|
absl::statusor
|
||||||
absl::examine_stack
|
absl::examine_stack
|
||||||
@@ -13,7 +43,22 @@ set(
|
|||||||
absl::base
|
absl::base
|
||||||
absl::config
|
absl::config
|
||||||
absl::core_headers
|
absl::core_headers
|
||||||
absl::raw_logging_internal
|
|
||||||
absl::failure_signal_handler
|
absl::failure_signal_handler
|
||||||
absl::flat_hash_map
|
absl::flat_hash_map
|
||||||
|
absl::cord
|
||||||
|
absl::hash
|
||||||
|
absl::synchronization
|
||||||
|
absl::time
|
||||||
|
absl::symbolize
|
||||||
|
absl::container_memory
|
||||||
|
absl::memory
|
||||||
|
absl::utility
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# Add int128 only on non-Windows platforms to avoid C++23 deprecation issues
|
||||||
|
if(NOT WIN32)
|
||||||
|
list(APPEND ABSL_TARGETS absl::int128)
|
||||||
|
message(STATUS "Including absl::int128 (non-Windows platform)")
|
||||||
|
else()
|
||||||
|
message(STATUS "Excluding absl::int128 on Windows to avoid C++23 deprecation issues")
|
||||||
|
endif()
|
||||||
|
|||||||
119
cmake/asar.cmake
119
cmake/asar.cmake
@@ -1,33 +1,94 @@
|
|||||||
get_target_property(ASAR_INCLUDE_DIR asar-static INCLUDE_DIRECTORIES)
|
# Modern Asar 65816 Assembler Integration
|
||||||
target_include_directories(asar-static PRIVATE ${ASAR_INCLUDE_DIR})
|
# Improved cross-platform support for macOS, Linux, and Windows
|
||||||
set(ASAR_GEN_EXE OFF)
|
|
||||||
set(ASAR_GEN_DLL ON)
|
|
||||||
set(ASAR_GEN_LIB ON)
|
|
||||||
set(ASAR_GEN_EXE_TEST OFF)
|
|
||||||
set(ASAR_GEN_DLL_TEST OFF)
|
|
||||||
|
|
||||||
set(ASAR_STATIC_SRC
|
# Configure Asar build options
|
||||||
"../src/lib/asar/src/asar/interface-lib.cpp"
|
set(ASAR_GEN_EXE OFF CACHE BOOL "Build Asar standalone executable")
|
||||||
"../src/lib/asar/src/asar/addr2line.cpp"
|
set(ASAR_GEN_DLL ON CACHE BOOL "Build Asar shared library")
|
||||||
"../src/lib/asar/src/asar/arch-65816.cpp"
|
set(ASAR_GEN_LIB ON CACHE BOOL "Build Asar static library")
|
||||||
"../src/lib/asar/src/asar/arch-spc700.cpp"
|
set(ASAR_GEN_EXE_TEST OFF CACHE BOOL "Build Asar executable tests")
|
||||||
"../src/lib/asar/src/asar/arch-superfx.cpp"
|
set(ASAR_GEN_DLL_TEST OFF CACHE BOOL "Build Asar DLL tests")
|
||||||
"../src/lib/asar/src/asar/assembleblock.cpp"
|
|
||||||
"../src/lib/asar/src/asar/crc32.cpp"
|
|
||||||
"../src/lib/asar/src/asar/libcon.cpp"
|
|
||||||
"../src/lib/asar/src/asar/libsmw.cpp"
|
|
||||||
"../src/lib/asar/src/asar/libstr.cpp"
|
|
||||||
"../src/lib/asar/src/asar/macro.cpp"
|
|
||||||
"../src/lib/asar/src/asar/main.cpp"
|
|
||||||
"../src/lib/asar/src/asar/asar_math.cpp"
|
|
||||||
"../src/lib/asar/src/asar/virtualfile.cpp"
|
|
||||||
"../src/lib/asar/src/asar/warnings.cpp"
|
|
||||||
"../src/lib/asar/src/asar/errors.cpp"
|
|
||||||
"../src/lib/asar/src/asar/platform/file-helpers.cpp"
|
|
||||||
)
|
|
||||||
|
|
||||||
if(WIN32 OR MINGW)
|
# Set Asar source directory
|
||||||
list(APPEND ASAR_STATIC_SRC "../src/lib/asar/src/asar/platform/windows/file-helpers-win32.cpp")
|
set(ASAR_SRC_DIR "${CMAKE_SOURCE_DIR}/src/lib/asar/src")
|
||||||
|
|
||||||
|
# Add Asar as subdirectory
|
||||||
|
add_subdirectory(${ASAR_SRC_DIR} EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# Create modern CMake target for Asar integration
|
||||||
|
if(TARGET asar-static)
|
||||||
|
# Ensure asar-static is available and properly configured
|
||||||
|
set_target_properties(asar-static PROPERTIES
|
||||||
|
CXX_STANDARD 17
|
||||||
|
CXX_STANDARD_REQUIRED ON
|
||||||
|
POSITION_INDEPENDENT_CODE ON
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set platform-specific definitions for Asar
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(asar-static PRIVATE
|
||||||
|
windows
|
||||||
|
strncasecmp=_strnicmp
|
||||||
|
strcasecmp=_stricmp
|
||||||
|
_CRT_SECURE_NO_WARNINGS
|
||||||
|
_CRT_NONSTDC_NO_WARNINGS
|
||||||
|
)
|
||||||
|
elseif(UNIX AND NOT APPLE)
|
||||||
|
target_compile_definitions(asar-static PRIVATE
|
||||||
|
linux
|
||||||
|
stricmp=strcasecmp
|
||||||
|
)
|
||||||
|
elseif(APPLE)
|
||||||
|
target_compile_definitions(asar-static PRIVATE
|
||||||
|
MACOS
|
||||||
|
stricmp=strcasecmp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Add include directories
|
||||||
|
target_include_directories(asar-static PUBLIC
|
||||||
|
$<BUILD_INTERFACE:${ASAR_SRC_DIR}>
|
||||||
|
$<BUILD_INTERFACE:${ASAR_SRC_DIR}/asar>
|
||||||
|
$<BUILD_INTERFACE:${ASAR_SRC_DIR}/asar-dll-bindings/c>
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create alias for easier linking
|
||||||
|
add_library(yaze::asar ALIAS asar-static)
|
||||||
|
|
||||||
|
# Export Asar variables for use in other parts of the build
|
||||||
|
set(ASAR_FOUND TRUE CACHE BOOL "Asar library found")
|
||||||
|
set(ASAR_LIBRARIES asar-static CACHE STRING "Asar library target")
|
||||||
|
set(ASAR_INCLUDE_DIRS
|
||||||
|
"${ASAR_SRC_DIR}"
|
||||||
|
"${ASAR_SRC_DIR}/asar"
|
||||||
|
"${ASAR_SRC_DIR}/asar-dll-bindings/c"
|
||||||
|
CACHE STRING "Asar include directories"
|
||||||
|
)
|
||||||
|
|
||||||
|
message(STATUS "Asar 65816 assembler integration configured successfully")
|
||||||
else()
|
else()
|
||||||
list(APPEND ASAR_STATIC_SRC "../src/lib/asar/src/asar/platform/linux/file-helpers-linux.cpp")
|
message(WARNING "Failed to configure Asar static library target")
|
||||||
|
set(ASAR_FOUND FALSE CACHE BOOL "Asar library found")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Function to add Asar patching capabilities to a target
|
||||||
|
function(yaze_add_asar_support target_name)
|
||||||
|
if(ASAR_FOUND)
|
||||||
|
target_link_libraries(${target_name} PRIVATE yaze::asar)
|
||||||
|
target_include_directories(${target_name} PRIVATE ${ASAR_INCLUDE_DIRS})
|
||||||
|
target_compile_definitions(${target_name} PRIVATE YAZE_ENABLE_ASAR=1)
|
||||||
|
else()
|
||||||
|
message(WARNING "Asar not available for target ${target_name}")
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
# Create function for ROM patching utilities
|
||||||
|
function(yaze_create_asar_patch_tool tool_name patch_file rom_file)
|
||||||
|
if(ASAR_FOUND)
|
||||||
|
add_custom_target(${tool_name}
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E echo "Patching ROM with Asar..."
|
||||||
|
COMMAND $<TARGET_FILE:asar-standalone> ${patch_file} ${rom_file}
|
||||||
|
DEPENDS asar-standalone
|
||||||
|
COMMENT "Applying Asar patch ${patch_file} to ${rom_file}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
11
cmake/gtest.cmake
Normal file
11
cmake/gtest.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# GoogleTest ------------------------------------------------------------------
|
||||||
|
include(FetchContent)
|
||||||
|
FetchContent_Declare(
|
||||||
|
googletest
|
||||||
|
URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
|
||||||
|
)
|
||||||
|
|
||||||
|
# For Windows: Prevent overriding the parent project's compiler/linker settings
|
||||||
|
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
||||||
|
FetchContent_MakeAvailable(googletest)
|
||||||
|
enable_testing()
|
||||||
@@ -1,25 +1,43 @@
|
|||||||
# gui libraries ---------------------------------------------------------------
|
# gui libraries ---------------------------------------------------------------
|
||||||
set(IMGUI_PATH ${CMAKE_SOURCE_DIR}/src/lib/imgui)
|
set(IMGUI_PATH ${CMAKE_SOURCE_DIR}/src/lib/imgui)
|
||||||
file(GLOB IMGUI_SOURCES ${IMGUI_PATH}/*.cpp)
|
file(GLOB IMGUI_SOURCES ${IMGUI_PATH}/*.cpp)
|
||||||
add_library("ImGui" STATIC ${IMGUI_SOURCES})
|
set(IMGUI_BACKEND_SOURCES
|
||||||
target_include_directories("ImGui" PUBLIC ${IMGUI_PATH})
|
${IMGUI_PATH}/backends/imgui_impl_sdl2.cpp
|
||||||
|
${IMGUI_PATH}/backends/imgui_impl_sdlrenderer2.cpp
|
||||||
|
${IMGUI_PATH}/misc/cpp/imgui_stdlib.cpp
|
||||||
|
)
|
||||||
|
add_library("ImGui" STATIC ${IMGUI_SOURCES} ${IMGUI_BACKEND_SOURCES})
|
||||||
|
target_include_directories("ImGui" PUBLIC ${IMGUI_PATH} ${IMGUI_PATH}/backends)
|
||||||
target_include_directories(ImGui PUBLIC ${SDL2_INCLUDE_DIR})
|
target_include_directories(ImGui PUBLIC ${SDL2_INCLUDE_DIR})
|
||||||
target_compile_definitions(ImGui PUBLIC
|
target_compile_definitions(ImGui PUBLIC
|
||||||
IMGUI_IMPL_OPENGL_LOADER_CUSTOM=<SDL2/SDL_opengl.h> GL_GLEXT_PROTOTYPES=1)
|
IMGUI_IMPL_OPENGL_LOADER_CUSTOM=<SDL2/SDL_opengl.h> GL_GLEXT_PROTOTYPES=1)
|
||||||
|
|
||||||
set(IMGUI_FILE_DLG_PATH ${CMAKE_SOURCE_DIR}/src/lib/ImGuiFileDialog)
|
# Set up ImGui Test Engine sources and target conditionally
|
||||||
file(GLOB IMGUI_FILE_DLG_SOURCES ${IMGUI_FILE_DLG_PATH}/*.cpp)
|
if(YAZE_ENABLE_UI_TESTS)
|
||||||
add_library("ImGuiFileDialog" STATIC ${IMGUI_FILE_DLG_SOURCES})
|
set(IMGUI_TEST_ENGINE_PATH ${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine/imgui_test_engine)
|
||||||
target_include_directories(ImGuiFileDialog PUBLIC ${IMGUI_PATH})
|
file(GLOB IMGUI_TEST_ENGINE_SOURCES ${IMGUI_TEST_ENGINE_PATH}/*.cpp)
|
||||||
target_compile_definitions(ImGuiFileDialog PUBLIC
|
add_library("ImGuiTestEngine" STATIC ${IMGUI_TEST_ENGINE_SOURCES})
|
||||||
IMGUI_IMPL_OPENGL_LOADER_CUSTOM=<SDL2/SDL_opengl.h> GL_GLEXT_PROTOTYPES=1)
|
target_include_directories(ImGuiTestEngine PUBLIC ${IMGUI_PATH} ${CMAKE_SOURCE_DIR}/src/lib)
|
||||||
|
target_link_libraries(ImGuiTestEngine PUBLIC ImGui)
|
||||||
|
|
||||||
set(IMGUI_COLOR_TEXT_EDIT_PATH ${CMAKE_SOURCE_DIR}/src/lib/ImGuiColorTextEdit)
|
# Enable test engine definitions only when UI tests are enabled
|
||||||
file(GLOB IMGUI_COLOR_TEXT_EDIT_SOURCES ${IMGUI_COLOR_TEXT_EDIT_PATH}/*.cpp)
|
target_compile_definitions(ImGuiTestEngine PUBLIC
|
||||||
add_library("ImGuiColorTextEdit" STATIC ${IMGUI_COLOR_TEXT_EDIT_SOURCES})
|
IMGUI_ENABLE_TEST_ENGINE=1
|
||||||
target_include_directories(ImGuiColorTextEdit PUBLIC ${IMGUI_PATH})
|
IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL=1)
|
||||||
target_compile_definitions(ImGuiColorTextEdit PUBLIC
|
|
||||||
IMGUI_IMPL_OPENGL_LOADER_CUSTOM=<SDL2/SDL_opengl.h> GL_GLEXT_PROTOTYPES=1)
|
# Also define for targets that link to ImGuiTestEngine
|
||||||
|
set(IMGUI_TEST_ENGINE_DEFINITIONS
|
||||||
|
IMGUI_ENABLE_TEST_ENGINE=1
|
||||||
|
IMGUI_TEST_ENGINE_ENABLE_COROUTINE_STDTHREAD_IMPL=1)
|
||||||
|
|
||||||
|
# Make ImGuiTestEngine target available
|
||||||
|
set(IMGUI_TEST_ENGINE_TARGET ImGuiTestEngine)
|
||||||
|
else()
|
||||||
|
# Create empty variables when UI tests are disabled
|
||||||
|
set(IMGUI_TEST_ENGINE_SOURCES "")
|
||||||
|
set(IMGUI_TEST_ENGINE_TARGET "")
|
||||||
|
set(IMGUI_TEST_ENGINE_DEFINITIONS "")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(
|
set(
|
||||||
IMGUI_SRC
|
IMGUI_SRC
|
||||||
@@ -27,9 +45,8 @@ set(
|
|||||||
${IMGUI_PATH}/imgui_demo.cpp
|
${IMGUI_PATH}/imgui_demo.cpp
|
||||||
${IMGUI_PATH}/imgui_draw.cpp
|
${IMGUI_PATH}/imgui_draw.cpp
|
||||||
${IMGUI_PATH}/imgui_widgets.cpp
|
${IMGUI_PATH}/imgui_widgets.cpp
|
||||||
${IMGUI_PATH}/backends/imgui_impl_sdl.cpp
|
${IMGUI_PATH}/backends/imgui_impl_sdl2.cpp
|
||||||
${IMGUI_PATH}/backends/imgui_impl_sdlrenderer.cpp
|
${IMGUI_PATH}/backends/imgui_impl_sdlrenderer2.cpp
|
||||||
${IMGUI_PATH}/misc/cpp/imgui_stdlib.cpp
|
${IMGUI_PATH}/misc/cpp/imgui_stdlib.cpp
|
||||||
${IMGUI_FILE_DLG_PATH}/ImGuiFileDialog.cpp
|
|
||||||
${IMGUI_COLOR_TEXT_EDIT_PATH}/TextEditor.cpp
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
21
cmake/mingw64.cmake
Normal file
21
cmake/mingw64.cmake
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# cmake -DCMAKE_TOOLCHAIN_FILE=./cmake/mingw64.cmake -B build/build-windows && cmake --build ./build/build-windows
|
||||||
|
|
||||||
|
set(CMAKE_SYSTEM_NAME Windows)
|
||||||
|
set(CMAKE_SYSTEM_VERSION 1)
|
||||||
|
set(CMAKE_SYSTEM_PROCESSOR x86_64)
|
||||||
|
|
||||||
|
set(CMAKE_C_COMPILER x86_64-w64-mingw32-gcc)
|
||||||
|
set(CMAKE_CXX_COMPILER x86_64-w64-mingw32-g++)
|
||||||
|
set(CMAKE_RC_COMPILER x86_64-w64-mingw32-windres)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH /usr/local/opt/mingw-w64)
|
||||||
|
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
|
||||||
|
|
||||||
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -pipe -g -feliminate-unused-debug-types")
|
||||||
|
|
||||||
|
# Static link the C++ standard library
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static -static-libgcc -static-libstdc++")
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
if (UNIX)
|
|
||||||
set(OPENSSL_INCLUDE_DIR "/usr/local/Cellar/openssl@1.1/1.1.1q/include")
|
|
||||||
set(OPENSSL_CRYPTO_LIBRARY "/usr/local/Cellar/openssl@1.1/1.1.1q/lib/libcrypto.dylib")
|
|
||||||
set(OPENSSL_SSL_LIBRARY "/usr/local/Cellar/openssl@1.1/1.1.1q/lib/libssl.dylib")
|
|
||||||
endif()
|
|
||||||
221
cmake/packaging.cmake
Normal file
221
cmake/packaging.cmake
Normal file
@@ -0,0 +1,221 @@
|
|||||||
|
# Modern packaging configuration for Yaze
|
||||||
|
# Supports Windows (NSIS), macOS (DMG), and Linux (DEB/RPM)
|
||||||
|
|
||||||
|
include(InstallRequiredSystemLibraries)
|
||||||
|
|
||||||
|
# Basic package information
|
||||||
|
set(CPACK_PACKAGE_NAME "yaze")
|
||||||
|
set(CPACK_PACKAGE_VENDOR "scawful")
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Yet Another Zelda3 Editor")
|
||||||
|
set(CPACK_PACKAGE_DESCRIPTION "A comprehensive editor for The Legend of Zelda: A Link to the Past ROM hacking")
|
||||||
|
set(CPACK_PACKAGE_VERSION_MAJOR ${YAZE_VERSION_MAJOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_MINOR ${YAZE_VERSION_MINOR})
|
||||||
|
set(CPACK_PACKAGE_VERSION_PATCH ${YAZE_VERSION_PATCH})
|
||||||
|
set(CPACK_PACKAGE_VERSION "${YAZE_VERSION_MAJOR}.${YAZE_VERSION_MINOR}.${YAZE_VERSION_PATCH}")
|
||||||
|
set(CPACK_PACKAGE_INSTALL_DIRECTORY "Yaze")
|
||||||
|
set(CPACK_PACKAGE_CONTACT "scawful@github.com")
|
||||||
|
set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/scawful/yaze")
|
||||||
|
|
||||||
|
# Resource files
|
||||||
|
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/LICENSE")
|
||||||
|
set(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md")
|
||||||
|
|
||||||
|
# Package icon
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/assets/yaze.png")
|
||||||
|
set(CPACK_PACKAGE_ICON "${CMAKE_SOURCE_DIR}/assets/yaze.png")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Platform-specific configuration
|
||||||
|
if(WIN32)
|
||||||
|
# Windows packaging configuration (conditional based on environment)
|
||||||
|
if(DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
# CI/CD build - use only ZIP (NSIS not available)
|
||||||
|
set(CPACK_GENERATOR "ZIP")
|
||||||
|
else()
|
||||||
|
# Local build - use both NSIS installer and ZIP
|
||||||
|
set(CPACK_GENERATOR "NSIS;ZIP")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# NSIS-specific configuration (only for local builds with NSIS available)
|
||||||
|
if(NOT DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
set(CPACK_NSIS_DISPLAY_NAME "Yaze - Zelda3 Editor")
|
||||||
|
set(CPACK_NSIS_PACKAGE_NAME "Yaze")
|
||||||
|
set(CPACK_NSIS_CONTACT "scawful@github.com")
|
||||||
|
set(CPACK_NSIS_URL_INFO_ABOUT "https://github.com/scawful/yaze")
|
||||||
|
set(CPACK_NSIS_HELP_LINK "https://github.com/scawful/yaze/issues")
|
||||||
|
set(CPACK_NSIS_MENU_LINKS
|
||||||
|
"bin/yaze.exe" "Yaze Editor"
|
||||||
|
"https://github.com/scawful/yaze" "Yaze Homepage"
|
||||||
|
)
|
||||||
|
set(CPACK_NSIS_CREATE_ICONS_EXTRA
|
||||||
|
"CreateShortCut '$SMPROGRAMS\\\\$STARTMENU_FOLDER\\\\Yaze.lnk' '$INSTDIR\\\\bin\\\\yaze.exe'"
|
||||||
|
"CreateShortCut '$DESKTOP\\\\Yaze.lnk' '$INSTDIR\\\\bin\\\\yaze.exe'"
|
||||||
|
)
|
||||||
|
set(CPACK_NSIS_DELETE_ICONS_EXTRA
|
||||||
|
"Delete '$SMPROGRAMS\\\\$START_MENU\\\\Yaze.lnk'"
|
||||||
|
"Delete '$DESKTOP\\\\Yaze.lnk'"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Windows architecture detection
|
||||||
|
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||||
|
if(DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-windows-x64")
|
||||||
|
else()
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-win64")
|
||||||
|
endif()
|
||||||
|
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES64")
|
||||||
|
else()
|
||||||
|
if(DEFINED ENV{GITHUB_ACTIONS})
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-windows-x86")
|
||||||
|
else()
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-win32")
|
||||||
|
endif()
|
||||||
|
set(CPACK_NSIS_INSTALL_ROOT "$PROGRAMFILES")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
elseif(APPLE)
|
||||||
|
# macOS DMG configuration
|
||||||
|
set(CPACK_GENERATOR "DragNDrop")
|
||||||
|
set(CPACK_DMG_VOLUME_NAME "Yaze ${CPACK_PACKAGE_VERSION}")
|
||||||
|
set(CPACK_DMG_FORMAT "UDZO")
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-macos")
|
||||||
|
|
||||||
|
# macOS app bundle configuration
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/assets/dmg_background.png")
|
||||||
|
set(CPACK_DMG_BACKGROUND_IMAGE "${CMAKE_SOURCE_DIR}/assets/dmg_background.png")
|
||||||
|
endif()
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/cmake/dmg_setup.scpt")
|
||||||
|
set(CPACK_DMG_DS_STORE_SETUP_SCRIPT "${CMAKE_SOURCE_DIR}/cmake/dmg_setup.scpt")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
elseif(UNIX)
|
||||||
|
# Linux DEB/RPM configuration
|
||||||
|
set(CPACK_GENERATOR "DEB;RPM;TGZ")
|
||||||
|
|
||||||
|
# DEB package configuration
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "scawful <scawful@github.com>")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SECTION "games")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_PRIORITY "optional")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_DEPENDS
|
||||||
|
"libsdl2-2.0-0, libpng16-16, libgl1-mesa-glx, libabsl20210324")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_RECOMMENDS "git")
|
||||||
|
set(CPACK_DEBIAN_PACKAGE_SUGGESTS "asar")
|
||||||
|
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
|
||||||
|
|
||||||
|
# RPM package configuration
|
||||||
|
set(CPACK_RPM_PACKAGE_SUMMARY "Zelda3 ROM Editor")
|
||||||
|
set(CPACK_RPM_PACKAGE_LICENSE "MIT")
|
||||||
|
set(CPACK_RPM_PACKAGE_GROUP "Amusements/Games")
|
||||||
|
set(CPACK_RPM_PACKAGE_REQUIRES
|
||||||
|
"SDL2 >= 2.0.0, libpng >= 1.6.0, mesa-libGL, abseil-cpp")
|
||||||
|
set(CPACK_RPM_PACKAGE_SUGGESTS "asar")
|
||||||
|
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
|
||||||
|
|
||||||
|
# Architecture detection
|
||||||
|
execute_process(
|
||||||
|
COMMAND uname -m
|
||||||
|
OUTPUT_VARIABLE CPACK_SYSTEM_ARCH
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
set(CPACK_PACKAGE_FILE_NAME "yaze-${CPACK_PACKAGE_VERSION}-linux-${CPACK_SYSTEM_ARCH}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Component configuration for advanced packaging
|
||||||
|
set(CPACK_COMPONENTS_ALL applications libraries headers documentation)
|
||||||
|
|
||||||
|
set(CPACK_COMPONENT_APPLICATIONS_DISPLAY_NAME "Yaze Application")
|
||||||
|
set(CPACK_COMPONENT_APPLICATIONS_DESCRIPTION "Main Yaze editor application")
|
||||||
|
set(CPACK_COMPONENT_APPLICATIONS_REQUIRED TRUE)
|
||||||
|
|
||||||
|
set(CPACK_COMPONENT_LIBRARIES_DISPLAY_NAME "Development Libraries")
|
||||||
|
set(CPACK_COMPONENT_LIBRARIES_DESCRIPTION "Yaze development libraries")
|
||||||
|
set(CPACK_COMPONENT_LIBRARIES_REQUIRED FALSE)
|
||||||
|
|
||||||
|
set(CPACK_COMPONENT_HEADERS_DISPLAY_NAME "Development Headers")
|
||||||
|
set(CPACK_COMPONENT_HEADERS_DESCRIPTION "Header files for Yaze development")
|
||||||
|
set(CPACK_COMPONENT_HEADERS_REQUIRED FALSE)
|
||||||
|
set(CPACK_COMPONENT_HEADERS_DEPENDS libraries)
|
||||||
|
|
||||||
|
set(CPACK_COMPONENT_DOCUMENTATION_DISPLAY_NAME "Documentation")
|
||||||
|
set(CPACK_COMPONENT_DOCUMENTATION_DESCRIPTION "User and developer documentation")
|
||||||
|
set(CPACK_COMPONENT_DOCUMENTATION_REQUIRED FALSE)
|
||||||
|
|
||||||
|
# Installation components
|
||||||
|
if(APPLE)
|
||||||
|
install(TARGETS yaze
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
BUNDLE DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
COMPONENT applications
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
install(TARGETS yaze
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
COMPONENT applications
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Install assets
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/assets/
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/yaze/assets
|
||||||
|
COMPONENT applications
|
||||||
|
PATTERN "*.png"
|
||||||
|
PATTERN "*.ttf"
|
||||||
|
PATTERN "*.asm"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install documentation
|
||||||
|
install(FILES
|
||||||
|
${CMAKE_SOURCE_DIR}/README.md
|
||||||
|
${CMAKE_SOURCE_DIR}/LICENSE
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||||
|
COMPONENT documentation
|
||||||
|
)
|
||||||
|
|
||||||
|
install(DIRECTORY ${CMAKE_SOURCE_DIR}/docs/
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DOCDIR}
|
||||||
|
COMPONENT documentation
|
||||||
|
PATTERN "*.md"
|
||||||
|
PATTERN "*.html"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Install headers and libraries if building library components
|
||||||
|
if(YAZE_INSTALL_LIB)
|
||||||
|
install(TARGETS yaze_c
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
COMPONENT libraries
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/incl/yaze.h ${CMAKE_SOURCE_DIR}/incl/zelda.h
|
||||||
|
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/yaze
|
||||||
|
COMPONENT headers
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Desktop integration for Linux
|
||||||
|
if(UNIX AND NOT APPLE)
|
||||||
|
# Desktop file
|
||||||
|
configure_file(
|
||||||
|
${CMAKE_SOURCE_DIR}/cmake/yaze.desktop.in
|
||||||
|
${CMAKE_BINARY_DIR}/yaze.desktop
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
|
||||||
|
install(FILES ${CMAKE_BINARY_DIR}/yaze.desktop
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/applications
|
||||||
|
COMPONENT applications
|
||||||
|
)
|
||||||
|
|
||||||
|
# Icon
|
||||||
|
if(EXISTS "${CMAKE_SOURCE_DIR}/assets/yaze.png")
|
||||||
|
install(FILES ${CMAKE_SOURCE_DIR}/assets/yaze.png
|
||||||
|
DESTINATION ${CMAKE_INSTALL_DATADIR}/pixmaps
|
||||||
|
RENAME yaze.png
|
||||||
|
COMPONENT applications
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Include CPack
|
||||||
|
include(CPack)
|
||||||
54
cmake/sdl2.cmake
Normal file
54
cmake/sdl2.cmake
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# SDL2
|
||||||
|
if (UNIX OR MINGW OR WIN32)
|
||||||
|
add_subdirectory(src/lib/SDL)
|
||||||
|
# When using bundled SDL, use the static target and set include directories
|
||||||
|
set(SDL_TARGETS SDL2-static)
|
||||||
|
set(SDL2_INCLUDE_DIR
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/SDL/include
|
||||||
|
${CMAKE_BINARY_DIR}/src/lib/SDL/include
|
||||||
|
${CMAKE_BINARY_DIR}/src/lib/SDL/include-config-${CMAKE_BUILD_TYPE}
|
||||||
|
)
|
||||||
|
# Also set for consistency with bundled SDL
|
||||||
|
set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
|
||||||
|
else()
|
||||||
|
find_package(SDL2)
|
||||||
|
# When using system SDL, use the imported targets
|
||||||
|
set(SDL_TARGETS SDL2::SDL2)
|
||||||
|
if(WIN32)
|
||||||
|
list(PREPEND SDL_TARGETS SDL2::SDL2main ws2_32)
|
||||||
|
add_definitions("-DSDL_MAIN_HANDLED")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# libpng and ZLIB dependencies
|
||||||
|
if(WIN32)
|
||||||
|
# Windows builds with vcpkg (OpenGL/GLEW removed to avoid MSYS2 issues)
|
||||||
|
if(NOT YAZE_MINIMAL_BUILD)
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
else()
|
||||||
|
# For CI/minimal builds, try to find but don't require
|
||||||
|
find_package(ZLIB QUIET)
|
||||||
|
find_package(PNG QUIET)
|
||||||
|
if(NOT ZLIB_FOUND OR NOT PNG_FOUND)
|
||||||
|
message(STATUS "PNG/ZLIB not found in minimal build, some features may be disabled")
|
||||||
|
set(PNG_FOUND FALSE)
|
||||||
|
set(PNG_LIBRARIES "")
|
||||||
|
set(PNG_INCLUDE_DIRS "")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
elseif(YAZE_MINIMAL_BUILD)
|
||||||
|
# For CI builds on other platforms, try to find but don't require
|
||||||
|
find_package(ZLIB QUIET)
|
||||||
|
find_package(PNG QUIET)
|
||||||
|
if(NOT ZLIB_FOUND OR NOT PNG_FOUND)
|
||||||
|
message(STATUS "PNG/ZLIB not found in minimal build, some features may be disabled")
|
||||||
|
set(PNG_FOUND FALSE)
|
||||||
|
set(PNG_LIBRARIES "")
|
||||||
|
set(PNG_INCLUDE_DIRS "")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
# Regular builds require these dependencies
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
find_package(PNG REQUIRED)
|
||||||
|
endif()
|
||||||
40
cmake/vcpkg.cmake
Normal file
40
cmake/vcpkg.cmake
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
# vcpkg configuration for Windows builds
|
||||||
|
add_definitions("-DMICROSOFT_WINDOWS_WINBASE_H_DEFINE_INTERLOCKED_CPLUSPLUS_OVERLOADS=0")
|
||||||
|
|
||||||
|
# vcpkg settings
|
||||||
|
set(VCPKG_CRT_LINKAGE dynamic)
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE dynamic)
|
||||||
|
|
||||||
|
# Enable vcpkg manifest mode for automatic dependency management
|
||||||
|
set(VCPKG_MANIFEST_MODE ON)
|
||||||
|
|
||||||
|
# Auto-detect target architecture and set vcpkg triplet
|
||||||
|
if(NOT DEFINED VCPKG_TARGET_TRIPLET)
|
||||||
|
if(CMAKE_SYSTEM_PROCESSOR MATCHES "ARM64|aarch64")
|
||||||
|
set(VCPKG_TARGET_TRIPLET "arm64-windows" CACHE STRING "vcpkg target triplet")
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE arm64)
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "AMD64|x86_64")
|
||||||
|
set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "vcpkg target triplet")
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i386|i686|x86")
|
||||||
|
set(VCPKG_TARGET_TRIPLET "x86-windows" CACHE STRING "vcpkg target triplet")
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE x86)
|
||||||
|
else()
|
||||||
|
# Fallback to x64 if architecture detection fails
|
||||||
|
set(VCPKG_TARGET_TRIPLET "x64-windows" CACHE STRING "vcpkg target triplet")
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||||
|
message(WARNING "Could not detect target architecture, defaulting to x64")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Set vcpkg installation directory if not already set
|
||||||
|
if(NOT DEFINED VCPKG_INSTALLED_DIR)
|
||||||
|
set(VCPKG_INSTALLED_DIR "${CMAKE_BINARY_DIR}/vcpkg_installed" CACHE PATH "vcpkg installed directory")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
message(STATUS "vcpkg configuration:")
|
||||||
|
message(STATUS " Target architecture: ${VCPKG_TARGET_ARCHITECTURE}")
|
||||||
|
message(STATUS " Target triplet: ${VCPKG_TARGET_TRIPLET}")
|
||||||
|
message(STATUS " Installed directory: ${VCPKG_INSTALLED_DIR}")
|
||||||
|
message(STATUS " Manifest mode: ${VCPKG_MANIFEST_MODE}")
|
||||||
13
cmake/yaze.desktop.in
Normal file
13
cmake/yaze.desktop.in
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
[Desktop Entry]
|
||||||
|
Version=1.0
|
||||||
|
Type=Application
|
||||||
|
Name=Yaze
|
||||||
|
Comment=Yet Another Zelda3 Editor
|
||||||
|
Comment[en]=ROM editor for The Legend of Zelda: A Link to the Past
|
||||||
|
Exec=@CMAKE_INSTALL_PREFIX@/@CMAKE_INSTALL_BINDIR@/yaze
|
||||||
|
Icon=yaze
|
||||||
|
Terminal=false
|
||||||
|
Categories=Game;Development;
|
||||||
|
Keywords=zelda;snes;rom;editor;hacking;
|
||||||
|
StartupNotify=true
|
||||||
|
MimeType=application/x-snes-rom;application/x-sfc;application/x-smc;
|
||||||
56
docs/01-getting-started.md
Normal file
56
docs/01-getting-started.md
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
# Getting Started
|
||||||
|
|
||||||
|
This software allows you to modify "The Legend of Zelda: A Link to the Past" (US or JP) ROMs. Built for compatibility with ZScream projects and designed to be cross-platform.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
1. **Download** the latest release for your platform
|
||||||
|
2. **Load ROM** via File > Open ROM
|
||||||
|
3. **Select Editor** from the toolbar (Overworld, Dungeon, Graphics, etc.)
|
||||||
|
4. **Make Changes** and save your project
|
||||||
|
|
||||||
|
## General Tips
|
||||||
|
|
||||||
|
- **Experiment Flags**: Enable/disable features in File > Options > Experiment Flags
|
||||||
|
- **Backup Files**: Enabled by default - each save creates a timestamped backup
|
||||||
|
- **Extensions**: Load custom tools via the Extensions menu (C library and Python module support)
|
||||||
|
|
||||||
|
## Supported Features
|
||||||
|
|
||||||
|
| Feature | Status | Details |
|
||||||
|
|---------|--------|---------|
|
||||||
|
| Overworld Maps | ✅ Complete | Edit and save tile32 data |
|
||||||
|
| OW Map Properties | ✅ Complete | Edit and save map properties |
|
||||||
|
| OW Entrances | ✅ Complete | Edit and save entrance data |
|
||||||
|
| OW Exits | ✅ Complete | Edit and save exit data |
|
||||||
|
| OW Sprites | 🔄 In Progress | Edit sprite positions, add/remove sprites |
|
||||||
|
| Dungeon Editor | 🔄 In Progress | View room metadata and edit room data |
|
||||||
|
| Palette Editor | 🔄 In Progress | Edit and save palettes, palette groups |
|
||||||
|
| Graphics Sheets | 🔄 In Progress | Edit and save graphics sheets |
|
||||||
|
| Graphics Groups | ✅ Complete | Edit and save graphics groups |
|
||||||
|
| Hex Editor | ✅ Complete | View and edit ROM data in hex |
|
||||||
|
| Asar Patching | ✅ Complete | Apply Asar 65816 assembly patches to ROM |
|
||||||
|
|
||||||
|
## Command Line Interface
|
||||||
|
|
||||||
|
The `z3ed` CLI tool provides ROM operations:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Apply Asar assembly patch
|
||||||
|
z3ed asar patch.asm --rom=zelda3.sfc
|
||||||
|
|
||||||
|
# Extract symbols from assembly
|
||||||
|
z3ed extract patch.asm
|
||||||
|
|
||||||
|
# Validate assembly syntax
|
||||||
|
z3ed validate patch.asm
|
||||||
|
|
||||||
|
# Launch interactive TUI
|
||||||
|
z3ed --tui
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extending Functionality
|
||||||
|
|
||||||
|
YAZE provides a pure C library interface and Python module for building extensions and custom sprites without assembly. Load these under the Extensions menu.
|
||||||
|
|
||||||
|
This feature is still in development and not fully documented yet.
|
||||||
459
docs/02-build-instructions.md
Normal file
459
docs/02-build-instructions.md
Normal file
@@ -0,0 +1,459 @@
|
|||||||
|
# Build Instructions
|
||||||
|
|
||||||
|
YAZE uses CMake 3.16+ with modern target-based configuration. The project includes comprehensive Windows support with Visual Studio integration, vcpkg package management, and automated setup scripts.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### macOS (Apple Silicon)
|
||||||
|
```bash
|
||||||
|
cmake --preset debug
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
```bash
|
||||||
|
cmake -B build -DCMAKE_BUILD_TYPE=Debug
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows (Recommended)
|
||||||
|
```powershell
|
||||||
|
# Automated setup (first time only)
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
|
||||||
|
# Generate Visual Studio projects (with proper vcpkg integration)
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Or use CMake directly
|
||||||
|
cmake --preset windows-debug
|
||||||
|
cmake --build build --preset windows-debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Minimal Build (CI/Fast)
|
||||||
|
```bash
|
||||||
|
cmake -B build -DYAZE_MINIMAL_BUILD=ON
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
### Required
|
||||||
|
- CMake 3.16+
|
||||||
|
- C++23 compiler (GCC 13+, Clang 16+, MSVC 2019+)
|
||||||
|
- Git with submodule support
|
||||||
|
|
||||||
|
### Bundled Libraries
|
||||||
|
- SDL2, ImGui, Abseil, Asar, GoogleTest
|
||||||
|
- Native File Dialog Extended (NFD)
|
||||||
|
- All dependencies included in repository
|
||||||
|
|
||||||
|
## Platform Setup
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
```bash
|
||||||
|
# Install Xcode Command Line Tools
|
||||||
|
xcode-select --install
|
||||||
|
|
||||||
|
# Optional: Install Homebrew dependencies (auto-detected)
|
||||||
|
brew install cmake pkg-config
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux (Ubuntu/Debian)
|
||||||
|
```bash
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y build-essential cmake ninja-build pkg-config \
|
||||||
|
libgtk-3-dev libdbus-1-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
|
||||||
|
#### Automated Setup (Recommended)
|
||||||
|
The project includes comprehensive setup scripts for Windows development:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Complete development environment setup
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
|
||||||
|
# Generate Visual Studio project files (with proper vcpkg integration)
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Test CMake configuration
|
||||||
|
.\scripts\test-cmake-config.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
**What the setup script installs:**
|
||||||
|
- Chocolatey package manager
|
||||||
|
- CMake 3.16+
|
||||||
|
- Git, Ninja, Python 3
|
||||||
|
- Visual Studio 2022 detection and verification
|
||||||
|
|
||||||
|
#### Manual Setup Options
|
||||||
|
|
||||||
|
**Option 1 - Minimal (CI/Fast Builds):**
|
||||||
|
- Visual Studio 2019+ with C++ CMake tools
|
||||||
|
- No additional dependencies needed (all bundled)
|
||||||
|
|
||||||
|
**Option 2 - Full Development with vcpkg:**
|
||||||
|
- Visual Studio 2019+ with C++ CMake tools
|
||||||
|
- vcpkg package manager for dependency management
|
||||||
|
|
||||||
|
#### vcpkg Integration
|
||||||
|
|
||||||
|
**Automatic Setup:**
|
||||||
|
```powershell
|
||||||
|
# PowerShell
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
|
||||||
|
# Command Prompt
|
||||||
|
scripts\setup-windows-dev.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
**Manual vcpkg Setup:**
|
||||||
|
```cmd
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
.\bootstrap-vcpkg.bat
|
||||||
|
.\vcpkg.exe integrate install
|
||||||
|
set VCPKG_ROOT=%CD%
|
||||||
|
```
|
||||||
|
|
||||||
|
**Dependencies (vcpkg.json):**
|
||||||
|
- zlib (compression)
|
||||||
|
- libpng (PNG support)
|
||||||
|
- sdl2 (graphics/input with Vulkan support)
|
||||||
|
|
||||||
|
**Note**: Abseil and gtest are built from source via CMake rather than through vcpkg to avoid compatibility issues.
|
||||||
|
|
||||||
|
#### Windows Build Commands
|
||||||
|
|
||||||
|
**Using CMake Presets:**
|
||||||
|
```cmd
|
||||||
|
# Debug build (minimal, no tests)
|
||||||
|
cmake --preset windows-debug
|
||||||
|
cmake --build build --preset windows-debug
|
||||||
|
|
||||||
|
# Development build (includes Google Test)
|
||||||
|
cmake --preset windows-dev
|
||||||
|
cmake --build build --preset windows-dev
|
||||||
|
|
||||||
|
# Release build (optimized, no tests)
|
||||||
|
cmake --preset windows-release
|
||||||
|
cmake --build build --preset windows-release
|
||||||
|
```
|
||||||
|
|
||||||
|
**Using Visual Studio Projects:**
|
||||||
|
```powershell
|
||||||
|
# Generate project files (with proper vcpkg integration)
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Open YAZE.sln in Visual Studio
|
||||||
|
# Select configuration (Debug/Release) and platform (x64/x86/ARM64)
|
||||||
|
# Press F5 to build and run
|
||||||
|
```
|
||||||
|
|
||||||
|
**Build Types:**
|
||||||
|
- **windows-debug**: Minimal debug build, no Google Test
|
||||||
|
- **windows-dev**: Development build with Google Test and ROM testing
|
||||||
|
- **windows-release**: Optimized release build, no Google Test
|
||||||
|
|
||||||
|
## Build Targets
|
||||||
|
|
||||||
|
### Applications
|
||||||
|
- **yaze**: Main GUI editor application
|
||||||
|
- **z3ed**: Command-line interface tool
|
||||||
|
|
||||||
|
### Libraries
|
||||||
|
- **yaze_c**: C API library for extensions
|
||||||
|
- **asar-static**: 65816 assembler library
|
||||||
|
|
||||||
|
### Development (Debug Builds Only)
|
||||||
|
- **yaze_emu**: Standalone SNES emulator
|
||||||
|
- **yaze_test**: Comprehensive test suite
|
||||||
|
|
||||||
|
## Build Configurations
|
||||||
|
|
||||||
|
### Debug (Full Features)
|
||||||
|
```bash
|
||||||
|
cmake --preset debug # macOS
|
||||||
|
# OR
|
||||||
|
cmake -B build -DCMAKE_BUILD_TYPE=Debug # All platforms
|
||||||
|
```
|
||||||
|
**Includes**: NFD, ImGuiTestEngine, PNG support, emulator, all tools
|
||||||
|
|
||||||
|
### Minimal (CI/Fast Builds)
|
||||||
|
```bash
|
||||||
|
cmake -B build -DYAZE_MINIMAL_BUILD=ON
|
||||||
|
```
|
||||||
|
**Excludes**: Emulator, CLI tools, UI tests, optional dependencies
|
||||||
|
|
||||||
|
### Release
|
||||||
|
```bash
|
||||||
|
cmake --preset release # macOS
|
||||||
|
# OR
|
||||||
|
cmake -B build -DCMAKE_BUILD_TYPE=Release # All platforms
|
||||||
|
```
|
||||||
|
|
||||||
|
## IDE Integration
|
||||||
|
|
||||||
|
### Visual Studio (Windows)
|
||||||
|
**Recommended approach:**
|
||||||
|
```powershell
|
||||||
|
# Setup development environment
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
|
||||||
|
# Generate Visual Studio project files (with proper vcpkg integration)
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Open YAZE.sln in Visual Studio 2022
|
||||||
|
# Select configuration (Debug/Release) and platform (x64/x86/ARM64)
|
||||||
|
# Press F5 to build and run
|
||||||
|
```
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Full IntelliSense support
|
||||||
|
- Integrated debugging
|
||||||
|
- Automatic vcpkg dependency management (zlib, libpng, SDL2)
|
||||||
|
- Multi-platform support (x64, ARM64)
|
||||||
|
- Automatic asset copying
|
||||||
|
- Generated project files stay in sync with CMake configuration
|
||||||
|
|
||||||
|
### VS Code
|
||||||
|
1. Install CMake Tools extension
|
||||||
|
2. Open project, select "Debug" preset
|
||||||
|
3. Language server uses `compile_commands.json` automatically
|
||||||
|
|
||||||
|
### CLion
|
||||||
|
- Opens CMake projects directly
|
||||||
|
- Select Debug configuration
|
||||||
|
|
||||||
|
### Xcode (macOS)
|
||||||
|
```bash
|
||||||
|
cmake --preset debug -G Xcode
|
||||||
|
open build/yaze.xcodeproj
|
||||||
|
```
|
||||||
|
|
||||||
|
## Windows Development Scripts
|
||||||
|
|
||||||
|
The project includes several PowerShell and Batch scripts to streamline Windows development:
|
||||||
|
|
||||||
|
### Setup Scripts
|
||||||
|
- **`setup-windows-dev.ps1`**: Complete development environment setup
|
||||||
|
- **`setup-windows-dev.bat`**: Batch version of setup script
|
||||||
|
|
||||||
|
**What they install:**
|
||||||
|
- Chocolatey package manager
|
||||||
|
- CMake 3.16+
|
||||||
|
- Git, Ninja, Python 3
|
||||||
|
- Visual Studio 2022 detection
|
||||||
|
|
||||||
|
### Project Generation Scripts
|
||||||
|
- **`generate-vs-projects.py`**: Generate Visual Studio project files with proper vcpkg integration
|
||||||
|
- **`generate-vs-projects.bat`**: Batch version of project generation
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Automatic CMake detection and installation
|
||||||
|
- Visual Studio 2022 detection
|
||||||
|
- Multi-architecture support (x64, ARM64)
|
||||||
|
- vcpkg integration
|
||||||
|
- CMake compatibility fixes
|
||||||
|
|
||||||
|
### Testing Scripts
|
||||||
|
- **`test-cmake-config.ps1`**: Test CMake configuration without full build
|
||||||
|
|
||||||
|
**Usage:**
|
||||||
|
```powershell
|
||||||
|
# Test configuration
|
||||||
|
.\scripts\test-cmake-config.ps1
|
||||||
|
|
||||||
|
# Test with specific architecture
|
||||||
|
.\scripts\test-cmake-config.ps1 -Architecture x86
|
||||||
|
|
||||||
|
# Clean test build
|
||||||
|
.\scripts\test-cmake-config.ps1 -Clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Features by Build Type
|
||||||
|
|
||||||
|
| Feature | Debug | Release | Minimal (CI) |
|
||||||
|
|---------|-------|---------|--------------|
|
||||||
|
| GUI Editor | ✅ | ✅ | ✅ |
|
||||||
|
| Native File Dialogs | ✅ | ✅ | ❌ |
|
||||||
|
| PNG Support | ✅ | ✅ | ❌ |
|
||||||
|
| Emulator | ✅ | ✅ | ❌ |
|
||||||
|
| CLI Tools | ✅ | ✅ | ❌ |
|
||||||
|
| Test Suite | ✅ | ❌ | ✅ (limited) |
|
||||||
|
| UI Testing | ✅ | ❌ | ❌ |
|
||||||
|
|
||||||
|
## CMake Compatibility
|
||||||
|
|
||||||
|
### Submodule Compatibility Issues
|
||||||
|
YAZE includes several submodules (abseil-cpp, SDL) that may have CMake compatibility issues. The project automatically handles these with:
|
||||||
|
|
||||||
|
**Automatic Policy Management:**
|
||||||
|
- `CMAKE_POLICY_VERSION_MINIMUM=3.5` (handles SDL requirements)
|
||||||
|
- `CMAKE_POLICY_VERSION_MAXIMUM=3.28` (prevents future issues)
|
||||||
|
- `CMAKE_WARN_DEPRECATED=OFF` (suppresses submodule warnings)
|
||||||
|
- `ABSL_PROPAGATE_CXX_STD=ON` (handles Abseil C++ standard propagation)
|
||||||
|
- `THREADS_PREFER_PTHREAD_FLAG=OFF` (fixes Windows pthread issues)
|
||||||
|
|
||||||
|
**Manual Configuration (if needed):**
|
||||||
|
```bash
|
||||||
|
cmake -B build \
|
||||||
|
-DCMAKE_POLICY_VERSION_MINIMUM=3.5 \
|
||||||
|
-DCMAKE_POLICY_VERSION_MAXIMUM=3.28 \
|
||||||
|
-DCMAKE_WARN_DEPRECATED=OFF \
|
||||||
|
-DABSL_PROPAGATE_CXX_STD=ON \
|
||||||
|
-DTHREADS_PREFER_PTHREAD_FLAG=OFF \
|
||||||
|
-DCMAKE_BUILD_TYPE=Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD and Release Builds
|
||||||
|
|
||||||
|
### GitHub Actions Workflows
|
||||||
|
|
||||||
|
The project includes three release workflows with different levels of complexity:
|
||||||
|
|
||||||
|
- **`release-simplified.yml`**: Fast, basic release builds
|
||||||
|
- **`release.yml`**: Standard release builds with fallback mechanisms
|
||||||
|
- **`release-complex.yml`**: Comprehensive release builds with multiple fallback strategies
|
||||||
|
|
||||||
|
### vcpkg Fallback Mechanisms
|
||||||
|
|
||||||
|
All Windows CI/CD builds include automatic fallback mechanisms:
|
||||||
|
|
||||||
|
**When vcpkg succeeds:**
|
||||||
|
- Full build with all dependencies (zlib, libpng, SDL2)
|
||||||
|
- Complete feature set available
|
||||||
|
|
||||||
|
**When vcpkg fails (network issues):**
|
||||||
|
- Automatic fallback to minimal build configuration
|
||||||
|
- Uses source-built dependencies (Abseil, etc.)
|
||||||
|
- Still produces functional executables
|
||||||
|
|
||||||
|
### Supported Architectures
|
||||||
|
|
||||||
|
**Windows:**
|
||||||
|
- x64 (64-bit) - Primary target for modern systems
|
||||||
|
- ARM64 - For ARM-based Windows devices (Surface Pro X, etc.)
|
||||||
|
|
||||||
|
**macOS:**
|
||||||
|
- Universal binary (Apple Silicon + Intel)
|
||||||
|
|
||||||
|
**Linux:**
|
||||||
|
- x64 (64-bit)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Windows CMake Issues
|
||||||
|
|
||||||
|
**CMake Not Found:**
|
||||||
|
```powershell
|
||||||
|
# Run the setup script
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
|
||||||
|
# Or install manually via Chocolatey
|
||||||
|
choco install cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
**Submodule Compatibility Errors:**
|
||||||
|
```powershell
|
||||||
|
# Test CMake configuration
|
||||||
|
.\scripts\test-cmake-config.ps1
|
||||||
|
|
||||||
|
# Clean build with compatibility flags
|
||||||
|
Remove-Item -Recurse -Force build
|
||||||
|
cmake -B build -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_WARN_DEPRECATED=OFF
|
||||||
|
```
|
||||||
|
|
||||||
|
**Visual Studio Project Issues:**
|
||||||
|
```powershell
|
||||||
|
# Regenerate project files
|
||||||
|
.\scripts\generate-vs-projects.ps1
|
||||||
|
|
||||||
|
# Clean and rebuild
|
||||||
|
Remove-Item -Recurse -Force build
|
||||||
|
cmake --preset windows-debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### vcpkg Issues
|
||||||
|
|
||||||
|
**Dependencies Not Installing:**
|
||||||
|
```cmd
|
||||||
|
# Check vcpkg installation
|
||||||
|
vcpkg version
|
||||||
|
|
||||||
|
# Reinstall dependencies
|
||||||
|
vcpkg install --triplet x64-windows zlib libpng sdl2
|
||||||
|
|
||||||
|
# Check installed packages
|
||||||
|
vcpkg list
|
||||||
|
```
|
||||||
|
|
||||||
|
**Network/Download Failures:**
|
||||||
|
- The CI/CD workflows automatically fall back to minimal builds
|
||||||
|
- For local development, ensure stable internet connection
|
||||||
|
- If vcpkg consistently fails, use minimal build mode:
|
||||||
|
```bash
|
||||||
|
cmake -B build -DYAZE_MINIMAL_BUILD=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
**Visual Studio Integration:**
|
||||||
|
```cmd
|
||||||
|
# Re-integrate vcpkg
|
||||||
|
cd C:\vcpkg
|
||||||
|
.\vcpkg.exe integrate install
|
||||||
|
```
|
||||||
|
|
||||||
|
**ZLIB or Other Dependencies Not Found:**
|
||||||
|
```bash
|
||||||
|
# Regenerate project files with proper vcpkg integration
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Ensure vcpkg is properly set up
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Architecture Errors (macOS)
|
||||||
|
```bash
|
||||||
|
# Clean and use ARM64-only preset
|
||||||
|
rm -rf build
|
||||||
|
cmake --preset debug # Uses arm64 only
|
||||||
|
```
|
||||||
|
|
||||||
|
### Missing Headers (Language Server)
|
||||||
|
```bash
|
||||||
|
# Regenerate compile commands
|
||||||
|
cmake --preset debug
|
||||||
|
cp build/compile_commands.json .
|
||||||
|
# Restart VS Code
|
||||||
|
```
|
||||||
|
|
||||||
|
### CI Build Failures
|
||||||
|
Use minimal build configuration that matches CI:
|
||||||
|
```bash
|
||||||
|
cmake -B build -DYAZE_MINIMAL_BUILD=ON -DYAZE_ENABLE_UI_TESTS=OFF
|
||||||
|
cmake --build build
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Error Solutions
|
||||||
|
|
||||||
|
**"CMake Deprecation Warning" from submodules:**
|
||||||
|
- This is automatically handled by the project's CMake configuration
|
||||||
|
- If you see these warnings, they can be safely ignored
|
||||||
|
|
||||||
|
**"pthread_create not found" on Windows:**
|
||||||
|
- The project automatically sets `THREADS_PREFER_PTHREAD_FLAG=OFF`
|
||||||
|
- This is normal for Windows builds
|
||||||
|
|
||||||
|
**"Abseil C++ std propagation" warnings:**
|
||||||
|
- Automatically handled with `ABSL_PROPAGATE_CXX_STD=ON`
|
||||||
|
- Ensures proper C++ standard handling
|
||||||
|
|
||||||
|
**Visual Studio "file not found" errors:**
|
||||||
|
- Run `python scripts/generate-vs-projects.py` to regenerate project files
|
||||||
|
- Ensure CMake configuration completed successfully first
|
||||||
|
|
||||||
|
**CI/CD Build Failures:**
|
||||||
|
- Check if vcpkg download failed (network issues)
|
||||||
|
- The workflows automatically fall back to minimal builds
|
||||||
|
- For persistent issues, check the workflow logs for specific error messages
|
||||||
141
docs/03-asar-integration.md
Normal file
141
docs/03-asar-integration.md
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
# Asar 65816 Assembler Integration
|
||||||
|
|
||||||
|
Complete cross-platform ROM patching with assembly code support, symbol extraction, and validation.
|
||||||
|
|
||||||
|
## Quick Examples
|
||||||
|
|
||||||
|
### Command Line
|
||||||
|
```bash
|
||||||
|
# Apply assembly patch to ROM
|
||||||
|
z3ed asar my_patch.asm --rom=zelda3.sfc
|
||||||
|
|
||||||
|
# Extract symbols without patching
|
||||||
|
z3ed extract my_patch.asm
|
||||||
|
|
||||||
|
# Validate assembly syntax
|
||||||
|
z3ed validate my_patch.asm
|
||||||
|
```
|
||||||
|
|
||||||
|
### C++ API
|
||||||
|
```cpp
|
||||||
|
#include "app/core/asar_wrapper.h"
|
||||||
|
|
||||||
|
yaze::app::core::AsarWrapper wrapper;
|
||||||
|
wrapper.Initialize();
|
||||||
|
|
||||||
|
// Apply patch to ROM
|
||||||
|
auto result = wrapper.ApplyPatch("patch.asm", rom_data);
|
||||||
|
if (result.ok() && result->success) {
|
||||||
|
for (const auto& symbol : result->symbols) {
|
||||||
|
std::cout << symbol.name << " @ $" << std::hex << symbol.address << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Assembly Patch Examples
|
||||||
|
|
||||||
|
### Basic Hook
|
||||||
|
```assembly
|
||||||
|
org $008000
|
||||||
|
custom_hook:
|
||||||
|
sei ; Disable interrupts
|
||||||
|
rep #$30 ; 16-bit A and X/Y
|
||||||
|
|
||||||
|
; Your custom code
|
||||||
|
lda #$1234
|
||||||
|
sta $7E0000
|
||||||
|
|
||||||
|
rts
|
||||||
|
|
||||||
|
custom_data:
|
||||||
|
db "YAZE", $00
|
||||||
|
dw $1234, $5678
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
```assembly
|
||||||
|
!player_health = $7EF36C
|
||||||
|
!custom_ram = $7E2000
|
||||||
|
|
||||||
|
macro save_context()
|
||||||
|
pha : phx : phy
|
||||||
|
endmacro
|
||||||
|
|
||||||
|
org $008000
|
||||||
|
advanced_hook:
|
||||||
|
%save_context()
|
||||||
|
|
||||||
|
sep #$20
|
||||||
|
lda #$A0 ; Full health
|
||||||
|
sta !player_health
|
||||||
|
|
||||||
|
%save_context()
|
||||||
|
rtl
|
||||||
|
```
|
||||||
|
|
||||||
|
## API Reference
|
||||||
|
|
||||||
|
### AsarWrapper Class
|
||||||
|
```cpp
|
||||||
|
class AsarWrapper {
|
||||||
|
public:
|
||||||
|
absl::Status Initialize();
|
||||||
|
absl::StatusOr<AsarPatchResult> ApplyPatch(
|
||||||
|
const std::string& patch_path,
|
||||||
|
std::vector<uint8_t>& rom_data);
|
||||||
|
absl::StatusOr<std::vector<AsarSymbol>> ExtractSymbols(
|
||||||
|
const std::string& asm_path);
|
||||||
|
absl::Status ValidateAssembly(const std::string& asm_path);
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Structures
|
||||||
|
```cpp
|
||||||
|
struct AsarSymbol {
|
||||||
|
std::string name; // Symbol name
|
||||||
|
uint32_t address; // Memory address
|
||||||
|
std::string opcode; // Associated opcode
|
||||||
|
std::string file; // Source file
|
||||||
|
int line; // Line number
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AsarPatchResult {
|
||||||
|
bool success; // Whether patch succeeded
|
||||||
|
std::vector<std::string> errors; // Error messages
|
||||||
|
std::vector<AsarSymbol> symbols; // Extracted symbols
|
||||||
|
uint32_t rom_size; // Final ROM size
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### ROM-Dependent Tests
|
||||||
|
```cpp
|
||||||
|
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
|
||||||
|
auto rom_data = TestRomManager::LoadTestRom();
|
||||||
|
AsarWrapper wrapper;
|
||||||
|
wrapper.Initialize();
|
||||||
|
|
||||||
|
auto result = wrapper.ApplyPatch("test.asm", rom_data);
|
||||||
|
EXPECT_TRUE(result.ok());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
ROM tests are automatically skipped in CI with `--label-exclude ROM_DEPENDENT`.
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
| Error | Cause | Solution |
|
||||||
|
|-------|-------|----------|
|
||||||
|
| `Unknown command` | Invalid opcode | Check 65816 instruction reference |
|
||||||
|
| `Label not found` | Undefined label | Define the label or check spelling |
|
||||||
|
| `Invalid hex value` | Bad hex format | Use `$1234` format |
|
||||||
|
| `Buffer too small` | ROM needs expansion | Check if ROM needs to be larger |
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
1. **Write assembly patch**
|
||||||
|
2. **Validate syntax**: `z3ed validate patch.asm`
|
||||||
|
3. **Extract symbols**: `z3ed extract patch.asm`
|
||||||
|
4. **Apply to test ROM**: `z3ed asar patch.asm --rom=test.sfc`
|
||||||
|
5. **Test in emulator**
|
||||||
208
docs/04-api-reference.md
Normal file
208
docs/04-api-reference.md
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
# API Reference
|
||||||
|
|
||||||
|
Comprehensive reference for the YAZE C API and C++ interfaces.
|
||||||
|
|
||||||
|
## C API (`incl/yaze.h`, `incl/zelda.h`)
|
||||||
|
|
||||||
|
### Core Library Functions
|
||||||
|
```c
|
||||||
|
// Initialization
|
||||||
|
yaze_status yaze_library_init(void);
|
||||||
|
void yaze_library_shutdown(void);
|
||||||
|
|
||||||
|
// Version management
|
||||||
|
const char* yaze_get_version_string(void);
|
||||||
|
int yaze_get_version_number(void);
|
||||||
|
bool yaze_check_version_compatibility(const char* expected_version);
|
||||||
|
|
||||||
|
// Status utilities
|
||||||
|
const char* yaze_status_to_string(yaze_status status);
|
||||||
|
```
|
||||||
|
|
||||||
|
### ROM Operations
|
||||||
|
```c
|
||||||
|
// ROM loading and management
|
||||||
|
zelda3_rom* yaze_load_rom(const char* filename);
|
||||||
|
void yaze_unload_rom(zelda3_rom* rom);
|
||||||
|
yaze_status yaze_save_rom(zelda3_rom* rom, const char* filename);
|
||||||
|
bool yaze_is_rom_modified(const zelda3_rom* rom);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Graphics Operations
|
||||||
|
```c
|
||||||
|
// SNES color management
|
||||||
|
snes_color yaze_rgb_to_snes_color(uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
void yaze_snes_color_to_rgb(snes_color color, uint8_t* r, uint8_t* g, uint8_t* b);
|
||||||
|
|
||||||
|
// Bitmap operations
|
||||||
|
yaze_bitmap* yaze_create_bitmap(int width, int height, uint8_t bpp);
|
||||||
|
void yaze_free_bitmap(yaze_bitmap* bitmap);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Palette System
|
||||||
|
```c
|
||||||
|
// Palette creation and management
|
||||||
|
snes_palette* yaze_create_palette(uint8_t id, uint8_t size);
|
||||||
|
void yaze_free_palette(snes_palette* palette);
|
||||||
|
snes_palette* yaze_load_palette_from_rom(const zelda3_rom* rom, uint8_t palette_id);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Message System
|
||||||
|
```c
|
||||||
|
// Message handling
|
||||||
|
zelda3_message* yaze_load_message(const zelda3_rom* rom, uint16_t message_id);
|
||||||
|
void yaze_free_message(zelda3_message* message);
|
||||||
|
yaze_status yaze_save_message(zelda3_rom* rom, const zelda3_message* message);
|
||||||
|
```
|
||||||
|
|
||||||
|
## C++ API
|
||||||
|
|
||||||
|
### AsarWrapper (`src/app/core/asar_wrapper.h`)
|
||||||
|
```cpp
|
||||||
|
namespace yaze::app::core {
|
||||||
|
|
||||||
|
class AsarWrapper {
|
||||||
|
public:
|
||||||
|
// Initialization
|
||||||
|
absl::Status Initialize();
|
||||||
|
void Shutdown();
|
||||||
|
bool IsInitialized() const;
|
||||||
|
|
||||||
|
// Core functionality
|
||||||
|
absl::StatusOr<AsarPatchResult> ApplyPatch(
|
||||||
|
const std::string& patch_path,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::vector<std::string>& include_paths = {});
|
||||||
|
|
||||||
|
absl::StatusOr<std::vector<AsarSymbol>> ExtractSymbols(
|
||||||
|
const std::string& asm_path,
|
||||||
|
const std::vector<std::string>& include_paths = {});
|
||||||
|
|
||||||
|
// Symbol management
|
||||||
|
std::optional<AsarSymbol> FindSymbol(const std::string& name);
|
||||||
|
std::vector<AsarSymbol> GetSymbolsAtAddress(uint32_t address);
|
||||||
|
std::map<std::string, AsarSymbol> GetSymbolTable();
|
||||||
|
|
||||||
|
// Utility functions
|
||||||
|
absl::Status ValidateAssembly(const std::string& asm_path);
|
||||||
|
std::string GetVersion();
|
||||||
|
void Reset();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Structures
|
||||||
|
|
||||||
|
#### ROM Version Support
|
||||||
|
```c
|
||||||
|
typedef enum zelda3_version {
|
||||||
|
ZELDA3_VERSION_US = 1,
|
||||||
|
ZELDA3_VERSION_JP = 2,
|
||||||
|
ZELDA3_VERSION_SD = 3,
|
||||||
|
ZELDA3_VERSION_RANDO = 4,
|
||||||
|
// Legacy aliases maintained for compatibility
|
||||||
|
US = ZELDA3_VERSION_US,
|
||||||
|
JP = ZELDA3_VERSION_JP,
|
||||||
|
SD = ZELDA3_VERSION_SD,
|
||||||
|
RANDO = ZELDA3_VERSION_RANDO,
|
||||||
|
} zelda3_version;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### SNES Graphics
|
||||||
|
```c
|
||||||
|
typedef struct snes_color {
|
||||||
|
uint16_t raw; // Raw 15-bit SNES color
|
||||||
|
uint8_t red; // Red component (0-31)
|
||||||
|
uint8_t green; // Green component (0-31)
|
||||||
|
uint8_t blue; // Blue component (0-31)
|
||||||
|
} snes_color;
|
||||||
|
|
||||||
|
typedef struct snes_palette {
|
||||||
|
uint8_t id; // Palette ID
|
||||||
|
uint8_t size; // Number of colors
|
||||||
|
snes_color* colors; // Color array
|
||||||
|
} snes_palette;
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Message System
|
||||||
|
```c
|
||||||
|
typedef struct zelda3_message {
|
||||||
|
uint16_t id; // Message ID (0-65535)
|
||||||
|
uint32_t rom_address; // Address in ROM
|
||||||
|
uint16_t length; // Length in bytes
|
||||||
|
uint8_t* raw_data; // Raw ROM data
|
||||||
|
char* parsed_text; // Decoded UTF-8 text
|
||||||
|
bool is_compressed; // Compression flag
|
||||||
|
uint8_t encoding_type; // Encoding type
|
||||||
|
} zelda3_message;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Status Codes
|
||||||
|
```c
|
||||||
|
typedef enum yaze_status {
|
||||||
|
YAZE_OK = 0, // Success
|
||||||
|
YAZE_ERROR_UNKNOWN = -1, // Unknown error
|
||||||
|
YAZE_ERROR_INVALID_ARG = 1, // Invalid argument
|
||||||
|
YAZE_ERROR_FILE_NOT_FOUND = 2, // File not found
|
||||||
|
YAZE_ERROR_MEMORY = 3, // Memory allocation failed
|
||||||
|
YAZE_ERROR_IO = 4, // I/O operation failed
|
||||||
|
YAZE_ERROR_CORRUPTION = 5, // Data corruption detected
|
||||||
|
YAZE_ERROR_NOT_INITIALIZED = 6, // Component not initialized
|
||||||
|
} yaze_status;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling Pattern
|
||||||
|
```c
|
||||||
|
yaze_status status = yaze_library_init();
|
||||||
|
if (status != YAZE_OK) {
|
||||||
|
printf("Failed to initialize YAZE: %s\n", yaze_status_to_string(status));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
zelda3_rom* rom = yaze_load_rom("zelda3.sfc");
|
||||||
|
if (rom == nullptr) {
|
||||||
|
printf("Failed to load ROM file\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use ROM...
|
||||||
|
yaze_unload_rom(rom);
|
||||||
|
yaze_library_shutdown();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Extension System
|
||||||
|
|
||||||
|
### Plugin Architecture
|
||||||
|
```c
|
||||||
|
typedef struct yaze_extension {
|
||||||
|
const char* name; // Extension name
|
||||||
|
const char* version; // Version string
|
||||||
|
const char* description; // Description
|
||||||
|
const char* author; // Author
|
||||||
|
int api_version; // Required API version
|
||||||
|
|
||||||
|
yaze_status (*initialize)(yaze_editor_context* context);
|
||||||
|
void (*cleanup)(void);
|
||||||
|
uint32_t (*get_capabilities)(void);
|
||||||
|
} yaze_extension;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Capability Flags
|
||||||
|
```c
|
||||||
|
#define YAZE_EXT_CAP_ROM_EDITING 0x0001 // ROM modification
|
||||||
|
#define YAZE_EXT_CAP_GRAPHICS 0x0002 // Graphics operations
|
||||||
|
#define YAZE_EXT_CAP_AUDIO 0x0004 // Audio processing
|
||||||
|
#define YAZE_EXT_CAP_SCRIPTING 0x0008 // Scripting support
|
||||||
|
#define YAZE_EXT_CAP_IMPORT_EXPORT 0x0010 // Data import/export
|
||||||
|
```
|
||||||
|
|
||||||
|
## Backward Compatibility
|
||||||
|
|
||||||
|
All existing code continues to work without modification due to:
|
||||||
|
- Legacy enum aliases (`US`, `JP`, `SD`, `RANDO`)
|
||||||
|
- Original struct field names maintained
|
||||||
|
- Duplicate field definitions for old/new naming conventions
|
||||||
|
- Typedef aliases for renamed types
|
||||||
173
docs/A1-testing-guide.md
Normal file
173
docs/A1-testing-guide.md
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
# Testing Guide
|
||||||
|
|
||||||
|
Comprehensive testing framework with efficient CI/CD integration and ROM-dependent test separation.
|
||||||
|
|
||||||
|
## Test Categories
|
||||||
|
|
||||||
|
### Stable Tests (STABLE)
|
||||||
|
**Always run in CI/CD - Required for releases**
|
||||||
|
|
||||||
|
- **AsarWrapperTest**: Core Asar functionality tests
|
||||||
|
- **SnesTileTest**: SNES tile format handling
|
||||||
|
- **CompressionTest**: Data compression/decompression
|
||||||
|
- **SnesPaletteTest**: SNES palette operations
|
||||||
|
- **HexTest**: Hexadecimal utilities
|
||||||
|
- **AsarIntegrationTest**: Asar integration without ROM dependencies
|
||||||
|
|
||||||
|
**Characteristics:**
|
||||||
|
- Fast execution (< 30 seconds total)
|
||||||
|
- No external dependencies (ROMs, complex setup)
|
||||||
|
- High reliability and deterministic results
|
||||||
|
|
||||||
|
### ROM-Dependent Tests (ROM_DEPENDENT)
|
||||||
|
**Only run in development with available ROM files**
|
||||||
|
|
||||||
|
- **AsarRomIntegrationTest**: Real ROM patching and symbol extraction
|
||||||
|
- **ROM-based integration tests**: Tests requiring actual game ROM files
|
||||||
|
|
||||||
|
**Characteristics:**
|
||||||
|
- Require specific ROM files to be present
|
||||||
|
- Test real-world functionality
|
||||||
|
- Automatically skipped in CI if ROM files unavailable
|
||||||
|
|
||||||
|
### Experimental Tests (EXPERIMENTAL)
|
||||||
|
**Run separately, allowed to fail**
|
||||||
|
|
||||||
|
- **CpuTest**: 65816 CPU emulation tests
|
||||||
|
- **Spc700Test**: SPC700 audio processor tests
|
||||||
|
- **ApuTest**: Audio Processing Unit tests
|
||||||
|
- **PpuTest**: Picture Processing Unit tests
|
||||||
|
|
||||||
|
**Characteristics:**
|
||||||
|
- May be unstable due to emulation complexity
|
||||||
|
- Test advanced/experimental features
|
||||||
|
- Allowed to fail without blocking releases
|
||||||
|
|
||||||
|
## Command Line Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run only stable tests (release-ready)
|
||||||
|
ctest --test-dir build --label-regex "STABLE"
|
||||||
|
|
||||||
|
# Run experimental tests (allowed to fail)
|
||||||
|
ctest --test-dir build --label-regex "EXPERIMENTAL"
|
||||||
|
|
||||||
|
# Run Asar-specific tests
|
||||||
|
ctest --test-dir build -R "*Asar*"
|
||||||
|
|
||||||
|
# Run tests excluding ROM-dependent ones
|
||||||
|
ctest --test-dir build --label-exclude "ROM_DEPENDENT"
|
||||||
|
|
||||||
|
# Run with specific preset
|
||||||
|
ctest --preset stable
|
||||||
|
ctest --preset experimental
|
||||||
|
```
|
||||||
|
|
||||||
|
## CMake Presets
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Development workflow
|
||||||
|
cmake --preset dev
|
||||||
|
cmake --build --preset dev
|
||||||
|
ctest --preset dev
|
||||||
|
|
||||||
|
# CI workflow
|
||||||
|
cmake --preset ci
|
||||||
|
cmake --build --preset ci
|
||||||
|
ctest --preset ci
|
||||||
|
|
||||||
|
# Release workflow
|
||||||
|
cmake --preset release
|
||||||
|
cmake --build --preset release
|
||||||
|
ctest --preset stable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Writing Tests
|
||||||
|
|
||||||
|
### Stable Tests
|
||||||
|
```cpp
|
||||||
|
TEST(SnesTileTest, UnpackBppTile) {
|
||||||
|
std::vector<uint8_t> tile_data = {0xAA, 0x55, 0xAA, 0x55};
|
||||||
|
std::vector<uint8_t> result = UnpackBppTile(tile_data, 2);
|
||||||
|
EXPECT_EQ(result.size(), 64);
|
||||||
|
// Test specific pixel values...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ROM-Dependent Tests
|
||||||
|
```cpp
|
||||||
|
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
|
||||||
|
auto rom_data = TestRomManager::LoadTestRom();
|
||||||
|
if (!rom_data.has_value()) {
|
||||||
|
GTEST_SKIP() << "ROM file not available";
|
||||||
|
}
|
||||||
|
|
||||||
|
AsarWrapper wrapper;
|
||||||
|
wrapper.Initialize();
|
||||||
|
|
||||||
|
auto result = wrapper.ApplyPatch("test.asm", *rom_data);
|
||||||
|
EXPECT_TRUE(result.ok());
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Experimental Tests
|
||||||
|
```cpp
|
||||||
|
TEST(CpuTest, InstructionExecution) {
|
||||||
|
// Complex emulation tests
|
||||||
|
// May be timing-sensitive or platform-dependent
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## CI/CD Integration
|
||||||
|
|
||||||
|
### GitHub Actions
|
||||||
|
```yaml
|
||||||
|
# Main CI pipeline
|
||||||
|
- name: Run Stable Tests
|
||||||
|
run: ctest --label-regex "STABLE"
|
||||||
|
|
||||||
|
# Experimental tests (allowed to fail)
|
||||||
|
- name: Run Experimental Tests
|
||||||
|
run: ctest --label-regex "EXPERIMENTAL"
|
||||||
|
continue-on-error: true
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Execution Strategy
|
||||||
|
1. **Stable tests run first** - Quick feedback for developers
|
||||||
|
2. **Experimental tests run in parallel** - Don't block on unstable tests
|
||||||
|
3. **ROM tests skipped** - No dependency on external files
|
||||||
|
4. **Selective test execution** - Only run relevant tests for changes
|
||||||
|
|
||||||
|
## Test Development Guidelines
|
||||||
|
|
||||||
|
### Writing Stable Tests
|
||||||
|
- **Fast execution**: Aim for < 1 second per test
|
||||||
|
- **No external dependencies**: Self-contained test data
|
||||||
|
- **Deterministic**: Same results every run
|
||||||
|
- **Core functionality**: Test essential features only
|
||||||
|
|
||||||
|
### Writing ROM-Dependent Tests
|
||||||
|
- **Use TestRomManager**: Proper ROM file handling
|
||||||
|
- **Graceful skipping**: Skip if ROM not available
|
||||||
|
- **Real-world scenarios**: Test with actual game data
|
||||||
|
- **Label appropriately**: Always include ROM_DEPENDENT label
|
||||||
|
|
||||||
|
### Writing Experimental Tests
|
||||||
|
- **Complex scenarios**: Multi-component integration
|
||||||
|
- **Advanced features**: Emulation, complex algorithms
|
||||||
|
- **Performance tests**: May vary by system
|
||||||
|
- **GUI components**: May require display context
|
||||||
|
|
||||||
|
## Performance and Maintenance
|
||||||
|
|
||||||
|
### Regular Review
|
||||||
|
- **Monthly review** of experimental test failures
|
||||||
|
- **Promote stable experimental tests** to stable category
|
||||||
|
- **Deprecate obsolete tests** that no longer provide value
|
||||||
|
- **Update test categorization** as features mature
|
||||||
|
|
||||||
|
### Performance Monitoring
|
||||||
|
- **Track test execution times** for CI efficiency
|
||||||
|
- **Identify slow tests** for optimization or recategorization
|
||||||
|
- **Monitor CI resource usage** and adjust parallelism
|
||||||
|
- **Benchmark critical path tests** for performance regression
|
||||||
239
docs/B1-contributing.md
Normal file
239
docs/B1-contributing.md
Normal file
@@ -0,0 +1,239 @@
|
|||||||
|
# Contributing
|
||||||
|
|
||||||
|
Guidelines for contributing to the YAZE project.
|
||||||
|
|
||||||
|
## Development Setup
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
- **CMake 3.16+**: Modern build system
|
||||||
|
- **C++23 Compiler**: GCC 13+, Clang 16+, MSVC 2022 17.8+
|
||||||
|
- **Git**: Version control with submodules
|
||||||
|
|
||||||
|
### Quick Start
|
||||||
|
```bash
|
||||||
|
# Clone with submodules
|
||||||
|
git clone --recursive https://github.com/scawful/yaze.git
|
||||||
|
cd yaze
|
||||||
|
|
||||||
|
# Build with presets
|
||||||
|
cmake --preset dev
|
||||||
|
cmake --build --preset dev
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
ctest --preset stable
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Style
|
||||||
|
|
||||||
|
### C++ Standards
|
||||||
|
- **C++23**: Use modern language features
|
||||||
|
- **Google C++ Style**: Follow Google C++ style guide
|
||||||
|
- **Naming**: Use descriptive names, avoid abbreviations
|
||||||
|
|
||||||
|
### File Organization
|
||||||
|
```cpp
|
||||||
|
// Header guards
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
// Includes (system, third-party, local)
|
||||||
|
#include <vector>
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "app/core/asar_wrapper.h"
|
||||||
|
|
||||||
|
// Namespace usage
|
||||||
|
namespace yaze::app::editor {
|
||||||
|
|
||||||
|
class ExampleClass {
|
||||||
|
public:
|
||||||
|
// Public interface
|
||||||
|
absl::Status Initialize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Private implementation
|
||||||
|
std::vector<uint8_t> data_;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
```cpp
|
||||||
|
// Use absl::Status for error handling
|
||||||
|
absl::Status LoadRom(const std::string& filename) {
|
||||||
|
if (filename.empty()) {
|
||||||
|
return absl::InvalidArgumentError("Filename cannot be empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... implementation
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use absl::StatusOr for operations that return values
|
||||||
|
absl::StatusOr<std::vector<uint8_t>> ReadFile(const std::string& filename);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing Requirements
|
||||||
|
|
||||||
|
### Test Categories
|
||||||
|
- **Stable Tests**: Fast, reliable, no external dependencies
|
||||||
|
- **ROM-Dependent Tests**: Require ROM files, skip in CI
|
||||||
|
- **Experimental Tests**: Complex, may be unstable
|
||||||
|
|
||||||
|
### Writing Tests
|
||||||
|
```cpp
|
||||||
|
// Stable test example
|
||||||
|
TEST(SnesTileTest, UnpackBppTile) {
|
||||||
|
std::vector<uint8_t> tile_data = {0xAA, 0x55};
|
||||||
|
auto result = UnpackBppTile(tile_data, 2);
|
||||||
|
EXPECT_TRUE(result.ok());
|
||||||
|
EXPECT_EQ(result->size(), 64);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ROM-dependent test example
|
||||||
|
YAZE_ROM_TEST(AsarIntegration, RealRomPatching) {
|
||||||
|
auto rom_data = TestRomManager::LoadTestRom();
|
||||||
|
if (!rom_data.has_value()) {
|
||||||
|
GTEST_SKIP() << "ROM file not available";
|
||||||
|
}
|
||||||
|
// ... test implementation
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Execution
|
||||||
|
```bash
|
||||||
|
# Run stable tests (required)
|
||||||
|
ctest --label-regex "STABLE"
|
||||||
|
|
||||||
|
# Run experimental tests (optional)
|
||||||
|
ctest --label-regex "EXPERIMENTAL"
|
||||||
|
|
||||||
|
# Run specific test
|
||||||
|
ctest -R "AsarWrapperTest"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Pull Request Process
|
||||||
|
|
||||||
|
### Before Submitting
|
||||||
|
1. **Run tests**: Ensure all stable tests pass
|
||||||
|
2. **Check formatting**: Use clang-format
|
||||||
|
3. **Update documentation**: Update relevant docs if needed
|
||||||
|
4. **Test on multiple platforms**: Verify cross-platform compatibility
|
||||||
|
|
||||||
|
### Pull Request Template
|
||||||
|
```markdown
|
||||||
|
## Description
|
||||||
|
Brief description of changes
|
||||||
|
|
||||||
|
## Type of Change
|
||||||
|
- [ ] Bug fix
|
||||||
|
- [ ] New feature
|
||||||
|
- [ ] Breaking change
|
||||||
|
- [ ] Documentation update
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
- [ ] Stable tests pass
|
||||||
|
- [ ] Manual testing completed
|
||||||
|
- [ ] Cross-platform testing (if applicable)
|
||||||
|
|
||||||
|
## Checklist
|
||||||
|
- [ ] Code follows project style guidelines
|
||||||
|
- [ ] Self-review completed
|
||||||
|
- [ ] Documentation updated
|
||||||
|
- [ ] Tests added/updated
|
||||||
|
```
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Branch Strategy
|
||||||
|
- **main**: Stable, release-ready code
|
||||||
|
- **feature/**: New features and enhancements
|
||||||
|
- **fix/**: Bug fixes
|
||||||
|
- **docs/**: Documentation updates
|
||||||
|
|
||||||
|
### Commit Messages
|
||||||
|
```
|
||||||
|
type(scope): brief description
|
||||||
|
|
||||||
|
Detailed explanation of changes, including:
|
||||||
|
- What was changed
|
||||||
|
- Why it was changed
|
||||||
|
- Any breaking changes
|
||||||
|
|
||||||
|
Fixes #issue_number
|
||||||
|
```
|
||||||
|
|
||||||
|
### Types
|
||||||
|
- **feat**: New features
|
||||||
|
- **fix**: Bug fixes
|
||||||
|
- **docs**: Documentation changes
|
||||||
|
- **style**: Code style changes
|
||||||
|
- **refactor**: Code refactoring
|
||||||
|
- **test**: Test additions/changes
|
||||||
|
- **chore**: Build/tooling changes
|
||||||
|
|
||||||
|
## Architecture Guidelines
|
||||||
|
|
||||||
|
### Component Design
|
||||||
|
- **Single Responsibility**: Each class should have one clear purpose
|
||||||
|
- **Dependency Injection**: Use dependency injection for testability
|
||||||
|
- **Interface Segregation**: Keep interfaces focused and minimal
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
- **RAII**: Use RAII for resource management
|
||||||
|
- **Smart Pointers**: Prefer unique_ptr and shared_ptr
|
||||||
|
- **Avoid Raw Pointers**: Use smart pointers or references
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
- **Profile Before Optimizing**: Measure before optimizing
|
||||||
|
- **Use Modern C++**: Leverage C++23 features for performance
|
||||||
|
- **Avoid Premature Optimization**: Focus on correctness first
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
|
||||||
|
### Code Documentation
|
||||||
|
- **Doxygen Comments**: Use Doxygen format for public APIs
|
||||||
|
- **Inline Comments**: Explain complex logic
|
||||||
|
- **README Updates**: Update relevant README files
|
||||||
|
|
||||||
|
### API Documentation
|
||||||
|
```cpp
|
||||||
|
/**
|
||||||
|
* @brief Applies an assembly patch to ROM data
|
||||||
|
* @param patch_path Path to the assembly patch file
|
||||||
|
* @param rom_data ROM data to patch (modified in place)
|
||||||
|
* @param include_paths Optional include paths for assembly
|
||||||
|
* @return Result containing success status and extracted symbols
|
||||||
|
* @throws std::invalid_argument if patch_path is empty
|
||||||
|
*/
|
||||||
|
absl::StatusOr<AsarPatchResult> ApplyPatch(
|
||||||
|
const std::string& patch_path,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::vector<std::string>& include_paths = {});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Community Guidelines
|
||||||
|
|
||||||
|
### Communication
|
||||||
|
- **Be Respectful**: Treat all contributors with respect
|
||||||
|
- **Be Constructive**: Provide helpful feedback
|
||||||
|
- **Be Patient**: Remember that everyone is learning
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
- **GitHub Issues**: Report bugs and request features
|
||||||
|
- **Discussions**: Ask questions and discuss ideas
|
||||||
|
- **Discord**: [Oracle of Secrets Discord](https://discord.gg/MBFkMTPEmk)
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
### Version Numbering
|
||||||
|
- **Semantic Versioning**: MAJOR.MINOR.PATCH
|
||||||
|
- **v0.3.1**: Current stable release
|
||||||
|
- **Pre-release**: v0.4.0-alpha, v0.4.0-beta
|
||||||
|
|
||||||
|
### Release Checklist
|
||||||
|
- [ ] All stable tests pass
|
||||||
|
- [ ] Documentation updated
|
||||||
|
- [ ] Changelog updated
|
||||||
|
- [ ] Cross-platform builds verified
|
||||||
|
- [ ] Release notes prepared
|
||||||
55
docs/B2-platform-compatibility.md
Normal file
55
docs/B2-platform-compatibility.md
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
# Platform Compatibility Improvements
|
||||||
|
|
||||||
|
Recent improvements to ensure YAZE works reliably across all supported platforms.
|
||||||
|
|
||||||
|
## Native File Dialog Support
|
||||||
|
|
||||||
|
YAZE now features native file dialogs on all platforms:
|
||||||
|
- **macOS**: Cocoa-based file selection with proper sandboxing support
|
||||||
|
- **Windows**: Windows Explorer integration with COM APIs
|
||||||
|
- **Linux**: GTK3 dialogs that match system appearance
|
||||||
|
- **Fallback**: Bespoke implementation when native dialogs unavailable
|
||||||
|
|
||||||
|
## Cross-Platform Build Reliability
|
||||||
|
|
||||||
|
Enhanced build system ensures consistent compilation:
|
||||||
|
- **Windows**: Resolved MSVC compatibility issues and dependency conflicts
|
||||||
|
- **Linux**: Fixed standard library compatibility for older distributions
|
||||||
|
- **macOS**: Proper support for both Intel and Apple Silicon architectures
|
||||||
|
- **All Platforms**: Bundled dependencies eliminate external package requirements
|
||||||
|
|
||||||
|
## Build Configuration Options
|
||||||
|
|
||||||
|
YAZE supports different build configurations for various use cases:
|
||||||
|
|
||||||
|
### Full Build (Development)
|
||||||
|
Includes all features: emulator, CLI tools, UI testing framework, and optional libraries.
|
||||||
|
|
||||||
|
### Minimal Build
|
||||||
|
Streamlined build excluding complex components, optimized for automated testing and CI environments.
|
||||||
|
|
||||||
|
## Implementation Details
|
||||||
|
|
||||||
|
The build system automatically detects platform capabilities and adjusts feature sets accordingly:
|
||||||
|
|
||||||
|
- **File Dialogs**: Uses native platform dialogs when available, with cross-platform fallbacks
|
||||||
|
- **Dependencies**: Bundles all required libraries to eliminate external package requirements
|
||||||
|
- **Testing**: Separates ROM-dependent tests from unit tests for CI compatibility
|
||||||
|
- **Architecture**: Supports both Intel and Apple Silicon on macOS without conflicts
|
||||||
|
|
||||||
|
## Platform-Specific Adaptations
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
- Complete COM-based file dialog implementation
|
||||||
|
- MSVC compatibility improvements for modern C++ features
|
||||||
|
- Resource file handling for proper application integration
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
- Cocoa-based native file dialogs with sandboxing support
|
||||||
|
- Universal binary support for Intel and Apple Silicon
|
||||||
|
- Proper bundle configuration for macOS applications
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
- GTK3 integration for native file dialogs
|
||||||
|
- Package manager integration for system dependencies
|
||||||
|
- Support for multiple compiler toolchains (GCC, Clang)
|
||||||
109
docs/B3-build-presets.md
Normal file
109
docs/B3-build-presets.md
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
# Build Presets Guide
|
||||||
|
|
||||||
|
CMake presets for development workflow and architecture-specific builds.
|
||||||
|
|
||||||
|
## 🍎 macOS ARM64 Presets (Recommended for Apple Silicon)
|
||||||
|
|
||||||
|
### For Development Work:
|
||||||
|
```bash
|
||||||
|
# ARM64-only development build with ROM testing
|
||||||
|
cmake --preset macos-dev
|
||||||
|
cmake --build --preset macos-dev
|
||||||
|
|
||||||
|
# ARM64-only debug build
|
||||||
|
cmake --preset macos-debug
|
||||||
|
cmake --build --preset macos-debug
|
||||||
|
|
||||||
|
# ARM64-only release build
|
||||||
|
cmake --preset macos-release
|
||||||
|
cmake --build --preset macos-release
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Distribution:
|
||||||
|
```bash
|
||||||
|
# Universal binary (ARM64 + x86_64) - use only when needed for distribution
|
||||||
|
cmake --preset macos-debug-universal
|
||||||
|
cmake --build --preset macos-debug-universal
|
||||||
|
|
||||||
|
cmake --preset macos-release-universal
|
||||||
|
cmake --build --preset macos-release-universal
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔧 Why This Fixes Architecture Errors
|
||||||
|
|
||||||
|
**Problem**: The original presets used `CMAKE_OSX_ARCHITECTURES: "x86_64;arm64"` which forced CMake to build universal binaries. This caused issues because:
|
||||||
|
- Dependencies like Abseil tried to use x86 SSE instructions (`-msse4.1`)
|
||||||
|
- These instructions don't exist on ARM64 processors
|
||||||
|
- Build failed with "unsupported option '-msse4.1' for target 'arm64-apple-darwin'"
|
||||||
|
|
||||||
|
**Solution**: The new ARM64-only presets use `CMAKE_OSX_ARCHITECTURES: "arm64"` which:
|
||||||
|
- ✅ Only targets ARM64 architecture
|
||||||
|
- ✅ Prevents x86-specific instruction usage
|
||||||
|
- ✅ Uses ARM64 optimizations instead
|
||||||
|
- ✅ Builds much faster (no cross-compilation)
|
||||||
|
|
||||||
|
## 📋 Available Presets
|
||||||
|
|
||||||
|
| Preset Name | Architecture | Purpose | ROM Tests |
|
||||||
|
|-------------|-------------|---------|-----------|
|
||||||
|
| `macos-dev` | ARM64 only | Development | ✅ Enabled |
|
||||||
|
| `macos-debug` | ARM64 only | Debug builds | ❌ Disabled |
|
||||||
|
| `macos-release` | ARM64 only | Release builds | ❌ Disabled |
|
||||||
|
| `macos-debug-universal` | Universal | Distribution debug | ❌ Disabled |
|
||||||
|
| `macos-release-universal` | Universal | Distribution release | ❌ Disabled |
|
||||||
|
|
||||||
|
## 🚀 Quick Start
|
||||||
|
|
||||||
|
For most development work on Apple Silicon:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clean build
|
||||||
|
rm -rf build
|
||||||
|
|
||||||
|
# Configure for ARM64 development
|
||||||
|
cmake --preset macos-dev
|
||||||
|
|
||||||
|
# Build
|
||||||
|
cmake --build --preset macos-dev
|
||||||
|
|
||||||
|
# Run tests
|
||||||
|
cmake --build --preset macos-dev --target test
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ IDE Integration
|
||||||
|
|
||||||
|
### VS Code with CMake Tools:
|
||||||
|
1. Open Command Palette (`Cmd+Shift+P`)
|
||||||
|
2. Run "CMake: Select Configure Preset"
|
||||||
|
3. Choose `macos-dev` or `macos-debug`
|
||||||
|
|
||||||
|
### CLion:
|
||||||
|
1. Go to Settings → Build, Execution, Deployment → CMake
|
||||||
|
2. Add new profile with preset `macos-dev`
|
||||||
|
|
||||||
|
### Xcode:
|
||||||
|
```bash
|
||||||
|
# Generate Xcode project
|
||||||
|
cmake --preset macos-debug -G Xcode
|
||||||
|
open build/yaze.xcodeproj
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔍 Troubleshooting
|
||||||
|
|
||||||
|
If you still get architecture errors:
|
||||||
|
1. **Clean completely**: `rm -rf build`
|
||||||
|
2. **Check preset**: Ensure you're using an ARM64 preset (not universal)
|
||||||
|
3. **Verify configuration**: Check that `CMAKE_OSX_ARCHITECTURES` shows only `arm64`
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Verify architecture setting
|
||||||
|
cmake --preset macos-debug
|
||||||
|
grep -A 5 -B 5 "CMAKE_OSX_ARCHITECTURES" build/CMakeCache.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Notes
|
||||||
|
|
||||||
|
- **ARM64 presets**: Fast builds, no architecture conflicts
|
||||||
|
- **Universal presets**: Slower builds, for distribution only
|
||||||
|
- **Deployment target**: ARM64 presets use macOS 11.0+ (when Apple Silicon was introduced)
|
||||||
|
- **Universal presets**: Still support macOS 10.15+ for backward compatibility
|
||||||
308
docs/B4-release-workflows.md
Normal file
308
docs/B4-release-workflows.md
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
# Release Workflows Documentation
|
||||||
|
|
||||||
|
YAZE uses three different GitHub Actions workflows for creating releases, each designed for specific use cases and reliability levels. This document explains the differences, use cases, and when to use each workflow.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
| Workflow | Complexity | Reliability | Use Case |
|
||||||
|
|----------|------------|-------------|----------|
|
||||||
|
| **release-simplified.yml** | Low | Basic | Quick releases, testing |
|
||||||
|
| **release.yml** | Medium | High | Standard releases |
|
||||||
|
| **release-complex.yml** | High | Maximum | Production releases, fallbacks |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Release-Simplified (`release-simplified.yml`)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
A streamlined workflow for quick releases and testing scenarios.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **Minimal Configuration**: Basic build setup with standard dependencies
|
||||||
|
- **No Fallback Mechanisms**: Direct dependency installation without error handling
|
||||||
|
- **Standard vcpkg**: Uses fixed vcpkg commit without fallback options
|
||||||
|
- **Basic Testing**: Simple executable verification
|
||||||
|
|
||||||
|
### Use Cases
|
||||||
|
- **Development Testing**: Testing release process during development
|
||||||
|
- **Beta Releases**: Quick beta or alpha releases
|
||||||
|
- **Hotfixes**: Emergency releases that need to be deployed quickly
|
||||||
|
- **CI/CD Validation**: Ensuring the basic release process works
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
```yaml
|
||||||
|
# Standard vcpkg setup
|
||||||
|
vcpkgGitCommitId: 'c8696863d371ab7f46e213d8f5ca923c4aef2a00'
|
||||||
|
# No fallback mechanisms
|
||||||
|
# Basic dependency installation
|
||||||
|
```
|
||||||
|
|
||||||
|
### Platforms Supported
|
||||||
|
- Windows (x64, x86, ARM64)
|
||||||
|
- macOS Universal
|
||||||
|
- Linux x64
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Release (`release.yml`)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
The standard production release workflow with enhanced reliability.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **Enhanced vcpkg**: Updated baseline and improved dependency management
|
||||||
|
- **Better Error Handling**: More robust error reporting and debugging
|
||||||
|
- **Comprehensive Testing**: Extended executable validation and artifact verification
|
||||||
|
- **Production Ready**: Designed for stable releases
|
||||||
|
|
||||||
|
### Use Cases
|
||||||
|
- **Stable Releases**: Official stable version releases
|
||||||
|
- **Feature Releases**: Major feature releases with full testing
|
||||||
|
- **Release Candidates**: Pre-release candidates for testing
|
||||||
|
|
||||||
|
### Configuration
|
||||||
|
```yaml
|
||||||
|
# Updated vcpkg baseline
|
||||||
|
builtin-baseline: "2024.12.12"
|
||||||
|
# Enhanced error handling
|
||||||
|
# Comprehensive testing
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advantages over Simplified
|
||||||
|
- More reliable dependency resolution
|
||||||
|
- Better error reporting
|
||||||
|
- Enhanced artifact validation
|
||||||
|
- Production-grade stability
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Release-Complex (`release-complex.yml`)
|
||||||
|
|
||||||
|
### Purpose
|
||||||
|
Maximum reliability release workflow with comprehensive fallback mechanisms.
|
||||||
|
|
||||||
|
### Key Features
|
||||||
|
- **Advanced Fallback System**: Multiple dependency installation strategies
|
||||||
|
- **vcpkg Failure Handling**: Automatic fallback to manual dependency installation
|
||||||
|
- **Chocolatey Integration**: Windows package manager fallback
|
||||||
|
- **Comprehensive Debugging**: Extensive logging and error analysis
|
||||||
|
- **Multiple Build Strategies**: CMake configuration fallbacks
|
||||||
|
- **Enhanced Validation**: Multi-stage build verification
|
||||||
|
|
||||||
|
### Use Cases
|
||||||
|
- **Production Releases**: Critical production releases requiring maximum reliability
|
||||||
|
- **Enterprise Deployments**: Releases for enterprise customers
|
||||||
|
- **Major Version Releases**: Significant version releases (v1.0, v2.0, etc.)
|
||||||
|
- **Problem Resolution**: When other workflows fail due to dependency issues
|
||||||
|
|
||||||
|
### Fallback Mechanisms
|
||||||
|
|
||||||
|
#### vcpkg Fallback
|
||||||
|
```yaml
|
||||||
|
# Primary: vcpkg installation
|
||||||
|
- name: Set up vcpkg (Windows)
|
||||||
|
continue-on-error: true
|
||||||
|
|
||||||
|
# Fallback: Manual dependency installation
|
||||||
|
- name: Install dependencies manually (Windows fallback)
|
||||||
|
if: steps.vcpkg_setup.outcome == 'failure'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Chocolatey Integration
|
||||||
|
```yaml
|
||||||
|
# Install Chocolatey if not present
|
||||||
|
if (-not (Get-Command choco -ErrorAction SilentlyContinue)) {
|
||||||
|
# Install Chocolatey
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install dependencies via Chocolatey
|
||||||
|
choco install -y cmake ninja git python3
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Build Configuration Fallback
|
||||||
|
```yaml
|
||||||
|
# Primary: Full build with vcpkg
|
||||||
|
cmake -DCMAKE_TOOLCHAIN_FILE="vcpkg.cmake" -DYAZE_MINIMAL_BUILD=OFF
|
||||||
|
|
||||||
|
# Fallback: Minimal build without vcpkg
|
||||||
|
cmake -DYAZE_MINIMAL_BUILD=ON
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
- **Multi-stage Validation**: Visual Studio project validation
|
||||||
|
- **Artifact Verification**: Comprehensive build artifact checking
|
||||||
|
- **Debug Information**: Extensive logging for troubleshooting
|
||||||
|
- **Environment Detection**: Automatic environment configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Workflow Comparison Matrix
|
||||||
|
|
||||||
|
| Feature | Simplified | Release | Complex |
|
||||||
|
|---------|------------|---------|---------|
|
||||||
|
| **vcpkg Integration** | Basic | Enhanced | Advanced + Fallback |
|
||||||
|
| **Error Handling** | Minimal | Standard | Comprehensive |
|
||||||
|
| **Fallback Mechanisms** | None | Limited | Multiple |
|
||||||
|
| **Debugging** | Basic | Standard | Extensive |
|
||||||
|
| **Dependency Management** | Fixed | Updated | Adaptive |
|
||||||
|
| **Build Validation** | Simple | Enhanced | Multi-stage |
|
||||||
|
| **Failure Recovery** | None | Limited | Automatic |
|
||||||
|
| **Production Ready** | No | Yes | Yes |
|
||||||
|
| **Build Time** | Fast | Medium | Slow |
|
||||||
|
| **Reliability** | Low | High | Maximum |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## When to Use Each Workflow
|
||||||
|
|
||||||
|
### Use Simplified When:
|
||||||
|
- ✅ Testing release process during development
|
||||||
|
- ✅ Creating beta or alpha releases
|
||||||
|
- ✅ Quick hotfix releases
|
||||||
|
- ✅ Validating basic CI/CD functionality
|
||||||
|
- ✅ Development team testing
|
||||||
|
|
||||||
|
### Use Release When:
|
||||||
|
- ✅ Creating stable production releases
|
||||||
|
- ✅ Feature releases with full testing
|
||||||
|
- ✅ Release candidates
|
||||||
|
- ✅ Standard version releases
|
||||||
|
- ✅ Most production scenarios
|
||||||
|
|
||||||
|
### Use Complex When:
|
||||||
|
- ✅ Critical production releases
|
||||||
|
- ✅ Major version releases (v1.0, v2.0)
|
||||||
|
- ✅ Enterprise customer releases
|
||||||
|
- ✅ When other workflows fail
|
||||||
|
- ✅ Maximum reliability requirements
|
||||||
|
- ✅ Complex dependency scenarios
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Workflow Selection Guide
|
||||||
|
|
||||||
|
### For Development Team
|
||||||
|
```
|
||||||
|
Development → Simplified
|
||||||
|
Testing → Release
|
||||||
|
Production → Complex
|
||||||
|
```
|
||||||
|
|
||||||
|
### For Release Manager
|
||||||
|
```
|
||||||
|
Hotfix → Simplified
|
||||||
|
Feature Release → Release
|
||||||
|
Major Release → Complex
|
||||||
|
```
|
||||||
|
|
||||||
|
### For CI/CD Pipeline
|
||||||
|
```
|
||||||
|
PR Validation → Simplified
|
||||||
|
Nightly Builds → Release
|
||||||
|
Release Pipeline → Complex
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Examples
|
||||||
|
|
||||||
|
### Triggering a Release
|
||||||
|
|
||||||
|
#### Manual Release (All Workflows)
|
||||||
|
```bash
|
||||||
|
# Using workflow_dispatch
|
||||||
|
gh workflow run release.yml -f tag=v0.3.0
|
||||||
|
gh workflow run release-simplified.yml -f tag=v0.3.0-beta
|
||||||
|
gh workflow run release-complex.yml -f tag=v1.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Automatic Release (Tag Push)
|
||||||
|
```bash
|
||||||
|
# Creates release automatically
|
||||||
|
git tag v0.3.0
|
||||||
|
git push origin v0.3.0
|
||||||
|
```
|
||||||
|
|
||||||
|
### Customizing Release Notes
|
||||||
|
All workflows support automatic changelog extraction:
|
||||||
|
```bash
|
||||||
|
# Extract changelog for version
|
||||||
|
python3 scripts/extract_changelog.py "0.3.0" > release_notes.md
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### vcpkg Failures (Windows)
|
||||||
|
- **Simplified**: Fails completely
|
||||||
|
- **Release**: Basic error reporting
|
||||||
|
- **Complex**: Automatic fallback to manual installation
|
||||||
|
|
||||||
|
#### Dependency Conflicts
|
||||||
|
- **Simplified**: Manual intervention required
|
||||||
|
- **Release**: Enhanced error reporting
|
||||||
|
- **Complex**: Multiple resolution strategies
|
||||||
|
|
||||||
|
#### Build Failures
|
||||||
|
- **Simplified**: Basic error output
|
||||||
|
- **Release**: Enhanced debugging
|
||||||
|
- **Complex**: Comprehensive failure analysis
|
||||||
|
|
||||||
|
### Debug Information
|
||||||
|
|
||||||
|
#### Simplified Workflow
|
||||||
|
- Basic build output
|
||||||
|
- Simple error messages
|
||||||
|
- Minimal logging
|
||||||
|
|
||||||
|
#### Release Workflow
|
||||||
|
- Enhanced error reporting
|
||||||
|
- Artifact verification
|
||||||
|
- Build validation
|
||||||
|
|
||||||
|
#### Complex Workflow
|
||||||
|
- Extensive debug output
|
||||||
|
- Multi-stage validation
|
||||||
|
- Comprehensive error analysis
|
||||||
|
- Automatic fallback execution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Workflow Selection
|
||||||
|
1. **Start with Simplified** for development and testing
|
||||||
|
2. **Use Release** for standard production releases
|
||||||
|
3. **Use Complex** only when maximum reliability is required
|
||||||
|
|
||||||
|
### Release Process
|
||||||
|
1. **Test with Simplified** first
|
||||||
|
2. **Validate with Release** for production readiness
|
||||||
|
3. **Use Complex** for critical releases
|
||||||
|
|
||||||
|
### Maintenance
|
||||||
|
1. **Keep all workflows updated** with latest dependency versions
|
||||||
|
2. **Monitor workflow performance** and adjust as needed
|
||||||
|
3. **Document any custom modifications** for team knowledge
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Improvements
|
||||||
|
|
||||||
|
### Planned Enhancements
|
||||||
|
- **Automated Workflow Selection**: Based on release type and criticality
|
||||||
|
- **Enhanced Fallback Strategies**: Additional dependency resolution methods
|
||||||
|
- **Performance Optimization**: Reduced build times while maintaining reliability
|
||||||
|
- **Cross-Platform Consistency**: Unified behavior across all platforms
|
||||||
|
|
||||||
|
### Integration Opportunities
|
||||||
|
- **Release Automation**: Integration with semantic versioning
|
||||||
|
- **Quality Gates**: Automated quality checks before release
|
||||||
|
- **Distribution**: Integration with package managers and app stores
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*This documentation is maintained alongside the YAZE project. For updates or corrections, please refer to the project repository.*
|
||||||
157
docs/C1-changelog.md
Normal file
157
docs/C1-changelog.md
Normal file
@@ -0,0 +1,157 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## 0.3.1
|
||||||
|
|
||||||
|
### Major Features
|
||||||
|
- **Complete Tile16 Editor Overhaul**: Professional-grade tile editing with modern UI and advanced capabilities
|
||||||
|
- **Advanced Palette Management**: Full access to all SNES palette groups with configurable normalization
|
||||||
|
- **Comprehensive Undo/Redo System**: 50-state history with intelligent time-based throttling
|
||||||
|
- **ZSCustomOverworld v3 Full Support**: Complete implementation of ZScream Save.cs functionality with complex transition calculations
|
||||||
|
- **ZEML System Removal**: Converted overworld editor from markup to pure ImGui for better performance and maintainability
|
||||||
|
- **OverworldEditorManager**: New management system to handle complex v3 overworld features
|
||||||
|
|
||||||
|
### Tile16 Editor Enhancements
|
||||||
|
- **Modern UI Layout**: Fully resizable 3-column interface (Tile8 Source, Editor, Preview & Controls)
|
||||||
|
- **Multi-Palette Group Support**: Access to Overworld Main/Aux1/Aux2, Dungeon Main, Global Sprites, Armors, and Swords palettes
|
||||||
|
- **Advanced Transform Operations**: Flip horizontal/vertical, rotate 90°, fill with tile8, clear operations
|
||||||
|
- **Professional Workflow**: Copy/paste, 4-slot scratch space, live preview with auto-commit
|
||||||
|
- **Pixel Normalization Settings**: Configurable pixel value masks (0x01-0xFF) for handling corrupted graphics sheets
|
||||||
|
|
||||||
|
### ZSCustomOverworld v3 Implementation
|
||||||
|
- **SaveLargeMapsExpanded()**: Complex neighbor-aware transition calculations for all area sizes (Small, Large, Wide, Tall)
|
||||||
|
- **Interactive Overlay System**: Full `SaveMapOverlays()` with ASM code generation for revealing holes and changing map elements
|
||||||
|
- **SaveCustomOverworldASM()**: Complete custom overworld ASM application with feature toggles and data tables
|
||||||
|
- **Expanded Memory Support**: Automatic detection and use of v3 expanded memory locations (0x140xxx)
|
||||||
|
- **Area-Specific Features**: Background colors, main palettes, mosaic transitions, GFX groups, subscreen overlays, animated tiles
|
||||||
|
- **Transition Logic**: Sophisticated camera transition calculations based on neighboring area types and quadrants
|
||||||
|
- **Version Compatibility**: Maintains vanilla/v2 compatibility while adding full v3+ feature support
|
||||||
|
|
||||||
|
### Technical Improvements
|
||||||
|
- **SNES Data Accuracy**: Proper 4-bit palette index handling with configurable normalization
|
||||||
|
- **Bitmap Pipeline Fixes**: Corrected tile16 extraction using `GetTilemapData()` with manual fallback
|
||||||
|
- **Real-time Updates**: Immediate visual feedback for all editing operations
|
||||||
|
- **Memory Safety**: Enhanced bounds checking and error handling throughout
|
||||||
|
- **ASM Version Detection**: Automatic detection of custom overworld ASM version for feature availability
|
||||||
|
- **Conditional Save Logic**: Different save paths for vanilla, v2, and v3+ ROMs
|
||||||
|
|
||||||
|
### User Interface
|
||||||
|
- **Keyboard Shortcuts**: Comprehensive shortcuts for all operations (H/V/R for transforms, Q/E for palette cycling, 1-8 for direct palette selection)
|
||||||
|
- **Visual Feedback**: Hover preview restoration, current palette highlighting, texture status indicators
|
||||||
|
- **Compact Controls**: Streamlined property panel with essential tools easily accessible
|
||||||
|
- **Settings Dialog**: Advanced palette normalization controls with real-time application
|
||||||
|
- **Pure ImGui Layout**: Removed ZEML markup system in favor of native ImGui tabs and tables for better performance
|
||||||
|
- **v3 Settings Panel**: Dedicated UI for ZSCustomOverworld v3 features with ASM version detection and feature toggles
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **Tile16 Bitmap Display**: Fixed blank/white tile issue caused by unnormalized pixel values
|
||||||
|
- **Hover Preview**: Restored tile8 preview when hovering over tile16 canvas
|
||||||
|
- **Canvas Scaling**: Corrected coordinate scaling for 8x magnification factor
|
||||||
|
- **Palette Corruption**: Fixed high-bit contamination in graphics sheets
|
||||||
|
- **UI Layout**: Proper column sizing and resizing behavior
|
||||||
|
- **Linux CI/CD Build**: Fixed undefined reference errors for `ShowSaveFileDialog` method
|
||||||
|
- **ZSCustomOverworld v3**: Fixed complex area transition calculations and neighbor-aware tilemap adjustments
|
||||||
|
- **ZEML Performance**: Eliminated markup parsing overhead by converting to native ImGui components
|
||||||
|
|
||||||
|
### ZScream Compatibility Improvements
|
||||||
|
- **Complete Save.cs Implementation**: All major methods from ZScream's Save.cs now implemented in YAZE
|
||||||
|
- **Area Size Support**: Full support for Small, Large, Wide, and Tall area types with proper transitions
|
||||||
|
- **Interactive Overlays**: Complete overlay save system matching ZScream's functionality
|
||||||
|
- **Custom ASM Integration**: Proper handling of ZSCustomOverworld ASM versions 1-3+
|
||||||
|
- **Memory Layout**: Correct usage of expanded vs vanilla memory locations based on ROM type
|
||||||
|
|
||||||
|
## 0.3.0 (September 2025)
|
||||||
|
|
||||||
|
### Major Features
|
||||||
|
- **Complete Theme Management System**: 5+ built-in themes with custom theme creation and editing
|
||||||
|
- **Multi-Session Workspace**: Work with multiple ROMs simultaneously in enhanced docked interface
|
||||||
|
- **Enhanced Welcome Screen**: Themed interface with quick access to all editors and features
|
||||||
|
- **Asar 65816 Assembler Integration**: Complete cross-platform ROM patching with assembly code
|
||||||
|
- **ZSCustomOverworld v3**: Full integration with enhanced overworld editing capabilities
|
||||||
|
- **Advanced Message Editing**: Enhanced text editing interface with improved parsing and real-time preview
|
||||||
|
- **GUI Docking System**: Improved docking and workspace management for better user workflow
|
||||||
|
- **Symbol Extraction**: Extract symbol names and opcodes from assembly files
|
||||||
|
- **Modernized Build System**: Upgraded to CMake 3.16+ with target-based configuration
|
||||||
|
|
||||||
|
### User Interface & Theming
|
||||||
|
- **Built-in Themes**: Classic YAZE, YAZE Tre, Cyberpunk, Sunset, Forest, and Midnight themes
|
||||||
|
- **Theme Editor**: Complete custom theme creation with save-to-file functionality
|
||||||
|
- **Animated Background Grid**: Optional moving grid with color breathing effects
|
||||||
|
- **Theme Import/Export**: Share custom themes with the community
|
||||||
|
- **Responsive UI**: All UI elements properly adapt to selected themes
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
- **Enhanced CLI Tools**: Improved z3ed with modern command line interface and TUI
|
||||||
|
- **CMakePresets**: Added development workflow presets for better productivity
|
||||||
|
- **Cross-Platform CI/CD**: Multi-platform automated builds and testing with lenient code quality checks
|
||||||
|
- **Professional Packaging**: NSIS, DMG, and DEB/RPM installers
|
||||||
|
- **ROM-Dependent Testing**: Separated testing infrastructure for CI compatibility with 46+ core tests
|
||||||
|
- **Comprehensive Documentation**: Updated guides, help menus, and API documentation
|
||||||
|
|
||||||
|
### Technical Improvements
|
||||||
|
- **Modern C++23**: Latest language features for performance and safety
|
||||||
|
- **Memory Safety**: Enhanced memory management with RAII and smart pointers
|
||||||
|
- **Error Handling**: Improved error handling using absl::Status throughout
|
||||||
|
- **Cross-Platform**: Consistent experience across Windows, macOS, and Linux
|
||||||
|
- **Performance**: Optimized rendering and data processing
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- **Graphics Arena Crash**: Fixed double-free error during Arena singleton destruction
|
||||||
|
- **SNES Tile Format**: Corrected tile unpacking algorithm based on SnesLab documentation
|
||||||
|
- **Palette System**: Fixed color conversion functions (ImVec4 float to uint8_t conversion)
|
||||||
|
- **CI/CD**: Fixed missing cstring include for Ubuntu compilation
|
||||||
|
- **ROM Loading**: Fixed file path issues in tests
|
||||||
|
|
||||||
|
## 0.2.2 (December 2024)
|
||||||
|
- DungeonMap editing improvements
|
||||||
|
- ZSCustomOverworld support
|
||||||
|
- Cross platform file handling
|
||||||
|
|
||||||
|
## 0.2.1 (August 2024)
|
||||||
|
- Improved MessageEditor parsing
|
||||||
|
- Added integration test window
|
||||||
|
- Bitmap bug fixes
|
||||||
|
|
||||||
|
## 0.2.0 (July 2024)
|
||||||
|
- iOS app support
|
||||||
|
- Graphics Sheet Browser
|
||||||
|
- Project Files
|
||||||
|
|
||||||
|
## 0.1.0 (May 2024)
|
||||||
|
- Bitmap bug fixes
|
||||||
|
- Error handling improvements
|
||||||
|
|
||||||
|
## 0.0.9 (April 2024)
|
||||||
|
- Documentation updates
|
||||||
|
- Entrance tile types
|
||||||
|
- Emulator subsystem overhaul
|
||||||
|
|
||||||
|
## 0.0.8 (February 2024)
|
||||||
|
- Hyrule Magic Compression
|
||||||
|
- Dungeon Room Entrances
|
||||||
|
- PNG Export
|
||||||
|
|
||||||
|
## 0.0.7 (January 2024)
|
||||||
|
- OverworldEntities
|
||||||
|
- Entrances
|
||||||
|
- Exits
|
||||||
|
- Items
|
||||||
|
- Sprites
|
||||||
|
|
||||||
|
## 0.0.6 (November 2023)
|
||||||
|
- ScreenEditor DungeonMap
|
||||||
|
- Tile16 Editor
|
||||||
|
- Canvas updates
|
||||||
|
|
||||||
|
## 0.0.5 (November 2023)
|
||||||
|
- DungeonEditor
|
||||||
|
- DungeonObjectRenderer
|
||||||
|
|
||||||
|
## 0.0.4 (November 2023)
|
||||||
|
- Tile16Editor
|
||||||
|
- GfxGroupEditor
|
||||||
|
- Add GfxGroups functions to Rom
|
||||||
|
- Add Tile16Editor and GfxGroupEditor to OverworldEditor
|
||||||
|
|
||||||
|
## 0.0.3 (October 2023)
|
||||||
|
- Emulator subsystem
|
||||||
|
- SNES PPU and PPURegisters
|
||||||
62
docs/D1-roadmap.md
Normal file
62
docs/D1-roadmap.md
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
# Roadmap
|
||||||
|
|
||||||
|
## 0.4.X (Next Major Release)
|
||||||
|
|
||||||
|
### Core Features
|
||||||
|
- **Overworld Sprites**: Complete sprite editing with add/remove functionality
|
||||||
|
- **Enhanced Dungeon Editing**: Advanced room object editing and manipulation
|
||||||
|
- **Tile16 Editing**: Enhanced editor for creating and modifying tile16 data
|
||||||
|
- **Plugin Architecture**: Framework for community extensions and custom tools
|
||||||
|
- **Graphics Sheets**: Complete editing, saving, and re-importing of sheets
|
||||||
|
- **Project Refactoring**: Clean up resource loading and memory usage
|
||||||
|
|
||||||
|
### Technical Improvements
|
||||||
|
- **Sprite Property Editor**: Add support for changing sprite behavior and attributes
|
||||||
|
- **Custom Sprites**: Support creating and editing custom sprites
|
||||||
|
- **Asar Patching**: Stabilize existing patching system for advanced modifications
|
||||||
|
|
||||||
|
## 0.5.X
|
||||||
|
|
||||||
|
### Advanced Features
|
||||||
|
- **SCAD Format**: Polish and finalize the scad file integration
|
||||||
|
- **Hex Editing Improvements**: Enhance user interface for direct ROM manipulation
|
||||||
|
- **Music Editing**: Add an interface to edit and manage music data
|
||||||
|
|
||||||
|
## 0.6.X
|
||||||
|
|
||||||
|
### Platform & Integration
|
||||||
|
- **Cross-Platform Stability**: Test and refine builds across Windows, macOS, iOS, and Linux
|
||||||
|
- **Plugin/Integration Framework**: Provide hooks or scripting for community add-ons
|
||||||
|
|
||||||
|
## 0.7.X
|
||||||
|
|
||||||
|
### Performance & Polish
|
||||||
|
- **Performance Optimizations**: Remove bottlenecks in rendering and data processing
|
||||||
|
- **Documentation Overhaul**: Update manuals, guides, and in-app tooltips
|
||||||
|
|
||||||
|
## 0.8.X
|
||||||
|
|
||||||
|
### Beta Preparation
|
||||||
|
- **Beta Release**: Code freeze on major features, focus on bug fixes and polish
|
||||||
|
- **User Interface Refinements**: Improve UI consistency, iconography, and layout
|
||||||
|
- **Internal Cleanup**: Remove deprecated code, finalize API calls
|
||||||
|
|
||||||
|
## 1.0.0
|
||||||
|
|
||||||
|
### Stable Release
|
||||||
|
- **Stable Release**: Final, production-ready version
|
||||||
|
- **Changelog**: Comprehensive summary of all changes since 0.0.0
|
||||||
|
|
||||||
|
## Current Focus Areas
|
||||||
|
|
||||||
|
### Immediate Priorities (v0.4.X)
|
||||||
|
1. **Dungeon Editor Refactoring**: Complete component-based architecture
|
||||||
|
2. **Sprite System**: Implement comprehensive sprite editing
|
||||||
|
3. **Graphics Pipeline**: Enhance graphics editing capabilities
|
||||||
|
4. **Plugin System**: Enable community extensions
|
||||||
|
|
||||||
|
### Long-term Vision
|
||||||
|
- **Community-Driven**: Robust plugin system for community contributions
|
||||||
|
- **Cross-Platform Excellence**: Seamless experience across all platforms
|
||||||
|
- **Performance**: Optimized for large ROMs and complex modifications
|
||||||
|
- **Accessibility**: User-friendly interface for both beginners and experts
|
||||||
223
docs/E1-asm-style-guide.md
Normal file
223
docs/E1-asm-style-guide.md
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
# Asm Style Guide
|
||||||
|
|
||||||
|
65816 Assembly is the assembly language used by the Super Nintendo Entertainment System (SNES) and its Ricoh 5A22 processor. This style guide provides conventions and best practices for writing 65816 assembly code in the context of the yaze project. Following these guidelines will help maintain consistency and readability across the codebase.
|
||||||
|
|
||||||
|
This guide is based primarily on the [Oracle of Secrets](https://github.com/scawful/Oracle-of-Secrets) codebase and is meant for the [Asar](https://github.com/RPGHacker/asar) assembler and derives influence from the [Asar 1.9 Manual](https://rpghacker.github.io/asar/asar_19/manual/).
|
||||||
|
|
||||||
|
Custom assembly code applied to the game should be included through the `yaze.asm` file found in `assets/asm`. This file can be applied to the ROM by the editor using the Asar library or included into a projects codebase for use with the Asar assembler.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
- [File Structure](#file-structure)
|
||||||
|
- [Labels and Symbols](#labels-and-symbols)
|
||||||
|
- [Comments](#comments)
|
||||||
|
- [Directives](#directives)
|
||||||
|
- [Instructions](#instructions)
|
||||||
|
- [Macros](#macros)
|
||||||
|
- [Loops and Branching](#loops-and-branching)
|
||||||
|
- [Data Structures](#data-structures)
|
||||||
|
- [Code Organization](#code-organization)
|
||||||
|
- [Custom Code](#custom-code)
|
||||||
|
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
- **File Extension**: Use `.asm` as the file extension for 65816 assembly files.
|
||||||
|
- **Header Comments**: Include a header comment at the beginning of each file describing its purpose and the author.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
; =========================================================
|
||||||
|
; Purpose: [Brief description of the file’s functionality]
|
||||||
|
; Author: [Your Name]
|
||||||
|
; =========================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Section Headers**: Use clear and consistent section headers to divide code into logical blocks. Each major section (e.g., sprite properties, main logic, subroutines) should start with a delineated header.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
; =========================================================
|
||||||
|
; Minecart Sprite Properties
|
||||||
|
; =========================================================
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Macro Definitions and Includes**: Place macros and include directives at the beginning of the file to keep them organized and easily accessible.
|
||||||
|
|
||||||
|
## Labels and Symbols
|
||||||
|
|
||||||
|
- **Naming Conventions**:
|
||||||
|
- **Global Labels**: Use descriptive names in `PascalCase` for global labels (e.g., `Sprite_Minecart_Main`).
|
||||||
|
- **Local Labels**: Prefix local labels with a dot (`.`) to indicate their limited scope (e.g., `.check_direction`).
|
||||||
|
- **Constants and Flags**: Use `ALL_CAPS_WITH_UNDERSCORES` for constants and flags (e.g., `!MINECART_SPEED`, `!HARVESTING_FLAG`).
|
||||||
|
- **Variables**: Use `CamelCase` for variable names to maintain readability (e.g., `LinkInCart`, `SpriteDirection`).
|
||||||
|
|
||||||
|
- **Alignment**: Align labels to the left margin for better readability. Indent instructions and comments to separate them from labels.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
Sprite_Minecart_Main:
|
||||||
|
{
|
||||||
|
JSR HandleTileDirections
|
||||||
|
JSR HandleDynamicSwitchTileDirections
|
||||||
|
RTS
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Comments
|
||||||
|
|
||||||
|
- **Purpose**: Comments should explain why the code exists and what it is intended to do, especially for complex logic.
|
||||||
|
- **Placement**:
|
||||||
|
- Comments can be placed above the code block they describe for longer explanations.
|
||||||
|
- Inline comments can be used for single lines of code where the purpose might not be immediately clear.
|
||||||
|
- **Clarity**: Avoid stating the obvious. Focus on explaining the logic rather than restating the code.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
LDA $22 : SEC : SBC $3F : STA $31 ; Adjust X position for camera movement
|
||||||
|
```
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
- **Single Line Instructions**: Combine multiple instructions on a single line using colons (`:`) where appropriate for related operations.
|
||||||
|
- **Separation**: Use line breaks to separate distinct sections of code logically, improving readability.
|
||||||
|
- **Optimization**: Always consider the most efficient instruction for the task at hand, especially in performance-critical sections.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
LDA #$01 : STA !LinkInCart ; Set Link in cart flag
|
||||||
|
```
|
||||||
|
|
||||||
|
## Macros
|
||||||
|
|
||||||
|
- **Naming**: Use `PascalCase` for macro names, with the first letter of each word capitalized (e.g., `InitMovement`, `MoveCart`).
|
||||||
|
- **Parameters**: Clearly define and document parameters within macros to ensure they are used correctly.
|
||||||
|
- **Reuse**: Encourage the reuse of macros to avoid code duplication and simplify maintenance.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
%macro HandlePlayerCamera
|
||||||
|
LDA $22 : SEC : SBC $3F : STA $31
|
||||||
|
LDA $20 : SEC : SBC $3E : STA $30
|
||||||
|
JSL Link_HandleMovingAnimation_FullLongEntry
|
||||||
|
JSL HandleIndoorCameraAndDoors
|
||||||
|
RTS
|
||||||
|
endmacro
|
||||||
|
```
|
||||||
|
|
||||||
|
## Loops and Branching
|
||||||
|
|
||||||
|
- **Branch Labels**: Use meaningful names for branch labels, prefixed with a dot (`.`) for local branches.
|
||||||
|
- **Optimization**: Minimize the number of instructions within loops and branches to improve performance.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
.loop_start
|
||||||
|
LDA $00 : CMP #$10 : BEQ .end_loop
|
||||||
|
INC $00
|
||||||
|
BRA .loop_start
|
||||||
|
.end_loop
|
||||||
|
RTS
|
||||||
|
```
|
||||||
|
|
||||||
|
## Data Structures
|
||||||
|
|
||||||
|
- **Alignment**: Align data tables and structures clearly, and use comments to describe the purpose and layout of each.
|
||||||
|
- **Access**: Ensure that data structures are accessed consistently, with clear boundaries between read and write operations.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
.DirectionTileLookup
|
||||||
|
{
|
||||||
|
db $02, $00, $04, $00 ; North
|
||||||
|
db $00, $00, $03, $01 ; East
|
||||||
|
db $00, $02, $00, $04 ; South
|
||||||
|
db $03, $01, $00, $00 ; West
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- **Structs**: Use structs to group related data together, improving readability and maintainability.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
struct AncillaAdd_HookshotData $099AF8
|
||||||
|
.speed_y: skip 4
|
||||||
|
.speed_x: skip 4
|
||||||
|
.offset_y: skip 8
|
||||||
|
.offset_x: skip 8
|
||||||
|
endstruct
|
||||||
|
|
||||||
|
AncillaAdd_Hookshot:
|
||||||
|
; $099AF0
|
||||||
|
.speed_y
|
||||||
|
db -64 ; up
|
||||||
|
db 64 ; down
|
||||||
|
db 0 ; left
|
||||||
|
db 0 ; right
|
||||||
|
; $099AFC
|
||||||
|
.speed_x
|
||||||
|
db 0 ; up
|
||||||
|
db 0 ; down
|
||||||
|
db -64 ; left
|
||||||
|
db 64 ; right
|
||||||
|
; $099B00
|
||||||
|
.offset_y
|
||||||
|
dw 4 ; up
|
||||||
|
dw 20 ; down
|
||||||
|
dw 8 ; left
|
||||||
|
dw 8 ; right
|
||||||
|
; $099B08
|
||||||
|
.offset_x
|
||||||
|
dw 0 ; up
|
||||||
|
dw 0 ; down
|
||||||
|
dw -4 ; left
|
||||||
|
dw 11 ; right
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code Organization
|
||||||
|
|
||||||
|
- **Logical Grouping**: Organize code into logical sections, with related routines and macros grouped together.
|
||||||
|
- **Separation of Concerns**: Ensure that each section of code is responsible for a specific task or set of related tasks, avoiding tightly coupled code.
|
||||||
|
- **Modularity**: Write code in a modular way, making it easier to reuse and maintain.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
; =========================================================
|
||||||
|
; Minecart Sprite Logic
|
||||||
|
; =========================================================
|
||||||
|
Sprite_Minecart_Main:
|
||||||
|
{
|
||||||
|
PHX
|
||||||
|
JSR HandleMinecartMovement
|
||||||
|
PLX
|
||||||
|
|
||||||
|
REP #$20
|
||||||
|
LDA !SpriteDirection : STA $00
|
||||||
|
SEP #$20
|
||||||
|
RTS
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Custom Code
|
||||||
|
|
||||||
|
- **Integration**: Include custom assembly code in the `yaze.asm` file to ensure it is applied correctly to the ROM. The module should include a define and conditional statement to allow users to disable the module if needed.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```asm
|
||||||
|
!YAZE_CUSTOM_MOSAIC = 1
|
||||||
|
|
||||||
|
if !YAZE_CUSTOM_MOSAIC != 0
|
||||||
|
incsrc "mosaic_change.asm"
|
||||||
|
endif
|
||||||
|
```
|
||||||
360
docs/E2-dungeon-editor-guide.md
Normal file
360
docs/E2-dungeon-editor-guide.md
Normal file
@@ -0,0 +1,360 @@
|
|||||||
|
# Dungeon Editor Guide
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Yaze Dungeon Editor is a comprehensive tool for editing Zelda 3: A Link to the Past dungeon rooms, objects, sprites, items, entrances, doors, and chests. It provides an integrated editing experience with real-time rendering, coordinate system management, and advanced features for dungeon modification.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
#### 1. DungeonEditorSystem
|
||||||
|
- **Purpose**: Central coordinator for all dungeon editing operations
|
||||||
|
- **Location**: `src/app/zelda3/dungeon/dungeon_editor_system.h/cc`
|
||||||
|
- **Features**:
|
||||||
|
- Room management (loading, saving, creating, deleting)
|
||||||
|
- Sprite management (enemies, NPCs, interactive objects)
|
||||||
|
- Item management (keys, hearts, rupees, etc.)
|
||||||
|
- Entrance/exit management (room connections)
|
||||||
|
- Door management (locked doors, key requirements)
|
||||||
|
- Chest management (treasure placement)
|
||||||
|
- Undo/redo system
|
||||||
|
- Event callbacks for real-time updates
|
||||||
|
|
||||||
|
#### 2. DungeonObjectEditor
|
||||||
|
- **Purpose**: Specialized editor for room objects (walls, floors, decorations)
|
||||||
|
- **Location**: `src/app/zelda3/dungeon/dungeon_object_editor.h/cc`
|
||||||
|
- **Features**:
|
||||||
|
- Object placement and editing
|
||||||
|
- Layer management (BG1, BG2, BG3)
|
||||||
|
- Object size editing with scroll wheel
|
||||||
|
- Collision detection and validation
|
||||||
|
- Selection and multi-selection
|
||||||
|
- Grid snapping
|
||||||
|
- Real-time preview
|
||||||
|
|
||||||
|
#### 3. ObjectRenderer
|
||||||
|
- **Purpose**: High-performance rendering system for dungeon objects
|
||||||
|
- **Location**: `src/app/zelda3/dungeon/object_renderer.h/cc`
|
||||||
|
- **Features**:
|
||||||
|
- Graphics cache for performance optimization
|
||||||
|
- Memory pool management
|
||||||
|
- Performance monitoring and statistics
|
||||||
|
- Object parsing from ROM data
|
||||||
|
- Palette support and color management
|
||||||
|
- Batch rendering for efficiency
|
||||||
|
|
||||||
|
#### 4. DungeonEditor (UI Layer)
|
||||||
|
- **Purpose**: User interface and interaction handling
|
||||||
|
- **Location**: `src/app/editor/dungeon/dungeon_editor.h/cc`
|
||||||
|
- **Features**:
|
||||||
|
- Integrated tabbed interface
|
||||||
|
- Canvas-based room editing
|
||||||
|
- Coordinate system management
|
||||||
|
- Object preview system
|
||||||
|
- Real-time rendering
|
||||||
|
- Compact editing panels
|
||||||
|
|
||||||
|
## Coordinate System
|
||||||
|
|
||||||
|
### Room Coordinates vs Canvas Coordinates
|
||||||
|
|
||||||
|
The dungeon editor uses a two-tier coordinate system:
|
||||||
|
|
||||||
|
1. **Room Coordinates**: 16x16 tile units (as used in the ROM)
|
||||||
|
2. **Canvas Coordinates**: Pixel coordinates for rendering
|
||||||
|
|
||||||
|
#### Conversion Functions
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Convert room coordinates to canvas coordinates
|
||||||
|
std::pair<int, int> RoomToCanvasCoordinates(int room_x, int room_y) const {
|
||||||
|
return {room_x * 16, room_y * 16};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert canvas coordinates to room coordinates
|
||||||
|
std::pair<int, int> CanvasToRoomCoordinates(int canvas_x, int canvas_y) const {
|
||||||
|
return {canvas_x / 16, canvas_y / 16};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if coordinates are within canvas bounds
|
||||||
|
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
### Coordinate System Features
|
||||||
|
|
||||||
|
- **Automatic Bounds Checking**: Objects outside visible canvas area are culled
|
||||||
|
- **Scrolling Support**: Canvas handles scrolling internally with proper coordinate transformation
|
||||||
|
- **Grid Alignment**: 16x16 pixel grid for precise object placement
|
||||||
|
- **Margin Support**: Configurable margins for partial object visibility
|
||||||
|
|
||||||
|
## Object Rendering System
|
||||||
|
|
||||||
|
### Object Types
|
||||||
|
|
||||||
|
The system supports three main object subtypes based on ROM structure:
|
||||||
|
|
||||||
|
1. **Subtype 1** (0x00-0xFF): Standard room objects (walls, floors, decorations)
|
||||||
|
2. **Subtype 2** (0x100-0x1FF): Interactive objects (doors, switches, chests)
|
||||||
|
3. **Subtype 3** (0x200+): Special objects (stairs, warps, bosses)
|
||||||
|
|
||||||
|
### Rendering Pipeline
|
||||||
|
|
||||||
|
1. **Object Loading**: Objects are loaded from ROM data using `LoadObjects()`
|
||||||
|
2. **Tile Parsing**: Object tiles are parsed using `ObjectParser`
|
||||||
|
3. **Graphics Caching**: Frequently used graphics are cached for performance
|
||||||
|
4. **Palette Application**: SNES palettes are applied to object graphics
|
||||||
|
5. **Canvas Rendering**: Objects are rendered to canvas with proper coordinate transformation
|
||||||
|
|
||||||
|
### Performance Optimizations
|
||||||
|
|
||||||
|
- **Graphics Cache**: Reduces redundant graphics sheet loading
|
||||||
|
- **Memory Pool**: Efficient memory allocation for rendering
|
||||||
|
- **Batch Rendering**: Multiple objects rendered in single pass
|
||||||
|
- **Bounds Culling**: Objects outside visible area are skipped
|
||||||
|
- **Cache Invalidation**: Smart cache management based on palette changes
|
||||||
|
|
||||||
|
## User Interface
|
||||||
|
|
||||||
|
### Integrated Editing Panels
|
||||||
|
|
||||||
|
The dungeon editor features a consolidated interface with:
|
||||||
|
|
||||||
|
#### Main Canvas
|
||||||
|
- **Room Visualization**: Real-time room rendering with background layers
|
||||||
|
- **Object Display**: Objects rendered with proper positioning and sizing
|
||||||
|
- **Interactive Editing**: Click-to-select, drag-to-move, scroll-to-resize
|
||||||
|
- **Grid Overlay**: Optional grid display for precise positioning
|
||||||
|
- **Coordinate Display**: Real-time coordinate information
|
||||||
|
|
||||||
|
#### Compact Editing Panels
|
||||||
|
|
||||||
|
1. **Object Editor**
|
||||||
|
- Mode selection (Select, Insert, Edit, Delete)
|
||||||
|
- Layer management (BG1, BG2, BG3)
|
||||||
|
- Object type selection
|
||||||
|
- Size editing with scroll wheel
|
||||||
|
- Configuration options (snap to grid, show grid)
|
||||||
|
|
||||||
|
2. **Sprite Editor**
|
||||||
|
- Sprite placement and management
|
||||||
|
- Enemy and NPC configuration
|
||||||
|
- Layer assignment
|
||||||
|
- Quick sprite addition
|
||||||
|
|
||||||
|
3. **Item Editor**
|
||||||
|
- Item placement (keys, hearts, rupees)
|
||||||
|
- Hidden item configuration
|
||||||
|
- Item type selection
|
||||||
|
- Room assignment
|
||||||
|
|
||||||
|
4. **Entrance Editor**
|
||||||
|
- Room connection management
|
||||||
|
- Bidirectional connection support
|
||||||
|
- Position configuration
|
||||||
|
- Connection validation
|
||||||
|
|
||||||
|
5. **Door Editor**
|
||||||
|
- Door placement and configuration
|
||||||
|
- Lock status management
|
||||||
|
- Key requirement setup
|
||||||
|
- Direction and target room assignment
|
||||||
|
|
||||||
|
6. **Chest Editor**
|
||||||
|
- Treasure chest placement
|
||||||
|
- Item and quantity configuration
|
||||||
|
- Big chest support
|
||||||
|
- Opened status tracking
|
||||||
|
|
||||||
|
7. **Properties Editor**
|
||||||
|
- Room metadata management
|
||||||
|
- Dungeon settings
|
||||||
|
- Music and ambient sound configuration
|
||||||
|
- Boss room and save room flags
|
||||||
|
|
||||||
|
### Object Preview System
|
||||||
|
|
||||||
|
- **Real-time Preview**: Objects are previewed in the canvas as they're selected
|
||||||
|
- **Centered Display**: Preview objects are centered in the canvas for optimal viewing
|
||||||
|
- **Palette Support**: Previews use current palette settings
|
||||||
|
- **Information Display**: Object properties are shown in preview window
|
||||||
|
|
||||||
|
## Integration with ZScream
|
||||||
|
|
||||||
|
The dungeon editor is designed to be compatible with ZScream C# patterns:
|
||||||
|
|
||||||
|
### Room Loading
|
||||||
|
- Uses same room loading patterns as ZScream
|
||||||
|
- Compatible with ZScream room data structures
|
||||||
|
- Supports ZScream room naming conventions
|
||||||
|
|
||||||
|
### Object Parsing
|
||||||
|
- Follows ZScream object parsing logic
|
||||||
|
- Compatible with ZScream object type definitions
|
||||||
|
- Supports ZScream size encoding
|
||||||
|
|
||||||
|
### Coordinate System
|
||||||
|
- Matches ZScream coordinate conventions
|
||||||
|
- Uses same tile size calculations
|
||||||
|
- Compatible with ZScream positioning logic
|
||||||
|
|
||||||
|
## Testing and Validation
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
|
||||||
|
The system includes comprehensive integration tests:
|
||||||
|
|
||||||
|
1. **Basic Object Rendering**: Tests fundamental object rendering functionality
|
||||||
|
2. **Multi-Palette Rendering**: Tests rendering with different palettes
|
||||||
|
3. **Real Room Object Rendering**: Tests with actual ROM room data
|
||||||
|
4. **Disassembly Room Validation**: Tests specific rooms from disassembly
|
||||||
|
5. **Performance Testing**: Measures rendering performance and memory usage
|
||||||
|
6. **Cache Effectiveness**: Tests graphics cache performance
|
||||||
|
7. **Error Handling**: Tests error conditions and edge cases
|
||||||
|
|
||||||
|
### Test Data
|
||||||
|
|
||||||
|
Tests use real ROM data from `build/bin/zelda3.sfc`:
|
||||||
|
- **Room 0x0000**: Ganon's room (from disassembly)
|
||||||
|
- **Room 0x0002, 0x0012**: Sewer rooms (from disassembly)
|
||||||
|
- **Room 0x0020**: Agahnim's tower (from disassembly)
|
||||||
|
- **Additional rooms**: 0x0001, 0x0010, 0x0033, 0x005A
|
||||||
|
|
||||||
|
### Performance Benchmarks
|
||||||
|
|
||||||
|
- **Rendering Time**: < 500ms for 100 objects
|
||||||
|
- **Memory Usage**: < 100MB for large object sets
|
||||||
|
- **Cache Hit Rate**: Optimized for frequent object access
|
||||||
|
- **Coordinate Conversion**: O(1) coordinate transformation
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Basic Object Editing
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Load a room
|
||||||
|
auto room_result = dungeon_editor_system_->GetRoom(0x0000);
|
||||||
|
|
||||||
|
// Add an object
|
||||||
|
auto status = object_editor_->InsertObject(5, 5, 0x10, 0x12, 0);
|
||||||
|
// Parameters: x, y, object_type, size, layer
|
||||||
|
|
||||||
|
// Render objects
|
||||||
|
auto result = object_renderer_->RenderObjects(objects, palette);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Coordinate Conversion
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Convert room coordinates to canvas coordinates
|
||||||
|
auto [canvas_x, canvas_y] = RoomToCanvasCoordinates(room_x, room_y);
|
||||||
|
|
||||||
|
// Check if coordinates are within bounds
|
||||||
|
if (IsWithinCanvasBounds(canvas_x, canvas_y)) {
|
||||||
|
// Render object at this position
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Object Preview
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Create preview object
|
||||||
|
auto preview_object = zelda3::RoomObject(id, 8, 8, 0x12, 0);
|
||||||
|
preview_object.set_rom(rom_);
|
||||||
|
preview_object.EnsureTilesLoaded();
|
||||||
|
|
||||||
|
// Render preview
|
||||||
|
auto result = object_renderer_->RenderObject(preview_object, palette);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### Editor Configuration
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
struct EditorConfig {
|
||||||
|
bool snap_to_grid = true;
|
||||||
|
int grid_size = 16;
|
||||||
|
bool show_grid = true;
|
||||||
|
bool show_preview = true;
|
||||||
|
bool auto_save = false;
|
||||||
|
int auto_save_interval = 300;
|
||||||
|
bool validate_objects = true;
|
||||||
|
bool show_collision_bounds = false;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Configuration
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Object renderer settings
|
||||||
|
object_renderer_->SetCacheSize(100);
|
||||||
|
object_renderer_->EnablePerformanceMonitoring(true);
|
||||||
|
|
||||||
|
// Canvas settings
|
||||||
|
canvas_.SetCanvasSize(ImVec2(512, 512));
|
||||||
|
canvas_.set_draggable(true);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Objects Not Displaying**
|
||||||
|
- Check if ROM is loaded
|
||||||
|
- Verify object tiles are loaded with `EnsureTilesLoaded()`
|
||||||
|
- Check coordinate bounds with `IsWithinCanvasBounds()`
|
||||||
|
|
||||||
|
2. **Coordinate Misalignment**
|
||||||
|
- Use coordinate conversion functions
|
||||||
|
- Check canvas scrolling settings
|
||||||
|
- Verify grid alignment
|
||||||
|
|
||||||
|
3. **Performance Issues**
|
||||||
|
- Enable graphics caching
|
||||||
|
- Check memory usage with `GetMemoryUsage()`
|
||||||
|
- Monitor performance stats with `GetPerformanceStats()`
|
||||||
|
|
||||||
|
4. **Preview Not Showing**
|
||||||
|
- Verify object is within canvas bounds
|
||||||
|
- Check palette is properly set
|
||||||
|
- Ensure object has valid tiles
|
||||||
|
|
||||||
|
### Debug Information
|
||||||
|
|
||||||
|
The system provides comprehensive debug information:
|
||||||
|
- Object count and statistics
|
||||||
|
- Cache hit/miss rates
|
||||||
|
- Memory usage tracking
|
||||||
|
- Performance metrics
|
||||||
|
- Coordinate system validation
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
|
||||||
|
1. **Advanced Object Editing**
|
||||||
|
- Multi-object selection and manipulation
|
||||||
|
- Object grouping and layers
|
||||||
|
- Advanced collision detection
|
||||||
|
|
||||||
|
2. **Enhanced Rendering**
|
||||||
|
- Real-time lighting effects
|
||||||
|
- Animation support
|
||||||
|
- Advanced shader effects
|
||||||
|
|
||||||
|
3. **Improved UX**
|
||||||
|
- Keyboard shortcuts
|
||||||
|
- Context menus
|
||||||
|
- Undo/redo visualization
|
||||||
|
|
||||||
|
4. **Integration Features**
|
||||||
|
- ZScream project import/export
|
||||||
|
- Collaborative editing
|
||||||
|
- Version control integration
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
The Yaze Dungeon Editor provides a comprehensive, high-performance solution for editing Zelda 3 dungeon rooms. With its integrated interface, robust coordinate system, and advanced rendering capabilities, it offers both novice and expert users the tools needed to create and modify dungeon content effectively.
|
||||||
|
|
||||||
|
The system's compatibility with ZScream patterns and comprehensive testing ensure reliability and consistency with existing tools, while its modern architecture provides a foundation for future enhancements and features.
|
||||||
364
docs/E3-dungeon-editor-design.md
Normal file
364
docs/E3-dungeon-editor-design.md
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
# Dungeon Editor Design Plan
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This document provides a comprehensive guide for future developers working on the Zelda 3 Dungeon Editor system. The dungeon editor has been refactored into a modular, component-based architecture that separates concerns and improves maintainability.
|
||||||
|
|
||||||
|
## Architecture Overview
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
The dungeon editor system consists of several key components:
|
||||||
|
|
||||||
|
1. **DungeonEditor** - Main orchestrator class that manages the overall editor state
|
||||||
|
2. **DungeonRoomSelector** - Handles room and entrance selection UI
|
||||||
|
3. **DungeonCanvasViewer** - Manages the main canvas rendering and room display
|
||||||
|
4. **DungeonObjectSelector** - Provides object selection, editing panels, and tile graphics
|
||||||
|
5. **ObjectRenderer** - Core rendering engine for dungeon objects
|
||||||
|
6. **DungeonEditorSystem** - High-level system for managing dungeon editing operations
|
||||||
|
|
||||||
|
### File Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/app/editor/dungeon/
|
||||||
|
├── dungeon_editor.h/cc # Main editor orchestrator
|
||||||
|
├── dungeon_room_selector.h/cc # Room/entrance selection component
|
||||||
|
├── dungeon_canvas_viewer.h/cc # Canvas rendering component
|
||||||
|
├── dungeon_object_selector.h/cc # Object editing component
|
||||||
|
└── dungeon_editor_system.h/cc # Core editing system
|
||||||
|
|
||||||
|
src/app/zelda3/dungeon/
|
||||||
|
├── object_renderer.h/cc # Object rendering engine
|
||||||
|
├── dungeon_object_editor.h/cc # Object editing logic
|
||||||
|
├── room.h/cc # Room data structures
|
||||||
|
├── room_object.h/cc # Object data structures
|
||||||
|
└── room_entrance.h/cc # Entrance data structures
|
||||||
|
```
|
||||||
|
|
||||||
|
## Component Responsibilities
|
||||||
|
|
||||||
|
### DungeonEditor (Main Orchestrator)
|
||||||
|
|
||||||
|
**Responsibilities:**
|
||||||
|
- Manages overall editor state and ROM data
|
||||||
|
- Coordinates between UI components
|
||||||
|
- Handles data initialization and propagation
|
||||||
|
- Implements the 3-column layout (Room Selector | Canvas | Object Selector)
|
||||||
|
|
||||||
|
**Key Methods:**
|
||||||
|
- `UpdateDungeonRoomView()` - Main UI update loop
|
||||||
|
- `Load()` - Initialize editor with ROM data
|
||||||
|
- `set_rom()` - Update ROM reference across components
|
||||||
|
|
||||||
|
### DungeonRoomSelector
|
||||||
|
|
||||||
|
**Responsibilities:**
|
||||||
|
- Room selection and navigation
|
||||||
|
- Entrance selection and editing
|
||||||
|
- Active room management
|
||||||
|
- Room list display with names
|
||||||
|
|
||||||
|
**Key Methods:**
|
||||||
|
- `Draw()` - Main rendering method
|
||||||
|
- `DrawRoomSelector()` - Room list and selection
|
||||||
|
- `DrawEntranceSelector()` - Entrance editing interface
|
||||||
|
- `set_rom()`, `set_rooms()`, `set_entrances()` - Data access methods
|
||||||
|
|
||||||
|
### DungeonCanvasViewer
|
||||||
|
|
||||||
|
**Responsibilities:**
|
||||||
|
- Main canvas rendering and display
|
||||||
|
- Room graphics loading and management
|
||||||
|
- Object rendering with proper coordinates
|
||||||
|
- Background layer management
|
||||||
|
- Coordinate conversion (room ↔ canvas)
|
||||||
|
|
||||||
|
**Key Methods:**
|
||||||
|
- `Draw(int room_id)` - Main canvas rendering
|
||||||
|
- `LoadAndRenderRoomGraphics()` - Graphics loading
|
||||||
|
- `RenderObjectInCanvas()` - Object rendering
|
||||||
|
- `RoomToCanvasCoordinates()` - Coordinate conversion
|
||||||
|
- `RenderRoomBackgroundLayers()` - Background rendering
|
||||||
|
|
||||||
|
### DungeonObjectSelector
|
||||||
|
|
||||||
|
**Responsibilities:**
|
||||||
|
- Object selection and preview
|
||||||
|
- Tile graphics display
|
||||||
|
- Compact editing panels for all editor modes
|
||||||
|
- Object renderer integration
|
||||||
|
|
||||||
|
**Key Methods:**
|
||||||
|
- `Draw()` - Main rendering with tabbed interface
|
||||||
|
- `DrawRoomGraphics()` - Tile graphics display
|
||||||
|
- `DrawIntegratedEditingPanels()` - Editing interface
|
||||||
|
- `DrawCompactObjectEditor()` - Object editing controls
|
||||||
|
- `DrawCompactSpriteEditor()` - Sprite editing controls
|
||||||
|
- Similar methods for Items, Entrances, Doors, Chests, Properties
|
||||||
|
|
||||||
|
## Data Flow
|
||||||
|
|
||||||
|
### Initialization Flow
|
||||||
|
|
||||||
|
1. **ROM Loading**: `DungeonEditor::Load()` is called with ROM data
|
||||||
|
2. **Component Setup**: ROM and data pointers are propagated to all components
|
||||||
|
3. **Graphics Initialization**: Room graphics are loaded and cached
|
||||||
|
4. **UI State Setup**: Active rooms, palettes, and editor modes are initialized
|
||||||
|
|
||||||
|
### Runtime Data Flow
|
||||||
|
|
||||||
|
1. **User Interaction**: User selects rooms, objects, or editing modes
|
||||||
|
2. **State Updates**: Components update their internal state
|
||||||
|
3. **Data Propagation**: Changes are communicated between components
|
||||||
|
4. **Rendering**: All components re-render with updated data
|
||||||
|
|
||||||
|
### Key Data Structures
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Main editor state
|
||||||
|
std::array<zelda3::Room, 0x128> rooms_;
|
||||||
|
std::array<zelda3::RoomEntrance, 0x8C> entrances_;
|
||||||
|
ImVector<int> active_rooms_;
|
||||||
|
gfx::PaletteGroup current_palette_group_;
|
||||||
|
|
||||||
|
// Component instances
|
||||||
|
DungeonRoomSelector room_selector_;
|
||||||
|
DungeonCanvasViewer canvas_viewer_;
|
||||||
|
DungeonObjectSelector object_selector_;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration Patterns
|
||||||
|
|
||||||
|
### Component Communication
|
||||||
|
|
||||||
|
Components communicate through:
|
||||||
|
1. **Direct method calls** - Parent calls child methods
|
||||||
|
2. **Data sharing** - Shared pointers to common data structures
|
||||||
|
3. **Event propagation** - State changes trigger updates
|
||||||
|
|
||||||
|
### ROM Data Management
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// ROM propagation pattern
|
||||||
|
void DungeonEditor::set_rom(Rom* rom) {
|
||||||
|
rom_ = rom;
|
||||||
|
room_selector_.set_rom(rom);
|
||||||
|
canvas_viewer_.SetRom(rom);
|
||||||
|
object_selector_.SetRom(rom);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### State Synchronization
|
||||||
|
|
||||||
|
Components maintain their own state but receive updates from the main editor:
|
||||||
|
- Room selection state is managed by `DungeonRoomSelector`
|
||||||
|
- Canvas rendering state is managed by `DungeonCanvasViewer`
|
||||||
|
- Object editing state is managed by `DungeonObjectSelector`
|
||||||
|
|
||||||
|
## UI Layout Architecture
|
||||||
|
|
||||||
|
### 3-Column Layout
|
||||||
|
|
||||||
|
The main editor uses a 3-column ImGui table layout:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
if (BeginTable("#DungeonEditTable", 3, kDungeonTableFlags, ImVec2(0, 0))) {
|
||||||
|
TableSetupColumn("Room/Entrance Selector", ImGuiTableColumnFlags_WidthFixed, 250);
|
||||||
|
TableSetupColumn("Canvas", ImGuiTableColumnFlags_WidthStretch);
|
||||||
|
TableSetupColumn("Object Selector/Editor", ImGuiTableColumnFlags_WidthFixed, 300);
|
||||||
|
|
||||||
|
// Column 1: Room Selector
|
||||||
|
TableNextColumn();
|
||||||
|
room_selector_.Draw();
|
||||||
|
|
||||||
|
// Column 2: Canvas
|
||||||
|
TableNextColumn();
|
||||||
|
canvas_viewer_.Draw(current_room);
|
||||||
|
|
||||||
|
// Column 3: Object Selector
|
||||||
|
TableNextColumn();
|
||||||
|
object_selector_.Draw();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Component Internal Layout
|
||||||
|
|
||||||
|
Each component manages its own internal layout:
|
||||||
|
- **DungeonRoomSelector**: Tabbed interface (Rooms | Entrances)
|
||||||
|
- **DungeonCanvasViewer**: Canvas with controls and debug popup
|
||||||
|
- **DungeonObjectSelector**: Tabbed interface (Graphics | Editor)
|
||||||
|
|
||||||
|
## Coordinate System
|
||||||
|
|
||||||
|
### Room Coordinates vs Canvas Coordinates
|
||||||
|
|
||||||
|
- **Room Coordinates**: 16x16 tile units (0-15 for a standard room)
|
||||||
|
- **Canvas Coordinates**: Pixel coordinates for rendering
|
||||||
|
- **Conversion**: `RoomToCanvasCoordinates(x, y) = (x * 16, y * 16)`
|
||||||
|
|
||||||
|
### Bounds Checking
|
||||||
|
|
||||||
|
All rendering operations include bounds checking:
|
||||||
|
```cpp
|
||||||
|
bool IsWithinCanvasBounds(int canvas_x, int canvas_y, int margin = 32) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling & Validation
|
||||||
|
|
||||||
|
### ROM Validation
|
||||||
|
|
||||||
|
All components validate ROM state before operations:
|
||||||
|
```cpp
|
||||||
|
if (!rom_ || !rom_->is_loaded()) {
|
||||||
|
ImGui::Text("ROM not loaded");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bounds Validation
|
||||||
|
|
||||||
|
Graphics operations include bounds checking:
|
||||||
|
```cpp
|
||||||
|
if (room_id < 0 || room_id >= rooms_->size()) {
|
||||||
|
return; // Skip invalid operations
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Considerations
|
||||||
|
|
||||||
|
### Caching Strategy
|
||||||
|
|
||||||
|
- **Object Render Cache**: Cached rendered bitmaps to avoid re-rendering
|
||||||
|
- **Graphics Cache**: Cached graphics sheets for frequently accessed data
|
||||||
|
- **Memory Pool**: Efficient memory allocation for temporary objects
|
||||||
|
|
||||||
|
### Rendering Optimization
|
||||||
|
|
||||||
|
- **Viewport Culling**: Objects outside visible area are not rendered
|
||||||
|
- **Lazy Loading**: Graphics are loaded only when needed
|
||||||
|
- **Selective Updates**: Only changed components re-render
|
||||||
|
|
||||||
|
## Testing Strategy
|
||||||
|
|
||||||
|
### Integration Tests
|
||||||
|
|
||||||
|
The system includes comprehensive integration tests:
|
||||||
|
- `dungeon_object_renderer_integration_test.cc` - Core rendering tests
|
||||||
|
- `dungeon_editor_system_integration_test.cc` - System integration tests
|
||||||
|
- `dungeon_object_renderer_mock_test.cc` - Mock ROM testing
|
||||||
|
|
||||||
|
### Test Categories
|
||||||
|
|
||||||
|
1. **Real ROM Tests**: Tests with actual Zelda 3 ROM data
|
||||||
|
2. **Mock ROM Tests**: Tests with simulated ROM data
|
||||||
|
3. **Performance Tests**: Rendering performance benchmarks
|
||||||
|
4. **Error Handling Tests**: Validation and error recovery
|
||||||
|
|
||||||
|
## Future Development Guidelines
|
||||||
|
|
||||||
|
### Adding New Features
|
||||||
|
|
||||||
|
1. **Identify Component**: Determine which component should handle the feature
|
||||||
|
2. **Extend Interface**: Add necessary methods to component header
|
||||||
|
3. **Implement Logic**: Add implementation in component source file
|
||||||
|
4. **Update Integration**: Modify main editor to use new functionality
|
||||||
|
5. **Add Tests**: Create tests for new functionality
|
||||||
|
|
||||||
|
### Component Extension Patterns
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Adding new data access method
|
||||||
|
void Component::SetNewData(const NewDataType& data) {
|
||||||
|
new_data_ = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding new rendering method
|
||||||
|
void Component::DrawNewFeature() {
|
||||||
|
// Implementation
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding to main Draw method
|
||||||
|
void Component::Draw() {
|
||||||
|
// Existing code
|
||||||
|
DrawNewFeature();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Flow Extension
|
||||||
|
|
||||||
|
When adding new data types:
|
||||||
|
1. Add to main editor state
|
||||||
|
2. Create setter methods in relevant components
|
||||||
|
3. Update initialization in `Load()` method
|
||||||
|
4. Add to `set_rom()` propagation if ROM-dependent
|
||||||
|
|
||||||
|
### UI Layout Extension
|
||||||
|
|
||||||
|
For new UI elements:
|
||||||
|
1. Determine placement (new tab, new panel, etc.)
|
||||||
|
2. Follow existing ImGui patterns
|
||||||
|
3. Maintain consistent spacing and styling
|
||||||
|
4. Add to appropriate component's Draw method
|
||||||
|
|
||||||
|
## Common Pitfalls & Solutions
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
- **Issue**: Dangling pointers to ROM data
|
||||||
|
- **Solution**: Always validate ROM state before use
|
||||||
|
|
||||||
|
### Coordinate System
|
||||||
|
|
||||||
|
- **Issue**: Objects rendering at wrong positions
|
||||||
|
- **Solution**: Use coordinate conversion helper methods
|
||||||
|
|
||||||
|
### State Synchronization
|
||||||
|
|
||||||
|
- **Issue**: Components showing stale data
|
||||||
|
- **Solution**: Ensure data propagation in setter methods
|
||||||
|
|
||||||
|
### Performance Issues
|
||||||
|
|
||||||
|
- **Issue**: Slow rendering with many objects
|
||||||
|
- **Solution**: Implement viewport culling and caching
|
||||||
|
|
||||||
|
## Debugging Tools
|
||||||
|
|
||||||
|
### Debug Popup
|
||||||
|
|
||||||
|
The canvas viewer includes a comprehensive debug popup with:
|
||||||
|
- Object statistics and metadata
|
||||||
|
- Cache information
|
||||||
|
- Performance metrics
|
||||||
|
- Object type breakdowns
|
||||||
|
|
||||||
|
### Logging
|
||||||
|
|
||||||
|
Key operations include logging for debugging:
|
||||||
|
```cpp
|
||||||
|
std::cout << "Loading room graphics for room " << room_id << std::endl;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Build Integration
|
||||||
|
|
||||||
|
### CMake Configuration
|
||||||
|
|
||||||
|
New components are automatically included via:
|
||||||
|
```cmake
|
||||||
|
# In CMakeLists.txt
|
||||||
|
file(GLOB YAZE_SRC_FILES "src/app/editor/dungeon/*.cc")
|
||||||
|
```
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
|
||||||
|
Key dependencies:
|
||||||
|
- ImGui for UI rendering
|
||||||
|
- gfx library for graphics operations
|
||||||
|
- zelda3 library for ROM data structures
|
||||||
|
- absl for status handling
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
This modular architecture provides a solid foundation for future dungeon editor development. The separation of concerns makes the codebase maintainable, testable, and extensible. Future developers should follow the established patterns and extend components rather than modifying the main orchestrator class.
|
||||||
|
|
||||||
|
For questions or clarifications, refer to the existing integration tests and component implementations as examples of proper usage patterns.
|
||||||
248
docs/E4-dungeon-editor-refactoring.md
Normal file
248
docs/E4-dungeon-editor-refactoring.md
Normal file
@@ -0,0 +1,248 @@
|
|||||||
|
# DungeonEditor Refactoring Plan
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This document outlines the comprehensive refactoring of the 1444-line `dungeon_editor.cc` file into focused, single-responsibility components.
|
||||||
|
|
||||||
|
## Component Structure
|
||||||
|
|
||||||
|
### ✅ Created Components
|
||||||
|
|
||||||
|
#### 1. DungeonToolset (`dungeon_toolset.h/cc`)
|
||||||
|
**Responsibility**: Toolbar UI management
|
||||||
|
- Background layer selection (All/BG1/BG2/BG3)
|
||||||
|
- Placement mode selection (Object/Sprite/Item/etc.)
|
||||||
|
- Undo/Redo buttons with callbacks
|
||||||
|
- **Replaces**: `DrawToolset()` method (~70 lines)
|
||||||
|
|
||||||
|
#### 2. DungeonObjectInteraction (`dungeon_object_interaction.h/cc`)
|
||||||
|
**Responsibility**: Object selection and placement
|
||||||
|
- Mouse interaction handling
|
||||||
|
- Object selection rectangle (like OverworldEditor)
|
||||||
|
- Drag and drop operations
|
||||||
|
- Coordinate conversion utilities
|
||||||
|
- **Replaces**: All mouse/selection methods (~400 lines)
|
||||||
|
|
||||||
|
#### 3. DungeonRenderer (`dungeon_renderer.h/cc`)
|
||||||
|
**Responsibility**: All rendering operations
|
||||||
|
- Object rendering with caching
|
||||||
|
- Background layer composition
|
||||||
|
- Layout object visualization
|
||||||
|
- Render cache management
|
||||||
|
- **Replaces**: All rendering methods (~200 lines)
|
||||||
|
|
||||||
|
#### 4. DungeonRoomLoader (`dungeon_room_loader.h/cc`)
|
||||||
|
**Responsibility**: ROM data loading
|
||||||
|
- Room loading from ROM
|
||||||
|
- Room size calculation
|
||||||
|
- Entrance loading
|
||||||
|
- Graphics loading coordination
|
||||||
|
- **Replaces**: Room loading methods (~150 lines)
|
||||||
|
|
||||||
|
#### 5. DungeonUsageTracker (`dungeon_usage_tracker.h/cc`)
|
||||||
|
**Responsibility**: Resource usage analysis
|
||||||
|
- Blockset/spriteset/palette usage tracking
|
||||||
|
- Usage statistics display
|
||||||
|
- Resource optimization insights
|
||||||
|
- **Replaces**: Usage statistics methods (~100 lines)
|
||||||
|
|
||||||
|
## Refactored DungeonEditor Structure
|
||||||
|
|
||||||
|
### Before Refactoring: 1444 lines
|
||||||
|
```cpp
|
||||||
|
class DungeonEditor {
|
||||||
|
// 30+ methods handling everything
|
||||||
|
// Mixed responsibilities
|
||||||
|
// Large data structures
|
||||||
|
// Complex dependencies
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### After Refactoring: ~400 lines
|
||||||
|
```cpp
|
||||||
|
class DungeonEditor {
|
||||||
|
// Core editor interface (unchanged)
|
||||||
|
void Initialize() override;
|
||||||
|
absl::Status Load() override;
|
||||||
|
absl::Status Update() override;
|
||||||
|
absl::Status Save() override;
|
||||||
|
|
||||||
|
// High-level UI orchestration
|
||||||
|
absl::Status UpdateDungeonRoomView();
|
||||||
|
void DrawCanvasAndPropertiesPanel();
|
||||||
|
void DrawRoomPropertiesDebugPopup();
|
||||||
|
|
||||||
|
// Component coordination
|
||||||
|
void OnRoomSelected(int room_id);
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Focused components
|
||||||
|
DungeonToolset toolset_;
|
||||||
|
DungeonObjectInteraction object_interaction_;
|
||||||
|
DungeonRenderer renderer_;
|
||||||
|
DungeonRoomLoader room_loader_;
|
||||||
|
DungeonUsageTracker usage_tracker_;
|
||||||
|
|
||||||
|
// Existing UI components
|
||||||
|
DungeonRoomSelector room_selector_;
|
||||||
|
DungeonCanvasViewer canvas_viewer_;
|
||||||
|
DungeonObjectSelector object_selector_;
|
||||||
|
|
||||||
|
// Core data and state
|
||||||
|
std::array<zelda3::Room, 0x128> rooms_;
|
||||||
|
bool is_loaded_ = false;
|
||||||
|
// etc.
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Method Migration Map
|
||||||
|
|
||||||
|
### Core Editor Methods (Keep in main file)
|
||||||
|
- ✅ `Initialize()` - Component initialization
|
||||||
|
- ✅ `Load()` - Delegates to room_loader_
|
||||||
|
- ✅ `Update()` - High-level update coordination
|
||||||
|
- ✅ `Save()`, `Undo()`, `Redo()` - Editor interface
|
||||||
|
- ✅ `UpdateDungeonRoomView()` - UI orchestration
|
||||||
|
|
||||||
|
### UI Methods (Keep for coordination)
|
||||||
|
- ✅ `DrawCanvasAndPropertiesPanel()` - Tab management
|
||||||
|
- ✅ `DrawRoomPropertiesDebugPopup()` - Debug popup
|
||||||
|
- ✅ `DrawDungeonTabView()` - Room tab management
|
||||||
|
- ✅ `DrawDungeonCanvas()` - Canvas coordination
|
||||||
|
- ✅ `OnRoomSelected()` - Room selection handling
|
||||||
|
|
||||||
|
### Methods Moved to Components
|
||||||
|
|
||||||
|
#### → DungeonToolset
|
||||||
|
- ❌ `DrawToolset()` - Toolbar rendering
|
||||||
|
|
||||||
|
#### → DungeonObjectInteraction
|
||||||
|
- ❌ `HandleCanvasMouseInput()` - Mouse handling
|
||||||
|
- ❌ `CheckForObjectSelection()` - Selection rectangle
|
||||||
|
- ❌ `DrawObjectSelectRect()` - Selection drawing
|
||||||
|
- ❌ `SelectObjectsInRect()` - Selection logic
|
||||||
|
- ❌ `PlaceObjectAtPosition()` - Object placement
|
||||||
|
- ❌ `DrawSelectBox()` - Selection visualization
|
||||||
|
- ❌ `DrawDragPreview()` - Drag preview
|
||||||
|
- ❌ `UpdateSelectedObjects()` - Selection updates
|
||||||
|
- ❌ `IsObjectInSelectBox()` - Selection testing
|
||||||
|
- ❌ Coordinate conversion helpers
|
||||||
|
|
||||||
|
#### → DungeonRenderer
|
||||||
|
- ❌ `RenderObjectInCanvas()` - Object rendering
|
||||||
|
- ❌ `DisplayObjectInfo()` - Object info overlay
|
||||||
|
- ❌ `RenderLayoutObjects()` - Layout rendering
|
||||||
|
- ❌ `RenderRoomBackgroundLayers()` - Background rendering
|
||||||
|
- ❌ `RefreshGraphics()` - Graphics refresh
|
||||||
|
- ❌ Object cache management
|
||||||
|
|
||||||
|
#### → DungeonRoomLoader
|
||||||
|
- ❌ `LoadDungeonRoomSize()` - Room size calculation
|
||||||
|
- ❌ `LoadAndRenderRoomGraphics()` - Graphics loading
|
||||||
|
- ❌ `ReloadAllRoomGraphics()` - Bulk reload
|
||||||
|
- ❌ Room size and address management
|
||||||
|
|
||||||
|
#### → DungeonUsageTracker
|
||||||
|
- ❌ `CalculateUsageStats()` - Usage calculation
|
||||||
|
- ❌ `DrawUsageStats()` - Usage display
|
||||||
|
- ❌ `DrawUsageGrid()` - Usage visualization
|
||||||
|
- ❌ `RenderSetUsage()` - Set usage rendering
|
||||||
|
|
||||||
|
## Component Communication
|
||||||
|
|
||||||
|
### Callback System
|
||||||
|
```cpp
|
||||||
|
// Object placement callback
|
||||||
|
object_interaction_.SetObjectPlacedCallback([this](const auto& object) {
|
||||||
|
renderer_.ClearObjectCache();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Toolset callbacks
|
||||||
|
toolset_.SetUndoCallback([this]() { Undo(); });
|
||||||
|
toolset_.SetPaletteToggleCallback([this]() { palette_showing_ = !palette_showing_; });
|
||||||
|
|
||||||
|
// Object selection callback
|
||||||
|
object_selector_.SetObjectSelectedCallback([this](const auto& object) {
|
||||||
|
object_interaction_.SetPreviewObject(object, true);
|
||||||
|
toolset_.set_placement_type(DungeonToolset::kObject);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Sharing
|
||||||
|
```cpp
|
||||||
|
// Update components with current room
|
||||||
|
void OnRoomSelected(int room_id) {
|
||||||
|
current_room_id_ = room_id;
|
||||||
|
object_interaction_.SetCurrentRoom(&rooms_, room_id);
|
||||||
|
// etc.
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits of Refactoring
|
||||||
|
|
||||||
|
### 1. **Reduced Complexity**
|
||||||
|
- Main file: 1444 → ~400 lines (72% reduction)
|
||||||
|
- Single responsibility per component
|
||||||
|
- Clear separation of concerns
|
||||||
|
|
||||||
|
### 2. **Improved Testability**
|
||||||
|
- Individual components can be unit tested
|
||||||
|
- Mocking becomes easier
|
||||||
|
- Isolated functionality testing
|
||||||
|
|
||||||
|
### 3. **Better Maintainability**
|
||||||
|
- Changes isolated to relevant components
|
||||||
|
- Easier to locate and fix bugs
|
||||||
|
- Cleaner code reviews
|
||||||
|
|
||||||
|
### 4. **Enhanced Extensibility**
|
||||||
|
- New features added to appropriate components
|
||||||
|
- Component interfaces allow easy replacement
|
||||||
|
- Plugin-style architecture possible
|
||||||
|
|
||||||
|
### 5. **Cleaner Dependencies**
|
||||||
|
- UI separate from data manipulation
|
||||||
|
- Rendering separate from business logic
|
||||||
|
- Clear component boundaries
|
||||||
|
|
||||||
|
## Implementation Status
|
||||||
|
|
||||||
|
### ✅ Completed
|
||||||
|
- Created all component header files
|
||||||
|
- Created component implementation stubs
|
||||||
|
- Updated DungeonEditor header with components
|
||||||
|
- Basic component integration
|
||||||
|
|
||||||
|
### 🔄 In Progress
|
||||||
|
- Method migration from main file to components
|
||||||
|
- Component callback setup
|
||||||
|
- Legacy method removal
|
||||||
|
|
||||||
|
### ⏳ Pending
|
||||||
|
- Full method implementation in components
|
||||||
|
- Complete integration testing
|
||||||
|
- Documentation updates
|
||||||
|
- Build system updates
|
||||||
|
|
||||||
|
## Migration Strategy
|
||||||
|
|
||||||
|
### Phase 1: Create Components ✅
|
||||||
|
- Define component interfaces
|
||||||
|
- Create header and implementation files
|
||||||
|
- Set up basic structure
|
||||||
|
|
||||||
|
### Phase 2: Integrate Components 🔄
|
||||||
|
- Add components to DungeonEditor
|
||||||
|
- Set up callback systems
|
||||||
|
- Begin method delegation
|
||||||
|
|
||||||
|
### Phase 3: Move Methods
|
||||||
|
- Systematically move methods to components
|
||||||
|
- Update method calls to use components
|
||||||
|
- Remove old implementations
|
||||||
|
|
||||||
|
### Phase 4: Cleanup
|
||||||
|
- Remove unused member variables
|
||||||
|
- Clean up includes
|
||||||
|
- Update documentation
|
||||||
|
|
||||||
|
This refactoring transforms the monolithic DungeonEditor into a well-organized, component-based architecture that's easier to maintain, test, and extend.
|
||||||
271
docs/E5-dungeon-object-system.md
Normal file
271
docs/E5-dungeon-object-system.md
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
# Dungeon Object System
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The Dungeon Object System provides a comprehensive framework for editing and managing dungeon rooms, objects, and layouts in The Legend of Zelda: A Link to the Past. This system combines real-time visual editing with precise data manipulation to create a powerful dungeon creation and modification toolkit.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
### Core Components
|
||||||
|
|
||||||
|
The dungeon system is built around several key components that work together to provide a seamless editing experience:
|
||||||
|
|
||||||
|
#### 1. DungeonEditor (`src/app/editor/dungeon/dungeon_editor.h`)
|
||||||
|
The main interface that orchestrates all dungeon editing functionality. It provides:
|
||||||
|
- **Windowed Canvas System**: Fixed-size canvas that prevents UI layout disruption
|
||||||
|
- **Tabbed Room Interface**: Multiple rooms can be open simultaneously for easy comparison and editing
|
||||||
|
- **Integrated Object Placement**: Direct object placement from selector to canvas
|
||||||
|
- **Real-time Preview**: Live object preview follows mouse cursor during placement
|
||||||
|
|
||||||
|
#### 2. DungeonObjectSelector (`src/app/editor/dungeon/dungeon_object_selector.h`)
|
||||||
|
Combines object browsing and editing in a unified interface:
|
||||||
|
- **Object Browser**: Visual grid of all available objects with real-time previews
|
||||||
|
- **Object Editor**: Integrated editing panels for sprites, items, entrances, doors, and chests
|
||||||
|
- **Callback System**: Notifies main editor when objects are selected for placement
|
||||||
|
|
||||||
|
#### 3. DungeonCanvasViewer (`src/app/editor/dungeon/dungeon_canvas_viewer.h`)
|
||||||
|
Specialized canvas for rendering dungeon rooms:
|
||||||
|
- **Background Layer Rendering**: Proper BG1/BG2 layer composition
|
||||||
|
- **Object Rendering**: Cached object rendering with palette support
|
||||||
|
- **Coordinate System**: Seamless translation between room and canvas coordinates
|
||||||
|
|
||||||
|
#### 4. Room Management System (`src/app/zelda3/dungeon/room.h`)
|
||||||
|
Core data structures for room representation:
|
||||||
|
- **Room Objects**: Tile-based objects (walls, floors, decorations)
|
||||||
|
- **Room Layout**: Structural elements and collision data
|
||||||
|
- **Sprites**: Enemy and NPC placement
|
||||||
|
- **Entrances/Exits**: Room connections and transitions
|
||||||
|
|
||||||
|
## Object Types and Hierarchies
|
||||||
|
|
||||||
|
### Room Objects
|
||||||
|
Room objects are the fundamental building blocks of dungeon rooms. They follow a hierarchical structure:
|
||||||
|
|
||||||
|
#### Type 1 Objects (0x00-0xFF)
|
||||||
|
Basic structural elements:
|
||||||
|
- **0x10-0x1F**: Wall objects (various types and orientations)
|
||||||
|
- **0x20-0x2F**: Floor tiles (stone, wood, carpet, etc.)
|
||||||
|
- **0x30-0x3F**: Decorative elements (torches, statues, pillars)
|
||||||
|
- **0x40-0x4F**: Interactive elements (switches, blocks)
|
||||||
|
|
||||||
|
#### Type 2 Objects (0x100-0x1FF)
|
||||||
|
Complex multi-tile objects:
|
||||||
|
- **0x100-0x10F**: Large wall sections
|
||||||
|
- **0x110-0x11F**: Complex floor patterns
|
||||||
|
- **0x120-0x12F**: Multi-tile decorations
|
||||||
|
|
||||||
|
#### Type 3 Objects (0x200+)
|
||||||
|
Special dungeon-specific objects:
|
||||||
|
- **0x200-0x20F**: Boss room elements
|
||||||
|
- **0x210-0x21F**: Puzzle-specific objects
|
||||||
|
- **0xF9-0xFA**: Chests (small and large)
|
||||||
|
|
||||||
|
### Object Properties
|
||||||
|
Each object has several key properties:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class RoomObject {
|
||||||
|
int id_; // Object type identifier
|
||||||
|
int x_, y_; // Position in room (16x16 tile units)
|
||||||
|
int size_; // Size modifier (affects rendering)
|
||||||
|
LayerType layer_; // Rendering layer (0=BG, 1=MID, 2=FG)
|
||||||
|
// ... additional properties
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## How Object Placement Works
|
||||||
|
|
||||||
|
### Selection Process
|
||||||
|
1. **Object Browser**: User selects an object from the visual grid
|
||||||
|
2. **Preview Generation**: Object is rendered with current room palette
|
||||||
|
3. **Callback Trigger**: Selection notifies main editor via callback
|
||||||
|
4. **Preview Update**: Main editor receives object and enables placement mode
|
||||||
|
|
||||||
|
### Placement Process
|
||||||
|
1. **Mouse Tracking**: Preview object follows mouse cursor on canvas
|
||||||
|
2. **Coordinate Translation**: Mouse position converted to room coordinates
|
||||||
|
3. **Visual Feedback**: Semi-transparent preview shows placement position
|
||||||
|
4. **Click Placement**: Left-click places object at current position
|
||||||
|
5. **Room Update**: Object added to room data and cache cleared for redraw
|
||||||
|
|
||||||
|
### Code Flow
|
||||||
|
```cpp
|
||||||
|
// Object selection in DungeonObjectSelector
|
||||||
|
if (ImGui::Selectable("", is_selected)) {
|
||||||
|
preview_object_ = selected_object;
|
||||||
|
object_loaded_ = true;
|
||||||
|
|
||||||
|
// Notify main editor
|
||||||
|
if (object_selected_callback_) {
|
||||||
|
object_selected_callback_(preview_object_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Object placement in DungeonEditor
|
||||||
|
void PlaceObjectAtPosition(int room_x, int room_y) {
|
||||||
|
auto new_object = preview_object_;
|
||||||
|
new_object.x_ = room_x;
|
||||||
|
new_object.y_ = room_y;
|
||||||
|
new_object.set_rom(rom_);
|
||||||
|
new_object.EnsureTilesLoaded();
|
||||||
|
|
||||||
|
room.AddTileObject(new_object);
|
||||||
|
object_render_cache_.clear(); // Force redraw
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Rendering Pipeline
|
||||||
|
|
||||||
|
### Object Rendering
|
||||||
|
The system uses a sophisticated rendering pipeline:
|
||||||
|
|
||||||
|
1. **Tile Loading**: Object tiles loaded from ROM based on object ID
|
||||||
|
2. **Palette Application**: Room-specific palette applied to object
|
||||||
|
3. **Bitmap Generation**: Object rendered to bitmap with proper composition
|
||||||
|
4. **Caching**: Rendered objects cached for performance
|
||||||
|
5. **Canvas Drawing**: Bitmap drawn to canvas at correct position
|
||||||
|
|
||||||
|
### Performance Optimizations
|
||||||
|
- **Render Caching**: Objects cached based on ID, position, size, and palette hash
|
||||||
|
- **Bounds Checking**: Only objects within canvas bounds are rendered
|
||||||
|
- **Lazy Loading**: Graphics and objects loaded on-demand
|
||||||
|
- **Palette Hashing**: Efficient cache invalidation when palettes change
|
||||||
|
|
||||||
|
## User Interface Components
|
||||||
|
|
||||||
|
### Three-Column Layout
|
||||||
|
The dungeon editor uses a carefully designed three-column layout:
|
||||||
|
|
||||||
|
#### Column 1: Room Control Panel (280px fixed)
|
||||||
|
- **Room Selector**: Browse and select rooms
|
||||||
|
- **Debug Controls**: Room properties in table format
|
||||||
|
- **Object Statistics**: Live object counts and cache status
|
||||||
|
|
||||||
|
#### Column 2: Windowed Canvas (800px fixed)
|
||||||
|
- **Tabbed Interface**: Multiple rooms open simultaneously
|
||||||
|
- **Fixed Dimensions**: Prevents UI layout disruption
|
||||||
|
- **Real-time Preview**: Object placement preview follows cursor
|
||||||
|
- **Layer Visualization**: Proper background/foreground rendering
|
||||||
|
|
||||||
|
#### Column 3: Object Selector/Editor (stretch)
|
||||||
|
- **Object Browser Tab**: Visual grid of available objects
|
||||||
|
- **Object Editor Tab**: Integrated editing for sprites, items, etc.
|
||||||
|
- **Placement Tools**: Object property editing and placement controls
|
||||||
|
|
||||||
|
### Debug and Control Features
|
||||||
|
|
||||||
|
#### Room Properties Table
|
||||||
|
Real-time editing of room attributes:
|
||||||
|
```
|
||||||
|
Property | Value
|
||||||
|
------------|--------
|
||||||
|
Room ID | 0x001 (1)
|
||||||
|
Layout | [Hex Input]
|
||||||
|
Blockset | [Hex Input]
|
||||||
|
Spriteset | [Hex Input]
|
||||||
|
Palette | [Hex Input]
|
||||||
|
Floor 1 | [Hex Input]
|
||||||
|
Floor 2 | [Hex Input]
|
||||||
|
Message ID | [Hex Input]
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Object Statistics
|
||||||
|
Live feedback on room contents:
|
||||||
|
- Total objects count
|
||||||
|
- Layout objects count
|
||||||
|
- Sprites count
|
||||||
|
- Chests count
|
||||||
|
- Cache status and controls
|
||||||
|
|
||||||
|
## Integration with ROM Data
|
||||||
|
|
||||||
|
### Data Sources
|
||||||
|
The system integrates with multiple ROM data sources:
|
||||||
|
|
||||||
|
#### Room Headers (`0x1F8000`)
|
||||||
|
- Room layout index
|
||||||
|
- Blockset and spriteset references
|
||||||
|
- Palette assignments
|
||||||
|
- Floor type definitions
|
||||||
|
|
||||||
|
#### Object Data
|
||||||
|
- Object definitions and tile mappings
|
||||||
|
- Size and layer information
|
||||||
|
- Interaction properties
|
||||||
|
|
||||||
|
#### Graphics Data
|
||||||
|
- Tile graphics (4bpp SNES format)
|
||||||
|
- Palette data (15-color palettes)
|
||||||
|
- Blockset compositions
|
||||||
|
|
||||||
|
### Assembly Integration
|
||||||
|
The system references the US disassembly (`assets/asm/usdasm/`) for:
|
||||||
|
- Room data structure validation
|
||||||
|
- Object type definitions
|
||||||
|
- Memory layout verification
|
||||||
|
- Data pointer validation
|
||||||
|
|
||||||
|
## Comparison with ZScream
|
||||||
|
|
||||||
|
### Architectural Differences
|
||||||
|
YAZE's approach differs from ZScream in several key ways:
|
||||||
|
|
||||||
|
#### Component-Based Architecture
|
||||||
|
- **YAZE**: Modular components with clear separation of concerns
|
||||||
|
- **ZScream**: More monolithic approach with integrated functionality
|
||||||
|
|
||||||
|
#### Real-time Rendering
|
||||||
|
- **YAZE**: Live object preview with mouse tracking
|
||||||
|
- **ZScream**: Static preview with separate placement step
|
||||||
|
|
||||||
|
#### UI Organization
|
||||||
|
- **YAZE**: Fixed-width columns prevent layout disruption
|
||||||
|
- **ZScream**: Resizable panels that can affect overall layout
|
||||||
|
|
||||||
|
#### Caching Strategy
|
||||||
|
- **YAZE**: Sophisticated object render caching with hash-based invalidation
|
||||||
|
- **ZScream**: Simpler caching approach
|
||||||
|
|
||||||
|
### Shared Concepts
|
||||||
|
Both systems share fundamental concepts:
|
||||||
|
- Object-based room construction
|
||||||
|
- Layer-based rendering
|
||||||
|
- ROM data integration
|
||||||
|
- Visual object browsing
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Performance
|
||||||
|
1. **Use Render Caching**: Don't clear cache unnecessarily
|
||||||
|
2. **Bounds Checking**: Only render visible objects
|
||||||
|
3. **Lazy Loading**: Load graphics and objects on-demand
|
||||||
|
4. **Efficient Callbacks**: Minimize callback frequency
|
||||||
|
|
||||||
|
### Code Organization
|
||||||
|
1. **Separation of Concerns**: Keep UI, data, and rendering separate
|
||||||
|
2. **Clear Interfaces**: Use callbacks for component communication
|
||||||
|
3. **Error Handling**: Validate ROM data and handle errors gracefully
|
||||||
|
4. **Memory Management**: Clean up resources properly
|
||||||
|
|
||||||
|
### User Experience
|
||||||
|
1. **Visual Feedback**: Provide clear object placement preview
|
||||||
|
2. **Consistent Layout**: Use fixed dimensions for stable UI
|
||||||
|
3. **Contextual Information**: Show relevant object properties
|
||||||
|
4. **Efficient Workflow**: Minimize clicks for common operations
|
||||||
|
|
||||||
|
## Future Enhancements
|
||||||
|
|
||||||
|
### Planned Features
|
||||||
|
1. **Drag and Drop**: Direct object dragging from selector to canvas
|
||||||
|
2. **Multi-Selection**: Select and manipulate multiple objects
|
||||||
|
3. **Copy/Paste**: Copy object configurations between rooms
|
||||||
|
4. **Undo/Redo**: Full edit history management
|
||||||
|
5. **Template System**: Save and load room templates
|
||||||
|
|
||||||
|
### Technical Improvements
|
||||||
|
1. **GPU Acceleration**: Move rendering to GPU for better performance
|
||||||
|
2. **Advanced Caching**: Predictive loading and intelligent cache management
|
||||||
|
3. **Background Processing**: Asynchronous ROM data loading
|
||||||
|
4. **Memory Optimization**: Reduce memory footprint for large dungeons
|
||||||
|
|
||||||
|
This documentation provides a comprehensive understanding of how the YAZE dungeon object system works, from high-level architecture to low-level implementation details. The system is designed to be both powerful for advanced users and accessible for newcomers to dungeon editing.
|
||||||
492
docs/F1-overworld-loading.md
Normal file
492
docs/F1-overworld-loading.md
Normal file
@@ -0,0 +1,492 @@
|
|||||||
|
# Overworld Loading Guide
|
||||||
|
|
||||||
|
This document provides a comprehensive guide to understanding how overworld loading works in both ZScream (C#) and yaze (C++), including the differences between vanilla ROMs and ZSCustomOverworld v2/v3 ROMs.
|
||||||
|
|
||||||
|
## Table of Contents
|
||||||
|
|
||||||
|
1. [Overview](#overview)
|
||||||
|
2. [ROM Types and Versions](#rom-types-and-versions)
|
||||||
|
3. [Overworld Map Structure](#overworld-map-structure)
|
||||||
|
4. [Loading Process](#loading-process)
|
||||||
|
5. [ZScream Implementation](#zscream-implementation)
|
||||||
|
6. [Yaze Implementation](#yaze-implementation)
|
||||||
|
7. [Key Differences](#key-differences)
|
||||||
|
8. [Common Issues and Solutions](#common-issues-and-solutions)
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Both ZScream and yaze are Zelda 3 ROM editors that support editing overworld maps. They handle three main types of ROMs:
|
||||||
|
|
||||||
|
- **Vanilla ROMs**: Original Zelda 3 ROMs without modifications
|
||||||
|
- **ZSCustomOverworld v2**: ROMs with expanded overworld features
|
||||||
|
- **ZSCustomOverworld v3**: ROMs with additional features like overlays and custom background colors
|
||||||
|
|
||||||
|
## ROM Types and Versions
|
||||||
|
|
||||||
|
### Version Detection
|
||||||
|
|
||||||
|
Both editors detect the ROM version using the same constant:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Address: 0x140145
|
||||||
|
constexpr int OverworldCustomASMHasBeenApplied = 0x140145;
|
||||||
|
|
||||||
|
// Version values:
|
||||||
|
// 0xFF = Vanilla ROM
|
||||||
|
// 0x02 = ZSCustomOverworld v2
|
||||||
|
// 0x03 = ZSCustomOverworld v3
|
||||||
|
```
|
||||||
|
|
||||||
|
### Feature Support by Version
|
||||||
|
|
||||||
|
| Feature | Vanilla | v2 | v3 |
|
||||||
|
|---------|---------|----|----|
|
||||||
|
| Basic Overworld Maps | ✅ | ✅ | ✅ |
|
||||||
|
| Area Size Enum | ❌ | ❌ | ✅ |
|
||||||
|
| Main Palette | ❌ | ✅ | ✅ |
|
||||||
|
| Custom Background Colors | ❌ | ✅ | ✅ |
|
||||||
|
| Subscreen Overlays | ✅ | ✅ | ✅ |
|
||||||
|
| Animated GFX | ❌ | ❌ | ✅ |
|
||||||
|
| Custom Tile Graphics | ❌ | ❌ | ✅ |
|
||||||
|
| Vanilla Overlays | ✅ | ✅ | ✅ |
|
||||||
|
|
||||||
|
**Note:** Subscreen overlays are visual effects (fog, rain, backgrounds, etc.) that are shared between vanilla ROMs and ZSCustomOverworld. ZSCustomOverworld v2+ expands on this by adding support for custom overlay configurations and additional overlay types.
|
||||||
|
|
||||||
|
## Overworld Map Structure
|
||||||
|
|
||||||
|
### Core Properties
|
||||||
|
|
||||||
|
Each overworld map contains the following core properties:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class OverworldMap {
|
||||||
|
// Basic properties
|
||||||
|
uint8_t index_; // Map index (0-159)
|
||||||
|
uint8_t parent_; // Parent map ID
|
||||||
|
uint8_t world_; // World type (0=LW, 1=DW, 2=SW)
|
||||||
|
uint8_t game_state_; // Game state (0=Beginning, 1=Zelda, 2=Agahnim)
|
||||||
|
|
||||||
|
// Graphics and palettes
|
||||||
|
uint8_t area_graphics_; // Area graphics ID
|
||||||
|
uint8_t area_palette_; // Area palette ID
|
||||||
|
uint8_t main_palette_; // Main palette ID (v2+)
|
||||||
|
std::array<uint8_t, 3> sprite_graphics_; // Sprite graphics IDs
|
||||||
|
std::array<uint8_t, 3> sprite_palette_; // Sprite palette IDs
|
||||||
|
|
||||||
|
// Map properties
|
||||||
|
uint16_t message_id_; // Message ID
|
||||||
|
bool mosaic_; // Mosaic effect enabled
|
||||||
|
bool large_map_; // Is large map (vanilla)
|
||||||
|
AreaSizeEnum area_size_; // Area size (v3)
|
||||||
|
|
||||||
|
// Custom features (v2/v3)
|
||||||
|
uint16_t area_specific_bg_color_; // Custom background color
|
||||||
|
uint16_t subscreen_overlay_; // Subscreen overlay ID (references special area maps)
|
||||||
|
uint8_t animated_gfx_; // Animated graphics ID
|
||||||
|
std::array<uint8_t, 8> custom_gfx_ids_; // Custom tile graphics
|
||||||
|
|
||||||
|
// Overlay support (vanilla and custom)
|
||||||
|
uint16_t vanilla_overlay_id_; // Vanilla overlay ID
|
||||||
|
bool has_vanilla_overlay_; // Has vanilla overlay data
|
||||||
|
std::vector<uint8_t> vanilla_overlay_data_; // Raw overlay data
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
## Overlays and Special Area Maps
|
||||||
|
|
||||||
|
### Understanding Overlays
|
||||||
|
|
||||||
|
Overlays in Zelda 3 are **visual effects** that are displayed over or behind the main overworld map. They include effects like fog, rain, canopy, backgrounds, and other atmospheric elements. Overlays are collections of tile positions and tile IDs that specify where to place specific graphics on the map.
|
||||||
|
|
||||||
|
### Special Area Maps (0x80-0x9F)
|
||||||
|
|
||||||
|
The special area maps (0x80-0x9F) contain the actual tile data for overlays. These maps store the graphics that overlays reference and use to create visual effects:
|
||||||
|
|
||||||
|
- **0x80-0x8F**: Various special area maps containing overlay graphics
|
||||||
|
- **0x90-0x9F**: Additional special area maps including more overlay graphics
|
||||||
|
|
||||||
|
### Overlay ID Mappings
|
||||||
|
|
||||||
|
Overlay IDs directly correspond to special area map indices. Common overlay mappings:
|
||||||
|
|
||||||
|
| Overlay ID | Special Area Map | Description |
|
||||||
|
|------------|------------------|-------------|
|
||||||
|
| 0x0093 | 0x93 | Triforce Room Curtain |
|
||||||
|
| 0x0094 | 0x94 | Under the Bridge |
|
||||||
|
| 0x0095 | 0x95 | Sky Background (LW Death Mountain) |
|
||||||
|
| 0x0096 | 0x96 | Pyramid Background |
|
||||||
|
| 0x0097 | 0x97 | First Fog Overlay (Master Sword Area) |
|
||||||
|
| 0x009C | 0x9C | Lava Background (DW Death Mountain) |
|
||||||
|
| 0x009D | 0x9D | Second Fog Overlay (Lost Woods/Skull Woods) |
|
||||||
|
| 0x009E | 0x9E | Tree Canopy (Forest) |
|
||||||
|
| 0x009F | 0x9F | Rain Effect (Misery Mire) |
|
||||||
|
|
||||||
|
### Drawing Order
|
||||||
|
|
||||||
|
Overlays are drawn in a specific order based on their type:
|
||||||
|
|
||||||
|
- **Background Overlays** (0x95, 0x96, 0x9C): Drawn behind the main map tiles
|
||||||
|
- **Foreground Overlays** (0x9D, 0x97, 0x93, 0x94, 0x9E, 0x9F): Drawn on top of the main map tiles with transparency
|
||||||
|
|
||||||
|
### Vanilla Overlay Loading
|
||||||
|
|
||||||
|
In vanilla ROMs, overlays are loaded by parsing SNES assembly-like commands that specify tile positions and IDs:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
absl::Status LoadVanillaOverlay() {
|
||||||
|
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
||||||
|
|
||||||
|
// Only load vanilla overlays for vanilla ROMs
|
||||||
|
if (asm_version != 0xFF) {
|
||||||
|
has_vanilla_overlay_ = false;
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load overlay pointer for this map
|
||||||
|
int address = (kOverlayPointersBank << 16) +
|
||||||
|
((*rom_)[kOverlayPointers + (index_ * 2) + 1] << 8) +
|
||||||
|
(*rom_)[kOverlayPointers + (index_ * 2)];
|
||||||
|
|
||||||
|
// Parse overlay commands:
|
||||||
|
// LDA #$xxxx - Load tile ID into accumulator
|
||||||
|
// LDX #$xxxx - Load position into X register
|
||||||
|
// STA $xxxx - Store tile at position
|
||||||
|
// STA $xxxx,x - Store tile at position + X
|
||||||
|
// INC A - Increment accumulator (for sequential tiles)
|
||||||
|
// JMP $xxxx - Jump to another overlay routine
|
||||||
|
// END (0x60) - End of overlay data
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Special Area Graphics Loading
|
||||||
|
|
||||||
|
Special area maps require special handling for graphics loading:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void LoadAreaInfo() {
|
||||||
|
if (parent_ >= kSpecialWorldMapIdStart) {
|
||||||
|
// Special World (SW) areas
|
||||||
|
if (asm_version >= 3 && asm_version != 0xFF) {
|
||||||
|
// Use expanded sprite tables for v3
|
||||||
|
sprite_graphics_[0] = (*rom_)[kOverworldSpecialSpriteGfxGroupExpandedTemp +
|
||||||
|
parent_ - kSpecialWorldMapIdStart];
|
||||||
|
} else {
|
||||||
|
// Use original sprite tables for v2/vanilla
|
||||||
|
sprite_graphics_[0] = (*rom_)[kOverworldSpecialGfxGroup +
|
||||||
|
parent_ - kSpecialWorldMapIdStart];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle special cases for specific maps
|
||||||
|
if (index_ == 0x88 || index_ == 0x93) {
|
||||||
|
area_graphics_ = 0x51;
|
||||||
|
area_palette_ = 0x00;
|
||||||
|
} else if (index_ == 0x95) {
|
||||||
|
// Make this the same GFX as LW death mountain areas
|
||||||
|
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x03];
|
||||||
|
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x03];
|
||||||
|
} else if (index_ == 0x96) {
|
||||||
|
// Make this the same GFX as pyramid areas
|
||||||
|
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x5B];
|
||||||
|
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x5B];
|
||||||
|
} else if (index_ == 0x9C) {
|
||||||
|
// Make this the same GFX as DW death mountain areas
|
||||||
|
area_graphics_ = (*rom_)[kAreaGfxIdPtr + 0x43];
|
||||||
|
area_palette_ = (*rom_)[kOverworldMapPaletteIds + 0x43];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Loading Process
|
||||||
|
|
||||||
|
### 1. Version Detection
|
||||||
|
|
||||||
|
Both editors first detect the ROM version:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
uint8_t asm_version = rom[OverworldCustomASMHasBeenApplied];
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Map Initialization
|
||||||
|
|
||||||
|
For each of the 160 overworld maps (0x00-0x9F):
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// ZScream
|
||||||
|
var map = new OverworldMap(index, overworld);
|
||||||
|
|
||||||
|
// Yaze
|
||||||
|
OverworldMap map(index, rom);
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Property Loading
|
||||||
|
|
||||||
|
The loading process varies by ROM version:
|
||||||
|
|
||||||
|
#### Vanilla ROMs (asm_version == 0xFF)
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void LoadAreaInfo() {
|
||||||
|
// Load from vanilla tables
|
||||||
|
message_id_ = rom[kOverworldMessageIds + index_ * 2];
|
||||||
|
area_graphics_ = rom[kOverworldMapGfx + index_];
|
||||||
|
area_palette_ = rom[kOverworldMapPaletteIds + index_];
|
||||||
|
|
||||||
|
// Determine large map status
|
||||||
|
large_map_ = (rom[kOverworldMapSize + index_] != 0);
|
||||||
|
|
||||||
|
// Load vanilla overlay
|
||||||
|
LoadVanillaOverlay();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### ZSCustomOverworld v2/v3
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void LoadAreaInfo() {
|
||||||
|
// Use expanded tables for v3
|
||||||
|
if (asm_version >= 3) {
|
||||||
|
message_id_ = rom[kOverworldMessagesExpanded + index_ * 2];
|
||||||
|
area_size_ = static_cast<AreaSizeEnum>(rom[kOverworldScreenSize + index_]);
|
||||||
|
} else {
|
||||||
|
message_id_ = rom[kOverworldMessageIds + index_ * 2];
|
||||||
|
area_size_ = large_map_ ? LargeArea : SmallArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load custom overworld data
|
||||||
|
LoadCustomOverworldData();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Custom Data Loading
|
||||||
|
|
||||||
|
For ZSCustomOverworld ROMs:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
void LoadCustomOverworldData() {
|
||||||
|
// Load main palette
|
||||||
|
main_palette_ = rom[OverworldCustomMainPaletteArray + index_];
|
||||||
|
|
||||||
|
// Load custom background color
|
||||||
|
if (rom[OverworldCustomAreaSpecificBGEnabled] != 0) {
|
||||||
|
area_specific_bg_color_ = rom[OverworldCustomAreaSpecificBGPalette + index_ * 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load v3 features
|
||||||
|
if (asm_version >= 3) {
|
||||||
|
subscreen_overlay_ = rom[OverworldCustomSubscreenOverlayArray + index_ * 2];
|
||||||
|
animated_gfx_ = rom[OverworldCustomAnimatedGFXArray + index_];
|
||||||
|
|
||||||
|
// Load custom tile graphics (8 sheets)
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
custom_gfx_ids_[i] = rom[OverworldCustomTileGFXGroupArray + index_ * 8 + i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## ZScream Implementation
|
||||||
|
|
||||||
|
### OverworldMap Constructor
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
public OverworldMap(byte index, Overworld overworld) {
|
||||||
|
Index = index;
|
||||||
|
this.overworld = overworld;
|
||||||
|
|
||||||
|
// Load area info
|
||||||
|
LoadAreaInfo();
|
||||||
|
|
||||||
|
// Load custom data if available
|
||||||
|
if (ROM.DATA[Constants.OverworldCustomASMHasBeenApplied] != 0xFF) {
|
||||||
|
LoadCustomOverworldData();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build graphics and palette
|
||||||
|
BuildMap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Methods
|
||||||
|
|
||||||
|
- `LoadAreaInfo()`: Loads basic map properties from ROM
|
||||||
|
- `LoadCustomOverworldData()`: Loads ZSCustomOverworld features
|
||||||
|
- `LoadPalette()`: Loads and processes palette data
|
||||||
|
- `BuildMap()`: Constructs the final map bitmap
|
||||||
|
|
||||||
|
**Note**: ZScream is the original C# implementation that yaze is designed to be compatible with.
|
||||||
|
|
||||||
|
## Yaze Implementation
|
||||||
|
|
||||||
|
### OverworldMap Constructor
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
OverworldMap::OverworldMap(int index, Rom* rom) : index_(index), rom_(rom) {
|
||||||
|
LoadAreaInfo();
|
||||||
|
LoadCustomOverworldData();
|
||||||
|
SetupCustomTileset(asm_version);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Methods
|
||||||
|
|
||||||
|
- `LoadAreaInfo()`: Loads basic map properties
|
||||||
|
- `LoadCustomOverworldData()`: Loads ZSCustomOverworld features
|
||||||
|
- `LoadVanillaOverlay()`: Loads vanilla overlay data
|
||||||
|
- `LoadPalette()`: Loads and processes palette data
|
||||||
|
- `BuildTileset()`: Constructs graphics tileset
|
||||||
|
- `BuildBitmap()`: Creates the final map bitmap
|
||||||
|
|
||||||
|
### Current Status
|
||||||
|
|
||||||
|
✅ **ZSCustomOverworld v2/v3 Support**: Fully implemented and tested
|
||||||
|
✅ **Vanilla ROM Support**: Complete compatibility maintained
|
||||||
|
✅ **Overlay System**: Both vanilla and custom overlays supported
|
||||||
|
✅ **Map Properties System**: Integrated with UI components
|
||||||
|
✅ **Graphics Loading**: Optimized with caching and performance monitoring
|
||||||
|
|
||||||
|
## Key Differences
|
||||||
|
|
||||||
|
### 1. Language and Architecture
|
||||||
|
|
||||||
|
| Aspect | ZScream | Yaze |
|
||||||
|
|--------|---------|------|
|
||||||
|
| Language | C# | C++ |
|
||||||
|
| Memory Management | Garbage Collected | Manual (RAII) |
|
||||||
|
| Graphics | System.Drawing | Custom OpenGL |
|
||||||
|
| UI Framework | WinForms | ImGui |
|
||||||
|
|
||||||
|
### 2. Data Structures
|
||||||
|
|
||||||
|
**ZScream:**
|
||||||
|
```csharp
|
||||||
|
public class OverworldMap {
|
||||||
|
public byte Index { get; set; }
|
||||||
|
public AreaSizeEnum AreaSize { get; set; }
|
||||||
|
public Bitmap GFXBitmap { get; set; }
|
||||||
|
// ... other properties
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Yaze:**
|
||||||
|
```cpp
|
||||||
|
class OverworldMap {
|
||||||
|
uint8_t index_;
|
||||||
|
AreaSizeEnum area_size_;
|
||||||
|
std::vector<uint8_t> bitmap_data_;
|
||||||
|
// ... other member variables
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Error Handling
|
||||||
|
|
||||||
|
**ZScream:** Uses exceptions and try-catch blocks
|
||||||
|
**Yaze:** Uses `absl::Status` return values and `RETURN_IF_ERROR` macros
|
||||||
|
|
||||||
|
### 4. Graphics Processing
|
||||||
|
|
||||||
|
**ZScream:** Uses .NET's `Bitmap` class and GDI+
|
||||||
|
**Yaze:** Uses custom `gfx::Bitmap` class with OpenGL textures
|
||||||
|
|
||||||
|
## Common Issues and Solutions
|
||||||
|
|
||||||
|
### 1. Version Detection Issues
|
||||||
|
|
||||||
|
**Problem:** ROM not recognized as ZSCustomOverworld
|
||||||
|
**Solution:** Check that `OverworldCustomASMHasBeenApplied` is set correctly
|
||||||
|
|
||||||
|
### 2. Palette Loading Errors
|
||||||
|
|
||||||
|
**Problem:** Maps appear with wrong colors
|
||||||
|
**Solution:** Verify palette group addresses and 0xFF fallback handling
|
||||||
|
|
||||||
|
### 3. Graphics Not Loading
|
||||||
|
|
||||||
|
**Problem:** Blank textures or missing graphics
|
||||||
|
**Solution:** Check graphics buffer bounds and ProcessGraphicsBuffer implementation
|
||||||
|
|
||||||
|
### 4. Overlay Issues
|
||||||
|
|
||||||
|
**Problem:** Vanilla overlays not displaying
|
||||||
|
**Solution:**
|
||||||
|
- Verify overlay pointer addresses and SNES-to-PC conversion
|
||||||
|
- Ensure special area maps (0x80-0x9F) are properly loaded with correct graphics
|
||||||
|
- Check that overlay ID mappings are correct (e.g., 0x009D → map 0x9D)
|
||||||
|
- Verify that overlay preview shows the actual bitmap of the referenced special area map
|
||||||
|
|
||||||
|
**Problem:** Overlay preview showing incorrect information
|
||||||
|
**Solution:** Ensure overlay preview correctly maps overlay IDs to special area map indices and displays the appropriate bitmap from the special area maps (0x80-0x9F)
|
||||||
|
|
||||||
|
### 5. Large Map Problems
|
||||||
|
|
||||||
|
**Problem:** Large maps not rendering correctly
|
||||||
|
**Solution:** Check parent-child relationships and large map detection logic
|
||||||
|
|
||||||
|
### 6. Special Area Graphics Issues
|
||||||
|
|
||||||
|
**Problem:** Special area maps (0x80-0x9F) showing blank or incorrect graphics
|
||||||
|
**Solution:**
|
||||||
|
- Verify special area graphics loading in `LoadAreaInfo()`
|
||||||
|
- Check that special cases for maps like 0x88, 0x93, 0x95, 0x96, 0x9C are handled correctly
|
||||||
|
- Ensure proper sprite graphics table selection for v2 vs v3 ROMs
|
||||||
|
- Verify that special area maps use the correct graphics from referenced LW/DW maps
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### 1. Version-Specific Code
|
||||||
|
|
||||||
|
Always check the ASM version before accessing version-specific features:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
uint8_t asm_version = (*rom_)[OverworldCustomASMHasBeenApplied];
|
||||||
|
if (asm_version >= 3) {
|
||||||
|
// v3 features
|
||||||
|
} else if (asm_version == 0xFF) {
|
||||||
|
// Vanilla features
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Error Handling
|
||||||
|
|
||||||
|
Use proper error handling for ROM operations:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
absl::Status LoadPalette() {
|
||||||
|
RETURN_IF_ERROR(LoadPaletteData());
|
||||||
|
RETURN_IF_ERROR(ProcessPalette());
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Memory Management
|
||||||
|
|
||||||
|
Be careful with memory management in C++:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Good: RAII and smart pointers
|
||||||
|
std::vector<uint8_t> data;
|
||||||
|
std::unique_ptr<OverworldMap> map;
|
||||||
|
|
||||||
|
// Bad: Raw pointers without cleanup
|
||||||
|
uint8_t* raw_data = new uint8_t[size];
|
||||||
|
OverworldMap* map = new OverworldMap();
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Thread Safety
|
||||||
|
|
||||||
|
Both editors use threading for performance:
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
// Yaze: Use std::async for parallel processing
|
||||||
|
auto future = std::async(std::launch::async, [this](int map_index) {
|
||||||
|
RefreshChildMap(map_index);
|
||||||
|
}, map_index);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
Understanding the differences between ZScream and yaze implementations is crucial for maintaining compatibility and adding new features. Both editors follow similar patterns but use different approaches due to their respective languages and architectures.
|
||||||
|
|
||||||
|
The key is to maintain the same ROM data structure understanding while adapting to each editor's specific implementation patterns.
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
## September 2022
|
|
||||||
|
|
||||||
- Drawing Overworld maps to the screen
|
|
||||||
- Drawing entrance data on the overworld
|
|
||||||
- Drawing 2bpp inventory graphics data
|
|
||||||
- Started the YazeDelta project for version control.
|
|
||||||
|
|
||||||
## August 2022
|
|
||||||
|
|
||||||
- Added ValidateCompressionResults to ROM::Compress
|
|
||||||
- Improved Overworld systems in preparation for drawing maps.
|
|
||||||
|
|
||||||
## July 2022
|
|
||||||
|
|
||||||
- Display current overworld map graphics tile sheets.
|
|
||||||
- Added CreateAllGraphicsData to the ROM class
|
|
||||||
- Added Google Abseil C++ library for error handling, string manipulation
|
|
||||||
- Refactor ROM class to use smart pointers and STL containers
|
|
||||||
|
|
||||||
## June 2022
|
|
||||||
|
|
||||||
- Implemented LC_LZ2 Decompression
|
|
||||||
- Created Bitmap class for displaying SNES Graphics
|
|
||||||
- Added Overworld and OverworldMap class definitions
|
|
||||||
- Built user interface using ImGui and SDL2
|
|
||||||
- Started YAZE
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
|
|
||||||
For VSCode users, use the following CMake extensions with MinGW-w64
|
|
||||||
|
|
||||||
https://marketplace.visualstudio.com/items?itemName=twxs.cmake
|
|
||||||
https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools
|
|
||||||
|
|
||||||
https://www.msys2.org/
|
|
||||||
|
|
||||||
Add to environment variables `C:\msys64\mingw64\bin`
|
|
||||||
|
|
||||||
Install the following packages using `pacman -S <package-name>`
|
|
||||||
|
|
||||||
`mingw-w64-x86_64-gcc`
|
|
||||||
`mingw-w64-x86_64-gcc-libs`
|
|
||||||
`mingw-w64-x86_64-cmake`
|
|
||||||
`mingw-w64-x86_64-glew`
|
|
||||||
`mingw-w64-x86_64-lib-png`
|
|
||||||
46
docs/index.md
Normal file
46
docs/index.md
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
# YAZE Documentation
|
||||||
|
|
||||||
|
Yet Another Zelda3 Editor - A comprehensive ROM editor for The Legend of Zelda: A Link to the Past.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
- [Getting Started](01-getting-started.md) - Basic setup and usage
|
||||||
|
- [Build Instructions](02-build-instructions.md) - Cross-platform build guide
|
||||||
|
- [Asar Integration](03-asar-integration.md) - 65816 assembler usage
|
||||||
|
- [API Reference](04-api-reference.md) - C/C++ API documentation
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
- [Testing Guide](A1-testing-guide.md) - Testing framework and best practices
|
||||||
|
- [Contributing](B1-contributing.md) - Development guidelines and standards
|
||||||
|
- [Platform Compatibility](B2-platform-compatibility.md) - Cross-platform support details
|
||||||
|
- [Build Presets](B3-build-presets.md) - CMake preset usage guide
|
||||||
|
- [Release Workflows](B4-release-workflows.md) - GitHub Actions release pipeline documentation
|
||||||
|
|
||||||
|
## Technical Documentation
|
||||||
|
|
||||||
|
### Assembly & Code
|
||||||
|
- [Assembly Style Guide](E1-asm-style-guide.md) - 65816 assembly coding standards
|
||||||
|
|
||||||
|
### Editor Systems
|
||||||
|
- [Dungeon Editor Guide](E2-dungeon-editor-guide.md) - Complete dungeon editing guide
|
||||||
|
- [Dungeon Editor Design](E3-dungeon-editor-design.md) - Architecture and development guide
|
||||||
|
- [Dungeon Editor Refactoring](E4-dungeon-editor-refactoring.md) - Component-based architecture plan
|
||||||
|
- [Dungeon Object System](E5-dungeon-object-system.md) - Object management framework
|
||||||
|
|
||||||
|
### Overworld System
|
||||||
|
- [Overworld Loading](F1-overworld-loading.md) - ZSCustomOverworld v3 implementation
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
- Complete GUI editor for all aspects of Zelda 3 ROM hacking
|
||||||
|
- Integrated Asar 65816 assembler for custom code patches
|
||||||
|
- ZSCustomOverworld v3 support for enhanced overworld editing
|
||||||
|
- Cross-platform support (Windows, macOS, Linux)
|
||||||
|
- Modern C++23 codebase with comprehensive testing
|
||||||
|
- **Windows Development**: Automated setup scripts, Visual Studio integration, vcpkg package management
|
||||||
|
- **CMake Compatibility**: Automatic handling of submodule compatibility issues (abseil-cpp, SDL)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: September 2025 - Version 0.3.0*
|
||||||
Binary file not shown.
@@ -1,40 +0,0 @@
|
|||||||
\documentclass[12pt, oneside]{report}
|
|
||||||
\title{Yet Another Zelda3 Editor}
|
|
||||||
\author{Justin Scofield\thanks{Special thanks to JaredBrian, Zarby89}}
|
|
||||||
\date{June 2022 - October 2022}
|
|
||||||
\pagestyle{headings}
|
|
||||||
|
|
||||||
\begin{document}
|
|
||||||
\maketitle
|
|
||||||
|
|
||||||
\tableofcontents
|
|
||||||
|
|
||||||
\chapter{Introduction}
|
|
||||||
|
|
||||||
{\bf Yet Another Zelda3 Editor} is a multi-purpose editor for the retro video game title {\it {"The Legend of Zelda: A Link to the Past"}} for the Super Nintendo Entertainment System. The editor only supports the US version.
|
|
||||||
|
|
||||||
\section{Getting Started}
|
|
||||||
\section{Loading from ROM}
|
|
||||||
\section{Saving to ROM}
|
|
||||||
|
|
||||||
\chapter{Overworld}
|
|
||||||
|
|
||||||
The editor provides an interface for the user to make various changes to the overworld maps. These changes include the manpulation of the maps tiles, palettes, entrances, exits, sprites, area music, and other properties. Here we will explain the basics of the tile system.
|
|
||||||
|
|
||||||
\section{Tile System}
|
|
||||||
\section{Map Toolset}
|
|
||||||
\section{Map Canvas}
|
|
||||||
|
|
||||||
\chapter{Dungeons}
|
|
||||||
|
|
||||||
\chapter{Palettes}
|
|
||||||
|
|
||||||
\chapter{Sprites}
|
|
||||||
|
|
||||||
\chapter{Screens}
|
|
||||||
\section{Inventory}
|
|
||||||
\section{Heads-up Display}
|
|
||||||
|
|
||||||
\chapter{Modules}
|
|
||||||
|
|
||||||
\end{document}
|
|
||||||
165
docs/vcpkg-integration.md
Normal file
165
docs/vcpkg-integration.md
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
# vcpkg Integration for Windows Builds
|
||||||
|
|
||||||
|
> **Note**: This document provides detailed vcpkg information. For the most up-to-date build instructions, see [Build Instructions](02-build-instructions.md).
|
||||||
|
|
||||||
|
This document describes how to use vcpkg for Windows builds in Visual Studio with YAZE.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
vcpkg is Microsoft's C++ package manager that simplifies dependency management for Windows builds. YAZE now includes full vcpkg integration with manifest mode support for automatic dependency resolution.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- **Manifest Mode**: Dependencies are automatically managed via `vcpkg.json`
|
||||||
|
- **Visual Studio Integration**: Seamless integration with Visual Studio 2022
|
||||||
|
- **Generated Project Files**: Visual Studio project files with proper vcpkg integration
|
||||||
|
- **CMake Presets**: Pre-configured build presets for Windows
|
||||||
|
- **Automatic Setup**: Setup scripts for easy vcpkg installation
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
### 1. Setup vcpkg
|
||||||
|
|
||||||
|
Run the automated setup script:
|
||||||
|
```powershell
|
||||||
|
# PowerShell (recommended)
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
This will:
|
||||||
|
- Set up vcpkg
|
||||||
|
- Install dependencies (zlib, libpng, SDL2)
|
||||||
|
- Generate Visual Studio project files with proper vcpkg integration
|
||||||
|
|
||||||
|
### 2. Build with Visual Studio
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Generate project files (if not already done)
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# Open YAZE.sln in Visual Studio 2022
|
||||||
|
# Select configuration and platform, then build
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Alternative: Build with CMake
|
||||||
|
|
||||||
|
Use the Windows presets in CMakePresets.json:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
# Debug build
|
||||||
|
cmake --preset windows-debug
|
||||||
|
cmake --build build --preset windows-debug
|
||||||
|
|
||||||
|
# Release build
|
||||||
|
cmake --preset windows-release
|
||||||
|
cmake --build build --preset windows-release
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Details
|
||||||
|
|
||||||
|
### vcpkg.json Manifest
|
||||||
|
|
||||||
|
The `vcpkg.json` file defines all dependencies:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "yaze",
|
||||||
|
"version": "0.3.1",
|
||||||
|
"description": "Yet Another Zelda3 Editor",
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "zlib",
|
||||||
|
"platform": "!uwp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "libpng",
|
||||||
|
"platform": "!uwp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "sdl2",
|
||||||
|
"platform": "!uwp",
|
||||||
|
"features": ["vulkan"]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"builtin-baseline": "2024.12.12"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### CMake Configuration
|
||||||
|
|
||||||
|
vcpkg integration is handled in several files:
|
||||||
|
|
||||||
|
- **CMakeLists.txt**: Automatic toolchain detection
|
||||||
|
- **cmake/vcpkg.cmake**: vcpkg-specific settings
|
||||||
|
- **CMakePresets.json**: Windows build presets
|
||||||
|
|
||||||
|
### Build Presets
|
||||||
|
|
||||||
|
Available Windows presets:
|
||||||
|
|
||||||
|
- `windows-debug`: Debug build with vcpkg
|
||||||
|
- `windows-release`: Release build with vcpkg
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
vcpkg automatically installs these dependencies:
|
||||||
|
|
||||||
|
- **zlib**: Compression library
|
||||||
|
- **libpng**: PNG image support
|
||||||
|
- **sdl2**: Graphics and input handling (with Vulkan support)
|
||||||
|
|
||||||
|
**Note**: Abseil and gtest are now built from source via CMake rather than through vcpkg to avoid compatibility issues.
|
||||||
|
|
||||||
|
## Environment Variables
|
||||||
|
|
||||||
|
Set `VCPKG_ROOT` to point to your vcpkg installation:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
set VCPKG_ROOT=C:\path\to\vcpkg
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **vcpkg not found**: Ensure `VCPKG_ROOT` is set or vcpkg is in the project directory
|
||||||
|
2. **Dependencies not installing**: Check internet connection and vcpkg bootstrap
|
||||||
|
3. **Visual Studio integration**: Run `vcpkg integrate install` from vcpkg directory
|
||||||
|
|
||||||
|
### Manual Setup
|
||||||
|
|
||||||
|
If automated setup fails:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
.\bootstrap-vcpkg.bat
|
||||||
|
.\vcpkg.exe integrate install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
- **Consistent Dependencies**: Same versions across development environments
|
||||||
|
- **Easy Updates**: Update dependencies via vcpkg.json
|
||||||
|
- **CI/CD Friendly**: Reproducible builds
|
||||||
|
- **Visual Studio Integration**: Native IntelliSense support
|
||||||
|
- **No Manual Downloads**: Automatic dependency resolution
|
||||||
|
|
||||||
|
## Advanced Usage
|
||||||
|
|
||||||
|
### Custom Triplets
|
||||||
|
|
||||||
|
Override the default x64-windows triplet:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
cmake --preset windows-debug -DVCPKG_TARGET_TRIPLET=x86-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
### Static Linking
|
||||||
|
|
||||||
|
For static builds, modify `cmake/vcpkg.cmake`:
|
||||||
|
|
||||||
|
```cmake
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE static)
|
||||||
|
set(VCPKG_CRT_LINKAGE static)
|
||||||
|
```
|
||||||
117
docs/vcpkg-triplet-setup.md
Normal file
117
docs/vcpkg-triplet-setup.md
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
# Installing vcpkg Triplets for Windows
|
||||||
|
|
||||||
|
This guide explains how to install the `x64-windows` triplet that's required for building YAZE on Windows.
|
||||||
|
|
||||||
|
## What is a vcpkg Triplet?
|
||||||
|
|
||||||
|
A triplet defines the target platform, architecture, and linking configuration for vcpkg packages. The `x64-windows` triplet is the most common one for 64-bit Windows development.
|
||||||
|
|
||||||
|
## Method 1: Install via Package (Recommended)
|
||||||
|
|
||||||
|
The easiest way to ensure the triplet is available is to install any package with that triplet:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
# Navigate to your vcpkg directory
|
||||||
|
cd C:\path\to\your\vcpkg
|
||||||
|
|
||||||
|
# Install a package with the x64-windows triplet
|
||||||
|
vcpkg install sdl2:x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
This will automatically create the triplet configuration if it doesn't exist.
|
||||||
|
|
||||||
|
## Method 2: Create Triplet File Manually
|
||||||
|
|
||||||
|
If you need to create the triplet configuration manually:
|
||||||
|
|
||||||
|
1. **Navigate to vcpkg triplets directory:**
|
||||||
|
```cmd
|
||||||
|
cd C:\path\to\your\vcpkg\triplets
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Create or verify `x64-windows.cmake` exists:**
|
||||||
|
```cmd
|
||||||
|
dir x64-windows.cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **If it doesn't exist, create it with this content:**
|
||||||
|
```cmake
|
||||||
|
set(VCPKG_TARGET_ARCHITECTURE x64)
|
||||||
|
set(VCPKG_CRT_LINKAGE dynamic)
|
||||||
|
set(VCPKG_LIBRARY_LINKAGE dynamic)
|
||||||
|
|
||||||
|
set(VCPKG_CMAKE_SYSTEM_NAME Windows)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Method 3: Check Available Triplets
|
||||||
|
|
||||||
|
To see what triplets are currently available on your system:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
vcpkg help triplet
|
||||||
|
```
|
||||||
|
|
||||||
|
Or list all available triplet files:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
vcpkg help triplet | findstr "Available"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Method 4: Install YAZE Dependencies
|
||||||
|
|
||||||
|
Since YAZE uses several vcpkg packages, installing them will ensure the triplet is properly set up:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
# From the YAZE project root
|
||||||
|
vcpkg install --triplet x64-windows sdl2 zlib libpng abseil
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues and Solutions
|
||||||
|
|
||||||
|
### Issue: "Invalid triplet"
|
||||||
|
**Solution:** Make sure vcpkg is properly installed and in your PATH:
|
||||||
|
```cmd
|
||||||
|
vcpkg version
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Triplet not found"
|
||||||
|
**Solution:** Install a package with that triplet first:
|
||||||
|
```cmd
|
||||||
|
vcpkg install zlib:x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue: "Permission denied"
|
||||||
|
**Solution:** Run Command Prompt as Administrator, or install vcpkg in a user-writable location.
|
||||||
|
|
||||||
|
## Alternative Triplets
|
||||||
|
|
||||||
|
If `x64-windows` doesn't work, you can try these alternatives:
|
||||||
|
|
||||||
|
- `x64-windows-static` - Static linking
|
||||||
|
- `x86-windows` - 32-bit Windows
|
||||||
|
- `x64-windows-static-md` - Static runtime, dynamic CRT
|
||||||
|
|
||||||
|
## Verification
|
||||||
|
|
||||||
|
To verify the triplet is working:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
vcpkg list --triplet x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
This should show installed packages for that triplet.
|
||||||
|
|
||||||
|
## For YAZE Build
|
||||||
|
|
||||||
|
Once the triplet is installed, you can build YAZE using CMake presets:
|
||||||
|
|
||||||
|
```cmd
|
||||||
|
cmake --preset=windows-release
|
||||||
|
cmake --build build --config Release
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with the Visual Studio solution:
|
||||||
|
```cmd
|
||||||
|
# Open yaze.sln in Visual Studio
|
||||||
|
# Build normally (F5 or Ctrl+Shift+B)
|
||||||
|
```
|
||||||
284
docs/visual-studio-setup.md
Normal file
284
docs/visual-studio-setup.md
Normal file
@@ -0,0 +1,284 @@
|
|||||||
|
# Visual Studio Setup Guide
|
||||||
|
|
||||||
|
> **Note**: This document provides detailed Visual Studio setup information. For the most up-to-date build instructions, see [Build Instructions](02-build-instructions.md).
|
||||||
|
|
||||||
|
This guide will help Visual Studio users set up and build the yaze project on Windows.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Required Software
|
||||||
|
1. **Visual Studio 2022** (Community, Professional, or Enterprise)
|
||||||
|
- Install with "Desktop development with C++" workload
|
||||||
|
- Ensure CMake tools are included
|
||||||
|
- Install Git for Windows (or use built-in Git support)
|
||||||
|
|
||||||
|
2. **vcpkg** (Package Manager)
|
||||||
|
- Download from: https://github.com/Microsoft/vcpkg
|
||||||
|
- Follow installation instructions to integrate with Visual Studio
|
||||||
|
|
||||||
|
3. **CMake** (3.16 or later)
|
||||||
|
- Usually included with Visual Studio 2022
|
||||||
|
- Verify with: `cmake --version`
|
||||||
|
|
||||||
|
### Environment Setup
|
||||||
|
|
||||||
|
1. **Set up vcpkg environment variable:**
|
||||||
|
```cmd
|
||||||
|
set VCPKG_ROOT=C:\vcpkg
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Integrate vcpkg with Visual Studio:**
|
||||||
|
```cmd
|
||||||
|
cd C:\vcpkg
|
||||||
|
.\vcpkg integrate install
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Setup
|
||||||
|
|
||||||
|
### 1. Clone the Repository
|
||||||
|
```cmd
|
||||||
|
git clone --recursive https://github.com/your-username/yaze.git
|
||||||
|
cd yaze
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Install Dependencies via vcpkg
|
||||||
|
The project uses `vcpkg.json` for automatic dependency management. Dependencies will be installed automatically during CMake configuration.
|
||||||
|
|
||||||
|
Manual installation (if needed):
|
||||||
|
```cmd
|
||||||
|
vcpkg install zlib:x64-windows
|
||||||
|
vcpkg install libpng:x64-windows
|
||||||
|
vcpkg install sdl2[vulkan]:x64-windows
|
||||||
|
vcpkg install abseil:x64-windows
|
||||||
|
vcpkg install gtest:x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Configure Build System
|
||||||
|
|
||||||
|
#### Option A: Using Visual Studio Project File (Easiest)
|
||||||
|
1. Open Visual Studio 2022
|
||||||
|
2. Select "Open a project or solution"
|
||||||
|
3. Navigate to the yaze project folder and open `yaze.sln`
|
||||||
|
4. The project is pre-configured with vcpkg integration and proper dependencies
|
||||||
|
5. Select your desired build configuration (Debug/Release) and platform (x64/x86)
|
||||||
|
6. Press F5 to build and run, or Ctrl+Shift+B to build only
|
||||||
|
|
||||||
|
#### Option B: Using CMake with Visual Studio (Recommended for developers)
|
||||||
|
1. Open Visual Studio 2022
|
||||||
|
2. Select "Open a local folder" and navigate to the yaze project folder
|
||||||
|
3. Visual Studio will automatically detect the CMake project
|
||||||
|
4. Wait for CMake configuration to complete (check Output window)
|
||||||
|
|
||||||
|
#### Option C: Using Command Line
|
||||||
|
```cmd
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Build Configuration
|
||||||
|
|
||||||
|
#### Using Visual Studio Project File (.vcxproj)
|
||||||
|
- **Debug Build:** Select "Debug" configuration and press F5 or Ctrl+Shift+B
|
||||||
|
- **Release Build:** Select "Release" configuration and press F5 or Ctrl+Shift+B
|
||||||
|
- **Platform:** Choose x64 (recommended) or x86 from the platform dropdown
|
||||||
|
|
||||||
|
#### Using CMake (Command Line)
|
||||||
|
```cmd
|
||||||
|
# For Development (Debug Build)
|
||||||
|
cmake --build . --config Debug --target yaze
|
||||||
|
|
||||||
|
# For Release Build
|
||||||
|
cmake --build . --config Release --target yaze
|
||||||
|
|
||||||
|
# For Testing (Optional)
|
||||||
|
cmake --build . --config Debug --target yaze_test
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues and Solutions
|
||||||
|
|
||||||
|
### Issue 1: zlib Import Errors
|
||||||
|
**Problem:** `fatal error C1083: Cannot open include file: 'zlib.h'`
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
1. Ensure vcpkg is properly integrated with Visual Studio
|
||||||
|
2. Verify the vcpkg toolchain file is set:
|
||||||
|
```cmd
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
|
||||||
|
```
|
||||||
|
3. Check that zlib is installed:
|
||||||
|
```cmd
|
||||||
|
vcpkg list zlib
|
||||||
|
```
|
||||||
|
|
||||||
|
### Issue 2: Executable Runs Tests Instead of Main App
|
||||||
|
**Problem:** Running `yaze.exe` starts the test framework instead of the application
|
||||||
|
|
||||||
|
**Solution:** This has been fixed in the latest version. The issue was caused by linking `gtest_main` to the main executable. The fix removes `gtest_main` from the main application while keeping `gtest` for testing capabilities.
|
||||||
|
|
||||||
|
### Issue 3: SDL2 Configuration Issues
|
||||||
|
**Problem:** SDL2 not found or linking errors
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
1. Install SDL2 with vcpkg:
|
||||||
|
```cmd
|
||||||
|
vcpkg install sdl2[vulkan]:x64-windows
|
||||||
|
```
|
||||||
|
2. Ensure the project uses the vcpkg toolchain file
|
||||||
|
|
||||||
|
### Issue 4: Build Errors with Abseil
|
||||||
|
**Problem:** Missing Abseil symbols or linking issues
|
||||||
|
|
||||||
|
**Solution:**
|
||||||
|
1. Install Abseil via vcpkg:
|
||||||
|
```cmd
|
||||||
|
vcpkg install abseil:x64-windows
|
||||||
|
```
|
||||||
|
2. The project is configured to use Abseil 20240116.2 (see vcpkg.json overrides)
|
||||||
|
|
||||||
|
## Visual Studio Configuration
|
||||||
|
|
||||||
|
### CMake Settings
|
||||||
|
Create or modify `.vscode/settings.json` or use Visual Studio's CMake settings:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"cmake.configureArgs": [
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE=${env:VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||||
|
"-Dyaze_BUILD_TESTS=ON",
|
||||||
|
"-Dyaze_BUILD_APP=ON",
|
||||||
|
"-Dyaze_BUILD_LIB=ON"
|
||||||
|
],
|
||||||
|
"cmake.buildDirectory": "${workspaceFolder}/build"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Build Presets
|
||||||
|
The project includes CMake presets in `CMakePresets.json`. Use these in Visual Studio:
|
||||||
|
|
||||||
|
1. **Debug Build:** `debug` preset
|
||||||
|
2. **Release Build:** `release` preset
|
||||||
|
3. **Development Build:** `dev` preset (includes ROM testing)
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
### Using Visual Studio Project File
|
||||||
|
1. Open `yaze.sln` in Visual Studio
|
||||||
|
2. Set `yaze` as the startup project (should be default)
|
||||||
|
3. Configure command line arguments in Project Properties > Debugging > Command Arguments
|
||||||
|
- Example: `--rom_file=C:\path\to\your\zelda3.sfc`
|
||||||
|
4. Press F5 to build and run, or Ctrl+F5 to run without debugging
|
||||||
|
|
||||||
|
### Command Line
|
||||||
|
```cmd
|
||||||
|
cd build/bin/Debug # or Release
|
||||||
|
yaze.exe --rom_file=path/to/your/zelda3.sfc
|
||||||
|
```
|
||||||
|
|
||||||
|
### Visual Studio (CMake)
|
||||||
|
1. Set `yaze` as the startup project
|
||||||
|
2. Configure command line arguments in Project Properties > Debugging
|
||||||
|
3. Press F5 to run
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
### Run Unit Tests
|
||||||
|
```cmd
|
||||||
|
cd build
|
||||||
|
ctest --build-config Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Run Specific Test Suite
|
||||||
|
```cmd
|
||||||
|
cd build/bin/Debug
|
||||||
|
yaze_test.exe
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Clean Build
|
||||||
|
If you encounter persistent issues:
|
||||||
|
```cmd
|
||||||
|
rmdir /s build
|
||||||
|
mkdir build
|
||||||
|
cd build
|
||||||
|
cmake .. -G "Visual Studio 17 2022" -A x64 -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
|
||||||
|
cmake --build . --config Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Check Dependencies
|
||||||
|
Verify all dependencies are properly installed:
|
||||||
|
```cmd
|
||||||
|
vcpkg list
|
||||||
|
```
|
||||||
|
|
||||||
|
### CMake Cache Issues
|
||||||
|
Clear CMake cache:
|
||||||
|
```cmd
|
||||||
|
del CMakeCache.txt
|
||||||
|
cmake .. -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
## Visual Studio Project File Features
|
||||||
|
|
||||||
|
The included `yaze.vcxproj` and `yaze.sln` files provide:
|
||||||
|
|
||||||
|
### **Automatic Dependency Management**
|
||||||
|
- **vcpkg Integration:** Automatically installs and links dependencies from `vcpkg.json`
|
||||||
|
- **Platform Support:** Pre-configured for both x64 and x86 builds
|
||||||
|
- **Library Linking:** Automatically links SDL2, zlib, libpng, and system libraries
|
||||||
|
|
||||||
|
### **Build Configuration**
|
||||||
|
- **Debug Configuration:** Includes debugging symbols and runtime checks
|
||||||
|
- **Release Configuration:** Optimized for performance with full optimizations
|
||||||
|
- **C++23 Standard:** Uses modern C++ features and standard library
|
||||||
|
|
||||||
|
### **Asset Management**
|
||||||
|
- **Automatic Asset Copying:** Post-build events copy themes and assets to output directory
|
||||||
|
- **ROM File Handling:** Automatically copies `zelda3.sfc` if present in project root
|
||||||
|
- **Resource Organization:** Properly structures output directory for distribution
|
||||||
|
|
||||||
|
### **Development Features**
|
||||||
|
- **IntelliSense Support:** Full code completion and error detection
|
||||||
|
- **Debugging Integration:** Native Visual Studio debugging support
|
||||||
|
- **Project Properties:** Easy access to compiler and linker settings
|
||||||
|
|
||||||
|
## CI/CD Integration
|
||||||
|
|
||||||
|
The Visual Studio project files are fully integrated into the CI/CD pipeline:
|
||||||
|
|
||||||
|
### **Automated Validation**
|
||||||
|
- **Pre-commit checks:** Visual Studio builds are validated on every pull request
|
||||||
|
- **Release validation:** Both CMake and Visual Studio builds are tested before release
|
||||||
|
- **Multi-platform testing:** x64 and x86 builds are validated on Windows
|
||||||
|
- **Dependency verification:** vcpkg integration is tested automatically
|
||||||
|
|
||||||
|
### **Build Matrix**
|
||||||
|
The CI/CD pipeline tests:
|
||||||
|
- **Windows x64 Debug/Release** using Visual Studio 2022
|
||||||
|
- **Windows x86 Debug/Release** using Visual Studio 2022
|
||||||
|
- **CMake builds** alongside Visual Studio builds for compatibility
|
||||||
|
- **Asset copying** and executable functionality
|
||||||
|
|
||||||
|
### **Quality Assurance**
|
||||||
|
- **Test main detection:** Prevents the test framework from hijacking the main application
|
||||||
|
- **Asset validation:** Ensures themes and resources are properly copied
|
||||||
|
- **Executable testing:** Verifies the application starts correctly
|
||||||
|
- **Dependency checking:** Validates all required libraries are properly linked
|
||||||
|
|
||||||
|
## Additional Notes
|
||||||
|
|
||||||
|
- The project supports both x64 and x86 builds (use appropriate vcpkg triplets)
|
||||||
|
- For ARM64 Windows builds, use `arm64-windows` triplet
|
||||||
|
- The CI/CD pipeline validates both CMake and Visual Studio builds
|
||||||
|
- Development builds include additional debugging features and ROM testing capabilities
|
||||||
|
- The `.vcxproj` file provides the easiest setup for Visual Studio users who prefer traditional project files over CMake
|
||||||
|
- All builds are automatically validated to ensure they produce working executables
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you encounter issues not covered in this guide:
|
||||||
|
1. Check the project's GitHub issues
|
||||||
|
2. Verify your Visual Studio and vcpkg installations
|
||||||
|
3. Ensure all dependencies are properly installed via vcpkg
|
||||||
|
4. Try a clean build following the troubleshooting steps above
|
||||||
346
docs/windows-development-guide.md
Normal file
346
docs/windows-development-guide.md
Normal file
@@ -0,0 +1,346 @@
|
|||||||
|
# Windows Development Guide for YAZE
|
||||||
|
|
||||||
|
This guide will help you set up a Windows development environment for YAZE and build the project successfully.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
### Required Software
|
||||||
|
|
||||||
|
1. **Visual Studio 2022** (Community, Professional, or Enterprise)
|
||||||
|
- Download from: https://visualstudio.microsoft.com/downloads/
|
||||||
|
- Required workloads:
|
||||||
|
- Desktop development with C++
|
||||||
|
- Game development with C++ (optional, for additional tools)
|
||||||
|
|
||||||
|
2. **Git for Windows**
|
||||||
|
- Download from: https://git-scm.com/download/win
|
||||||
|
- Use default installation options
|
||||||
|
|
||||||
|
3. **Python 3.8 or later**
|
||||||
|
- Download from: https://www.python.org/downloads/
|
||||||
|
- Make sure to check "Add Python to PATH" during installation
|
||||||
|
|
||||||
|
### Optional Software
|
||||||
|
|
||||||
|
- **PowerShell 7** (recommended for better script support)
|
||||||
|
- **Windows Terminal** (for better terminal experience)
|
||||||
|
|
||||||
|
## Quick Setup
|
||||||
|
|
||||||
|
### Automated Setup
|
||||||
|
|
||||||
|
The easiest way to get started is to use our automated setup script:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Run from the YAZE project root directory
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
This script will:
|
||||||
|
- Check for required software (Visual Studio 2022, Git, Python)
|
||||||
|
- Set up vcpkg and install dependencies (zlib, libpng, SDL2)
|
||||||
|
- Generate Visual Studio project files with proper vcpkg integration
|
||||||
|
- Perform a test build to verify everything works
|
||||||
|
|
||||||
|
### Manual Setup
|
||||||
|
|
||||||
|
If you prefer to set up manually or the automated script fails:
|
||||||
|
|
||||||
|
#### 1. Clone the Repository
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/your-username/yaze.git
|
||||||
|
cd yaze
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. Set up vcpkg
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clone vcpkg
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git vcpkg
|
||||||
|
|
||||||
|
# Bootstrap vcpkg
|
||||||
|
cd vcpkg
|
||||||
|
.\bootstrap-vcpkg.bat
|
||||||
|
cd ..
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
.\vcpkg\vcpkg.exe install --triplet x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Generate Visual Studio Project Files
|
||||||
|
|
||||||
|
The generation script creates project files with proper vcpkg integration:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates:
|
||||||
|
- `YAZE.sln` - Visual Studio solution file
|
||||||
|
- `YAZE.vcxproj` - Visual Studio project file with vcpkg integration
|
||||||
|
- Proper vcpkg triplet settings for all platforms (x86, x64, ARM64)
|
||||||
|
|
||||||
|
#### 4. Build the Project
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Using PowerShell script (recommended)
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Release -Platform x64
|
||||||
|
|
||||||
|
# Or using batch script
|
||||||
|
.\scripts\build-windows.bat Release x64
|
||||||
|
|
||||||
|
# Or using Visual Studio
|
||||||
|
# Open YAZE.sln in Visual Studio 2022 and build
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building the Project
|
||||||
|
|
||||||
|
### Using Visual Studio
|
||||||
|
|
||||||
|
1. Open `YAZE.sln` in Visual Studio 2022
|
||||||
|
2. Select your desired configuration:
|
||||||
|
- **Debug**: For development and debugging
|
||||||
|
- **Release**: For optimized builds
|
||||||
|
- **RelWithDebInfo**: Release with debug information
|
||||||
|
- **MinSizeRel**: Minimal size release
|
||||||
|
3. Select your platform:
|
||||||
|
- **x64**: 64-bit (recommended)
|
||||||
|
- **x86**: 32-bit
|
||||||
|
- **ARM64**: ARM64 (if supported)
|
||||||
|
4. Build the solution (Ctrl+Shift+B)
|
||||||
|
|
||||||
|
### Using Command Line
|
||||||
|
|
||||||
|
#### PowerShell Script (Recommended)
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Build Release x64 (default)
|
||||||
|
.\scripts\build-windows.ps1
|
||||||
|
|
||||||
|
# Build Debug x64
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Debug -Platform x64
|
||||||
|
|
||||||
|
# Build Release x86
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Release -Platform x86
|
||||||
|
|
||||||
|
# Clean build
|
||||||
|
.\scripts\build-windows.ps1 -Clean
|
||||||
|
|
||||||
|
# Verbose output
|
||||||
|
.\scripts\build-windows.ps1 -Verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Batch Script
|
||||||
|
|
||||||
|
```batch
|
||||||
|
REM Build Release x64 (default)
|
||||||
|
.\scripts\build-windows.bat
|
||||||
|
|
||||||
|
REM Build Debug x64
|
||||||
|
.\scripts\build-windows.bat Debug x64
|
||||||
|
|
||||||
|
REM Build Release x86
|
||||||
|
.\scripts\build-windows.bat Release x86
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Direct MSBuild
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Build Release x64
|
||||||
|
msbuild YAZE.sln /p:Configuration=Release /p:Platform=x64 /p:VcpkgEnabled=true /p:VcpkgManifestInstall=true /m
|
||||||
|
|
||||||
|
# Build Debug x64
|
||||||
|
msbuild YAZE.sln /p:Configuration=Debug /p:Platform=x64 /p:VcpkgEnabled=true /p:VcpkgManifestInstall=true /m
|
||||||
|
```
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
yaze/
|
||||||
|
├── YAZE.sln # Visual Studio solution file (generated)
|
||||||
|
├── YAZE.vcxproj # Visual Studio project file (generated)
|
||||||
|
├── vcpkg.json # vcpkg dependencies
|
||||||
|
├── scripts/ # Build and setup scripts
|
||||||
|
│ ├── build-windows.ps1 # PowerShell build script
|
||||||
|
│ ├── build-windows.bat # Batch build script
|
||||||
|
│ ├── setup-windows-dev.ps1 # Automated setup script
|
||||||
|
│ └── generate-vs-projects.py # Project file generator
|
||||||
|
├── src/ # Source code
|
||||||
|
├── incl/ # Public headers
|
||||||
|
├── assets/ # Game assets
|
||||||
|
└── docs/ # Documentation
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note**: The Visual Studio project files (`YAZE.sln`, `YAZE.vcxproj`) are generated automatically and should not be edited manually. If you need to modify project settings, update the generation script instead.
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
#### 1. MSBuild Not Found
|
||||||
|
|
||||||
|
**Error**: `'msbuild' is not recognized as an internal or external command`
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Install Visual Studio 2022 with C++ workload
|
||||||
|
- Or add MSBuild to your PATH:
|
||||||
|
```bash
|
||||||
|
# Add to PATH (adjust path as needed)
|
||||||
|
C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. vcpkg Integration Issues
|
||||||
|
|
||||||
|
**Error**: `vcpkg.json not found` or dependency resolution fails
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Ensure vcpkg is properly set up:
|
||||||
|
```bash
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
```
|
||||||
|
- Or manually set up vcpkg as described in the manual setup section
|
||||||
|
|
||||||
|
#### 3. ZLIB or Other Dependencies Not Found
|
||||||
|
|
||||||
|
**Error**: `Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)`
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- This usually means vcpkg integration isn't working properly
|
||||||
|
- Regenerate project files with proper vcpkg integration:
|
||||||
|
```bash
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
```
|
||||||
|
- Ensure vcpkg is installed and dependencies are available:
|
||||||
|
```bash
|
||||||
|
.\vcpkg\vcpkg.exe install --triplet x64-windows
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 4. Python Script Execution Policy
|
||||||
|
|
||||||
|
**Error**: `execution of scripts is disabled on this system`
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
```powershell
|
||||||
|
# Run as Administrator
|
||||||
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 5. Missing Dependencies
|
||||||
|
|
||||||
|
**Error**: Linker errors about missing libraries
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Ensure all dependencies are installed via vcpkg:
|
||||||
|
```bash
|
||||||
|
.\vcpkg\vcpkg.exe install --triplet x64-windows
|
||||||
|
```
|
||||||
|
- Regenerate project files:
|
||||||
|
```bash
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 6. Build Failures
|
||||||
|
|
||||||
|
**Error**: Compilation or linking errors
|
||||||
|
|
||||||
|
**Solution**:
|
||||||
|
- Clean and rebuild:
|
||||||
|
```powershell
|
||||||
|
.\scripts\build-windows.ps1 -Clean
|
||||||
|
```
|
||||||
|
- Check that all source files are included in the project
|
||||||
|
- Verify that include paths are correct
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
|
||||||
|
If you encounter issues not covered here:
|
||||||
|
|
||||||
|
1. Check the [main build instructions](02-build-instructions.md)
|
||||||
|
2. Review the [troubleshooting section](02-build-instructions.md#troubleshooting)
|
||||||
|
3. Check the [GitHub Issues](https://github.com/your-username/yaze/issues)
|
||||||
|
4. Create a new issue with:
|
||||||
|
- Your Windows version
|
||||||
|
- Visual Studio version
|
||||||
|
- Complete error message
|
||||||
|
- Steps to reproduce
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Making Changes
|
||||||
|
|
||||||
|
1. Make your changes to the source code
|
||||||
|
2. If you added new source files, regenerate project files:
|
||||||
|
```bash
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
```
|
||||||
|
3. Build the project:
|
||||||
|
```powershell
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Debug -Platform x64
|
||||||
|
```
|
||||||
|
4. Test your changes
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
1. Set breakpoints in Visual Studio
|
||||||
|
2. Build in Debug configuration
|
||||||
|
3. Run with debugger (F5)
|
||||||
|
4. Use Visual Studio's debugging tools
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
1. Build the project
|
||||||
|
2. Run the executable:
|
||||||
|
```bash
|
||||||
|
.\build\bin\Debug\yaze.exe
|
||||||
|
```
|
||||||
|
3. Test with a ROM file:
|
||||||
|
```bash
|
||||||
|
.\build\bin\Debug\yaze.exe --rom_file=path\to\your\rom.sfc
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Tips
|
||||||
|
|
||||||
|
### Build Performance
|
||||||
|
|
||||||
|
- Use the `/m` flag for parallel builds
|
||||||
|
- Use SSD storage for better I/O performance
|
||||||
|
- Exclude build directories from antivirus scanning
|
||||||
|
- Use Release configuration for final builds
|
||||||
|
|
||||||
|
### Development Performance
|
||||||
|
|
||||||
|
- Use Debug configuration for development
|
||||||
|
- Use incremental builds (default in Visual Studio)
|
||||||
|
- Use RelWithDebInfo for performance testing with debug info
|
||||||
|
|
||||||
|
## Advanced Configuration
|
||||||
|
|
||||||
|
### Custom Build Configurations
|
||||||
|
|
||||||
|
You can create custom build configurations by modifying the Visual Studio project file or using CMake directly.
|
||||||
|
|
||||||
|
### Cross-Platform Development
|
||||||
|
|
||||||
|
While this guide focuses on Windows, YAZE also supports:
|
||||||
|
- Linux (Ubuntu/Debian)
|
||||||
|
- macOS
|
||||||
|
|
||||||
|
See the main build instructions for other platforms.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
When contributing to YAZE on Windows:
|
||||||
|
|
||||||
|
1. Follow the [coding standards](B1-contributing.md)
|
||||||
|
2. Test your changes on Windows
|
||||||
|
3. Ensure the build scripts still work
|
||||||
|
4. Update documentation if needed
|
||||||
|
5. Submit a pull request
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
- [Visual Studio Documentation](https://docs.microsoft.com/en-us/visualstudio/)
|
||||||
|
- [vcpkg Documentation](https://vcpkg.readthedocs.io/)
|
||||||
|
- [CMake Documentation](https://cmake.org/documentation/)
|
||||||
|
- [YAZE API Reference](04-api-reference.md)
|
||||||
63
docs/yaze.org
Normal file
63
docs/yaze.org
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
#+TITLE: yaze todo
|
||||||
|
#+SUBTITLE: yet another zelda3 editor todo list
|
||||||
|
#+AUTHOR: @scawful
|
||||||
|
#+TODO: TODO ACTIVE FEEDBACK VERIFY | DONE
|
||||||
|
|
||||||
|
* Daily Log
|
||||||
|
|
||||||
|
<2024-11-14 Thu>
|
||||||
|
Been making lots of adjustments and cleaning up old code. Primarily improving the dungeon map editor and supporting bin graphics for my Oracle of Secrets dungeon maps. Additionally, working to support saving for resources like graphics sheets and expanded the project file system.
|
||||||
|
|
||||||
|
<2024-09-07 Sat>
|
||||||
|
Various header cleanup using the LSP in emacs to detect unused includes.
|
||||||
|
Making adjustments to font loading so the editor can be opened from terminal/emacs.
|
||||||
|
Currently the font files and the zeml files require the binary to be relative to `assets/layouts` and `assets/fonts`
|
||||||
|
I've set it up so that the macOS app bundles the resources into the `yaze.app` so that the binary can be run from anywhere. This will need to be adjusted for other platforms.
|
||||||
|
|
||||||
|
<2024-09-02 Mon>
|
||||||
|
Extracted the DisplayPalette function out of the PaletteEditor and into its own standalone function.
|
||||||
|
|
||||||
|
<2024-09-01 Sun>
|
||||||
|
Started learning spacemacs and org-mode.
|
||||||
|
|
||||||
|
* Editors
|
||||||
|
** Overworld
|
||||||
|
*** TODO ZSCustomOverworld implementation.
|
||||||
|
**** DONE Custom Overworld Map Settings Inputs
|
||||||
|
**** DONE Load ZSCOW data from ROM in OverworldMap
|
||||||
|
**** TODO Add Main Palette support
|
||||||
|
**** TODO Add Custom Area BG Color support
|
||||||
|
|
||||||
|
*** TODO Fix sprite icon draw positions
|
||||||
|
*** TODO Fix exit icon draw positions
|
||||||
|
|
||||||
|
** Dungeon
|
||||||
|
*** TODO Draw dungeon objects
|
||||||
|
|
||||||
|
** Graphics
|
||||||
|
*** TODO Tile16 Editor
|
||||||
|
- [ ] Draw tile8 to tile16 quadrant.
|
||||||
|
|
||||||
|
*** TODO Fix graphics sheet pencil drawing
|
||||||
|
|
||||||
|
** Message
|
||||||
|
*** TODO Fix Message Parsing
|
||||||
|
|
||||||
|
** Palette
|
||||||
|
*** TODO Persist color changes for saving to ROM.
|
||||||
|
|
||||||
|
** Screens
|
||||||
|
*** ACTIVE Dungeon Maps
|
||||||
|
*** ACTIVE Inventory Menu
|
||||||
|
*** TODO Overworld Map
|
||||||
|
*** TODO Title Screen
|
||||||
|
*** TODO Naming Screen
|
||||||
|
|
||||||
|
* Infrastructure
|
||||||
|
** File Handling
|
||||||
|
*** TODO Update recent files manager to bundle the recent files list with the application
|
||||||
|
*** DONE Create a util for handling file operations from the bundled resources.
|
||||||
|
** Font Loading
|
||||||
|
*** TODO Make font sizes variables so they can be reloaded by the user.
|
||||||
|
** ZEML
|
||||||
|
*** DONE Package layout files with the executable to avoid relative file lookup
|
||||||
588
incl/yaze.h
Normal file
588
incl/yaze.h
Normal file
@@ -0,0 +1,588 @@
|
|||||||
|
#ifndef YAZE_H
|
||||||
|
#define YAZE_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file yaze.h
|
||||||
|
* @brief Yet Another Zelda3 Editor (YAZE) - Public C API
|
||||||
|
*
|
||||||
|
* This header provides the main C API for YAZE, a modern ROM editor for
|
||||||
|
* The Legend of Zelda: A Link to the Past. This API allows external
|
||||||
|
* applications to interact with YAZE's functionality.
|
||||||
|
*
|
||||||
|
* @version 0.3.1
|
||||||
|
* @author YAZE Team
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "zelda.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup version Version Information
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** Major version number */
|
||||||
|
#define YAZE_VERSION_MAJOR 0
|
||||||
|
/** Minor version number */
|
||||||
|
#define YAZE_VERSION_MINOR 3
|
||||||
|
/** Patch version number */
|
||||||
|
#define YAZE_VERSION_PATCH 1
|
||||||
|
|
||||||
|
/** Combined version as a string */
|
||||||
|
#define YAZE_VERSION_STRING "0.3.1"
|
||||||
|
|
||||||
|
/** Combined version as a number (major * 10000 + minor * 100 + patch) */
|
||||||
|
#define YAZE_VERSION_NUMBER 301
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
typedef struct yaze_editor_context {
|
||||||
|
zelda3_rom* rom;
|
||||||
|
const char* error_message;
|
||||||
|
} yaze_editor_context;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup core Core API
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Status codes returned by YAZE functions
|
||||||
|
*
|
||||||
|
* All YAZE functions that can fail return a status code to indicate
|
||||||
|
* success or the type of error that occurred.
|
||||||
|
*/
|
||||||
|
typedef enum yaze_status {
|
||||||
|
YAZE_OK = 0, /**< Operation completed successfully */
|
||||||
|
YAZE_ERROR_UNKNOWN = -1, /**< Unknown error occurred */
|
||||||
|
YAZE_ERROR_INVALID_ARG = 1, /**< Invalid argument provided */
|
||||||
|
YAZE_ERROR_FILE_NOT_FOUND = 2, /**< File not found */
|
||||||
|
YAZE_ERROR_MEMORY = 3, /**< Memory allocation failed */
|
||||||
|
YAZE_ERROR_IO = 4, /**< I/O operation failed */
|
||||||
|
YAZE_ERROR_CORRUPTION = 5, /**< Data corruption detected */
|
||||||
|
YAZE_ERROR_NOT_INITIALIZED = 6, /**< Component not initialized */
|
||||||
|
} yaze_status;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert a status code to a human-readable string
|
||||||
|
*
|
||||||
|
* @param status The status code to convert
|
||||||
|
* @return A null-terminated string describing the status
|
||||||
|
*/
|
||||||
|
const char* yaze_status_to_string(yaze_status status);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the YAZE library
|
||||||
|
*
|
||||||
|
* This function must be called before using any other YAZE functions.
|
||||||
|
* It initializes internal subsystems and prepares the library for use.
|
||||||
|
*
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status yaze_library_init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shutdown the YAZE library
|
||||||
|
*
|
||||||
|
* This function cleans up resources allocated by yaze_library_init().
|
||||||
|
* After calling this function, no other YAZE functions should be called
|
||||||
|
* until yaze_library_init() is called again.
|
||||||
|
*/
|
||||||
|
void yaze_library_shutdown(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main entry point for the YAZE application
|
||||||
|
*
|
||||||
|
* @param argc Number of command line arguments
|
||||||
|
* @param argv Array of command line argument strings
|
||||||
|
* @return Exit code (0 for success, non-zero for error)
|
||||||
|
*/
|
||||||
|
int yaze_app_main(int argc, char** argv);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the current YAZE version is compatible with the expected version
|
||||||
|
*
|
||||||
|
* @param expected_version Expected version string (e.g., "0.3.1")
|
||||||
|
* @return true if compatible, false otherwise
|
||||||
|
*/
|
||||||
|
bool yaze_check_version_compatibility(const char* expected_version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current YAZE version string
|
||||||
|
*
|
||||||
|
* @return A null-terminated string containing the version
|
||||||
|
*/
|
||||||
|
const char* yaze_get_version_string(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the current YAZE version number
|
||||||
|
*
|
||||||
|
* @return Version number (major * 10000 + minor * 100 + patch)
|
||||||
|
*/
|
||||||
|
int yaze_get_version_number(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize a YAZE editor context
|
||||||
|
*
|
||||||
|
* Creates and initializes an editor context for working with ROM files.
|
||||||
|
* The context manages the ROM data and provides access to editing functions.
|
||||||
|
*
|
||||||
|
* @param context Pointer to context structure to initialize
|
||||||
|
* @param rom_filename Path to the ROM file to load (can be NULL to create empty context)
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*
|
||||||
|
* @note The caller is responsible for calling yaze_shutdown() to clean up the context
|
||||||
|
*/
|
||||||
|
yaze_status yaze_init(yaze_editor_context* context, const char* rom_filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Shutdown and clean up a YAZE editor context
|
||||||
|
*
|
||||||
|
* Releases all resources associated with the context, including ROM data.
|
||||||
|
* After calling this function, the context should not be used.
|
||||||
|
*
|
||||||
|
* @param context Pointer to context to shutdown
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status yaze_shutdown(yaze_editor_context* context);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup graphics Graphics and Bitmap Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Bitmap data structure
|
||||||
|
*
|
||||||
|
* Represents a bitmap image with pixel data and metadata.
|
||||||
|
*/
|
||||||
|
typedef struct yaze_bitmap {
|
||||||
|
int width; /**< Width in pixels */
|
||||||
|
int height; /**< Height in pixels */
|
||||||
|
uint8_t bpp; /**< Bits per pixel (1, 2, 4, 8) */
|
||||||
|
uint8_t* data; /**< Pixel data (caller owns memory) */
|
||||||
|
} yaze_bitmap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a bitmap from file
|
||||||
|
*
|
||||||
|
* Loads a bitmap image from the specified file. Supports common
|
||||||
|
* image formats and SNES-specific formats.
|
||||||
|
*
|
||||||
|
* @param filename Path to the image file
|
||||||
|
* @return Bitmap structure with loaded data, or empty bitmap on error
|
||||||
|
*
|
||||||
|
* @note The caller is responsible for freeing the data pointer
|
||||||
|
*/
|
||||||
|
yaze_bitmap yaze_load_bitmap(const char* filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free bitmap data
|
||||||
|
*
|
||||||
|
* Releases memory allocated for bitmap pixel data.
|
||||||
|
*
|
||||||
|
* @param bitmap Pointer to bitmap structure to free
|
||||||
|
*/
|
||||||
|
void yaze_free_bitmap(yaze_bitmap* bitmap);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an empty bitmap
|
||||||
|
*
|
||||||
|
* Allocates a new bitmap with the specified dimensions.
|
||||||
|
*
|
||||||
|
* @param width Width in pixels
|
||||||
|
* @param height Height in pixels
|
||||||
|
* @param bpp Bits per pixel
|
||||||
|
* @return Initialized bitmap structure, or empty bitmap on error
|
||||||
|
*/
|
||||||
|
yaze_bitmap yaze_create_bitmap(int width, int height, uint8_t bpp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SNES color in 15-bit RGB format (BGR555)
|
||||||
|
*
|
||||||
|
* Represents a color in the SNES native format. Colors are stored
|
||||||
|
* as 8-bit values but only the lower 5 bits are used by the SNES.
|
||||||
|
*/
|
||||||
|
typedef struct snes_color {
|
||||||
|
uint16_t red; /**< Red component (0-255, but SNES uses 0-31) */
|
||||||
|
uint16_t green; /**< Green component (0-255, but SNES uses 0-31) */
|
||||||
|
uint16_t blue; /**< Blue component (0-255, but SNES uses 0-31) */
|
||||||
|
} snes_color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert RGB888 color to SNES color
|
||||||
|
*
|
||||||
|
* @param r Red component (0-255)
|
||||||
|
* @param g Green component (0-255)
|
||||||
|
* @param b Blue component (0-255)
|
||||||
|
* @return SNES color structure
|
||||||
|
*/
|
||||||
|
snes_color yaze_rgb_to_snes_color(uint8_t r, uint8_t g, uint8_t b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert SNES color to RGB888
|
||||||
|
*
|
||||||
|
* @param color SNES color to convert
|
||||||
|
* @param r Pointer to store red component (0-255)
|
||||||
|
* @param g Pointer to store green component (0-255)
|
||||||
|
* @param b Pointer to store blue component (0-255)
|
||||||
|
*/
|
||||||
|
void yaze_snes_color_to_rgb(snes_color color, uint8_t* r, uint8_t* g, uint8_t* b);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief SNES color palette
|
||||||
|
*
|
||||||
|
* Represents a color palette used by the SNES. Each palette contains
|
||||||
|
* up to 256 colors, though most modes use fewer colors per palette.
|
||||||
|
*/
|
||||||
|
typedef struct snes_palette {
|
||||||
|
uint16_t id; /**< Palette ID (0-255) */
|
||||||
|
uint16_t size; /**< Number of colors in palette (1-256) */
|
||||||
|
snes_color* colors; /**< Array of colors (caller owns memory) */
|
||||||
|
} snes_palette;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create an empty palette
|
||||||
|
*
|
||||||
|
* @param id Palette ID
|
||||||
|
* @param size Number of colors to allocate
|
||||||
|
* @return Initialized palette structure, or NULL on error
|
||||||
|
*/
|
||||||
|
snes_palette* yaze_create_palette(uint16_t id, uint16_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free palette memory
|
||||||
|
*
|
||||||
|
* @param palette Pointer to palette to free
|
||||||
|
*/
|
||||||
|
void yaze_free_palette(snes_palette* palette);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load palette from ROM
|
||||||
|
*
|
||||||
|
* @param rom ROM to load palette from
|
||||||
|
* @param palette_id ID of palette to load
|
||||||
|
* @return Loaded palette, or NULL on error
|
||||||
|
*/
|
||||||
|
snes_palette* yaze_load_palette_from_rom(const zelda3_rom* rom, uint16_t palette_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 8x8 SNES tile data
|
||||||
|
*
|
||||||
|
* Represents an 8x8 pixel tile with indexed color data.
|
||||||
|
* Each pixel value is an index into a palette.
|
||||||
|
*/
|
||||||
|
typedef struct snes_tile8 {
|
||||||
|
uint32_t id; /**< Tile ID for reference */
|
||||||
|
uint32_t palette_id; /**< Associated palette ID */
|
||||||
|
uint8_t data[64]; /**< 64 pixels in row-major order (y*8+x) */
|
||||||
|
} snes_tile8;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load tile data from ROM
|
||||||
|
*
|
||||||
|
* @param rom ROM to load from
|
||||||
|
* @param tile_id ID of tile to load
|
||||||
|
* @param bpp Bits per pixel (1, 2, 4, 8)
|
||||||
|
* @return Loaded tile data, or empty tile on error
|
||||||
|
*/
|
||||||
|
snes_tile8 yaze_load_tile_from_rom(const zelda3_rom* rom, uint32_t tile_id, uint8_t bpp);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert tile data between different bit depths
|
||||||
|
*
|
||||||
|
* @param tile Source tile data
|
||||||
|
* @param from_bpp Source bits per pixel
|
||||||
|
* @param to_bpp Target bits per pixel
|
||||||
|
* @return Converted tile data
|
||||||
|
*/
|
||||||
|
snes_tile8 yaze_convert_tile_bpp(const snes_tile8* tile, uint8_t from_bpp, uint8_t to_bpp);
|
||||||
|
|
||||||
|
typedef struct snes_tile_info {
|
||||||
|
uint16_t id;
|
||||||
|
uint8_t palette;
|
||||||
|
bool priority;
|
||||||
|
bool vertical_mirror;
|
||||||
|
bool horizontal_mirror;
|
||||||
|
} snes_tile_info;
|
||||||
|
|
||||||
|
typedef struct snes_tile16 {
|
||||||
|
snes_tile_info tiles[4];
|
||||||
|
} snes_tile16;
|
||||||
|
|
||||||
|
typedef struct snes_tile32 {
|
||||||
|
uint16_t t0;
|
||||||
|
uint16_t t1;
|
||||||
|
uint16_t t2;
|
||||||
|
uint16_t t3;
|
||||||
|
} snes_tile32;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup rom ROM Manipulation
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a ROM file
|
||||||
|
*
|
||||||
|
* Loads a Zelda 3 ROM file and validates its format.
|
||||||
|
*
|
||||||
|
* @param filename Path to ROM file (.sfc, .smc, etc.)
|
||||||
|
* @return Pointer to ROM structure, or NULL on error
|
||||||
|
*
|
||||||
|
* @note Caller must call yaze_unload_rom() to free memory
|
||||||
|
*/
|
||||||
|
zelda3_rom* yaze_load_rom_file(const char* filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate ROM integrity
|
||||||
|
*
|
||||||
|
* Checks if the ROM data is valid and uncorrupted.
|
||||||
|
*
|
||||||
|
* @param rom ROM to validate
|
||||||
|
* @return YAZE_OK if valid, error code if corrupted
|
||||||
|
*/
|
||||||
|
yaze_status yaze_validate_rom(const zelda3_rom* rom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get ROM information
|
||||||
|
*
|
||||||
|
* @param rom ROM to query
|
||||||
|
* @param version Pointer to store detected ROM version
|
||||||
|
* @param size Pointer to store ROM size in bytes
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status yaze_get_rom_info(const zelda3_rom* rom, zelda3_version* version, uint64_t* size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a color from a palette set
|
||||||
|
*
|
||||||
|
* Retrieves a specific color from a palette set in the ROM.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to get the color from
|
||||||
|
* @param palette_set The palette set index (0-255)
|
||||||
|
* @param palette The palette index within the set (0-15)
|
||||||
|
* @param color The color index within the palette (0-15)
|
||||||
|
* @return The color from the palette set
|
||||||
|
*/
|
||||||
|
snes_color yaze_get_color_from_paletteset(const zelda3_rom* rom,
|
||||||
|
int palette_set, int palette,
|
||||||
|
int color);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup overworld Overworld Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the overworld from ROM
|
||||||
|
*
|
||||||
|
* Loads and parses the overworld data from the ROM, including all maps,
|
||||||
|
* sprites, and related data structures.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load the overworld from
|
||||||
|
* @return Pointer to overworld structure, or NULL on error
|
||||||
|
*
|
||||||
|
* @note Caller must free the returned pointer when done
|
||||||
|
*/
|
||||||
|
zelda3_overworld* yaze_load_overworld(const zelda3_rom* rom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free overworld data
|
||||||
|
*
|
||||||
|
* @param overworld Pointer to overworld to free
|
||||||
|
*/
|
||||||
|
void yaze_free_overworld(zelda3_overworld* overworld);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get overworld map by index
|
||||||
|
*
|
||||||
|
* @param overworld Overworld data
|
||||||
|
* @param map_index Map index (0-159 for most ROMs)
|
||||||
|
* @return Pointer to map data, or NULL if invalid index
|
||||||
|
*/
|
||||||
|
const zelda3_overworld_map* yaze_get_overworld_map(const zelda3_overworld* overworld, int map_index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get total number of overworld maps
|
||||||
|
*
|
||||||
|
* @param overworld Overworld data
|
||||||
|
* @return Number of maps available
|
||||||
|
*/
|
||||||
|
int yaze_get_overworld_map_count(const zelda3_overworld* overworld);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup dungeon Dungeon Functions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load all dungeon rooms from ROM
|
||||||
|
*
|
||||||
|
* Loads and parses all dungeon room data from the ROM.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load rooms from
|
||||||
|
* @param room_count Pointer to store the number of rooms loaded
|
||||||
|
* @return Array of room structures, or NULL on error
|
||||||
|
*
|
||||||
|
* @note Caller must free the returned array when done
|
||||||
|
*/
|
||||||
|
zelda3_dungeon_room* yaze_load_all_rooms(const zelda3_rom* rom, int* room_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a specific dungeon room
|
||||||
|
*
|
||||||
|
* @param rom ROM to load from
|
||||||
|
* @param room_id Room ID to load (0-295 for most ROMs)
|
||||||
|
* @return Pointer to room data, or NULL on error
|
||||||
|
*/
|
||||||
|
const zelda3_dungeon_room* yaze_load_room(const zelda3_rom* rom, int room_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free dungeon room data
|
||||||
|
*
|
||||||
|
* @param rooms Array of rooms to free
|
||||||
|
* @param room_count Number of rooms in array
|
||||||
|
*/
|
||||||
|
void yaze_free_rooms(zelda3_dungeon_room* rooms, int room_count);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup messages Message System
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load all text messages from ROM
|
||||||
|
*
|
||||||
|
* Loads and parses all in-game text messages from the ROM.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load messages from
|
||||||
|
* @param messages Pointer to store array of messages
|
||||||
|
* @param message_count Pointer to store number of messages loaded
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*
|
||||||
|
* @note Caller must free the messages array when done
|
||||||
|
*/
|
||||||
|
yaze_status yaze_load_messages(const zelda3_rom* rom, zelda3_message** messages, int* message_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a specific message by ID
|
||||||
|
*
|
||||||
|
* @param rom ROM to load from
|
||||||
|
* @param message_id Message ID to retrieve
|
||||||
|
* @return Pointer to message data, or NULL if not found
|
||||||
|
*/
|
||||||
|
const zelda3_message* yaze_get_message(const zelda3_rom* rom, int message_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free message data
|
||||||
|
*
|
||||||
|
* @param messages Array of messages to free
|
||||||
|
* @param message_count Number of messages in array
|
||||||
|
*/
|
||||||
|
void yaze_free_messages(zelda3_message* messages, int message_count);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function pointer to initialize the extension.
|
||||||
|
*
|
||||||
|
* @param context The editor context.
|
||||||
|
*/
|
||||||
|
typedef void (*yaze_initialize_func)(yaze_editor_context* context);
|
||||||
|
typedef void (*yaze_cleanup_func)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup extensions Extension System
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extension interface for YAZE
|
||||||
|
*
|
||||||
|
* Defines the interface for YAZE extensions. Extensions can add new
|
||||||
|
* functionality to YAZE and can be written in C or other languages.
|
||||||
|
*/
|
||||||
|
typedef struct yaze_extension {
|
||||||
|
const char* name; /**< Extension name (must not be NULL) */
|
||||||
|
const char* version; /**< Extension version string */
|
||||||
|
const char* description; /**< Brief description of functionality */
|
||||||
|
const char* author; /**< Extension author */
|
||||||
|
int api_version; /**< Required YAZE API version */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the extension
|
||||||
|
*
|
||||||
|
* Called when the extension is loaded. Use this to set up
|
||||||
|
* any resources or state needed by the extension.
|
||||||
|
*
|
||||||
|
* @param context Editor context provided by YAZE
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status (*initialize)(yaze_editor_context* context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clean up the extension
|
||||||
|
*
|
||||||
|
* Called when the extension is unloaded. Use this to clean up
|
||||||
|
* any resources or state used by the extension.
|
||||||
|
*/
|
||||||
|
void (*cleanup)(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get extension capabilities
|
||||||
|
*
|
||||||
|
* Returns a bitmask indicating what features this extension provides.
|
||||||
|
*
|
||||||
|
* @return Capability flags (see YAZE_EXT_CAP_* constants)
|
||||||
|
*/
|
||||||
|
uint32_t (*get_capabilities)(void);
|
||||||
|
} yaze_extension;
|
||||||
|
|
||||||
|
/** Extension capability flags */
|
||||||
|
#define YAZE_EXT_CAP_ROM_EDITING (1 << 0) /**< Can edit ROM data */
|
||||||
|
#define YAZE_EXT_CAP_GRAPHICS (1 << 1) /**< Provides graphics functions */
|
||||||
|
#define YAZE_EXT_CAP_AUDIO (1 << 2) /**< Provides audio functions */
|
||||||
|
#define YAZE_EXT_CAP_SCRIPTING (1 << 3) /**< Provides scripting support */
|
||||||
|
#define YAZE_EXT_CAP_IMPORT_EXPORT (1 << 4) /**< Can import/export data */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Register an extension with YAZE
|
||||||
|
*
|
||||||
|
* @param extension Extension to register
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status yaze_register_extension(const yaze_extension* extension);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unregister an extension
|
||||||
|
*
|
||||||
|
* @param name Name of extension to unregister
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
yaze_status yaze_unregister_extension(const char* name);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // YAZE_H
|
||||||
499
incl/zelda.h
Normal file
499
incl/zelda.h
Normal file
@@ -0,0 +1,499 @@
|
|||||||
|
#ifndef ZELDA_H
|
||||||
|
#define ZELDA_H
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file zelda.h
|
||||||
|
* @brief The Legend of Zelda: A Link to the Past - Data Structures and Constants
|
||||||
|
*
|
||||||
|
* This header defines data structures and constants specific to
|
||||||
|
* The Legend of Zelda: A Link to the Past ROM format and game data.
|
||||||
|
*
|
||||||
|
* @version 0.3.1
|
||||||
|
* @author YAZE Team
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup rom_types ROM Types and Versions
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Different versions of the game supported by YAZE
|
||||||
|
*
|
||||||
|
* YAZE supports multiple regional versions and ROM hacks of
|
||||||
|
* The Legend of Zelda: A Link to the Past.
|
||||||
|
*/
|
||||||
|
typedef enum zelda3_version {
|
||||||
|
ZELDA3_VERSION_UNKNOWN = 0, /**< Unknown or unsupported version */
|
||||||
|
ZELDA3_VERSION_US = 1, /**< US/North American version */
|
||||||
|
ZELDA3_VERSION_JP = 2, /**< Japanese version */
|
||||||
|
ZELDA3_VERSION_EU = 3, /**< European version */
|
||||||
|
ZELDA3_VERSION_PROTO = 4, /**< Prototype/development version */
|
||||||
|
ZELDA3_VERSION_RANDOMIZER = 5, /**< Randomizer ROM (experimental) */
|
||||||
|
|
||||||
|
// Legacy aliases for backward compatibility
|
||||||
|
US = ZELDA3_VERSION_US, /**< @deprecated Use ZELDA3_VERSION_US */
|
||||||
|
JP = ZELDA3_VERSION_JP, /**< @deprecated Use ZELDA3_VERSION_JP */
|
||||||
|
SD = ZELDA3_VERSION_PROTO, /**< @deprecated Use ZELDA3_VERSION_PROTO */
|
||||||
|
RANDO = ZELDA3_VERSION_RANDOMIZER, /**< @deprecated Use ZELDA3_VERSION_RANDOMIZER */
|
||||||
|
} zelda3_version;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Detect ROM version from header data
|
||||||
|
*
|
||||||
|
* @param rom_data Pointer to ROM data
|
||||||
|
* @param size Size of ROM data in bytes
|
||||||
|
* @return Detected version, or ZELDA3_VERSION_UNKNOWN if not recognized
|
||||||
|
*/
|
||||||
|
zelda3_version zelda3_detect_version(const uint8_t* rom_data, size_t size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get version name as string
|
||||||
|
*
|
||||||
|
* @param version Version enum value
|
||||||
|
* @return Human-readable version name
|
||||||
|
*/
|
||||||
|
const char* zelda3_version_to_string(zelda3_version version);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ROM data pointers for different game versions
|
||||||
|
*
|
||||||
|
* Contains memory addresses where specific data structures are located
|
||||||
|
* within the ROM. These addresses vary between different regional versions.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_version_pointers {
|
||||||
|
// New Google C++ style names
|
||||||
|
uint32_t gfx_animated_pointer; /**< Animated graphics pointer */
|
||||||
|
uint32_t overworld_gfx_groups1; /**< Overworld graphics group 1 */
|
||||||
|
uint32_t overworld_gfx_groups2; /**< Overworld graphics group 2 */
|
||||||
|
uint32_t compressed_map32_pointers_high; /**< Map32 high pointers */
|
||||||
|
uint32_t compressed_map32_pointers_low; /**< Map32 low pointers */
|
||||||
|
uint32_t overworld_map_palette_group; /**< Map palette groups */
|
||||||
|
uint32_t overlay_pointers; /**< Overlay data pointers */
|
||||||
|
uint32_t overlay_pointers_bank; /**< Overlay bank number */
|
||||||
|
uint32_t overworld_tiles_type; /**< Tile type definitions */
|
||||||
|
uint32_t overworld_gfx_ptr1; /**< Graphics pointer 1 */
|
||||||
|
uint32_t overworld_gfx_ptr2; /**< Graphics pointer 2 */
|
||||||
|
uint32_t overworld_gfx_ptr3; /**< Graphics pointer 3 */
|
||||||
|
uint32_t map32_tile_tl; /**< 32x32 tile top-left */
|
||||||
|
uint32_t map32_tile_tr; /**< 32x32 tile top-right */
|
||||||
|
uint32_t map32_tile_bl; /**< 32x32 tile bottom-left */
|
||||||
|
uint32_t map32_tile_br; /**< 32x32 tile bottom-right */
|
||||||
|
uint32_t sprite_blockset_pointer; /**< Sprite graphics pointer */
|
||||||
|
uint32_t dungeon_palettes_groups; /**< Dungeon palette groups */
|
||||||
|
|
||||||
|
// Legacy aliases for backward compatibility (deprecated)
|
||||||
|
uint32_t kGfxAnimatedPointer; /**< @deprecated Use gfx_animated_pointer */
|
||||||
|
uint32_t kOverworldGfxGroups1; /**< @deprecated Use overworld_gfx_groups1 */
|
||||||
|
uint32_t kOverworldGfxGroups2; /**< @deprecated Use overworld_gfx_groups2 */
|
||||||
|
uint32_t kCompressedAllMap32PointersHigh; /**< @deprecated Use compressed_map32_pointers_high */
|
||||||
|
uint32_t kCompressedAllMap32PointersLow; /**< @deprecated Use compressed_map32_pointers_low */
|
||||||
|
uint32_t kOverworldMapPaletteGroup; /**< @deprecated Use overworld_map_palette_group */
|
||||||
|
uint32_t kOverlayPointers; /**< @deprecated Use overlay_pointers */
|
||||||
|
uint32_t kOverlayPointersBank; /**< @deprecated Use overlay_pointers_bank */
|
||||||
|
uint32_t kOverworldTilesType; /**< @deprecated Use overworld_tiles_type */
|
||||||
|
uint32_t kOverworldGfxPtr1; /**< @deprecated Use overworld_gfx_ptr1 */
|
||||||
|
uint32_t kOverworldGfxPtr2; /**< @deprecated Use overworld_gfx_ptr2 */
|
||||||
|
uint32_t kOverworldGfxPtr3; /**< @deprecated Use overworld_gfx_ptr3 */
|
||||||
|
uint32_t kMap32TileTL; /**< @deprecated Use map32_tile_tl */
|
||||||
|
uint32_t kMap32TileTR; /**< @deprecated Use map32_tile_tr */
|
||||||
|
uint32_t kMap32TileBL; /**< @deprecated Use map32_tile_bl */
|
||||||
|
uint32_t kMap32TileBR; /**< @deprecated Use map32_tile_br */
|
||||||
|
uint32_t kSpriteBlocksetPointer; /**< @deprecated Use sprite_blockset_pointer */
|
||||||
|
uint32_t kDungeonPalettesGroups; /**< @deprecated Use dungeon_palettes_groups */
|
||||||
|
} zelda3_version_pointers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get version-specific pointers
|
||||||
|
*
|
||||||
|
* @param version ROM version
|
||||||
|
* @return Pointer to version-specific address structure
|
||||||
|
*/
|
||||||
|
const zelda3_version_pointers* zelda3_get_version_pointers(zelda3_version version);
|
||||||
|
|
||||||
|
const static zelda3_version_pointers zelda3_us_pointers = {
|
||||||
|
// New style names
|
||||||
|
0x10275, // gfx_animated_pointer
|
||||||
|
0x5D97, // overworld_gfx_groups1
|
||||||
|
0x6073, // overworld_gfx_groups2
|
||||||
|
0x1794D, // compressed_map32_pointers_high
|
||||||
|
0x17B2D, // compressed_map32_pointers_low
|
||||||
|
0x75504, // overworld_map_palette_group
|
||||||
|
0x77664, // overlay_pointers
|
||||||
|
0x0E, // overlay_pointers_bank
|
||||||
|
0x71459, // overworld_tiles_type
|
||||||
|
0x4F80, // overworld_gfx_ptr1
|
||||||
|
0x505F, // overworld_gfx_ptr2
|
||||||
|
0x513E, // overworld_gfx_ptr3
|
||||||
|
0x18000, // map32_tile_tl
|
||||||
|
0x1B400, // map32_tile_tr
|
||||||
|
0x20000, // map32_tile_bl
|
||||||
|
0x23400, // map32_tile_br
|
||||||
|
0x5B57, // sprite_blockset_pointer
|
||||||
|
0x75460, // dungeon_palettes_groups
|
||||||
|
|
||||||
|
// Legacy k-prefixed names (same values for backward compatibility)
|
||||||
|
0x10275, // kGfxAnimatedPointer
|
||||||
|
0x5D97, // kOverworldGfxGroups1
|
||||||
|
0x6073, // kOverworldGfxGroups2
|
||||||
|
0x1794D, // kCompressedAllMap32PointersHigh
|
||||||
|
0x17B2D, // kCompressedAllMap32PointersLow
|
||||||
|
0x75504, // kOverworldMapPaletteGroup
|
||||||
|
0x77664, // kOverlayPointers
|
||||||
|
0x0E, // kOverlayPointersBank
|
||||||
|
0x71459, // kOverworldTilesType
|
||||||
|
0x4F80, // kOverworldGfxPtr1
|
||||||
|
0x505F, // kOverworldGfxPtr2
|
||||||
|
0x513E, // kOverworldGfxPtr3
|
||||||
|
0x18000, // kMap32TileTL
|
||||||
|
0x1B400, // kMap32TileTR
|
||||||
|
0x20000, // kMap32TileBL
|
||||||
|
0x23400, // kMap32TileBR
|
||||||
|
0x5B57, // kSpriteBlocksetPointer
|
||||||
|
0x75460, // kDungeonPalettesGroups
|
||||||
|
};
|
||||||
|
|
||||||
|
const static zelda3_version_pointers zelda3_jp_pointers = {
|
||||||
|
// New style names
|
||||||
|
0x10624, // gfx_animated_pointer
|
||||||
|
0x5DD7, // overworld_gfx_groups1
|
||||||
|
0x60B3, // overworld_gfx_groups2
|
||||||
|
0x176B1, // compressed_map32_pointers_high
|
||||||
|
0x17891, // compressed_map32_pointers_low
|
||||||
|
0x67E74, // overworld_map_palette_group
|
||||||
|
0x3FAF4, // overlay_pointers
|
||||||
|
0x07, // overlay_pointers_bank
|
||||||
|
0x7FD94, // overworld_tiles_type
|
||||||
|
0x4FC0, // overworld_gfx_ptr1
|
||||||
|
0x509F, // overworld_gfx_ptr2
|
||||||
|
0x517E, // overworld_gfx_ptr3
|
||||||
|
0x18000, // map32_tile_tl
|
||||||
|
0x1B3C0, // map32_tile_tr
|
||||||
|
0x20000, // map32_tile_bl
|
||||||
|
0x233C0, // map32_tile_br
|
||||||
|
0x5B97, // sprite_blockset_pointer
|
||||||
|
0x67DD0, // dungeon_palettes_groups
|
||||||
|
|
||||||
|
// Legacy k-prefixed names (same values for backward compatibility)
|
||||||
|
0x10624, // kGfxAnimatedPointer
|
||||||
|
0x5DD7, // kOverworldGfxGroups1
|
||||||
|
0x60B3, // kOverworldGfxGroups2
|
||||||
|
0x176B1, // kCompressedAllMap32PointersHigh
|
||||||
|
0x17891, // kCompressedAllMap32PointersLow
|
||||||
|
0x67E74, // kOverworldMapPaletteGroup
|
||||||
|
0x3FAF4, // kOverlayPointers
|
||||||
|
0x07, // kOverlayPointersBank
|
||||||
|
0x7FD94, // kOverworldTilesType
|
||||||
|
0x4FC0, // kOverworldGfxPtr1
|
||||||
|
0x509F, // kOverworldGfxPtr2
|
||||||
|
0x517E, // kOverworldGfxPtr3
|
||||||
|
0x18000, // kMap32TileTL
|
||||||
|
0x1B3C0, // kMap32TileTR
|
||||||
|
0x20000, // kMap32TileBL
|
||||||
|
0x233C0, // kMap32TileBR
|
||||||
|
0x5B97, // kSpriteBlocksetPointer
|
||||||
|
0x67DD0, // kDungeonPalettesGroups
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ROM data structure
|
||||||
|
*
|
||||||
|
* Represents a loaded Zelda 3 ROM with its data and metadata.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_rom {
|
||||||
|
const char* filename; /**< Original filename (can be NULL) */
|
||||||
|
uint8_t* data; /**< ROM data (read-only for external users) */
|
||||||
|
uint64_t size; /**< Size of ROM data in bytes */
|
||||||
|
zelda3_version version; /**< Detected ROM version */
|
||||||
|
bool is_modified; /**< True if ROM has been modified */
|
||||||
|
void* impl; /**< Internal implementation pointer */
|
||||||
|
} zelda3_rom;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup rom_functions ROM File Operations
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load a ROM file
|
||||||
|
*
|
||||||
|
* @param filename Path to ROM file
|
||||||
|
* @return Loaded ROM structure, or NULL on error
|
||||||
|
*/
|
||||||
|
zelda3_rom* yaze_load_rom(const char* filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Unload and free ROM data
|
||||||
|
*
|
||||||
|
* @param rom ROM to unload
|
||||||
|
*/
|
||||||
|
void yaze_unload_rom(zelda3_rom* rom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Save ROM to file
|
||||||
|
*
|
||||||
|
* @param rom ROM to save
|
||||||
|
* @param filename Output filename
|
||||||
|
* @return YAZE_OK on success, error code on failure
|
||||||
|
*/
|
||||||
|
int yaze_save_rom(zelda3_rom* rom, const char* filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a copy of ROM data
|
||||||
|
*
|
||||||
|
* @param rom Source ROM
|
||||||
|
* @return Copy of ROM, or NULL on error
|
||||||
|
*/
|
||||||
|
zelda3_rom* yaze_copy_rom(const zelda3_rom* rom);
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup messages Message Data Structures
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief In-game text message data
|
||||||
|
*
|
||||||
|
* Represents a text message from the game, including both raw
|
||||||
|
* ROM data and parsed/decoded text content.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_message {
|
||||||
|
uint16_t id; /**< Message ID (0-65535) */
|
||||||
|
uint32_t rom_address; /**< Address in ROM where message data starts */
|
||||||
|
uint16_t length; /**< Length of message data in bytes */
|
||||||
|
uint8_t* raw_data; /**< Raw message data from ROM */
|
||||||
|
char* parsed_text; /**< Decoded text content (UTF-8) */
|
||||||
|
bool is_compressed; /**< True if message uses compression */
|
||||||
|
uint8_t encoding_type; /**< Text encoding type used */
|
||||||
|
} zelda3_message;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup overworld Overworld Data Structures
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Overworld map data
|
||||||
|
*
|
||||||
|
* Represents a single screen/area in the overworld, including
|
||||||
|
* graphics, palette, music, and sprite information.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_overworld_map {
|
||||||
|
uint16_t id; /**< Map ID (0-159 for most ROMs) */
|
||||||
|
uint8_t parent_id; /**< Parent map ID for sub-areas */
|
||||||
|
uint8_t quadrant_id; /**< Quadrant within parent (0-3) */
|
||||||
|
uint8_t world_id; /**< World number (Light/Dark) */
|
||||||
|
uint8_t game_state; /**< Game state requirements */
|
||||||
|
|
||||||
|
/* Graphics and Visual Properties */
|
||||||
|
uint8_t area_graphics; /**< Area graphics set ID */
|
||||||
|
uint8_t area_palette; /**< Area palette set ID */
|
||||||
|
uint8_t main_palette; /**< Main palette ID */
|
||||||
|
uint8_t animated_gfx; /**< Animated graphics ID */
|
||||||
|
|
||||||
|
/* Sprite Configuration */
|
||||||
|
uint8_t sprite_graphics[3]; /**< Sprite graphics sets */
|
||||||
|
uint8_t sprite_palette[3]; /**< Sprite palette sets */
|
||||||
|
|
||||||
|
/* Audio Configuration */
|
||||||
|
uint8_t area_music[4]; /**< Music tracks for different states */
|
||||||
|
|
||||||
|
/* Extended Graphics (ZSCustomOverworld) */
|
||||||
|
uint8_t static_graphics[16]; /**< Static graphics assignments */
|
||||||
|
uint8_t custom_tileset[8]; /**< Custom tileset assignments */
|
||||||
|
|
||||||
|
/* Screen Properties */
|
||||||
|
uint16_t area_specific_bg_color; /**< Background color override */
|
||||||
|
uint16_t subscreen_overlay; /**< Subscreen overlay settings */
|
||||||
|
|
||||||
|
/* Flags and Metadata */
|
||||||
|
bool is_large_map; /**< True for 32x32 maps */
|
||||||
|
bool has_special_gfx; /**< True if uses special graphics */
|
||||||
|
} zelda3_overworld_map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Complete overworld data
|
||||||
|
*
|
||||||
|
* Contains all overworld maps and related data for the entire game world.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_overworld {
|
||||||
|
void* impl; /**< Internal implementation pointer */
|
||||||
|
zelda3_overworld_map** maps; /**< Array of overworld maps */
|
||||||
|
int map_count; /**< Number of maps in array */
|
||||||
|
zelda3_version rom_version; /**< ROM version this data came from */
|
||||||
|
bool has_zsco_features; /**< True if ZSCustomOverworld features detected */
|
||||||
|
} zelda3_overworld;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup dungeon Dungeon Data Structures
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dungeon sprite definition
|
||||||
|
*
|
||||||
|
* Represents a sprite that can appear in dungeon rooms.
|
||||||
|
*/
|
||||||
|
typedef struct dungeon_sprite {
|
||||||
|
const char* name; /**< Sprite name (for debugging/display) */
|
||||||
|
uint8_t id; /**< Sprite type ID */
|
||||||
|
uint8_t subtype; /**< Sprite subtype/variant */
|
||||||
|
uint8_t x; /**< X position in room */
|
||||||
|
uint8_t y; /**< Y position in room */
|
||||||
|
uint8_t layer; /**< Layer (0=background, 1=foreground) */
|
||||||
|
uint16_t properties; /**< Additional sprite properties */
|
||||||
|
} dungeon_sprite;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Background layer 2 effects
|
||||||
|
*
|
||||||
|
* Defines the different visual effects that can be applied to
|
||||||
|
* background layer 2 in dungeon rooms.
|
||||||
|
*/
|
||||||
|
typedef enum zelda3_bg2_effect {
|
||||||
|
ZELDA3_BG2_OFF = 0, /**< Background layer 2 disabled */
|
||||||
|
ZELDA3_BG2_PARALLAX = 1, /**< Parallax scrolling effect */
|
||||||
|
ZELDA3_BG2_DARK = 2, /**< Dark overlay effect */
|
||||||
|
ZELDA3_BG2_ON_TOP = 3, /**< Layer appears on top */
|
||||||
|
ZELDA3_BG2_TRANSLUCENT = 4, /**< Semi-transparent overlay */
|
||||||
|
ZELDA3_BG2_ADDITION = 5, /**< Additive blending */
|
||||||
|
ZELDA3_BG2_NORMAL = 6, /**< Normal blending */
|
||||||
|
ZELDA3_BG2_TRANSPARENT = 7, /**< Fully transparent */
|
||||||
|
ZELDA3_BG2_DARK_ROOM = 8 /**< Dark room effect */
|
||||||
|
} zelda3_bg2_effect;
|
||||||
|
|
||||||
|
// Legacy aliases for backward compatibility
|
||||||
|
typedef zelda3_bg2_effect background2;
|
||||||
|
#define Off ZELDA3_BG2_OFF
|
||||||
|
#define Parallax ZELDA3_BG2_PARALLAX
|
||||||
|
#define Dark ZELDA3_BG2_DARK
|
||||||
|
#define OnTop ZELDA3_BG2_ON_TOP
|
||||||
|
#define Translucent ZELDA3_BG2_TRANSLUCENT
|
||||||
|
#define Addition ZELDA3_BG2_ADDITION
|
||||||
|
#define Normal ZELDA3_BG2_NORMAL
|
||||||
|
#define Transparent ZELDA3_BG2_TRANSPARENT
|
||||||
|
#define DarkRoom ZELDA3_BG2_DARK_ROOM
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Dungeon door object
|
||||||
|
*
|
||||||
|
* Represents a door or passage between rooms.
|
||||||
|
*/
|
||||||
|
typedef struct object_door {
|
||||||
|
uint16_t id; /**< Door ID for reference */
|
||||||
|
uint8_t x; /**< X position in room (0-63) */
|
||||||
|
uint8_t y; /**< Y position in room (0-63) */
|
||||||
|
uint8_t size; /**< Door size (width/height) */
|
||||||
|
uint8_t type; /**< Door type (normal, locked, etc.) */
|
||||||
|
uint8_t layer; /**< Layer (0=background, 1=foreground) */
|
||||||
|
uint8_t key_type; /**< Required key type (0=none) */
|
||||||
|
bool is_locked; /**< True if door requires key */
|
||||||
|
} object_door;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Staircase connection
|
||||||
|
*
|
||||||
|
* Represents stairs or holes that connect different rooms or levels.
|
||||||
|
*/
|
||||||
|
typedef struct staircase {
|
||||||
|
uint8_t id; /**< Staircase ID */
|
||||||
|
uint8_t room; /**< Target room ID (for backward compatibility) */
|
||||||
|
const char* label; /**< Description (for debugging) */
|
||||||
|
} staircase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Treasure chest
|
||||||
|
*
|
||||||
|
* Represents a chest containing an item.
|
||||||
|
*/
|
||||||
|
typedef struct chest {
|
||||||
|
uint8_t x; /**< X position in room */
|
||||||
|
uint8_t y; /**< Y position in room */
|
||||||
|
uint8_t item; /**< Item ID (for backward compatibility) */
|
||||||
|
bool picker; /**< Legacy field */
|
||||||
|
bool big_chest; /**< True for large chests */
|
||||||
|
} chest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Legacy chest data structure
|
||||||
|
*
|
||||||
|
* @deprecated Use chest structure instead
|
||||||
|
*/
|
||||||
|
typedef struct chest_data {
|
||||||
|
uint8_t id; /**< Chest ID */
|
||||||
|
bool size; /**< True for big chest */
|
||||||
|
} chest_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Room transition destination
|
||||||
|
*
|
||||||
|
* Defines where the player goes when using stairs, holes, or other transitions.
|
||||||
|
*/
|
||||||
|
typedef struct destination {
|
||||||
|
uint8_t index; /**< Entrance index */
|
||||||
|
uint8_t target; /**< Target room ID */
|
||||||
|
uint8_t target_layer; /**< Target layer */
|
||||||
|
} destination;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Complete dungeon room data
|
||||||
|
*
|
||||||
|
* Contains all objects, sprites, and properties for a single dungeon room.
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_dungeon_room {
|
||||||
|
uint16_t id; /**< Room ID (0-295) */
|
||||||
|
background2 bg2; /**< Background layer 2 effect (legacy) */
|
||||||
|
|
||||||
|
/* Room Contents */
|
||||||
|
dungeon_sprite* sprites; /**< Array of sprites in room */
|
||||||
|
int sprite_count; /**< Number of sprites */
|
||||||
|
|
||||||
|
object_door* doors; /**< Array of doors */
|
||||||
|
int door_count; /**< Number of doors */
|
||||||
|
|
||||||
|
staircase* staircases; /**< Array of staircases */
|
||||||
|
int staircase_count; /**< Number of staircases */
|
||||||
|
|
||||||
|
chest* chests; /**< Array of chests */
|
||||||
|
int chest_count; /**< Number of chests */
|
||||||
|
|
||||||
|
/* Room Connections */
|
||||||
|
destination pits; /**< Pit fall destination */
|
||||||
|
destination stairs[4]; /**< Stair destinations (up to 4) */
|
||||||
|
|
||||||
|
/* Room Properties */
|
||||||
|
uint8_t floor_type; /**< Floor graphics type */
|
||||||
|
uint8_t wall_type; /**< Wall graphics type */
|
||||||
|
uint8_t palette_id; /**< Room palette ID */
|
||||||
|
uint8_t music_track; /**< Background music track */
|
||||||
|
|
||||||
|
/* Flags */
|
||||||
|
bool is_dark; /**< True if room requires lamp */
|
||||||
|
bool has_water; /**< True if room contains water */
|
||||||
|
bool blocks_items; /**< True if room blocks certain items */
|
||||||
|
} zelda3_dungeon_room;
|
||||||
|
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // ZELDA_H
|
||||||
143
scripts/README.md
Normal file
143
scripts/README.md
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
# YAZE Build Scripts
|
||||||
|
|
||||||
|
This directory contains build and setup scripts for YAZE development on different platforms.
|
||||||
|
|
||||||
|
## Windows Scripts
|
||||||
|
|
||||||
|
### Setup Scripts
|
||||||
|
- **`setup-windows-dev.ps1`** - Complete Windows development environment setup (PowerShell)
|
||||||
|
- **`setup-vcpkg-windows.ps1`** - vcpkg setup only (PowerShell)
|
||||||
|
- **`setup-vcpkg-windows.bat`** - vcpkg setup only (Batch)
|
||||||
|
|
||||||
|
### Build Scripts
|
||||||
|
- **`build-windows.ps1`** - Build YAZE on Windows (PowerShell)
|
||||||
|
- **`build-windows.bat`** - Build YAZE on Windows (Batch)
|
||||||
|
|
||||||
|
### Validation Scripts
|
||||||
|
- **`validate-windows-build.ps1`** - Validate Windows build environment
|
||||||
|
|
||||||
|
### Project Generation
|
||||||
|
- **`generate-vs-projects.py`** - Generate Visual Studio project files (Cross-platform Python)
|
||||||
|
- **`generate-vs-projects.ps1`** - Generate Visual Studio project files (PowerShell)
|
||||||
|
- **`generate-vs-projects.bat`** - Generate Visual Studio project files (Batch)
|
||||||
|
|
||||||
|
## Quick Start (Windows)
|
||||||
|
|
||||||
|
### Option 1: Automated Setup (Recommended)
|
||||||
|
```powershell
|
||||||
|
.\scripts\setup-windows-dev.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 2: Manual Setup
|
||||||
|
```powershell
|
||||||
|
# 1. Setup vcpkg
|
||||||
|
.\scripts\setup-vcpkg-windows.ps1
|
||||||
|
|
||||||
|
# 2. Generate project files
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
# 3. Build
|
||||||
|
.\scripts\build-windows.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
### Option 3: Using Batch Scripts
|
||||||
|
```batch
|
||||||
|
REM Setup vcpkg
|
||||||
|
.\scripts\setup-vcpkg-windows.bat
|
||||||
|
|
||||||
|
REM Generate project files
|
||||||
|
python scripts/generate-vs-projects.py
|
||||||
|
|
||||||
|
REM Build
|
||||||
|
.\scripts\build-windows.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
## Script Options
|
||||||
|
|
||||||
|
### setup-windows-dev.ps1
|
||||||
|
- `-SkipVcpkg` - Skip vcpkg setup
|
||||||
|
- `-SkipVS` - Skip Visual Studio check
|
||||||
|
- `-SkipBuild` - Skip test build
|
||||||
|
|
||||||
|
### build-windows.ps1
|
||||||
|
- `-Configuration` - Build configuration (Debug, Release, RelWithDebInfo, MinSizeRel)
|
||||||
|
- `-Platform` - Target platform (x64, x86, ARM64)
|
||||||
|
- `-Clean` - Clean build directories before building
|
||||||
|
- `-Verbose` - Verbose build output
|
||||||
|
|
||||||
|
### build-windows.bat
|
||||||
|
- First argument: Configuration (Debug, Release, RelWithDebInfo, MinSizeRel)
|
||||||
|
- Second argument: Platform (x64, x86, ARM64)
|
||||||
|
- `clean` - Clean build directories
|
||||||
|
- `verbose` - Verbose build output
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
# Build Release x64 (default)
|
||||||
|
.\scripts\build-windows.ps1
|
||||||
|
|
||||||
|
# Build Debug x64
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Debug -Platform x64
|
||||||
|
|
||||||
|
# Build Release x86
|
||||||
|
.\scripts\build-windows.ps1 -Configuration Release -Platform x86
|
||||||
|
|
||||||
|
# Clean build
|
||||||
|
.\scripts\build-windows.ps1 -Clean
|
||||||
|
|
||||||
|
# Verbose build
|
||||||
|
.\scripts\build-windows.ps1 -Verbose
|
||||||
|
|
||||||
|
# Validate environment
|
||||||
|
.\scripts\validate-windows-build.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
```batch
|
||||||
|
REM Build Release x64 (default)
|
||||||
|
.\scripts\build-windows.bat
|
||||||
|
|
||||||
|
REM Build Debug x64
|
||||||
|
.\scripts\build-windows.bat Debug x64
|
||||||
|
|
||||||
|
REM Build Release x86
|
||||||
|
.\scripts\build-windows.bat Release x86
|
||||||
|
|
||||||
|
REM Clean build
|
||||||
|
.\scripts\build-windows.bat clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **PowerShell Execution Policy**
|
||||||
|
```powershell
|
||||||
|
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **MSBuild Not Found**
|
||||||
|
- Install Visual Studio 2022 with C++ workload
|
||||||
|
- Or add MSBuild to PATH
|
||||||
|
|
||||||
|
3. **vcpkg Issues**
|
||||||
|
- Run `.\scripts\setup-vcpkg-windows.ps1` to reinstall
|
||||||
|
- Check internet connection for dependency downloads
|
||||||
|
|
||||||
|
4. **Python Not Found**
|
||||||
|
- Install Python 3.8+ from python.org
|
||||||
|
- Make sure Python is in PATH
|
||||||
|
|
||||||
|
### Getting Help
|
||||||
|
|
||||||
|
1. Run validation script: `.\scripts\validate-windows-build.ps1`
|
||||||
|
2. Check the [Windows Development Guide](../docs/windows-development-guide.md)
|
||||||
|
3. Review build output for specific error messages
|
||||||
|
|
||||||
|
## Other Scripts
|
||||||
|
|
||||||
|
- **`create_release.sh`** - Create GitHub releases (Linux/macOS)
|
||||||
|
- **`extract_changelog.py`** - Extract changelog for releases
|
||||||
|
- **`quality_check.sh`** - Code quality checks (Linux/macOS)
|
||||||
|
- **`test_asar_integration.py`** - Test Asar integration
|
||||||
|
- **`agent.sh`** - AI agent helper script (Linux/macOS)
|
||||||
369
scripts/agent.sh
Executable file
369
scripts/agent.sh
Executable file
@@ -0,0 +1,369 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Unified background agent script for YAZE (macOS launchd, Linux systemd)
|
||||||
|
# Subcommands:
|
||||||
|
# install [--build-type X] [--use-inotify] [--ubuntu-bootstrap] [--enable-linger]
|
||||||
|
# uninstall
|
||||||
|
# run-once # one-shot build & test
|
||||||
|
# watch # linux: inotify-based watch loop
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
|
BUILD_DIR_DEFAULT="${PROJECT_ROOT}/build"
|
||||||
|
BUILD_TYPE_DEFAULT="Debug"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
Usage: $0 <subcommand> [options]
|
||||||
|
|
||||||
|
Subcommands:
|
||||||
|
install Install background agent
|
||||||
|
--build-type X CMake build type (default: ${BUILD_TYPE_DEFAULT})
|
||||||
|
--use-inotify Linux: use long-lived inotify watcher
|
||||||
|
--ubuntu-bootstrap Install Ubuntu deps via apt (sudo)
|
||||||
|
--enable-linger Enable user lingering (Linux)
|
||||||
|
|
||||||
|
uninstall Remove installed background agent
|
||||||
|
|
||||||
|
run-once One-shot build and test
|
||||||
|
env: BUILD_DIR, BUILD_TYPE
|
||||||
|
|
||||||
|
watch Linux: inotify-based watch loop
|
||||||
|
env: BUILD_DIR, BUILD_TYPE, INTERVAL_SECONDS (fallback)
|
||||||
|
|
||||||
|
Environment:
|
||||||
|
BUILD_DIR Build directory (default: ${BUILD_DIR_DEFAULT})
|
||||||
|
BUILD_TYPE CMake build type (default: ${BUILD_TYPE_DEFAULT})
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
build_and_test() {
|
||||||
|
local build_dir="${BUILD_DIR:-${BUILD_DIR_DEFAULT}}"
|
||||||
|
local build_type="${BUILD_TYPE:-${BUILD_TYPE_DEFAULT}}"
|
||||||
|
local log_file="${LOG_FILE:-"${build_dir}/yaze_agent.log"}"
|
||||||
|
|
||||||
|
mkdir -p "${build_dir}"
|
||||||
|
{
|
||||||
|
echo "==== $(date '+%Y-%m-%d %H:%M:%S') | yaze agent run (type=${build_type}) ===="
|
||||||
|
echo "Project: ${PROJECT_ROOT}"
|
||||||
|
|
||||||
|
cmake -S "${PROJECT_ROOT}" -B "${build_dir}" -DCMAKE_BUILD_TYPE="${build_type}"
|
||||||
|
cmake --build "${build_dir}" --config "${build_type}" -j
|
||||||
|
|
||||||
|
if [[ -x "${build_dir}/bin/yaze_test" ]]; then
|
||||||
|
"${build_dir}/bin/yaze_test"
|
||||||
|
else
|
||||||
|
if command -v ctest >/dev/null 2>&1; then
|
||||||
|
ctest --test-dir "${build_dir}" --output-on-failure
|
||||||
|
else
|
||||||
|
echo "ctest not found and test binary missing. Skipping tests." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
} >>"${log_file}" 2>&1
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_run_once() {
|
||||||
|
build_and_test
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_watch() {
|
||||||
|
local build_dir="${BUILD_DIR:-${BUILD_DIR_DEFAULT}}"
|
||||||
|
local build_type="${BUILD_TYPE:-${BUILD_TYPE_DEFAULT}}"
|
||||||
|
local interval="${INTERVAL_SECONDS:-5}"
|
||||||
|
mkdir -p "${build_dir}"
|
||||||
|
if command -v inotifywait >/dev/null 2>&1; then
|
||||||
|
echo "[agent] using inotifywait watcher"
|
||||||
|
while true; do
|
||||||
|
BUILD_DIR="${build_dir}" BUILD_TYPE="${build_type}" build_and_test || true
|
||||||
|
inotifywait -r -e modify,create,delete,move \
|
||||||
|
"${PROJECT_ROOT}/src" \
|
||||||
|
"${PROJECT_ROOT}/test" \
|
||||||
|
"${PROJECT_ROOT}/CMakeLists.txt" \
|
||||||
|
"${PROJECT_ROOT}/src/CMakeLists.txt" >/dev/null 2>&1 || true
|
||||||
|
done
|
||||||
|
else
|
||||||
|
echo "[agent] inotifywait not found; running periodic loop (${interval}s)"
|
||||||
|
while true; do
|
||||||
|
BUILD_DIR="${build_dir}" BUILD_TYPE="${build_type}" build_and_test || true
|
||||||
|
sleep "${interval}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_exec() {
|
||||||
|
if [[ ! -x "$1" ]]; then
|
||||||
|
chmod +x "$1"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
ubuntu_bootstrap() {
|
||||||
|
if command -v apt-get >/dev/null 2>&1; then
|
||||||
|
sudo apt-get update
|
||||||
|
sudo apt-get install -y inotify-tools build-essential cmake ninja-build pkg-config \
|
||||||
|
libsdl2-dev libpng-dev libglew-dev libwavpack-dev libabsl-dev \
|
||||||
|
libboost-all-dev libboost-python-dev python3-dev libpython3-dev
|
||||||
|
else
|
||||||
|
echo "apt-get not found; skipping Ubuntu bootstrap" >&2
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_linger_linux() {
|
||||||
|
if command -v loginctl >/dev/null 2>&1; then
|
||||||
|
if sudo -n true 2>/dev/null; then
|
||||||
|
sudo loginctl enable-linger "$USER" || true
|
||||||
|
else
|
||||||
|
echo "Note: enabling linger may require sudo: sudo loginctl enable-linger $USER" >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wrapper to run systemctl --user with a session bus in headless shells
|
||||||
|
systemctl_user() {
|
||||||
|
# Only apply on Linux
|
||||||
|
if [[ "$(uname -s)" != "Linux" ]]; then
|
||||||
|
systemctl "$@"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local uid
|
||||||
|
uid="$(id -u)"
|
||||||
|
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/${uid}}"
|
||||||
|
export DBUS_SESSION_BUS_ADDRESS="${DBUS_SESSION_BUS_ADDRESS:-unix:path=${XDG_RUNTIME_DIR}/bus}"
|
||||||
|
if [[ ! -S "${XDG_RUNTIME_DIR}/bus" ]]; then
|
||||||
|
echo "[agent] Warning: user bus not found at ${XDG_RUNTIME_DIR}/bus. If this fails, run: sudo loginctl enable-linger $USER" >&2
|
||||||
|
fi
|
||||||
|
systemctl --user "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
is_systemd_available() {
|
||||||
|
# True if systemd is PID 1 and systemctl exists and a user bus likely available
|
||||||
|
if [[ ! -d /run/systemd/system ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
if ! command -v systemctl >/dev/null 2>&1; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
start_userland_agent() {
|
||||||
|
local build_type="${1}"
|
||||||
|
local build_dir="${2}"
|
||||||
|
local agent_home="$HOME/.local/share/yaze-agent"
|
||||||
|
mkdir -p "${agent_home}"
|
||||||
|
local log_file="${agent_home}/agent.log"
|
||||||
|
nohup env BUILD_TYPE="${build_type}" BUILD_DIR="${build_dir}" "${SCRIPT_DIR}/agent.sh" watch >>"${log_file}" 2>&1 & echo $! > "${agent_home}/agent.pid"
|
||||||
|
echo "Userland agent started (PID $(cat "${agent_home}/agent.pid")) - logs: ${log_file}"
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_userland_agent() {
|
||||||
|
local agent_home="$HOME/.local/share/yaze-agent"
|
||||||
|
local pid_file="${agent_home}/agent.pid"
|
||||||
|
if [[ -f "${pid_file}" ]]; then
|
||||||
|
local pid
|
||||||
|
pid="$(cat "${pid_file}")"
|
||||||
|
if kill -0 "${pid}" >/dev/null 2>&1; then
|
||||||
|
kill "${pid}" || true
|
||||||
|
fi
|
||||||
|
rm -f "${pid_file}"
|
||||||
|
echo "Stopped userland agent"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
install_macos() {
|
||||||
|
local build_type="${1}"
|
||||||
|
local build_dir="${2}"
|
||||||
|
local label="com.yaze.watchtest"
|
||||||
|
local plist_path="$HOME/Library/LaunchAgents/${label}.plist"
|
||||||
|
|
||||||
|
mkdir -p "${build_dir}"
|
||||||
|
|
||||||
|
cat >"$plist_path" <<PLIST
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>Label</key>
|
||||||
|
<string>${label}</string>
|
||||||
|
<key>RunAtLoad</key>
|
||||||
|
<true/>
|
||||||
|
<key>ProgramArguments</key>
|
||||||
|
<array>
|
||||||
|
<string>/bin/zsh</string>
|
||||||
|
<string>-lc</string>
|
||||||
|
<string>"${SCRIPT_DIR}/agent.sh" run-once</string>
|
||||||
|
</array>
|
||||||
|
<key>WorkingDirectory</key>
|
||||||
|
<string>${PROJECT_ROOT}</string>
|
||||||
|
<key>WatchPaths</key>
|
||||||
|
<array>
|
||||||
|
<string>${PROJECT_ROOT}/src</string>
|
||||||
|
<string>${PROJECT_ROOT}/test</string>
|
||||||
|
<string>${PROJECT_ROOT}/CMakeLists.txt</string>
|
||||||
|
<string>${PROJECT_ROOT}/src/CMakeLists.txt</string>
|
||||||
|
</array>
|
||||||
|
<key>StandardOutPath</key>
|
||||||
|
<string>${build_dir}/yaze_agent.out.log</string>
|
||||||
|
<key>StandardErrorPath</key>
|
||||||
|
<string>${build_dir}/yaze_agent.err.log</string>
|
||||||
|
<key>EnvironmentVariables</key>
|
||||||
|
<dict>
|
||||||
|
<key>BUILD_TYPE</key><string>${build_type}</string>
|
||||||
|
<key>BUILD_DIR</key><string>${build_dir}</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
PLIST
|
||||||
|
|
||||||
|
launchctl unload -w "$plist_path" 2>/dev/null || true
|
||||||
|
launchctl load -w "$plist_path"
|
||||||
|
echo "LaunchAgent installed and loaded: ${plist_path}"
|
||||||
|
}
|
||||||
|
|
||||||
|
install_linux() {
|
||||||
|
local build_type="${1}"
|
||||||
|
local build_dir="${2}"
|
||||||
|
local use_inotify="${3}"
|
||||||
|
local systemd_dir="$HOME/.config/systemd/user"
|
||||||
|
local service_name="yaze-watchtest.service"
|
||||||
|
local path_name="yaze-watchtest.path"
|
||||||
|
|
||||||
|
mkdir -p "${systemd_dir}" "${build_dir}"
|
||||||
|
|
||||||
|
if ! is_systemd_available; then
|
||||||
|
echo "[agent] systemd not available; installing userland background agent"
|
||||||
|
start_userland_agent "${build_type}" "${build_dir}"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "${use_inotify}" == "1" ]]; then
|
||||||
|
cat >"${systemd_dir}/yaze-watchtest-inotify.service" <<UNIT
|
||||||
|
[Unit]
|
||||||
|
Description=Yaze inotify watcher build-and-test
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment=BUILD_TYPE=${build_type}
|
||||||
|
Environment=BUILD_DIR=${build_dir}
|
||||||
|
WorkingDirectory=${PROJECT_ROOT}
|
||||||
|
ExecStart=/bin/bash -lc '"${SCRIPT_DIR}/agent.sh" watch'
|
||||||
|
Restart=always
|
||||||
|
RestartSec=2
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
systemctl_user daemon-reload
|
||||||
|
systemctl_user enable --now yaze-watchtest-inotify.service
|
||||||
|
echo "systemd user service enabled: yaze-watchtest-inotify.service"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat >"${systemd_dir}/${service_name}" <<UNIT
|
||||||
|
[Unit]
|
||||||
|
Description=Yaze build-and-test (one-shot)
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
Environment=BUILD_TYPE=${build_type}
|
||||||
|
Environment=BUILD_DIR=${build_dir}
|
||||||
|
WorkingDirectory=${PROJECT_ROOT}
|
||||||
|
ExecStart=/bin/bash -lc '"${SCRIPT_DIR}/agent.sh" run-once'
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
cat >"${systemd_dir}/${path_name}" <<UNIT
|
||||||
|
[Unit]
|
||||||
|
Description=Watch Yaze src/test for changes
|
||||||
|
|
||||||
|
[Path]
|
||||||
|
PathModified=${PROJECT_ROOT}/src
|
||||||
|
PathModified=${PROJECT_ROOT}/test
|
||||||
|
PathModified=${PROJECT_ROOT}/CMakeLists.txt
|
||||||
|
PathModified=${PROJECT_ROOT}/src/CMakeLists.txt
|
||||||
|
Unit=${service_name}
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
||||||
|
UNIT
|
||||||
|
|
||||||
|
systemctl_user daemon-reload
|
||||||
|
systemctl_user enable --now "$path_name"
|
||||||
|
echo "systemd user path unit enabled: ${path_name}"
|
||||||
|
systemctl_user start "$service_name" || true
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_install() {
|
||||||
|
local build_type="${BUILD_TYPE:-${BUILD_TYPE_DEFAULT}}"
|
||||||
|
local build_dir="${BUILD_DIR:-${BUILD_DIR_DEFAULT}}"
|
||||||
|
local use_inotify=0
|
||||||
|
local do_bootstrap=0
|
||||||
|
local do_linger=0
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case "$1" in
|
||||||
|
--build-type) build_type="$2"; shift 2 ;;
|
||||||
|
--use-inotify) use_inotify=1; shift ;;
|
||||||
|
--ubuntu-bootstrap) do_bootstrap=1; shift ;;
|
||||||
|
--enable-linger) do_linger=1; shift ;;
|
||||||
|
-h|--help) usage; exit 0 ;;
|
||||||
|
*) echo "Unknown option for install: $1" >&2; usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin)
|
||||||
|
install_macos "${build_type}" "${build_dir}" ;;
|
||||||
|
Linux)
|
||||||
|
if (( do_bootstrap == 1 )); then ubuntu_bootstrap; fi
|
||||||
|
if (( do_linger == 1 )); then enable_linger_linux; fi
|
||||||
|
install_linux "${build_type}" "${build_dir}" "${use_inotify}" ;;
|
||||||
|
*)
|
||||||
|
echo "Unsupported platform" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
sub_uninstall() {
|
||||||
|
case "$(uname -s)" in
|
||||||
|
Darwin)
|
||||||
|
local label="com.yaze.watchtest"
|
||||||
|
local plist_path="$HOME/Library/LaunchAgents/${label}.plist"
|
||||||
|
launchctl unload -w "$plist_path" 2>/dev/null || true
|
||||||
|
rm -f "$plist_path"
|
||||||
|
echo "Removed LaunchAgent ${label}"
|
||||||
|
;;
|
||||||
|
Linux)
|
||||||
|
local systemd_dir="$HOME/.config/systemd/user"
|
||||||
|
if is_systemd_available; then
|
||||||
|
systemctl_user stop yaze-watchtest.path 2>/dev/null || true
|
||||||
|
systemctl_user disable yaze-watchtest.path 2>/dev/null || true
|
||||||
|
systemctl_user stop yaze-watchtest.service 2>/dev/null || true
|
||||||
|
systemctl_user stop yaze-watchtest-inotify.service 2>/dev/null || true
|
||||||
|
systemctl_user disable yaze-watchtest-inotify.service 2>/dev/null || true
|
||||||
|
rm -f "${systemd_dir}/yaze-watchtest.service" "${systemd_dir}/yaze-watchtest.path" "${systemd_dir}/yaze-watchtest-inotify.service"
|
||||||
|
systemctl_user daemon-reload || true
|
||||||
|
echo "Removed systemd user units"
|
||||||
|
fi
|
||||||
|
stop_userland_agent
|
||||||
|
;;
|
||||||
|
*) echo "Unsupported platform" >&2; exit 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
ensure_exec "$0"
|
||||||
|
local subcmd="${1:-}"; shift || true
|
||||||
|
case "${subcmd}" in
|
||||||
|
install) sub_install "$@" ;;
|
||||||
|
uninstall) sub_uninstall ;;
|
||||||
|
run-once) sub_run_once ;;
|
||||||
|
watch) sub_watch ;;
|
||||||
|
-h|--help|help|"") usage ;;
|
||||||
|
*) echo "Unknown subcommand: ${subcmd}" >&2; usage; exit 1 ;;
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
|
||||||
|
|
||||||
164
scripts/build-windows.bat
Normal file
164
scripts/build-windows.bat
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
@echo off
|
||||||
|
REM YAZE Windows Build Script (Batch Version)
|
||||||
|
REM This script builds the YAZE project on Windows using MSBuild
|
||||||
|
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
REM Parse command line arguments
|
||||||
|
set BUILD_CONFIG=Release
|
||||||
|
set BUILD_PLATFORM=x64
|
||||||
|
set CLEAN_BUILD=0
|
||||||
|
set VERBOSE=0
|
||||||
|
|
||||||
|
:parse_args
|
||||||
|
if "%~1"=="" goto :args_done
|
||||||
|
if /i "%~1"=="Debug" set BUILD_CONFIG=Debug
|
||||||
|
if /i "%~1"=="Release" set BUILD_CONFIG=Release
|
||||||
|
if /i "%~1"=="RelWithDebInfo" set BUILD_CONFIG=RelWithDebInfo
|
||||||
|
if /i "%~1"=="MinSizeRel" set BUILD_CONFIG=MinSizeRel
|
||||||
|
if /i "%~1"=="x64" set BUILD_PLATFORM=x64
|
||||||
|
if /i "%~1"=="x86" set BUILD_PLATFORM=x86
|
||||||
|
if /i "%~1"=="ARM64" set BUILD_PLATFORM=ARM64
|
||||||
|
if /i "%~1"=="clean" set CLEAN_BUILD=1
|
||||||
|
if /i "%~1"=="verbose" set VERBOSE=1
|
||||||
|
shift
|
||||||
|
goto :parse_args
|
||||||
|
|
||||||
|
:args_done
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo YAZE Windows Build Script
|
||||||
|
echo ========================================
|
||||||
|
|
||||||
|
REM Check if we're in the right directory
|
||||||
|
if not exist "YAZE.sln" (
|
||||||
|
echo ERROR: YAZE.sln not found. Please run this script from the project root directory.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ YAZE.sln found
|
||||||
|
|
||||||
|
REM Check for MSBuild
|
||||||
|
where msbuild >nul 2>&1
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ERROR: MSBuild not found. Please install Visual Studio 2022 or later.
|
||||||
|
echo Make sure to install the C++ development workload.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ MSBuild found
|
||||||
|
|
||||||
|
REM Check for vcpkg
|
||||||
|
if not exist "vcpkg.json" (
|
||||||
|
echo WARNING: vcpkg.json not found. vcpkg integration may not work properly.
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Build Configuration: %BUILD_CONFIG%
|
||||||
|
echo Build Platform: %BUILD_PLATFORM%
|
||||||
|
|
||||||
|
REM Create build directories
|
||||||
|
echo Creating build directories...
|
||||||
|
if not exist "build" mkdir build
|
||||||
|
if not exist "build\bin" mkdir build\bin
|
||||||
|
if not exist "build\obj" mkdir build\obj
|
||||||
|
|
||||||
|
REM Clean build if requested
|
||||||
|
if %CLEAN_BUILD%==1 (
|
||||||
|
echo Cleaning build directories...
|
||||||
|
if exist "build\bin" rmdir /s /q "build\bin" 2>nul
|
||||||
|
if exist "build\obj" rmdir /s /q "build\obj" 2>nul
|
||||||
|
if not exist "build\bin" mkdir build\bin
|
||||||
|
if not exist "build\obj" mkdir build\obj
|
||||||
|
echo ✓ Build directories cleaned
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Generate yaze_config.h if it doesn't exist
|
||||||
|
if not exist "yaze_config.h" (
|
||||||
|
echo Generating yaze_config.h...
|
||||||
|
if exist "src\yaze_config.h.in" (
|
||||||
|
copy "src\yaze_config.h.in" "yaze_config.h" >nul
|
||||||
|
powershell -Command "(Get-Content 'yaze_config.h') -replace '@yaze_VERSION_MAJOR@', '0' -replace '@yaze_VERSION_MINOR@', '3' -replace '@yaze_VERSION_PATCH@', '1' | Set-Content 'yaze_config.h'"
|
||||||
|
echo ✓ Generated yaze_config.h
|
||||||
|
) else (
|
||||||
|
echo WARNING: yaze_config.h.in not found, creating basic config
|
||||||
|
echo // yaze config file > yaze_config.h
|
||||||
|
echo #define YAZE_VERSION_MAJOR 0 >> yaze_config.h
|
||||||
|
echo #define YAZE_VERSION_MINOR 3 >> yaze_config.h
|
||||||
|
echo #define YAZE_VERSION_PATCH 1 >> yaze_config.h
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Build using MSBuild
|
||||||
|
echo Building with MSBuild...
|
||||||
|
|
||||||
|
set MSBUILD_ARGS=YAZE.sln /p:Configuration=%BUILD_CONFIG% /p:Platform=%BUILD_PLATFORM% /p:VcpkgEnabled=true /p:VcpkgManifestInstall=true /m
|
||||||
|
|
||||||
|
if %VERBOSE%==1 (
|
||||||
|
set MSBUILD_ARGS=%MSBUILD_ARGS% /verbosity:detailed
|
||||||
|
) else (
|
||||||
|
set MSBUILD_ARGS=%MSBUILD_ARGS% /verbosity:minimal
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Command: msbuild %MSBUILD_ARGS%
|
||||||
|
|
||||||
|
msbuild %MSBUILD_ARGS%
|
||||||
|
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ERROR: Build failed with exit code %errorlevel%
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ Build completed successfully
|
||||||
|
|
||||||
|
REM Verify executable was created
|
||||||
|
set EXE_PATH=build\bin\%BUILD_CONFIG%\yaze.exe
|
||||||
|
if not exist "%EXE_PATH%" (
|
||||||
|
echo ERROR: Executable not found at expected path: %EXE_PATH%
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ Executable created: %EXE_PATH%
|
||||||
|
|
||||||
|
REM Test that the executable runs (basic test)
|
||||||
|
echo Testing executable startup...
|
||||||
|
"%EXE_PATH%" --help >nul 2>&1
|
||||||
|
set EXIT_CODE=%errorlevel%
|
||||||
|
|
||||||
|
REM Check if it's the test main or app main
|
||||||
|
"%EXE_PATH%" --help 2>&1 | findstr /i "Google Test" >nul
|
||||||
|
if %errorlevel% equ 0 (
|
||||||
|
echo ERROR: Executable is running test main instead of app main!
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ Executable runs correctly (exit code: %EXIT_CODE%)
|
||||||
|
|
||||||
|
REM Display file info
|
||||||
|
for %%A in ("%EXE_PATH%") do set FILE_SIZE=%%~zA
|
||||||
|
set /a FILE_SIZE_MB=%FILE_SIZE% / 1024 / 1024
|
||||||
|
echo Executable size: %FILE_SIZE_MB% MB
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo ✓ YAZE Windows build completed successfully!
|
||||||
|
echo ========================================
|
||||||
|
echo.
|
||||||
|
echo Build Configuration: %BUILD_CONFIG%
|
||||||
|
echo Build Platform: %BUILD_PLATFORM%
|
||||||
|
echo Executable: %EXE_PATH%
|
||||||
|
echo.
|
||||||
|
echo To run YAZE:
|
||||||
|
echo %EXE_PATH%
|
||||||
|
echo.
|
||||||
|
echo To build other configurations:
|
||||||
|
echo %~nx0 Debug x64
|
||||||
|
echo %~nx0 Release x86
|
||||||
|
echo %~nx0 RelWithDebInfo ARM64
|
||||||
|
echo %~nx0 clean
|
||||||
|
echo.
|
||||||
|
|
||||||
|
pause
|
||||||
220
scripts/build-windows.ps1
Normal file
220
scripts/build-windows.ps1
Normal file
@@ -0,0 +1,220 @@
|
|||||||
|
# YAZE Windows Build Script
|
||||||
|
# This script builds the YAZE project on Windows using MSBuild
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$Configuration = "Release",
|
||||||
|
[string]$Platform = "x64",
|
||||||
|
[switch]$Clean,
|
||||||
|
[switch]$Verbose
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set error handling
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
$Colors = @{
|
||||||
|
Success = "Green"
|
||||||
|
Warning = "Yellow"
|
||||||
|
Error = "Red"
|
||||||
|
Info = "Cyan"
|
||||||
|
White = "White"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Status {
|
||||||
|
param([string]$Message, [string]$Color = "White")
|
||||||
|
Write-Host $Message -ForegroundColor $Colors[$Color]
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-Command {
|
||||||
|
param([string]$Command)
|
||||||
|
try {
|
||||||
|
$null = Get-Command $Command -ErrorAction Stop
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-MSBuildPath {
|
||||||
|
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||||
|
if (Test-Path $vsWhere) {
|
||||||
|
$vsInstall = & $vsWhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||||
|
if ($vsInstall) {
|
||||||
|
$msbuildPath = Join-Path $vsInstall "MSBuild\Current\Bin\MSBuild.exe"
|
||||||
|
if (Test-Path $msbuildPath) {
|
||||||
|
return $msbuildPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status "YAZE Windows Build Script" "Info"
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
|
||||||
|
# Validate parameters
|
||||||
|
$ValidConfigs = @("Debug", "Release", "RelWithDebInfo", "MinSizeRel")
|
||||||
|
$ValidPlatforms = @("x64", "x86", "ARM64")
|
||||||
|
|
||||||
|
if ($ValidConfigs -notcontains $Configuration) {
|
||||||
|
Write-Status "ERROR: Invalid configuration '$Configuration'. Valid options: $($ValidConfigs -join ', ')" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($ValidPlatforms -notcontains $Platform) {
|
||||||
|
Write-Status "ERROR: Invalid platform '$Platform'. Valid options: $($ValidPlatforms -join ', ')" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "Build Configuration: $Configuration" "Warning"
|
||||||
|
Write-Status "Build Platform: $Platform" "Warning"
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if (-not (Test-Path "YAZE.sln")) {
|
||||||
|
Write-Status "ERROR: YAZE.sln not found. Please run this script from the project root directory." "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ Found YAZE.sln" "Success"
|
||||||
|
|
||||||
|
# Check for MSBuild
|
||||||
|
$msbuildPath = Get-MSBuildPath
|
||||||
|
if (-not $msbuildPath) {
|
||||||
|
Write-Status "ERROR: MSBuild not found. Please install Visual Studio 2022 with C++ workload." "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ MSBuild found at: $msbuildPath" "Success"
|
||||||
|
|
||||||
|
# Check for vcpkg
|
||||||
|
if (-not (Test-Path "vcpkg.json")) {
|
||||||
|
Write-Status "WARNING: vcpkg.json not found. vcpkg integration may not work properly." "Warning"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create build directories
|
||||||
|
Write-Status "Creating build directories..." "Warning"
|
||||||
|
$directories = @("build", "build\bin", "build\obj")
|
||||||
|
foreach ($dir in $directories) {
|
||||||
|
if (-not (Test-Path $dir)) {
|
||||||
|
New-Item -ItemType Directory -Path $dir -Force | Out-Null
|
||||||
|
Write-Status "✓ Created directory: $dir" "Success"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Clean build if requested
|
||||||
|
if ($Clean) {
|
||||||
|
Write-Status "Cleaning build directories..." "Warning"
|
||||||
|
if (Test-Path "build\bin") {
|
||||||
|
Remove-Item -Recurse -Force "build\bin\*" -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
if (Test-Path "build\obj") {
|
||||||
|
Remove-Item -Recurse -Force "build\obj\*" -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
Write-Status "✓ Build directories cleaned" "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Generate yaze_config.h if it doesn't exist
|
||||||
|
if (-not (Test-Path "yaze_config.h")) {
|
||||||
|
Write-Status "Generating yaze_config.h..." "Warning"
|
||||||
|
if (Test-Path "src\yaze_config.h.in") {
|
||||||
|
Copy-Item "src\yaze_config.h.in" "yaze_config.h"
|
||||||
|
$content = Get-Content "yaze_config.h" -Raw
|
||||||
|
$content = $content -replace '@yaze_VERSION_MAJOR@', '0'
|
||||||
|
$content = $content -replace '@yaze_VERSION_MINOR@', '3'
|
||||||
|
$content = $content -replace '@yaze_VERSION_PATCH@', '1'
|
||||||
|
Set-Content "yaze_config.h" $content
|
||||||
|
Write-Status "✓ Generated yaze_config.h" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "WARNING: yaze_config.h.in not found, creating basic config" "Warning"
|
||||||
|
@"
|
||||||
|
// yaze config file
|
||||||
|
#define YAZE_VERSION_MAJOR 0
|
||||||
|
#define YAZE_VERSION_MINOR 3
|
||||||
|
#define YAZE_VERSION_PATCH 1
|
||||||
|
"@ | Out-File -FilePath "yaze_config.h" -Encoding UTF8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Build using MSBuild
|
||||||
|
Write-Status "Building with MSBuild..." "Warning"
|
||||||
|
|
||||||
|
$msbuildArgs = @(
|
||||||
|
"YAZE.sln"
|
||||||
|
"/p:Configuration=$Configuration"
|
||||||
|
"/p:Platform=$Platform"
|
||||||
|
"/p:VcpkgEnabled=true"
|
||||||
|
"/p:VcpkgManifestInstall=true"
|
||||||
|
"/m"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($Verbose) {
|
||||||
|
$msbuildArgs += "/verbosity:detailed"
|
||||||
|
} else {
|
||||||
|
$msbuildArgs += "/verbosity:minimal"
|
||||||
|
}
|
||||||
|
|
||||||
|
$msbuildCommand = "& `"$msbuildPath`" $($msbuildArgs -join ' ')"
|
||||||
|
Write-Status "Command: $msbuildCommand" "Info"
|
||||||
|
|
||||||
|
try {
|
||||||
|
& $msbuildPath @msbuildArgs
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
throw "MSBuild failed with exit code $LASTEXITCODE"
|
||||||
|
}
|
||||||
|
Write-Status "✓ Build completed successfully" "Success"
|
||||||
|
} catch {
|
||||||
|
Write-Status "✗ Build failed: $_" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verify executable was created
|
||||||
|
$exePath = "build\bin\$Configuration\yaze.exe"
|
||||||
|
if (-not (Test-Path $exePath)) {
|
||||||
|
Write-Status "ERROR: Executable not found at expected path: $exePath" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ Executable created: $exePath" "Success"
|
||||||
|
|
||||||
|
# Test that the executable runs
|
||||||
|
Write-Status "Testing executable..." "Warning"
|
||||||
|
try {
|
||||||
|
$testResult = & $exePath --help 2>&1
|
||||||
|
$exitCode = $LASTEXITCODE
|
||||||
|
|
||||||
|
# Check if it's the test main or app main
|
||||||
|
if ($testResult -match "Google Test|gtest") {
|
||||||
|
Write-Status "ERROR: Executable is running test main instead of app main!" "Error"
|
||||||
|
Write-Status "Output: $testResult" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ Executable runs correctly (exit code: $exitCode)" "Success"
|
||||||
|
} catch {
|
||||||
|
Write-Status "WARNING: Could not test executable: $_" "Warning"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Display file info
|
||||||
|
$exeInfo = Get-Item $exePath
|
||||||
|
$fileSizeMB = [math]::Round($exeInfo.Length / 1MB, 2)
|
||||||
|
Write-Status "Executable size: $fileSizeMB MB" "Info"
|
||||||
|
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status "✓ YAZE Windows build completed successfully!" "Success"
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "Build Configuration: $Configuration" "White"
|
||||||
|
Write-Status "Build Platform: $Platform" "White"
|
||||||
|
Write-Status "Executable: $exePath" "White"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "To run YAZE:" "Warning"
|
||||||
|
Write-Status " $exePath" "White"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "To build other configurations:" "Warning"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1 -Configuration Debug -Platform x64" "White"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1 -Configuration Release -Platform x86" "White"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1 -Configuration RelWithDebInfo -Platform ARM64" "White"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1 -Clean" "White"
|
||||||
|
Write-Status ""
|
||||||
64
scripts/create-macos-bundle.sh
Executable file
64
scripts/create-macos-bundle.sh
Executable file
@@ -0,0 +1,64 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create macOS bundle script
|
||||||
|
# Usage: create-macos-bundle.sh <version> <artifact_name>
|
||||||
|
|
||||||
|
VERSION_NUM="$1"
|
||||||
|
ARTIFACT_NAME="$2"
|
||||||
|
|
||||||
|
if [ -z "$VERSION_NUM" ] || [ -z "$ARTIFACT_NAME" ]; then
|
||||||
|
echo "Usage: $0 <version> <artifact_name>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Creating macOS bundle for version: $VERSION_NUM"
|
||||||
|
|
||||||
|
# macOS packaging
|
||||||
|
if [ -d "build/bin/yaze.app" ]; then
|
||||||
|
echo "Found macOS bundle, using it directly"
|
||||||
|
cp -r build/bin/yaze.app ./Yaze.app
|
||||||
|
# Add additional resources to the bundle
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Update Info.plist with correct version
|
||||||
|
if [ -f "cmake/yaze.plist.in" ]; then
|
||||||
|
sed "s/@yaze_VERSION@/$VERSION_NUM/g" cmake/yaze.plist.in > "Yaze.app/Contents/Info.plist"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
echo "No bundle found, creating manual bundle"
|
||||||
|
mkdir -p "Yaze.app/Contents/MacOS"
|
||||||
|
mkdir -p "Yaze.app/Contents/Resources"
|
||||||
|
cp build/bin/yaze "Yaze.app/Contents/MacOS/"
|
||||||
|
cp -r assets "Yaze.app/Contents/Resources/" 2>/dev/null || echo "assets directory not found"
|
||||||
|
# Create Info.plist with correct version
|
||||||
|
cat > "Yaze.app/Contents/Info.plist" <<EOF
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>yaze</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>com.yaze.editor</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>Yaze</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>$VERSION_NUM</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>$VERSION_NUM</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create DMG
|
||||||
|
mkdir dmg_staging
|
||||||
|
cp -r Yaze.app dmg_staging/
|
||||||
|
cp LICENSE dmg_staging/ 2>/dev/null || echo "LICENSE not found"
|
||||||
|
cp README.md dmg_staging/ 2>/dev/null || echo "README.md not found"
|
||||||
|
cp -r docs dmg_staging/ 2>/dev/null || echo "docs directory not found"
|
||||||
|
hdiutil create -srcfolder dmg_staging -format UDZO -volname "Yaze v$VERSION_NUM" "$ARTIFACT_NAME.dmg"
|
||||||
|
|
||||||
|
echo "macOS bundle creation completed successfully!"
|
||||||
138
scripts/create_release.sh
Executable file
138
scripts/create_release.sh
Executable file
@@ -0,0 +1,138 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Script to create a proper release tag for YAZE
|
||||||
|
# Usage: ./scripts/create_release.sh [version]
|
||||||
|
# Example: ./scripts/create_release.sh 0.3.0
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Function to print colored output
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}ℹ️ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}✅ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}⚠️ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}❌ $1${NC}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we're in a git repository
|
||||||
|
if ! git rev-parse --git-dir > /dev/null 2>&1; then
|
||||||
|
print_error "Not in a git repository!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if we're on master branch
|
||||||
|
current_branch=$(git branch --show-current)
|
||||||
|
if [ "$current_branch" != "master" ]; then
|
||||||
|
print_warning "You're on branch '$current_branch', not 'master'"
|
||||||
|
read -p "Continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_info "Switching to master branch..."
|
||||||
|
git checkout master
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get version argument or prompt for it
|
||||||
|
if [ $# -eq 0 ]; then
|
||||||
|
echo
|
||||||
|
print_info "Enter the version number (e.g., 0.3.0, 1.0.0-beta, 2.1.0-rc1):"
|
||||||
|
read -p "Version: " version
|
||||||
|
else
|
||||||
|
version=$1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Validate version format
|
||||||
|
if [[ ! "$version" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then
|
||||||
|
print_error "Invalid version format: '$version'"
|
||||||
|
print_info "Version must follow semantic versioning (e.g., 1.2.3 or 1.2.3-beta)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create tag with v prefix
|
||||||
|
tag="v$version"
|
||||||
|
|
||||||
|
# Check if tag already exists
|
||||||
|
if git tag -l | grep -q "^$tag$"; then
|
||||||
|
print_error "Tag '$tag' already exists!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show current status
|
||||||
|
echo
|
||||||
|
print_info "Current repository status:"
|
||||||
|
git status --short
|
||||||
|
|
||||||
|
# Check for uncommitted changes
|
||||||
|
if ! git diff-index --quiet HEAD --; then
|
||||||
|
print_warning "You have uncommitted changes!"
|
||||||
|
read -p "Continue with creating release? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_info "Please commit your changes first, then run this script again."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Show what will happen
|
||||||
|
echo
|
||||||
|
print_info "Creating release for YAZE:"
|
||||||
|
echo " 📦 Version: $version"
|
||||||
|
echo " 🏷️ Tag: $tag"
|
||||||
|
echo " 🌿 Branch: $current_branch"
|
||||||
|
echo " 📝 Changelog: docs/C1-changelog.md"
|
||||||
|
echo
|
||||||
|
|
||||||
|
# Confirm
|
||||||
|
read -p "Create this release? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_info "Release creation cancelled."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Create and push tag
|
||||||
|
print_info "Creating tag '$tag'..."
|
||||||
|
if git tag -a "$tag" -m "Release $tag"; then
|
||||||
|
print_success "Tag '$tag' created successfully!"
|
||||||
|
else
|
||||||
|
print_error "Failed to create tag!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "Pushing tag to origin..."
|
||||||
|
if git push origin "$tag"; then
|
||||||
|
print_success "Tag pushed successfully!"
|
||||||
|
else
|
||||||
|
print_error "Failed to push tag!"
|
||||||
|
print_info "You can manually push with: git push origin $tag"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo
|
||||||
|
print_success "🎉 Release $tag created successfully!"
|
||||||
|
print_info "The GitHub Actions release workflow will now:"
|
||||||
|
echo " • Build packages for Windows, macOS, and Linux"
|
||||||
|
echo " • Extract changelog from docs/C1-changelog.md"
|
||||||
|
echo " • Create GitHub release with all assets"
|
||||||
|
echo " • Include themes, fonts, layouts, and documentation"
|
||||||
|
echo
|
||||||
|
print_info "Check the release progress at:"
|
||||||
|
echo " https://github.com/scawful/yaze/actions"
|
||||||
|
echo
|
||||||
|
print_info "The release will be available at:"
|
||||||
|
echo " https://github.com/scawful/yaze/releases/tag/$tag"
|
||||||
94
scripts/extract_changelog.py
Executable file
94
scripts/extract_changelog.py
Executable file
@@ -0,0 +1,94 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Extract changelog section for a specific version from docs/C1-changelog.md
|
||||||
|
Usage: python3 extract_changelog.py <version>
|
||||||
|
Example: python3 extract_changelog.py 0.3.0
|
||||||
|
"""
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
def extract_version_changelog(version_num, changelog_file):
|
||||||
|
"""Extract changelog section for specific version"""
|
||||||
|
try:
|
||||||
|
with open(changelog_file, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
# Find the section for this version
|
||||||
|
version_pattern = rf"## {re.escape(version_num)}\s*\([^)]+\)"
|
||||||
|
next_version_pattern = r"## \d+\.\d+\.\d+\s*\([^)]+\)"
|
||||||
|
|
||||||
|
# Find start of current version section
|
||||||
|
version_match = re.search(version_pattern, content)
|
||||||
|
if not version_match:
|
||||||
|
return f"Changelog section not found for version {version_num}."
|
||||||
|
|
||||||
|
start_pos = version_match.end()
|
||||||
|
|
||||||
|
# Find start of next version section
|
||||||
|
remaining_content = content[start_pos:]
|
||||||
|
next_match = re.search(next_version_pattern, remaining_content)
|
||||||
|
|
||||||
|
if next_match:
|
||||||
|
end_pos = start_pos + next_match.start()
|
||||||
|
section_content = content[start_pos:end_pos].strip()
|
||||||
|
else:
|
||||||
|
section_content = remaining_content.strip()
|
||||||
|
|
||||||
|
return section_content
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
return f"Error reading changelog: {str(e)}"
|
||||||
|
|
||||||
|
def main():
|
||||||
|
if len(sys.argv) != 2:
|
||||||
|
print("Usage: python3 extract_changelog.py <version>")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
version_num = sys.argv[1]
|
||||||
|
changelog_file = "docs/C1-changelog.md"
|
||||||
|
|
||||||
|
# Check if changelog file exists
|
||||||
|
if not os.path.exists(changelog_file):
|
||||||
|
print(f"Error: Changelog file {changelog_file} not found")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Extract changelog content
|
||||||
|
changelog_content = extract_version_changelog(version_num, changelog_file)
|
||||||
|
|
||||||
|
# Generate full release notes
|
||||||
|
release_notes = f"""# Yaze v{version_num} Release Notes
|
||||||
|
|
||||||
|
{changelog_content}
|
||||||
|
|
||||||
|
## Download Instructions
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
- Download `yaze-windows-x64.zip` for 64-bit Windows
|
||||||
|
- Download `yaze-windows-x86.zip` for 32-bit Windows
|
||||||
|
- Extract and run `yaze.exe`
|
||||||
|
|
||||||
|
### macOS
|
||||||
|
- Download `yaze-macos.dmg`
|
||||||
|
- Mount the DMG and drag Yaze to Applications
|
||||||
|
- You may need to allow the app in System Preferences > Security & Privacy
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
- Download `yaze-linux-x64.tar.gz`
|
||||||
|
- Extract: `tar -xzf yaze-linux-x64.tar.gz`
|
||||||
|
- Run: `./yaze`
|
||||||
|
|
||||||
|
## System Requirements
|
||||||
|
- **Windows**: Windows 10 or later (64-bit recommended)
|
||||||
|
- **macOS**: macOS 10.15 (Catalina) or later
|
||||||
|
- **Linux**: Ubuntu 20.04 or equivalent, with X11 or Wayland
|
||||||
|
|
||||||
|
## Support
|
||||||
|
For issues and questions, please visit our [GitHub Issues](https://github.com/scawful/yaze/issues) page.
|
||||||
|
"""
|
||||||
|
|
||||||
|
print(release_notes)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
328
scripts/generate-vs-projects-simple.py
Normal file
328
scripts/generate-vs-projects-simple.py
Normal file
@@ -0,0 +1,328 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Simple Visual Studio project generator for YAZE
|
||||||
|
This script creates Visual Studio project files without complex CMake dependencies
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def generate_vcxproj():
|
||||||
|
"""Generate the YAZE.vcxproj file with all source files"""
|
||||||
|
|
||||||
|
# Source file lists (from CMake files)
|
||||||
|
app_core_src = [
|
||||||
|
"app/core/controller.cc",
|
||||||
|
"app/emu/emulator.cc",
|
||||||
|
"app/core/project.cc",
|
||||||
|
"app/core/window.cc",
|
||||||
|
"app/core/asar_wrapper.cc",
|
||||||
|
"app/core/platform/font_loader.cc",
|
||||||
|
"app/core/platform/clipboard.cc",
|
||||||
|
"app/core/platform/file_dialog.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_emu_src = [
|
||||||
|
"app/emu/audio/apu.cc",
|
||||||
|
"app/emu/audio/spc700.cc",
|
||||||
|
"app/emu/audio/dsp.cc",
|
||||||
|
"app/emu/audio/internal/addressing.cc",
|
||||||
|
"app/emu/audio/internal/instructions.cc",
|
||||||
|
"app/emu/cpu/internal/addressing.cc",
|
||||||
|
"app/emu/cpu/internal/instructions.cc",
|
||||||
|
"app/emu/cpu/cpu.cc",
|
||||||
|
"app/emu/video/ppu.cc",
|
||||||
|
"app/emu/memory/dma.cc",
|
||||||
|
"app/emu/memory/memory.cc",
|
||||||
|
"app/emu/snes.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_editor_src = [
|
||||||
|
"app/editor/editor_manager.cc",
|
||||||
|
"app/editor/dungeon/dungeon_editor.cc",
|
||||||
|
"app/editor/dungeon/dungeon_room_selector.cc",
|
||||||
|
"app/editor/dungeon/dungeon_canvas_viewer.cc",
|
||||||
|
"app/editor/dungeon/dungeon_object_selector.cc",
|
||||||
|
"app/editor/dungeon/dungeon_toolset.cc",
|
||||||
|
"app/editor/dungeon/dungeon_object_interaction.cc",
|
||||||
|
"app/editor/dungeon/dungeon_renderer.cc",
|
||||||
|
"app/editor/dungeon/dungeon_room_loader.cc",
|
||||||
|
"app/editor/dungeon/dungeon_usage_tracker.cc",
|
||||||
|
"app/editor/overworld/overworld_editor.cc",
|
||||||
|
"app/editor/overworld/overworld_editor_manager.cc",
|
||||||
|
"app/editor/sprite/sprite_editor.cc",
|
||||||
|
"app/editor/music/music_editor.cc",
|
||||||
|
"app/editor/message/message_editor.cc",
|
||||||
|
"app/editor/message/message_data.cc",
|
||||||
|
"app/editor/message/message_preview.cc",
|
||||||
|
"app/editor/code/assembly_editor.cc",
|
||||||
|
"app/editor/graphics/screen_editor.cc",
|
||||||
|
"app/editor/graphics/graphics_editor.cc",
|
||||||
|
"app/editor/graphics/palette_editor.cc",
|
||||||
|
"app/editor/overworld/tile16_editor.cc",
|
||||||
|
"app/editor/overworld/map_properties.cc",
|
||||||
|
"app/editor/graphics/gfx_group_editor.cc",
|
||||||
|
"app/editor/overworld/entity.cc",
|
||||||
|
"app/editor/system/settings_editor.cc",
|
||||||
|
"app/editor/system/command_manager.cc",
|
||||||
|
"app/editor/system/extension_manager.cc",
|
||||||
|
"app/editor/system/shortcut_manager.cc",
|
||||||
|
"app/editor/system/popup_manager.cc",
|
||||||
|
"app/test/test_manager.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_gfx_src = [
|
||||||
|
"app/gfx/arena.cc",
|
||||||
|
"app/gfx/background_buffer.cc",
|
||||||
|
"app/gfx/bitmap.cc",
|
||||||
|
"app/gfx/compression.cc",
|
||||||
|
"app/gfx/scad_format.cc",
|
||||||
|
"app/gfx/snes_palette.cc",
|
||||||
|
"app/gfx/snes_tile.cc",
|
||||||
|
"app/gfx/snes_color.cc",
|
||||||
|
"app/gfx/tilemap.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_zelda3_src = [
|
||||||
|
"app/zelda3/hyrule_magic.cc",
|
||||||
|
"app/zelda3/overworld/overworld_map.cc",
|
||||||
|
"app/zelda3/overworld/overworld.cc",
|
||||||
|
"app/zelda3/screen/inventory.cc",
|
||||||
|
"app/zelda3/screen/title_screen.cc",
|
||||||
|
"app/zelda3/screen/dungeon_map.cc",
|
||||||
|
"app/zelda3/sprite/sprite.cc",
|
||||||
|
"app/zelda3/sprite/sprite_builder.cc",
|
||||||
|
"app/zelda3/music/tracker.cc",
|
||||||
|
"app/zelda3/dungeon/room.cc",
|
||||||
|
"app/zelda3/dungeon/room_object.cc",
|
||||||
|
"app/zelda3/dungeon/object_parser.cc",
|
||||||
|
"app/zelda3/dungeon/object_renderer.cc",
|
||||||
|
"app/zelda3/dungeon/room_layout.cc",
|
||||||
|
"app/zelda3/dungeon/dungeon_editor_system.cc",
|
||||||
|
"app/zelda3/dungeon/dungeon_object_editor.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
gui_src = [
|
||||||
|
"app/gui/modules/asset_browser.cc",
|
||||||
|
"app/gui/modules/text_editor.cc",
|
||||||
|
"app/gui/canvas.cc",
|
||||||
|
"app/gui/canvas_utils.cc",
|
||||||
|
"app/gui/enhanced_palette_editor.cc",
|
||||||
|
"app/gui/input.cc",
|
||||||
|
"app/gui/style.cc",
|
||||||
|
"app/gui/color.cc",
|
||||||
|
"app/gui/zeml.cc",
|
||||||
|
"app/gui/theme_manager.cc",
|
||||||
|
"app/gui/background_renderer.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
util_src = [
|
||||||
|
"util/bps.cc",
|
||||||
|
"util/flag.cc",
|
||||||
|
"util/hex.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Combine all source files
|
||||||
|
all_source_files = (
|
||||||
|
["yaze.cc", "app/main.cc", "app/rom.cc"] +
|
||||||
|
app_core_src + app_emu_src + app_editor_src +
|
||||||
|
app_gfx_src + app_zelda3_src + gui_src + util_src
|
||||||
|
)
|
||||||
|
|
||||||
|
# Header files
|
||||||
|
header_files = [
|
||||||
|
"incl/yaze.h",
|
||||||
|
"incl/zelda.h",
|
||||||
|
"src/yaze_config.h.in"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Generate the .vcxproj file content
|
||||||
|
vcxproj_content = '''<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{B2C3D4E5-F6G7-8901-BCDE-F23456789012}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>YAZE</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>YAZE</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)incl;$(ProjectDir)src\\lib;$(ProjectDir)vcpkg\\installed\\x64-windows\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||||
|
<BigObj>true</BigObj>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(ProjectDir)vcpkg\\installed\\x64-windows\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2.lib;SDL2main.lib;libpng16.lib;zlib.lib;absl_base.lib;absl_strings.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)incl;$(ProjectDir)src\\lib;$(ProjectDir)vcpkg\\installed\\x64-windows\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||||
|
<BigObj>true</BigObj>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalLibraryDirectories>$(ProjectDir)vcpkg\\installed\\x64-windows\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>SDL2.lib;SDL2main.lib;libpng16.lib;zlib.lib;absl_base.lib;absl_strings.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
'''
|
||||||
|
|
||||||
|
for header in header_files:
|
||||||
|
vcxproj_content += f' <ClInclude Include="{header}" />\n'
|
||||||
|
|
||||||
|
vcxproj_content += ''' </ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
'''
|
||||||
|
|
||||||
|
for source in all_source_files:
|
||||||
|
vcxproj_content += f' <ClCompile Include="src\\{source}" />\n'
|
||||||
|
|
||||||
|
vcxproj_content += ''' </ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="CMakeLists.txt" />
|
||||||
|
<None Include="vcpkg.json" />
|
||||||
|
<None Include="README.md" />
|
||||||
|
<None Include="LICENSE" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>'''
|
||||||
|
|
||||||
|
return vcxproj_content
|
||||||
|
|
||||||
|
def generate_solution():
|
||||||
|
"""Generate the YAZE.sln file"""
|
||||||
|
return '''Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YAZE", "YAZE.vcxproj", "{B2C3D4E5-F6G7-8901-BCDE-F23456789012}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.Build.0 = Release|x64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal'''
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to generate Visual Studio project files"""
|
||||||
|
print("Generating simple Visual Studio project files for YAZE...")
|
||||||
|
|
||||||
|
# Get the project root directory
|
||||||
|
script_dir = Path(__file__).parent
|
||||||
|
project_root = script_dir.parent
|
||||||
|
|
||||||
|
# Generate .vcxproj file
|
||||||
|
vcxproj_content = generate_vcxproj()
|
||||||
|
vcxproj_path = project_root / "YAZE.vcxproj"
|
||||||
|
|
||||||
|
with open(vcxproj_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(vcxproj_content)
|
||||||
|
|
||||||
|
print(f"Generated: {vcxproj_path}")
|
||||||
|
|
||||||
|
# Generate .sln file
|
||||||
|
solution_content = generate_solution()
|
||||||
|
solution_path = project_root / "YAZE.sln"
|
||||||
|
|
||||||
|
with open(solution_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(solution_content)
|
||||||
|
|
||||||
|
print(f"Generated: {solution_path}")
|
||||||
|
|
||||||
|
print("Visual Studio project files generated successfully!")
|
||||||
|
print("")
|
||||||
|
print("IMPORTANT: Before building in Visual Studio:")
|
||||||
|
print("1. Make sure vcpkg is set up: .\\scripts\\setup-vcpkg-windows.ps1")
|
||||||
|
print("2. Install dependencies: .\\vcpkg\\vcpkg.exe install --triplet x64-windows")
|
||||||
|
print("3. Open YAZE.sln in Visual Studio 2022")
|
||||||
|
print("4. Build the solution (Ctrl+Shift+B)")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
200
scripts/generate-vs-projects.bat
Normal file
200
scripts/generate-vs-projects.bat
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
@echo off
|
||||||
|
REM Configure Visual Studio project files for YAZE
|
||||||
|
REM This script configures CMake build system to work with existing Visual Studio project files
|
||||||
|
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
REM Default values
|
||||||
|
set CONFIGURATION=Debug
|
||||||
|
set ARCHITECTURE=x64
|
||||||
|
set CLEAN=false
|
||||||
|
|
||||||
|
REM Parse command line arguments
|
||||||
|
:parse_args
|
||||||
|
if "%~1"=="" goto :args_done
|
||||||
|
if "%~1"=="--clean" set CLEAN=true
|
||||||
|
if "%~1"=="--release" set CONFIGURATION=Release
|
||||||
|
if "%~1"=="--x86" set ARCHITECTURE=Win32
|
||||||
|
if "%~1"=="--x64" set ARCHITECTURE=x64
|
||||||
|
if "%~1"=="--arm64" set ARCHITECTURE=ARM64
|
||||||
|
shift
|
||||||
|
goto :parse_args
|
||||||
|
|
||||||
|
:args_done
|
||||||
|
|
||||||
|
REM Validate architecture
|
||||||
|
if not "%ARCHITECTURE%"=="x64" if not "%ARCHITECTURE%"=="Win32" if not "%ARCHITECTURE%"=="ARM64" (
|
||||||
|
echo Invalid architecture: %ARCHITECTURE%
|
||||||
|
echo Valid architectures: x64, Win32, ARM64
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo Generating Visual Studio project files for YAZE...
|
||||||
|
|
||||||
|
REM Check if we're on Windows
|
||||||
|
if not "%OS%"=="Windows_NT" (
|
||||||
|
echo This script is designed for Windows. Use CMake presets on other platforms.
|
||||||
|
echo Available presets:
|
||||||
|
echo - windows-debug
|
||||||
|
echo - windows-release
|
||||||
|
echo - windows-dev
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if CMake is available
|
||||||
|
where cmake >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
REM Try common CMake installation paths
|
||||||
|
if exist "C:\Program Files\CMake\bin\cmake.exe" (
|
||||||
|
echo Found CMake at: C:\Program Files\CMake\bin\cmake.exe
|
||||||
|
set "PATH=%PATH%;C:\Program Files\CMake\bin"
|
||||||
|
goto :cmake_found
|
||||||
|
)
|
||||||
|
if exist "C:\Program Files (x86)\CMake\bin\cmake.exe" (
|
||||||
|
echo Found CMake at: C:\Program Files (x86)\CMake\bin\cmake.exe
|
||||||
|
set "PATH=%PATH%;C:\Program Files (x86)\CMake\bin"
|
||||||
|
goto :cmake_found
|
||||||
|
)
|
||||||
|
if exist "C:\cmake\bin\cmake.exe" (
|
||||||
|
echo Found CMake at: C:\cmake\bin\cmake.exe
|
||||||
|
set "PATH=%PATH%;C:\cmake\bin"
|
||||||
|
goto :cmake_found
|
||||||
|
)
|
||||||
|
|
||||||
|
REM If we get here, CMake is not found
|
||||||
|
echo CMake not found in PATH. Attempting to install...
|
||||||
|
|
||||||
|
REM Try to install CMake via Chocolatey
|
||||||
|
where choco >nul 2>&1
|
||||||
|
if not errorlevel 1 (
|
||||||
|
echo Installing CMake via Chocolatey...
|
||||||
|
choco install -y cmake
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo Failed to install CMake via Chocolatey
|
||||||
|
) else (
|
||||||
|
echo CMake installed successfully
|
||||||
|
REM Refresh PATH
|
||||||
|
call refreshenv
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo Chocolatey not found. Please install CMake manually:
|
||||||
|
echo 1. Download from: https://cmake.org/download/
|
||||||
|
echo 2. Or install Chocolatey first: https://chocolatey.org/install
|
||||||
|
echo 3. Then run: choco install cmake
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check again after installation
|
||||||
|
where cmake >nul 2>&1
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo CMake still not found after installation. Please restart your terminal or add CMake to PATH manually.
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
:cmake_found
|
||||||
|
echo CMake found and ready to use
|
||||||
|
|
||||||
|
REM Set up paths
|
||||||
|
set SOURCE_DIR=%~dp0..
|
||||||
|
set BUILD_DIR=%SOURCE_DIR%\build-vs
|
||||||
|
|
||||||
|
echo Source directory: %SOURCE_DIR%
|
||||||
|
echo Build directory: %BUILD_DIR%
|
||||||
|
|
||||||
|
REM Clean build directory if requested
|
||||||
|
if "%CLEAN%"=="true" (
|
||||||
|
if exist "%BUILD_DIR%" (
|
||||||
|
echo Cleaning build directory...
|
||||||
|
rmdir /s /q "%BUILD_DIR%"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Create build directory
|
||||||
|
if not exist "%BUILD_DIR%" mkdir "%BUILD_DIR%"
|
||||||
|
|
||||||
|
REM Check if vcpkg is available
|
||||||
|
set VCPKG_PATH=%SOURCE_DIR%\vcpkg\scripts\buildsystems\vcpkg.cmake
|
||||||
|
if exist "%VCPKG_PATH%" (
|
||||||
|
echo Using vcpkg toolchain: %VCPKG_PATH%
|
||||||
|
set USE_VCPKG=true
|
||||||
|
) else (
|
||||||
|
echo vcpkg not found, using system libraries
|
||||||
|
set USE_VCPKG=false
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Build CMake command
|
||||||
|
set CMAKE_ARGS=-B "%BUILD_DIR%" -G "Visual Studio 17 2022" -A %ARCHITECTURE% -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DCMAKE_POLICY_VERSION_MINIMUM=3.5 -DCMAKE_POLICY_VERSION_MAXIMUM=3.28 -DCMAKE_WARN_DEPRECATED=OFF -DABSL_PROPAGATE_CXX_STD=ON -DTHREADS_PREFER_PTHREAD_FLAG=OFF -DYAZE_BUILD_TESTS=ON -DYAZE_BUILD_APP=ON -DYAZE_BUILD_LIB=ON -DYAZE_BUILD_EMU=ON -DYAZE_BUILD_Z3ED=ON -DYAZE_ENABLE_ROM_TESTS=OFF -DYAZE_ENABLE_EXPERIMENTAL_TESTS=ON -DYAZE_ENABLE_UI_TESTS=ON -DYAZE_INSTALL_LIB=OFF
|
||||||
|
|
||||||
|
if "%USE_VCPKG%"=="true" (
|
||||||
|
set CMAKE_ARGS=%CMAKE_ARGS% -DCMAKE_TOOLCHAIN_FILE="%VCPKG_PATH%" -DVCPKG_TARGET_TRIPLET=%ARCHITECTURE%-windows -DVCPKG_MANIFEST_MODE=ON
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Run CMake configuration
|
||||||
|
echo Configuring CMake...
|
||||||
|
echo Command: cmake %CMAKE_ARGS% "%SOURCE_DIR%"
|
||||||
|
|
||||||
|
cmake %CMAKE_ARGS% "%SOURCE_DIR%"
|
||||||
|
|
||||||
|
if errorlevel 1 (
|
||||||
|
echo CMake configuration failed!
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Check if the existing solution file is present and valid
|
||||||
|
set EXISTING_SOLUTION_FILE=%SOURCE_DIR%\YAZE.sln
|
||||||
|
if exist "%EXISTING_SOLUTION_FILE%" (
|
||||||
|
echo ✅ Using existing Visual Studio solution: %EXISTING_SOLUTION_FILE%
|
||||||
|
|
||||||
|
REM Verify the solution file references the project file
|
||||||
|
findstr /C:"YAZE.vcxproj" "%EXISTING_SOLUTION_FILE%" >nul
|
||||||
|
if not errorlevel 1 (
|
||||||
|
echo ✅ Solution file references YAZE.vcxproj correctly
|
||||||
|
|
||||||
|
REM Check if project configurations are set up
|
||||||
|
findstr /C:"ProjectConfigurationPlatforms" "%EXISTING_SOLUTION_FILE%" >nul
|
||||||
|
if not errorlevel 1 (
|
||||||
|
echo ✅ Project configurations are properly set up
|
||||||
|
) else (
|
||||||
|
echo ⚠️ Warning: Project configurations may not be set up
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo ❌ Solution file does not reference YAZE.vcxproj
|
||||||
|
echo Please ensure the solution file includes the YAZE project
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Try to open solution in Visual Studio
|
||||||
|
where devenv >nul 2>&1
|
||||||
|
if not errorlevel 1 (
|
||||||
|
echo Opening solution in Visual Studio...
|
||||||
|
start "" devenv "%EXISTING_SOLUTION_FILE%"
|
||||||
|
) else (
|
||||||
|
echo Visual Studio solution ready: %EXISTING_SOLUTION_FILE%
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
echo ❌ Existing solution file not found: %EXISTING_SOLUTION_FILE%
|
||||||
|
echo Please ensure YAZE.sln exists in the project root
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo 🎉 Visual Studio project configuration complete!
|
||||||
|
echo.
|
||||||
|
echo Next steps:
|
||||||
|
echo 1. Open YAZE.sln in Visual Studio
|
||||||
|
echo 2. Select configuration: %CONFIGURATION%
|
||||||
|
echo 3. Select platform: %ARCHITECTURE%
|
||||||
|
echo 4. Build the solution (Ctrl+Shift+B)
|
||||||
|
echo.
|
||||||
|
echo Available configurations:
|
||||||
|
echo - Debug (with debugging symbols)
|
||||||
|
echo - Release (optimized)
|
||||||
|
echo - RelWithDebInfo (optimized with debug info)
|
||||||
|
echo - MinSizeRel (minimum size)
|
||||||
|
echo.
|
||||||
|
echo Available architectures:
|
||||||
|
echo - x64 (64-bit Intel/AMD)
|
||||||
|
echo - x86 (32-bit Intel/AMD)
|
||||||
|
echo - ARM64 (64-bit ARM)
|
||||||
|
|
||||||
|
pause
|
||||||
251
scripts/generate-vs-projects.ps1
Normal file
251
scripts/generate-vs-projects.ps1
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
# Configure Visual Studio project files for YAZE
|
||||||
|
# This script configures CMake build system to work with existing Visual Studio project files
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$Configuration = "Debug",
|
||||||
|
[string]$Architecture = "x64",
|
||||||
|
[switch]$Clean = $false,
|
||||||
|
[switch]$UseVcpkg = $false,
|
||||||
|
[switch]$Help = $false
|
||||||
|
)
|
||||||
|
|
||||||
|
# Show help if requested
|
||||||
|
if ($Help) {
|
||||||
|
Write-Host "Usage: .\generate-vs-projects.ps1 [options]"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Options:"
|
||||||
|
Write-Host " -Configuration <config> Build configuration (Debug, Release, RelWithDebInfo, MinSizeRel)"
|
||||||
|
Write-Host " -Architecture <arch> Target architecture (x64, x86, ARM64)"
|
||||||
|
Write-Host " -Clean Clean build directory before configuring"
|
||||||
|
Write-Host " -UseVcpkg Use vcpkg for dependency management"
|
||||||
|
Write-Host " -Help Show this help message"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Examples:"
|
||||||
|
Write-Host " .\generate-vs-projects.ps1 # Default: Debug x64"
|
||||||
|
Write-Host " .\generate-vs-projects.ps1 -Configuration Release -Architecture x86"
|
||||||
|
Write-Host " .\generate-vs-projects.ps1 -Clean -UseVcpkg"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Note: This script configures CMake to work with existing YAZE.sln and YAZE.vcxproj files"
|
||||||
|
exit 0
|
||||||
|
}
|
||||||
|
|
||||||
|
# Validate architecture parameter
|
||||||
|
$ValidArchitectures = @("x64", "x86", "ARM64")
|
||||||
|
if ($Architecture -notin $ValidArchitectures) {
|
||||||
|
Write-Host "Invalid architecture: $Architecture" -ForegroundColor Red
|
||||||
|
Write-Host "Valid architectures: $($ValidArchitectures -join ', ')" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Generating Visual Studio project files for YAZE..." -ForegroundColor Green
|
||||||
|
|
||||||
|
# Check if we're on Windows
|
||||||
|
if ($env:OS -ne "Windows_NT") {
|
||||||
|
Write-Host "This script is designed for Windows. Use CMake presets on other platforms." -ForegroundColor Yellow
|
||||||
|
Write-Host "Available presets:" -ForegroundColor Cyan
|
||||||
|
Write-Host " - windows-debug" -ForegroundColor Gray
|
||||||
|
Write-Host " - windows-release" -ForegroundColor Gray
|
||||||
|
Write-Host " - windows-dev" -ForegroundColor Gray
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if CMake is available
|
||||||
|
$cmakePath = Get-Command cmake -ErrorAction SilentlyContinue
|
||||||
|
if (-not $cmakePath) {
|
||||||
|
# Try common CMake installation paths
|
||||||
|
$commonPaths = @(
|
||||||
|
"C:\Program Files\CMake\bin\cmake.exe",
|
||||||
|
"C:\Program Files (x86)\CMake\bin\cmake.exe",
|
||||||
|
"C:\cmake\bin\cmake.exe"
|
||||||
|
)
|
||||||
|
|
||||||
|
foreach ($path in $commonPaths) {
|
||||||
|
if (Test-Path $path) {
|
||||||
|
Write-Host "Found CMake at: $path" -ForegroundColor Green
|
||||||
|
$env:Path += ";$(Split-Path $path)"
|
||||||
|
$cmakePath = Get-Command cmake -ErrorAction SilentlyContinue
|
||||||
|
if ($cmakePath) {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not $cmakePath) {
|
||||||
|
Write-Host "CMake not found in PATH. Attempting to install..." -ForegroundColor Yellow
|
||||||
|
|
||||||
|
# Try to install CMake via Chocolatey
|
||||||
|
if (Get-Command choco -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Host "Installing CMake via Chocolatey..." -ForegroundColor Yellow
|
||||||
|
choco install -y cmake
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Host "CMake installed successfully" -ForegroundColor Green
|
||||||
|
# Refresh PATH
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
|
} else {
|
||||||
|
Write-Host "Failed to install CMake via Chocolatey" -ForegroundColor Red
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "Chocolatey not found. Please install CMake manually:" -ForegroundColor Red
|
||||||
|
Write-Host "1. Download from: https://cmake.org/download/" -ForegroundColor Yellow
|
||||||
|
Write-Host "2. Or install Chocolatey first: https://chocolatey.org/install" -ForegroundColor Yellow
|
||||||
|
Write-Host "3. Then run: choco install cmake" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check again after installation
|
||||||
|
$cmakePath = Get-Command cmake -ErrorAction SilentlyContinue
|
||||||
|
if (-not $cmakePath) {
|
||||||
|
Write-Host "CMake still not found after installation. Please restart your terminal or add CMake to PATH manually." -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "CMake found: $($cmakePath.Source)" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Check if Visual Studio is available
|
||||||
|
$vsWhere = Get-Command "C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe" -ErrorAction SilentlyContinue
|
||||||
|
if (-not $vsWhere) {
|
||||||
|
$vsWhere = Get-Command vswhere -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($vsWhere) {
|
||||||
|
$vsInstallPath = & $vsWhere.Source -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||||
|
if ($vsInstallPath) {
|
||||||
|
Write-Host "Visual Studio found at: $vsInstallPath" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "Visual Studio 2022 not found. Please install Visual Studio 2022 with C++ workload." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "vswhere not found. Assuming Visual Studio is available." -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
# Set up paths
|
||||||
|
$SourceDir = Split-Path -Parent $PSScriptRoot
|
||||||
|
$BuildDir = Join-Path $SourceDir "build-vs"
|
||||||
|
|
||||||
|
Write-Host "Source directory: $SourceDir" -ForegroundColor Cyan
|
||||||
|
Write-Host "Build directory: $BuildDir" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Clean build directory if requested
|
||||||
|
if ($Clean -and (Test-Path $BuildDir)) {
|
||||||
|
Write-Host "Cleaning build directory..." -ForegroundColor Yellow
|
||||||
|
Remove-Item -Recurse -Force $BuildDir
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create build directory
|
||||||
|
if (-not (Test-Path $BuildDir)) {
|
||||||
|
New-Item -ItemType Directory -Path $BuildDir | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if vcpkg is available
|
||||||
|
$VcpkgPath = Join-Path $SourceDir "vcpkg\scripts\buildsystems\vcpkg.cmake"
|
||||||
|
$UseVcpkg = Test-Path $VcpkgPath
|
||||||
|
|
||||||
|
if ($UseVcpkg) {
|
||||||
|
Write-Host "Using vcpkg toolchain: $VcpkgPath" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "vcpkg not found, using system libraries" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
# Determine generator and architecture
|
||||||
|
$Generator = "Visual Studio 17 2022"
|
||||||
|
$ArchFlag = if ($Architecture -eq "x64") { "-A x64" } else { "-A Win32" }
|
||||||
|
|
||||||
|
# Build CMake command
|
||||||
|
$CmakeArgs = @(
|
||||||
|
"-B", $BuildDir,
|
||||||
|
"-G", "`"$Generator`"",
|
||||||
|
$ArchFlag,
|
||||||
|
"-DCMAKE_BUILD_TYPE=$Configuration",
|
||||||
|
"-DCMAKE_POLICY_VERSION_MINIMUM=3.5",
|
||||||
|
"-DCMAKE_POLICY_VERSION_MAXIMUM=3.28",
|
||||||
|
"-DCMAKE_WARN_DEPRECATED=OFF",
|
||||||
|
"-DABSL_PROPAGATE_CXX_STD=ON",
|
||||||
|
"-DTHREADS_PREFER_PTHREAD_FLAG=OFF",
|
||||||
|
"-DYAZE_BUILD_TESTS=ON",
|
||||||
|
"-DYAZE_BUILD_APP=ON",
|
||||||
|
"-DYAZE_BUILD_LIB=ON",
|
||||||
|
"-DYAZE_BUILD_EMU=ON",
|
||||||
|
"-DYAZE_BUILD_Z3ED=ON",
|
||||||
|
"-DYAZE_ENABLE_ROM_TESTS=OFF",
|
||||||
|
"-DYAZE_ENABLE_EXPERIMENTAL_TESTS=ON",
|
||||||
|
"-DYAZE_ENABLE_UI_TESTS=ON",
|
||||||
|
"-DYAZE_INSTALL_LIB=OFF"
|
||||||
|
)
|
||||||
|
|
||||||
|
if ($UseVcpkg) {
|
||||||
|
$CmakeArgs += @(
|
||||||
|
"-DCMAKE_TOOLCHAIN_FILE=`"$VcpkgPath`"",
|
||||||
|
"-DVCPKG_TARGET_TRIPLET=$Architecture-windows",
|
||||||
|
"-DVCPKG_MANIFEST_MODE=ON"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure CMake to generate build files (but don't overwrite existing project files)
|
||||||
|
Write-Host "Configuring CMake for build system..." -ForegroundColor Yellow
|
||||||
|
Write-Host "Command: cmake $($CmakeArgs -join ' ')" -ForegroundColor Gray
|
||||||
|
|
||||||
|
& cmake @CmakeArgs $SourceDir
|
||||||
|
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Write-Host "CMake configuration failed!" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if the existing solution file is present and valid
|
||||||
|
$ExistingSolutionFile = Join-Path $SourceDir "YAZE.sln"
|
||||||
|
if (Test-Path $ExistingSolutionFile) {
|
||||||
|
Write-Host "✅ Using existing Visual Studio solution: $ExistingSolutionFile" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Verify the solution file is properly structured
|
||||||
|
$SolutionContent = Get-Content $ExistingSolutionFile -Raw
|
||||||
|
if ($SolutionContent -match "YAZE\.vcxproj") {
|
||||||
|
Write-Host "✅ Solution file references YAZE.vcxproj correctly" -ForegroundColor Green
|
||||||
|
|
||||||
|
# Check if project configurations are set up
|
||||||
|
if ($SolutionContent -match "ProjectConfigurationPlatforms") {
|
||||||
|
Write-Host "✅ Project configurations are properly set up" -ForegroundColor Green
|
||||||
|
} else {
|
||||||
|
Write-Host "⚠️ Warning: Project configurations may not be set up" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "❌ Solution file does not reference YAZE.vcxproj" -ForegroundColor Red
|
||||||
|
Write-Host "Please ensure the solution file includes the YAZE project" -ForegroundColor Yellow
|
||||||
|
}
|
||||||
|
|
||||||
|
# Open solution in Visual Studio if available
|
||||||
|
if (Get-Command "devenv" -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Host "Opening solution in Visual Studio..." -ForegroundColor Yellow
|
||||||
|
& devenv $ExistingSolutionFile
|
||||||
|
} elseif (Get-Command "code" -ErrorAction SilentlyContinue) {
|
||||||
|
Write-Host "Opening solution in VS Code..." -ForegroundColor Yellow
|
||||||
|
& code $ExistingSolutionFile
|
||||||
|
} else {
|
||||||
|
Write-Host "Visual Studio solution ready: $ExistingSolutionFile" -ForegroundColor Cyan
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Host "❌ Existing solution file not found: $ExistingSolutionFile" -ForegroundColor Red
|
||||||
|
Write-Host "Please ensure YAZE.sln exists in the project root" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "🎉 Visual Studio project configuration complete!" -ForegroundColor Green
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Next steps:" -ForegroundColor Cyan
|
||||||
|
Write-Host "1. Open YAZE.sln in Visual Studio" -ForegroundColor White
|
||||||
|
Write-Host "2. Select configuration: $Configuration" -ForegroundColor White
|
||||||
|
Write-Host "3. Select platform: $Architecture" -ForegroundColor White
|
||||||
|
Write-Host "4. Build the solution (Ctrl+Shift+B)" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Available configurations:" -ForegroundColor Cyan
|
||||||
|
Write-Host " - Debug (with debugging symbols)" -ForegroundColor Gray
|
||||||
|
Write-Host " - Release (optimized)" -ForegroundColor Gray
|
||||||
|
Write-Host " - RelWithDebInfo (optimized with debug info)" -ForegroundColor Gray
|
||||||
|
Write-Host " - MinSizeRel (minimum size)" -ForegroundColor Gray
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Available architectures:" -ForegroundColor Cyan
|
||||||
|
Write-Host " - x64 (64-bit Intel/AMD)" -ForegroundColor Gray
|
||||||
|
Write-Host " - x86 (32-bit Intel/AMD)" -ForegroundColor Gray
|
||||||
|
Write-Host " - ARM64 (64-bit ARM)" -ForegroundColor Gray
|
||||||
543
scripts/generate-vs-projects.py
Normal file
543
scripts/generate-vs-projects.py
Normal file
@@ -0,0 +1,543 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Python script to generate proper Visual Studio project files for YAZE
|
||||||
|
This script creates a comprehensive .vcxproj file with all necessary source files
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def generate_vcxproj():
|
||||||
|
"""Generate the YAZE.vcxproj file with all source files"""
|
||||||
|
|
||||||
|
# Source file lists (from CMake files)
|
||||||
|
app_core_src = [
|
||||||
|
"app/core/controller.cc",
|
||||||
|
"app/emu/emulator.cc",
|
||||||
|
"app/core/project.cc",
|
||||||
|
"app/core/window.cc",
|
||||||
|
"app/core/asar_wrapper.cc",
|
||||||
|
"app/core/platform/font_loader.cc",
|
||||||
|
"app/core/platform/clipboard.cc",
|
||||||
|
"app/core/platform/file_dialog.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_emu_src = [
|
||||||
|
"app/emu/audio/apu.cc",
|
||||||
|
"app/emu/audio/spc700.cc",
|
||||||
|
"app/emu/audio/dsp.cc",
|
||||||
|
"app/emu/audio/internal/addressing.cc",
|
||||||
|
"app/emu/audio/internal/instructions.cc",
|
||||||
|
"app/emu/cpu/internal/addressing.cc",
|
||||||
|
"app/emu/cpu/internal/instructions.cc",
|
||||||
|
"app/emu/cpu/cpu.cc",
|
||||||
|
"app/emu/video/ppu.cc",
|
||||||
|
"app/emu/memory/dma.cc",
|
||||||
|
"app/emu/memory/memory.cc",
|
||||||
|
"app/emu/snes.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_editor_src = [
|
||||||
|
"app/editor/editor_manager.cc",
|
||||||
|
"app/editor/dungeon/dungeon_editor.cc",
|
||||||
|
"app/editor/dungeon/dungeon_room_selector.cc",
|
||||||
|
"app/editor/dungeon/dungeon_canvas_viewer.cc",
|
||||||
|
"app/editor/dungeon/dungeon_object_selector.cc",
|
||||||
|
"app/editor/dungeon/dungeon_toolset.cc",
|
||||||
|
"app/editor/dungeon/dungeon_object_interaction.cc",
|
||||||
|
"app/editor/dungeon/dungeon_renderer.cc",
|
||||||
|
"app/editor/dungeon/dungeon_room_loader.cc",
|
||||||
|
"app/editor/dungeon/dungeon_usage_tracker.cc",
|
||||||
|
"app/editor/overworld/overworld_editor.cc",
|
||||||
|
"app/editor/overworld/overworld_editor_manager.cc",
|
||||||
|
"app/editor/sprite/sprite_editor.cc",
|
||||||
|
"app/editor/music/music_editor.cc",
|
||||||
|
"app/editor/message/message_editor.cc",
|
||||||
|
"app/editor/message/message_data.cc",
|
||||||
|
"app/editor/message/message_preview.cc",
|
||||||
|
"app/editor/code/assembly_editor.cc",
|
||||||
|
"app/editor/graphics/screen_editor.cc",
|
||||||
|
"app/editor/graphics/graphics_editor.cc",
|
||||||
|
"app/editor/graphics/palette_editor.cc",
|
||||||
|
"app/editor/overworld/tile16_editor.cc",
|
||||||
|
"app/editor/overworld/map_properties.cc",
|
||||||
|
"app/editor/graphics/gfx_group_editor.cc",
|
||||||
|
"app/editor/overworld/entity.cc",
|
||||||
|
"app/editor/system/settings_editor.cc",
|
||||||
|
"app/editor/system/command_manager.cc",
|
||||||
|
"app/editor/system/extension_manager.cc",
|
||||||
|
"app/editor/system/shortcut_manager.cc",
|
||||||
|
"app/editor/system/popup_manager.cc",
|
||||||
|
"app/test/test_manager.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_gfx_src = [
|
||||||
|
"app/gfx/arena.cc",
|
||||||
|
"app/gfx/background_buffer.cc",
|
||||||
|
"app/gfx/bitmap.cc",
|
||||||
|
"app/gfx/compression.cc",
|
||||||
|
"app/gfx/scad_format.cc",
|
||||||
|
"app/gfx/snes_palette.cc",
|
||||||
|
"app/gfx/snes_tile.cc",
|
||||||
|
"app/gfx/snes_color.cc",
|
||||||
|
"app/gfx/tilemap.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
app_zelda3_src = [
|
||||||
|
"app/zelda3/hyrule_magic.cc",
|
||||||
|
"app/zelda3/overworld/overworld_map.cc",
|
||||||
|
"app/zelda3/overworld/overworld.cc",
|
||||||
|
"app/zelda3/screen/inventory.cc",
|
||||||
|
"app/zelda3/screen/title_screen.cc",
|
||||||
|
"app/zelda3/screen/dungeon_map.cc",
|
||||||
|
"app/zelda3/sprite/sprite.cc",
|
||||||
|
"app/zelda3/sprite/sprite_builder.cc",
|
||||||
|
"app/zelda3/music/tracker.cc",
|
||||||
|
"app/zelda3/dungeon/room.cc",
|
||||||
|
"app/zelda3/dungeon/room_object.cc",
|
||||||
|
"app/zelda3/dungeon/object_parser.cc",
|
||||||
|
"app/zelda3/dungeon/object_renderer.cc",
|
||||||
|
"app/zelda3/dungeon/room_layout.cc",
|
||||||
|
"app/zelda3/dungeon/dungeon_editor_system.cc",
|
||||||
|
"app/zelda3/dungeon/dungeon_object_editor.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
gui_src = [
|
||||||
|
"app/gui/modules/asset_browser.cc",
|
||||||
|
"app/gui/modules/text_editor.cc",
|
||||||
|
"app/gui/canvas.cc",
|
||||||
|
"app/gui/canvas_utils.cc",
|
||||||
|
"app/gui/enhanced_palette_editor.cc",
|
||||||
|
"app/gui/input.cc",
|
||||||
|
"app/gui/style.cc",
|
||||||
|
"app/gui/color.cc",
|
||||||
|
"app/gui/zeml.cc",
|
||||||
|
"app/gui/theme_manager.cc",
|
||||||
|
"app/gui/background_renderer.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
util_src = [
|
||||||
|
"util/bps.cc",
|
||||||
|
"util/flag.cc",
|
||||||
|
"util/hex.cc"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Combine all source files
|
||||||
|
all_source_files = (
|
||||||
|
["yaze.cc", "app/main.cc", "app/rom.cc"] +
|
||||||
|
app_core_src + app_emu_src + app_editor_src +
|
||||||
|
app_gfx_src + app_zelda3_src + gui_src + util_src
|
||||||
|
)
|
||||||
|
|
||||||
|
# Header files
|
||||||
|
header_files = [
|
||||||
|
"incl/yaze.h",
|
||||||
|
"incl/zelda.h",
|
||||||
|
"src/yaze_config.h.in"
|
||||||
|
]
|
||||||
|
|
||||||
|
# Generate the .vcxproj file content
|
||||||
|
vcxproj_content = '''<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="17.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x86">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x86</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x86">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x86</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="RelWithDebInfo|x64">
|
||||||
|
<Configuration>RelWithDebInfo</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="RelWithDebInfo|x86">
|
||||||
|
<Configuration>RelWithDebInfo</Configuration>
|
||||||
|
<Platform>x86</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="RelWithDebInfo|ARM64">
|
||||||
|
<Configuration>RelWithDebInfo</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MinSizeRel|x64">
|
||||||
|
<Configuration>MinSizeRel</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MinSizeRel|x86">
|
||||||
|
<Configuration>MinSizeRel</Configuration>
|
||||||
|
<Platform>x86</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="MinSizeRel|ARM64">
|
||||||
|
<Configuration>MinSizeRel</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>17.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{B2C3D4E5-F6G7-8901-BCDE-F23456789012}</ProjectGuid>
|
||||||
|
<Keyword>Win32Proj</Keyword>
|
||||||
|
<RootNamespace>YAZE</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>YAZE</ProjectName>
|
||||||
|
<VcpkgEnabled>true</VcpkgEnabled>
|
||||||
|
<VcpkgManifestInstall>true</VcpkgManifestInstall>
|
||||||
|
<VcpkgTriplet Condition="'$(Platform)'=='Win32'">x86-windows</VcpkgTriplet>
|
||||||
|
<VcpkgTriplet Condition="'$(Platform)'=='x64'">x64-windows</VcpkgTriplet>
|
||||||
|
<VcpkgTriplet Condition="'$(Platform)'=='ARM64'">arm64-windows</VcpkgTriplet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
<CharacterSet>Unicode</CharacterSet>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'">
|
||||||
|
<Import Project="$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<LinkIncremental>true</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|x86'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|x86'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|ARM64'">
|
||||||
|
<LinkIncremental>false</LinkIncremental>
|
||||||
|
<OutDir>$(SolutionDir)build\\bin\\$(Configuration)\\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)build\\obj\\$(Configuration)\\</IntDir>
|
||||||
|
</PropertyGroup>'''
|
||||||
|
|
||||||
|
# Add compiler and linker settings for all configurations
|
||||||
|
configurations = ["Debug", "Release", "RelWithDebInfo", "MinSizeRel"]
|
||||||
|
platforms = ["x64", "x86", "ARM64"]
|
||||||
|
|
||||||
|
for config in configurations:
|
||||||
|
for platform in platforms:
|
||||||
|
is_debug = (config == "Debug")
|
||||||
|
debug_flags = "_DEBUG;_CONSOLE;%(PreprocessorDefinitions)" if is_debug else "NDEBUG;_CONSOLE;%(PreprocessorDefinitions)"
|
||||||
|
link_incremental = "true" if is_debug else "false"
|
||||||
|
generate_debug_info = "false" if config == "MinSizeRel" else "true"
|
||||||
|
|
||||||
|
vcxproj_content += f'''
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='{config}|{platform}'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<PreprocessorDefinitions>{debug_flags}</PreprocessorDefinitions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)src;$(ProjectDir)incl;$(ProjectDir)src\\lib;$(ProjectDir)src\\lib\\asar\\src;$(ProjectDir)src\\lib\\asar\\src\\asar;$(ProjectDir)src\\lib\\asar\\src\\asar-dll-bindings\\c;$(ProjectDir)src\\lib\\imgui;$(ProjectDir)src\\lib\\imgui_test_engine;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp23</LanguageStandard>
|
||||||
|
<BigObj>true</BigObj>
|
||||||
|
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||||
|
<RuntimeLibrary>MultiThreaded{"Debug" if is_debug else ""}DLL</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<GenerateDebugInformation>{generate_debug_info}</GenerateDebugInformation>
|
||||||
|
<EnableCOMDATFolding>{"false" if is_debug else "true"}</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>{"false" if is_debug else "true"}</OptimizeReferences>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>'''
|
||||||
|
|
||||||
|
# Add source files
|
||||||
|
vcxproj_content += '''
|
||||||
|
<ItemGroup>
|
||||||
|
'''
|
||||||
|
for header in header_files:
|
||||||
|
vcxproj_content += f' <ClInclude Include="{header}" />\n'
|
||||||
|
|
||||||
|
vcxproj_content += ''' </ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
'''
|
||||||
|
for source in all_source_files:
|
||||||
|
vcxproj_content += f' <ClCompile Include="src\\{source}" />\n'
|
||||||
|
|
||||||
|
vcxproj_content += ''' </ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="CMakeLists.txt" />
|
||||||
|
<None Include="CMakePresets.json" />
|
||||||
|
<None Include="vcpkg.json" />
|
||||||
|
<None Include="README.md" />
|
||||||
|
<None Include="LICENSE" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>'''
|
||||||
|
|
||||||
|
return vcxproj_content
|
||||||
|
|
||||||
|
def generate_solution():
|
||||||
|
"""Generate the YAZE.sln file"""
|
||||||
|
return '''Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "YAZE", "YAZE.vcxproj", "{B2C3D4E5-F6G7-8901-BCDE-F23456789012}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|x64 = Debug|x64
|
||||||
|
Debug|x86 = Debug|x86
|
||||||
|
Debug|ARM64 = Debug|ARM64
|
||||||
|
Release|x64 = Release|x64
|
||||||
|
Release|x86 = Release|x86
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
|
RelWithDebInfo|x64 = RelWithDebInfo|x64
|
||||||
|
RelWithDebInfo|x86 = RelWithDebInfo|x86
|
||||||
|
RelWithDebInfo|ARM64 = RelWithDebInfo|ARM64
|
||||||
|
MinSizeRel|x64 = MinSizeRel|x64
|
||||||
|
MinSizeRel|x86 = MinSizeRel|x86
|
||||||
|
MinSizeRel|ARM64 = MinSizeRel|ARM64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|x86.Build.0 = Debug|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x64.Build.0 = Release|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|x86.Build.0 = Release|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x64.ActiveCfg = RelWithDebInfo|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x64.Build.0 = RelWithDebInfo|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x86.ActiveCfg = RelWithDebInfo|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|x86.Build.0 = RelWithDebInfo|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|ARM64.ActiveCfg = RelWithDebInfo|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.RelWithDebInfo|ARM64.Build.0 = RelWithDebInfo|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x64.ActiveCfg = MinSizeRel|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x64.Build.0 = MinSizeRel|x64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x86.ActiveCfg = MinSizeRel|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|x86.Build.0 = MinSizeRel|x86
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|ARM64.ActiveCfg = MinSizeRel|ARM64
|
||||||
|
{B2C3D4E5-F6G7-8901-BCDE-F23456789012}.MinSizeRel|ARM64.Build.0 = MinSizeRel|ARM64
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {A1B2C3D4-E5F6-7890-ABCD-EF1234567890}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal'''
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Main function to generate Visual Studio project files"""
|
||||||
|
print("Generating Visual Studio project files for YAZE...")
|
||||||
|
|
||||||
|
# Get the project root directory
|
||||||
|
script_dir = Path(__file__).parent
|
||||||
|
project_root = script_dir.parent
|
||||||
|
|
||||||
|
# Generate .vcxproj file
|
||||||
|
vcxproj_content = generate_vcxproj()
|
||||||
|
vcxproj_path = project_root / "YAZE.vcxproj"
|
||||||
|
|
||||||
|
with open(vcxproj_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(vcxproj_content)
|
||||||
|
|
||||||
|
print(f"Generated: {vcxproj_path}")
|
||||||
|
|
||||||
|
# Generate .sln file
|
||||||
|
solution_content = generate_solution()
|
||||||
|
solution_path = project_root / "YAZE.sln"
|
||||||
|
|
||||||
|
with open(solution_path, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(solution_content)
|
||||||
|
|
||||||
|
print(f"Generated: {solution_path}")
|
||||||
|
|
||||||
|
print("Visual Studio project files generated successfully!")
|
||||||
|
print("")
|
||||||
|
print("To build:")
|
||||||
|
print("1. Open YAZE.sln in Visual Studio 2022")
|
||||||
|
print("2. Ensure vcpkg is installed and configured")
|
||||||
|
print("3. Select your desired configuration (Debug/Release) and platform (x64/x86/ARM64)")
|
||||||
|
print("4. Build the solution (Ctrl+Shift+B)")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
54
scripts/quality_check.sh
Executable file
54
scripts/quality_check.sh
Executable file
@@ -0,0 +1,54 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Quality check script for YAZE codebase
|
||||||
|
# This script runs various code quality checks to ensure CI/CD pipeline passes
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
|
||||||
|
|
||||||
|
cd "${PROJECT_ROOT}"
|
||||||
|
|
||||||
|
echo "🔍 Running code quality checks for YAZE..."
|
||||||
|
|
||||||
|
# Check if required tools are available
|
||||||
|
command -v clang-format >/dev/null 2>&1 || { echo "❌ clang-format not found. Please install it."; exit 1; }
|
||||||
|
command -v cppcheck >/dev/null 2>&1 || { echo "❌ cppcheck not found. Please install it."; exit 1; }
|
||||||
|
|
||||||
|
# Create .clang-format config if it doesn't exist
|
||||||
|
if [ ! -f .clang-format ]; then
|
||||||
|
echo "📝 Creating .clang-format configuration..."
|
||||||
|
clang-format --style=Google --dump-config > .clang-format
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "✅ Code formatting check..."
|
||||||
|
# Check formatting without modifying files
|
||||||
|
FORMATTING_ISSUES=$(find src test -name "*.cc" -o -name "*.h" | head -50 | xargs clang-format --dry-run --Werror --style=Google 2>&1 || true)
|
||||||
|
if [ -n "$FORMATTING_ISSUES" ]; then
|
||||||
|
echo "⚠️ Formatting issues found. Run 'make format' to fix them."
|
||||||
|
echo "$FORMATTING_ISSUES" | head -20
|
||||||
|
else
|
||||||
|
echo "✅ All files are properly formatted"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "🔍 Running static analysis..."
|
||||||
|
# Run cppcheck on main source directories
|
||||||
|
cppcheck --enable=all --error-exitcode=0 \
|
||||||
|
--suppress=missingIncludeSystem \
|
||||||
|
--suppress=unusedFunction \
|
||||||
|
--suppress=unmatchedSuppression \
|
||||||
|
--suppress=unreadVariable \
|
||||||
|
--suppress=cstyleCast \
|
||||||
|
--suppress=variableScope \
|
||||||
|
src/ 2>&1 | head -30
|
||||||
|
|
||||||
|
echo "✅ Quality checks completed!"
|
||||||
|
echo ""
|
||||||
|
echo "💡 To fix formatting issues automatically, run:"
|
||||||
|
echo " find src test -name '*.cc' -o -name '*.h' | xargs clang-format -i --style=Google"
|
||||||
|
echo ""
|
||||||
|
echo "💡 For CI/CD pipeline compatibility, ensure:"
|
||||||
|
echo " - All formatting issues are resolved"
|
||||||
|
echo " - absl::Status return values are handled with RETURN_IF_ERROR() or PRINT_IF_ERROR()"
|
||||||
|
echo " - Use Google C++ style for consistency"
|
||||||
81
scripts/setup-vcpkg-windows.bat
Normal file
81
scripts/setup-vcpkg-windows.bat
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
@echo off
|
||||||
|
REM YAZE vcpkg Setup Script (Batch Version)
|
||||||
|
REM This script sets up vcpkg for YAZE development on Windows
|
||||||
|
|
||||||
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo YAZE vcpkg Setup Script
|
||||||
|
echo ========================================
|
||||||
|
|
||||||
|
REM Check if we're in the right directory
|
||||||
|
if not exist "vcpkg.json" (
|
||||||
|
echo ERROR: vcpkg.json not found. Please run this script from the project root directory.
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ vcpkg.json found
|
||||||
|
|
||||||
|
REM Check for Git
|
||||||
|
where git >nul 2>&1
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ERROR: Git not found. Please install Git for Windows.
|
||||||
|
echo Download from: https://git-scm.com/download/win
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ✓ Git found
|
||||||
|
|
||||||
|
REM Clone vcpkg if needed
|
||||||
|
if not exist "vcpkg" (
|
||||||
|
echo Cloning vcpkg...
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git vcpkg
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ERROR: Failed to clone vcpkg
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
echo ✓ vcpkg cloned successfully
|
||||||
|
) else (
|
||||||
|
echo ✓ vcpkg directory already exists
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Bootstrap vcpkg
|
||||||
|
if not exist "vcpkg\vcpkg.exe" (
|
||||||
|
echo Bootstrapping vcpkg...
|
||||||
|
cd vcpkg
|
||||||
|
call bootstrap-vcpkg.bat
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo ERROR: Failed to bootstrap vcpkg
|
||||||
|
cd ..
|
||||||
|
pause
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
cd ..
|
||||||
|
echo ✓ vcpkg bootstrapped successfully
|
||||||
|
) else (
|
||||||
|
echo ✓ vcpkg already bootstrapped
|
||||||
|
)
|
||||||
|
|
||||||
|
REM Install dependencies
|
||||||
|
echo Installing dependencies...
|
||||||
|
vcpkg\vcpkg.exe install --triplet x64-windows
|
||||||
|
if %errorlevel% neq 0 (
|
||||||
|
echo WARNING: Some dependencies may not have installed correctly
|
||||||
|
) else (
|
||||||
|
echo ✓ Dependencies installed successfully
|
||||||
|
)
|
||||||
|
|
||||||
|
echo ========================================
|
||||||
|
echo ✓ vcpkg setup complete!
|
||||||
|
echo ========================================
|
||||||
|
echo.
|
||||||
|
echo You can now build YAZE using:
|
||||||
|
echo .\scripts\build-windows.ps1
|
||||||
|
echo or
|
||||||
|
echo .\scripts\build-windows.bat
|
||||||
|
echo.
|
||||||
|
|
||||||
|
pause
|
||||||
106
scripts/setup-vcpkg-windows.ps1
Normal file
106
scripts/setup-vcpkg-windows.ps1
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# YAZE vcpkg Setup Script
|
||||||
|
# This script sets up vcpkg for YAZE development on Windows
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$Triplet = "x64-windows"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Set error handling
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
$Colors = @{
|
||||||
|
Success = "Green"
|
||||||
|
Warning = "Yellow"
|
||||||
|
Error = "Red"
|
||||||
|
Info = "Cyan"
|
||||||
|
White = "White"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Status {
|
||||||
|
param([string]$Message, [string]$Color = "White")
|
||||||
|
Write-Host $Message -ForegroundColor $Colors[$Color]
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-Command {
|
||||||
|
param([string]$Command)
|
||||||
|
try {
|
||||||
|
$null = Get-Command $Command -ErrorAction Stop
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status "YAZE vcpkg Setup Script" "Info"
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
|
||||||
|
Write-Status "Target triplet: $Triplet" "Warning"
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if (-not (Test-Path "vcpkg.json")) {
|
||||||
|
Write-Status "ERROR: vcpkg.json not found. Please run this script from the project root directory." "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ Found vcpkg.json" "Success"
|
||||||
|
|
||||||
|
# Check for Git
|
||||||
|
if (-not (Test-Command "git")) {
|
||||||
|
Write-Status "ERROR: Git not found. Please install Git for Windows." "Error"
|
||||||
|
Write-Status "Download from: https://git-scm.com/download/win" "Info"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "✓ Git found" "Success"
|
||||||
|
|
||||||
|
# Clone vcpkg if needed
|
||||||
|
if (-not (Test-Path "vcpkg")) {
|
||||||
|
Write-Status "Cloning vcpkg..." "Warning"
|
||||||
|
& git clone https://github.com/Microsoft/vcpkg.git vcpkg
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Status "✓ vcpkg cloned successfully" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Failed to clone vcpkg" "Error"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Status "✓ vcpkg directory already exists" "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bootstrap vcpkg
|
||||||
|
$vcpkgExe = "vcpkg\vcpkg.exe"
|
||||||
|
if (-not (Test-Path $vcpkgExe)) {
|
||||||
|
Write-Status "Bootstrapping vcpkg..." "Warning"
|
||||||
|
Push-Location vcpkg
|
||||||
|
& .\bootstrap-vcpkg.bat
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Status "✓ vcpkg bootstrapped successfully" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Failed to bootstrap vcpkg" "Error"
|
||||||
|
Pop-Location
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
Pop-Location
|
||||||
|
} else {
|
||||||
|
Write-Status "✓ vcpkg already bootstrapped" "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
Write-Status "Installing dependencies for triplet: $Triplet" "Warning"
|
||||||
|
& $vcpkgExe install --triplet $Triplet
|
||||||
|
if ($LASTEXITCODE -eq 0) {
|
||||||
|
Write-Status "✓ Dependencies installed successfully" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "⚠ Some dependencies may not have installed correctly" "Warning"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status "✓ vcpkg setup complete!" "Success"
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "You can now build YAZE using:" "Warning"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1" "White"
|
||||||
|
Write-Status ""
|
||||||
219
scripts/setup-windows-dev.ps1
Normal file
219
scripts/setup-windows-dev.ps1
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
# YAZE Windows Development Setup Script
|
||||||
|
# Sequential approach with no functions and minimal conditionals
|
||||||
|
|
||||||
|
param(
|
||||||
|
[switch]$SkipVcpkg,
|
||||||
|
[switch]$SkipVS,
|
||||||
|
[switch]$SkipBuild
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "YAZE Windows Development Setup" -ForegroundColor Cyan
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
|
||||||
|
# Step 1: Check project directory
|
||||||
|
Write-Host "Step 1: Checking project directory..." -ForegroundColor Yellow
|
||||||
|
$projectValid = Test-Path "CMakeLists.txt"
|
||||||
|
switch ($projectValid) {
|
||||||
|
$true { Write-Host "✓ CMakeLists.txt found" -ForegroundColor Green }
|
||||||
|
$false {
|
||||||
|
Write-Host "✗ CMakeLists.txt not found" -ForegroundColor Red
|
||||||
|
Write-Host "Please run this script from the YAZE project root directory" -ForegroundColor Yellow
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 2: Check Visual Studio
|
||||||
|
Write-Host "Step 2: Checking Visual Studio..." -ForegroundColor Yellow
|
||||||
|
switch ($SkipVS) {
|
||||||
|
$true { Write-Host "Skipping Visual Studio check" -ForegroundColor Yellow }
|
||||||
|
$false {
|
||||||
|
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||||
|
$vsFound = $false
|
||||||
|
$vsExists = Test-Path $vsWhere
|
||||||
|
switch ($vsExists) {
|
||||||
|
$true {
|
||||||
|
$vsInstall = & $vsWhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||||
|
switch ($null -ne $vsInstall) {
|
||||||
|
$true {
|
||||||
|
$msbuildPath = Join-Path $vsInstall "MSBuild\Current\Bin\MSBuild.exe"
|
||||||
|
$vsFound = Test-Path $msbuildPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($vsFound) {
|
||||||
|
$true { Write-Host "✓ Visual Studio 2022 with C++ workload found" -ForegroundColor Green }
|
||||||
|
$false {
|
||||||
|
Write-Host "⚠ Visual Studio 2022 with C++ workload not found" -ForegroundColor Yellow
|
||||||
|
Write-Host "Please install Visual Studio 2022 with 'Desktop development with C++' workload" -ForegroundColor White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 3: Check Git
|
||||||
|
Write-Host "Step 3: Checking Git..." -ForegroundColor Yellow
|
||||||
|
$gitFound = $false
|
||||||
|
try {
|
||||||
|
$null = Get-Command git -ErrorAction Stop
|
||||||
|
$gitFound = $true
|
||||||
|
} catch {
|
||||||
|
$gitFound = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($gitFound) {
|
||||||
|
$true {
|
||||||
|
$gitVersion = & git --version
|
||||||
|
Write-Host "✓ Git found: $gitVersion" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
$false {
|
||||||
|
Write-Host "⚠ Git not found" -ForegroundColor Yellow
|
||||||
|
Write-Host "Please install Git for Windows from: https://git-scm.com/download/win" -ForegroundColor White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 4: Check Python
|
||||||
|
Write-Host "Step 4: Checking Python..." -ForegroundColor Yellow
|
||||||
|
$pythonFound = $false
|
||||||
|
try {
|
||||||
|
$null = Get-Command python -ErrorAction Stop
|
||||||
|
$pythonFound = $true
|
||||||
|
} catch {
|
||||||
|
$pythonFound = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ($pythonFound) {
|
||||||
|
$true {
|
||||||
|
$pythonVersion = & python --version
|
||||||
|
Write-Host "✓ Python found: $pythonVersion" -ForegroundColor Green
|
||||||
|
}
|
||||||
|
$false {
|
||||||
|
Write-Host "⚠ Python not found" -ForegroundColor Yellow
|
||||||
|
Write-Host "Please install Python 3.8+ from: https://www.python.org/downloads/" -ForegroundColor White
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 5: Setup vcpkg
|
||||||
|
Write-Host "Step 5: Setting up vcpkg..." -ForegroundColor Yellow
|
||||||
|
switch ($SkipVcpkg) {
|
||||||
|
$true { Write-Host "Skipping vcpkg setup" -ForegroundColor Yellow }
|
||||||
|
$false {
|
||||||
|
# Clone vcpkg
|
||||||
|
$vcpkgExists = Test-Path "vcpkg"
|
||||||
|
switch ($vcpkgExists) {
|
||||||
|
$false {
|
||||||
|
Write-Host "Cloning vcpkg..." -ForegroundColor Yellow
|
||||||
|
switch ($gitFound) {
|
||||||
|
$true {
|
||||||
|
& git clone https://github.com/Microsoft/vcpkg.git vcpkg
|
||||||
|
$cloneSuccess = ($LASTEXITCODE -eq 0)
|
||||||
|
switch ($cloneSuccess) {
|
||||||
|
$true { Write-Host "✓ vcpkg cloned successfully" -ForegroundColor Green }
|
||||||
|
$false {
|
||||||
|
Write-Host "✗ Failed to clone vcpkg" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$false {
|
||||||
|
Write-Host "✗ Git is required to clone vcpkg" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$true { Write-Host "✓ vcpkg directory already exists" -ForegroundColor Green }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Bootstrap vcpkg
|
||||||
|
$vcpkgExe = "vcpkg\vcpkg.exe"
|
||||||
|
$vcpkgBootstrapped = Test-Path $vcpkgExe
|
||||||
|
switch ($vcpkgBootstrapped) {
|
||||||
|
$false {
|
||||||
|
Write-Host "Bootstrapping vcpkg..." -ForegroundColor Yellow
|
||||||
|
Push-Location vcpkg
|
||||||
|
& .\bootstrap-vcpkg.bat
|
||||||
|
$bootstrapSuccess = ($LASTEXITCODE -eq 0)
|
||||||
|
Pop-Location
|
||||||
|
switch ($bootstrapSuccess) {
|
||||||
|
$true { Write-Host "✓ vcpkg bootstrapped successfully" -ForegroundColor Green }
|
||||||
|
$false {
|
||||||
|
Write-Host "✗ Failed to bootstrap vcpkg" -ForegroundColor Red
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$true { Write-Host "✓ vcpkg already bootstrapped" -ForegroundColor Green }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install dependencies
|
||||||
|
Write-Host "Installing dependencies..." -ForegroundColor Yellow
|
||||||
|
& $vcpkgExe install --triplet x64-windows
|
||||||
|
$installSuccess = ($LASTEXITCODE -eq 0)
|
||||||
|
switch ($installSuccess) {
|
||||||
|
$true { Write-Host "✓ Dependencies installed successfully" -ForegroundColor Green }
|
||||||
|
$false { Write-Host "⚠ Some dependencies may not have installed correctly" -ForegroundColor Yellow }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 6: Generate project files
|
||||||
|
Write-Host "Step 6: Generating Visual Studio project files..." -ForegroundColor Yellow
|
||||||
|
switch ($pythonFound) {
|
||||||
|
$true {
|
||||||
|
& python scripts/generate-vs-projects-simple.py
|
||||||
|
$generateSuccess = ($LASTEXITCODE -eq 0)
|
||||||
|
switch ($generateSuccess) {
|
||||||
|
$true { Write-Host "✓ Project files generated successfully" -ForegroundColor Green }
|
||||||
|
$false {
|
||||||
|
Write-Host "⚠ Failed to generate project files with simple generator, trying original..." -ForegroundColor Yellow
|
||||||
|
& python scripts/generate-vs-projects.py
|
||||||
|
$generateSuccess2 = ($LASTEXITCODE -eq 0)
|
||||||
|
switch ($generateSuccess2) {
|
||||||
|
$true { Write-Host "✓ Project files generated successfully" -ForegroundColor Green }
|
||||||
|
$false { Write-Host "⚠ Failed to generate project files" -ForegroundColor Yellow }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$false { Write-Host "⚠ Python required to generate project files" -ForegroundColor Yellow }
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 7: Test build
|
||||||
|
Write-Host "Step 7: Testing build..." -ForegroundColor Yellow
|
||||||
|
switch ($SkipBuild) {
|
||||||
|
$true { Write-Host "Skipping test build" -ForegroundColor Yellow }
|
||||||
|
$false {
|
||||||
|
$buildScriptExists = Test-Path "scripts\build-windows.ps1"
|
||||||
|
switch ($buildScriptExists) {
|
||||||
|
$true {
|
||||||
|
& .\scripts\build-windows.ps1 -Configuration Release -Platform x64
|
||||||
|
$buildSuccess = ($LASTEXITCODE -eq 0)
|
||||||
|
switch ($buildSuccess) {
|
||||||
|
$true { Write-Host "✓ Test build successful" -ForegroundColor Green }
|
||||||
|
$false { Write-Host "⚠ Test build failed, but setup is complete" -ForegroundColor Yellow }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$false { Write-Host "⚠ Build script not found" -ForegroundColor Yellow }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Final instructions
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host "✓ YAZE Windows development setup complete!" -ForegroundColor Green
|
||||||
|
Write-Host "========================================" -ForegroundColor Cyan
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Next steps:" -ForegroundColor Yellow
|
||||||
|
Write-Host "1. Visual Studio project files have been generated" -ForegroundColor White
|
||||||
|
Write-Host "2. Open YAZE.sln in Visual Studio 2022" -ForegroundColor White
|
||||||
|
Write-Host "3. Select configuration (Debug/Release) and platform (x64/x86/ARM64)" -ForegroundColor White
|
||||||
|
Write-Host "4. Build the solution (Ctrl+Shift+B)" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Or use command line:" -ForegroundColor Yellow
|
||||||
|
Write-Host " .\scripts\build-windows.ps1 -Configuration Release -Platform x64" -ForegroundColor White
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "For more information, see docs/windows-development-guide.md" -ForegroundColor Cyan
|
||||||
150
scripts/test_asar_integration.py
Executable file
150
scripts/test_asar_integration.py
Executable file
@@ -0,0 +1,150 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Asar Integration Test Script for Yaze
|
||||||
|
Tests the Asar 65816 assembler integration with real ROM files
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
import tempfile
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
def find_project_root():
|
||||||
|
"""Find the yaze project root directory"""
|
||||||
|
current = Path(__file__).parent
|
||||||
|
while current != current.parent:
|
||||||
|
if (current / "CMakeLists.txt").exists():
|
||||||
|
return current
|
||||||
|
current = current.parent
|
||||||
|
raise FileNotFoundError("Could not find yaze project root")
|
||||||
|
|
||||||
|
def main():
|
||||||
|
print("🧪 Yaze Asar Integration Test")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
project_root = find_project_root()
|
||||||
|
build_dir = project_root / "build_test"
|
||||||
|
rom_path = build_dir / "bin" / "zelda3.sfc"
|
||||||
|
test_patch = project_root / "test" / "assets" / "test_patch.asm"
|
||||||
|
|
||||||
|
# Check if ROM file exists
|
||||||
|
if not rom_path.exists():
|
||||||
|
print(f"❌ ROM file not found: {rom_path}")
|
||||||
|
print(" Please ensure you have a test ROM at the expected location")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(f"✅ Found ROM file: {rom_path}")
|
||||||
|
print(f" Size: {rom_path.stat().st_size:,} bytes")
|
||||||
|
|
||||||
|
# Check if test patch exists
|
||||||
|
if not test_patch.exists():
|
||||||
|
print(f"❌ Test patch not found: {test_patch}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(f"✅ Found test patch: {test_patch}")
|
||||||
|
|
||||||
|
# Check if z3ed tool exists
|
||||||
|
z3ed_path = build_dir / "bin" / "z3ed"
|
||||||
|
if not z3ed_path.exists():
|
||||||
|
print(f"❌ z3ed CLI tool not found: {z3ed_path}")
|
||||||
|
print(" Run: cmake --build build_test --target z3ed")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
print(f"✅ Found z3ed CLI tool: {z3ed_path}")
|
||||||
|
|
||||||
|
# Create temporary directory for testing
|
||||||
|
with tempfile.TemporaryDirectory() as temp_dir:
|
||||||
|
temp_path = Path(temp_dir)
|
||||||
|
test_rom_path = temp_path / "test_rom.sfc"
|
||||||
|
patched_rom_path = temp_path / "patched_rom.sfc"
|
||||||
|
|
||||||
|
# Copy ROM to temporary location
|
||||||
|
shutil.copy2(rom_path, test_rom_path)
|
||||||
|
print(f"📋 Copied ROM to: {test_rom_path}")
|
||||||
|
|
||||||
|
# Test 1: Apply patch using z3ed CLI
|
||||||
|
print("\n🔧 Test 1: Applying patch with z3ed CLI")
|
||||||
|
try:
|
||||||
|
cmd = [str(z3ed_path), "asar", str(test_patch), str(test_rom_path)]
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
print("✅ Patch applied successfully!")
|
||||||
|
if result.stdout:
|
||||||
|
print(f" Output: {result.stdout.strip()}")
|
||||||
|
else:
|
||||||
|
print(f"❌ Patch failed with return code: {result.returncode}")
|
||||||
|
if result.stderr:
|
||||||
|
print(f" Error: {result.stderr.strip()}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print("❌ Patch operation timed out")
|
||||||
|
return 1
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Error running patch: {e}")
|
||||||
|
return 1
|
||||||
|
|
||||||
|
# Test 2: Verify ROM was modified
|
||||||
|
print("\n🔍 Test 2: Verifying ROM modification")
|
||||||
|
original_size = rom_path.stat().st_size
|
||||||
|
modified_size = test_rom_path.stat().st_size
|
||||||
|
|
||||||
|
print(f" Original ROM size: {original_size:,} bytes")
|
||||||
|
print(f" Modified ROM size: {modified_size:,} bytes")
|
||||||
|
|
||||||
|
# Read first few bytes to check for changes
|
||||||
|
with open(rom_path, 'rb') as orig_file, open(test_rom_path, 'rb') as mod_file:
|
||||||
|
orig_bytes = orig_file.read(1024)
|
||||||
|
mod_bytes = mod_file.read(1024)
|
||||||
|
|
||||||
|
if orig_bytes != mod_bytes:
|
||||||
|
print("✅ ROM was successfully modified!")
|
||||||
|
# Count different bytes
|
||||||
|
diff_count = sum(1 for a, b in zip(orig_bytes, mod_bytes) if a != b)
|
||||||
|
print(f" {diff_count} bytes differ in first 1KB")
|
||||||
|
else:
|
||||||
|
print("⚠️ No differences detected in first 1KB")
|
||||||
|
print(" (Patch may have been applied to a different region)")
|
||||||
|
|
||||||
|
# Test 3: Run unit tests if available
|
||||||
|
yaze_test_path = build_dir / "bin" / "yaze_test"
|
||||||
|
if yaze_test_path.exists():
|
||||||
|
print("\n🧪 Test 3: Running Asar unit tests")
|
||||||
|
try:
|
||||||
|
# Run only the Asar-related tests
|
||||||
|
cmd = [str(yaze_test_path), "--gtest_filter=*Asar*", "--gtest_brief=1"]
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True, timeout=60)
|
||||||
|
|
||||||
|
print(f" Exit code: {result.returncode}")
|
||||||
|
if result.stdout:
|
||||||
|
# Extract test results
|
||||||
|
lines = result.stdout.split('\n')
|
||||||
|
for line in lines:
|
||||||
|
if 'PASSED' in line or 'FAILED' in line or 'RUN' in line:
|
||||||
|
print(f" {line}")
|
||||||
|
|
||||||
|
if result.returncode == 0:
|
||||||
|
print("✅ Unit tests passed!")
|
||||||
|
else:
|
||||||
|
print("⚠️ Some unit tests failed (this may be expected)")
|
||||||
|
|
||||||
|
except subprocess.TimeoutExpired:
|
||||||
|
print("❌ Unit tests timed out")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"⚠️ Error running unit tests: {e}")
|
||||||
|
else:
|
||||||
|
print("\n⚠️ Test 3: yaze_test executable not found")
|
||||||
|
|
||||||
|
print("\n🎉 Asar integration test completed!")
|
||||||
|
print("\nNext steps:")
|
||||||
|
print("- Run full test suite with: ctest --test-dir build_test")
|
||||||
|
print("- Test Asar functionality in the main yaze application")
|
||||||
|
print("- Create custom assembly patches for your ROM hacking projects")
|
||||||
|
|
||||||
|
return 0
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
132
scripts/validate-windows-build.ps1
Normal file
132
scripts/validate-windows-build.ps1
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
# YAZE Windows Build Validation Script
|
||||||
|
# This script validates that the Windows build environment is properly set up
|
||||||
|
|
||||||
|
# Set error handling
|
||||||
|
$ErrorActionPreference = "Continue"
|
||||||
|
|
||||||
|
# Colors for output
|
||||||
|
$Colors = @{
|
||||||
|
Success = "Green"
|
||||||
|
Warning = "Yellow"
|
||||||
|
Error = "Red"
|
||||||
|
Info = "Cyan"
|
||||||
|
White = "White"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Write-Status {
|
||||||
|
param([string]$Message, [string]$Color = "White")
|
||||||
|
Write-Host $Message -ForegroundColor $Colors[$Color]
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-Command {
|
||||||
|
param([string]$Command)
|
||||||
|
try {
|
||||||
|
$null = Get-Command $Command -ErrorAction Stop
|
||||||
|
return $true
|
||||||
|
} catch {
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Test-VisualStudio {
|
||||||
|
$vsWhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe"
|
||||||
|
if (Test-Path $vsWhere) {
|
||||||
|
$vsInstall = & $vsWhere -latest -products * -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath
|
||||||
|
if ($vsInstall) {
|
||||||
|
$msbuildPath = Join-Path $vsInstall "MSBuild\Current\Bin\MSBuild.exe"
|
||||||
|
if (Test-Path $msbuildPath) {
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main script
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
Write-Status "YAZE Windows Build Validation" "Info"
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
|
||||||
|
$allGood = $true
|
||||||
|
|
||||||
|
# Check if we're in the right directory
|
||||||
|
if (-not (Test-Path "YAZE.sln")) {
|
||||||
|
Write-Status "✗ YAZE.sln not found" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
} else {
|
||||||
|
Write-Status "✓ YAZE.sln found" "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for vcpkg.json
|
||||||
|
if (-not (Test-Path "vcpkg.json")) {
|
||||||
|
Write-Status "✗ vcpkg.json not found" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
} else {
|
||||||
|
Write-Status "✓ vcpkg.json found" "Success"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for Visual Studio
|
||||||
|
if (Test-VisualStudio) {
|
||||||
|
Write-Status "✓ Visual Studio 2022 with C++ workload found" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Visual Studio 2022 with C++ workload not found" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for Git
|
||||||
|
if (Test-Command "git") {
|
||||||
|
$gitVersion = & git --version
|
||||||
|
Write-Status "✓ Git found: $gitVersion" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Git not found" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for Python
|
||||||
|
if (Test-Command "python") {
|
||||||
|
$pythonVersion = & python --version
|
||||||
|
Write-Status "✓ Python found: $pythonVersion" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Python not found" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for vcpkg
|
||||||
|
if (Test-Path "vcpkg\vcpkg.exe") {
|
||||||
|
Write-Status "✓ vcpkg found and bootstrapped" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ vcpkg not found or not bootstrapped" "Error"
|
||||||
|
$allGood = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for generated project files
|
||||||
|
if (Test-Path "YAZE.vcxproj") {
|
||||||
|
Write-Status "✓ Visual Studio project file found" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Visual Studio project file not found" "Error"
|
||||||
|
Write-Status " Run: python scripts/generate-vs-projects.py" "Info"
|
||||||
|
$allGood = $false
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check for config file
|
||||||
|
if (Test-Path "yaze_config.h") {
|
||||||
|
Write-Status "✓ yaze_config.h found" "Success"
|
||||||
|
} else {
|
||||||
|
Write-Status "⚠ yaze_config.h not found (will be generated during build)" "Warning"
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
|
if ($allGood) {
|
||||||
|
Write-Status "✓ All checks passed! Build environment is ready." "Success"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "You can now build YAZE using:" "Warning"
|
||||||
|
Write-Status " .\scripts\build-windows.ps1" "White"
|
||||||
|
Write-Status " or" "White"
|
||||||
|
Write-Status " .\scripts\build-windows.bat" "White"
|
||||||
|
} else {
|
||||||
|
Write-Status "✗ Some checks failed. Please fix the issues above." "Error"
|
||||||
|
Write-Status ""
|
||||||
|
Write-Status "Run the setup script to fix issues:" "Warning"
|
||||||
|
Write-Status " .\scripts\setup-windows-dev.ps1" "White"
|
||||||
|
}
|
||||||
|
Write-Status "========================================" "Info"
|
||||||
@@ -1,115 +1,96 @@
|
|||||||
# yaze source files -----------------------------------------------------------
|
|
||||||
set(
|
set(
|
||||||
YAZE_APP_CORE_SRC
|
YAZE_APP_EMU_SRC
|
||||||
app/core/common.cc
|
app/emu/audio/apu.cc
|
||||||
app/core/controller.cc
|
app/emu/audio/spc700.cc
|
||||||
|
app/emu/audio/dsp.cc
|
||||||
|
app/emu/audio/internal/addressing.cc
|
||||||
|
app/emu/audio/internal/instructions.cc
|
||||||
|
app/emu/cpu/internal/addressing.cc
|
||||||
|
app/emu/cpu/internal/instructions.cc
|
||||||
|
app/emu/cpu/cpu.cc
|
||||||
|
app/emu/video/ppu.cc
|
||||||
|
app/emu/memory/dma.cc
|
||||||
|
app/emu/memory/memory.cc
|
||||||
|
app/emu/snes.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
YAZE_APP_EDITOR_SRC
|
YAZE_UTIL_SRC
|
||||||
app/editor/assembly_editor.cc
|
util/bps.cc
|
||||||
app/editor/dungeon_editor.cc
|
util/flag.cc
|
||||||
app/editor/master_editor.cc
|
util/hex.cc
|
||||||
app/editor/music_editor.cc
|
|
||||||
app/editor/overworld_editor.cc
|
|
||||||
app/editor/palette_editor.cc
|
|
||||||
app/editor/screen_editor.cc
|
|
||||||
)
|
)
|
||||||
|
|
||||||
set(
|
set(YAZE_RESOURCE_FILES
|
||||||
YAZE_APP_GFX_SRC
|
${CMAKE_SOURCE_DIR}/assets/font/Karla-Regular.ttf
|
||||||
app/gfx/bitmap.cc
|
${CMAKE_SOURCE_DIR}/assets/font/Roboto-Medium.ttf
|
||||||
app/gfx/snes_palette.cc
|
${CMAKE_SOURCE_DIR}/assets/font/Cousine-Regular.ttf
|
||||||
app/gfx/snes_tile.cc
|
${CMAKE_SOURCE_DIR}/assets/font/DroidSans.ttf
|
||||||
|
${CMAKE_SOURCE_DIR}/assets/font/NotoSansJP.ttf
|
||||||
|
${CMAKE_SOURCE_DIR}/assets/font/IBMPlexSansJP-Bold.ttf
|
||||||
|
${CMAKE_SOURCE_DIR}/assets/font/MaterialIcons-Regular.ttf
|
||||||
)
|
)
|
||||||
|
|
||||||
set(
|
# Add theme files for macOS bundle (replacing the glob pattern with explicit files)
|
||||||
YAZE_APP_ZELDA3_SRC
|
file(GLOB YAZE_THEME_FILES "${CMAKE_SOURCE_DIR}/assets/themes/*.theme")
|
||||||
app/zelda3/inventory.cc
|
list(APPEND YAZE_RESOURCE_FILES ${YAZE_THEME_FILES})
|
||||||
app/zelda3/overworld_map.cc
|
|
||||||
app/zelda3/overworld.cc
|
|
||||||
app/zelda3/title_screen.cc
|
|
||||||
app/zelda3/sprite.cc
|
|
||||||
)
|
|
||||||
|
|
||||||
set(
|
foreach (FILE ${YAZE_RESOURCE_FILES})
|
||||||
YAZE_GUI_SRC
|
file(RELATIVE_PATH NEW_FILE "${CMAKE_SOURCE_DIR}/assets" ${FILE})
|
||||||
gui/canvas.cc
|
get_filename_component(NEW_FILE_PATH ${NEW_FILE} DIRECTORY)
|
||||||
gui/input.cc
|
set_source_files_properties(${FILE}
|
||||||
gui/style.cc
|
PROPERTIES
|
||||||
gui/widgets.cc
|
MACOSX_PACKAGE_LOCATION "Resources/${NEW_FILE_PATH}"
|
||||||
gui/color.cc
|
)
|
||||||
)
|
endforeach()
|
||||||
|
|
||||||
# executable creation ---------------------------------------------------------
|
# Conditionally add native file dialog (optional for CI builds)
|
||||||
|
if(NOT YAZE_MINIMAL_BUILD)
|
||||||
add_executable(
|
# Check if we can build NFD before adding it
|
||||||
yaze
|
find_package(PkgConfig QUIET)
|
||||||
app/yaze.cc
|
if(PKG_CONFIG_FOUND AND UNIX AND NOT APPLE)
|
||||||
app/rom.cc
|
pkg_check_modules(GTK3 QUIET gtk+-3.0)
|
||||||
${YAZE_APP_CORE_SRC}
|
if(GTK3_FOUND)
|
||||||
${YAZE_APP_EDITOR_SRC}
|
add_subdirectory(lib/nativefiledialog-extended)
|
||||||
${YAZE_APP_GFX_SRC}
|
set(YAZE_HAS_NFD ON)
|
||||||
${YAZE_APP_ZELDA3_SRC}
|
message(STATUS "NFD enabled with GTK3 support")
|
||||||
${YAZE_GUI_SRC}
|
else()
|
||||||
${ASAR_STATIC_SRC}
|
set(YAZE_HAS_NFD OFF)
|
||||||
${SNES_SPC_SOURCES}
|
message(STATUS "NFD disabled - GTK3 not found")
|
||||||
${IMGUI_SRC}
|
endif()
|
||||||
)
|
elseif(WIN32 OR APPLE)
|
||||||
|
add_subdirectory(lib/nativefiledialog-extended)
|
||||||
# including libraries ---------------------------------------------------------
|
set(YAZE_HAS_NFD ON)
|
||||||
|
message(STATUS "NFD enabled for Windows/macOS")
|
||||||
target_include_directories(
|
else()
|
||||||
yaze PUBLIC
|
set(YAZE_HAS_NFD OFF)
|
||||||
lib/
|
message(STATUS "NFD disabled - no platform support")
|
||||||
app/
|
endif()
|
||||||
${CMAKE_SOURCE_DIR}/src/
|
else()
|
||||||
${PNG_INCLUDE_DIRS}
|
set(YAZE_HAS_NFD OFF)
|
||||||
${SDL2_INCLUDE_DIR}
|
message(STATUS "NFD disabled for minimal build")
|
||||||
lib/SDL_mixer/include/
|
|
||||||
${GLEW_INCLUDE_DIRS}
|
|
||||||
lib/asar/src/asar/
|
|
||||||
lib/snes_spc/snes_spc/
|
|
||||||
)
|
|
||||||
|
|
||||||
set(SDL_TARGETS SDL2::SDL2)
|
|
||||||
|
|
||||||
if(WIN32 OR MINGW)
|
|
||||||
list(PREPEND SDL_TARGETS SDL2::SDL2main)
|
|
||||||
add_definitions(-DSDL_MAIN_HANDLED)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# linking libraries -----------------------------------------------------------
|
if (YAZE_BUILD_APP)
|
||||||
|
include(app/app.cmake)
|
||||||
target_link_libraries(
|
endif()
|
||||||
yaze PUBLIC
|
if (YAZE_BUILD_EMU)
|
||||||
${ABSL_TARGETS}
|
include(app/emu/emu.cmake)
|
||||||
${SDL_TARGETS}
|
endif()
|
||||||
${SDLMIXER_LIBRARY}
|
if (YAZE_BUILD_Z3ED)
|
||||||
SDL2_mixer
|
include(cli/z3ed.cmake)
|
||||||
${PNG_LIBRARIES}
|
|
||||||
${GLEW_LIBRARIES}
|
|
||||||
${OPENGL_LIBRARIES}
|
|
||||||
${CMAKE_DL_LIBS}
|
|
||||||
asar-static
|
|
||||||
snes_spc
|
|
||||||
ImGui
|
|
||||||
)
|
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
target_compile_definitions(yaze PRIVATE "linux")
|
|
||||||
target_compile_definitions(yaze PRIVATE "stricmp=strcasecmp")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MACOS)
|
if(MACOS)
|
||||||
set(MACOSX_BUNDLE_ICON_FILE ${CMAKE_SOURCE_DIR}/yaze.ico)
|
|
||||||
set_target_properties(yaze
|
set_target_properties(yaze
|
||||||
PROPERTIES
|
PROPERTIES
|
||||||
BUNDLE True
|
BUNDLE True
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
OUTPUT_NAME "yaze"
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
# MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/yaze.plist.in
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
|
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/cmake/yaze.plist.in
|
||||||
|
RESOURCE ${YAZE_RESOURCE_FILES}
|
||||||
)
|
)
|
||||||
elseif(UNIX)
|
elseif(UNIX)
|
||||||
set_target_properties(yaze
|
set_target_properties(yaze
|
||||||
@@ -119,65 +100,146 @@ elseif(UNIX)
|
|||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
)
|
)
|
||||||
|
target_compile_definitions(yaze PRIVATE "linux")
|
||||||
|
target_compile_definitions(yaze PRIVATE "stricmp=strcasecmp")
|
||||||
else()
|
else()
|
||||||
set_target_properties(yaze
|
if(YAZE_MINIMAL_BUILD)
|
||||||
PROPERTIES
|
# Skip Windows resource file in CI/minimal builds to avoid architecture conflicts
|
||||||
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
set_target_properties(yaze
|
||||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
PROPERTIES
|
||||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/yaze.res"
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
)
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
set_target_properties(yaze
|
||||||
|
PROPERTIES
|
||||||
|
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
|
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
|
||||||
|
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
|
||||||
|
LINK_FLAGS "${CMAKE_CURRENT_SOURCE_DIR}/win32/yaze.res"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# add_subdirectory(app/delta)
|
# Yaze Core Library (for testing and C API)
|
||||||
|
if (YAZE_BUILD_LIB)
|
||||||
|
# Create core library for testing (includes editor and zelda3 components needed by tests)
|
||||||
|
set(YAZE_CORE_SOURCES
|
||||||
|
app/rom.cc
|
||||||
|
${YAZE_APP_CORE_SRC}
|
||||||
|
${YAZE_APP_GFX_SRC}
|
||||||
|
${YAZE_APP_EDITOR_SRC}
|
||||||
|
${YAZE_APP_ZELDA3_SRC}
|
||||||
|
${YAZE_APP_EMU_SRC}
|
||||||
|
${YAZE_GUI_SRC}
|
||||||
|
${YAZE_UTIL_SRC}
|
||||||
|
)
|
||||||
|
|
||||||
# add_executable(
|
# Create full library for C API
|
||||||
# yaze_delta
|
set(YAZE_C_SOURCES
|
||||||
# app/delta/delta.cc
|
./yaze.cc
|
||||||
# app/delta/viewer.cc
|
${YAZE_CORE_SOURCES}
|
||||||
# app/delta/service.cc
|
${YAZE_GUI_SRC}
|
||||||
# app/delta/client.cc
|
${IMGUI_SRC}
|
||||||
# app/rom.cc
|
)
|
||||||
# ${YAZE_APP_ASM_SRC}
|
|
||||||
# ${YAZE_APP_CORE_SRC}
|
|
||||||
# ${YAZE_APP_EDITOR_SRC}
|
|
||||||
# ${YAZE_APP_GFX_SRC}
|
|
||||||
# ${YAZE_APP_ZELDA3_SRC}
|
|
||||||
# ${YAZE_GUI_SRC}
|
|
||||||
# ${IMGUI_SRC}
|
|
||||||
# ${ASAR_STATIC_SRC}
|
|
||||||
# )
|
|
||||||
|
|
||||||
# target_include_directories(
|
# Add emulator sources (required for comprehensive testing)
|
||||||
# yaze_delta PUBLIC
|
list(APPEND YAZE_C_SOURCES ${YAZE_APP_EMU_SRC})
|
||||||
# lib/
|
|
||||||
# app/
|
|
||||||
# lib/asar/src/
|
|
||||||
# ${ASAR_INCLUDE_DIR}
|
|
||||||
# ${CMAKE_SOURCE_DIR}/src/
|
|
||||||
# ${PNG_INCLUDE_DIRS}
|
|
||||||
# ${SDL2_INCLUDE_DIR}
|
|
||||||
# ${GLEW_INCLUDE_DIRS}
|
|
||||||
# )
|
|
||||||
|
|
||||||
# target_link_libraries(
|
# Only add ImGui Test Engine sources if UI tests are enabled
|
||||||
# yaze_delta PUBLIC
|
if(YAZE_ENABLE_UI_TESTS)
|
||||||
# ${ABSL_TARGETS}
|
list(APPEND YAZE_C_SOURCES ${IMGUI_TEST_ENGINE_SOURCES})
|
||||||
# ${SDL_TARGETS}
|
endif()
|
||||||
# ${PNG_LIBRARIES}
|
|
||||||
# ${GLEW_LIBRARIES}
|
|
||||||
# ${OPENGL_LIBRARIES}
|
|
||||||
# ${CMAKE_DL_LIBS}
|
|
||||||
# delta-service
|
|
||||||
# asar-static
|
|
||||||
# ImGui
|
|
||||||
# )
|
|
||||||
# target_compile_definitions(yaze_delta PRIVATE "linux")
|
|
||||||
# target_compile_definitions(yaze_delta PRIVATE "stricmp=strcasecmp")
|
|
||||||
|
|
||||||
# set (source "${CMAKE_SOURCE_DIR}/assets")
|
# Create the core library (static for testing)
|
||||||
# set (destination "${CMAKE_CURRENT_BINARY_DIR}/assets")
|
add_library(yaze_core STATIC ${YAZE_CORE_SOURCES})
|
||||||
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
|
|
||||||
# COMMAND ${CMAKE_COMMAND} -E create_symlink ${source} ${destination}
|
# Create the full C API library (static for CI, shared for release)
|
||||||
# DEPENDS ${destination}
|
if(YAZE_MINIMAL_BUILD)
|
||||||
# COMMENT "symbolic link resources folder from ${source} => ${destination}")
|
add_library(yaze_c STATIC ${YAZE_C_SOURCES})
|
||||||
|
else()
|
||||||
|
add_library(yaze_c SHARED ${YAZE_C_SOURCES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Configure core library (for testing)
|
||||||
|
target_include_directories(
|
||||||
|
yaze_core PUBLIC
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/app/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
|
||||||
|
${CMAKE_SOURCE_DIR}/incl/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/imgui
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
|
||||||
|
${SDL2_INCLUDE_DIR}
|
||||||
|
${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
yaze_core PUBLIC
|
||||||
|
asar-static
|
||||||
|
${ABSL_TARGETS}
|
||||||
|
${SDL_TARGETS}
|
||||||
|
${CMAKE_DL_LIBS}
|
||||||
|
ImGui
|
||||||
|
)
|
||||||
|
|
||||||
|
# Configure full C API library
|
||||||
|
target_include_directories(
|
||||||
|
yaze_c PUBLIC
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/app/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
|
||||||
|
${CMAKE_SOURCE_DIR}/incl/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
|
||||||
|
${SDL2_INCLUDE_DIR}
|
||||||
|
${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conditionally add PNG include dirs if available
|
||||||
|
if(PNG_FOUND)
|
||||||
|
target_include_directories(yaze_c PUBLIC ${PNG_INCLUDE_DIRS})
|
||||||
|
target_include_directories(yaze_core PUBLIC ${PNG_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
yaze_c PRIVATE
|
||||||
|
yaze_core
|
||||||
|
ImGui
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conditionally link ImGui Test Engine and set definitions
|
||||||
|
if(YAZE_ENABLE_UI_TESTS AND TARGET ImGuiTestEngine)
|
||||||
|
target_link_libraries(yaze_c PRIVATE ImGuiTestEngine)
|
||||||
|
target_compile_definitions(yaze_c PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(yaze_c PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Conditionally link PNG if available
|
||||||
|
if(PNG_FOUND)
|
||||||
|
target_link_libraries(yaze_c PRIVATE ${PNG_LIBRARIES})
|
||||||
|
target_link_libraries(yaze_core PRIVATE ${PNG_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (YAZE_INSTALL_LIB)
|
||||||
|
install(TARGETS yaze_c
|
||||||
|
RUNTIME DESTINATION bin
|
||||||
|
LIBRARY DESTINATION lib
|
||||||
|
ARCHIVE DESTINATION lib/static)
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES
|
||||||
|
incl/yaze.h
|
||||||
|
incl/zelda.h
|
||||||
|
DESTINATION
|
||||||
|
include
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|||||||
127
src/app/app.cmake
Normal file
127
src/app/app.cmake
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
include(app/core/core.cmake)
|
||||||
|
include(app/editor/editor.cmake)
|
||||||
|
include(app/gfx/gfx.cmake)
|
||||||
|
include(app/gui/gui.cmake)
|
||||||
|
include(app/zelda3/zelda3.cmake)
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
add_executable(
|
||||||
|
yaze
|
||||||
|
MACOSX_BUNDLE
|
||||||
|
app/main.cc
|
||||||
|
app/rom.cc
|
||||||
|
${YAZE_APP_EMU_SRC}
|
||||||
|
${YAZE_APP_CORE_SRC}
|
||||||
|
${YAZE_APP_EDITOR_SRC}
|
||||||
|
${YAZE_APP_GFX_SRC}
|
||||||
|
${YAZE_APP_ZELDA3_SRC}
|
||||||
|
${YAZE_UTIL_SRC}
|
||||||
|
${YAZE_GUI_SRC}
|
||||||
|
${IMGUI_SRC}
|
||||||
|
# Bundled Resources
|
||||||
|
${YAZE_RESOURCE_FILES}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add the app icon to the macOS bundle
|
||||||
|
set(ICON_FILE "${CMAKE_SOURCE_DIR}/assets/yaze.icns")
|
||||||
|
target_sources(yaze PRIVATE ${ICON_FILE})
|
||||||
|
set_source_files_properties(${ICON_FILE} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||||
|
|
||||||
|
# Set macOS bundle properties
|
||||||
|
set_target_properties(yaze PROPERTIES
|
||||||
|
MACOSX_BUNDLE_ICON_FILE "yaze.icns"
|
||||||
|
MACOSX_BUNDLE_BUNDLE_NAME "Yaze"
|
||||||
|
MACOSX_BUNDLE_EXECUTABLE_NAME "yaze"
|
||||||
|
MACOSX_BUNDLE_GUI_IDENTIFIER "com.scawful.yaze"
|
||||||
|
MACOSX_BUNDLE_INFO_STRING "Yet Another Zelda3 Editor"
|
||||||
|
MACOSX_BUNDLE_LONG_VERSION_STRING "${PROJECT_VERSION}"
|
||||||
|
MACOSX_BUNDLE_SHORT_VERSION_STRING "${PROJECT_VERSION}"
|
||||||
|
MACOSX_BUNDLE_BUNDLE_VERSION "${PROJECT_VERSION}"
|
||||||
|
MACOSX_BUNDLE_COPYRIGHT "Copyright © 2024 scawful. All rights reserved."
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
add_executable(
|
||||||
|
yaze
|
||||||
|
app/main.cc
|
||||||
|
app/rom.cc
|
||||||
|
${YAZE_APP_EMU_SRC}
|
||||||
|
${YAZE_APP_CORE_SRC}
|
||||||
|
${YAZE_APP_EDITOR_SRC}
|
||||||
|
${YAZE_APP_GFX_SRC}
|
||||||
|
${YAZE_APP_ZELDA3_SRC}
|
||||||
|
${YAZE_UTIL_SRC}
|
||||||
|
${YAZE_GUI_SRC}
|
||||||
|
${IMGUI_SRC}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(
|
||||||
|
yaze PUBLIC
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/app/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/asar/src/asar-dll-bindings/c
|
||||||
|
${CMAKE_SOURCE_DIR}/incl/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/
|
||||||
|
${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine
|
||||||
|
${SDL2_INCLUDE_DIR}
|
||||||
|
${PROJECT_BINARY_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conditionally add PNG include dirs if available
|
||||||
|
if(PNG_FOUND)
|
||||||
|
target_include_directories(yaze PUBLIC ${PNG_INCLUDE_DIRS})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Conditionally link nfd if available
|
||||||
|
if(YAZE_HAS_NFD)
|
||||||
|
target_link_libraries(yaze PRIVATE nfd)
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_NFD=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_NFD=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries(
|
||||||
|
yaze PUBLIC
|
||||||
|
asar-static
|
||||||
|
${ABSL_TARGETS}
|
||||||
|
${SDL_TARGETS}
|
||||||
|
${CMAKE_DL_LIBS}
|
||||||
|
ImGui
|
||||||
|
)
|
||||||
|
|
||||||
|
# Conditionally link ImGui Test Engine
|
||||||
|
if(YAZE_ENABLE_UI_TESTS)
|
||||||
|
if(TARGET ImGuiTestEngine)
|
||||||
|
target_include_directories(yaze PUBLIC ${CMAKE_SOURCE_DIR}/src/lib/imgui_test_engine)
|
||||||
|
target_link_libraries(yaze PUBLIC ImGuiTestEngine)
|
||||||
|
target_compile_definitions(yaze PRIVATE
|
||||||
|
YAZE_ENABLE_IMGUI_TEST_ENGINE=1
|
||||||
|
${IMGUI_TEST_ENGINE_DEFINITIONS})
|
||||||
|
else()
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_IMGUI_TEST_ENGINE=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Link Google Test if available for integrated testing (but NOT gtest_main to avoid main() conflicts)
|
||||||
|
if(YAZE_BUILD_TESTS AND TARGET gtest)
|
||||||
|
target_link_libraries(yaze PRIVATE gtest)
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_GTEST=1)
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_TESTING=1)
|
||||||
|
else()
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_GTEST=0)
|
||||||
|
target_compile_definitions(yaze PRIVATE YAZE_ENABLE_TESTING=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Conditionally link PNG if available
|
||||||
|
if(PNG_FOUND)
|
||||||
|
target_link_libraries(yaze PUBLIC ${PNG_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (APPLE)
|
||||||
|
target_link_libraries(yaze PUBLIC ${COCOA_LIBRARY})
|
||||||
|
endif()
|
||||||
|
|
||||||
297
src/app/core/asar_wrapper.cc
Normal file
297
src/app/core/asar_wrapper.cc
Normal file
@@ -0,0 +1,297 @@
|
|||||||
|
#include "app/core/asar_wrapper.h"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
|
#include "absl/strings/str_format.h"
|
||||||
|
#include "absl/strings/str_join.h"
|
||||||
|
|
||||||
|
// Include Asar C bindings
|
||||||
|
#include "asar-dll-bindings/c/asar.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
AsarWrapper::AsarWrapper() : initialized_(false) {}
|
||||||
|
|
||||||
|
AsarWrapper::~AsarWrapper() {
|
||||||
|
if (initialized_) {
|
||||||
|
Shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status AsarWrapper::Initialize() {
|
||||||
|
if (initialized_) {
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify API version compatibility
|
||||||
|
int api_version = asar_apiversion();
|
||||||
|
if (api_version < 300) { // Require at least API version 3.0
|
||||||
|
return absl::InternalError(absl::StrFormat(
|
||||||
|
"Asar API version %d is too old (required: 300+)", api_version));
|
||||||
|
}
|
||||||
|
|
||||||
|
initialized_ = true;
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsarWrapper::Shutdown() {
|
||||||
|
if (initialized_) {
|
||||||
|
// Note: Static library doesn't have asar_close()
|
||||||
|
initialized_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AsarWrapper::GetVersion() const {
|
||||||
|
if (!initialized_) {
|
||||||
|
return "Not initialized";
|
||||||
|
}
|
||||||
|
|
||||||
|
int version = asar_version();
|
||||||
|
int major = version / 10000;
|
||||||
|
int minor = (version / 100) % 100;
|
||||||
|
int patch = version % 100;
|
||||||
|
|
||||||
|
return absl::StrFormat("%d.%d.%d", major, minor, patch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int AsarWrapper::GetApiVersion() const {
|
||||||
|
if (!initialized_) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return asar_apiversion();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<AsarPatchResult> AsarWrapper::ApplyPatch(
|
||||||
|
const std::string& patch_path,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::vector<std::string>& include_paths) {
|
||||||
|
|
||||||
|
if (!initialized_) {
|
||||||
|
return absl::FailedPreconditionError("Asar not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset previous state
|
||||||
|
Reset();
|
||||||
|
|
||||||
|
AsarPatchResult result;
|
||||||
|
result.success = false;
|
||||||
|
|
||||||
|
// Prepare ROM data
|
||||||
|
int rom_size = static_cast<int>(rom_data.size());
|
||||||
|
int buffer_size = std::max(rom_size, 16 * 1024 * 1024); // At least 16MB buffer
|
||||||
|
|
||||||
|
// Resize ROM data if needed
|
||||||
|
if (rom_data.size() < buffer_size) {
|
||||||
|
rom_data.resize(buffer_size, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the patch
|
||||||
|
bool patch_success = asar_patch(
|
||||||
|
patch_path.c_str(),
|
||||||
|
reinterpret_cast<char*>(rom_data.data()),
|
||||||
|
buffer_size,
|
||||||
|
&rom_size);
|
||||||
|
|
||||||
|
// Process results
|
||||||
|
ProcessErrors();
|
||||||
|
ProcessWarnings();
|
||||||
|
|
||||||
|
result.errors = last_errors_;
|
||||||
|
result.warnings = last_warnings_;
|
||||||
|
result.success = patch_success && last_errors_.empty();
|
||||||
|
|
||||||
|
if (result.success) {
|
||||||
|
// Resize ROM data to actual size
|
||||||
|
rom_data.resize(rom_size);
|
||||||
|
result.rom_size = rom_size;
|
||||||
|
|
||||||
|
// Extract symbols
|
||||||
|
ExtractSymbolsFromLastOperation();
|
||||||
|
result.symbols.reserve(symbol_table_.size());
|
||||||
|
for (const auto& [name, symbol] : symbol_table_) {
|
||||||
|
result.symbols.push_back(symbol);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate CRC32 if available
|
||||||
|
// Note: Asar might provide this, check if function exists
|
||||||
|
result.crc32 = 0; // TODO: Implement CRC32 calculation
|
||||||
|
} else {
|
||||||
|
return absl::InternalError(absl::StrFormat(
|
||||||
|
"Patch failed: %s", absl::StrJoin(last_errors_, "; ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<AsarPatchResult> AsarWrapper::ApplyPatchFromString(
|
||||||
|
const std::string& patch_content,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::string& base_path) {
|
||||||
|
|
||||||
|
// Create temporary file for patch content
|
||||||
|
std::string temp_path = "/tmp/yaze_temp_patch.asm";
|
||||||
|
if (!base_path.empty()) {
|
||||||
|
// Ensure directory exists
|
||||||
|
std::filesystem::create_directories(base_path);
|
||||||
|
temp_path = base_path + "/temp_patch.asm";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ofstream temp_file(temp_path);
|
||||||
|
if (!temp_file) {
|
||||||
|
return absl::InternalError(absl::StrFormat(
|
||||||
|
"Failed to create temporary patch file at: %s", temp_path));
|
||||||
|
}
|
||||||
|
|
||||||
|
temp_file << patch_content;
|
||||||
|
temp_file.close();
|
||||||
|
|
||||||
|
auto result = ApplyPatch(temp_path, rom_data);
|
||||||
|
|
||||||
|
// Clean up temporary file
|
||||||
|
std::remove(temp_path.c_str());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::StatusOr<std::vector<AsarSymbol>> AsarWrapper::ExtractSymbols(
|
||||||
|
const std::string& asm_path,
|
||||||
|
const std::vector<std::string>& include_paths) {
|
||||||
|
|
||||||
|
if (!initialized_) {
|
||||||
|
return absl::FailedPreconditionError("Asar not initialized");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a dummy ROM for symbol extraction
|
||||||
|
std::vector<uint8_t> dummy_rom(1024 * 1024, 0); // 1MB dummy ROM
|
||||||
|
|
||||||
|
auto result = ApplyPatch(asm_path, dummy_rom, include_paths);
|
||||||
|
if (!result.ok()) {
|
||||||
|
return result.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result->symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, AsarSymbol> AsarWrapper::GetSymbolTable() const {
|
||||||
|
return symbol_table_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<AsarSymbol> AsarWrapper::FindSymbol(const std::string& name) const {
|
||||||
|
auto it = symbol_table_.find(name);
|
||||||
|
if (it != symbol_table_.end()) {
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<AsarSymbol> AsarWrapper::GetSymbolsAtAddress(uint32_t address) const {
|
||||||
|
std::vector<AsarSymbol> symbols;
|
||||||
|
for (const auto& [name, symbol] : symbol_table_) {
|
||||||
|
if (symbol.address == address) {
|
||||||
|
symbols.push_back(symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return symbols;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsarWrapper::Reset() {
|
||||||
|
if (initialized_) {
|
||||||
|
asar_reset();
|
||||||
|
}
|
||||||
|
symbol_table_.clear();
|
||||||
|
last_errors_.clear();
|
||||||
|
last_warnings_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status AsarWrapper::CreatePatch(
|
||||||
|
const std::vector<uint8_t>& original_rom,
|
||||||
|
const std::vector<uint8_t>& modified_rom,
|
||||||
|
const std::string& patch_path) {
|
||||||
|
|
||||||
|
// This is a complex operation that would require:
|
||||||
|
// 1. Analyzing differences between ROMs
|
||||||
|
// 2. Generating appropriate assembly code
|
||||||
|
// 3. Writing the patch file
|
||||||
|
|
||||||
|
// For now, return not implemented
|
||||||
|
return absl::UnimplementedError(
|
||||||
|
"Patch creation from ROM differences not yet implemented");
|
||||||
|
}
|
||||||
|
|
||||||
|
absl::Status AsarWrapper::ValidateAssembly(const std::string& asm_path) {
|
||||||
|
// Create a dummy ROM for validation
|
||||||
|
std::vector<uint8_t> dummy_rom(1024, 0);
|
||||||
|
|
||||||
|
auto result = ApplyPatch(asm_path, dummy_rom);
|
||||||
|
if (!result.ok()) {
|
||||||
|
return result.status();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!result->success) {
|
||||||
|
return absl::InvalidArgumentError(absl::StrFormat(
|
||||||
|
"Assembly validation failed: %s",
|
||||||
|
absl::StrJoin(result->errors, "; ")));
|
||||||
|
}
|
||||||
|
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsarWrapper::ProcessErrors() {
|
||||||
|
last_errors_.clear();
|
||||||
|
|
||||||
|
int error_count = 0;
|
||||||
|
const errordata* errors = asar_geterrors(&error_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < error_count; ++i) {
|
||||||
|
last_errors_.push_back(std::string(errors[i].fullerrdata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsarWrapper::ProcessWarnings() {
|
||||||
|
last_warnings_.clear();
|
||||||
|
|
||||||
|
int warning_count = 0;
|
||||||
|
const errordata* warnings = asar_getwarnings(&warning_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < warning_count; ++i) {
|
||||||
|
last_warnings_.push_back(std::string(warnings[i].fullerrdata));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AsarWrapper::ExtractSymbolsFromLastOperation() {
|
||||||
|
symbol_table_.clear();
|
||||||
|
|
||||||
|
// Extract labels using the correct API function
|
||||||
|
int symbol_count = 0;
|
||||||
|
const labeldata* labels = asar_getalllabels(&symbol_count);
|
||||||
|
|
||||||
|
for (int i = 0; i < symbol_count; ++i) {
|
||||||
|
AsarSymbol symbol;
|
||||||
|
symbol.name = std::string(labels[i].name);
|
||||||
|
symbol.address = labels[i].location;
|
||||||
|
symbol.file = ""; // Not available in basic API
|
||||||
|
symbol.line = 0; // Not available in basic API
|
||||||
|
symbol.opcode = ""; // Would need additional processing
|
||||||
|
symbol.comment = "";
|
||||||
|
|
||||||
|
symbol_table_[symbol.name] = symbol;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AsarSymbol AsarWrapper::ConvertAsarSymbol(const void* asar_symbol_data) const {
|
||||||
|
// This would convert from Asar's internal symbol representation
|
||||||
|
// to our AsarSymbol struct. Implementation depends on Asar's API.
|
||||||
|
|
||||||
|
AsarSymbol symbol;
|
||||||
|
// Placeholder implementation
|
||||||
|
return symbol;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
212
src/app/core/asar_wrapper.h
Normal file
212
src/app/core/asar_wrapper.h
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
#ifndef YAZE_APP_CORE_ASAR_WRAPPER_H
|
||||||
|
#define YAZE_APP_CORE_ASAR_WRAPPER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
|
#include "absl/status/status.h"
|
||||||
|
#include "absl/status/statusor.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace app {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Symbol information extracted from Asar assembly
|
||||||
|
*/
|
||||||
|
struct AsarSymbol {
|
||||||
|
std::string name; // Symbol name
|
||||||
|
uint32_t address; // Memory address
|
||||||
|
std::string opcode; // Associated opcode if available
|
||||||
|
std::string file; // Source file
|
||||||
|
int line; // Line number in source
|
||||||
|
std::string comment; // Optional comment
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Asar patch result information
|
||||||
|
*/
|
||||||
|
struct AsarPatchResult {
|
||||||
|
bool success; // Whether patch was successful
|
||||||
|
std::vector<std::string> errors; // Error messages if any
|
||||||
|
std::vector<std::string> warnings; // Warning messages
|
||||||
|
std::vector<AsarSymbol> symbols; // Extracted symbols
|
||||||
|
uint32_t rom_size; // Final ROM size after patching
|
||||||
|
uint32_t crc32; // CRC32 checksum of patched ROM
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Modern C++ wrapper for Asar 65816 assembler integration
|
||||||
|
*
|
||||||
|
* This class provides a high-level interface for:
|
||||||
|
* - Patching ROMs with assembly code
|
||||||
|
* - Extracting symbol names and opcodes
|
||||||
|
* - Cross-platform compatibility (Windows, macOS, Linux)
|
||||||
|
*/
|
||||||
|
class AsarWrapper {
|
||||||
|
public:
|
||||||
|
AsarWrapper();
|
||||||
|
~AsarWrapper();
|
||||||
|
|
||||||
|
// Disable copy constructor and assignment
|
||||||
|
AsarWrapper(const AsarWrapper&) = delete;
|
||||||
|
AsarWrapper& operator=(const AsarWrapper&) = delete;
|
||||||
|
|
||||||
|
// Enable move constructor and assignment
|
||||||
|
AsarWrapper(AsarWrapper&&) = default;
|
||||||
|
AsarWrapper& operator=(AsarWrapper&&) = default;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the Asar library
|
||||||
|
* @return Status indicating success or failure
|
||||||
|
*/
|
||||||
|
absl::Status Initialize();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clean up and close the Asar library
|
||||||
|
*/
|
||||||
|
void Shutdown();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if Asar is initialized and ready
|
||||||
|
* @return True if initialized, false otherwise
|
||||||
|
*/
|
||||||
|
bool IsInitialized() const { return initialized_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get Asar version information
|
||||||
|
* @return Version string
|
||||||
|
*/
|
||||||
|
std::string GetVersion() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get Asar API version
|
||||||
|
* @return API version number
|
||||||
|
*/
|
||||||
|
int GetApiVersion() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply an assembly patch to a ROM
|
||||||
|
* @param patch_path Path to the .asm patch file
|
||||||
|
* @param rom_data ROM data to patch (will be modified)
|
||||||
|
* @param include_paths Additional include paths for assembly files
|
||||||
|
* @return Patch result with status and extracted information
|
||||||
|
*/
|
||||||
|
absl::StatusOr<AsarPatchResult> ApplyPatch(
|
||||||
|
const std::string& patch_path,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::vector<std::string>& include_paths = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Apply an assembly patch from string content
|
||||||
|
* @param patch_content Assembly source code as string
|
||||||
|
* @param rom_data ROM data to patch (will be modified)
|
||||||
|
* @param base_path Base path for resolving includes
|
||||||
|
* @return Patch result with status and extracted information
|
||||||
|
*/
|
||||||
|
absl::StatusOr<AsarPatchResult> ApplyPatchFromString(
|
||||||
|
const std::string& patch_content,
|
||||||
|
std::vector<uint8_t>& rom_data,
|
||||||
|
const std::string& base_path = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extract symbols from an assembly file without patching
|
||||||
|
* @param asm_path Path to the assembly file
|
||||||
|
* @param include_paths Additional include paths
|
||||||
|
* @return Vector of extracted symbols
|
||||||
|
*/
|
||||||
|
absl::StatusOr<std::vector<AsarSymbol>> ExtractSymbols(
|
||||||
|
const std::string& asm_path,
|
||||||
|
const std::vector<std::string>& include_paths = {});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get all available symbols from the last patch operation
|
||||||
|
* @return Map of symbol names to symbol information
|
||||||
|
*/
|
||||||
|
std::map<std::string, AsarSymbol> GetSymbolTable() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Find a symbol by name
|
||||||
|
* @param name Symbol name to search for
|
||||||
|
* @return Symbol information if found
|
||||||
|
*/
|
||||||
|
std::optional<AsarSymbol> FindSymbol(const std::string& name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get symbols at a specific address
|
||||||
|
* @param address Memory address to search
|
||||||
|
* @return Vector of symbols at that address
|
||||||
|
*/
|
||||||
|
std::vector<AsarSymbol> GetSymbolsAtAddress(uint32_t address) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Reset the Asar state (clear errors, warnings, symbols)
|
||||||
|
*/
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the last error messages
|
||||||
|
* @return Vector of error strings
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetLastErrors() const { return last_errors_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the last warning messages
|
||||||
|
* @return Vector of warning strings
|
||||||
|
*/
|
||||||
|
std::vector<std::string> GetLastWarnings() const { return last_warnings_; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Create a patch that can be applied to transform one ROM to another
|
||||||
|
* @param original_rom Original ROM data
|
||||||
|
* @param modified_rom Modified ROM data
|
||||||
|
* @param patch_path Output path for the generated patch
|
||||||
|
* @return Status indicating success or failure
|
||||||
|
*/
|
||||||
|
absl::Status CreatePatch(
|
||||||
|
const std::vector<uint8_t>& original_rom,
|
||||||
|
const std::vector<uint8_t>& modified_rom,
|
||||||
|
const std::string& patch_path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Validate an assembly file for syntax errors
|
||||||
|
* @param asm_path Path to the assembly file
|
||||||
|
* @return Status indicating validation result
|
||||||
|
*/
|
||||||
|
absl::Status ValidateAssembly(const std::string& asm_path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool initialized_;
|
||||||
|
std::map<std::string, AsarSymbol> symbol_table_;
|
||||||
|
std::vector<std::string> last_errors_;
|
||||||
|
std::vector<std::string> last_warnings_;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process errors from Asar and store them
|
||||||
|
*/
|
||||||
|
void ProcessErrors();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Process warnings from Asar and store them
|
||||||
|
*/
|
||||||
|
void ProcessWarnings();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Extract symbols from the last Asar operation
|
||||||
|
*/
|
||||||
|
void ExtractSymbolsFromLastOperation();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Convert Asar symbol data to AsarSymbol struct
|
||||||
|
*/
|
||||||
|
AsarSymbol ConvertAsarSymbol(const void* asar_symbol_data) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace app
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_CORE_ASAR_WRAPPER_H
|
||||||
@@ -1,63 +0,0 @@
|
|||||||
#include "common.h"
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace core {
|
|
||||||
|
|
||||||
unsigned int SnesToPc(unsigned int addr) {
|
|
||||||
if (addr >= 0x808000) {
|
|
||||||
addr -= 0x808000;
|
|
||||||
}
|
|
||||||
unsigned int temp = (addr & 0x7FFF) + ((addr / 2) & 0xFF8000);
|
|
||||||
return (temp + 0x0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int AddressFromBytes(uint8_t addr1, uint8_t addr2, uint8_t addr3) {
|
|
||||||
return (addr1 << 16) | (addr2 << 8) | addr3;
|
|
||||||
}
|
|
||||||
|
|
||||||
// hextodec has been imported from SNESDisasm to parse hex numbers
|
|
||||||
int HexToDec(char *input, int length) {
|
|
||||||
int result = 0;
|
|
||||||
int value;
|
|
||||||
int ceiling = length - 1;
|
|
||||||
int power16 = 16;
|
|
||||||
|
|
||||||
int j = ceiling;
|
|
||||||
|
|
||||||
for (; j >= 0; j--) {
|
|
||||||
if (input[j] >= 'A' && input[j] <= 'F') {
|
|
||||||
value = input[j] - 'F';
|
|
||||||
value += 15;
|
|
||||||
} else {
|
|
||||||
value = input[j] - '9';
|
|
||||||
value += 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == ceiling) {
|
|
||||||
result += value;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
result += (value * power16);
|
|
||||||
power16 *= 16;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool StringReplace(std::string &str, const std::string &from,
|
|
||||||
const std::string &to) {
|
|
||||||
size_t start = str.find(from);
|
|
||||||
if (start == std::string::npos) return false;
|
|
||||||
|
|
||||||
str.replace(start, from.length(), to);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace core
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef YAZE_CORE_COMMON_H
|
|
||||||
#define YAZE_CORE_COMMON_H
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
namespace yaze {
|
|
||||||
namespace app {
|
|
||||||
namespace core {
|
|
||||||
|
|
||||||
unsigned int SnesToPc(unsigned int addr);
|
|
||||||
int AddressFromBytes(uint8_t addr1, uint8_t addr2, uint8_t addr3);
|
|
||||||
int HexToDec(char *input, int length);
|
|
||||||
bool StringReplace(std::string &str, const std::string &from,
|
|
||||||
const std::string &to);
|
|
||||||
|
|
||||||
} // namespace core
|
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,229 +1,83 @@
|
|||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <SDL_mixer.h>
|
|
||||||
#include <imgui/backends/imgui_impl_sdl.h>
|
|
||||||
#include <imgui/backends/imgui_impl_sdlrenderer.h>
|
|
||||||
#include <imgui/imgui.h>
|
|
||||||
#include <imgui/imgui_internal.h>
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "absl/strings/str_format.h"
|
#include "app/core/window.h"
|
||||||
#include "app/editor/master_editor.h"
|
#include "app/editor/editor_manager.h"
|
||||||
#include "gui/icons.h"
|
#include "app/gui/background_renderer.h"
|
||||||
#include "gui/style.h"
|
#include "app/gui/theme_manager.h"
|
||||||
|
#include "imgui/backends/imgui_impl_sdl2.h"
|
||||||
|
#include "imgui/backends/imgui_impl_sdlrenderer2.h"
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
namespace {
|
absl::Status Controller::OnEntry(std::string filename) {
|
||||||
|
RETURN_IF_ERROR(CreateWindow(window_, SDL_WINDOW_RESIZABLE));
|
||||||
void InitializeKeymap() {
|
editor_manager_.emulator().set_audio_buffer(window_.audio_buffer_.get());
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
editor_manager_.emulator().set_audio_device_id(window_.audio_device_);
|
||||||
io.KeyMap[ImGuiKey_Backspace] = SDL_GetScancodeFromKey(SDLK_BACKSPACE);
|
editor_manager_.Initialize(filename);
|
||||||
io.KeyMap[ImGuiKey_LeftShift] = SDL_GetScancodeFromKey(SDLK_LSHIFT);
|
|
||||||
io.KeyMap[ImGuiKey_Enter] = SDL_GetScancodeFromKey(SDLK_RETURN);
|
|
||||||
io.KeyMap[ImGuiKey_UpArrow] = SDL_GetScancodeFromKey(SDLK_UP);
|
|
||||||
io.KeyMap[ImGuiKey_DownArrow] = SDL_GetScancodeFromKey(SDLK_DOWN);
|
|
||||||
io.KeyMap[ImGuiKey_Tab] = SDL_GetScancodeFromKey(SDLK_TAB);
|
|
||||||
io.KeyMap[ImGuiKey_LeftCtrl] = SDL_GetScancodeFromKey(SDLK_LCTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleKeyDown(SDL_Event &event) {
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
|
||||||
switch (event.key.keysym.sym) {
|
|
||||||
case SDLK_UP:
|
|
||||||
case SDLK_DOWN:
|
|
||||||
case SDLK_RETURN:
|
|
||||||
case SDLK_BACKSPACE:
|
|
||||||
case SDLK_LSHIFT:
|
|
||||||
case SDLK_LCTRL:
|
|
||||||
case SDLK_TAB:
|
|
||||||
io.KeysDown[event.key.keysym.scancode] = (event.type == SDL_KEYDOWN);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleKeyUp(SDL_Event &event) {
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
|
||||||
int key = event.key.keysym.scancode;
|
|
||||||
IM_ASSERT(key >= 0 && key < IM_ARRAYSIZE(io.KeysDown));
|
|
||||||
io.KeysDown[key] = (event.type == SDL_KEYDOWN);
|
|
||||||
io.KeyShift = ((SDL_GetModState() & KMOD_SHIFT) != 0);
|
|
||||||
io.KeyCtrl = ((SDL_GetModState() & KMOD_CTRL) != 0);
|
|
||||||
io.KeyAlt = ((SDL_GetModState() & KMOD_ALT) != 0);
|
|
||||||
io.KeySuper = ((SDL_GetModState() & KMOD_GUI) != 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ChangeWindowSizeEvent(SDL_Event &event) {
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
|
||||||
io.DisplaySize.x = static_cast<float>(event.window.data1);
|
|
||||||
io.DisplaySize.y = static_cast<float>(event.window.data2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void HandleMouseMovement(int &wheel) {
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
|
||||||
int mouseX;
|
|
||||||
int mouseY;
|
|
||||||
const int buttons = SDL_GetMouseState(&mouseX, &mouseY);
|
|
||||||
|
|
||||||
io.DeltaTime = 1.0f / 60.0f;
|
|
||||||
io.MousePos = ImVec2(static_cast<float>(mouseX), static_cast<float>(mouseY));
|
|
||||||
io.MouseDown[0] = buttons & SDL_BUTTON(SDL_BUTTON_LEFT);
|
|
||||||
io.MouseDown[1] = buttons & SDL_BUTTON(SDL_BUTTON_RIGHT);
|
|
||||||
io.MouseWheel = static_cast<float>(wheel);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool Controller::isActive() const { return active_; }
|
|
||||||
|
|
||||||
absl::Status Controller::onEntry() {
|
|
||||||
RETURN_IF_ERROR(CreateWindow())
|
|
||||||
RETURN_IF_ERROR(CreateRenderer())
|
|
||||||
RETURN_IF_ERROR(CreateGuiContext())
|
|
||||||
InitializeKeymap();
|
|
||||||
master_editor_.SetupScreen(renderer_);
|
|
||||||
active_ = true;
|
active_ = true;
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::onInput() {
|
void Controller::OnInput() {
|
||||||
int wheel = 0;
|
PRINT_IF_ERROR(HandleEvents(window_));
|
||||||
SDL_Event event;
|
|
||||||
ImGuiIO &io = ImGui::GetIO();
|
|
||||||
|
|
||||||
while (SDL_PollEvent(&event)) {
|
|
||||||
switch (event.type) {
|
|
||||||
case SDL_KEYDOWN:
|
|
||||||
HandleKeyDown(event);
|
|
||||||
break;
|
|
||||||
case SDL_KEYUP:
|
|
||||||
HandleKeyUp(event);
|
|
||||||
break;
|
|
||||||
case SDL_TEXTINPUT:
|
|
||||||
io.AddInputCharactersUTF8(event.text.text);
|
|
||||||
break;
|
|
||||||
case SDL_MOUSEWHEEL:
|
|
||||||
wheel = event.wheel.y;
|
|
||||||
break;
|
|
||||||
case SDL_WINDOWEVENT:
|
|
||||||
switch (event.window.event) {
|
|
||||||
case SDL_WINDOWEVENT_CLOSE:
|
|
||||||
CloseWindow();
|
|
||||||
break;
|
|
||||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
|
||||||
ChangeWindowSizeEvent(event);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleMouseMovement(wheel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::onLoad() { master_editor_.UpdateScreen(); }
|
absl::Status Controller::OnLoad() {
|
||||||
|
if (editor_manager_.quit() || !window_.active_) {
|
||||||
|
active_ = false;
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::doRender() const {
|
#if TARGET_OS_IPHONE != 1
|
||||||
SDL_RenderClear(renderer_.get());
|
ImGui_ImplSDLRenderer2_NewFrame();
|
||||||
|
ImGui_ImplSDL2_NewFrame();
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
const ImGuiViewport *viewport = ImGui::GetMainViewport();
|
||||||
|
ImGui::SetNextWindowPos(viewport->WorkPos);
|
||||||
|
ImGui::SetNextWindowSize(viewport->WorkSize);
|
||||||
|
ImGui::SetNextWindowViewport(viewport->ID);
|
||||||
|
|
||||||
|
ImGuiWindowFlags window_flags =
|
||||||
|
ImGuiWindowFlags_MenuBar | ImGuiWindowFlags_NoDocking;
|
||||||
|
window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse |
|
||||||
|
ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove;
|
||||||
|
window_flags |=
|
||||||
|
ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoNavFocus;
|
||||||
|
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowBorderSize, 0.0f);
|
||||||
|
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||||
|
ImGui::Begin("DockSpaceWindow", nullptr, window_flags);
|
||||||
|
ImGui::PopStyleVar(3);
|
||||||
|
|
||||||
|
// Create DockSpace first
|
||||||
|
ImGuiID dockspace_id = ImGui::GetID("MyDockSpace");
|
||||||
|
gui::DockSpaceRenderer::BeginEnhancedDockSpace(dockspace_id, ImVec2(0.0f, 0.0f),
|
||||||
|
ImGuiDockNodeFlags_PassthruCentralNode);
|
||||||
|
|
||||||
|
editor_manager_.DrawMenuBar(); // Draw the fixed menu bar at the top
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
#endif
|
||||||
|
RETURN_IF_ERROR(editor_manager_.Update());
|
||||||
|
return absl::OkStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::DoRender() const {
|
||||||
ImGui::Render();
|
ImGui::Render();
|
||||||
ImGui_ImplSDLRenderer_RenderDrawData(ImGui::GetDrawData());
|
SDL_RenderClear(Renderer::Get().renderer());
|
||||||
SDL_RenderPresent(renderer_.get());
|
ImGui_ImplSDLRenderer2_RenderDrawData(ImGui::GetDrawData(),
|
||||||
|
Renderer::Get().renderer());
|
||||||
|
SDL_RenderPresent(Renderer::Get().renderer());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::onExit() const {
|
void Controller::OnExit() { PRINT_IF_ERROR(ShutdownWindow(window_)); }
|
||||||
ImGui_ImplSDLRenderer_Shutdown();
|
|
||||||
ImGui_ImplSDL2_Shutdown();
|
|
||||||
ImGui::DestroyContext();
|
|
||||||
SDL_Quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status Controller::CreateWindow() {
|
|
||||||
if (SDL_Init(SDL_INIT_EVERYTHING) != 0) {
|
|
||||||
return absl::InternalError(
|
|
||||||
absl::StrFormat("SDL_Init: %s\n", SDL_GetError()));
|
|
||||||
} else {
|
|
||||||
window_ = std::unique_ptr<SDL_Window, sdl_deleter>(
|
|
||||||
SDL_CreateWindow("Yet Another Zelda3 Editor", // window title
|
|
||||||
SDL_WINDOWPOS_UNDEFINED, // initial x position
|
|
||||||
SDL_WINDOWPOS_UNDEFINED, // initial y position
|
|
||||||
kScreenWidth, // width, in pixels
|
|
||||||
kScreenHeight, // height, in pixels
|
|
||||||
SDL_WINDOW_RESIZABLE),
|
|
||||||
sdl_deleter());
|
|
||||||
if (window_ == nullptr) {
|
|
||||||
return absl::InternalError(
|
|
||||||
absl::StrFormat("SDL_CreateWindow: %s\n", SDL_GetError()));
|
|
||||||
}
|
|
||||||
// Initialize SDL_mixer
|
|
||||||
if (Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048) < 0) {
|
|
||||||
printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n",
|
|
||||||
Mix_GetError());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status Controller::CreateRenderer() {
|
|
||||||
renderer_ = std::unique_ptr<SDL_Renderer, sdl_deleter>(
|
|
||||||
SDL_CreateRenderer(window_.get(), -1,
|
|
||||||
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC),
|
|
||||||
sdl_deleter());
|
|
||||||
if (renderer_ == nullptr) {
|
|
||||||
return absl::InternalError(
|
|
||||||
absl::StrFormat("SDL_CreateRenderer: %s\n", SDL_GetError()));
|
|
||||||
} else {
|
|
||||||
SDL_SetRenderDrawBlendMode(renderer_.get(), SDL_BLENDMODE_BLEND);
|
|
||||||
SDL_SetRenderDrawColor(renderer_.get(), 0x00, 0x00, 0x00, 0x00);
|
|
||||||
}
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
absl::Status Controller::CreateGuiContext() {
|
|
||||||
ImGui::CreateContext();
|
|
||||||
|
|
||||||
// Initialize ImGui for SDL
|
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(window_.get(), renderer_.get());
|
|
||||||
ImGui_ImplSDLRenderer_Init(renderer_.get());
|
|
||||||
|
|
||||||
// Load available fonts
|
|
||||||
const ImGuiIO &io = ImGui::GetIO();
|
|
||||||
io.Fonts->AddFontFromFileTTF("assets/font/Karla-Regular.ttf", 14.0f);
|
|
||||||
|
|
||||||
// merge in icons from Google Material Design
|
|
||||||
static const ImWchar icons_ranges[] = {ICON_MIN_MD, 0xf900, 0};
|
|
||||||
ImFontConfig icons_config;
|
|
||||||
icons_config.MergeMode = true;
|
|
||||||
icons_config.GlyphOffset.y = 5.0f;
|
|
||||||
icons_config.GlyphMinAdvanceX = 13.0f;
|
|
||||||
icons_config.PixelSnapH = true;
|
|
||||||
io.Fonts->AddFontFromFileTTF(FONT_ICON_FILE_NAME_MD, 18.0f, &icons_config,
|
|
||||||
icons_ranges);
|
|
||||||
io.Fonts->AddFontFromFileTTF("assets/font/Roboto-Medium.ttf", 14.0f);
|
|
||||||
io.Fonts->AddFontFromFileTTF("assets/font/Cousine-Regular.ttf", 14.0f);
|
|
||||||
io.Fonts->AddFontFromFileTTF("assets/font/DroidSans.ttf", 16.0f);
|
|
||||||
|
|
||||||
// Set the default style
|
|
||||||
gui::ColorsYaze();
|
|
||||||
|
|
||||||
// Build a new ImGui frame
|
|
||||||
ImGui_ImplSDLRenderer_NewFrame();
|
|
||||||
ImGui_ImplSDL2_NewFrame(window_.get());
|
|
||||||
|
|
||||||
return absl::OkStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
@@ -2,56 +2,46 @@
|
|||||||
#define YAZE_APP_CORE_CONTROLLER_H
|
#define YAZE_APP_CORE_CONTROLLER_H
|
||||||
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#include <imgui/backends/imgui_impl_sdl.h>
|
|
||||||
#include <imgui/backends/imgui_impl_sdlrenderer.h>
|
|
||||||
#include <imgui/imgui.h>
|
|
||||||
#include <imgui/imgui_internal.h>
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "absl/status/status.h"
|
#include "absl/status/status.h"
|
||||||
#include "app/editor/master_editor.h"
|
#include "app/core/window.h"
|
||||||
#include "gui/icons.h"
|
#include "app/editor/editor_manager.h"
|
||||||
#include "gui/style.h"
|
|
||||||
|
|
||||||
int main(int argc, char **argv);
|
int main(int argc, char **argv);
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze {
|
||||||
namespace app {
|
|
||||||
namespace core {
|
namespace core {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main controller for the application.
|
||||||
|
*
|
||||||
|
* This class is responsible for managing the main window and the
|
||||||
|
* main editor. It is the main entry point for the application.
|
||||||
|
*/
|
||||||
class Controller {
|
class Controller {
|
||||||
public:
|
public:
|
||||||
bool isActive() const;
|
bool IsActive() const { return active_; }
|
||||||
absl::Status onEntry();
|
absl::Status OnEntry(std::string filename = "");
|
||||||
void onInput();
|
void OnInput();
|
||||||
void onLoad();
|
absl::Status OnLoad();
|
||||||
void onLoadDelta();
|
void DoRender() const;
|
||||||
void doRender() const;
|
void OnExit();
|
||||||
void onExit() const;
|
|
||||||
|
auto window() -> SDL_Window * { return window_.window_.get(); }
|
||||||
|
void set_active(bool active) { active_ = active; }
|
||||||
|
auto active() const { return active_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct sdl_deleter {
|
|
||||||
void operator()(SDL_Window *p) const { SDL_DestroyWindow(p); }
|
|
||||||
void operator()(SDL_Renderer *p) const { SDL_DestroyRenderer(p); }
|
|
||||||
void operator()(SDL_Texture *p) const { SDL_DestroyTexture(p); }
|
|
||||||
};
|
|
||||||
|
|
||||||
absl::Status CreateWindow();
|
|
||||||
absl::Status CreateRenderer();
|
|
||||||
absl::Status CreateGuiContext();
|
|
||||||
void CloseWindow() { active_ = false; }
|
|
||||||
|
|
||||||
friend int ::main(int argc, char **argv);
|
friend int ::main(int argc, char **argv);
|
||||||
|
|
||||||
bool active_;
|
bool active_ = false;
|
||||||
editor::MasterEditor master_editor_;
|
core::Window window_;
|
||||||
std::shared_ptr<SDL_Window> window_;
|
editor::EditorManager editor_manager_;
|
||||||
std::shared_ptr<SDL_Renderer> renderer_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace core
|
} // namespace core
|
||||||
} // namespace app
|
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif // YAZE_APP_CORE_CONTROLLER_H
|
#endif // YAZE_APP_CORE_CONTROLLER_H
|
||||||
33
src/app/core/core.cmake
Normal file
33
src/app/core/core.cmake
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
set(
|
||||||
|
YAZE_APP_CORE_SRC
|
||||||
|
app/core/controller.cc
|
||||||
|
app/emu/emulator.cc
|
||||||
|
app/core/project.cc
|
||||||
|
app/core/window.cc
|
||||||
|
app/core/asar_wrapper.cc
|
||||||
|
)
|
||||||
|
|
||||||
|
if (WIN32 OR MINGW OR UNIX AND NOT APPLE)
|
||||||
|
list(APPEND YAZE_APP_CORE_SRC
|
||||||
|
app/core/platform/font_loader.cc
|
||||||
|
app/core/platform/clipboard.cc
|
||||||
|
app/core/platform/file_dialog.cc
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
list(APPEND YAZE_APP_CORE_SRC
|
||||||
|
app/core/platform/file_dialog.cc
|
||||||
|
app/core/platform/file_dialog.mm
|
||||||
|
app/core/platform/app_delegate.mm
|
||||||
|
app/core/platform/font_loader.cc
|
||||||
|
app/core/platform/font_loader.mm
|
||||||
|
app/core/platform/clipboard.mm
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(COCOA_LIBRARY Cocoa)
|
||||||
|
if(NOT COCOA_LIBRARY)
|
||||||
|
message(FATAL_ERROR "Cocoa not found")
|
||||||
|
endif()
|
||||||
|
set(CMAKE_EXE_LINKER_FLAGS "-framework ServiceManagement -framework Foundation -framework Cocoa")
|
||||||
|
endif()
|
||||||
176
src/app/core/features.h
Normal file
176
src/app/core/features.h
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
#ifndef YAZE_APP_CORE_FEATURES_H
|
||||||
|
#define YAZE_APP_CORE_FEATURES_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "imgui/imgui.h"
|
||||||
|
|
||||||
|
namespace yaze {
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @class FeatureFlags
|
||||||
|
* @brief A class to manage experimental feature flags.
|
||||||
|
*/
|
||||||
|
class FeatureFlags {
|
||||||
|
public:
|
||||||
|
struct Flags {
|
||||||
|
// Log instructions to the GUI debugger.
|
||||||
|
bool kLogInstructions = true;
|
||||||
|
|
||||||
|
// Flag to enable the saving of all palettes to the Rom.
|
||||||
|
bool kSaveAllPalettes = false;
|
||||||
|
|
||||||
|
// Flag to enable the saving of gfx groups to the rom.
|
||||||
|
bool kSaveGfxGroups = false;
|
||||||
|
|
||||||
|
// Flag to enable the change queue, which could have any anonymous
|
||||||
|
// save routine for the Rom. In practice, just the overworld tilemap
|
||||||
|
// and tile32 save.
|
||||||
|
bool kSaveWithChangeQueue = false;
|
||||||
|
|
||||||
|
// Save dungeon map edits to the Rom.
|
||||||
|
bool kSaveDungeonMaps = false;
|
||||||
|
|
||||||
|
// Save graphics sheet to the Rom.
|
||||||
|
bool kSaveGraphicsSheet = false;
|
||||||
|
|
||||||
|
// Log to the console.
|
||||||
|
bool kLogToConsole = false;
|
||||||
|
|
||||||
|
// Use NFD (Native File Dialog) instead of bespoke file dialog implementation.
|
||||||
|
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
|
||||||
|
bool kUseNativeFileDialog = true;
|
||||||
|
#else
|
||||||
|
bool kUseNativeFileDialog = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Overworld flags
|
||||||
|
struct Overworld {
|
||||||
|
// Load and render overworld sprites to the screen. Unstable.
|
||||||
|
bool kDrawOverworldSprites = false;
|
||||||
|
|
||||||
|
// Save overworld map edits to the Rom.
|
||||||
|
bool kSaveOverworldMaps = true;
|
||||||
|
|
||||||
|
// Save overworld entrances to the Rom.
|
||||||
|
bool kSaveOverworldEntrances = true;
|
||||||
|
|
||||||
|
// Save overworld exits to the Rom.
|
||||||
|
bool kSaveOverworldExits = true;
|
||||||
|
|
||||||
|
// Save overworld items to the Rom.
|
||||||
|
bool kSaveOverworldItems = true;
|
||||||
|
|
||||||
|
// Save overworld properties to the Rom.
|
||||||
|
bool kSaveOverworldProperties = true;
|
||||||
|
|
||||||
|
// Enable custom overworld features for vanilla ROMs or override detection.
|
||||||
|
// If ZSCustomOverworld ASM is already applied, features are auto-enabled.
|
||||||
|
bool kLoadCustomOverworld = false;
|
||||||
|
|
||||||
|
// Apply ZSCustomOverworld ASM patches when upgrading ROM versions.
|
||||||
|
bool kApplyZSCustomOverworldASM = false;
|
||||||
|
} overworld;
|
||||||
|
};
|
||||||
|
|
||||||
|
static Flags &get() {
|
||||||
|
static Flags instance;
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Serialize() const {
|
||||||
|
std::string result;
|
||||||
|
result +=
|
||||||
|
"kLogInstructions: " + std::to_string(get().kLogInstructions) + "\n";
|
||||||
|
result +=
|
||||||
|
"kSaveAllPalettes: " + std::to_string(get().kSaveAllPalettes) + "\n";
|
||||||
|
result += "kSaveGfxGroups: " + std::to_string(get().kSaveGfxGroups) + "\n";
|
||||||
|
result +=
|
||||||
|
"kSaveWithChangeQueue: " + std::to_string(get().kSaveWithChangeQueue) +
|
||||||
|
"\n";
|
||||||
|
result +=
|
||||||
|
"kSaveDungeonMaps: " + std::to_string(get().kSaveDungeonMaps) + "\n";
|
||||||
|
result += "kLogToConsole: " + std::to_string(get().kLogToConsole) + "\n";
|
||||||
|
result += "kDrawOverworldSprites: " +
|
||||||
|
std::to_string(get().overworld.kDrawOverworldSprites) + "\n";
|
||||||
|
result += "kSaveOverworldMaps: " +
|
||||||
|
std::to_string(get().overworld.kSaveOverworldMaps) + "\n";
|
||||||
|
result += "kSaveOverworldEntrances: " +
|
||||||
|
std::to_string(get().overworld.kSaveOverworldEntrances) + "\n";
|
||||||
|
result += "kSaveOverworldExits: " +
|
||||||
|
std::to_string(get().overworld.kSaveOverworldExits) + "\n";
|
||||||
|
result += "kSaveOverworldItems: " +
|
||||||
|
std::to_string(get().overworld.kSaveOverworldItems) + "\n";
|
||||||
|
result += "kSaveOverworldProperties: " +
|
||||||
|
std::to_string(get().overworld.kSaveOverworldProperties) + "\n";
|
||||||
|
result += "kLoadCustomOverworld: " +
|
||||||
|
std::to_string(get().overworld.kLoadCustomOverworld) + "\n";
|
||||||
|
result += "kApplyZSCustomOverworldASM: " +
|
||||||
|
std::to_string(get().overworld.kApplyZSCustomOverworldASM) + "\n";
|
||||||
|
result += "kUseNativeFileDialog: " +
|
||||||
|
std::to_string(get().kUseNativeFileDialog) + "\n";
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
using ImGui::BeginMenu;
|
||||||
|
using ImGui::Checkbox;
|
||||||
|
using ImGui::EndMenu;
|
||||||
|
using ImGui::MenuItem;
|
||||||
|
using ImGui::Separator;
|
||||||
|
|
||||||
|
struct FlagsMenu {
|
||||||
|
void DrawOverworldFlags() {
|
||||||
|
Checkbox("Enable Overworld Sprites",
|
||||||
|
&FeatureFlags::get().overworld.kDrawOverworldSprites);
|
||||||
|
Separator();
|
||||||
|
Checkbox("Save Overworld Maps",
|
||||||
|
&FeatureFlags::get().overworld.kSaveOverworldMaps);
|
||||||
|
Checkbox("Save Overworld Entrances",
|
||||||
|
&FeatureFlags::get().overworld.kSaveOverworldEntrances);
|
||||||
|
Checkbox("Save Overworld Exits",
|
||||||
|
&FeatureFlags::get().overworld.kSaveOverworldExits);
|
||||||
|
Checkbox("Save Overworld Items",
|
||||||
|
&FeatureFlags::get().overworld.kSaveOverworldItems);
|
||||||
|
Checkbox("Save Overworld Properties",
|
||||||
|
&FeatureFlags::get().overworld.kSaveOverworldProperties);
|
||||||
|
Checkbox("Enable Custom Overworld Features",
|
||||||
|
&FeatureFlags::get().overworld.kLoadCustomOverworld);
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("?")) {
|
||||||
|
ImGui::OpenPopup("CustomOverworldHelp");
|
||||||
|
}
|
||||||
|
if (ImGui::BeginPopup("CustomOverworldHelp")) {
|
||||||
|
ImGui::Text("This flag enables ZSCustomOverworld features.");
|
||||||
|
ImGui::Text("If ZSCustomOverworld ASM is already applied to the ROM,");
|
||||||
|
ImGui::Text("features are auto-enabled regardless of this flag.");
|
||||||
|
ImGui::Text("For vanilla ROMs, enable this to use custom features.");
|
||||||
|
ImGui::EndPopup();
|
||||||
|
}
|
||||||
|
Checkbox("Apply ZSCustomOverworld ASM",
|
||||||
|
&FeatureFlags::get().overworld.kApplyZSCustomOverworldASM);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawDungeonFlags() {
|
||||||
|
Checkbox("Save Dungeon Maps", &FeatureFlags::get().kSaveDungeonMaps);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawResourceFlags() {
|
||||||
|
Checkbox("Save All Palettes", &FeatureFlags::get().kSaveAllPalettes);
|
||||||
|
Checkbox("Save Gfx Groups", &FeatureFlags::get().kSaveGfxGroups);
|
||||||
|
Checkbox("Save Graphics Sheets", &FeatureFlags::get().kSaveGraphicsSheet);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawSystemFlags() {
|
||||||
|
Checkbox("Enable Console Logging", &FeatureFlags::get().kLogToConsole);
|
||||||
|
Checkbox("Log Instructions to Emulator Debugger",
|
||||||
|
&FeatureFlags::get().kLogInstructions);
|
||||||
|
Checkbox("Use Native File Dialog (NFD)", &FeatureFlags::get().kUseNativeFileDialog);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace core
|
||||||
|
} // namespace yaze
|
||||||
|
|
||||||
|
#endif // YAZE_APP_CORE_FEATURES_H
|
||||||
64
src/app/core/platform/app_delegate.h
Normal file
64
src/app/core/platform/app_delegate.h
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
#ifndef YAZE_APP_CORE_PLATFORM_APP_DELEGATE_H
|
||||||
|
#define YAZE_APP_CORE_PLATFORM_APP_DELEGATE_H
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
/* Apple OSX and iOS (Darwin). */
|
||||||
|
#import <CoreText/CoreText.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
|
#if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
|
||||||
|
/* iOS in Xcode simulator */
|
||||||
|
#import <PencilKit/PencilKit.h>
|
||||||
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
|
@interface AppDelegate : UIResponder <UIApplicationDelegate,
|
||||||
|
UIDocumentPickerDelegate,
|
||||||
|
UITabBarControllerDelegate,
|
||||||
|
PKCanvasViewDelegate>
|
||||||
|
@property(strong, nonatomic) UIWindow *window;
|
||||||
|
|
||||||
|
@property UIDocumentPickerViewController *documentPicker;
|
||||||
|
@property(nonatomic, copy) void (^completionHandler)(NSString *selectedFile);
|
||||||
|
- (void)PresentDocumentPickerWithCompletionHandler:
|
||||||
|
(void (^)(NSString *selectedFile))completionHandler;
|
||||||
|
|
||||||
|
// TODO: Setup a tab bar controller for multiple yaze instances
|
||||||
|
@property(nonatomic) UITabBarController *tabBarController;
|
||||||
|
|
||||||
|
// TODO: Setup a font picker for the text editor and display settings
|
||||||
|
@property(nonatomic) UIFontPickerViewController *fontPicker;
|
||||||
|
|
||||||
|
// TODO: Setup the pencil kit for drawing
|
||||||
|
@property PKToolPicker *toolPicker;
|
||||||
|
@property PKCanvasView *canvasView;
|
||||||
|
|
||||||
|
// TODO: Setup the file manager for file operations
|
||||||
|
@property NSFileManager *fileManager;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#elif TARGET_OS_MAC == 1
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Initialize the Cocoa application.
|
||||||
|
*/
|
||||||
|
void yaze_initialize_cocoa();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Run the Cocoa application delegate.
|
||||||
|
*/
|
||||||
|
int yaze_run_cocoa_app_delegate(const char *filename);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
} // extern "C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // TARGET_OS_MAC
|
||||||
|
|
||||||
|
#endif // defined(__APPLE__) && defined(__MACH__)
|
||||||
|
|
||||||
|
#endif // YAZE_APP_CORE_PLATFORM_APP_DELEGATE_H
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user