mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 10:41:15 +00:00
Merge branch 'master' of https://github.com/isledecomp/isle-portable
This commit is contained in:
commit
b3a993b9b2
@ -14,3 +14,8 @@ trim_trailing_whitespace = true
|
||||
|
||||
[{CMakeLists.txt,*.cmake}]
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{json,xml.in,desktop.in}]
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
|
||||
4
.gitattributes
vendored
4
.gitattributes
vendored
@ -5,3 +5,7 @@
|
||||
*.html text eol=lf diff=html
|
||||
*.mdp binary
|
||||
*.mak text eol=crlf
|
||||
**/*.ico binary
|
||||
**/*.png binary
|
||||
**/*.svg text eol=lf
|
||||
**/*.desktop text eol=lf
|
||||
|
||||
160
.github/workflows/ci.yml
vendored
160
.github/workflows/ci.yml
vendored
@ -25,6 +25,7 @@ jobs:
|
||||
build:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
container: ${{ matrix.container || '' }}
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell || 'sh' }}
|
||||
@ -33,14 +34,19 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: 'Linux', os: 'ubuntu-latest', dx5: false, config: true, build-type: 'Debug', linux: true, werror: true, clang-tidy: true }
|
||||
- { name: 'MSVC (x86)', os: 'windows-latest', dx5: true, config: false, build-type: 'Debug', msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_x86' }
|
||||
- { name: 'MSVC (x64)', os: 'windows-latest', dx5: false, config: false, build-type: 'Debug', msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64' }
|
||||
- { name: 'MSVC (arm64)', os: 'windows-latest', dx5: false, config: false, build-type: 'Debug', msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_arm64' }
|
||||
- { name: 'msys2 mingw32', os: 'windows-latest', dx5: false, config: false, build-type: 'Debug', mingw: true, werror: true, clang-tidy: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' }
|
||||
- { name: 'msys2 mingw64', os: 'windows-latest', dx5: false, config: true, build-type: 'Debug', mingw: true, werror: true, clang-tidy: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' }
|
||||
- { name: 'macOS', os: 'macos-latest', dx5: false, config: true, build-type: 'Debug', brew: true, werror: true, clang-tidy: false }
|
||||
- { name: 'Emscripten', os: 'ubuntu-latest', dx5: false, config: false, build-type: 'Debug', emsdk: true, werror: true, clang-tidy: false, cmake-wrapper: 'emcmake' }
|
||||
- { name: 'Linux', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: true, linux: true, werror: true, clang-tidy: true }
|
||||
- { name: 'Linux (Debug)', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: true, linux: true, werror: true, clang-tidy: true, debug: true }
|
||||
- { name: 'MSVC (x86)', os: 'windows-latest', generator: 'Ninja', dx5: true, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_x86' }
|
||||
- { name: 'MSVC (x64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64' }
|
||||
- { name: 'MSVC (x64 Debug)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64', debug: true }
|
||||
- { name: 'MSVC (arm64)', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64_arm64' }
|
||||
- { name: 'msys2 mingw32', os: 'windows-latest', generator: 'Ninja', dx5: false, config: false, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw32', msys-env: 'mingw-w64-i686', shell: 'msys2 {0}' }
|
||||
- { name: 'msys2 mingw64', os: 'windows-latest', generator: 'Ninja', dx5: false, config: true, mingw: true, werror: true, clang-tidy: true, msystem: 'mingw64', msys-env: 'mingw-w64-x86_64', shell: 'msys2 {0}' }
|
||||
- { name: 'macOS', os: 'macos-latest', generator: 'Ninja', dx5: false, config: true, brew: true, werror: true, clang-tidy: false }
|
||||
- { name: 'iOS', os: 'macos-15', generator: 'Xcode', dx5: false, config: false, brew: true, werror: true, clang-tidy: false, cmake-args: '-DCMAKE_SYSTEM_NAME=iOS' }
|
||||
- { name: 'Emscripten', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: false, emsdk: true, werror: true, clang-tidy: false, cmake-wrapper: 'emcmake' }
|
||||
- { name: 'Nintendo 3DS', os: 'ubuntu-latest', generator: 'Ninja', dx5: false, config: false, n3ds: true, werror: true, clang-tidy: false, container: 'devkitpro/devkitarm:latest', cmake-args: '-DCMAKE_TOOLCHAIN_FILE=/opt/devkitpro/cmake/3DS.cmake' }
|
||||
- { name: 'Xbox One', os: 'windows-latest', generator: 'Visual Studio 17 2022', dx5: false, config: false, msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64', cmake-args: '-DCMAKE_SYSTEM_NAME=WindowsStore -DCMAKE_SYSTEM_VERSION=10.0.26100.0', xbox-one: true}
|
||||
steps:
|
||||
- name: Setup vcvars
|
||||
if: ${{ !!matrix.msvc }}
|
||||
@ -59,6 +65,20 @@ jobs:
|
||||
${{ matrix.msys-env }}-ninja
|
||||
${{ matrix.msys-env }}-clang-tools-extra
|
||||
${{ (matrix.config && format('{0}-qt6-base', matrix.msys-env)) || '' }}
|
||||
- name: Install Qt
|
||||
if: ${{ !!matrix.msvc && matrix.config }}
|
||||
uses: jurplel/install-qt-action@v4
|
||||
with:
|
||||
cache: 'true'
|
||||
|
||||
- name: Install 3DS dependencies
|
||||
if: ${{ matrix.n3ds }}
|
||||
run: |
|
||||
wget https://github.com/diasurgical/bannertool/releases/download/1.2.0/bannertool.zip
|
||||
unzip -j "bannertool.zip" "linux-x86_64/bannertool" -d "/opt/devkitpro/tools/bin"
|
||||
wget https://github.com/3DSGuy/Project_CTR/releases/download/makerom-v0.18/makerom-v0.18-ubuntu_x86_64.zip
|
||||
unzip "makerom-v0.18-ubuntu_x86_64.zip" "makerom" -d "/opt/devkitpro/tools/bin"
|
||||
chmod a+x /opt/devkitpro/tools/bin/makerom
|
||||
|
||||
- name: Install Linux dependencies (apt-get)
|
||||
if: ${{ matrix.linux }}
|
||||
@ -66,8 +86,8 @@ jobs:
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev \
|
||||
libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols libgl1-mesa-dev libglew-dev qt6-base-dev \
|
||||
libasound2-dev
|
||||
libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols libgl1-mesa-dev qt6-base-dev \
|
||||
libasound2-dev qt6-xdgdesktopportal-platformtheme
|
||||
|
||||
- name: Install macOS dependencies (brew)
|
||||
if: ${{ matrix.brew }}
|
||||
@ -88,27 +108,106 @@ jobs:
|
||||
|
||||
- name: Configure (CMake)
|
||||
run: |
|
||||
${{ matrix.cmake-wrapper || '' }} cmake -S . -B build -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
${{ matrix.cmake-wrapper || '' }} cmake -S . -B build -G "${{ matrix.generator }}" \
|
||||
${{ matrix.cmake-args || '' }} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DISLE_USE_DX5=${{ !!matrix.dx5 }} \
|
||||
-DISLE_BUILD_CONFIG=${{ matrix.config }} \
|
||||
-DISLE_BUILD_CONFIG=${{ !!matrix.config }} \
|
||||
-DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \
|
||||
-DISLE_WERROR=${{ !!matrix.werror }} \
|
||||
-DISLE_DEBUG=${{ matrix.debug || 'OFF' }} \
|
||||
-Werror=dev
|
||||
|
||||
- name: Build (CMake)
|
||||
run: cmake --build build --verbose
|
||||
run: cmake --build build --verbose --config Release
|
||||
|
||||
- name: Package (CPack)
|
||||
if: ${{ !matrix.n3ds }}
|
||||
run: |
|
||||
cd build
|
||||
cpack .
|
||||
success=0
|
||||
max_tries=10
|
||||
for i in $(seq $max_tries); do
|
||||
cpack . && success=1
|
||||
if test $success = 1; then
|
||||
break
|
||||
fi
|
||||
echo "Package creation failed. Sleep 1 second and try again."
|
||||
sleep 1
|
||||
done
|
||||
if test $success = 0; then
|
||||
echo "Package creation failed after $max_tries attempts."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Install linuxdeploy
|
||||
if: ${{ matrix.linux }}
|
||||
id: install-linuxdeploy
|
||||
uses: miurahr/install-linuxdeploy-action@v1.8.0
|
||||
with:
|
||||
plugins: qt appimage
|
||||
|
||||
- name: Package (AppImage)
|
||||
if: ${{ matrix.linux }}
|
||||
run: |
|
||||
cd build && \
|
||||
export LD_LIBRARY_PATH=".:$LD_LIBRARY_PATH" && \
|
||||
NO_STRIP=1 ${{ steps.install-linuxdeploy.outputs.linuxdeploy }} \
|
||||
-p qt \
|
||||
-e isle \
|
||||
-e isle-config \
|
||||
-d packaging/linux/org.legoisland.Isle.desktop \
|
||||
-i icons/org.legoisland.Isle.svg \
|
||||
--custom-apprun=../packaging/linux/appimage/AppRun \
|
||||
--appdir packaging/linux/appimage/AppDir \
|
||||
--output appimage && \
|
||||
mv *.AppImage dist/
|
||||
|
||||
- name: Package (3DS)
|
||||
if: ${{ matrix.n3ds }}
|
||||
run: |
|
||||
cd build
|
||||
mkdir dist
|
||||
mv *.3dsx dist/
|
||||
mv *.cia dist/
|
||||
|
||||
- name: Upload Build Artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: '${{ matrix.name }} ${{ matrix.build-type }}'
|
||||
path: build/dist/isle-*
|
||||
name: '${{ matrix.name }}'
|
||||
path: |
|
||||
build/dist/isle-*
|
||||
build/dist/*.AppImage
|
||||
build/dist/*.3dsx
|
||||
build/dist/*.cia
|
||||
|
||||
flatpak:
|
||||
name: "Flatpak (${{ matrix.arch }})"
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: x86_64
|
||||
os: ubuntu-latest
|
||||
|
||||
- arch: aarch64
|
||||
os: ubuntu-22.04-arm
|
||||
|
||||
container:
|
||||
image: ghcr.io/flathub-infra/flatpak-github-actions:kde-6.8
|
||||
options: --privileged
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Build Flatpak
|
||||
uses: flatpak/flatpak-github-actions/flatpak-builder@v6
|
||||
with:
|
||||
bundle: org.legoisland.Isle.${{ matrix.arch }}.flatpak
|
||||
manifest-path: packaging/linux/flatpak/org.legoisland.Isle.json
|
||||
arch: ${{ matrix.arch }}
|
||||
|
||||
ncc:
|
||||
name: 'C++'
|
||||
@ -148,3 +247,30 @@ jobs:
|
||||
LEGO1/omni/src/video/flic.cpp \
|
||||
$action_headers \
|
||||
--path LEGO1/omni LEGO1/lego/legoomni
|
||||
|
||||
release:
|
||||
name: 'Release'
|
||||
if: ${{ github.event_name == 'push' && github.ref_name == 'master' }}
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- build
|
||||
- flatpak
|
||||
steps:
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@main
|
||||
with:
|
||||
pattern: "*"
|
||||
path: Release
|
||||
merge-multiple: true
|
||||
|
||||
- name: Checkout uploadtool
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'probonopd/uploadtool'
|
||||
path: 'uploadtool'
|
||||
|
||||
- name: Upload Continuous Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
./uploadtool/upload.sh Release/*
|
||||
|
||||
55
.github/workflows/docker.yml
vendored
Normal file
55
.github/workflows/docker.yml
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ['master']
|
||||
|
||||
env:
|
||||
REGISTRY: ghcr.io
|
||||
IMAGE_NAME: ${{ github.repository }}-emscripten
|
||||
|
||||
jobs:
|
||||
publish-emscripten:
|
||||
name: Publish web port
|
||||
env:
|
||||
IMAGE_NAME: ${{ github.repository }}-emscripten
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
packages: write
|
||||
attestations: write
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Extract metadata (tags, labels) for Docker
|
||||
id: meta
|
||||
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
|
||||
with:
|
||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
- name: Build and push Docker image
|
||||
id: push
|
||||
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
|
||||
with:
|
||||
file: docker/emscripten/Dockerfile
|
||||
context: .
|
||||
push: true
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
- name: Generate artifact attestation
|
||||
uses: actions/attest-build-provenance@v2
|
||||
with:
|
||||
subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
|
||||
subject-digest: ${{ steps.push.outputs.digest }}
|
||||
push-to-registry: true
|
||||
116
.github/workflows/release.yml
vendored
116
.github/workflows/release.yml
vendored
@ -1,116 +0,0 @@
|
||||
name: Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: ${{ matrix.name }}
|
||||
runs-on: ${{ matrix.os }}
|
||||
defaults:
|
||||
run:
|
||||
shell: ${{ matrix.shell || 'sh' }}
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { name: 'Linux', os: 'ubuntu-latest', dx5: false, config: true, build-type: 'Release', linux: true, werror: true, clang-tidy: false }
|
||||
- { name: 'Windows', os: 'windows-latest', dx5: false, config: false, build-type: 'Release', msvc: true, werror: false, clang-tidy: false, vc-arch: 'amd64' }
|
||||
- { name: 'macOS', os: 'macos-latest', dx5: false, config: true, build-type: 'Release', brew: true, werror: true, clang-tidy: false }
|
||||
steps:
|
||||
- name: Setup vcvars
|
||||
if: ${{ !!matrix.msvc }}
|
||||
uses: ilammy/msvc-dev-cmd@v1
|
||||
with:
|
||||
arch: ${{ matrix.vc-arch }}
|
||||
|
||||
- name: Set up MSYS2
|
||||
if: ${{ !!matrix.msystem }}
|
||||
uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
msystem: ${{ matrix.msystem }}
|
||||
install: >-
|
||||
${{ matrix.msys-env }}-cc
|
||||
${{ matrix.msys-env }}-cmake
|
||||
${{ matrix.msys-env }}-ninja
|
||||
${{ matrix.msys-env }}-clang-tools-extra
|
||||
${{ (matrix.config && format('{0}-qt6-base', matrix.msys-env)) || '' }}
|
||||
|
||||
- name: Install Linux dependencies (apt-get)
|
||||
if: ${{ matrix.linux }}
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
libx11-dev libxext-dev libxrandr-dev libxrender-dev libxfixes-dev libxi-dev libxinerama-dev \
|
||||
libxcursor-dev libwayland-dev libxkbcommon-dev wayland-protocols libgl1-mesa-dev libglew-dev qt6-base-dev \
|
||||
libasound2-dev
|
||||
|
||||
- name: Install macOS dependencies (brew)
|
||||
if: ${{ matrix.brew }}
|
||||
run: |
|
||||
brew update
|
||||
brew install cmake ninja llvm qt6
|
||||
echo "LLVM_ROOT=$(brew --prefix llvm)/bin" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup Emscripten
|
||||
uses: mymindstorm/setup-emsdk@master
|
||||
if: ${{ matrix.emsdk }}
|
||||
|
||||
- name: Setup ninja
|
||||
if: ${{ matrix.msvc }}
|
||||
uses: ashutoshvarma/setup-ninja@master
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Configure (CMake)
|
||||
run: |
|
||||
${{ matrix.cmake-wrapper || '' }} cmake -S . -B build -GNinja \
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
|
||||
-DISLE_USE_DX5=${{ !!matrix.dx5 }} \
|
||||
-DISLE_BUILD_CONFIG=${{ matrix.config }} \
|
||||
-DENABLE_CLANG_TIDY=${{ !!matrix.clang-tidy }} \
|
||||
-DISLE_WERROR=${{ !!matrix.werror }} \
|
||||
-DISLE_DEBUG=OFF \
|
||||
-Werror=dev
|
||||
|
||||
- name: Build (CMake)
|
||||
run: cmake --build build --verbose
|
||||
|
||||
- name: Package (CPack)
|
||||
run: |
|
||||
cd build
|
||||
cpack .
|
||||
|
||||
- name: Upload Artifact
|
||||
uses: actions/upload-artifact@main
|
||||
with:
|
||||
name: Release-${{ matrix.name }}
|
||||
path: |
|
||||
build/dist/isle-*
|
||||
|
||||
release:
|
||||
name: 'Release'
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- name: Download All Artifacts
|
||||
uses: actions/download-artifact@main
|
||||
with:
|
||||
pattern: Release-*
|
||||
path: Release
|
||||
merge-multiple: true
|
||||
|
||||
- name: Checkout uploadtool
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
repository: 'probonopd/uploadtool'
|
||||
path: 'uploadtool'
|
||||
|
||||
- name: Upload Continuous Release
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
./uploadtool/upload.sh Release/*
|
||||
6
.gitignore
vendored
6
.gitignore
vendored
@ -30,3 +30,9 @@ LEGO1.DLL
|
||||
|
||||
# Kate - Text
|
||||
/.cache
|
||||
|
||||
# Flatpak build cache
|
||||
**/.flatpak-builder/
|
||||
|
||||
# Flatpak build dir
|
||||
**/flatpak-build/
|
||||
|
||||
@ -88,7 +88,7 @@ persistent=yes
|
||||
|
||||
# Minimum Python version to use for version dependent checks. Will default to
|
||||
# the version used to run pylint.
|
||||
py-version=3.11
|
||||
py-version=3.12
|
||||
|
||||
# Discover python modules and packages in the file system subtree.
|
||||
recursive=no
|
||||
|
||||
156
CMake/detectcpu.cmake
Normal file
156
CMake/detectcpu.cmake
Normal file
@ -0,0 +1,156 @@
|
||||
function(DetectTargetCPUArchitectures DETECTED_ARCHS)
|
||||
|
||||
set(known_archs EMSCRIPTEN ARM32 ARM64 ARM64EC LOONGARCH64 POWERPC32 POWERPC64 X86 X64)
|
||||
|
||||
if(APPLE AND CMAKE_OSX_ARCHITECTURES)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
set(CPU_${known_arch} "0" PARENT_SCOPE)
|
||||
endforeach()
|
||||
set(detected_archs)
|
||||
foreach(osx_arch IN LISTS CMAKE_OSX_ARCHITECTURES)
|
||||
if(osx_arch STREQUAL "x86_64")
|
||||
set(CPU_X64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "X64")
|
||||
elseif(osx_arch STREQUAL "arm64")
|
||||
set(CPU_ARM64 "1" PARENT_SCOPE)
|
||||
list(APPEND detected_archs "ARM64")
|
||||
endif()
|
||||
endforeach()
|
||||
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(detected_archs)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
if(CPU_${known_arch})
|
||||
list(APPEND detected_archs "${known_arch}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
if(detected_archs)
|
||||
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(arch_check_ARM32 "defined(__arm__) || defined(_M_ARM)")
|
||||
set(arch_check_ARM64 "defined(__aarch64__) || defined(_M_ARM64)")
|
||||
set(arch_check_ARM64EC "defined(_M_ARM64EC)")
|
||||
set(arch_check_EMSCRIPTEN "defined(__EMSCRIPTEN__)")
|
||||
set(arch_check_LOONGARCH64 "defined(__loongarch64)")
|
||||
set(arch_check_POWERPC32 "(defined(__PPC__) || defined(__powerpc__)) && !defined(__powerpc64__)")
|
||||
set(arch_check_POWERPC64 "defined(__PPC64__) || defined(__powerpc64__)")
|
||||
set(arch_check_X86 "defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) ||defined( __i386) || defined(_M_IX86)")
|
||||
set(arch_check_X64 "(defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) || defined(_M_X64) || defined(_M_AMD64)) && !defined(_M_ARM64EC)")
|
||||
|
||||
set(src_vars "")
|
||||
set(src_main "")
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
set(detected_${known_arch} "0")
|
||||
|
||||
string(APPEND src_vars "
|
||||
#if ${arch_check_${known_arch}}
|
||||
#define ARCH_${known_arch} \"1\"
|
||||
#else
|
||||
#define ARCH_${known_arch} \"0\"
|
||||
#endif
|
||||
const char *arch_${known_arch} = \"INFO<${known_arch}=\" ARCH_${known_arch} \">\";
|
||||
")
|
||||
string(APPEND src_main "
|
||||
result += arch_${known_arch}[argc];")
|
||||
endforeach()
|
||||
|
||||
set(src_arch_detect "${src_vars}
|
||||
int main(int argc, char *argv[]) {
|
||||
int result = 0;
|
||||
(void)argv;
|
||||
${src_main}
|
||||
return result;
|
||||
}")
|
||||
|
||||
if(CMAKE_C_COMPILER)
|
||||
set(ext ".c")
|
||||
elseif(CMAKE_CXX_COMPILER)
|
||||
set(ext ".cpp")
|
||||
else()
|
||||
enable_language(C)
|
||||
set(ext ".c")
|
||||
endif()
|
||||
set(path_src_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/detect_arch${ext}")
|
||||
file(WRITE "${path_src_arch_detect}" "${src_arch_detect}")
|
||||
set(path_dir_arch_detect "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/detect_arch")
|
||||
set(path_bin_arch_detect "${path_dir_arch_detect}/bin")
|
||||
|
||||
set(detected_archs)
|
||||
|
||||
set(msg "Detecting Target CPU Architecture")
|
||||
message(STATUS "${msg}")
|
||||
|
||||
include(CMakePushCheckState)
|
||||
|
||||
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
|
||||
|
||||
cmake_push_check_state(RESET)
|
||||
try_compile(CPU_CHECK_ALL
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/CMakeTmp/detect_arch"
|
||||
SOURCES "${path_src_arch_detect}"
|
||||
COPY_FILE "${path_bin_arch_detect}"
|
||||
)
|
||||
cmake_pop_check_state()
|
||||
if(NOT CPU_CHECK_ALL)
|
||||
message(STATUS "${msg} - <ERROR>")
|
||||
message(WARNING "Failed to compile source detecting the target CPU architecture")
|
||||
else()
|
||||
set(re "INFO<([A-Z0-9]+)=([01])>")
|
||||
file(STRINGS "${path_bin_arch_detect}" infos REGEX "${re}")
|
||||
|
||||
foreach(info_arch_01 IN LISTS infos)
|
||||
string(REGEX MATCH "${re}" A "${info_arch_01}")
|
||||
if(NOT "${CMAKE_MATCH_1}" IN_LIST known_archs)
|
||||
message(WARNING "Unknown architecture: \"${CMAKE_MATCH_1}\"")
|
||||
continue()
|
||||
endif()
|
||||
set(arch "${CMAKE_MATCH_1}")
|
||||
set(arch_01 "${CMAKE_MATCH_2}")
|
||||
set(detected_${arch} "${arch_01}")
|
||||
endforeach()
|
||||
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
if(detected_${known_arch})
|
||||
list(APPEND detected_archs ${known_arch})
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
||||
if(detected_archs)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
set("CPU_${known_arch}" "${detected_${known_arch}}" CACHE BOOL "Detected architecture ${known_arch}")
|
||||
endforeach()
|
||||
message(STATUS "${msg} - ${detected_archs}")
|
||||
else()
|
||||
include(CheckCSourceCompiles)
|
||||
cmake_push_check_state(RESET)
|
||||
foreach(known_arch IN LISTS known_archs)
|
||||
if(NOT detected_archs)
|
||||
set(cache_variable "CPU_${known_arch}")
|
||||
set(test_src "
|
||||
int main(int argc, char *argv[]) {
|
||||
#if ${arch_check_${known_arch}}
|
||||
return 0;
|
||||
#else
|
||||
choke
|
||||
#endif
|
||||
}
|
||||
")
|
||||
check_c_source_compiles("${test_src}" "${cache_variable}")
|
||||
if(${cache_variable})
|
||||
set(CPU_${known_arch} "1" CACHE BOOL "Detected architecture ${known_arch}")
|
||||
set(detected_archs ${known_arch})
|
||||
else()
|
||||
set(CPU_${known_arch} "0" CACHE BOOL "Detected architecture ${known_arch}")
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
cmake_pop_check_state()
|
||||
endif()
|
||||
set("${DETECTED_ARCHS}" "${detected_archs}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
345
CMakeLists.txt
345
CMakeLists.txt
@ -2,9 +2,19 @@ cmake_minimum_required(VERSION 3.25...4.0 FATAL_ERROR)
|
||||
|
||||
project(isle LANGUAGES CXX C VERSION 0.1)
|
||||
|
||||
if (IOS)
|
||||
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED NO)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "12.0")
|
||||
add_compile_definitions(IOS)
|
||||
endif()
|
||||
|
||||
if (WINDOWS_STORE)
|
||||
add_compile_definitions(WINDOWS_STORE)
|
||||
endif()
|
||||
|
||||
if (EMSCRIPTEN)
|
||||
add_compile_options(-pthread)
|
||||
add_link_options(-sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
|
||||
add_link_options(-sUSE_WEBGL2=1 -sMIN_WEBGL_VERSION=2 -sALLOW_MEMORY_GROWTH=1 -sMAXIMUM_MEMORY=2gb -sUSE_PTHREADS=1 -sPROXY_TO_PTHREAD=1 -sOFFSCREENCANVAS_SUPPORT=1 -sPTHREAD_POOL_SIZE_STRICT=0 -sFORCE_FILESYSTEM=1 -sWASMFS=1 -sEXIT_RUNTIME=1)
|
||||
set(SDL_PTHREADS ON CACHE BOOL "Enable SDL pthreads" FORCE)
|
||||
endif()
|
||||
|
||||
@ -13,6 +23,9 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
|
||||
include(CheckCXXSourceCompiles)
|
||||
include(CMakeDependentOption)
|
||||
include(CMakePushCheckState)
|
||||
include(CMake/detectcpu.cmake)
|
||||
|
||||
DetectTargetCPUArchitectures(ISLE_CPUS)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@ -26,7 +39,7 @@ else()
|
||||
endif()
|
||||
|
||||
find_program(SDL_SHADERCROSS_BIN NAMES "shadercross")
|
||||
find_package(Python3 3.11 COMPONENTS Interpreter)
|
||||
find_package(Python3 3.12 COMPONENTS Interpreter)
|
||||
|
||||
option(ISLE_BUILD_APP "Build isle application" ON)
|
||||
option(ISLE_ASAN "Enable Address Sanitizer" OFF)
|
||||
@ -35,7 +48,8 @@ option(ISLE_WERROR "Treat warnings as errors" OFF)
|
||||
option(ISLE_DEBUG "Enable imgui debug" ON)
|
||||
cmake_dependent_option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" "${NOT_MINGW}" "WIN32;CMAKE_SIZEOF_VOID_P EQUAL 4" OFF)
|
||||
cmake_dependent_option(ISLE_MINIWIN "Use miniwin" ON "NOT ISLE_USE_DX5" OFF)
|
||||
cmake_dependent_option(ISLE_BUILD_CONFIG "Build CONFIG.EXE application" ON "MSVC OR ISLE_MINIWIN" OFF)
|
||||
cmake_dependent_option(ISLE_EXTENSIONS "Use extensions" ON "NOT ISLE_USE_DX5" OFF)
|
||||
cmake_dependent_option(ISLE_BUILD_CONFIG "Build CONFIG.EXE application" ON "MSVC OR ISLE_MINIWIN;NOT NINTENDO_3DS;NOT WINDOWS_STORE" OFF)
|
||||
cmake_dependent_option(ISLE_COMPILE_SHADERS "Compile shaders" ON "SDL_SHADERCROSS_BIN;TARGET Python3::Interpreter" OFF)
|
||||
option(CMAKE_POSITION_INDEPENDENT_CODE "Build with -fPIC" ON)
|
||||
option(ENABLE_CLANG_TIDY "Enable clang-tidy")
|
||||
@ -48,50 +62,60 @@ message(STATUS "Isle app: ${ISLE_BUILD_APP}")
|
||||
message(STATUS "Config app: ${ISLE_BUILD_CONFIG}")
|
||||
message(STATUS "Internal DirectX5 SDK: ${ISLE_USE_DX5}")
|
||||
message(STATUS "Internal miniwin: ${ISLE_MINIWIN}")
|
||||
message(STATUS "Isle extensions: ${ISLE_EXTENSIONS}")
|
||||
message(STATUS "Isle debugging: ${ISLE_DEBUG}")
|
||||
message(STATUS "Compile shaders: ${ISLE_COMPILE_SHADERS}")
|
||||
|
||||
add_library(Isle::iniparser INTERFACE IMPORTED)
|
||||
|
||||
if (DOWNLOAD_DEPENDENCIES)
|
||||
# FetchContent downloads and configures dependencies
|
||||
message(STATUS "Fetching SDL3 and iniparser. This might take a while...")
|
||||
include(FetchContent)
|
||||
# FetchContent downloads and configures dependencies
|
||||
message(STATUS "Fetching SDL3 and iniparser. This might take a while...")
|
||||
include(FetchContent)
|
||||
if (WINDOWS_STORE)
|
||||
FetchContent_Declare(
|
||||
SDL3
|
||||
GIT_REPOSITORY "https://github.com/Helloyunho/SDL3-uwp.git"
|
||||
GIT_TAG "main"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
else()
|
||||
FetchContent_Declare(
|
||||
SDL3
|
||||
GIT_REPOSITORY "https://github.com/libsdl-org/SDL.git"
|
||||
GIT_TAG "main"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
endif()
|
||||
FetchContent_MakeAvailable(SDL3)
|
||||
|
||||
FetchContent_Declare(
|
||||
iniparser
|
||||
GIT_REPOSITORY "https://gitlab.com/iniparser/iniparser.git"
|
||||
GIT_TAG "main"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
block()
|
||||
set(BUILD_DOCS off)
|
||||
set(BUILD_SHARED_LIBS off)
|
||||
FetchContent_MakeAvailable(iniparser)
|
||||
target_link_libraries(Isle::iniparser INTERFACE iniparser-static)
|
||||
endblock()
|
||||
FetchContent_Declare(
|
||||
iniparser
|
||||
GIT_REPOSITORY "https://gitlab.com/iniparser/iniparser.git"
|
||||
GIT_TAG "main"
|
||||
EXCLUDE_FROM_ALL
|
||||
)
|
||||
block()
|
||||
set(BUILD_DOCS off)
|
||||
set(BUILD_SHARED_LIBS off)
|
||||
FetchContent_MakeAvailable(iniparser)
|
||||
target_link_libraries(Isle::iniparser INTERFACE iniparser-static)
|
||||
endblock()
|
||||
else()
|
||||
# find_package looks for already-installed system packages.
|
||||
# Configure with `-DCMAKE_PREFIX_PATH="/path/to/package1;/path/to/package2"`
|
||||
# to add search paths.
|
||||
find_package(SDL3 CONFIG REQUIRED)
|
||||
# find_package looks for already-installed system packages.
|
||||
# Configure with `-DCMAKE_PREFIX_PATH="/path/to/package1;/path/to/package2"`
|
||||
# to add search paths.
|
||||
find_package(SDL3 CONFIG REQUIRED)
|
||||
|
||||
find_package(iniparser REQUIRED CONFIG COMPONENTS shared)
|
||||
target_link_libraries(Isle::iniparser INTERFACE iniparser-shared)
|
||||
find_package(iniparser REQUIRED CONFIG COMPONENTS shared)
|
||||
target_link_libraries(Isle::iniparser INTERFACE iniparser-shared)
|
||||
endif()
|
||||
|
||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
if (ENABLE_CLANG_TIDY)
|
||||
find_program(CLANG_TIDY_BIN NAMES "clang-tidy" ENV "LLVM_ROOT" REQUIRED)
|
||||
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_BIN}")
|
||||
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}")
|
||||
find_program(CLANG_TIDY_BIN NAMES "clang-tidy" ENV "LLVM_ROOT" REQUIRED)
|
||||
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_BIN}")
|
||||
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_BIN}")
|
||||
endif()
|
||||
|
||||
if (ISLE_ASAN)
|
||||
@ -109,26 +133,26 @@ add_subdirectory(miniwin EXCLUDE_FROM_ALL)
|
||||
set(isle_targets)
|
||||
|
||||
function(add_cxx_warning WARNING)
|
||||
if (ISLE_WERROR)
|
||||
set(compiler_option "-Werror=${WARNING}")
|
||||
else()
|
||||
set(compiler_option "-W${WARNING}")
|
||||
endif()
|
||||
string(MAKE_C_IDENTIFIER "COMPILER_SUPPORTS${compiler_option}" varname)
|
||||
if (ISLE_WERROR)
|
||||
set(compiler_option "-Werror=${WARNING}")
|
||||
else()
|
||||
set(compiler_option "-W${WARNING}")
|
||||
endif()
|
||||
string(MAKE_C_IDENTIFIER "COMPILER_SUPPORTS${compiler_option}" varname)
|
||||
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_FLAGS "${compiler_option} ")
|
||||
if (MSVC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "/WX")
|
||||
else()
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
endif()
|
||||
check_cxx_source_compiles("int main() { return 0; }" ${varname})
|
||||
cmake_pop_check_state()
|
||||
cmake_push_check_state(RESET)
|
||||
set(CMAKE_REQUIRED_FLAGS "${compiler_option} ")
|
||||
if (MSVC)
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "/WX")
|
||||
else()
|
||||
string(APPEND CMAKE_REQUIRED_FLAGS "-Werror")
|
||||
endif()
|
||||
check_cxx_source_compiles("int main() { return 0; }" ${varname})
|
||||
cmake_pop_check_state()
|
||||
|
||||
if (${varname})
|
||||
add_compile_options(${compiler_option})
|
||||
endif()
|
||||
if (${varname})
|
||||
add_compile_options(${compiler_option})
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
add_subdirectory(3rdparty EXCLUDE_FROM_ALL SYSTEM)
|
||||
@ -148,6 +172,7 @@ add_library(lego1
|
||||
target_precompile_headers(lego1 PRIVATE "LEGO1/lego1_pch.h")
|
||||
set_property(TARGET lego1 PROPERTY DEFINE_SYMBOL "LEGO1_DLL")
|
||||
target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/util>")
|
||||
target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/extensions/include>")
|
||||
target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/LEGO1>")
|
||||
target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/LEGO1/omni/include>")
|
||||
target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/LEGO1/lego/sources>")
|
||||
@ -156,6 +181,8 @@ target_include_directories(lego1 PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/L
|
||||
target_link_libraries(lego1 PRIVATE SDL3::SDL3)
|
||||
target_link_libraries(lego1 PUBLIC SDL3::Headers)
|
||||
target_link_libraries(lego1 PRIVATE $<$<BOOL:${ISLE_USE_DX5}>:DirectX5::DirectX5>)
|
||||
# Allow unconditional include of miniwin/miniwind3d.h
|
||||
target_link_libraries(lego1 PRIVATE miniwin-headers)
|
||||
if(WIN32)
|
||||
set_property(TARGET lego1 PROPERTY PREFIX "")
|
||||
endif()
|
||||
@ -286,10 +313,10 @@ target_sources(lego1 PRIVATE
|
||||
LEGO1/omni/src/common/mxcompositepresenter.cpp
|
||||
LEGO1/omni/src/common/mxcore.cpp
|
||||
LEGO1/omni/src/common/mxdebug.cpp
|
||||
LEGO1/omni/src/common/mxmediamanager.cpp
|
||||
LEGO1/omni/src/common/mxmediapresenter.cpp
|
||||
LEGO1/omni/src/common/mxmisc.cpp
|
||||
LEGO1/omni/src/common/mxobjectfactory.cpp
|
||||
LEGO1/omni/src/common/mxpresentationmanager.cpp
|
||||
LEGO1/omni/src/common/mxpresenter.cpp
|
||||
LEGO1/omni/src/common/mxstring.cpp
|
||||
LEGO1/omni/src/common/mxticklemanager.cpp
|
||||
@ -435,9 +462,6 @@ target_sources(lego1 PRIVATE
|
||||
LEGO1/lego/legoomni/src/race/raceskel.cpp
|
||||
LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp
|
||||
LEGO1/lego/legoomni/src/video/legopartpresenter.cpp
|
||||
@ -465,11 +489,22 @@ if (NOT ISLE_MINIWIN)
|
||||
target_compile_definitions(lego1 PRIVATE DIRECTINPUT_VERSION=0x0500)
|
||||
endif()
|
||||
|
||||
if (ISLE_EXTENSIONS)
|
||||
target_compile_definitions(lego1 PUBLIC EXTENSIONS)
|
||||
target_sources(lego1 PRIVATE
|
||||
extensions/src/extensions.cpp
|
||||
extensions/src/textureloader.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if (ISLE_BUILD_APP)
|
||||
add_executable(isle WIN32
|
||||
ISLE/res/isle.rc
|
||||
ISLE/isleapp.cpp
|
||||
ISLE/islefiles.cpp
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/arrow_bmp.h
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/busy_bmp.h
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/no_bmp.h
|
||||
)
|
||||
list(APPEND isle_targets isle)
|
||||
if (WIN32)
|
||||
@ -490,6 +525,9 @@ if (ISLE_BUILD_APP)
|
||||
# Allow unconditional include of miniwin/miniwindevice.h
|
||||
target_link_libraries(isle PRIVATE miniwin-headers)
|
||||
|
||||
# Vector math
|
||||
target_link_libraries(isle PRIVATE Vec::Vec)
|
||||
|
||||
# Link DSOUND and WINMM
|
||||
if (WIN32)
|
||||
target_link_libraries(isle PRIVATE winmm)
|
||||
@ -513,19 +551,71 @@ if (ISLE_BUILD_APP)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
target_sources(isle PRIVATE
|
||||
ISLE/emscripten/config.cpp
|
||||
ISLE/emscripten/events.cpp
|
||||
ISLE/emscripten/filesystem.cpp
|
||||
ISLE/emscripten/haptic.cpp
|
||||
ISLE/emscripten/messagebox.cpp
|
||||
ISLE/emscripten/window.cpp
|
||||
)
|
||||
target_compile_definitions(isle PRIVATE "ISLE_EMSCRIPTEN_HOST=\"${ISLE_EMSCRIPTEN_HOST}\"")
|
||||
set_property(TARGET isle PROPERTY SUFFIX ".html")
|
||||
endif()
|
||||
if(NINTENDO_3DS)
|
||||
target_sources(isle PRIVATE
|
||||
ISLE/3ds/apthooks.cpp
|
||||
ISLE/3ds/config.cpp
|
||||
)
|
||||
endif()
|
||||
if(WINDOWS_STORE)
|
||||
target_sources(isle PRIVATE
|
||||
ISLE/xbox_one_series/config.cpp
|
||||
)
|
||||
endif()
|
||||
if (IOS)
|
||||
target_sources(isle PRIVATE
|
||||
ISLE/ios/config.cpp
|
||||
)
|
||||
endif()
|
||||
if(Python3_FOUND)
|
||||
if(NOT DEFINED PYTHON_PIL_AVAILABLE)
|
||||
execute_process(
|
||||
COMMAND ${Python3_EXECUTABLE} -c "import PIL; print('pil')"
|
||||
RESULT_VARIABLE PIL_RESULT
|
||||
OUTPUT_VARIABLE PIL_OUTPUT
|
||||
ERROR_QUIET
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
if(PIL_RESULT EQUAL 0 AND PIL_OUTPUT STREQUAL "pil")
|
||||
set(PIL_AVAILABLE 1)
|
||||
else()
|
||||
message(STATUS "Python PIL not found, using pre-generated headers.")
|
||||
set(PIL_AVAILABLE 0)
|
||||
endif()
|
||||
set(PYTHON_PIL_AVAILABLE ${PIL_AVAILABLE} CACHE BOOL "Is Python3 Pillow available?")
|
||||
endif()
|
||||
if(PYTHON_PIL_AVAILABLE)
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/arrow_bmp.h
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/busy_bmp.h
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/no_bmp.h
|
||||
COMMAND ${Python3_EXECUTABLE} tools/curpng2h.py ISLE/res/arrow.png ISLE/res/busy.png ISLE/res/no.png
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
DEPENDS
|
||||
${CMAKE_SOURCE_DIR}/tools/curpng2h.py
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/arrow.png
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/busy.png
|
||||
${CMAKE_SOURCE_DIR}/ISLE/res/no.png
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (ISLE_BUILD_CONFIG)
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Widgets)
|
||||
qt_standard_project_setup()
|
||||
qt_add_executable(config WIN32
|
||||
qt_add_executable(isle-config WIN32
|
||||
LEGO1/mxdirectx/mxdirectxinfo.cpp
|
||||
LEGO1/mxdirectx/legodxinfo.cpp
|
||||
CONFIG/config.cpp
|
||||
@ -535,22 +625,22 @@ if (ISLE_BUILD_CONFIG)
|
||||
CONFIG/res/config.rc
|
||||
CONFIG/res/config.qrc
|
||||
)
|
||||
target_link_libraries(config PRIVATE Qt6::Core Qt6::Widgets)
|
||||
set_property(TARGET config PROPERTY AUTOMOC ON)
|
||||
set_property(TARGET config PROPERTY AUTORCC ON)
|
||||
set_property(TARGET config PROPERTY AUTOUIC ON)
|
||||
set_property(TARGET config PROPERTY AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/CONFIG/res")
|
||||
list(APPEND isle_targets config)
|
||||
target_compile_definitions(config PRIVATE _AFXDLL MXDIRECTX_FOR_CONFIG)
|
||||
target_include_directories(config PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/LEGO1")
|
||||
target_include_directories(config PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/util>")
|
||||
target_link_libraries(isle-config PRIVATE Qt6::Core Qt6::Widgets)
|
||||
set_property(TARGET isle-config PROPERTY AUTOMOC ON)
|
||||
set_property(TARGET isle-config PROPERTY AUTORCC ON)
|
||||
set_property(TARGET isle-config PROPERTY AUTOUIC ON)
|
||||
set_property(TARGET isle-config PROPERTY AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/CONFIG/res")
|
||||
list(APPEND isle_targets isle-config)
|
||||
target_compile_definitions(isle-config PRIVATE _AFXDLL MXDIRECTX_FOR_CONFIG)
|
||||
target_include_directories(isle-config PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/LEGO1")
|
||||
target_include_directories(isle-config PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/util>")
|
||||
if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 14)
|
||||
target_link_libraries(config PRIVATE DirectX5::DirectX5)
|
||||
target_link_libraries(isle-config PRIVATE DirectX5::DirectX5)
|
||||
endif()
|
||||
target_compile_definitions(config PRIVATE DIRECT3D_VERSION=0x500)
|
||||
target_link_libraries(config PRIVATE SDL3::SDL3 Isle::iniparser)
|
||||
target_compile_definitions(isle-config PRIVATE DIRECT3D_VERSION=0x500)
|
||||
target_link_libraries(isle-config PRIVATE SDL3::SDL3 Isle::iniparser)
|
||||
if (NOT ISLE_MINIWIN)
|
||||
target_link_libraries(config PRIVATE ddraw dxguid)
|
||||
target_link_libraries(isle-config PRIVATE ddraw dxguid)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -564,8 +654,14 @@ if (MSVC)
|
||||
if (TARGET isle)
|
||||
target_compile_definitions(isle PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||
endif()
|
||||
if (TARGET config)
|
||||
target_compile_definitions(config PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||
if (TARGET isle-config)
|
||||
target_compile_definitions(isle-config PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||
endif()
|
||||
if (TARGET iniparser-static)
|
||||
target_compile_definitions(iniparser-static PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||
endif()
|
||||
if (TARGET libsmacker)
|
||||
target_compile_definitions(libsmacker PRIVATE "_CRT_SECURE_NO_WARNINGS")
|
||||
endif()
|
||||
endif()
|
||||
# Visual Studio 2017 version 15.7 needs "/Zc:__cplusplus" for __cplusplus
|
||||
@ -574,8 +670,8 @@ if (MSVC)
|
||||
if (TARGET isle)
|
||||
target_compile_options(isle PRIVATE "-Zc:__cplusplus")
|
||||
endif()
|
||||
if (TARGET config)
|
||||
target_compile_options(config PRIVATE "-Zc:__cplusplus")
|
||||
if (TARGET isle-config)
|
||||
target_compile_options(isle-config PRIVATE "-Zc:__cplusplus")
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
@ -624,17 +720,46 @@ else()
|
||||
include(GNUInstallDirs)
|
||||
endif()
|
||||
|
||||
set(ISLE_PACKAGE_NAME "${CMAKE_SYSTEM_NAME}-${CMAKE_SYSTEM_PROCESSOR}" CACHE STRING "Platform name of the package")
|
||||
string(REPLACE ";" "-" ISLE_CPUS_STRING "${ISLE_CPUS}")
|
||||
string(TOLOWER "${ISLE_CPUS_STRING}" ISLE_CPUS_STRING)
|
||||
if (WINDOWS_STORE)
|
||||
set(ISLE_PACKAGE_NAME "Xbox_One_Series_XS-${ISLE_CPUS_STRING}" CACHE STRING "Platform name of the package")
|
||||
else()
|
||||
set(ISLE_PACKAGE_NAME "${CMAKE_SYSTEM_NAME}-${ISLE_CPUS_STRING}" CACHE STRING "Platform name of the package")
|
||||
endif()
|
||||
if(BUILD_SHARED_LIBS)
|
||||
list(APPEND install_extra_targets lego1)
|
||||
endif()
|
||||
install(TARGETS isle ${install_extra_targets}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
)
|
||||
if (ISLE_BUILD_CONFIG)
|
||||
install(TARGETS config
|
||||
if (NOT (NINTENDO_3DS OR WINDOWS_STORE))
|
||||
install(TARGETS isle ${install_extra_targets}
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
if (ISLE_BUILD_CONFIG)
|
||||
if(WIN32)
|
||||
find_program(WINDEPLOYQT_EXECUTABLE windeployqt)
|
||||
if(WINDEPLOYQT_EXECUTABLE)
|
||||
install(CODE "message(STATUS \"Running windeployqt with minimal dependencies\")
|
||||
execute_process(COMMAND \"${WINDEPLOYQT_EXECUTABLE}\"
|
||||
\"$<TARGET_FILE:isle-config>\"
|
||||
--dir QTLibs
|
||||
--no-compiler-runtime
|
||||
--no-opengl-sw
|
||||
--no-system-d3d-compiler
|
||||
--no-translations
|
||||
--no-quick-import
|
||||
)"
|
||||
)
|
||||
install(DIRECTORY "Build/QTLibs/" DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
else()
|
||||
message(STATUS "windeployqt not found: Qt binaries will not be installed")
|
||||
endif()
|
||||
endif()
|
||||
install(TARGETS isle-config
|
||||
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
BUNDLE DESTINATION "."
|
||||
)
|
||||
endif()
|
||||
if(EMSCRIPTEN)
|
||||
@ -643,11 +768,77 @@ if(EMSCRIPTEN)
|
||||
)
|
||||
endif()
|
||||
|
||||
add_subdirectory(packaging)
|
||||
|
||||
set(CPACK_PACKAGE_DIRECTORY "dist")
|
||||
set(CPACK_PACKAGE_FILE_NAME "isle-${PROJECT_VERSION}-${ISLE_PACKAGE_NAME}-${CMAKE_SYSTEM_PROCESSOR}")
|
||||
if(MSVC)
|
||||
set(CPACK_PACKAGE_FILE_NAME "isle-${PROJECT_VERSION}-${ISLE_PACKAGE_NAME}")
|
||||
if(NINTENDO_3DS)
|
||||
find_program(BANNERTOOL bannertool)
|
||||
find_program(MAKEROM makerom)
|
||||
|
||||
ctr_generate_smdh(isle.smdh
|
||||
NAME "LEGO Island"
|
||||
TITLE "LEGO Island"
|
||||
DESCRIPTION "LEGO Island for the Nintendo 3DS"
|
||||
AUTHOR "isledecomp/isle-portable"
|
||||
VERSION "${PROJECT_VERSION}"
|
||||
ICON "${CMAKE_SOURCE_DIR}/packaging/3ds/icon.png"
|
||||
)
|
||||
|
||||
ctr_create_3dsx(isle SMDH isle.smdh)
|
||||
if(BANNERTOOL AND MAKEROM)
|
||||
add_custom_command(
|
||||
OUTPUT "isle.bnr"
|
||||
COMMAND "${BANNERTOOL}" makebanner
|
||||
-i "${CMAKE_SOURCE_DIR}/packaging/3ds/banner.png"
|
||||
-a "${CMAKE_SOURCE_DIR}/packaging/3ds/banner.wav"
|
||||
-o "isle.bnr"
|
||||
DEPENDS "${CMAKE_SOURCE_DIR}/packaging/3ds/banner.png" "${CMAKE_SOURCE_DIR}/packaging/3ds/banner.wav"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT "isle.cia"
|
||||
COMMAND "${MAKEROM}"
|
||||
-f cia
|
||||
-exefslogo
|
||||
-o "isle.cia"
|
||||
-rsf "${CMAKE_SOURCE_DIR}/packaging/3ds/template.rsf"
|
||||
-major "${CMAKE_PROJECT_VERSION_MAJOR}"
|
||||
-minor "${CMAKE_PROJECT_VERSION_MINOR}"
|
||||
-micro 0
|
||||
-icon "isle.smdh"
|
||||
-banner "isle.bnr"
|
||||
-elf "isle.elf"
|
||||
DEPENDS "${CMAKE_SOURCE_DIR}/packaging/3ds/template.rsf" "isle.smdh" "isle.bnr"
|
||||
COMMENT "Building CIA executable target isle.cia"
|
||||
VERBATIM
|
||||
)
|
||||
|
||||
add_custom_target("isle_cia" ALL DEPENDS "isle.cia" isle)
|
||||
install(FILES "$<TARGET_FILE_DIR:isle>/isle.cia" DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
endif()
|
||||
install(FILES "$<TARGET_FILE_DIR:isle>/isle.3dsx" DESTINATION "${CMAKE_INSTALL_BINDIR}")
|
||||
endif()
|
||||
if(WINDOWS_STORE)
|
||||
install(
|
||||
DIRECTORY
|
||||
"${CMAKE_BINARY_DIR}/AppPackages/isle/"
|
||||
DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
FILES_MATCHING PATTERN "*/Dependencies/x64/Microsoft.VCLibs.x64*.14.00.appx"
|
||||
PATTERN "*/*.msix"
|
||||
PATTERN "*/*.msixbundle")
|
||||
endif()
|
||||
if(MSVC OR IOS)
|
||||
set(CPACK_GENERATOR ZIP)
|
||||
if(IOS)
|
||||
set(CPACK_ARCHIVE_FILE_EXTENSION ".ipa")
|
||||
set(CPACK_INCLUDE_TOPLEVEL_DIRECTORY OFF)
|
||||
endif()
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(CPACK_GENERATOR DragNDrop)
|
||||
else()
|
||||
set(CPACK_GENERATOR TGZ)
|
||||
endif()
|
||||
|
||||
include(CPack)
|
||||
|
||||
@ -11,6 +11,10 @@
|
||||
#include "res/resource.h"
|
||||
|
||||
#include <QKeyEvent>
|
||||
#include <QMessageBox>
|
||||
#include <QProcess>
|
||||
#include <SDL3/SDL.h>
|
||||
#include <cmath>
|
||||
#include <mxdirectx/legodxinfo.h>
|
||||
#include <ui_maindialog.h>
|
||||
|
||||
@ -52,13 +56,21 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent)
|
||||
this,
|
||||
&CMainDialog::OnRadiobuttonTextureHighQuality
|
||||
);
|
||||
|
||||
connect(m_ui->windowedRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioWindowed);
|
||||
connect(m_ui->fullscreenRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioFullscreen);
|
||||
connect(m_ui->exFullscreenRadioButton, &QRadioButton::toggled, this, &CMainDialog::OnRadioExclusiveFullscreen);
|
||||
connect(m_ui->devicesList, &QListWidget::currentRowChanged, this, &CMainDialog::OnList3DevicesSelectionChanged);
|
||||
connect(m_ui->musicCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxMusic);
|
||||
connect(m_ui->sound3DCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckbox3DSound);
|
||||
connect(m_ui->joystickCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxJoystick);
|
||||
connect(m_ui->fullscreenCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxFullscreen);
|
||||
connect(m_ui->rumbleCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxRumble);
|
||||
connect(m_ui->textureCheckBox, &QCheckBox::toggled, this, &CMainDialog::OnCheckboxTexture);
|
||||
connect(m_ui->touchComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TouchControlsChanged);
|
||||
connect(m_ui->transitionTypeComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::TransitionTypeChanged);
|
||||
connect(m_ui->exFullResComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::ExclusiveResolutionChanged);
|
||||
connect(m_ui->okButton, &QPushButton::clicked, this, &CMainDialog::accept);
|
||||
connect(m_ui->cancelButton, &QPushButton::clicked, this, &CMainDialog::reject);
|
||||
connect(m_ui->launchButton, &QPushButton::clicked, this, &CMainDialog::launch);
|
||||
|
||||
connect(m_ui->dataPathOpen, &QPushButton::clicked, this, &CMainDialog::SelectDataPathDialog);
|
||||
connect(m_ui->savePathOpen, &QPushButton::clicked, this, &CMainDialog::SelectSavePathDialog);
|
||||
@ -66,10 +78,57 @@ CMainDialog::CMainDialog(QWidget* pParent) : QDialog(pParent)
|
||||
connect(m_ui->dataPath, &QLineEdit::editingFinished, this, &CMainDialog::DataPathEdited);
|
||||
connect(m_ui->savePath, &QLineEdit::editingFinished, this, &CMainDialog::SavePathEdited);
|
||||
|
||||
connect(m_ui->texturePathOpen, &QPushButton::clicked, this, &CMainDialog::SelectTexturePathDialog);
|
||||
connect(m_ui->texturePath, &QLineEdit::editingFinished, this, &CMainDialog::TexturePathEdited);
|
||||
|
||||
connect(m_ui->maxLoDSlider, &QSlider::valueChanged, this, &CMainDialog::MaxLoDChanged);
|
||||
connect(m_ui->maxLoDSlider, &QSlider::sliderMoved, this, &CMainDialog::MaxLoDChanged);
|
||||
connect(m_ui->maxActorsSlider, &QSlider::valueChanged, this, &CMainDialog::MaxActorsChanged);
|
||||
connect(m_ui->maxActorsSlider, &QSlider::sliderMoved, this, &CMainDialog::MaxActorsChanged);
|
||||
|
||||
connect(m_ui->msaaSlider, &QSlider::valueChanged, this, &CMainDialog::MSAAChanged);
|
||||
connect(m_ui->msaaSlider, &QSlider::sliderMoved, this, &CMainDialog::MSAAChanged);
|
||||
connect(m_ui->AFSlider, &QSlider::valueChanged, this, &CMainDialog::AFChanged);
|
||||
connect(m_ui->AFSlider, &QSlider::sliderMoved, this, &CMainDialog::AFChanged);
|
||||
|
||||
connect(m_ui->aspectRatioComboBox, &QComboBox::currentIndexChanged, this, &CMainDialog::AspectRatioChanged);
|
||||
connect(m_ui->xResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::XResChanged);
|
||||
connect(m_ui->yResSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::YResChanged);
|
||||
connect(m_ui->framerateSpinBox, &QSpinBox::valueChanged, this, &CMainDialog::FramerateChanged);
|
||||
|
||||
layout()->setSizeConstraint(QLayout::SetFixedSize);
|
||||
|
||||
if (currentConfigApp->m_ram_quality_limit != 0) {
|
||||
m_modified = true;
|
||||
const QString ramError = QString("Insufficient RAM!");
|
||||
m_ui->sound3DCheckBox->setChecked(false);
|
||||
m_ui->sound3DCheckBox->setEnabled(false);
|
||||
m_ui->sound3DCheckBox->setToolTip(ramError);
|
||||
m_ui->modelQualityHighRadioButton->setEnabled(false);
|
||||
m_ui->modelQualityHighRadioButton->setToolTip(ramError);
|
||||
m_ui->modelQualityLowRadioButton->setEnabled(true);
|
||||
if (currentConfigApp->m_ram_quality_limit == 2) {
|
||||
m_ui->modelQualityLowRadioButton->setChecked(true);
|
||||
m_ui->modelQualityMediumRadioButton->setEnabled(false);
|
||||
m_ui->modelQualityMediumRadioButton->setToolTip(ramError);
|
||||
m_ui->maxLoDSlider->setMaximum(30);
|
||||
m_ui->maxActorsSlider->setMaximum(15);
|
||||
}
|
||||
else {
|
||||
m_ui->modelQualityMediumRadioButton->setChecked(true);
|
||||
m_ui->modelQualityMediumRadioButton->setEnabled(true);
|
||||
m_ui->maxLoDSlider->setMaximum(40);
|
||||
m_ui->maxActorsSlider->setMaximum(30);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_ui->sound3DCheckBox->setEnabled(true);
|
||||
m_ui->modelQualityLowRadioButton->setEnabled(true);
|
||||
m_ui->modelQualityMediumRadioButton->setEnabled(true);
|
||||
m_ui->modelQualityHighRadioButton->setEnabled(true);
|
||||
m_ui->maxLoDSlider->setMaximum(60);
|
||||
m_ui->maxActorsSlider->setMaximum(40);
|
||||
}
|
||||
}
|
||||
|
||||
CMainDialog::~CMainDialog()
|
||||
@ -87,7 +146,7 @@ bool CMainDialog::OnInitDialog()
|
||||
int device_i = 0;
|
||||
int selected = 0;
|
||||
char device_name[256];
|
||||
const list<MxDriver>& driver_list = enumerator->GetDriverList();
|
||||
const list<MxDriver>& driver_list = enumerator->m_ddInfo;
|
||||
for (list<MxDriver>::const_iterator it_driver = driver_list.begin(); it_driver != driver_list.end(); it_driver++) {
|
||||
const MxDriver& driver = *it_driver;
|
||||
for (list<Direct3DDeviceInfo>::const_iterator it_device = driver.m_devices.begin();
|
||||
@ -111,7 +170,27 @@ bool CMainDialog::OnInitDialog()
|
||||
m_ui->devicesList->setCurrentRow(selected);
|
||||
|
||||
m_ui->maxLoDSlider->setValue((int) currentConfigApp->m_max_lod * 10);
|
||||
m_ui->LoDNum->setNum((int) currentConfigApp->m_max_lod * 10);
|
||||
m_ui->maxActorsSlider->setValue(currentConfigApp->m_max_actors);
|
||||
m_ui->maxActorsNum->setNum(currentConfigApp->m_max_actors);
|
||||
|
||||
m_ui->exFullResComboBox->clear();
|
||||
|
||||
int displayModeCount;
|
||||
displayModes = SDL_GetFullscreenDisplayModes(SDL_GetPrimaryDisplay(), &displayModeCount);
|
||||
|
||||
for (int i = 0; i < displayModeCount; ++i) {
|
||||
QString mode =
|
||||
QString("%1x%2 @ %3Hz").arg(displayModes[i]->w).arg(displayModes[i]->h).arg(displayModes[i]->refresh_rate);
|
||||
m_ui->exFullResComboBox->addItem(mode);
|
||||
|
||||
if ((displayModes[i]->w == currentConfigApp->m_exf_x_res) &&
|
||||
(displayModes[i]->h == currentConfigApp->m_exf_y_res) &&
|
||||
(displayModes[i]->refresh_rate == currentConfigApp->m_exf_fps)) {
|
||||
m_ui->exFullResComboBox->setCurrentIndex(i);
|
||||
}
|
||||
}
|
||||
|
||||
UpdateInterface();
|
||||
return true;
|
||||
}
|
||||
@ -155,6 +234,30 @@ void CMainDialog::accept()
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
void CMainDialog::launch()
|
||||
{
|
||||
if (m_modified) {
|
||||
currentConfigApp->WriteRegisterSettings();
|
||||
}
|
||||
|
||||
QDir::setCurrent(QCoreApplication::applicationDirPath());
|
||||
|
||||
QMessageBox msgBox = QMessageBox(
|
||||
QMessageBox::Warning,
|
||||
QString("Error!"),
|
||||
QString("Unable to locate isle executable!"),
|
||||
QMessageBox::Close
|
||||
);
|
||||
|
||||
if (!QProcess::startDetached("./isle")) { // Check in isle-config directory
|
||||
if (!QProcess::startDetached("isle")) { // Check in $PATH
|
||||
msgBox.exec();
|
||||
}
|
||||
}
|
||||
|
||||
QDialog::accept();
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x00404360
|
||||
void CMainDialog::UpdateInterface()
|
||||
{
|
||||
@ -182,11 +285,46 @@ void CMainDialog::UpdateInterface()
|
||||
else {
|
||||
m_ui->textureQualityHighRadioButton->setChecked(true);
|
||||
}
|
||||
m_ui->joystickCheckBox->setChecked(currentConfigApp->m_use_joystick);
|
||||
if (currentConfigApp->m_exclusive_full_screen) {
|
||||
m_ui->exFullscreenRadioButton->setChecked(true);
|
||||
m_ui->resolutionBox->setEnabled(false);
|
||||
m_ui->exFullResContainer->setEnabled(true);
|
||||
}
|
||||
else {
|
||||
m_ui->resolutionBox->setEnabled(true);
|
||||
m_ui->exFullResContainer->setEnabled(false);
|
||||
if (currentConfigApp->m_full_screen) {
|
||||
m_ui->fullscreenRadioButton->setChecked(true);
|
||||
}
|
||||
else {
|
||||
m_ui->windowedRadioButton->setChecked(true);
|
||||
}
|
||||
}
|
||||
m_ui->musicCheckBox->setChecked(currentConfigApp->m_music);
|
||||
m_ui->fullscreenCheckBox->setChecked(currentConfigApp->m_full_screen);
|
||||
m_ui->rumbleCheckBox->setChecked(currentConfigApp->m_haptic);
|
||||
m_ui->touchComboBox->setCurrentIndex(currentConfigApp->m_touch_scheme);
|
||||
m_ui->transitionTypeComboBox->setCurrentIndex(currentConfigApp->m_transition_type);
|
||||
m_ui->dataPath->setText(QString::fromStdString(currentConfigApp->m_cd_path));
|
||||
m_ui->savePath->setText(QString::fromStdString(currentConfigApp->m_save_path));
|
||||
|
||||
m_ui->textureCheckBox->setChecked(currentConfigApp->m_texture_load);
|
||||
m_ui->texturePath->setText(QString::fromStdString(currentConfigApp->m_texture_path));
|
||||
m_ui->texturePath->setEnabled(currentConfigApp->m_texture_load);
|
||||
m_ui->texturePathOpen->setEnabled(currentConfigApp->m_texture_load);
|
||||
|
||||
m_ui->aspectRatioComboBox->setCurrentIndex(currentConfigApp->m_aspect_ratio);
|
||||
m_ui->xResSpinBox->setValue(currentConfigApp->m_x_res);
|
||||
m_ui->yResSpinBox->setValue(currentConfigApp->m_y_res);
|
||||
m_ui->framerateSpinBox->setValue(static_cast<int>(std::round(1000.0f / currentConfigApp->m_frame_delta)));
|
||||
|
||||
m_ui->maxLoDSlider->setValue((int) (currentConfigApp->m_max_lod * 10));
|
||||
m_ui->LoDNum->setNum(currentConfigApp->m_max_lod);
|
||||
m_ui->maxActorsSlider->setValue(currentConfigApp->m_max_actors);
|
||||
m_ui->maxActorsNum->setNum(currentConfigApp->m_max_actors);
|
||||
m_ui->msaaSlider->setValue(log2(currentConfigApp->m_msaa));
|
||||
m_ui->msaaNum->setNum(currentConfigApp->m_msaa);
|
||||
m_ui->AFSlider->setValue(log2(currentConfigApp->m_anisotropy));
|
||||
m_ui->AFNum->setNum(currentConfigApp->m_anisotropy);
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x004045e0
|
||||
@ -246,12 +384,40 @@ void CMainDialog::OnRadiobuttonTextureHighQuality(bool checked)
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x00404790
|
||||
void CMainDialog::OnCheckboxJoystick(bool checked)
|
||||
void CMainDialog::OnRadioWindowed(bool checked)
|
||||
{
|
||||
currentConfigApp->m_use_joystick = checked;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
if (checked) {
|
||||
currentConfigApp->m_full_screen = false;
|
||||
currentConfigApp->m_exclusive_full_screen = false;
|
||||
m_ui->resolutionBox->setEnabled(true);
|
||||
m_ui->exFullResContainer->setEnabled(false);
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CMainDialog::OnRadioFullscreen(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
currentConfigApp->m_full_screen = true;
|
||||
currentConfigApp->m_exclusive_full_screen = false;
|
||||
m_ui->resolutionBox->setEnabled(true);
|
||||
m_ui->exFullResContainer->setEnabled(false);
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
}
|
||||
|
||||
void CMainDialog::OnRadioExclusiveFullscreen(bool checked)
|
||||
{
|
||||
if (checked) {
|
||||
currentConfigApp->m_full_screen = true;
|
||||
currentConfigApp->m_exclusive_full_screen = true;
|
||||
m_ui->resolutionBox->setEnabled(false);
|
||||
m_ui->exFullResContainer->setEnabled(true);
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x004048c0
|
||||
@ -262,9 +428,39 @@ void CMainDialog::OnCheckboxMusic(bool checked)
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::OnCheckboxFullscreen(bool checked)
|
||||
void CMainDialog::OnCheckboxRumble(bool checked)
|
||||
{
|
||||
currentConfigApp->m_full_screen = checked;
|
||||
currentConfigApp->m_haptic = checked;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::OnCheckboxTexture(bool checked)
|
||||
{
|
||||
currentConfigApp->m_texture_load = checked;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::TouchControlsChanged(int index)
|
||||
{
|
||||
currentConfigApp->m_touch_scheme = index;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::TransitionTypeChanged(int index)
|
||||
{
|
||||
currentConfigApp->m_transition_type = index;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::ExclusiveResolutionChanged(int index)
|
||||
{
|
||||
currentConfigApp->m_exf_x_res = displayModes[index]->w;
|
||||
currentConfigApp->m_exf_y_res = displayModes[index]->h;
|
||||
currentConfigApp->m_exf_fps = displayModes[index]->refresh_rate;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
@ -341,10 +537,112 @@ void CMainDialog::MaxLoDChanged(int value)
|
||||
{
|
||||
currentConfigApp->m_max_lod = static_cast<float>(value) / 10.0f;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::MaxActorsChanged(int value)
|
||||
{
|
||||
currentConfigApp->m_max_actors = value;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::MSAAChanged(int value)
|
||||
{
|
||||
currentConfigApp->m_msaa = exp2(value);
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::AFChanged(int value)
|
||||
{
|
||||
currentConfigApp->m_anisotropy = exp2(value);
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::SelectTexturePathDialog()
|
||||
{
|
||||
QString texture_path = QString::fromStdString(currentConfigApp->m_texture_path);
|
||||
texture_path = QFileDialog::getExistingDirectory(
|
||||
this,
|
||||
tr("Open Directory"),
|
||||
texture_path,
|
||||
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks
|
||||
);
|
||||
|
||||
QDir texture_dir = QDir(texture_path);
|
||||
|
||||
if (texture_dir.exists()) {
|
||||
currentConfigApp->m_texture_path = texture_dir.absolutePath().toStdString();
|
||||
m_modified = true;
|
||||
}
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::TexturePathEdited()
|
||||
{
|
||||
QDir texture_dir = QDir(m_ui->texturePath->text());
|
||||
|
||||
if (texture_dir.exists()) {
|
||||
currentConfigApp->m_texture_path = texture_dir.absolutePath().toStdString();
|
||||
m_modified = true;
|
||||
}
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::AspectRatioChanged(int index)
|
||||
{
|
||||
currentConfigApp->m_aspect_ratio = index;
|
||||
EnsureAspectRatio();
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::XResChanged(int i)
|
||||
{
|
||||
currentConfigApp->m_x_res = i;
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::YResChanged(int i)
|
||||
{
|
||||
currentConfigApp->m_y_res = i;
|
||||
EnsureAspectRatio();
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
void CMainDialog::EnsureAspectRatio()
|
||||
{
|
||||
if (currentConfigApp->m_aspect_ratio != 3) {
|
||||
m_ui->xResSpinBox->setReadOnly(true);
|
||||
switch (currentConfigApp->m_aspect_ratio) {
|
||||
case 0: {
|
||||
float standardAspect = 4.0f / 3.0f;
|
||||
currentConfigApp->m_x_res = static_cast<int>(std::round((currentConfigApp->m_y_res) * standardAspect));
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
float wideAspect = 16.0f / 9.0f;
|
||||
currentConfigApp->m_x_res = static_cast<int>(std::round((currentConfigApp->m_y_res) * wideAspect));
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
currentConfigApp->m_x_res = currentConfigApp->m_y_res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_ui->xResSpinBox->setReadOnly(false);
|
||||
}
|
||||
}
|
||||
|
||||
void CMainDialog::FramerateChanged(int i)
|
||||
{
|
||||
currentConfigApp->m_frame_delta = (1000.0f / static_cast<float>(i));
|
||||
m_modified = true;
|
||||
UpdateInterface();
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
|
||||
#include <QDialog>
|
||||
#include <QFileDialog>
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
@ -29,6 +30,7 @@ class CMainDialog : public QDialog {
|
||||
bool m_modified = false;
|
||||
bool m_advanced = false;
|
||||
Ui::MainDialog* m_ui = nullptr;
|
||||
SDL_DisplayMode** displayModes;
|
||||
|
||||
void keyReleaseEvent(QKeyEvent* event) override;
|
||||
bool OnInitDialog();
|
||||
@ -40,17 +42,33 @@ private slots:
|
||||
void OnRadiobuttonModelHighQuality(bool checked);
|
||||
void OnRadiobuttonTextureLowQuality(bool checked);
|
||||
void OnRadiobuttonTextureHighQuality(bool checked);
|
||||
void OnCheckboxJoystick(bool checked);
|
||||
void OnRadioWindowed(bool checked);
|
||||
void OnRadioFullscreen(bool checked);
|
||||
void OnRadioExclusiveFullscreen(bool checked);
|
||||
void OnCheckboxMusic(bool checked);
|
||||
void OnCheckboxFullscreen(bool checked);
|
||||
void OnCheckboxRumble(bool checked);
|
||||
void OnCheckboxTexture(bool checked);
|
||||
void TouchControlsChanged(int index);
|
||||
void TransitionTypeChanged(int index);
|
||||
void ExclusiveResolutionChanged(int index);
|
||||
void accept() override;
|
||||
void reject() override;
|
||||
void launch();
|
||||
void SelectDataPathDialog();
|
||||
void SelectSavePathDialog();
|
||||
void DataPathEdited();
|
||||
void SavePathEdited();
|
||||
void MaxLoDChanged(int value);
|
||||
void MaxActorsChanged(int value);
|
||||
void MSAAChanged(int value);
|
||||
void AFChanged(int value);
|
||||
void SelectTexturePathDialog();
|
||||
void TexturePathEdited();
|
||||
void XResChanged(int i);
|
||||
void YResChanged(int i);
|
||||
void AspectRatioChanged(int index);
|
||||
void EnsureAspectRatio();
|
||||
void FramerateChanged(int i);
|
||||
};
|
||||
|
||||
// SYNTHETIC: CONFIG 0x00403de0
|
||||
|
||||
@ -56,12 +56,27 @@ bool CConfigApp::InitInstance()
|
||||
return false;
|
||||
}
|
||||
m_device_enumerator = new LegoDeviceEnumerate;
|
||||
if (m_device_enumerator->DoEnumerate()) {
|
||||
SDL_Window* window = SDL_CreateWindow("Test window", 640, 480, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL);
|
||||
HWND hWnd;
|
||||
#ifdef MINIWIN
|
||||
hWnd = reinterpret_cast<HWND>(window);
|
||||
#else
|
||||
hWnd = (HWND) SDL_GetPointerProperty(SDL_GetWindowProperties(window), SDL_PROP_WINDOW_WIN32_HWND_POINTER, NULL);
|
||||
#endif
|
||||
if (m_device_enumerator->DoEnumerate(hWnd)) {
|
||||
return FALSE;
|
||||
}
|
||||
SDL_DestroyWindow(window);
|
||||
m_aspect_ratio = 0;
|
||||
m_exf_x_res = m_x_res = 640;
|
||||
m_exf_y_res = m_y_res = 480;
|
||||
m_exf_fps = 60.00f;
|
||||
m_frame_delta = 10.0f;
|
||||
m_driver = NULL;
|
||||
m_device = NULL;
|
||||
m_full_screen = TRUE;
|
||||
m_exclusive_full_screen = FALSE;
|
||||
m_transition_type = 3; // 3: Mosaic
|
||||
m_wide_view_angle = TRUE;
|
||||
m_use_joystick = TRUE;
|
||||
m_music = TRUE;
|
||||
@ -69,8 +84,15 @@ bool CConfigApp::InitInstance()
|
||||
m_3d_video_ram = FALSE;
|
||||
m_joystick_index = -1;
|
||||
m_display_bit_depth = 16;
|
||||
m_msaa = 1;
|
||||
m_anisotropy = 1;
|
||||
m_haptic = TRUE;
|
||||
m_touch_scheme = 2;
|
||||
m_texture_load = TRUE;
|
||||
m_texture_path = "/textures/";
|
||||
int totalRamMiB = SDL_GetSystemRAM();
|
||||
if (totalRamMiB < 12) {
|
||||
m_ram_quality_limit = 2;
|
||||
m_3d_sound = FALSE;
|
||||
m_model_quality = 0;
|
||||
m_texture_quality = 1;
|
||||
@ -78,6 +100,7 @@ bool CConfigApp::InitInstance()
|
||||
m_max_actors = 5;
|
||||
}
|
||||
else if (totalRamMiB < 20) {
|
||||
m_ram_quality_limit = 1;
|
||||
m_3d_sound = FALSE;
|
||||
m_model_quality = 1;
|
||||
m_texture_quality = 1;
|
||||
@ -85,6 +108,7 @@ bool CConfigApp::InitInstance()
|
||||
m_max_actors = 10;
|
||||
}
|
||||
else {
|
||||
m_ram_quality_limit = 0;
|
||||
m_model_quality = 2;
|
||||
m_3d_sound = TRUE;
|
||||
m_texture_quality = 1;
|
||||
@ -113,7 +137,7 @@ D3DCOLORMODEL CConfigApp::GetHardwareDeviceColorModel() const
|
||||
// FUNCTION: CONFIG 0x00403410
|
||||
bool CConfigApp::IsPrimaryDriver() const
|
||||
{
|
||||
return m_driver == &m_device_enumerator->GetDriverList().front();
|
||||
return m_driver == &m_device_enumerator->m_ddInfo.front();
|
||||
}
|
||||
|
||||
// FUNCTION: CONFIG 0x00403430
|
||||
@ -145,6 +169,9 @@ bool CConfigApp::ReadRegisterSettings()
|
||||
m_display_bit_depth = iniparser_getint(dict, "isle:Display Bit Depth", -1);
|
||||
m_flip_surfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flip_surfaces);
|
||||
m_full_screen = iniparser_getboolean(dict, "isle:Full Screen", m_full_screen);
|
||||
m_exclusive_full_screen = iniparser_getboolean(dict, "isle:Exclusive Full Screen", m_exclusive_full_screen);
|
||||
m_transition_type = iniparser_getint(dict, "isle:Transition Type", m_transition_type);
|
||||
m_touch_scheme = iniparser_getint(dict, "isle:Touch Scheme", m_touch_scheme);
|
||||
m_3d_video_ram = iniparser_getboolean(dict, "isle:Back Buffers in Video RAM", m_3d_video_ram);
|
||||
m_wide_view_angle = iniparser_getboolean(dict, "isle:Wide View Angle", m_wide_view_angle);
|
||||
m_3d_sound = iniparser_getboolean(dict, "isle:3DSound", m_3d_sound);
|
||||
@ -152,10 +179,22 @@ bool CConfigApp::ReadRegisterSettings()
|
||||
m_model_quality = iniparser_getint(dict, "isle:Island Quality", m_model_quality);
|
||||
m_texture_quality = iniparser_getint(dict, "isle:Island Texture", m_texture_quality);
|
||||
m_use_joystick = iniparser_getboolean(dict, "isle:UseJoystick", m_use_joystick);
|
||||
m_haptic = iniparser_getboolean(dict, "isle:Haptic", m_haptic);
|
||||
m_music = iniparser_getboolean(dict, "isle:Music", m_music);
|
||||
m_joystick_index = iniparser_getint(dict, "isle:JoystickIndex", m_joystick_index);
|
||||
m_max_lod = iniparser_getdouble(dict, "isle:Max LOD", m_max_lod);
|
||||
m_max_actors = iniparser_getint(dict, "isle:Max Allowed Extras", m_max_actors);
|
||||
m_msaa = iniparser_getint(dict, "isle:MSAA", m_msaa);
|
||||
m_anisotropy = iniparser_getint(dict, "isle:Anisotropic", m_anisotropy);
|
||||
m_texture_load = iniparser_getboolean(dict, "extensions:texture loader", m_texture_load);
|
||||
m_texture_path = iniparser_getstring(dict, "texture loader:texture path", m_texture_path.c_str());
|
||||
m_aspect_ratio = iniparser_getint(dict, "isle:Aspect Ratio", m_aspect_ratio);
|
||||
m_x_res = iniparser_getint(dict, "isle:Horizontal Resolution", m_x_res);
|
||||
m_y_res = iniparser_getint(dict, "isle:Vertical Resolution", m_y_res);
|
||||
m_exf_x_res = iniparser_getint(dict, "isle:Exclusive X Resolution", m_exf_x_res);
|
||||
m_exf_y_res = iniparser_getint(dict, "isle:Exclusive Y Resolution", m_exf_y_res);
|
||||
m_exf_fps = iniparser_getdouble(dict, "isle:Exclusive Framerate", m_exf_fps);
|
||||
m_frame_delta = iniparser_getdouble(dict, "isle:Frame Delta", m_frame_delta);
|
||||
iniparser_freedict(dict);
|
||||
return true;
|
||||
}
|
||||
@ -212,7 +251,7 @@ bool CConfigApp::ValidateSettings()
|
||||
is_modified = TRUE;
|
||||
}
|
||||
|
||||
if (m_max_lod < 0.0f || m_max_lod > 5.0f) {
|
||||
if (m_max_lod < 0.0f || m_max_lod > 6.0f) {
|
||||
m_max_lod = 3.5f;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
@ -220,6 +259,42 @@ bool CConfigApp::ValidateSettings()
|
||||
m_max_actors = 20;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (!m_use_joystick) {
|
||||
m_use_joystick = true;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (m_touch_scheme < 0 || m_touch_scheme > 2) {
|
||||
m_touch_scheme = 2;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (m_exclusive_full_screen && !m_full_screen) {
|
||||
m_full_screen = TRUE;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (!(m_msaa & (m_msaa - 1))) { // Check if MSAA is power of 2 (1, 2, 4, 8, etc)
|
||||
m_msaa = exp2(round(log2(m_msaa))); // Closest power of 2
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (m_msaa > 16) {
|
||||
m_msaa = 16;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
else if (m_msaa < 1) {
|
||||
m_msaa = 1;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (!(m_anisotropy & (m_anisotropy - 1))) { // Check if anisotropy is power of 2 (1, 2, 4, 8, etc)
|
||||
m_anisotropy = exp2(round(log2(m_anisotropy))); // Closest power of 2
|
||||
is_modified = TRUE;
|
||||
}
|
||||
if (m_anisotropy > 16) {
|
||||
m_anisotropy = 16;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
else if (m_anisotropy < 1) {
|
||||
m_anisotropy = 1;
|
||||
is_modified = TRUE;
|
||||
}
|
||||
|
||||
return is_modified;
|
||||
}
|
||||
@ -288,6 +363,8 @@ void CConfigApp::WriteRegisterSettings() const
|
||||
|
||||
dictionary* dict = dictionary_new(0);
|
||||
iniparser_set(dict, "isle", NULL);
|
||||
iniparser_set(dict, "extensions", NULL);
|
||||
iniparser_set(dict, "texture loader", NULL);
|
||||
if (m_device_enumerator->FormatDeviceName(buffer, m_driver, m_device) >= 0) {
|
||||
iniparser_set(dict, "isle:3D Device ID", buffer);
|
||||
}
|
||||
@ -296,17 +373,27 @@ void CConfigApp::WriteRegisterSettings() const
|
||||
iniparser_set(dict, "isle:savepath", m_save_path.c_str());
|
||||
|
||||
SetIniInt(dict, "isle:Display Bit Depth", m_display_bit_depth);
|
||||
SetIniInt(dict, "isle:MSAA", m_msaa);
|
||||
SetIniInt(dict, "isle:Anisotropic", m_anisotropy);
|
||||
SetIniBool(dict, "isle:Flip Surfaces", m_flip_surfaces);
|
||||
SetIniBool(dict, "isle:Full Screen", m_full_screen);
|
||||
SetIniBool(dict, "isle:Exclusive Full Screen", m_exclusive_full_screen);
|
||||
SetIniBool(dict, "isle:Wide View Angle", m_wide_view_angle);
|
||||
|
||||
SetIniInt(dict, "isle:Transition Type", m_transition_type);
|
||||
SetIniInt(dict, "isle:Touch Scheme", m_touch_scheme);
|
||||
|
||||
SetIniBool(dict, "isle:3DSound", m_3d_sound);
|
||||
SetIniBool(dict, "isle:Music", m_music);
|
||||
SetIniBool(dict, "isle:Haptic", m_haptic);
|
||||
|
||||
SetIniBool(dict, "isle:UseJoystick", m_use_joystick);
|
||||
SetIniInt(dict, "isle:JoystickIndex", m_joystick_index);
|
||||
SetIniBool(dict, "isle:Draw Cursor", m_draw_cursor);
|
||||
|
||||
SetIniBool(dict, "extensions:texture loader", m_texture_load);
|
||||
iniparser_set(dict, "texture loader:texture path", m_texture_path.c_str());
|
||||
|
||||
SetIniBool(dict, "isle:Back Buffers in Video RAM", m_3d_video_ram);
|
||||
|
||||
SetIniInt(dict, "isle:Island Quality", m_model_quality);
|
||||
@ -315,6 +402,14 @@ void CConfigApp::WriteRegisterSettings() const
|
||||
iniparser_set(dict, "isle:Max LOD", std::to_string(m_max_lod).c_str());
|
||||
SetIniInt(dict, "isle:Max Allowed Extras", m_max_actors);
|
||||
|
||||
SetIniInt(dict, "isle:Aspect Ratio", m_aspect_ratio);
|
||||
SetIniInt(dict, "isle:Horizontal Resolution", m_x_res);
|
||||
SetIniInt(dict, "isle:Vertical Resolution", m_y_res);
|
||||
SetIniInt(dict, "isle:Exclusive X Resolution", m_exf_x_res);
|
||||
SetIniInt(dict, "isle:Exclusive Y Resolution", m_exf_y_res);
|
||||
iniparser_set(dict, "isle:Exclusive Framerate", std::to_string(m_exf_fps).c_str());
|
||||
iniparser_set(dict, "isle:Frame Delta", std::to_string(m_frame_delta).c_str());
|
||||
|
||||
#undef SetIniBool
|
||||
#undef SetIniInt
|
||||
|
||||
|
||||
@ -59,27 +59,43 @@ class CConfigApp {
|
||||
// DECLARE_MESSAGE_MAP()
|
||||
|
||||
public:
|
||||
int m_aspect_ratio;
|
||||
int m_x_res;
|
||||
int m_y_res;
|
||||
int m_exf_x_res;
|
||||
int m_exf_y_res;
|
||||
float m_exf_fps;
|
||||
float m_frame_delta;
|
||||
LegoDeviceEnumerate* m_device_enumerator;
|
||||
MxDriver* m_driver;
|
||||
Direct3DDeviceInfo* m_device;
|
||||
int m_display_bit_depth;
|
||||
int m_msaa;
|
||||
int m_anisotropy;
|
||||
bool m_flip_surfaces;
|
||||
bool m_full_screen;
|
||||
bool m_exclusive_full_screen;
|
||||
int m_transition_type;
|
||||
bool m_3d_video_ram;
|
||||
bool m_wide_view_angle;
|
||||
bool m_3d_sound;
|
||||
bool m_draw_cursor;
|
||||
bool m_use_joystick;
|
||||
bool m_haptic;
|
||||
int m_joystick_index;
|
||||
int m_model_quality;
|
||||
int m_texture_quality;
|
||||
bool m_music;
|
||||
bool m_texture_load;
|
||||
std::string m_texture_path;
|
||||
std::string m_iniPath;
|
||||
std::string m_base_path;
|
||||
std::string m_cd_path;
|
||||
std::string m_save_path;
|
||||
float m_max_lod;
|
||||
int m_max_actors;
|
||||
int m_touch_scheme;
|
||||
int m_ram_quality_limit;
|
||||
};
|
||||
|
||||
extern CConfigApp g_theApp;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -6,12 +6,7 @@ If you feel fit to contribute, feel free to create a pull request! Someone will
|
||||
|
||||
Please keep your pull requests small and understandable; you may be able to shoot ahead and make a lot of progress in a short amount of time, but this is a collaborative project, so you must allow others to catch up and follow along. Large pull requests become significantly more unwieldy to review, and as such make it exponentially more likely for a mistake or error to go undetected. They also make it harder to merge other pull requests because the more files you modify, the more likely it is for a merge conflict to occur. A general guideline is to keep submissions limited to one class at a time. Sometimes two or more classes may be too interlinked for this to be feasible, so this is not a hard rule, however if your PR is starting to modify more than 10 or so files, it's probably getting too big.
|
||||
|
||||
This repository has a single goal: achieving platform independence. Consequently, contributions that do not support this goal cannot be accepted. Examples of out-of-scope contributions include:
|
||||
|
||||
* Improving code efficiency or performance without addressing platform compatibility
|
||||
* Replacing `MxString` with `std::string`
|
||||
* Fixing gameplay bugs
|
||||
* Enhancing audio or video quality
|
||||
This repository has achieving platform independence as its primary goal, with limited support for light modding (using [`extensions`](/extensions)). Any changes that modify code in `LEGO1` are unlikely to be accepted, unless they directly serve to increase platform compatibility.
|
||||
|
||||
If in doubt, please contact us in the [Matrix chatroom](https://matrix.to/#/#isledecomp:matrix.org).
|
||||
|
||||
|
||||
30
ISLE/3ds/apthooks.cpp
Normal file
30
ISLE/3ds/apthooks.cpp
Normal file
@ -0,0 +1,30 @@
|
||||
#include "apthooks.h"
|
||||
|
||||
#include "legomain.h"
|
||||
#include "misc.h"
|
||||
|
||||
aptHookCookie g_aptCookie;
|
||||
|
||||
void N3DS_AptHookCallback(APT_HookType hookType, void* param)
|
||||
{
|
||||
switch (hookType) {
|
||||
case APTHOOK_ONSLEEP:
|
||||
case APTHOOK_ONSUSPEND:
|
||||
Lego()->Pause();
|
||||
break;
|
||||
case APTHOOK_ONWAKEUP:
|
||||
case APTHOOK_ONRESTORE:
|
||||
Lego()->Resume();
|
||||
break;
|
||||
case APTHOOK_ONEXIT:
|
||||
Lego()->CloseMainWindow();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void N3DS_SetupAptHooks()
|
||||
{
|
||||
aptHook(&g_aptCookie, N3DS_AptHookCallback, NULL);
|
||||
}
|
||||
9
ISLE/3ds/apthooks.h
Normal file
9
ISLE/3ds/apthooks.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef N3DS_APTHOOKS_H
|
||||
#define N3DS_APTHOOKS_H
|
||||
|
||||
#include <3ds.h>
|
||||
|
||||
void N3DS_AptHookCallback(APT_HookType hookType, void* param);
|
||||
void N3DS_SetupAptHooks();
|
||||
|
||||
#endif // N3DS_APTHOOKS_H
|
||||
19
ISLE/3ds/config.cpp
Normal file
19
ISLE/3ds/config.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <iniparser.h>
|
||||
|
||||
void N3DS_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
||||
{
|
||||
SDL_Log("Overriding default config for 3DS");
|
||||
|
||||
// We are currently not bundling the assets into romfs.
|
||||
// User must place assets in sdmc:/3ds/isle where
|
||||
// sdmc:/3ds/isle/LEGO/SCRIPTS/CREDITS.si exists, for example.
|
||||
iniparser_set(p_dictionary, "isle:diskpath", "sdmc:/3ds/isle/LEGO/disk");
|
||||
iniparser_set(p_dictionary, "isle:cdpath", "sdmc:/3ds/isle");
|
||||
|
||||
// TODO: Save path: can we use libctru FS save data functions? Would be neat, especially for CIA install
|
||||
// Extra / at the end causes some issues
|
||||
iniparser_set(p_dictionary, "isle:savepath", "sdmc:/3ds/isle");
|
||||
}
|
||||
8
ISLE/3ds/config.h
Normal file
8
ISLE/3ds/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef N3DS_CONFIG_H
|
||||
#define N3DS_CONFIG_H
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
void N3DS_SetupDefaultConfigOverrides(dictionary* p_dictionary);
|
||||
|
||||
#endif // N3DS_CONFIG_H
|
||||
27
ISLE/emscripten/config.cpp
Normal file
27
ISLE/emscripten/config.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
#include "config.h"
|
||||
|
||||
#include "filesystem.h"
|
||||
#include "window.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <emscripten.h>
|
||||
#include <iniparser.h>
|
||||
|
||||
void Emscripten_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
||||
{
|
||||
SDL_Log("Overriding default config for Emscripten");
|
||||
|
||||
iniparser_set(p_dictionary, "isle:diskpath", Emscripten_bundledPath);
|
||||
iniparser_set(p_dictionary, "isle:cdpath", Emscripten_streamPath);
|
||||
iniparser_set(p_dictionary, "isle:savepath", Emscripten_savePath);
|
||||
iniparser_set(p_dictionary, "isle:Full Screen", "false");
|
||||
iniparser_set(p_dictionary, "isle:Flip Surfaces", "true");
|
||||
|
||||
// Emscripten-only for now
|
||||
Emscripten_SetScaleAspect(iniparser_getboolean(p_dictionary, "isle:Original Aspect Ratio", true));
|
||||
Emscripten_SetOriginalResolution(iniparser_getboolean(p_dictionary, "isle:Original Resolution", true));
|
||||
|
||||
// clang-format off
|
||||
MAIN_THREAD_EM_ASM({JSEvents.fullscreenEnabled = function() { return false; }});
|
||||
// clang-format on
|
||||
}
|
||||
8
ISLE/emscripten/config.h
Normal file
8
ISLE/emscripten/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef EMSCRIPTEN_CONFIG_H
|
||||
#define EMSCRIPTEN_CONFIG_H
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
void Emscripten_SetupDefaultConfigOverrides(dictionary* p_dictionary);
|
||||
|
||||
#endif // EMSCRIPTEN_CONFIG_H
|
||||
@ -1,5 +1,43 @@
|
||||
diff --git a/src/lib/libhtml5.js b/src/lib/libhtml5.js
|
||||
index da08765e7..24e5da22e 100644
|
||||
--- a/src/lib/libhtml5.js
|
||||
+++ b/src/lib/libhtml5.js
|
||||
@@ -1182,6 +1182,7 @@ var LibraryHTML5 = {
|
||||
|
||||
$registerRestoreOldStyle__deps: ['$getCanvasElementSize', '$setCanvasElementSize', '$currentFullscreenStrategy'],
|
||||
$registerRestoreOldStyle: (canvas) => {
|
||||
+ return;
|
||||
var canvasSize = getCanvasElementSize(canvas);
|
||||
var oldWidth = canvasSize[0];
|
||||
var oldHeight = canvasSize[1];
|
||||
@@ -1326,9 +1327,9 @@ var LibraryHTML5 = {
|
||||
var topMargin;
|
||||
|
||||
if (inAspectRatioFixedFullscreenMode) {
|
||||
- if (w*y < x*h) h = (w * y / x) | 0;
|
||||
- else if (w*y > x*h) w = (h * x / y) | 0;
|
||||
- topMargin = ((screenHeight - h) / 2) | 0;
|
||||
+ if (w*y < x*h) h = Math.round(w * y / x) | 0;
|
||||
+ else if (w*y > x*h) w = Math.round(h * x / y) | 0;
|
||||
+ topMargin = Math.round((screenHeight - h) / 2) | 0;
|
||||
}
|
||||
|
||||
if (inPixelPerfectFullscreenMode) {
|
||||
diff --git a/src/lib/libpthread.js b/src/lib/libpthread.js
|
||||
index 6d979627e..97e3f8684 100644
|
||||
--- a/src/lib/libpthread.js
|
||||
+++ b/src/lib/libpthread.js
|
||||
@@ -697,7 +697,7 @@ var LibraryPThread = {
|
||||
{
|
||||
transferredCanvasNames = UTF8ToString(transferredCanvasNames).trim();
|
||||
}
|
||||
- transferredCanvasNames = transferredCanvasNames ? transferredCanvasNames.split(',') : [];
|
||||
+ transferredCanvasNames = transferredCanvasNames && !Module['disableOffscreenCanvases'] ? transferredCanvasNames.split(',') : [];
|
||||
#if GL_DEBUG
|
||||
dbg(`pthread_create: transferredCanvasNames="${transferredCanvasNames}"`);
|
||||
#endif
|
||||
diff --git a/src/lib/libwasmfs_fetch.js b/src/lib/libwasmfs_fetch.js
|
||||
index e8c9f7e21..1c0eea957 100644
|
||||
index e8c9f7e21..caf1971d2 100644
|
||||
--- a/src/lib/libwasmfs_fetch.js
|
||||
+++ b/src/lib/libwasmfs_fetch.js
|
||||
@@ -38,36 +38,7 @@ addToLibrary({
|
||||
@ -89,7 +127,21 @@ index e8c9f7e21..1c0eea957 100644
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@@ -164,6 +156,21 @@ addToLibrary({
|
||||
@@ -156,14 +148,31 @@ addToLibrary({
|
||||
return readLength;
|
||||
},
|
||||
getSize: async (file) => {
|
||||
- try {
|
||||
- await getFileRange(file, 0, 0);
|
||||
- } catch (failedResponse) {
|
||||
- return 0;
|
||||
+ if (!(file in wasmFS$JSMemoryRanges)) {
|
||||
+ try {
|
||||
+ await getFileRange(file, undefined, undefined);
|
||||
+ } catch (failedResponse) {
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
return wasmFS$JSMemoryRanges[file].size;
|
||||
},
|
||||
};
|
||||
@ -112,3 +164,27 @@ index e8c9f7e21..1c0eea957 100644
|
||||
},
|
||||
-
|
||||
});
|
||||
diff --git a/src/preamble.js b/src/preamble.js
|
||||
index 572694517..44e65c823 100644
|
||||
--- a/src/preamble.js
|
||||
+++ b/src/preamble.js
|
||||
@@ -1062,3 +1062,19 @@ function getCompilerSetting(name) {
|
||||
// dynamic linker as symbols are loaded.
|
||||
var asyncifyStubs = {};
|
||||
#endif
|
||||
+
|
||||
+if (typeof document !== "undefined") {
|
||||
+ (async () => {
|
||||
+ try {
|
||||
+ await navigator.storage.getDirectory();
|
||||
+ Module["disableOpfs"] = false;
|
||||
+ } catch (e) {
|
||||
+ Module["disableOpfs"] = true;
|
||||
+ }
|
||||
+ console.log("disableOpfs: " + Module["disableOpfs"]);
|
||||
+ })();
|
||||
+
|
||||
+ Module["disableOffscreenCanvases"] ||= !document.createElement('canvas').getContext('webgl');
|
||||
+ console.log("disableOffscreenCanvases: " + Module["disableOffscreenCanvases"]);
|
||||
+}
|
||||
+
|
||||
@ -36,3 +36,11 @@ void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleS
|
||||
|
||||
Emscripten_SendEvent("presenterProgress", buf);
|
||||
}
|
||||
|
||||
void Emscripten_SendExtensionProgress(const char* p_extension, MxU32 p_progress)
|
||||
{
|
||||
char buf[128];
|
||||
SDL_snprintf(buf, sizeof(buf), "{\"name\": \"%s\", \"progress\": %d}", p_extension, p_progress);
|
||||
|
||||
Emscripten_SendEvent("extensionProgress", buf);
|
||||
}
|
||||
|
||||
@ -4,5 +4,6 @@
|
||||
#include "mxpresenter.h"
|
||||
|
||||
void Emscripten_SendPresenterProgress(MxDSAction* p_action, MxPresenter::TickleState p_tickleState);
|
||||
void Emscripten_SendExtensionProgress(const char* p_extension, MxU32 p_progress);
|
||||
|
||||
#endif // EMSCRIPTEN_EVENTS_H
|
||||
|
||||
@ -1,22 +1,32 @@
|
||||
#include "filesystem.h"
|
||||
|
||||
#include "events.h"
|
||||
#include "extensions/textureloader.h"
|
||||
#include "legogamestate.h"
|
||||
#include "misc.h"
|
||||
#include "mxomni.h"
|
||||
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <emscripten.h>
|
||||
#include <emscripten/wasmfs.h>
|
||||
|
||||
static backend_t opfs = nullptr;
|
||||
static backend_t fetchfs = nullptr;
|
||||
|
||||
extern const char* g_files[46];
|
||||
extern const char* g_textures[120];
|
||||
|
||||
void Emscripten_SetupConfig(const char* p_iniConfig)
|
||||
bool Emscripten_OPFSDisabled()
|
||||
{
|
||||
if (!p_iniConfig || !*p_iniConfig) {
|
||||
return;
|
||||
return MAIN_THREAD_EM_ASM_INT({return !!Module["disableOpfs"]});
|
||||
}
|
||||
|
||||
bool Emscripten_SetupConfig(const char* p_iniConfig)
|
||||
{
|
||||
if (Emscripten_OPFSDisabled()) {
|
||||
SDL_Log("OPFS is disabled; ignoring .ini path");
|
||||
return false;
|
||||
}
|
||||
|
||||
opfs = wasmfs_create_opfs_backend();
|
||||
@ -28,11 +38,13 @@ void Emscripten_SetupConfig(const char* p_iniConfig)
|
||||
wasmfs_create_directory(iniConfig.GetData(), 0644, opfs);
|
||||
*parse = '/';
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Emscripten_SetupFilesystem()
|
||||
{
|
||||
fetchfs = wasmfs_create_fetch_backend((MxString(Emscripten_streamHost) + MxString("/LEGO")).GetData(), 512 * 1024);
|
||||
fetchfs = wasmfs_create_fetch_backend((MxString(Emscripten_streamHost) + "/LEGO").GetData(), 512 * 1024);
|
||||
|
||||
wasmfs_create_directory("/LEGO", 0644, fetchfs);
|
||||
wasmfs_create_directory("/LEGO/Scripts", 0644, fetchfs);
|
||||
@ -62,11 +74,42 @@ void Emscripten_SetupFilesystem()
|
||||
}
|
||||
};
|
||||
|
||||
const auto preloadFile = [](const char* p_path) -> bool {
|
||||
size_t length = 0;
|
||||
void* data = SDL_LoadFile(p_path, &length);
|
||||
if (data) {
|
||||
SDL_free(data);
|
||||
}
|
||||
return length > 0;
|
||||
};
|
||||
|
||||
for (const char* file : g_files) {
|
||||
registerFile(file);
|
||||
}
|
||||
|
||||
if (GameState()->GetSavePath() && *GameState()->GetSavePath()) {
|
||||
#ifdef EXTENSIONS
|
||||
if (Extensions::TextureLoader::enabled) {
|
||||
MxString directory =
|
||||
MxString("/LEGO") + Extensions::TextureLoader::options["texture loader:texture path"].c_str();
|
||||
Extensions::TextureLoader::options["texture loader:texture path"] = directory.GetData();
|
||||
wasmfs_create_directory(directory.GetData(), 0644, fetchfs);
|
||||
|
||||
MxU32 i = 0;
|
||||
Emscripten_SendExtensionProgress("HD Textures", 0);
|
||||
for (const char* file : g_textures) {
|
||||
MxString path = directory + "/" + file + ".bmp";
|
||||
registerFile(path.GetData());
|
||||
|
||||
if (!preloadFile(path.GetData())) {
|
||||
Extensions::TextureLoader::excludedFiles.emplace_back(file);
|
||||
}
|
||||
|
||||
Emscripten_SendExtensionProgress("HD Textures", (++i * 100) / sizeOfArray(g_textures));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (GameState()->GetSavePath() && *GameState()->GetSavePath() && !Emscripten_OPFSDisabled()) {
|
||||
if (!opfs) {
|
||||
opfs = wasmfs_create_opfs_backend();
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ inline static const char* Emscripten_savePath = "/save";
|
||||
inline static const char* Emscripten_streamPath = "/";
|
||||
inline static const char* Emscripten_streamHost = ISLE_EMSCRIPTEN_HOST;
|
||||
|
||||
void Emscripten_SetupConfig(const char* p_iniConfig);
|
||||
bool Emscripten_SetupConfig(const char* p_iniConfig);
|
||||
void Emscripten_SetupFilesystem();
|
||||
|
||||
#endif // EMSCRIPTEN_FILESYSTEM_H
|
||||
|
||||
55
ISLE/emscripten/haptic.cpp
Normal file
55
ISLE/emscripten/haptic.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include "haptic.h"
|
||||
|
||||
#include "compat.h"
|
||||
#include "lego/sources/misc/legoutil.h"
|
||||
#include "legoinputmanager.h"
|
||||
#include "misc.h"
|
||||
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
void Emscripten_HandleRumbleEvent(float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds)
|
||||
{
|
||||
std::visit(
|
||||
overloaded{
|
||||
[](LegoInputManager::SDL_KeyboardID_v p_id) {},
|
||||
[](LegoInputManager::SDL_MouseID_v p_id) {},
|
||||
[p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds](LegoInputManager::SDL_JoystickID_v p_id) {
|
||||
const char* name = SDL_GetJoystickNameForID((SDL_JoystickID) p_id);
|
||||
if (name) {
|
||||
MAIN_THREAD_EM_ASM(
|
||||
{
|
||||
const name = UTF8ToString($0);
|
||||
const gamepads = navigator.getGamepads();
|
||||
for (const gamepad of gamepads) {
|
||||
if (gamepad && gamepad.connected && gamepad.id == name && gamepad.vibrationActuator) {
|
||||
gamepad.vibrationActuator.playEffect("dual-rumble", {
|
||||
startDelay : 0,
|
||||
weakMagnitude : $1,
|
||||
strongMagnitude : $2,
|
||||
duration : $3,
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
name,
|
||||
SDL_clamp(p_lowFrequencyRumble, 0, 1),
|
||||
SDL_clamp(p_highFrequencyRumble, 0, 1),
|
||||
p_milliseconds
|
||||
);
|
||||
}
|
||||
},
|
||||
[p_milliseconds](LegoInputManager::SDL_TouchID_v p_id) {
|
||||
MAIN_THREAD_EM_ASM(
|
||||
{
|
||||
if (navigator.vibrate) {
|
||||
navigator.vibrate($0);
|
||||
}
|
||||
},
|
||||
p_milliseconds
|
||||
);
|
||||
}
|
||||
},
|
||||
InputManager()->GetLastInputMethod()
|
||||
);
|
||||
}
|
||||
8
ISLE/emscripten/haptic.h
Normal file
8
ISLE/emscripten/haptic.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef EMSCRIPTEN_HAPTIC_H
|
||||
#define EMSCRIPTEN_HAPTIC_H
|
||||
|
||||
#include "mxtypes.h"
|
||||
|
||||
void Emscripten_HandleRumbleEvent(float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds);
|
||||
|
||||
#endif // EMSCRIPTEN_HAPTIC_H
|
||||
99
ISLE/emscripten/window.cpp
Normal file
99
ISLE/emscripten/window.cpp
Normal file
@ -0,0 +1,99 @@
|
||||
#include "window.h"
|
||||
|
||||
#include "mxtypes.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <algorithm>
|
||||
#include <emscripten/html5.h>
|
||||
|
||||
double g_fullWidth;
|
||||
double g_fullHeight;
|
||||
bool g_scaleAspect = true;
|
||||
bool g_originalResolution = true;
|
||||
|
||||
extern MxS32 g_targetWidth;
|
||||
extern MxS32 g_targetHeight;
|
||||
|
||||
void Emscripten_SetupWindow(SDL_Window* p_window)
|
||||
{
|
||||
EmscriptenFullscreenStrategy strategy;
|
||||
strategy.scaleMode = g_scaleAspect ? EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT : EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH;
|
||||
strategy.canvasResolutionScaleMode = EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF;
|
||||
strategy.filteringMode = EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT;
|
||||
strategy.canvasResizedCallbackUserData = p_window;
|
||||
strategy.canvasResizedCallback = [](int eventType, const void* reserved, void* userData) -> bool {
|
||||
int width, height;
|
||||
emscripten_get_canvas_element_size("canvas", &width, &height);
|
||||
emscripten_get_element_css_size("#canvas", &g_fullWidth, &g_fullHeight);
|
||||
|
||||
if (g_originalResolution) {
|
||||
SDL_SetWindowSize((SDL_Window*) userData, g_targetWidth, g_targetHeight);
|
||||
}
|
||||
else {
|
||||
SDL_SetWindowSize((SDL_Window*) userData, width, height);
|
||||
}
|
||||
|
||||
SDL_Log(
|
||||
"Emscripten: window size %dx%d, canvas size %dx%d, scale aspect %s, original resolution %s",
|
||||
width,
|
||||
height,
|
||||
(int) g_fullWidth,
|
||||
(int) g_fullHeight,
|
||||
g_scaleAspect ? "TRUE" : "FALSE",
|
||||
g_originalResolution ? "TRUE" : "FALSE"
|
||||
);
|
||||
return true;
|
||||
};
|
||||
|
||||
emscripten_enter_soft_fullscreen("canvas", &strategy);
|
||||
}
|
||||
|
||||
void Emscripten_SetScaleAspect(bool p_scaleAspect)
|
||||
{
|
||||
g_scaleAspect = p_scaleAspect;
|
||||
}
|
||||
|
||||
void Emscripten_SetOriginalResolution(bool p_originalResolution)
|
||||
{
|
||||
g_originalResolution = p_originalResolution;
|
||||
}
|
||||
|
||||
void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event)
|
||||
{
|
||||
if (!g_scaleAspect) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_MOUSE_MOTION: {
|
||||
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||
event->motion.x = (event->motion.x - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) / widthRatio;
|
||||
event->motion.y = (event->motion.y - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) / heightRatio;
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP: {
|
||||
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||
event->button.x = (event->button.x - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) / widthRatio;
|
||||
event->button.y = (event->button.y - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) / heightRatio;
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
case SDL_EVENT_FINGER_CANCELED: {
|
||||
const float scale = std::min(g_fullWidth / g_targetWidth, g_fullHeight / g_targetHeight);
|
||||
const float widthRatio = (g_targetWidth * scale) / g_fullWidth;
|
||||
const float heightRatio = (g_targetHeight * scale) / g_fullHeight;
|
||||
event->tfinger.x = (event->tfinger.x * g_targetWidth - (g_targetWidth * (1.0f - widthRatio) / 2.0f)) /
|
||||
widthRatio / g_targetWidth;
|
||||
event->tfinger.y = (event->tfinger.y * g_targetHeight - (g_targetHeight * (1.0f - heightRatio) / 2.0f)) /
|
||||
heightRatio / g_targetHeight;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
ISLE/emscripten/window.h
Normal file
11
ISLE/emscripten/window.h
Normal file
@ -0,0 +1,11 @@
|
||||
#ifndef EMSCRIPTEN_WINDOW_H
|
||||
#define EMSCRIPTEN_WINDOW_H
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
|
||||
void Emscripten_SetupWindow(SDL_Window* p_window);
|
||||
void Emscripten_SetScaleAspect(bool p_scaleAspect);
|
||||
void Emscripten_SetOriginalResolution(bool p_originalResolution);
|
||||
void Emscripten_ConvertEventToRenderCoordinates(SDL_Event* event);
|
||||
|
||||
#endif // EMSCRIPTEN_WINDOW_H
|
||||
25
ISLE/ios/config.cpp
Normal file
25
ISLE/ios/config.cpp
Normal file
@ -0,0 +1,25 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <SDL3/SDL_filesystem.h>
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <iniparser.h>
|
||||
|
||||
void IOS_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
||||
{
|
||||
SDL_Log("Overriding default config for iOS");
|
||||
|
||||
// Use DevelopmentFiles path for disk and cd paths
|
||||
// It's good to use that path since user can easily
|
||||
// connect through SMB and copy the files
|
||||
const char* documentFolder = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
|
||||
char* diskPath = new char[strlen(documentFolder) + strlen("isle") + 1]();
|
||||
strcpy(diskPath, documentFolder);
|
||||
strcat(diskPath, "isle");
|
||||
|
||||
if (!SDL_GetPathInfo(diskPath, NULL)) {
|
||||
SDL_CreateDirectory(diskPath);
|
||||
}
|
||||
|
||||
iniparser_set(p_dictionary, "isle:diskpath", diskPath);
|
||||
iniparser_set(p_dictionary, "isle:cdpath", diskPath);
|
||||
}
|
||||
8
ISLE/ios/config.h
Normal file
8
ISLE/ios/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef IOS_CONFIG_H
|
||||
#define IOS_CONFIG_H
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
void IOS_SetupDefaultConfigOverrides(dictionary* p_dictionary);
|
||||
|
||||
#endif // IOS_CONFIG_H
|
||||
652
ISLE/isleapp.cpp
652
ISLE/isleapp.cpp
@ -28,13 +28,19 @@
|
||||
#include "mxtransitionmanager.h"
|
||||
#include "mxutilities.h"
|
||||
#include "mxvariabletable.h"
|
||||
#include "res/arrow_bmp.h"
|
||||
#include "res/busy_bmp.h"
|
||||
#include "res/isle_bmp.h"
|
||||
#include "res/no_bmp.h"
|
||||
#include "res/resource.h"
|
||||
#include "roi/legoroi.h"
|
||||
#include "tgl/d3drm/impl.h"
|
||||
#include "viewmanager/viewmanager.h"
|
||||
|
||||
#include <array>
|
||||
#include <extensions/extensions.h>
|
||||
#include <miniwin/miniwindevice.h>
|
||||
#include <vec.h>
|
||||
|
||||
#define SDL_MAIN_USE_CALLBACKS
|
||||
#include <SDL3/SDL.h>
|
||||
@ -45,9 +51,25 @@
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include "emscripten/config.h"
|
||||
#include "emscripten/events.h"
|
||||
#include "emscripten/filesystem.h"
|
||||
#include "emscripten/haptic.h"
|
||||
#include "emscripten/messagebox.h"
|
||||
#include "emscripten/window.h"
|
||||
#endif
|
||||
|
||||
#ifdef __3DS__
|
||||
#include "3ds/apthooks.h"
|
||||
#include "3ds/config.h"
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWS_STORE
|
||||
#include "xbox_one_series/config.h"
|
||||
#endif
|
||||
|
||||
#ifdef IOS
|
||||
#include "ios/config.h"
|
||||
#endif
|
||||
|
||||
DECOMP_SIZE_ASSERT(IsleApp, 0x8c)
|
||||
@ -82,6 +104,17 @@ MxS32 g_targetDepth = 16;
|
||||
// GLOBAL: ISLE 0x410064
|
||||
MxS32 g_reqEnableRMDevice = FALSE;
|
||||
|
||||
MxFloat g_lastJoystickMouseX = 0;
|
||||
MxFloat g_lastJoystickMouseY = 0;
|
||||
MxFloat g_lastMouseX = 320;
|
||||
MxFloat g_lastMouseY = 240;
|
||||
MxBool g_mouseWarped = FALSE;
|
||||
|
||||
bool g_dpadUp = false;
|
||||
bool g_dpadDown = false;
|
||||
bool g_dpadLeft = false;
|
||||
bool g_dpadRight = false;
|
||||
|
||||
// STRING: ISLE 0x4101dc
|
||||
#define WINDOW_TITLE "LEGO®"
|
||||
|
||||
@ -96,11 +129,7 @@ IsleApp::IsleApp()
|
||||
m_cdPath = NULL;
|
||||
m_deviceId = NULL;
|
||||
m_savePath = NULL;
|
||||
#ifdef __EMSCRIPTEN__
|
||||
m_fullScreen = FALSE;
|
||||
#else
|
||||
m_fullScreen = TRUE;
|
||||
#endif
|
||||
m_flipSurfaces = FALSE;
|
||||
m_backBuffersInVram = TRUE;
|
||||
m_using8bit = FALSE;
|
||||
@ -109,8 +138,6 @@ IsleApp::IsleApp()
|
||||
m_drawCursor = FALSE;
|
||||
m_use3dSound = TRUE;
|
||||
m_useMusic = TRUE;
|
||||
m_useJoystick = TRUE;
|
||||
m_joystickIndex = 0;
|
||||
m_wideViewAngle = TRUE;
|
||||
m_islandQuality = 2;
|
||||
m_islandTexture = 1;
|
||||
@ -134,12 +161,29 @@ IsleApp::IsleApp()
|
||||
m_cursorBusy = NULL;
|
||||
m_cursorNo = NULL;
|
||||
m_cursorCurrent = NULL;
|
||||
m_cursorArrowBitmap = NULL;
|
||||
m_cursorBusyBitmap = NULL;
|
||||
m_cursorNoBitmap = NULL;
|
||||
m_cursorCurrentBitmap = NULL;
|
||||
|
||||
LegoOmni::CreateInstance();
|
||||
|
||||
m_iniPath = NULL;
|
||||
m_maxLod = RealtimeView::GetUserMaxLOD();
|
||||
m_maxAllowedExtras = m_islandQuality <= 1 ? 10 : 20;
|
||||
m_transitionType = MxTransitionManager::e_mosaic;
|
||||
m_cursorSensitivity = 4;
|
||||
m_touchScheme = LegoInputManager::e_gamepad;
|
||||
m_haptic = TRUE;
|
||||
m_xRes = 640;
|
||||
m_yRes = 480;
|
||||
m_exclusiveXRes = m_xRes;
|
||||
m_exclusiveYRes = m_yRes;
|
||||
m_exclusiveFrameRate = 60.00f;
|
||||
m_frameRate = 100.0f;
|
||||
m_exclusiveFullScreen = FALSE;
|
||||
m_msaaSamples = 0;
|
||||
m_anisotropic = 0.0f;
|
||||
}
|
||||
|
||||
// FUNCTION: ISLE 0x4011a0
|
||||
@ -244,7 +288,7 @@ void IsleApp::SetupVideoFlags(
|
||||
m_videoParam.Flags().SetLacksLightSupport(!hasLightSupport);
|
||||
m_videoParam.Flags().SetF1bit7(param_7);
|
||||
m_videoParam.Flags().SetWideViewAngle(wideViewAngle);
|
||||
m_videoParam.Flags().SetF2bit1(1);
|
||||
m_videoParam.Flags().SetEnabled(TRUE);
|
||||
m_videoParam.SetDeviceName(deviceId);
|
||||
if (using8bit) {
|
||||
m_videoParam.Flags().Set16Bit(0);
|
||||
@ -261,7 +305,7 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
|
||||
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK)) {
|
||||
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD | SDL_INIT_HAPTIC)) {
|
||||
char buffer[256];
|
||||
SDL_snprintf(
|
||||
buffer,
|
||||
@ -280,7 +324,8 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
|
||||
// Create global app instance
|
||||
g_isle = new IsleApp();
|
||||
|
||||
if (g_isle->ParseArguments(argc, argv) != SUCCESS) {
|
||||
switch (g_isle->ParseArguments(argc, argv)) {
|
||||
case SDL_APP_FAILURE:
|
||||
Any_ShowSimpleMessageBox(
|
||||
SDL_MESSAGEBOX_ERROR,
|
||||
"LEGO® Island Error",
|
||||
@ -288,6 +333,10 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
|
||||
window
|
||||
);
|
||||
return SDL_APP_FAILURE;
|
||||
case SDL_APP_SUCCESS:
|
||||
return SDL_APP_SUCCESS;
|
||||
case SDL_APP_CONTINUE:
|
||||
break;
|
||||
}
|
||||
|
||||
// Create window
|
||||
@ -304,6 +353,23 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
|
||||
// Get reference to window
|
||||
*appstate = g_isle->GetWindowHandle();
|
||||
|
||||
// Currently, SDL doesn't send SDL_EVENT_MOUSE_ADDED at startup (unlike for gamepads)
|
||||
// This will probably be fixed in the future: https://github.com/libsdl-org/SDL/issues/12815
|
||||
{
|
||||
int count;
|
||||
SDL_MouseID* mice = SDL_GetMice(&count);
|
||||
|
||||
if (mice) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (InputManager()) {
|
||||
InputManager()->AddMouse(mice[i]);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_free(mice);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
SDL_AddEventWatch(
|
||||
[](void* userdata, SDL_Event* event) -> bool {
|
||||
@ -316,6 +382,9 @@ SDL_AppResult SDL_AppInit(void** appstate, int argc, char** argv)
|
||||
},
|
||||
NULL
|
||||
);
|
||||
#endif
|
||||
#ifdef __3DS__
|
||||
N3DS_SetupAptHooks();
|
||||
#endif
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
@ -367,6 +436,8 @@ SDL_AppResult SDL_AppIterate(void* appstate)
|
||||
if (g_mousemoved) {
|
||||
g_mousemoved = FALSE;
|
||||
}
|
||||
|
||||
g_isle->MoveVirtualMouseViaJoystick();
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
@ -382,26 +453,27 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
// [library:window]
|
||||
// Remaining functionality to be implemented:
|
||||
// WM_TIMER - use SDL_Timer functionality instead
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
// Workaround for the fact we are getting both mouse & touch events on mobile devices running Emscripten.
|
||||
// On desktops, we are only getting mouse events, but a touch device (pen_input) may also be present...
|
||||
// See: https://github.com/libsdl-org/SDL/issues/13161
|
||||
static bool detectedTouchEvents = false;
|
||||
#endif
|
||||
if (InputManager()) {
|
||||
InputManager()->UpdateLastInputMethod(event);
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
case SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED:
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
case SDL_EVENT_FINGER_MOTION:
|
||||
case SDL_EVENT_FINGER_DOWN:
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
case SDL_EVENT_FINGER_CANCELED:
|
||||
IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice();
|
||||
if (device && !device->ConvertEventToRenderCoordinates(event)) {
|
||||
SDL_Log("Failed to convert event coordinates: %s", SDL_GetError());
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Emscripten_ConvertEventToRenderCoordinates(event);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
@ -422,6 +494,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_WINDOW_CLOSE_REQUESTED:
|
||||
case SDL_EVENT_QUIT:
|
||||
if (!g_closed) {
|
||||
delete g_isle;
|
||||
g_isle = NULL;
|
||||
@ -435,7 +508,7 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
|
||||
SDL_Keycode keyCode = event->key.key;
|
||||
|
||||
if (event->key.mod == SDL_KMOD_LALT && keyCode == SDLK_RETURN) {
|
||||
if ((event->key.mod & SDL_KMOD_LALT) && keyCode == SDLK_RETURN) {
|
||||
SDL_SetWindowFullscreen(window, !(SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN));
|
||||
}
|
||||
else {
|
||||
@ -445,12 +518,155 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (detectedTouchEvents) {
|
||||
case SDL_EVENT_KEYBOARD_ADDED:
|
||||
if (InputManager()) {
|
||||
InputManager()->AddKeyboard(event->kdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_KEYBOARD_REMOVED:
|
||||
if (InputManager()) {
|
||||
InputManager()->RemoveKeyboard(event->kdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_ADDED:
|
||||
if (InputManager()) {
|
||||
InputManager()->AddMouse(event->mdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_MOUSE_REMOVED:
|
||||
if (InputManager()) {
|
||||
InputManager()->RemoveMouse(event->mdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_ADDED:
|
||||
if (InputManager()) {
|
||||
InputManager()->AddJoystick(event->jdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_REMOVED:
|
||||
if (InputManager()) {
|
||||
InputManager()->RemoveJoystick(event->jdevice.which);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_DOWN: {
|
||||
switch (event->gbutton.button) {
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_UP:
|
||||
g_dpadUp = true;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
g_dpadDown = true;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
g_dpadLeft = true;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
g_dpadRight = true;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_EAST:
|
||||
g_mousedown = TRUE;
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(
|
||||
c_notificationButtonDown,
|
||||
LegoEventNotificationParam::c_lButtonState,
|
||||
g_lastMouseX,
|
||||
g_lastMouseY,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_GAMEPAD_BUTTON_SOUTH:
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(c_notificationKeyPress, SDLK_SPACE, 0, 0, SDLK_SPACE);
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_GAMEPAD_BUTTON_START:
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(c_notificationKeyPress, SDLK_ESCAPE, 0, 0, SDLK_ESCAPE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_EVENT_GAMEPAD_BUTTON_UP: {
|
||||
switch (event->gbutton.button) {
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_UP:
|
||||
g_dpadUp = false;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_DOWN:
|
||||
g_dpadDown = false;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_LEFT:
|
||||
g_dpadLeft = false;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_DPAD_RIGHT:
|
||||
g_dpadRight = false;
|
||||
break;
|
||||
case SDL_GAMEPAD_BUTTON_EAST:
|
||||
g_mousedown = FALSE;
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(
|
||||
c_notificationButtonUp,
|
||||
LegoEventNotificationParam::c_lButtonState,
|
||||
g_lastMouseX,
|
||||
g_lastMouseY,
|
||||
0
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_GAMEPAD_AXIS_MOTION: {
|
||||
MxS16 axisValue = 0;
|
||||
if (event->gaxis.value < -8000 || event->gaxis.value > 8000) {
|
||||
// Ignore small axis values
|
||||
axisValue = event->gaxis.value;
|
||||
}
|
||||
if (event->gaxis.axis == SDL_GAMEPAD_AXIS_RIGHTX) {
|
||||
g_lastJoystickMouseX = ((MxFloat) axisValue) / SDL_JOYSTICK_AXIS_MAX * g_isle->GetCursorSensitivity();
|
||||
}
|
||||
else if (event->gaxis.axis == SDL_GAMEPAD_AXIS_RIGHTY) {
|
||||
g_lastJoystickMouseY = ((MxFloat) axisValue) / SDL_JOYSTICK_AXIS_MAX * g_isle->GetCursorSensitivity();
|
||||
}
|
||||
else if (event->gaxis.axis == SDL_GAMEPAD_AXIS_RIGHT_TRIGGER) {
|
||||
if (axisValue != 0 && !g_mousedown) {
|
||||
g_mousedown = TRUE;
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(
|
||||
c_notificationButtonDown,
|
||||
LegoEventNotificationParam::c_lButtonState,
|
||||
g_lastMouseX,
|
||||
g_lastMouseY,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
else if (axisValue == 0 && g_mousedown) {
|
||||
g_mousedown = FALSE;
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(
|
||||
c_notificationButtonUp,
|
||||
LegoEventNotificationParam::c_lButtonState,
|
||||
g_lastMouseX,
|
||||
g_lastMouseY,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_MOTION:
|
||||
if (g_mouseWarped) {
|
||||
g_mouseWarped = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
g_mousemoved = TRUE;
|
||||
|
||||
if (InputManager()) {
|
||||
@ -463,34 +679,41 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
);
|
||||
}
|
||||
|
||||
if (g_isle->GetDrawCursor()) {
|
||||
VideoManager()->MoveCursor(Min((MxS32) event->motion.x, 639), Min((MxS32) event->motion.y, 479));
|
||||
g_lastMouseX = event->motion.x;
|
||||
g_lastMouseY = event->motion.y;
|
||||
|
||||
SDL_ShowCursor();
|
||||
g_isle->SetDrawCursor(FALSE);
|
||||
if (VideoManager()) {
|
||||
VideoManager()->SetCursorBitmap(NULL);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_MOTION: {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
detectedTouchEvents = true;
|
||||
#endif
|
||||
g_mousemoved = TRUE;
|
||||
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(c_notificationMouseMove, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
||||
MxU8 modifier = LegoEventNotificationParam::c_lButtonState;
|
||||
if (InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme())) {
|
||||
modifier |= LegoEventNotificationParam::c_motionHandled;
|
||||
}
|
||||
|
||||
InputManager()->QueueEvent(c_notificationMouseMove, modifier, x, y, 0);
|
||||
}
|
||||
|
||||
if (g_isle->GetDrawCursor()) {
|
||||
VideoManager()->MoveCursor(Min((MxS32) x, 639), Min((MxS32) y, 479));
|
||||
g_lastMouseX = x;
|
||||
g_lastMouseY = y;
|
||||
|
||||
SDL_HideCursor();
|
||||
g_isle->SetDrawCursor(FALSE);
|
||||
if (VideoManager()) {
|
||||
VideoManager()->SetCursorBitmap(NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_DOWN:
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (detectedTouchEvents) {
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
g_mousedown = TRUE;
|
||||
|
||||
if (InputManager()) {
|
||||
@ -504,31 +727,27 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_DOWN: {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
detectedTouchEvents = true;
|
||||
#endif
|
||||
g_mousedown = TRUE;
|
||||
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme());
|
||||
InputManager()->QueueEvent(c_notificationButtonDown, LegoEventNotificationParam::c_lButtonState, x, y, 0);
|
||||
}
|
||||
|
||||
g_lastMouseX = x;
|
||||
g_lastMouseY = y;
|
||||
|
||||
SDL_HideCursor();
|
||||
g_isle->SetDrawCursor(FALSE);
|
||||
if (VideoManager()) {
|
||||
VideoManager()->SetCursorBitmap(NULL);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_MOUSE_BUTTON_UP:
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (detectedTouchEvents) {
|
||||
// Abusing the fact (bug?) that we are always getting mouse events on Emscripten.
|
||||
// This functionality should be enabled in a more general way with touch events,
|
||||
// but SDL touch event's don't have a "double tap" indicator right now.
|
||||
if (event->button.clicks == 2) {
|
||||
InputManager()->QueueEvent(c_notificationKeyPress, SDLK_SPACE, 0, 0, SDLK_SPACE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
g_mousedown = FALSE;
|
||||
|
||||
if (InputManager()) {
|
||||
@ -541,23 +760,21 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case SDL_EVENT_FINGER_UP: {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
detectedTouchEvents = true;
|
||||
#endif
|
||||
case SDL_EVENT_FINGER_UP:
|
||||
case SDL_EVENT_FINGER_CANCELED: {
|
||||
g_mousedown = FALSE;
|
||||
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * 640;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * 480;
|
||||
float x = SDL_clamp(event->tfinger.x, 0, 1) * g_targetWidth;
|
||||
float y = SDL_clamp(event->tfinger.y, 0, 1) * g_targetHeight;
|
||||
|
||||
g_isle->DetectDoubleTap(event->tfinger);
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->HandleTouchEvent(event, g_isle->GetTouchScheme());
|
||||
InputManager()->QueueEvent(c_notificationButtonUp, 0, x, y, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_EVENT_QUIT:
|
||||
return SDL_APP_SUCCESS;
|
||||
break;
|
||||
}
|
||||
|
||||
if (event->user.type == g_legoSdlEvents.m_windowsMessage) {
|
||||
@ -588,9 +805,41 @@ SDL_AppResult SDL_AppEvent(void* appstate, SDL_Event* event)
|
||||
if (!g_isle->GetGameStarted() && action && state == MxPresenter::e_ready &&
|
||||
!SDL_strncmp(action->GetObjectName(), "Lego_Smk", 8)) {
|
||||
g_isle->SetGameStarted(TRUE);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Emscripten_SetupWindow((SDL_Window*) g_isle->GetWindowHandle());
|
||||
#endif
|
||||
|
||||
SDL_Log("Game started");
|
||||
}
|
||||
}
|
||||
else if (event->user.type == g_legoSdlEvents.m_gameEvent) {
|
||||
auto rumble = [](float p_strength, float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds
|
||||
) {
|
||||
if (g_isle->GetHaptic() &&
|
||||
!InputManager()
|
||||
->HandleRumbleEvent(p_strength, p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds)) {
|
||||
// Platform-specific handling
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Emscripten_HandleRumbleEvent(p_lowFrequencyRumble, p_highFrequencyRumble, p_milliseconds);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
switch (event->user.code) {
|
||||
case e_hitActor:
|
||||
rumble(0.5f, 0.5f, 0.5f, 700);
|
||||
break;
|
||||
case e_skeletonKick:
|
||||
rumble(0.8f, 0.8f, 0.8f, 2500);
|
||||
break;
|
||||
case e_raceFinished:
|
||||
case e_goodEnding:
|
||||
case e_badEnding:
|
||||
rumble(1.0f, 1.0f, 1.0f, 3000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
@ -651,18 +900,39 @@ MxResult IsleApp::SetupWindow()
|
||||
m_cursorBusy = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_WAIT);
|
||||
m_cursorNo = SDL_CreateSystemCursor(SDL_SYSTEM_CURSOR_NOT_ALLOWED);
|
||||
SDL_SetCursor(m_cursorCurrent);
|
||||
m_cursorCurrentBitmap = m_cursorArrowBitmap = &arrow_cursor;
|
||||
m_cursorBusyBitmap = &busy_cursor;
|
||||
m_cursorNoBitmap = &no_cursor;
|
||||
|
||||
SDL_PropertiesID props = SDL_CreateProperties();
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_WIDTH_NUMBER, g_targetWidth);
|
||||
SDL_SetNumberProperty(props, SDL_PROP_WINDOW_CREATE_HEIGHT_NUMBER, g_targetHeight);
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_FULLSCREEN_BOOLEAN, m_fullScreen);
|
||||
SDL_SetStringProperty(props, SDL_PROP_WINDOW_CREATE_TITLE_STRING, WINDOW_TITLE);
|
||||
#ifdef MINIWIN
|
||||
#if defined(MINIWIN) && !defined(__3DS__) && !defined(WINDOWS_STORE)
|
||||
SDL_SetBooleanProperty(props, SDL_PROP_WINDOW_CREATE_OPENGL_BOOLEAN, true);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindowWithProperties(props);
|
||||
SDL_SetPointerProperty(SDL_GetWindowProperties(window), ISLE_PROP_WINDOW_CREATE_VIDEO_PARAM, &m_videoParam);
|
||||
|
||||
if (m_exclusiveFullScreen && m_fullScreen) {
|
||||
SDL_DisplayMode closestMode;
|
||||
SDL_DisplayID displayID = SDL_GetDisplayForWindow(window);
|
||||
if (SDL_GetClosestFullscreenDisplayMode(
|
||||
displayID,
|
||||
m_exclusiveXRes,
|
||||
m_exclusiveYRes,
|
||||
m_exclusiveFrameRate,
|
||||
true,
|
||||
&closestMode
|
||||
)) {
|
||||
SDL_SetWindowFullscreenMode(window, &closestMode);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef MINIWIN
|
||||
m_windowHandle = reinterpret_cast<HWND>(window);
|
||||
#else
|
||||
@ -703,6 +973,7 @@ MxResult IsleApp::SetupWindow()
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
DetectGameVersion();
|
||||
GameState()->SerializePlayersInfo(LegoStorage::c_read);
|
||||
GameState()->SerializeScoreHistory(LegoStorage::c_read);
|
||||
|
||||
@ -725,11 +996,11 @@ MxResult IsleApp::SetupWindow()
|
||||
LegoBuildingManager::configureLegoBuildingManager(m_islandQuality);
|
||||
LegoROI::configureLegoROI(iVar10);
|
||||
LegoAnimationManager::configureLegoAnimationManager(m_maxAllowedExtras);
|
||||
MxTransitionManager::configureMxTransitionManager(m_transitionType);
|
||||
RealtimeView::SetUserMaxLOD(m_maxLod);
|
||||
if (LegoOmni::GetInstance()) {
|
||||
if (LegoOmni::GetInstance()->GetInputManager()) {
|
||||
LegoOmni::GetInstance()->GetInputManager()->SetUseJoystick(m_useJoystick);
|
||||
LegoOmni::GetInstance()->GetInputManager()->SetJoystickIndex(m_joystickIndex);
|
||||
if (LegoOmni::GetInstance()->GetVideoManager()) {
|
||||
LegoOmni::GetInstance()->GetVideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
|
||||
}
|
||||
MxDirect3D* d3d = LegoOmni::GetInstance()->GetVideoManager()->GetDirect3D();
|
||||
if (d3d) {
|
||||
@ -752,8 +1023,19 @@ MxResult IsleApp::SetupWindow()
|
||||
// FUNCTION: ISLE 0x4028d0
|
||||
bool IsleApp::LoadConfig()
|
||||
{
|
||||
#ifdef IOS
|
||||
const char* prefPath = SDL_GetUserFolder(SDL_FOLDER_DOCUMENTS);
|
||||
#else
|
||||
char* prefPath = SDL_GetPrefPath("isledecomp", "isle");
|
||||
#endif
|
||||
char* iniConfig;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (m_iniPath && !Emscripten_SetupConfig(m_iniPath)) {
|
||||
m_iniPath = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_iniPath) {
|
||||
iniConfig = new char[strlen(m_iniPath) + 1];
|
||||
strcpy(iniConfig, m_iniPath);
|
||||
@ -769,10 +1051,6 @@ bool IsleApp::LoadConfig()
|
||||
}
|
||||
SDL_Log("Reading configuration from \"%s\"", iniConfig);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
Emscripten_SetupConfig(iniConfig);
|
||||
#endif
|
||||
|
||||
dictionary* dict = iniparser_load(iniConfig);
|
||||
|
||||
// [library:config]
|
||||
@ -807,14 +1085,14 @@ bool IsleApp::LoadConfig()
|
||||
|
||||
iniparser_set(dict, "isle:Flip Surfaces", m_flipSurfaces ? "true" : "false");
|
||||
iniparser_set(dict, "isle:Full Screen", m_fullScreen ? "true" : "false");
|
||||
iniparser_set(dict, "isle:Exclusive Full Screen", m_exclusiveFullScreen ? "true" : "false");
|
||||
iniparser_set(dict, "isle:Wide View Angle", m_wideViewAngle ? "true" : "false");
|
||||
|
||||
iniparser_set(dict, "isle:3DSound", m_use3dSound ? "true" : "false");
|
||||
iniparser_set(dict, "isle:Music", m_useMusic ? "true" : "false");
|
||||
|
||||
iniparser_set(dict, "isle:UseJoystick", m_useJoystick ? "true" : "false");
|
||||
iniparser_set(dict, "isle:JoystickIndex", SDL_itoa(m_joystickIndex, buf, 10));
|
||||
iniparser_set(dict, "isle:Draw Cursor", m_drawCursor ? "true" : "false");
|
||||
SDL_snprintf(buf, sizeof(buf), "%f", m_cursorSensitivity);
|
||||
iniparser_set(dict, "isle:Cursor Sensitivity", buf);
|
||||
|
||||
iniparser_set(dict, "isle:Back Buffers in Video RAM", "-1");
|
||||
|
||||
@ -823,26 +1101,47 @@ bool IsleApp::LoadConfig()
|
||||
SDL_snprintf(buf, sizeof(buf), "%f", m_maxLod);
|
||||
iniparser_set(dict, "isle:Max LOD", buf);
|
||||
iniparser_set(dict, "isle:Max Allowed Extras", SDL_itoa(m_maxAllowedExtras, buf, 10));
|
||||
iniparser_set(dict, "isle:Transition Type", SDL_itoa(m_transitionType, buf, 10));
|
||||
iniparser_set(dict, "isle:Touch Scheme", SDL_itoa(m_touchScheme, buf, 10));
|
||||
iniparser_set(dict, "isle:Haptic", m_haptic ? "true" : "false");
|
||||
iniparser_set(dict, "isle:Horizontal Resolution", SDL_itoa(m_xRes, buf, 10));
|
||||
iniparser_set(dict, "isle:Vertical Resolution", SDL_itoa(m_yRes, buf, 10));
|
||||
iniparser_set(dict, "isle:Exclusive X Resolution", SDL_itoa(m_exclusiveXRes, buf, 10));
|
||||
iniparser_set(dict, "isle:Exclusive Y Resolution", SDL_itoa(m_exclusiveYRes, buf, 10));
|
||||
iniparser_set(dict, "isle:Exclusive Framerate", SDL_itoa(m_exclusiveFrameRate, buf, 10));
|
||||
iniparser_set(dict, "isle:Frame Delta", SDL_itoa(m_frameDelta, buf, 10));
|
||||
|
||||
#ifdef EXTENSIONS
|
||||
iniparser_set(dict, "extensions", NULL);
|
||||
for (const char* key : Extensions::availableExtensions) {
|
||||
iniparser_set(dict, key, "false");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __3DS__
|
||||
N3DS_SetupDefaultConfigOverrides(dict);
|
||||
#endif
|
||||
#ifdef WINDOWS_STORE
|
||||
XBONE_SetupDefaultConfigOverrides(dict);
|
||||
#endif
|
||||
#ifdef IOS
|
||||
IOS_SetupDefaultConfigOverrides(dict);
|
||||
#endif
|
||||
iniparser_dump_ini(dict, iniFP);
|
||||
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION, "New config written at '%s'", iniConfig);
|
||||
fclose(iniFP);
|
||||
}
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const char* hdPath = Emscripten_bundledPath;
|
||||
#else
|
||||
const char* hdPath = iniparser_getstring(dict, "isle:diskpath", SDL_GetBasePath());
|
||||
Emscripten_SetupDefaultConfigOverrides(dict);
|
||||
#endif
|
||||
|
||||
const char* hdPath = iniparser_getstring(dict, "isle:diskpath", SDL_GetBasePath());
|
||||
m_hdPath = new char[strlen(hdPath) + 1];
|
||||
strcpy(m_hdPath, hdPath);
|
||||
MxOmni::SetHD(m_hdPath);
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const char* cdPath = Emscripten_streamPath;
|
||||
#else
|
||||
const char* cdPath = iniparser_getstring(dict, "isle:cdpath", MxOmni::GetCD());
|
||||
#endif
|
||||
m_cdPath = new char[strlen(cdPath) + 1];
|
||||
strcpy(m_cdPath, cdPath);
|
||||
MxOmni::SetCD(m_cdPath);
|
||||
@ -853,12 +1152,11 @@ bool IsleApp::LoadConfig()
|
||||
|
||||
m_flipSurfaces = iniparser_getboolean(dict, "isle:Flip Surfaces", m_flipSurfaces);
|
||||
m_fullScreen = iniparser_getboolean(dict, "isle:Full Screen", m_fullScreen);
|
||||
m_exclusiveFullScreen = iniparser_getboolean(dict, "isle:Exclusive Full Screen", m_exclusiveFullScreen);
|
||||
m_wideViewAngle = iniparser_getboolean(dict, "isle:Wide View Angle", m_wideViewAngle);
|
||||
m_use3dSound = iniparser_getboolean(dict, "isle:3DSound", m_use3dSound);
|
||||
m_useMusic = iniparser_getboolean(dict, "isle:Music", m_useMusic);
|
||||
m_useJoystick = iniparser_getboolean(dict, "isle:UseJoystick", m_useJoystick);
|
||||
m_joystickIndex = iniparser_getint(dict, "isle:JoystickIndex", m_joystickIndex);
|
||||
m_drawCursor = iniparser_getboolean(dict, "isle:Draw Cursor", m_drawCursor);
|
||||
m_cursorSensitivity = iniparser_getdouble(dict, "isle:Cursor Sensitivity", m_cursorSensitivity);
|
||||
|
||||
MxS32 backBuffersInVRAM = iniparser_getboolean(dict, "isle:Back Buffers in Video RAM", -1);
|
||||
if (backBuffersInVRAM != -1) {
|
||||
@ -879,6 +1177,22 @@ bool IsleApp::LoadConfig()
|
||||
m_islandTexture = iniparser_getint(dict, "isle:Island Texture", m_islandTexture);
|
||||
m_maxLod = iniparser_getdouble(dict, "isle:Max LOD", m_maxLod);
|
||||
m_maxAllowedExtras = iniparser_getint(dict, "isle:Max Allowed Extras", m_maxAllowedExtras);
|
||||
m_transitionType =
|
||||
(MxTransitionManager::TransitionType) iniparser_getint(dict, "isle:Transition Type", m_transitionType);
|
||||
m_touchScheme = (LegoInputManager::TouchScheme) iniparser_getint(dict, "isle:Touch Scheme", m_touchScheme);
|
||||
m_haptic = iniparser_getboolean(dict, "isle:Haptic", m_haptic);
|
||||
m_xRes = iniparser_getint(dict, "isle:Horizontal Resolution", m_xRes);
|
||||
m_yRes = iniparser_getint(dict, "isle:Vertical Resolution", m_yRes);
|
||||
m_exclusiveXRes = iniparser_getint(dict, "isle:Exclusive X Resolution", m_exclusiveXRes);
|
||||
m_exclusiveYRes = iniparser_getint(dict, "isle:Exclusive Y Resolution", m_exclusiveXRes);
|
||||
m_exclusiveFrameRate = iniparser_getdouble(dict, "isle:Exclusive Framerate", m_exclusiveFrameRate);
|
||||
if (!m_fullScreen) {
|
||||
m_videoParam.GetRect() = MxRect32(0, 0, (m_xRes - 1), (m_yRes - 1));
|
||||
}
|
||||
m_frameRate = (1000.0f / iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta));
|
||||
m_frameDelta = static_cast<int>(std::round(iniparser_getdouble(dict, "isle:Frame Delta", m_frameDelta)));
|
||||
m_videoParam.SetMSAASamples((m_msaaSamples = iniparser_getint(dict, "isle:MSAA", m_msaaSamples)));
|
||||
m_videoParam.SetAnisotropic((m_anisotropic = iniparser_getdouble(dict, "isle:Anisotropic", m_anisotropic)));
|
||||
|
||||
const char* deviceId = iniparser_getstring(dict, "isle:3D Device ID", NULL);
|
||||
if (deviceId != NULL) {
|
||||
@ -889,17 +1203,33 @@ bool IsleApp::LoadConfig()
|
||||
// [library:config]
|
||||
// The original game does not save any data if no savepath is given.
|
||||
// Instead, we use SDLs prefPath as a default fallback and always save data.
|
||||
#ifdef __EMSCRIPTEN__
|
||||
const char* savePath = Emscripten_savePath;
|
||||
#else
|
||||
const char* savePath = iniparser_getstring(dict, "isle:savepath", prefPath);
|
||||
#endif
|
||||
m_savePath = new char[strlen(savePath) + 1];
|
||||
strcpy(m_savePath, savePath);
|
||||
|
||||
#ifdef EXTENSIONS
|
||||
for (const char* key : Extensions::availableExtensions) {
|
||||
if (iniparser_getboolean(dict, key, 0)) {
|
||||
std::vector<const char*> extensionKeys;
|
||||
const char* section = SDL_strchr(key, ':') + 1;
|
||||
extensionKeys.resize(iniparser_getsecnkeys(dict, section));
|
||||
iniparser_getseckeys(dict, section, extensionKeys.data());
|
||||
|
||||
std::map<std::string, std::string> extensionDict;
|
||||
for (const char* key : extensionKeys) {
|
||||
extensionDict[key] = iniparser_getstring(dict, key, NULL);
|
||||
}
|
||||
|
||||
Extensions::Enable(key, std::move(extensionDict));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
iniparser_freedict(dict);
|
||||
delete[] iniConfig;
|
||||
#ifndef IOS
|
||||
SDL_free(prefPath);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1003,15 +1333,19 @@ void IsleApp::SetupCursor(Cursor p_cursor)
|
||||
switch (p_cursor) {
|
||||
case e_cursorArrow:
|
||||
m_cursorCurrent = m_cursorArrow;
|
||||
m_cursorCurrentBitmap = m_cursorArrowBitmap;
|
||||
break;
|
||||
case e_cursorBusy:
|
||||
m_cursorCurrent = m_cursorBusy;
|
||||
m_cursorCurrentBitmap = m_cursorBusyBitmap;
|
||||
break;
|
||||
case e_cursorNo:
|
||||
m_cursorCurrent = m_cursorNo;
|
||||
m_cursorCurrentBitmap = m_cursorNoBitmap;
|
||||
break;
|
||||
case e_cursorNone:
|
||||
m_cursorCurrent = NULL;
|
||||
m_cursorCurrentBitmap = NULL;
|
||||
case e_cursorUnused3:
|
||||
case e_cursorUnused4:
|
||||
case e_cursorUnused5:
|
||||
@ -1023,16 +1357,21 @@ void IsleApp::SetupCursor(Cursor p_cursor)
|
||||
break;
|
||||
}
|
||||
|
||||
if (m_cursorCurrent != NULL) {
|
||||
SDL_SetCursor(m_cursorCurrent);
|
||||
SDL_ShowCursor();
|
||||
if (g_isle->GetDrawCursor()) {
|
||||
VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
|
||||
}
|
||||
else {
|
||||
SDL_HideCursor();
|
||||
if (m_cursorCurrent != NULL) {
|
||||
SDL_SetCursor(m_cursorCurrent);
|
||||
SDL_ShowCursor();
|
||||
}
|
||||
else {
|
||||
SDL_HideCursor();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MxResult IsleApp::ParseArguments(int argc, char** argv)
|
||||
SDL_AppResult IsleApp::ParseArguments(int argc, char** argv)
|
||||
{
|
||||
for (int i = 1, consumed; i < argc; i += consumed) {
|
||||
consumed = -1;
|
||||
@ -1049,13 +1388,29 @@ MxResult IsleApp::ParseArguments(int argc, char** argv)
|
||||
#endif
|
||||
consumed = 1;
|
||||
}
|
||||
else if (strcmp(argv[i], "--help") == 0) {
|
||||
DisplayArgumentHelp();
|
||||
return SDL_APP_SUCCESS;
|
||||
}
|
||||
if (consumed <= 0) {
|
||||
SDL_Log("Invalid argument(s): %s", argv[i]);
|
||||
return FAILURE;
|
||||
DisplayArgumentHelp();
|
||||
return SDL_APP_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return SUCCESS;
|
||||
return SDL_APP_CONTINUE;
|
||||
}
|
||||
|
||||
void IsleApp::DisplayArgumentHelp()
|
||||
{
|
||||
SDL_Log("Usage: isle [options]");
|
||||
SDL_Log("Options:");
|
||||
SDL_Log(" --ini <path> Set custom path to .ini config");
|
||||
#ifdef ISLE_DEBUG
|
||||
SDL_Log(" --debug Launch in debug mode");
|
||||
#endif
|
||||
SDL_Log(" --help Show this help message");
|
||||
}
|
||||
|
||||
MxResult IsleApp::VerifyFilesystem()
|
||||
@ -1098,6 +1453,34 @@ MxResult IsleApp::VerifyFilesystem()
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
void IsleApp::DetectGameVersion()
|
||||
{
|
||||
const char* file = "/lego/scripts/infocntr/infomain.si";
|
||||
SDL_PathInfo info;
|
||||
bool success = false;
|
||||
|
||||
MxString path = MxString(m_hdPath) + file;
|
||||
path.MapPathToFilesystem();
|
||||
if (!(success = SDL_GetPathInfo(path.GetData(), &info))) {
|
||||
path = MxString(m_cdPath) + file;
|
||||
path.MapPathToFilesystem();
|
||||
success = SDL_GetPathInfo(path.GetData(), &info);
|
||||
}
|
||||
|
||||
assert(success);
|
||||
|
||||
// File sizes of INFOMAIN.SI in English 1.0 and Japanese 1.0
|
||||
Lego()->SetVersion10(info.size == 58130432 || info.size == 57737216);
|
||||
|
||||
if (Lego()->IsVersion10()) {
|
||||
SDL_Log("Detected game version 1.0");
|
||||
SDL_SetWindowTitle(reinterpret_cast<SDL_Window*>(m_windowHandle), "Lego Island");
|
||||
}
|
||||
else {
|
||||
SDL_Log("Detected game version 1.1");
|
||||
}
|
||||
}
|
||||
|
||||
IDirect3DRMMiniwinDevice* GetD3DRMMiniwinDevice()
|
||||
{
|
||||
LegoVideoManager* videoManager = LegoOmni::GetInstance()->GetVideoManager();
|
||||
@ -1126,3 +1509,80 @@ IDirect3DRMMiniwinDevice* GetD3DRMMiniwinDevice()
|
||||
}
|
||||
return d3drmMiniwinDev;
|
||||
}
|
||||
|
||||
void IsleApp::MoveVirtualMouseViaJoystick()
|
||||
{
|
||||
float dpadX = 0.0f;
|
||||
float dpadY = 0.0f;
|
||||
|
||||
if (g_dpadLeft) {
|
||||
dpadX -= m_cursorSensitivity;
|
||||
}
|
||||
if (g_dpadRight) {
|
||||
dpadX += m_cursorSensitivity;
|
||||
}
|
||||
if (g_dpadUp) {
|
||||
dpadY -= m_cursorSensitivity;
|
||||
}
|
||||
if (g_dpadDown) {
|
||||
dpadY += m_cursorSensitivity;
|
||||
}
|
||||
|
||||
// Use joystick axis if non-zero, else fall back to dpad
|
||||
float moveX = (g_lastJoystickMouseX != 0) ? g_lastJoystickMouseX : dpadX;
|
||||
float moveY = (g_lastJoystickMouseY != 0) ? g_lastJoystickMouseY : dpadY;
|
||||
|
||||
if (moveX != 0 || moveY != 0) {
|
||||
g_mousemoved = TRUE;
|
||||
|
||||
g_lastMouseX = SDL_clamp(g_lastMouseX + moveX, 0, g_targetWidth);
|
||||
g_lastMouseY = SDL_clamp(g_lastMouseY + moveY, 0, g_targetHeight);
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(
|
||||
c_notificationMouseMove,
|
||||
g_mousedown ? LegoEventNotificationParam::c_lButtonState : 0,
|
||||
g_lastMouseX,
|
||||
g_lastMouseY,
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
SDL_HideCursor();
|
||||
g_isle->SetDrawCursor(TRUE);
|
||||
if (VideoManager()) {
|
||||
VideoManager()->SetCursorBitmap(m_cursorCurrentBitmap);
|
||||
VideoManager()->MoveCursor(Min((MxS32) g_lastMouseX, 639), Min((MxS32) g_lastMouseY, 479));
|
||||
}
|
||||
IDirect3DRMMiniwinDevice* device = GetD3DRMMiniwinDevice();
|
||||
if (device) {
|
||||
Sint32 x, y;
|
||||
device->ConvertRenderToWindowCoordinates(g_lastMouseX, g_lastMouseY, x, y);
|
||||
g_mouseWarped = TRUE;
|
||||
SDL_WarpMouseInWindow(window, x, y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void IsleApp::DetectDoubleTap(const SDL_TouchFingerEvent& p_event)
|
||||
{
|
||||
typedef std::pair<Uint64, std::array<float, 2>> LastTap;
|
||||
|
||||
const MxU32 doubleTapMs = 500;
|
||||
const float doubleTapDist = 0.001;
|
||||
static LastTap lastTap = {0, {0, 0}};
|
||||
|
||||
LastTap currentTap = {p_event.timestamp, {p_event.x, p_event.y}};
|
||||
if (SDL_NS_TO_MS(currentTap.first - lastTap.first) < doubleTapMs &&
|
||||
DISTSQRD2(currentTap.second, lastTap.second) < doubleTapDist) {
|
||||
|
||||
if (InputManager()) {
|
||||
InputManager()->QueueEvent(c_notificationKeyPress, SDLK_SPACE, 0, 0, SDLK_SPACE);
|
||||
}
|
||||
|
||||
lastTap = {0, {0, 0}};
|
||||
}
|
||||
else {
|
||||
lastTap = currentTap;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
#ifndef ISLEAPP_H
|
||||
#define ISLEAPP_H
|
||||
|
||||
#include "cursor.h"
|
||||
#include "lego1_export.h"
|
||||
#include "legoinputmanager.h"
|
||||
#include "legoutils.h"
|
||||
#include "mxtransitionmanager.h"
|
||||
#include "mxtypes.h"
|
||||
#include "mxvideoparam.h"
|
||||
|
||||
@ -50,19 +53,26 @@ class IsleApp {
|
||||
SDL_Cursor* GetCursorNo() { return m_cursorNo; }
|
||||
MxS32 GetDrawCursor() { return m_drawCursor; }
|
||||
MxS32 GetGameStarted() { return m_gameStarted; }
|
||||
MxFloat GetCursorSensitivity() { return m_cursorSensitivity; }
|
||||
LegoInputManager::TouchScheme GetTouchScheme() { return m_touchScheme; }
|
||||
MxBool GetHaptic() { return m_haptic; }
|
||||
|
||||
void SetWindowActive(MxS32 p_windowActive) { m_windowActive = p_windowActive; }
|
||||
void SetGameStarted(MxS32 p_gameStarted) { m_gameStarted = p_gameStarted; }
|
||||
void SetDrawCursor(MxS32 p_drawCursor) { m_drawCursor = p_drawCursor; }
|
||||
|
||||
MxResult ParseArguments(int argc, char** argv);
|
||||
SDL_AppResult ParseArguments(int argc, char** argv);
|
||||
MxResult VerifyFilesystem();
|
||||
void DetectGameVersion();
|
||||
void MoveVirtualMouseViaJoystick();
|
||||
void DetectDoubleTap(const SDL_TouchFingerEvent& p_event);
|
||||
|
||||
private:
|
||||
char* m_hdPath; // 0x00
|
||||
char* m_cdPath; // 0x04
|
||||
char* m_deviceId; // 0x08
|
||||
char* m_savePath; // 0x0c
|
||||
MxS32 m_fullScreen; // 0x10
|
||||
MxBool m_fullScreen; // 0x10
|
||||
MxS32 m_flipSurfaces; // 0x14
|
||||
MxS32 m_backBuffersInVram; // 0x18
|
||||
MxS32 m_using8bit; // 0x1c
|
||||
@ -70,8 +80,6 @@ class IsleApp {
|
||||
MxS32 m_hasLightSupport; // 0x24
|
||||
MxS32 m_use3dSound; // 0x28
|
||||
MxS32 m_useMusic; // 0x2c
|
||||
MxS32 m_useJoystick; // 0x30
|
||||
MxS32 m_joystickIndex; // 0x34
|
||||
MxS32 m_wideViewAngle; // 0x38
|
||||
MxS32 m_islandQuality; // 0x3c
|
||||
MxS32 m_islandTexture; // 0x40
|
||||
@ -85,14 +93,33 @@ class IsleApp {
|
||||
SDL_Cursor* m_cursorBusy; // 0x80
|
||||
SDL_Cursor* m_cursorNo; // 0x84
|
||||
SDL_Cursor* m_cursorCurrent; // 0x88
|
||||
const CursorBitmap* m_cursorArrowBitmap;
|
||||
const CursorBitmap* m_cursorBusyBitmap;
|
||||
const CursorBitmap* m_cursorNoBitmap;
|
||||
const CursorBitmap* m_cursorCurrentBitmap;
|
||||
char* m_mediaPath;
|
||||
MxFloat m_cursorSensitivity;
|
||||
void DisplayArgumentHelp();
|
||||
|
||||
char* m_iniPath;
|
||||
MxFloat m_maxLod;
|
||||
MxU32 m_maxAllowedExtras;
|
||||
MxTransitionManager::TransitionType m_transitionType;
|
||||
LegoInputManager::TouchScheme m_touchScheme;
|
||||
MxBool m_haptic;
|
||||
MxS32 m_xRes;
|
||||
MxS32 m_yRes;
|
||||
MxS32 m_exclusiveXRes;
|
||||
MxS32 m_exclusiveYRes;
|
||||
MxFloat m_exclusiveFrameRate;
|
||||
MxFloat m_frameRate;
|
||||
MxBool m_exclusiveFullScreen;
|
||||
MxU32 m_msaaSamples;
|
||||
MxFloat m_anisotropic;
|
||||
};
|
||||
|
||||
extern IsleApp* g_isle;
|
||||
extern MxS32 g_closed;
|
||||
|
||||
extern IDirect3DRMMiniwinDevice* GetD3DRMMiniwinDevice();
|
||||
|
||||
|
||||
@ -46,7 +46,7 @@ class DebugViewer {
|
||||
if (plantManager->m_numEntries) {
|
||||
if (ImGui::BeginTable("Animated Entries", 4, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("ROI Name");
|
||||
ImGui::TableSetupColumn("ROI m_unk0x100");
|
||||
ImGui::TableSetupColumn("ROI m_sharedLodList");
|
||||
ImGui::TableSetupColumn("Entity Name");
|
||||
ImGui::TableSetupColumn("Time");
|
||||
ImGui::TableHeadersRow();
|
||||
@ -55,7 +55,7 @@ class DebugViewer {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::Text("%s", entry->m_roi->m_name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_roi->m_unk0x100);
|
||||
ImGui::Text("%d", entry->m_roi->m_sharedLodList);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
|
||||
ImGui::TableNextColumn();
|
||||
@ -75,7 +75,7 @@ class DebugViewer {
|
||||
if (buildingManager->m_numEntries) {
|
||||
if (ImGui::BeginTable("Animated Entries", 6, ImGuiTableFlags_Borders)) {
|
||||
ImGui::TableSetupColumn("ROI Name");
|
||||
ImGui::TableSetupColumn("ROI m_unk0x100");
|
||||
ImGui::TableSetupColumn("ROI m_sharedLodList");
|
||||
ImGui::TableSetupColumn("Entity Name");
|
||||
ImGui::TableSetupColumn("Time");
|
||||
ImGui::TableSetupColumn("Y");
|
||||
@ -86,13 +86,13 @@ class DebugViewer {
|
||||
ImGui::TableNextRow();
|
||||
ImGui::Text("%s", entry->m_roi->m_name);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_roi->m_unk0x100);
|
||||
ImGui::Text("%d", entry->m_roi->m_sharedLodList);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", entry->m_roi->m_entity->ClassName());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_time);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_y);
|
||||
ImGui::Text("%f", entry->m_y);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%d", entry->m_muted);
|
||||
}
|
||||
@ -135,7 +135,7 @@ class DebugViewer {
|
||||
ImGui::Text("unk0x70: %u", videoManager->m_unk0x70);
|
||||
ImGui::Text("Dither: %d", videoManager->m_dither);
|
||||
ImGui::Text("BufferCount: %u", videoManager->m_bufferCount);
|
||||
ImGui::Text("Paused: %f", videoManager->m_paused);
|
||||
ImGui::Text("Paused: %d", videoManager->m_paused);
|
||||
ImGui::Text("back: %g", videoManager->m_back);
|
||||
ImGui::Text("front: %g", videoManager->m_front);
|
||||
ImGui::Text("cameraWidth: %g", videoManager->m_cameraWidth);
|
||||
@ -309,7 +309,7 @@ void IsleDebug_Render()
|
||||
if (ImGui::TreeNode("Sound Manager")) {
|
||||
LegoSoundManager* soundManager = lego->GetSoundManager();
|
||||
Sint32 oldVolume = soundManager->GetVolume();
|
||||
Sint32 volume = oldVolume;
|
||||
int volume = oldVolume;
|
||||
ImGui::SliderInt("volume", &volume, 0, 100);
|
||||
if (volume != oldVolume) {
|
||||
soundManager->SetVolume(volume);
|
||||
|
||||
@ -46,3 +46,24 @@ const char* g_files[46] = {
|
||||
"/LEGO/data/WORLD.WDB",
|
||||
"/LEGO/data/testinf.dta",
|
||||
};
|
||||
|
||||
const char* g_textures[120] = {
|
||||
"bank01.gif", "beach.gif", "black.gif", "bowtie.gif", "brela_01.gif", "bth1chst.gif", "bth2chst.gif",
|
||||
"capch.gif", "capdb.gif", "capjs.gif", "capmd.gif", "caprc.gif", "cave_24x.gif", "caverocx.gif",
|
||||
"caverokx.gif", "cheker01.gif", "construct.gif", "copchest.gif", "dbfrfn.gif", "doctor.gif", "dogface.gif",
|
||||
"dummy.gif", "e.gif", "flowers.gif", "fruit.gif", "gasroad.gif", "gdface.gif", "g.gif",
|
||||
"grassx.gif", "infochst.gif", "infoface.gif", "jailpad.gif", "jfrnt.gif", "jsfrnt4.gif", "jsfrnt.gif",
|
||||
"jside.gif", "jswnsh5.gif", "jswnsh.gif", "l6.gif", "l.gif", "mamachst.gif", "mamaface.gif",
|
||||
"mamamap.gif", "mech.gif", "medic01.gif", "mitesx.gif", "mustache.gif", "nickchst.gif", "nickface.gif",
|
||||
"nickmap.gif", "nopizza.gif", "norachst.gif", "noraface.gif", "noramap.gif", "nwcurve.gif", "octan01.gif",
|
||||
"octsq01.gif", "o.gif", "papachst.gif", "papaface.gif", "papamap.gif", "pebblesx.gif", "pepperha.gif",
|
||||
"peppizza.gif", "peppmap.gif", "peprchst.gif", "peprface.gif", "pianokys.gif", "pizcurve.gif", "pizza01.gif",
|
||||
"pizza.gif", "polbar01.gif", "polbla01.gif", "polkadot.gif", "polwhi01.gif", "postchst.gif", "post.gif",
|
||||
"rac1chst.gif", "rac2chst.gif", "radar.gif", "raddis01.gif", "rcback.gif", "rc-butn.gif", "rcfrnt5.gif",
|
||||
"rcfrnt6.gif", "rcfrnt7.gif", "rcfrnt.gif", "rcside1.gif", "rcside2.gif", "rcside3.gif", "rctail.gif",
|
||||
"redskul.gif", "relrel01.gif", "road1way.gif", "road3wa2.gif", "road3wa3.gif", "road3way.gif", "road4way.gif",
|
||||
"roadstr8.gif", "rockx.gif", "roofpiz.gif", "sandredx.gif", "se_curve.gif", "shftchst.gif", "shftface2.gif",
|
||||
"shftface.gif", "shldwn02.gif", "skull.gif", "smile.gif", "smileshd.gif", "supr2_01.gif", "tightcrv.gif",
|
||||
"unkchst.gif", "val_02.gif", "vest.gif", "water2x.gif", "w_curve.gif", "wnbars.gif", "woman.gif",
|
||||
"womanshd.gif"
|
||||
};
|
||||
|
||||
BIN
ISLE/res/arrow.png
Normal file
BIN
ISLE/res/arrow.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 165 B |
37
ISLE/res/arrow_bmp.h
Normal file
37
ISLE/res/arrow_bmp.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
// Generated from ISLE/res/arrow.png
|
||||
// Dimensions: 32x32
|
||||
// This file is auto-generated, do not edit it.
|
||||
|
||||
#include "cursor.h"
|
||||
|
||||
static const unsigned char arrow_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00,
|
||||
0x48, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x42, 0x00, 0x00, 0x00,
|
||||
0x41, 0x00, 0x00, 0x00, 0x40, 0x80, 0x00, 0x00, 0x40, 0x40, 0x00, 0x00,
|
||||
0x40, 0x20, 0x00, 0x00, 0x41, 0xF0, 0x00, 0x00, 0x49, 0x00, 0x00, 0x00,
|
||||
0x54, 0x80, 0x00, 0x00, 0x64, 0x80, 0x00, 0x00, 0x42, 0x40, 0x00, 0x00,
|
||||
0x02, 0x40, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00,
|
||||
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char arrow_mask[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x60, 0x00, 0x00, 0x00, 0x70, 0x00, 0x00, 0x00,
|
||||
0x78, 0x00, 0x00, 0x00, 0x7C, 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00,
|
||||
0x7F, 0x00, 0x00, 0x00, 0x7F, 0x80, 0x00, 0x00, 0x7F, 0xC0, 0x00, 0x00,
|
||||
0x7F, 0xE0, 0x00, 0x00, 0x7F, 0xF0, 0x00, 0x00, 0x7F, 0x00, 0x00, 0x00,
|
||||
0x77, 0x80, 0x00, 0x00, 0x67, 0x80, 0x00, 0x00, 0x43, 0xC0, 0x00, 0x00,
|
||||
0x03, 0xC0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00, 0x01, 0xE0, 0x00, 0x00,
|
||||
0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const CursorBitmap arrow_cursor = { 32, 32, arrow_data, arrow_mask };
|
||||
BIN
ISLE/res/busy.png
Normal file
BIN
ISLE/res/busy.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 173 B |
37
ISLE/res/busy_bmp.h
Normal file
37
ISLE/res/busy_bmp.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
// Generated from ISLE/res/busy.png
|
||||
// Dimensions: 32x32
|
||||
// This file is auto-generated, do not edit it.
|
||||
|
||||
#include "cursor.h"
|
||||
|
||||
static const unsigned char busy_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||
0x00, 0x40, 0x01, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x20, 0x02, 0x00,
|
||||
0x00, 0x20, 0x02, 0x00, 0x00, 0x20, 0x02, 0x00, 0x00, 0x22, 0xA2, 0x00,
|
||||
0x00, 0x11, 0x44, 0x00, 0x00, 0x08, 0x88, 0x00, 0x00, 0x04, 0x10, 0x00,
|
||||
0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00, 0x00, 0x02, 0x20, 0x00,
|
||||
0x00, 0x02, 0x20, 0x00, 0x00, 0x04, 0x10, 0x00, 0x00, 0x08, 0x88, 0x00,
|
||||
0x00, 0x10, 0x04, 0x00, 0x00, 0x20, 0x82, 0x00, 0x00, 0x21, 0x42, 0x00,
|
||||
0x00, 0x22, 0xA2, 0x00, 0x00, 0x25, 0x52, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||
0x00, 0x40, 0x01, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char busy_mask[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||
0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||
0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||
0x00, 0x1F, 0xFC, 0x00, 0x00, 0x0F, 0xF8, 0x00, 0x00, 0x07, 0xF0, 0x00,
|
||||
0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xE0, 0x00, 0x00, 0x03, 0xE0, 0x00,
|
||||
0x00, 0x03, 0xE0, 0x00, 0x00, 0x07, 0xF0, 0x00, 0x00, 0x0F, 0xF8, 0x00,
|
||||
0x00, 0x1F, 0xFC, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00,
|
||||
0x00, 0x3F, 0xFE, 0x00, 0x00, 0x3F, 0xFE, 0x00, 0x00, 0x7F, 0xFF, 0x00,
|
||||
0x00, 0x7F, 0xFF, 0x00, 0x00, 0x7F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const CursorBitmap busy_cursor = { 32, 32, busy_data, busy_mask };
|
||||
BIN
ISLE/res/no.png
Normal file
BIN
ISLE/res/no.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 191 B |
37
ISLE/res/no_bmp.h
Normal file
37
ISLE/res/no_bmp.h
Normal file
@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
// Generated from ISLE/res/no.png
|
||||
// Dimensions: 32x32
|
||||
// This file is auto-generated, do not edit it.
|
||||
|
||||
#include "cursor.h"
|
||||
|
||||
static const unsigned char no_data[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0x00,
|
||||
0x00, 0x3C, 0x3C, 0x00, 0x00, 0x70, 0x0E, 0x00, 0x00, 0xF8, 0x07, 0x00,
|
||||
0x00, 0xDC, 0x03, 0x00, 0x01, 0xCE, 0x03, 0x80, 0x01, 0x87, 0x01, 0x80,
|
||||
0x01, 0x83, 0x81, 0x80, 0x01, 0x81, 0xC1, 0x80, 0x01, 0x80, 0xE1, 0x80,
|
||||
0x01, 0xC0, 0x73, 0x80, 0x00, 0xC0, 0x3B, 0x00, 0x00, 0xE0, 0x1F, 0x00,
|
||||
0x00, 0x70, 0x0E, 0x00, 0x00, 0x3C, 0x1C, 0x00, 0x00, 0x1F, 0xF8, 0x00,
|
||||
0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const unsigned char no_mask[] = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x07, 0xE0, 0x00, 0x00, 0x1F, 0xF8, 0x00, 0x00, 0x3F, 0xFC, 0x00,
|
||||
0x00, 0x7F, 0xFE, 0x00, 0x00, 0xFC, 0x3F, 0x00, 0x01, 0xFC, 0x0F, 0x80,
|
||||
0x01, 0xFE, 0x07, 0x80, 0x03, 0xFF, 0x07, 0xC0, 0x03, 0xCF, 0x83, 0xC0,
|
||||
0x03, 0xC7, 0xC3, 0xC0, 0x03, 0xC3, 0xE3, 0xC0, 0x03, 0xC1, 0xF3, 0xC0,
|
||||
0x03, 0xE0, 0xFF, 0xC0, 0x01, 0xE0, 0x7F, 0x80, 0x01, 0xF0, 0x3F, 0x80,
|
||||
0x00, 0xFC, 0x1F, 0x00, 0x00, 0x7F, 0xFE, 0x00, 0x00, 0x3F, 0xFC, 0x00,
|
||||
0x00, 0x1F, 0xF8, 0x00, 0x00, 0x07, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
};
|
||||
|
||||
static const CursorBitmap no_cursor = { 32, 32, no_data, no_mask };
|
||||
18
ISLE/xbox_one_series/config.cpp
Normal file
18
ISLE/xbox_one_series/config.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "config.h"
|
||||
|
||||
#include <SDL3/SDL_log.h>
|
||||
#include <iniparser.h>
|
||||
|
||||
void XBONE_SetupDefaultConfigOverrides(dictionary* p_dictionary)
|
||||
{
|
||||
SDL_Log("Overriding default config for Xbox One/Series");
|
||||
|
||||
// Use DevelopmentFiles path for disk and cd paths
|
||||
// It's good to use that path since user can easily
|
||||
// connect through SMB and copy the files
|
||||
iniparser_set(p_dictionary, "isle:diskpath", "D:\\DevelopmentFiles\\isle\\");
|
||||
iniparser_set(p_dictionary, "isle:cdpath", "D:\\DevelopmentFiles\\isle\\");
|
||||
|
||||
// Enable cursor by default
|
||||
iniparser_set(p_dictionary, "isle:Draw Cursor", "true");
|
||||
}
|
||||
8
ISLE/xbox_one_series/config.h
Normal file
8
ISLE/xbox_one_series/config.h
Normal file
@ -0,0 +1,8 @@
|
||||
#ifndef XBOX_ONE_SERIES_CONFIG_H
|
||||
#define XBOX_ONE_SERIES_CONFIG_H
|
||||
|
||||
#include "dictionary.h"
|
||||
|
||||
void XBONE_SetupDefaultConfigOverrides(dictionary* p_dictionary);
|
||||
|
||||
#endif // XBOX_ONE_SERIES_CONFIG_H
|
||||
8
LEGO1/cursor.h
Normal file
8
LEGO1/cursor.h
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct CursorBitmap {
|
||||
int width;
|
||||
int height;
|
||||
const unsigned char* data;
|
||||
const unsigned char* mask;
|
||||
} CursorBitmap;
|
||||
@ -20,12 +20,12 @@ class MxQuaternionTransformer;
|
||||
struct Act3ListElement {
|
||||
MxU32 m_objectId; // 0x00
|
||||
undefined4 m_unk0x04; // 0x04
|
||||
undefined m_unk0x08; // 0x08
|
||||
MxBool m_hasStarted; // 0x08
|
||||
|
||||
Act3ListElement() {}
|
||||
|
||||
Act3ListElement(MxU32 p_objectId, undefined4 p_unk0x04, undefined p_unk0x08)
|
||||
: m_objectId(p_objectId), m_unk0x04(p_unk0x04), m_unk0x08(p_unk0x08)
|
||||
Act3ListElement(MxU32 p_objectId, undefined4 p_unk0x04, MxBool p_hasStarted)
|
||||
: m_objectId(p_objectId), m_unk0x04(p_unk0x04), m_hasStarted(p_hasStarted)
|
||||
{
|
||||
}
|
||||
|
||||
@ -36,12 +36,18 @@ struct Act3ListElement {
|
||||
// SIZE 0x10
|
||||
class Act3List : private list<Act3ListElement> {
|
||||
public:
|
||||
enum InsertMode {
|
||||
e_replaceAction = 1,
|
||||
e_queueAction = 2,
|
||||
e_onlyIfEmpty = 3
|
||||
};
|
||||
|
||||
Act3List() { m_unk0x0c = 0; }
|
||||
|
||||
void Insert(MxS32 p_objectId, MxS32 p_option);
|
||||
void FUN_10071fa0();
|
||||
void Insert(MxS32 p_objectId, InsertMode p_option);
|
||||
void DeleteActionWrapper();
|
||||
void Clear();
|
||||
void FUN_100720d0(MxU32 p_objectId);
|
||||
void RemoveByObjectIdOrFirst(MxU32 p_objectId);
|
||||
|
||||
private:
|
||||
undefined4 m_unk0x0c; // 0x0c
|
||||
@ -129,7 +135,7 @@ class Act3 : public LegoWorld {
|
||||
void RemoveDonut(Act3Ammo& p_p);
|
||||
MxResult ShootPizza(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
|
||||
MxResult ShootDonut(LegoPathController* p_controller, Vector3& p_location, Vector3& p_direction, Vector3& p_up);
|
||||
void FUN_10072ad0(undefined4 p_param1);
|
||||
void TriggerHitSound(undefined4 p_param1);
|
||||
MxResult FUN_10073360(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
MxResult FUN_10073390(Act3Ammo& p_ammo, const Vector3& p_param2);
|
||||
void SetBrickster(Act3Brickster* p_brickster);
|
||||
@ -168,12 +174,12 @@ class Act3 : public LegoWorld {
|
||||
Helicopter* m_copter; // 0x420c
|
||||
Act3Shark* m_shark; // 0x4210
|
||||
MxFloat m_time; // 0x4214
|
||||
MxU8 m_unk0x4218; // 0x4218
|
||||
MxU8 m_unk0x4219; // 0x4219
|
||||
MxU8 m_unk0x421a; // 0x421a
|
||||
MxU8 m_unk0x421b; // 0x421b
|
||||
MxU8 m_unk0x421c; // 0x421c
|
||||
MxU8 m_unk0x421d; // 0x421d
|
||||
MxU8 m_pizzaHitSound; // 0x4218
|
||||
MxU8 m_pizzaMissSound; // 0x4219
|
||||
MxU8 m_copDonutSound; // 0x421a
|
||||
MxU8 m_donutMissSound; // 0x421b
|
||||
MxU8 m_islanderSound; // 0x421c
|
||||
MxU8 m_bricksterDonutSound; // 0x421d
|
||||
undefined m_unk0x421e; // 0x421e
|
||||
Act3List m_unk0x4220; // 0x4220
|
||||
MxPresenter* m_helicopterDots[15]; // 0x4230
|
||||
|
||||
@ -90,7 +90,7 @@ class Act3Ammo : public LegoPathActor {
|
||||
// Act3Ammo::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
MxResult FUN_10053db0(float p_param1, const Matrix4& p_param2);
|
||||
MxResult FUN_10053db0(float p_param1, Matrix4& p_param2);
|
||||
|
||||
static Mx3DPointFloat g_unk0x10104f08;
|
||||
|
||||
|
||||
@ -11,6 +11,12 @@ class MxEndActionNotificationParam;
|
||||
// SIZE 0x24
|
||||
class AmbulanceMissionState : public LegoState {
|
||||
public:
|
||||
enum {
|
||||
e_ready = 0,
|
||||
e_enteredAmbulance = 1,
|
||||
e_prepareAmbulance = 2,
|
||||
};
|
||||
|
||||
AmbulanceMissionState();
|
||||
|
||||
// FUNCTION: LEGO1 0x10037440
|
||||
@ -125,18 +131,18 @@ class AmbulanceMissionState : public LegoState {
|
||||
// SYNTHETIC: LEGO1 0x100376c0
|
||||
// AmbulanceMissionState::`scalar deleting destructor'
|
||||
|
||||
undefined4 m_unk0x08; // 0x08
|
||||
MxLong m_startTime; // 0x0c
|
||||
MxS16 m_peScore; // 0x10
|
||||
MxS16 m_maScore; // 0x12
|
||||
MxS16 m_paScore; // 0x14
|
||||
MxS16 m_niScore; // 0x16
|
||||
MxS16 m_laScore; // 0x18
|
||||
MxS16 m_peHighScore; // 0x1a
|
||||
MxS16 m_maHighScore; // 0x1c
|
||||
MxS16 m_paHighScore; // 0x1e
|
||||
MxS16 m_niHighScore; // 0x20
|
||||
MxS16 m_laHighScore; // 0x22
|
||||
MxU32 m_state; // 0x08
|
||||
MxLong m_startTime; // 0x0c
|
||||
MxS16 m_peScore; // 0x10
|
||||
MxS16 m_maScore; // 0x12
|
||||
MxS16 m_paScore; // 0x14
|
||||
MxS16 m_niScore; // 0x16
|
||||
MxS16 m_laScore; // 0x18
|
||||
MxS16 m_peHighScore; // 0x1a
|
||||
MxS16 m_maHighScore; // 0x1c
|
||||
MxS16 m_paHighScore; // 0x1e
|
||||
MxS16 m_niHighScore; // 0x20
|
||||
MxS16 m_laHighScore; // 0x22
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d71a8
|
||||
@ -177,15 +183,21 @@ class Ambulance : public IslePathActor {
|
||||
virtual MxLong HandleEndAction(MxEndActionNotificationParam& p_param); // vtable+0xf4
|
||||
|
||||
void CreateState();
|
||||
void FUN_10036e60();
|
||||
void Init();
|
||||
void ActivateSceneActions();
|
||||
void StopActions();
|
||||
void FUN_10037250();
|
||||
void Reset();
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10036130
|
||||
// Ambulance::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
enum {
|
||||
e_none = 0,
|
||||
e_waiting = 1,
|
||||
e_finished = 3,
|
||||
};
|
||||
|
||||
void PlayAnimation(IsleScript::Script p_objectId);
|
||||
void PlayFinalAnimation(IsleScript::Script p_objectId);
|
||||
void StopAction(IsleScript::Script p_objectId);
|
||||
@ -196,10 +208,10 @@ class Ambulance : public IslePathActor {
|
||||
AmbulanceMissionState* m_state; // 0x164
|
||||
MxS16 m_unk0x168; // 0x168
|
||||
MxS16 m_actorId; // 0x16a
|
||||
MxS16 m_unk0x16c; // 0x16c
|
||||
MxS16 m_unk0x16e; // 0x16e
|
||||
MxS16 m_unk0x170; // 0x170
|
||||
MxS16 m_unk0x172; // 0x172
|
||||
MxS16 m_atPoliceTask; // 0x16c
|
||||
MxS16 m_atBeachTask; // 0x16e
|
||||
MxS16 m_taskState; // 0x170
|
||||
MxS16 m_enableRandomAudio; // 0x172
|
||||
IsleScript::Script m_lastAction; // 0x174
|
||||
IsleScript::Script m_lastAnimation; // 0x178
|
||||
MxFloat m_fuel; // 0x17c
|
||||
|
||||
@ -52,13 +52,13 @@ class CarRace : public LegoRace {
|
||||
return !strcmp(p_name, CarRace::ClassName()) || LegoRace::IsA(p_name);
|
||||
}
|
||||
|
||||
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
|
||||
void ReadyWorld() override; // vtable+0x50
|
||||
MxBool Escape() override; // vtable+0x64
|
||||
MxLong HandleClick(LegoEventNotificationParam&) override; // vtable+0x6c
|
||||
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
|
||||
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
|
||||
MxLong HandleType0Notification(MxNotificationParam&) override; // vtable+0x78
|
||||
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
|
||||
void ReadyWorld() override; // vtable+0x50
|
||||
MxBool Escape() override; // vtable+0x64
|
||||
MxLong HandleControl(LegoControlManagerNotificationParam&) override; // vtable+0x6c
|
||||
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
|
||||
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
|
||||
MxLong HandleType0Notification(MxNotificationParam&) override; // vtable+0x78
|
||||
|
||||
// FUNCTION: BETA10 0x100cd060
|
||||
RaceSkel* GetSkeleton() { return m_skeleton; }
|
||||
|
||||
@ -123,7 +123,7 @@ class Hospital : public LegoWorld {
|
||||
MxLong m_copLedAnimTimer; // 0x11c
|
||||
MxLong m_pizzaLedAnimTimer; // 0x120
|
||||
MxLong m_time; // 0x124
|
||||
undefined m_unk0x128; // 0x128
|
||||
MxBool m_exited; // 0x128
|
||||
};
|
||||
|
||||
#endif // HOSPITAL_H
|
||||
|
||||
@ -78,10 +78,20 @@ class InfocenterState : public LegoState {
|
||||
|
||||
// SIZE 0x18
|
||||
struct InfocenterMapEntry {
|
||||
enum {
|
||||
e_infocenter = 3,
|
||||
e_jetrace = 10,
|
||||
e_carrace = 11,
|
||||
e_pizzeria = 12,
|
||||
e_garage = 13,
|
||||
e_hospital = 14,
|
||||
e_police = 15,
|
||||
};
|
||||
|
||||
InfocenterMapEntry();
|
||||
|
||||
MxStillPresenter* m_destCtl; // 0x00
|
||||
undefined4 m_unk0x04; // 0x04
|
||||
MxU32 m_target; // 0x04
|
||||
MxRect<MxS32> m_area; // 0x08
|
||||
};
|
||||
|
||||
@ -154,7 +164,7 @@ class Infocenter : public LegoWorld {
|
||||
void PlayCutscene(Cutscene p_entityId, MxBool p_scale);
|
||||
void StopCutscene();
|
||||
|
||||
void FUN_10070d10(MxS32 p_x, MxS32 p_y);
|
||||
void UpdateEnabledGlowControl(MxS32 p_x, MxS32 p_y);
|
||||
|
||||
void StartCredits();
|
||||
void StopCredits();
|
||||
@ -173,12 +183,12 @@ class Infocenter : public LegoWorld {
|
||||
Radio m_radio; // 0x10c
|
||||
MxStillPresenter* m_dragPresenter; // 0x11c
|
||||
InfocenterMapEntry m_glowInfo[7]; // 0x120
|
||||
MxS16 m_unk0x1c8; // 0x1c8
|
||||
MxS16 m_enabledGlowControl; // 0x1c8
|
||||
MxStillPresenter* m_frame; // 0x1cc
|
||||
MxS16 m_infoManDialogueTimer; // 0x1d0
|
||||
MxS16 m_bookAnimationTimer; // 0x1d2
|
||||
MxU16 m_unk0x1d4; // 0x1d4
|
||||
MxS16 m_unk0x1d6; // 0x1d6
|
||||
MxU16 m_playingMovieCounter; // 0x1d4
|
||||
MxS16 m_bigInfoBlinkTimer; // 0x1d6
|
||||
};
|
||||
|
||||
#endif // INFOCENTER_H
|
||||
|
||||
@ -34,6 +34,21 @@ class Act1State : public LegoState {
|
||||
c_floor3
|
||||
};
|
||||
|
||||
enum {
|
||||
e_none = 0,
|
||||
e_initial = 1,
|
||||
e_elevator = 2,
|
||||
e_pizza = 3,
|
||||
e_helicopter = 4,
|
||||
e_transitionToJetski = 5,
|
||||
e_transitionToRacecar = 6,
|
||||
e_transitionToTowtrack = 7,
|
||||
e_towtrack = 8,
|
||||
e_transitionToAmbulance = 9,
|
||||
e_ambulance = 10,
|
||||
e_jukebox = 11,
|
||||
};
|
||||
|
||||
Act1State();
|
||||
|
||||
// FUNCTION: LEGO1 0x100338a0
|
||||
@ -58,11 +73,11 @@ class Act1State : public LegoState {
|
||||
void RemoveActors();
|
||||
void PlaceActors();
|
||||
|
||||
MxU32 GetUnknown18() { return m_unk0x018; }
|
||||
MxU32 GetState() { return m_state; }
|
||||
ElevatorFloor GetElevatorFloor() { return (ElevatorFloor) m_elevFloor; }
|
||||
MxU8 GetUnknown21() { return m_unk0x021; }
|
||||
|
||||
void SetUnknown18(MxU32 p_unk0x18) { m_unk0x018 = p_unk0x18; }
|
||||
void SetState(MxU32 p_state) { m_state = p_state; }
|
||||
void SetElevatorFloor(ElevatorFloor p_elevFloor) { m_elevFloor = p_elevFloor; }
|
||||
void SetUnknown21(MxU8 p_unk0x21) { m_unk0x021 = p_unk0x21; }
|
||||
|
||||
@ -73,7 +88,7 @@ class Act1State : public LegoState {
|
||||
|
||||
Playlist m_cptClickDialogue; // 0x008
|
||||
IsleScript::Script m_currentCptClickDialogue; // 0x014
|
||||
MxU32 m_unk0x018; // 0x018
|
||||
MxU32 m_state; // 0x018
|
||||
MxS16 m_elevFloor; // 0x01c
|
||||
MxBool m_unk0x01e; // 0x01e
|
||||
MxBool m_unk0x01f; // 0x01f
|
||||
|
||||
@ -29,12 +29,12 @@ class JetskiRace : public LegoRace {
|
||||
return !strcmp(p_name, JetskiRace::ClassName()) || LegoRace::IsA(p_name);
|
||||
}
|
||||
|
||||
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
|
||||
void ReadyWorld() override; // vtable+0x50
|
||||
MxBool Escape() override; // vtable+0x64
|
||||
MxLong HandleClick(LegoEventNotificationParam&) override; // vtable+0x6c
|
||||
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
|
||||
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
|
||||
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
|
||||
void ReadyWorld() override; // vtable+0x50
|
||||
MxBool Escape() override; // vtable+0x64
|
||||
MxLong HandleControl(LegoControlManagerNotificationParam&) override; // vtable+0x6c
|
||||
MxLong HandlePathStruct(LegoPathStructNotificationParam&) override; // vtable+0x70
|
||||
MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74
|
||||
|
||||
void FUN_10016930(MxS32 p_param1, MxS16 p_param2);
|
||||
|
||||
|
||||
@ -304,4 +304,7 @@ class LegoAnimationManager : public MxCore {
|
||||
// TEMPLATE: LEGO1 0x10061750
|
||||
// MxListCursor<LegoTranInfo *>::MxListCursor<LegoTranInfo *>
|
||||
|
||||
// TEMPLATE: BETA10 0x1004b5d0
|
||||
// MxListCursor<LegoTranInfo *>::Next
|
||||
|
||||
#endif // LEGOANIMATIONMANAGER_H
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define LEGOANIMPRESENTER_H
|
||||
|
||||
#include "legoroilist.h"
|
||||
#include "legoroimaplist.h"
|
||||
#include "mxatom.h"
|
||||
#include "mxvideopresenter.h"
|
||||
|
||||
@ -92,7 +93,11 @@ class LegoAnimPresenter : public MxVideoPresenter {
|
||||
const char* GetActionObjectName();
|
||||
|
||||
void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; }
|
||||
|
||||
// FUNCTION: BETA10 0x1005aad0
|
||||
void SetUnknown0x0cTo1() { m_unk0x9c = 1; }
|
||||
|
||||
// FUNCTION: BETA10 0x1005ab00
|
||||
void SetUnknown0xa0(Matrix4* p_unk0xa0) { m_unk0xa0 = p_unk0xa0; }
|
||||
|
||||
LegoAnim* GetAnimation() { return m_anim; }
|
||||
@ -121,7 +126,7 @@ class LegoAnimPresenter : public MxVideoPresenter {
|
||||
void SubstituteVariables();
|
||||
void FUN_1006b900(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
|
||||
void FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p_matrix);
|
||||
void FUN_1006c8a0(MxBool p_bool);
|
||||
void SetDisabled(MxBool p_disabled);
|
||||
|
||||
LegoAnim* m_anim; // 0x64
|
||||
LegoROI** m_roiMap; // 0x68
|
||||
@ -143,14 +148,191 @@ class LegoAnimPresenter : public MxVideoPresenter {
|
||||
MxS16 m_unk0x9c; // 0x9c
|
||||
Matrix4* m_unk0xa0; // 0xa0
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10068650
|
||||
// LegoAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
public:
|
||||
float m_unk0xa4; // 0xa4
|
||||
Mx3DPointFloat m_unk0xa8; // 0xa8
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d4900
|
||||
// SIZE 0xc0
|
||||
class LegoLoopingAnimPresenter : public LegoAnimPresenter {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x1005c6f0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f0700
|
||||
return "LegoLoopingAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1000c9a0
|
||||
// FUNCTION: BETA10 0x1005c6c0
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1000c9b0
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void StreamingTickle() override; // vtable+0x20
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1006d000
|
||||
// LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1000f440
|
||||
// LegoLoopingAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
undefined4 m_unk0xbc; // 0xbc
|
||||
};
|
||||
|
||||
class LegoAnimActor;
|
||||
|
||||
// VTABLE: LEGO1 0x100d9170
|
||||
// SIZE 0xd8
|
||||
class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
|
||||
public:
|
||||
LegoLocomotionAnimPresenter();
|
||||
~LegoLocomotionAnimPresenter() override;
|
||||
|
||||
// FUNCTION: BETA10 0x1005c4e0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f06e4
|
||||
return "LegoLocomotionAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006ce50
|
||||
// FUNCTION: BETA10 0x1005c4b0
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006ce60
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void ReadyTickle() override; // vtable+0x18
|
||||
void StartingTickle() override; // vtable+0x1c
|
||||
void StreamingTickle() override; // vtable+0x20
|
||||
MxResult AddToManager() override; // vtable+0x34
|
||||
void Destroy() override; // vtable+0x38
|
||||
void EndAction() override; // vtable+0x40
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88
|
||||
|
||||
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
|
||||
|
||||
void DecrementUnknown0xd4()
|
||||
{
|
||||
if (m_unk0xd4) {
|
||||
--m_unk0xd4;
|
||||
}
|
||||
}
|
||||
|
||||
undefined2 GetUnknown0xd4() { return m_unk0xd4; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1006cfe0
|
||||
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
|
||||
undefined4 m_unk0xc0; // 0xc0
|
||||
undefined4* m_unk0xc4; // 0xc4
|
||||
LegoROIMapList* m_roiMapList; // 0xc8
|
||||
MxS32 m_unk0xcc; // 0xcc
|
||||
MxS32 m_unk0xd0; // 0xd0
|
||||
undefined2 m_unk0xd4; // 0xd4
|
||||
};
|
||||
|
||||
class LegoPathBoundary;
|
||||
|
||||
struct LegoHideAnimStructComparator {
|
||||
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
|
||||
};
|
||||
|
||||
// SIZE 0x08
|
||||
struct LegoHideAnimStruct {
|
||||
LegoPathBoundary* m_boundary; // 0x00
|
||||
MxU32 m_index; // 0x04
|
||||
};
|
||||
|
||||
typedef map<const char*, LegoHideAnimStruct, LegoHideAnimStructComparator> LegoHideAnimStructMap;
|
||||
|
||||
// VTABLE: LEGO1 0x100d9278
|
||||
// SIZE 0xc4
|
||||
class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
|
||||
public:
|
||||
LegoHideAnimPresenter();
|
||||
~LegoHideAnimPresenter() override;
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d860
|
||||
void VTable0x8c() override {} // vtable+0x8c
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d870
|
||||
void VTable0x90() override {} // vtable+0x90
|
||||
|
||||
// FUNCTION: BETA10 0x1005d4a0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f06cc
|
||||
return "LegoHideAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d880
|
||||
// FUNCTION: BETA10 0x1005d470
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d890
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void ReadyTickle() override; // vtable+0x18
|
||||
void StartingTickle() override; // vtable+0x18
|
||||
MxResult AddToManager() override; // vtable+0x34
|
||||
void Destroy() override; // vtable+0x38
|
||||
void EndAction() override; // vtable+0x40
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
|
||||
void FUN_1006db40(LegoTime p_time);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1006d9d0
|
||||
// LegoHideAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time);
|
||||
void FUN_1006dc10();
|
||||
void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node);
|
||||
void FUN_1006e470(
|
||||
LegoHideAnimStructMap& p_map,
|
||||
LegoAnimNodeData* p_data,
|
||||
const char* p_name,
|
||||
LegoPathBoundary* p_boundary
|
||||
);
|
||||
|
||||
LegoPathBoundary** m_boundaryMap; // 0xc0
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
// SYNTHETIC: LEGO1 0x10068650
|
||||
// LegoAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
// TEMPLATE: LEGO1 0x100689c0
|
||||
// map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >::~map<char const *,char const *,LegoAnimSubstComparator,allocator<char const *> >
|
||||
@ -208,6 +390,33 @@ class LegoAnimPresenter : public MxVideoPresenter {
|
||||
|
||||
// GLOBAL: LEGO1 0x100f7688
|
||||
// _Tree<char const *,pair<char const * const,LegoAnimStruct>,map<char const *,LegoAnimStruct,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Kfn,LegoAnimStructComparator,allocator<LegoAnimStruct> >::_Nil
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006ddb0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~_Tree<char const *,pair<ch
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006de80
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Inc
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006dec0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::erase
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e310
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Erase
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e350
|
||||
// Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>::~Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e3a0
|
||||
// map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e6d0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Dec
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e720
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Insert
|
||||
|
||||
// GLOBAL: LEGO1 0x100f768c
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Nil
|
||||
// clang-format on
|
||||
|
||||
#endif // LEGOANIMPRESENTER_H
|
||||
|
||||
@ -79,7 +79,7 @@ class LegoBuildingManager : public MxCore {
|
||||
MxBool SwitchMove(LegoEntity* p_entity);
|
||||
MxBool SwitchMood(LegoEntity* p_entity);
|
||||
MxU32 GetAnimationId(LegoEntity* p_entity);
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state);
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_basedOnMood);
|
||||
MxBool DecrementCounter(LegoEntity* p_entity);
|
||||
MxBool DecrementCounter(MxS32 p_index);
|
||||
MxBool DecrementCounter(LegoBuildingInfo* p_data);
|
||||
|
||||
@ -48,10 +48,13 @@ typedef set<LegoCacheSoundEntry, Set100d6b4cComparator> Set100d6b4c;
|
||||
typedef list<LegoCacheSoundEntry> List100d6b4c;
|
||||
|
||||
// VTABLE: LEGO1 0x100d6b4c
|
||||
// VTABLE: BETA10 0x101becac
|
||||
// SIZE 0x20
|
||||
class LegoCacheSoundManager {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x100d0a60
|
||||
LegoCacheSoundManager() {}
|
||||
|
||||
~LegoCacheSoundManager();
|
||||
|
||||
virtual MxResult Tickle(); // vtable+0x00
|
||||
@ -68,6 +71,9 @@ class LegoCacheSoundManager {
|
||||
List100d6b4c m_list; // 0x14
|
||||
};
|
||||
|
||||
// SYNTHETIC: BETA10 0x100d06b0
|
||||
// LegoCacheSoundManager::`scalar deleting destructor'
|
||||
|
||||
// TODO: Function names subject to change.
|
||||
|
||||
// clang-format off
|
||||
|
||||
@ -38,17 +38,17 @@ class LegoCameraController : public LegoPointOfViewController {
|
||||
virtual MxResult Create(); // vtable+0x44
|
||||
|
||||
void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up);
|
||||
void FUN_10012290(float p_angle);
|
||||
void FUN_10012320(float p_angle);
|
||||
MxResult FUN_100123b0(Matrix4& p_matrix);
|
||||
void FUN_100123e0(const Matrix4& p_transform, MxU32 p_und);
|
||||
void RotateZ(float p_angle);
|
||||
void RotateY(float p_angle);
|
||||
MxResult GetPointOfView(Matrix4& p_matrix);
|
||||
void TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply);
|
||||
Mx3DPointFloat GetWorldUp();
|
||||
Mx3DPointFloat GetWorldLocation();
|
||||
Mx3DPointFloat GetWorldDirection();
|
||||
|
||||
private:
|
||||
MxMatrix m_matrix1; // 0x38
|
||||
MxMatrix m_matrix2; // 0x80
|
||||
MxMatrix m_currentTransform; // 0x38
|
||||
MxMatrix m_originalTransform; // 0x80
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10011f50
|
||||
|
||||
@ -137,11 +137,11 @@ class LegoCarBuild : public LegoWorld {
|
||||
void FUN_10022f00();
|
||||
void FUN_10022f30();
|
||||
void FUN_10023130(MxLong p_x, MxLong p_y);
|
||||
void FUN_100236d0();
|
||||
void AddSelectedPartToBuild();
|
||||
undefined4 FUN_10024250(LegoEventNotificationParam* p_param);
|
||||
void FUN_100243a0();
|
||||
undefined4 FUN_10024480(MxActionNotificationParam* p_param);
|
||||
undefined4 FUN_100244e0(MxLong p_x, MxLong p_y);
|
||||
undefined4 SelectPartFromMousePosition(MxLong p_x, MxLong p_y);
|
||||
undefined4 FUN_100246e0(MxLong p_x, MxLong p_y);
|
||||
MxS32 FUN_10024850(MxLong p_x, MxLong p_y);
|
||||
undefined4 FUN_10024890(MxParam* p_param);
|
||||
@ -184,7 +184,7 @@ class LegoCarBuild : public LegoWorld {
|
||||
MxU8 m_unk0x109; // 0x109
|
||||
MxU16 m_unk0x10a; // 0x10a
|
||||
Uint64 m_unk0x10c; // 0x10c
|
||||
LegoROI* m_unk0x110; // 0x110
|
||||
LegoROI* m_selectedPart; // 0x110
|
||||
BoundingSphere m_unk0x114; // 0x114
|
||||
MxMatrix m_unk0x12c; // 0x12c
|
||||
undefined m_unk0x174; // 0x174
|
||||
@ -202,10 +202,10 @@ class LegoCarBuild : public LegoWorld {
|
||||
MxS32 m_unk0x290[2]; // 0x290
|
||||
MxS32 m_unk0x298[2]; // 0x298
|
||||
|
||||
MxFloat m_unk0x2a0; // 0x2a0
|
||||
Mx4DPointFloat m_unk0x2a4; // 0x2a4
|
||||
Mx4DPointFloat m_unk0x2bc; // 0x2bc
|
||||
MxBool m_unk0x2d4; // 0x2d4
|
||||
MxFloat m_unk0x2a0; // 0x2a0
|
||||
Mx4DPointFloat m_unk0x2a4; // 0x2a4
|
||||
Mx4DPointFloat m_unk0x2bc; // 0x2bc
|
||||
MxBool m_selectedPartIsPlaced; // 0x2d4
|
||||
|
||||
// variable names verified by BETA10 0x1006b27a
|
||||
MxStillPresenter* m_ColorBook_Bitmap; // 0x2dc
|
||||
|
||||
@ -77,11 +77,11 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter {
|
||||
void FUN_10079050(MxS16 p_index);
|
||||
void SwapNodesByName(LegoChar* p_param1, LegoChar* p_param2);
|
||||
void InitBuildPlatform();
|
||||
void FUN_100795d0(LegoChar* p_param);
|
||||
void FUN_10079680(LegoChar* p_param);
|
||||
void HideBuildPartByName(LegoChar* p_param);
|
||||
void ShowBuildPartByName(LegoChar* p_param);
|
||||
LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
|
||||
LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name);
|
||||
void FUN_10079790(const LegoChar* p_name);
|
||||
void AddPartToBuildByName(const LegoChar* p_name);
|
||||
void RotateAroundYAxis(MxFloat p_angle);
|
||||
MxBool FUN_10079c30(const LegoChar* p_name);
|
||||
MxBool PartIsPlaced(const LegoChar* p_name);
|
||||
|
||||
@ -48,6 +48,7 @@ struct LegoActorInfo;
|
||||
typedef map<char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap;
|
||||
|
||||
// VTABLE: LEGO1 0x100da878
|
||||
// VTABLE: BETA10 0x101bc028
|
||||
// SIZE 0x24
|
||||
class CustomizeAnimFileVariable : public MxVariable {
|
||||
public:
|
||||
@ -88,7 +89,7 @@ class LegoCharacterManager {
|
||||
MxBool SwitchMove(LegoROI* p_roi);
|
||||
MxBool SwitchMood(LegoROI* p_roi);
|
||||
MxU32 GetAnimationId(LegoROI* p_roi);
|
||||
MxU32 GetSoundId(LegoROI* p_roi, MxBool p_und);
|
||||
MxU32 GetSoundId(LegoROI* p_roi, MxBool p_basedOnMood);
|
||||
MxU8 GetMood(LegoROI* p_roi);
|
||||
LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity);
|
||||
MxResult UpdateBoundingSphereAndBox(LegoROI* p_roi);
|
||||
|
||||
@ -24,11 +24,11 @@ class LegoControlManagerNotificationParam : public LegoEventNotificationParam {
|
||||
|
||||
void SetClickedObjectId(MxS32 p_clickedObjectId) { m_clickedObjectId = p_clickedObjectId; }
|
||||
void SetClickedAtom(const char* p_clickedAtom) { m_clickedAtom = p_clickedAtom; }
|
||||
void SetUnknown0x28(MxS16 p_unk0x28) { m_unk0x28 = p_unk0x28; }
|
||||
void SetEnabledChild(MxS16 p_enabledChild) { m_enabledChild = p_enabledChild; }
|
||||
|
||||
MxS32 m_clickedObjectId; // 0x20
|
||||
const char* m_clickedAtom; // 0x24
|
||||
MxS16 m_unk0x28; // 0x28
|
||||
MxS16 m_enabledChild; // 0x28
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10028bf0
|
||||
@ -66,27 +66,33 @@ class LegoControlManager : public MxCore {
|
||||
return !strcmp(p_name, LegoControlManager::ClassName()) || MxCore::IsA(p_name);
|
||||
}
|
||||
|
||||
void FUN_10028df0(MxPresenterList* p_presenterList);
|
||||
void SetPresenterList(MxPresenterList* p_presenterList);
|
||||
void Register(MxCore* p_listener);
|
||||
void Unregister(MxCore* p_listener);
|
||||
MxBool FUN_10029210(LegoEventNotificationParam& p_param, MxPresenter* p_presenter);
|
||||
void FUN_100293c0(MxU32 p_objectId, const char* p_atom, MxS16 p_unk0x4e);
|
||||
MxControlPresenter* FUN_100294e0(MxS32 p_x, MxS32 p_y);
|
||||
MxBool FUN_10029630();
|
||||
MxBool FUN_10029750();
|
||||
void FUN_100292e0();
|
||||
MxBool HandleButtonDown(LegoEventNotificationParam& p_param, MxPresenter* p_presenter);
|
||||
void UpdateEnabledChild(MxU32 p_objectId, const char* p_atom, MxS16 p_enabledChild);
|
||||
MxControlPresenter* GetControlAt(MxS32 p_x, MxS32 p_y);
|
||||
MxBool HandleButtonDown();
|
||||
MxBool HandleButtonUp();
|
||||
void Notify();
|
||||
|
||||
undefined4 GetUnknown0x0c() { return m_unk0x0c; }
|
||||
undefined GetUnknown0x10() { return m_unk0x10; }
|
||||
MxU32 HandleUpNextTickle() { return m_handleUpNextTickle; }
|
||||
MxBool IsSecondButtonDown() { return m_secondButtonDown; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10028d40
|
||||
// LegoControlManager::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
undefined4 m_unk0x08; // 0x08
|
||||
undefined4 m_unk0x0c; // 0x0c
|
||||
MxBool m_unk0x10; // 0x10
|
||||
MxPresenter* m_unk0x14; // 0x14
|
||||
enum {
|
||||
e_idle = 0,
|
||||
e_waitNextTickle = 1,
|
||||
e_tickled = 2,
|
||||
};
|
||||
|
||||
MxU32 m_buttonDownState; // 0x08
|
||||
MxU32 m_handleUpNextTickle; // 0x0c
|
||||
MxBool m_secondButtonDown; // 0x10
|
||||
MxPresenter* m_handledPresenter; // 0x14
|
||||
LegoControlManagerNotificationParam m_event; // 0x18
|
||||
MxPresenterList* m_presenterList; // 0x44
|
||||
LegoNotifyList m_notifyList; // 0x48
|
||||
|
||||
@ -28,7 +28,7 @@ class LegoEntity : public MxEntity {
|
||||
};
|
||||
|
||||
enum {
|
||||
c_altBit1 = 0x01
|
||||
c_disabled = 0x01
|
||||
};
|
||||
|
||||
LegoEntity() { Init(); }
|
||||
@ -68,13 +68,13 @@ class LegoEntity : public MxEntity {
|
||||
// FUNCTION: BETA10 0x10013260
|
||||
virtual void SetWorldSpeed(MxFloat p_worldSpeed) { m_worldSpeed = p_worldSpeed; } // vtable+0x30
|
||||
|
||||
virtual void ClickSound(MxBool p_und); // vtable+0x34
|
||||
virtual void ClickAnimation(); // vtable+0x38
|
||||
virtual void SwitchVariant(); // vtable+0x3c
|
||||
virtual void SwitchSound(); // vtable+0x40
|
||||
virtual void SwitchMove(); // vtable+0x44
|
||||
virtual void SwitchColor(LegoROI* p_roi); // vtable+0x48
|
||||
virtual void SwitchMood(); // vtable+0x4c
|
||||
virtual void ClickSound(MxBool p_basedOnMood); // vtable+0x34
|
||||
virtual void ClickAnimation(); // vtable+0x38
|
||||
virtual void SwitchVariant(); // vtable+0x3c
|
||||
virtual void SwitchSound(); // vtable+0x40
|
||||
virtual void SwitchMove(); // vtable+0x44
|
||||
virtual void SwitchColor(LegoROI* p_roi); // vtable+0x48
|
||||
virtual void SwitchMood(); // vtable+0x4c
|
||||
|
||||
void FUN_10010c30();
|
||||
void SetType(MxU8 p_type);
|
||||
@ -83,7 +83,7 @@ class LegoEntity : public MxEntity {
|
||||
Mx3DPointFloat GetWorldUp();
|
||||
Mx3DPointFloat GetWorldPosition();
|
||||
|
||||
MxBool GetUnknown0x10IsSet(MxU8 p_flag) { return m_unk0x10 & p_flag; }
|
||||
MxBool IsInteraction(MxU8 p_flag) { return m_interaction & p_flag; }
|
||||
MxBool GetFlagsIsSet(MxU8 p_flag) { return m_flags & p_flag; }
|
||||
MxU8 GetFlags() { return m_flags; }
|
||||
|
||||
@ -101,14 +101,14 @@ class LegoEntity : public MxEntity {
|
||||
void SetFlags(MxU8 p_flags) { m_flags = p_flags; }
|
||||
void SetFlag(MxU8 p_flag) { m_flags |= p_flag; }
|
||||
void ClearFlag(MxU8 p_flag) { m_flags &= ~p_flag; }
|
||||
void SetUnknown0x10Flag(MxU8 p_flag) { m_unk0x10 |= p_flag; }
|
||||
void ClearUnknown0x10Flag(MxU8 p_flag) { m_unk0x10 &= ~p_flag; }
|
||||
void SetInteractionFlag(MxU8 p_flag) { m_interaction |= p_flag; }
|
||||
void ClearInteractionFlag(MxU8 p_flag) { m_interaction &= ~p_flag; }
|
||||
|
||||
protected:
|
||||
void Init();
|
||||
void SetWorld();
|
||||
|
||||
MxU8 m_unk0x10; // 0x10
|
||||
MxU8 m_interaction; // 0x10
|
||||
MxU8 m_flags; // 0x11
|
||||
Mx3DPointFloat m_worldLocation; // 0x14
|
||||
Mx3DPointFloat m_worldDirection; // 0x28
|
||||
|
||||
@ -18,6 +18,7 @@ class LegoEventNotificationParam : public MxNotificationParam {
|
||||
c_rButtonState = 2,
|
||||
c_modKey1 = 4,
|
||||
c_modKey2 = 8,
|
||||
c_motionHandled = 16,
|
||||
};
|
||||
|
||||
// FUNCTION: LEGO1 0x10028690
|
||||
|
||||
@ -30,6 +30,7 @@ struct InternationalCharacter {
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d74a8
|
||||
// VTABLE: BETA10 0x101bc4f0
|
||||
// SIZE 0x30
|
||||
class LegoBackgroundColor : public MxVariable {
|
||||
public:
|
||||
@ -50,9 +51,11 @@ class LegoBackgroundColor : public MxVariable {
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d74b8
|
||||
// VTABLE: BETA10 0x101bc500
|
||||
// SIZE 0x24
|
||||
class LegoFullScreenMovie : public MxVariable {
|
||||
public:
|
||||
LegoFullScreenMovie();
|
||||
LegoFullScreenMovie(const char* p_key, const char* p_value);
|
||||
|
||||
void SetValue(const char* p_option) override; // vtable+0x04
|
||||
@ -110,19 +113,19 @@ class LegoGameState {
|
||||
e_dunecarbuild,
|
||||
e_jetskibuild,
|
||||
e_racecarbuild,
|
||||
e_unk40,
|
||||
e_helicopterSpawn,
|
||||
e_unk41,
|
||||
e_unk42,
|
||||
e_unk43,
|
||||
e_unk44,
|
||||
e_unk45,
|
||||
e_dunebuggySpawn,
|
||||
e_racecarSpawn,
|
||||
e_jetskiSpawn,
|
||||
e_act2main,
|
||||
e_act3script,
|
||||
e_unk48,
|
||||
e_unk49,
|
||||
e_unk50,
|
||||
e_unk51,
|
||||
e_unk52,
|
||||
e_towTrackHookedUp,
|
||||
e_jukeboxw,
|
||||
e_jukeboxExterior,
|
||||
e_unk55,
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
#ifndef LEGOHIDEANIMPRESENTER_H
|
||||
#define LEGOHIDEANIMPRESENTER_H
|
||||
|
||||
#include "decomp.h"
|
||||
#include "legoloopinganimpresenter.h"
|
||||
|
||||
class LegoPathBoundary;
|
||||
|
||||
struct LegoHideAnimStructComparator {
|
||||
MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; }
|
||||
};
|
||||
|
||||
// SIZE 0x08
|
||||
struct LegoHideAnimStruct {
|
||||
LegoPathBoundary* m_boundary; // 0x00
|
||||
MxU32 m_index; // 0x04
|
||||
};
|
||||
|
||||
typedef map<const char*, LegoHideAnimStruct, LegoHideAnimStructComparator> LegoHideAnimStructMap;
|
||||
|
||||
// VTABLE: LEGO1 0x100d9278
|
||||
// SIZE 0xc4
|
||||
class LegoHideAnimPresenter : public LegoLoopingAnimPresenter {
|
||||
public:
|
||||
LegoHideAnimPresenter();
|
||||
~LegoHideAnimPresenter() override;
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d860
|
||||
void VTable0x8c() override {} // vtable+0x8c
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d870
|
||||
void VTable0x90() override {} // vtable+0x90
|
||||
|
||||
// FUNCTION: BETA10 0x1005d4a0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f06cc
|
||||
return "LegoHideAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d880
|
||||
// FUNCTION: BETA10 0x1005d470
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006d890
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void ReadyTickle() override; // vtable+0x18
|
||||
void StartingTickle() override; // vtable+0x18
|
||||
MxResult AddToManager() override; // vtable+0x34
|
||||
void Destroy() override; // vtable+0x38
|
||||
void EndAction() override; // vtable+0x40
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
|
||||
void FUN_1006db40(LegoTime p_time);
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time);
|
||||
void FUN_1006dc10();
|
||||
void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node);
|
||||
void FUN_1006e470(
|
||||
LegoHideAnimStructMap& p_map,
|
||||
LegoAnimNodeData* p_data,
|
||||
const char* p_name,
|
||||
LegoPathBoundary* p_boundary
|
||||
);
|
||||
|
||||
LegoPathBoundary** m_boundaryMap; // 0xc0
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
// SYNTHETIC: LEGO1 0x1006d9d0
|
||||
// LegoHideAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006ddb0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~_Tree<char const *,pair<ch
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006de80
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Inc
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006dec0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::erase
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e310
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Erase
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e350
|
||||
// Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>::~Map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator>
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e3a0
|
||||
// map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::~map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e6d0
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::iterator::_Dec
|
||||
|
||||
// TEMPLATE: LEGO1 0x1006e720
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Insert
|
||||
|
||||
// GLOBAL: LEGO1 0x100f768c
|
||||
// _Tree<char const *,pair<char const * const,LegoHideAnimStruct>,map<char const *,LegoHideAnimStruct,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Kfn,LegoHideAnimStructComparator,allocator<LegoHideAnimStruct> >::_Nil
|
||||
// clang-format on
|
||||
|
||||
#endif // LEGOHIDEANIMPRESENTER_H
|
||||
@ -8,6 +8,7 @@
|
||||
#include "mxpresenter.h"
|
||||
#include "mxqueue.h"
|
||||
|
||||
#include <SDL3/SDL_haptic.h>
|
||||
#include <SDL3/SDL_joystick.h>
|
||||
#include <SDL3/SDL_keyboard.h>
|
||||
#include <SDL3/SDL_keycode.h>
|
||||
@ -18,12 +19,15 @@
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <variant>
|
||||
|
||||
class LegoCameraController;
|
||||
class LegoControlManager;
|
||||
class LegoWorld;
|
||||
|
||||
extern MxS32 g_unk0x100f31b0;
|
||||
extern const char* g_unk0x100f31b4;
|
||||
extern MxS32 g_clickedObjectId;
|
||||
extern const char* g_clickedAtom;
|
||||
|
||||
// VTABLE: LEGO1 0x100d87b8
|
||||
// class MxCollection<LegoEventNotificationParam>
|
||||
@ -89,6 +93,13 @@ class LegoInputManager : public MxPresenter {
|
||||
c_upOrDown = c_up | c_down
|
||||
};
|
||||
|
||||
enum TouchScheme {
|
||||
e_none = -1,
|
||||
e_mouse = 0,
|
||||
e_arrowKeys,
|
||||
e_gamepad,
|
||||
};
|
||||
|
||||
LegoInputManager();
|
||||
~LegoInputManager() override;
|
||||
|
||||
@ -108,7 +119,7 @@ class LegoInputManager : public MxPresenter {
|
||||
|
||||
MxResult Create(HWND p_hwnd);
|
||||
void Destroy() override;
|
||||
MxResult GetJoystick();
|
||||
LEGO1_EXPORT MxResult GetJoystick();
|
||||
MxResult GetJoystickState(MxU32* p_joystickX, MxU32* p_joystickY, MxU32* p_povPosition);
|
||||
void StartAutoDragTimer();
|
||||
void StopAutoDragTimer();
|
||||
@ -121,9 +132,8 @@ class LegoInputManager : public MxPresenter {
|
||||
void SetUnknown88(MxBool p_unk0x88) { m_unk0x88 = p_unk0x88; }
|
||||
void SetUnknown335(MxBool p_unk0x335) { m_unk0x335 = p_unk0x335; }
|
||||
void SetUnknown336(MxBool p_unk0x336) { m_unk0x336 = p_unk0x336; }
|
||||
void SetUseJoystick(MxBool p_useJoystick) { m_useJoystick = p_useJoystick; }
|
||||
void SetJoystickIndex(MxS32 p_joystickIndex) { m_joystickIndex = p_joystickIndex; }
|
||||
|
||||
// FUNCTION: BETA10 0x1002e290
|
||||
void DisableInputProcessing()
|
||||
{
|
||||
m_unk0x88 = TRUE;
|
||||
@ -144,11 +154,31 @@ class LegoInputManager : public MxPresenter {
|
||||
void GetKeyboardState();
|
||||
MxResult GetNavigationKeyStates(MxU32& p_keyFlags);
|
||||
MxResult GetNavigationTouchStates(MxU32& p_keyFlags);
|
||||
LEGO1_EXPORT void AddKeyboard(SDL_KeyboardID p_keyboardID);
|
||||
LEGO1_EXPORT void RemoveKeyboard(SDL_KeyboardID p_keyboardID);
|
||||
LEGO1_EXPORT void AddMouse(SDL_MouseID p_mouseID);
|
||||
LEGO1_EXPORT void RemoveMouse(SDL_MouseID p_mouseID);
|
||||
LEGO1_EXPORT void AddJoystick(SDL_JoystickID p_joystickID);
|
||||
LEGO1_EXPORT void RemoveJoystick(SDL_JoystickID p_joystickID);
|
||||
LEGO1_EXPORT MxBool HandleTouchEvent(SDL_Event* p_event, TouchScheme p_touchScheme);
|
||||
LEGO1_EXPORT MxBool
|
||||
HandleRumbleEvent(float p_strength, float p_lowFrequencyRumble, float p_highFrequencyRumble, MxU32 p_milliseconds);
|
||||
LEGO1_EXPORT void UpdateLastInputMethod(SDL_Event* p_event);
|
||||
const auto& GetLastInputMethod() { return m_lastInputMethod; }
|
||||
|
||||
// clang-format off
|
||||
enum class SDL_KeyboardID_v : SDL_KeyboardID {};
|
||||
enum class SDL_MouseID_v : SDL_MouseID {};
|
||||
enum class SDL_JoystickID_v : SDL_JoystickID {};
|
||||
enum class SDL_TouchID_v : SDL_TouchID {};
|
||||
// clang-format on
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1005b8d0
|
||||
// LegoInputManager::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
void InitializeHaptics();
|
||||
|
||||
MxCriticalSection m_criticalSection; // 0x58
|
||||
LegoNotifyList* m_keyboardNotifyList; // 0x5c
|
||||
LegoCameraController* m_camera; // 0x60
|
||||
@ -165,12 +195,18 @@ class LegoInputManager : public MxPresenter {
|
||||
MxBool m_unk0x88; // 0x88
|
||||
const bool* m_keyboardState;
|
||||
MxBool m_unk0x195; // 0x195
|
||||
SDL_JoystickID* m_joyids;
|
||||
SDL_Joystick* m_joystick;
|
||||
MxS32 m_joystickIndex; // 0x19c
|
||||
MxBool m_useJoystick; // 0x334
|
||||
MxBool m_unk0x335; // 0x335
|
||||
MxBool m_unk0x336; // 0x336
|
||||
MxBool m_unk0x335; // 0x335
|
||||
MxBool m_unk0x336; // 0x336
|
||||
|
||||
TouchScheme m_touchScheme = e_none;
|
||||
SDL_Point m_touchVirtualThumb = {0, 0};
|
||||
SDL_FPoint m_touchVirtualThumbOrigin;
|
||||
std::map<SDL_FingerID, MxU32> m_touchFlags;
|
||||
std::map<SDL_KeyboardID, std::pair<void*, void*>> m_keyboards;
|
||||
std::map<SDL_MouseID, std::pair<void*, SDL_Haptic*>> m_mice;
|
||||
std::map<SDL_JoystickID, std::pair<SDL_Gamepad*, SDL_Haptic*>> m_joysticks;
|
||||
std::map<SDL_HapticID, SDL_Haptic*> m_otherHaptics;
|
||||
std::variant<SDL_KeyboardID_v, SDL_MouseID_v, SDL_JoystickID_v, SDL_TouchID_v> m_lastInputMethod;
|
||||
};
|
||||
|
||||
// TEMPLATE: LEGO1 0x10028850
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
#ifndef LEGOLOCOMOTIONANIMPRESENTER_H
|
||||
#define LEGOLOCOMOTIONANIMPRESENTER_H
|
||||
|
||||
#include "legoloopinganimpresenter.h"
|
||||
#include "legoroimaplist.h"
|
||||
|
||||
class LegoAnimActor;
|
||||
|
||||
// VTABLE: LEGO1 0x100d9170
|
||||
// SIZE 0xd8
|
||||
class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter {
|
||||
public:
|
||||
LegoLocomotionAnimPresenter();
|
||||
~LegoLocomotionAnimPresenter() override;
|
||||
|
||||
// FUNCTION: BETA10 0x1005c4e0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f06e4
|
||||
return "LegoLocomotionAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006ce50
|
||||
// FUNCTION: BETA10 0x1005c4b0
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1006ce60
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void ReadyTickle() override; // vtable+0x18
|
||||
void StartingTickle() override; // vtable+0x1c
|
||||
void StreamingTickle() override; // vtable+0x20
|
||||
MxResult AddToManager() override; // vtable+0x34
|
||||
void Destroy() override; // vtable+0x38
|
||||
void EndAction() override; // vtable+0x40
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1006cfe0
|
||||
// LegoLocomotionAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value);
|
||||
|
||||
void DecrementUnknown0xd4()
|
||||
{
|
||||
if (m_unk0xd4) {
|
||||
--m_unk0xd4;
|
||||
}
|
||||
}
|
||||
|
||||
undefined2 GetUnknown0xd4() { return m_unk0xd4; }
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
|
||||
undefined4 m_unk0xc0; // 0xc0
|
||||
undefined4* m_unk0xc4; // 0xc4
|
||||
LegoROIMapList* m_roiMapList; // 0xc8
|
||||
MxS32 m_unk0xcc; // 0xcc
|
||||
MxS32 m_unk0xd0; // 0xd0
|
||||
undefined2 m_unk0xd4; // 0xd4
|
||||
};
|
||||
|
||||
#endif // LEGOLOCOMOTIONANIMPRESENTER_H
|
||||
@ -1,43 +0,0 @@
|
||||
#ifndef LEGOLOOPINGANIMPRESENTER_H
|
||||
#define LEGOLOOPINGANIMPRESENTER_H
|
||||
|
||||
#include "legoanimpresenter.h"
|
||||
|
||||
// VTABLE: LEGO1 0x100d4900
|
||||
// SIZE 0xc0
|
||||
class LegoLoopingAnimPresenter : public LegoAnimPresenter {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x1005c6f0
|
||||
static const char* HandlerClassName()
|
||||
{
|
||||
// STRING: LEGO1 0x100f0700
|
||||
return "LegoLoopingAnimPresenter";
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1000c9a0
|
||||
// FUNCTION: BETA10 0x1005c6c0
|
||||
const char* ClassName() const override // vtable+0x0c
|
||||
{
|
||||
return HandlerClassName();
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1000c9b0
|
||||
MxBool IsA(const char* p_name) const override // vtable+0x10
|
||||
{
|
||||
return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name);
|
||||
}
|
||||
|
||||
void StreamingTickle() override; // vtable+0x20
|
||||
void PutFrame() override; // vtable+0x6c
|
||||
|
||||
private:
|
||||
undefined4 m_unk0xbc; // 0xbc
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1006d000
|
||||
// LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1000f440
|
||||
// LegoLoopingAnimPresenter::`scalar deleting destructor'
|
||||
|
||||
#endif // LEGOLOOPINGANIMPRESENTER_H
|
||||
@ -134,7 +134,7 @@ class LegoOmni : public MxOmni {
|
||||
LegoROI* FindROI(const char* p_name);
|
||||
void AddWorld(LegoWorld* p_world);
|
||||
void DeleteWorld(LegoWorld* p_world);
|
||||
void FUN_1005b4f0(MxBool p_disable, MxU16 p_flags);
|
||||
void Disable(MxBool p_disable, MxU16 p_flags);
|
||||
LEGO1_EXPORT void CreateBackgroundAudio();
|
||||
LEGO1_EXPORT void RemoveWorld(const MxAtomId& p_atom, MxLong p_objectId);
|
||||
MxResult RegisterWorlds();
|
||||
@ -185,8 +185,8 @@ class LegoOmni : public MxOmni {
|
||||
// FUNCTION: BETA10 0x100d55c0
|
||||
void SetExit(MxBool p_exit) { m_exit = p_exit; }
|
||||
|
||||
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; }
|
||||
void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; }
|
||||
MxResult StartActionIfInitialized(MxDSAction& p_dsAction) { return m_initialized ? Start(&p_dsAction) : SUCCESS; }
|
||||
void SetInitialized(MxBool p_unk0x13c) { m_initialized = p_unk0x13c; }
|
||||
|
||||
void CloseMainWindow()
|
||||
{
|
||||
@ -200,6 +200,9 @@ class LegoOmni : public MxOmni {
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
|
||||
void SetVersion10(MxBool p_version10) { m_version10 = p_version10; }
|
||||
MxBool IsVersion10() { return m_version10; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10058b30
|
||||
// LegoOmni::`scalar deleting destructor'
|
||||
|
||||
@ -221,9 +224,10 @@ class LegoOmni : public MxOmni {
|
||||
MxDSAction m_action; // 0xa0
|
||||
MxBackgroundAudioManager* m_bkgAudioManager; // 0x134
|
||||
MxTransitionManager* m_transitionManager; // 0x138
|
||||
MxBool m_version10;
|
||||
|
||||
public:
|
||||
MxBool m_unk0x13c; // 0x13c
|
||||
MxBool m_initialized; // 0x13c
|
||||
};
|
||||
|
||||
#endif // LEGOMAIN_H
|
||||
|
||||
@ -47,7 +47,7 @@ class LegoModelPresenter : public MxVideoPresenter {
|
||||
void ReadyTickle() override; // vtable+0x18
|
||||
void ParseExtra() override; // vtable+0x30
|
||||
|
||||
MxResult FUN_1007ff70(MxDSChunk& p_chunk, LegoEntity* p_entity, MxBool p_roiVisible, LegoWorld* p_world);
|
||||
MxResult CreateROI(MxDSChunk& p_chunk, LegoEntity* p_entity, MxBool p_roiVisible, LegoWorld* p_world);
|
||||
|
||||
void Reset()
|
||||
{
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "lego1_export.h"
|
||||
#include "legonamedpartlist.h"
|
||||
#include "mxmediapresenter.h"
|
||||
#include "viewmanager/viewlodlist.h"
|
||||
|
||||
// VTABLE: LEGO1 0x100d4df0
|
||||
// SIZE 0x54
|
||||
@ -50,10 +51,21 @@ class LegoPartPresenter : public MxMediaPresenter {
|
||||
MxResult Read(MxDSChunk& p_chunk);
|
||||
void Store();
|
||||
|
||||
static void Release()
|
||||
{
|
||||
for (auto* lodList : g_lodLists) {
|
||||
lodList->Release();
|
||||
}
|
||||
|
||||
g_lodLists.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
|
||||
LegoNamedPartList* m_parts; // 0x50
|
||||
|
||||
static vector<ViewLODList*> g_lodLists;
|
||||
};
|
||||
|
||||
#endif // LEGOPARTPRESENTER_H
|
||||
|
||||
@ -13,7 +13,7 @@ struct LegoPathEdgeContainer;
|
||||
struct LegoOrientedEdge;
|
||||
class LegoWEEdge;
|
||||
|
||||
extern MxLong g_unk0x100f3308;
|
||||
extern MxLong g_timeLastHitSoundPlayed;
|
||||
extern const char* g_strHIT_WALL_SOUND;
|
||||
|
||||
// VTABLE: LEGO1 0x100d6e28
|
||||
|
||||
@ -75,7 +75,7 @@ class LegoPathBoundary : public LegoWEGEdge {
|
||||
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::erase
|
||||
|
||||
// TEMPLATE: LEGO1 0x1002c440
|
||||
// TEMPLATE: BETA10 0x100b6480
|
||||
// TEMPLATE: BETA10 0x10020480
|
||||
// _Tree<LegoPathActor *,LegoPathActor *,set<LegoPathActor *,LegoPathActorSetCompare,allocator<LegoPathActor *> >::_Kfn,LegoPathActorSetCompare,allocator<LegoPathActor *> >::find
|
||||
|
||||
// TEMPLATE: LEGO1 0x1002c4c0
|
||||
@ -190,6 +190,12 @@ class LegoPathBoundary : public LegoWEGEdge {
|
||||
// TEMPLATE: BETA10 0x10082b40
|
||||
// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::const_iterator::operator*
|
||||
|
||||
// TEMPLATE: BETA10 0x100b6440
|
||||
// set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::find
|
||||
|
||||
// TEMPLATE: BETA10 0x100b6480
|
||||
// _Tree<LegoAnimPresenter *,LegoAnimPresenter *,set<LegoAnimPresenter *,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::_Kfn,LegoAnimPresenterSetCompare,allocator<LegoAnimPresenter *> >::find
|
||||
|
||||
// TEMPLATE: BETA10 0x10021dc0
|
||||
// ??0?$Set@PAVLegoPathActor@@ULegoPathActorSetCompare@@@@QAE@ABV0@@Z
|
||||
|
||||
|
||||
@ -42,9 +42,9 @@ class LegoPhonemePresenter : public MxFlcPresenter {
|
||||
|
||||
MxS32 m_rectCount; // 0x68
|
||||
LegoTextureInfo* m_textureInfo; // 0x6c
|
||||
MxBool m_unk0x70; // 0x70
|
||||
MxBool m_reusedPhoneme; // 0x70
|
||||
MxString m_roiName; // 0x74
|
||||
MxBool m_unk0x84; // 0x84
|
||||
MxBool m_isPartOfAnimMM; // 0x84
|
||||
};
|
||||
|
||||
// TEMPLATE: LEGO1 0x1004eb20
|
||||
|
||||
@ -49,12 +49,12 @@ class LEGO1_EXPORT LegoPlantManager : public MxCore {
|
||||
MxBool SwitchMove(LegoEntity* p_entity);
|
||||
MxBool SwitchMood(LegoEntity* p_entity);
|
||||
MxU32 GetAnimationId(LegoEntity* p_entity);
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state);
|
||||
MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_basedOnMood);
|
||||
LegoPlantInfo* GetInfoArray(MxS32& p_length);
|
||||
LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, LegoOmni::World p_worldId);
|
||||
MxBool DecrementCounter(LegoEntity* p_entity);
|
||||
void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length);
|
||||
MxResult FUN_10026410();
|
||||
MxResult DetermineBoundaries();
|
||||
void ClearCounters();
|
||||
void SetInitialCounters();
|
||||
|
||||
@ -77,11 +77,11 @@ class LEGO1_EXPORT LegoPlantManager : public MxCore {
|
||||
static MxS32 g_maxMove[4];
|
||||
static MxU32 g_maxSound;
|
||||
|
||||
LegoOmni::World m_worldId; // 0x08
|
||||
undefined m_unk0x0c; // 0x0c
|
||||
AnimEntry* m_entries[5]; // 0x10
|
||||
MxS8 m_numEntries; // 0x24
|
||||
LegoWorld* m_world; // 0x28
|
||||
LegoOmni::World m_worldId; // 0x08
|
||||
MxBool m_boundariesDetermined; // 0x0c
|
||||
AnimEntry* m_entries[5]; // 0x10
|
||||
MxS8 m_numEntries; // 0x24
|
||||
LegoWorld* m_world; // 0x28
|
||||
|
||||
friend class DebugViewer;
|
||||
};
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#include "mxtypes.h"
|
||||
|
||||
class Act1State;
|
||||
class LegoEventNotificationParam;
|
||||
class LegoControlManagerNotificationParam;
|
||||
class LegoPathActor;
|
||||
class MxEndActionNotificationParam;
|
||||
class MxNotificationParam;
|
||||
@ -117,7 +117,7 @@ class LegoRace : public LegoWorld {
|
||||
|
||||
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
|
||||
|
||||
virtual MxLong HandleClick(LegoEventNotificationParam&) = 0; // vtable+0x6c
|
||||
virtual MxLong HandleControl(LegoControlManagerNotificationParam&) = 0; // vtable+0x6c
|
||||
|
||||
// FUNCTION: LEGO1 0x10015b70
|
||||
virtual MxLong HandlePathStruct(LegoPathStructNotificationParam&) { return 0; } // vtable+0x70
|
||||
|
||||
@ -144,10 +144,10 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap {
|
||||
MxResult VTable0x9c() override; // vtable+0x9c
|
||||
|
||||
virtual void SetMaxLinearVelocity(float p_maxLinearVelocity);
|
||||
virtual void FUN_10012ff0(float p_param);
|
||||
virtual void KickCamera(float p_param);
|
||||
virtual MxU32 HandleSkeletonKicks(float p_param1);
|
||||
|
||||
static void FUN_10012de0();
|
||||
static void InitYouCantStopSound();
|
||||
static void InitSoundIndices();
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10014240
|
||||
@ -155,7 +155,7 @@ class LegoRaceCar : public LegoCarRaceActor, public LegoRaceMap {
|
||||
|
||||
private:
|
||||
undefined m_userState; // 0x54
|
||||
float m_unk0x58; // 0x58
|
||||
float m_kickStart; // 0x58
|
||||
Mx3DPointFloat m_unk0x5c; // 0x5c
|
||||
|
||||
// Names verified by BETA10 0x100cb4a9
|
||||
|
||||
@ -44,8 +44,11 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
|
||||
Vector3& p_v3
|
||||
) override; // vtable+0x6c
|
||||
void Animate(float p_time) override; // vtable+0x70
|
||||
void SwitchBoundary(LegoPathBoundary*& p_boundary, LegoOrientedEdge*& p_edge, float& p_unk0xe4)
|
||||
override; // vtable+0x98
|
||||
void SwitchBoundary(
|
||||
LegoPathBoundary*& p_boundary,
|
||||
LegoOrientedEdge*& p_edge,
|
||||
float& p_unk0xe4
|
||||
) override; // vtable+0x98
|
||||
MxResult VTable0x9c() override; // vtable+0x9c
|
||||
|
||||
// LegoCarRaceActor vtable
|
||||
@ -83,7 +86,7 @@ class LegoCarRaceActor : public virtual LegoRaceActor {
|
||||
|
||||
protected:
|
||||
MxFloat m_unk0x08; // 0x08
|
||||
MxU8 m_unk0x0c; // 0x0c
|
||||
MxU8 m_animState; // 0x0c
|
||||
|
||||
// Could be a multiplier for the maximum speed when going straight
|
||||
MxFloat m_unk0x10; // 0x10
|
||||
|
||||
@ -17,15 +17,15 @@ class LegoSoundManager : public MxSoundManager {
|
||||
void Destroy() override; // vtable+0x18
|
||||
MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; // vtable+0x30
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10029920
|
||||
// SYNTHETIC: BETA10 0x100d0660
|
||||
// LegoSoundManager::`scalar deleting destructor'
|
||||
|
||||
void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity);
|
||||
|
||||
// FUNCTION: BETA10 0x1000f350
|
||||
LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; }
|
||||
|
||||
// SYNTHETIC: LEGO1 0x10029920
|
||||
// SYNTHETIC: BETA10 0x100d0660
|
||||
// LegoSoundManager::`scalar deleting destructor'
|
||||
|
||||
private:
|
||||
void Init();
|
||||
void Destroy(MxBool p_fromDestructor);
|
||||
|
||||
@ -28,9 +28,11 @@ class LegoTranInfoList : public MxPtrList<LegoTranInfo> {
|
||||
// class MxPtrListCursor<LegoTranInfo>
|
||||
|
||||
// VTABLE: LEGO1 0x100d8d20
|
||||
// VTABLE: BETA10 0x101bad70
|
||||
// SIZE 0x10
|
||||
class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x100496d0
|
||||
LegoTranInfoListCursor(LegoTranInfoList* p_list) : MxPtrListCursor<LegoTranInfo>(p_list) {}
|
||||
};
|
||||
|
||||
@ -62,9 +64,14 @@ class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
|
||||
// MxPtrList<LegoTranInfo>::`scalar deleting destructor'
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100612f0
|
||||
// SYNTHETIC: BETA10 0x100498c0
|
||||
// LegoTranInfoListCursor::`scalar deleting destructor'
|
||||
|
||||
// SYNTHETIC: BETA10 0x10049770
|
||||
// MxPtrListCursor<LegoTranInfo>::MxPtrListCursor<LegoTranInfo>
|
||||
|
||||
// FUNCTION: LEGO1 0x10061360
|
||||
// FUNCTION: BETA10 0x10049910
|
||||
// MxPtrListCursor<LegoTranInfo>::~MxPtrListCursor<LegoTranInfo>
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100613b0
|
||||
@ -77,6 +84,7 @@ class LegoTranInfoListCursor : public MxPtrListCursor<LegoTranInfo> {
|
||||
// MxListCursor<LegoTranInfo *>::~MxListCursor<LegoTranInfo *>
|
||||
|
||||
// FUNCTION: LEGO1 0x100614e0
|
||||
// FUNCTION: BETA10 0x10049ab0
|
||||
// LegoTranInfoListCursor::~LegoTranInfoListCursor
|
||||
|
||||
#endif // LEGOTRANINFOLIST_H
|
||||
|
||||
@ -32,6 +32,14 @@ enum Cursor {
|
||||
e_cursorNone
|
||||
};
|
||||
|
||||
enum GameEvent {
|
||||
e_hitActor,
|
||||
e_skeletonKick,
|
||||
e_raceFinished,
|
||||
e_badEnding,
|
||||
e_goodEnding
|
||||
};
|
||||
|
||||
class BoundingSphere;
|
||||
class MxAtomId;
|
||||
class LegoEntity;
|
||||
@ -49,28 +57,29 @@ LegoROI* PickROI(MxLong p_x, MxLong p_y);
|
||||
LegoROI* PickRootROI(MxLong p_x, MxLong p_y);
|
||||
void RotateY(LegoROI* p_roi, MxFloat p_angle);
|
||||
MxBool SpheresIntersect(const BoundingSphere& p_sphere1, const BoundingSphere& p_sphere2);
|
||||
MxBool FUN_1003ded0(MxFloat p_param1[2], MxFloat p_param2[3], MxFloat p_param3[3]);
|
||||
MxBool CalculateRayOriginDirection(MxFloat p_coordinates[2], MxFloat p_direction[3], MxFloat p_origin[3]);
|
||||
MxBool TransformWorldToScreen(const MxFloat p_world[3], MxFloat p_screen[4]);
|
||||
MxS16 CountTotalTreeNodes(LegoTreeNode* p_node);
|
||||
LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index);
|
||||
void FUN_1003e050(LegoAnimPresenter* p_presenter);
|
||||
void CalculateViewFromAnimation(LegoAnimPresenter* p_presenter);
|
||||
Extra::ActionType MatchActionString(const char*);
|
||||
void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender);
|
||||
void SetCameraControllerFromIsle();
|
||||
void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut);
|
||||
void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBool p_bool);
|
||||
void FUN_1003eda0();
|
||||
void ResetViewVelocity();
|
||||
MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id);
|
||||
void EnableAnimations(MxBool p_enable);
|
||||
void SetAppCursor(Cursor p_cursor);
|
||||
MxBool FUN_1003ef60();
|
||||
MxBool CanExit();
|
||||
MxBool RemoveFromWorld(MxAtomId& p_entityAtom, MxS32 p_entityId, MxAtomId& p_worldAtom, MxS32 p_worldEntityId);
|
||||
MxS32 UpdateLightPosition(MxS32 p_increase);
|
||||
void SetLightPosition(MxS32 p_index);
|
||||
LegoNamedTexture* ReadNamedTexture(LegoStorage* p_storage);
|
||||
void WriteDefaultTexture(LegoStorage* p_storage, const char* p_name);
|
||||
void WriteNamedTexture(LegoStorage* p_storage, LegoNamedTexture* p_namedTexture);
|
||||
void FUN_1003f930(LegoNamedTexture* p_namedTexture);
|
||||
void LoadFromNamedTexture(LegoNamedTexture* p_namedTexture);
|
||||
void EmitGameEvent(GameEvent p_event);
|
||||
|
||||
// FUNCTION: BETA10 0x100260a0
|
||||
inline void StartIsleAction(IsleScript::Script p_objectId)
|
||||
|
||||
@ -17,41 +17,60 @@ extern const char* g_varVISIBILITY;
|
||||
extern const char* g_varCAMERALOCATION;
|
||||
extern const char* g_varCURSOR;
|
||||
extern const char* g_varWHOAMI;
|
||||
extern const char* g_varDEBUG;
|
||||
|
||||
// VTABLE: LEGO1 0x100d86c8
|
||||
// VTABLE: BETA10 0x101bc980
|
||||
// SIZE 0x24
|
||||
class VisibilityVariable : public MxVariable {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x10093470
|
||||
VisibilityVariable() { m_key = g_varVISIBILITY; }
|
||||
|
||||
void SetValue(const char* p_value) override; // vtable+0x04
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d86b8
|
||||
// VTABLE: BETA10 0x101bc990
|
||||
// SIZE 0x24
|
||||
class CameraLocationVariable : public MxVariable {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x10093510
|
||||
CameraLocationVariable() { m_key = g_varCAMERALOCATION; }
|
||||
|
||||
void SetValue(const char* p_value) override; // vtable+0x04
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d86a8
|
||||
// VTABLE: BETA10 0x101bc9a0
|
||||
// SIZE 0x24
|
||||
class CursorVariable : public MxVariable {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x100935b0
|
||||
CursorVariable() { m_key = g_varCURSOR; }
|
||||
|
||||
void SetValue(const char* p_value) override; // vtable+0x04
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d8698
|
||||
// VTABLE: BETA10 0x101bc9b0
|
||||
// SIZE 0x24
|
||||
class WhoAmIVariable : public MxVariable {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x10093650
|
||||
WhoAmIVariable() { m_key = g_varWHOAMI; }
|
||||
|
||||
void SetValue(const char* p_value) override; // vtable+0x04
|
||||
};
|
||||
|
||||
// VTABLE: BETA10 0x101bc9c0
|
||||
// SIZE 0x24
|
||||
class DebugVariable : public MxVariable {
|
||||
public:
|
||||
// FUNCTION: BETA10 0x100936f0
|
||||
DebugVariable() { m_key = g_varDEBUG; }
|
||||
|
||||
void SetValue(const char* p_value) override; // vtable+0x04
|
||||
};
|
||||
|
||||
#endif // LEGOVARIABLES_H
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#ifndef LEGOVIDEOMANAGER_H
|
||||
#define LEGOVIDEOMANAGER_H
|
||||
|
||||
#include "cursor.h"
|
||||
#include "decomp.h"
|
||||
#include "lego1_export.h"
|
||||
#include "legophonemelist.h"
|
||||
@ -37,6 +38,7 @@ class LegoVideoManager : public MxVideoManager {
|
||||
void EnableFullScreenMovie(MxBool p_enable);
|
||||
LEGO1_EXPORT void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale);
|
||||
LEGO1_EXPORT void MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY);
|
||||
LEGO1_EXPORT void SetCursorBitmap(const CursorBitmap* p_cursorBitmap);
|
||||
void ToggleFPS(MxBool p_visible);
|
||||
|
||||
MxResult Tickle() override; // vtable+0x08
|
||||
@ -68,7 +70,9 @@ class LegoVideoManager : public MxVideoManager {
|
||||
MxBool GetRender3D() { return m_render3d; }
|
||||
double GetElapsedSeconds() { return m_elapsedSeconds; }
|
||||
|
||||
// FUNCTION: BETA10 0x1002e290
|
||||
void SetRender3D(MxBool p_render3d) { m_render3d = p_render3d; }
|
||||
|
||||
void SetUnk0x554(MxBool p_unk0x554) { m_unk0x554 = p_unk0x554; }
|
||||
|
||||
private:
|
||||
|
||||
@ -49,11 +49,11 @@ LegoPlantManager* PlantManager();
|
||||
LegoBuildingManager* BuildingManager();
|
||||
LegoTextureContainer* TextureContainer();
|
||||
ViewLODListManager* GetViewLODListManager();
|
||||
void FUN_10015820(MxBool p_disable, MxU16 p_flags);
|
||||
void Disable(MxBool p_disable, MxU16 p_flags);
|
||||
LegoROI* FindROI(const char* p_name);
|
||||
void SetROIVisible(const char* p_name, MxBool p_visible);
|
||||
void SetUserActor(LegoPathActor* p_userActor);
|
||||
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction);
|
||||
MxResult StartActionIfInitialized(MxDSAction& p_dsAction);
|
||||
void DeleteAction();
|
||||
LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid);
|
||||
MxDSAction& GetCurrentAction();
|
||||
|
||||
@ -44,21 +44,28 @@ class MxControlPresenter : public MxCompositePresenter {
|
||||
void EndAction() override; // vtable+0x40
|
||||
MxBool HasTickleStatePassed(TickleState p_tickleState) override; // vtable+0x48
|
||||
void Enable(MxBool p_enable) override; // vtable+0x54
|
||||
virtual void VTable0x6c(MxS16 p_unk0x4e); // vtable+0x6c
|
||||
virtual void UpdateEnabledChild(MxS16 p_enabledChild); // vtable+0x6c
|
||||
|
||||
MxBool FUN_10044480(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter);
|
||||
MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter);
|
||||
MxBool Notify(LegoControlManagerNotificationParam* p_param, MxPresenter* p_presenter);
|
||||
MxBool CheckButtonDown(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter);
|
||||
|
||||
MxS16 GetUnknown0x4e() { return m_unk0x4e; }
|
||||
MxS16 GetEnabledChild() { return m_enabledChild; }
|
||||
|
||||
private:
|
||||
MxS16 m_unk0x4c; // 0x4c
|
||||
MxS16 m_unk0x4e; // 0x4e
|
||||
MxBool m_unk0x50; // 0x50
|
||||
MxS16 m_unk0x52; // 0x52
|
||||
MxS16 m_unk0x54; // 0x54
|
||||
MxS16 m_unk0x56; // 0x56
|
||||
MxS16* m_states; // 0x58
|
||||
enum {
|
||||
e_none,
|
||||
e_toggle,
|
||||
e_grid,
|
||||
e_map,
|
||||
};
|
||||
|
||||
MxS16 m_style; // 0x4c
|
||||
MxS16 m_enabledChild; // 0x4e
|
||||
MxBool m_unk0x50; // 0x50
|
||||
MxS16 m_columnsOrRows; // 0x52
|
||||
MxS16 m_rowsOrColumns; // 0x54
|
||||
MxS16 m_stateOrCellIndex; // 0x56
|
||||
MxS16* m_states; // 0x58
|
||||
};
|
||||
|
||||
// SYNTHETIC: LEGO1 0x100440f0
|
||||
|
||||
@ -55,6 +55,8 @@ class MxTransitionManager : public MxCore {
|
||||
|
||||
TransitionType GetTransitionType() { return m_mode; }
|
||||
|
||||
LEGO1_EXPORT static void configureMxTransitionManager(TransitionType p_transitionManagerConfig);
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1004b9e0
|
||||
// MxTransitionManager::`scalar deleting destructor'
|
||||
|
||||
|
||||
@ -12,6 +12,13 @@ class MxEndActionNotificationParam;
|
||||
// SIZE 0x28
|
||||
class TowTrackMissionState : public LegoState {
|
||||
public:
|
||||
enum {
|
||||
e_none = 0,
|
||||
e_started = 1,
|
||||
e_hookedUp = 2,
|
||||
e_hookingUp = 3,
|
||||
};
|
||||
|
||||
TowTrackMissionState();
|
||||
|
||||
// FUNCTION: LEGO1 0x1004dde0
|
||||
@ -126,19 +133,19 @@ class TowTrackMissionState : public LegoState {
|
||||
// SYNTHETIC: LEGO1 0x1004e060
|
||||
// TowTrackMissionState::`scalar deleting destructor'
|
||||
|
||||
undefined4 m_unk0x08; // 0x08
|
||||
MxLong m_startTime; // 0x0c
|
||||
MxBool m_unk0x10; // 0x10
|
||||
MxS16 m_peScore; // 0x12
|
||||
MxS16 m_maScore; // 0x14
|
||||
MxS16 m_paScore; // 0x16
|
||||
MxS16 m_niScore; // 0x18
|
||||
MxS16 m_laScore; // 0x1a
|
||||
MxS16 m_peHighScore; // 0x1c
|
||||
MxS16 m_maHighScore; // 0x1e
|
||||
MxS16 m_paHighScore; // 0x20
|
||||
MxS16 m_niHighScore; // 0x22
|
||||
MxS16 m_laHighScore; // 0x24
|
||||
MxU32 m_state; // 0x08
|
||||
MxLong m_startTime; // 0x0c
|
||||
MxBool m_takingTooLong; // 0x10
|
||||
MxS16 m_peScore; // 0x12
|
||||
MxS16 m_maScore; // 0x14
|
||||
MxS16 m_paScore; // 0x16
|
||||
MxS16 m_niScore; // 0x18
|
||||
MxS16 m_laScore; // 0x1a
|
||||
MxS16 m_peHighScore; // 0x1c
|
||||
MxS16 m_maHighScore; // 0x1e
|
||||
MxS16 m_paHighScore; // 0x20
|
||||
MxS16 m_niHighScore; // 0x22
|
||||
MxS16 m_laHighScore; // 0x24
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d7ee0
|
||||
@ -174,10 +181,10 @@ class TowTrack : public IslePathActor {
|
||||
virtual MxLong HandleEndAction(MxEndActionNotificationParam& p_param); // vtable+0xf0
|
||||
|
||||
void CreateState();
|
||||
void FUN_1004dab0();
|
||||
void Init();
|
||||
void ActivateSceneActions();
|
||||
void StopActions();
|
||||
void FUN_1004dbe0();
|
||||
void Reset();
|
||||
|
||||
// SYNTHETIC: LEGO1 0x1004c950
|
||||
// TowTrack::`scalar deleting destructor'
|
||||
@ -192,8 +199,8 @@ class TowTrack : public IslePathActor {
|
||||
TowTrackMissionState* m_state; // 0x164
|
||||
MxS16 m_unk0x168; // 0x168
|
||||
MxS16 m_actorId; // 0x16a
|
||||
MxS16 m_unk0x16c; // 0x16c
|
||||
MxS16 m_unk0x16e; // 0x16e
|
||||
MxS16 m_treeBlockageTriggered; // 0x16c
|
||||
MxS16 m_speedComplaintTriggered; // 0x16e
|
||||
IsleScript::Script m_lastAction; // 0x170
|
||||
IsleScript::Script m_lastAnimation; // 0x174
|
||||
MxFloat m_fuel; // 0x178
|
||||
|
||||
@ -631,7 +631,7 @@ MxU32 Act2Actor::FUN_10019700(MxFloat p_param)
|
||||
MxFloat time = p_param - (m_unk0x2c - m_shootAnim->GetDuration());
|
||||
|
||||
for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
|
||||
LegoROI::FUN_100a8e80(root->GetChild(i), matrix, time, m_shootAnim->GetROIMap());
|
||||
LegoROI::ApplyAnimationTransformation(root->GetChild(i), matrix, time, m_shootAnim->GetROIMap());
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
||||
@ -4,9 +4,9 @@
|
||||
#include "act3ammo.h"
|
||||
#include "anim/legoanim.h"
|
||||
#include "define.h"
|
||||
#include "legoanimpresenter.h"
|
||||
#include "legobuildingmanager.h"
|
||||
#include "legocachesoundmanager.h"
|
||||
#include "legolocomotionanimpresenter.h"
|
||||
#include "legopathedgecontainer.h"
|
||||
#include "legoplantmanager.h"
|
||||
#include "legoplants.h"
|
||||
@ -580,7 +580,7 @@ void Act3Brickster::Animate(float p_time)
|
||||
}
|
||||
|
||||
if (m_unk0x54 < p_time) {
|
||||
((Act3*) m_world)->FUN_10072ad0(5);
|
||||
((Act3*) m_world)->TriggerHitSound(5);
|
||||
m_unk0x54 = p_time + 15000.0f;
|
||||
}
|
||||
|
||||
@ -596,7 +596,7 @@ void Act3Brickster::Animate(float p_time)
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
|
||||
if (m_unk0x58 >= 8) {
|
||||
((Act3*) m_world)->FUN_10072ad0(6);
|
||||
((Act3*) m_world)->TriggerHitSound(6);
|
||||
}
|
||||
else {
|
||||
SoundManager()->GetCacheSoundManager()->Play("eatpz", NULL, FALSE);
|
||||
@ -639,7 +639,7 @@ void Act3Brickster::Animate(float p_time)
|
||||
float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration());
|
||||
|
||||
for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
|
||||
LegoROI::FUN_100a8e80(root->GetChild(i), local70, time, m_shootAnim->GetROIMap());
|
||||
LegoROI::ApplyAnimationTransformation(root->GetChild(i), local70, time, m_shootAnim->GetROIMap());
|
||||
}
|
||||
}
|
||||
|
||||
@ -686,7 +686,7 @@ void Act3Brickster::Animate(float p_time)
|
||||
float time = p_time - (m_unk0x50 - m_shootAnim->GetDuration());
|
||||
|
||||
for (MxS32 i = 0; i < root->GetNumChildren(); i++) {
|
||||
LegoROI::FUN_100a8e80(root->GetChild(i), locale4, time, m_shootAnim->GetROIMap());
|
||||
LegoROI::ApplyAnimationTransformation(root->GetChild(i), locale4, time, m_shootAnim->GetROIMap());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,7 +1187,7 @@ void Act3Shark::Animate(float p_time)
|
||||
vec = m_unk0x3c;
|
||||
|
||||
LegoTreeNode* node = m_unk0x34->GetAnimTreePtr()->GetRoot();
|
||||
LegoROI::FUN_100a8e80(node, mat, duration, m_unk0x34->GetROIMap());
|
||||
LegoROI::ApplyAnimationTransformation(node, mat, duration, m_unk0x34->GetROIMap());
|
||||
}
|
||||
else {
|
||||
roiMap[1] = m_unk0x38;
|
||||
|
||||
@ -200,7 +200,7 @@ MxResult Act3Ammo::FUN_10053d30(LegoPathController* p_p, MxFloat p_unk0x19c)
|
||||
|
||||
// FUNCTION: LEGO1 0x10053db0
|
||||
// FUNCTION: BETA10 0x1001e0f0
|
||||
MxResult Act3Ammo::FUN_10053db0(float p_param1, const Matrix4& p_param2)
|
||||
MxResult Act3Ammo::FUN_10053db0(float p_param1, Matrix4& p_param2)
|
||||
{
|
||||
float local34 = p_param1 * p_param1;
|
||||
|
||||
@ -378,12 +378,14 @@ void Act3Ammo::Animate(float p_time)
|
||||
if (IsBit4()) {
|
||||
if (IsPizza()) {
|
||||
m_world->RemovePizza(*this);
|
||||
m_world->FUN_10072ad0(2);
|
||||
m_world->TriggerHitSound(2);
|
||||
}
|
||||
else {
|
||||
m_world->RemoveDonut(*this);
|
||||
m_world->FUN_10072ad0(4);
|
||||
m_world->TriggerHitSound(4);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (IsPizza()) {
|
||||
@ -394,89 +396,99 @@ void Act3Ammo::Animate(float p_time)
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("stickdn", NULL, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
LegoPathActorSet& plpas = m_boundary->GetActors();
|
||||
LegoPathActorSet lpas(plpas);
|
||||
LegoPathActorSet& plpas = m_boundary->GetActors();
|
||||
LegoPathActorSet lpas(plpas);
|
||||
|
||||
for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
|
||||
if (plpas.find(*itpa) != plpas.end() && this != *itpa) {
|
||||
LegoROI* r = (*itpa)->GetROI();
|
||||
assert(r);
|
||||
for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
|
||||
if (plpas.find(*itpa) == plpas.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!strncmp(r->GetName(), "pammo", 5)) {
|
||||
Mx3DPointFloat local1c8;
|
||||
Mx3DPointFloat local1b4;
|
||||
if (this == *itpa) {
|
||||
continue;
|
||||
}
|
||||
|
||||
local1c8 = r->GetLocal2World()[3];
|
||||
local1b4 = m_roi->GetLocal2World()[3];
|
||||
LegoROI* r = (*itpa)->GetROI();
|
||||
assert(r);
|
||||
|
||||
local1b4 -= local1c8;
|
||||
if (!strncmp(r->GetName(), "pammo", 5)) {
|
||||
Mx3DPointFloat local1c8;
|
||||
Mx3DPointFloat local1b4;
|
||||
|
||||
float radius = r->GetWorldBoundingSphere().Radius();
|
||||
if (local1b4.LenSquared() <= radius * radius) {
|
||||
MxS32 index = -1;
|
||||
if (sscanf(r->GetName(), "pammo%d", &index) != 1) {
|
||||
assert(0);
|
||||
}
|
||||
local1c8 = r->GetLocal2World()[3];
|
||||
local1b4 = m_roi->GetLocal2World()[3];
|
||||
|
||||
assert(m_world);
|
||||
local1b4 -= local1c8;
|
||||
|
||||
if (m_world->m_pizzas[index].IsValid() && !m_world->m_pizzas[index].IsSharkFood()) {
|
||||
m_world->EatPizza(index);
|
||||
m_world->m_brickster->FUN_100417c0();
|
||||
}
|
||||
|
||||
if (IsDonut()) {
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("dnhitpz", NULL, FALSE);
|
||||
m_world->RemoveDonut(*this);
|
||||
local14 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
float radius = r->GetWorldBoundingSphere().Radius();
|
||||
if (local1b4.LenSquared() <= radius * radius) {
|
||||
MxS32 index = -1;
|
||||
if (sscanf(r->GetName(), "pammo%d", &index) != 1) {
|
||||
assert(0);
|
||||
}
|
||||
else if (!strncmp(r->GetName(), "dammo", 5)) {
|
||||
Mx3DPointFloat local1f8;
|
||||
Mx3DPointFloat local1e4;
|
||||
|
||||
local1f8 = r->GetLocal2World()[3];
|
||||
local1e4 = m_roi->GetLocal2World()[3];
|
||||
assert(m_world);
|
||||
|
||||
local1e4 -= local1f8;
|
||||
#ifdef BETA10
|
||||
m_world->EatPizza(index);
|
||||
#else
|
||||
if (m_world->m_pizzas[index].IsValid() && !m_world->m_pizzas[index].IsSharkFood()) {
|
||||
m_world->EatPizza(index);
|
||||
m_world->m_brickster->FUN_100417c0();
|
||||
}
|
||||
#endif
|
||||
|
||||
float radius = r->GetWorldBoundingSphere().Radius();
|
||||
if (local1e4.LenSquared() <= radius * radius) {
|
||||
MxS32 index = -1;
|
||||
if (sscanf(r->GetName(), "dammo%d", &index) != 1) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
assert(m_world);
|
||||
|
||||
m_world->EatDonut(index);
|
||||
|
||||
if (IsPizza()) {
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("pzhitdn", NULL, FALSE);
|
||||
m_world->RemovePizza(*this);
|
||||
local14 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (IsDonut()) {
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("dnhitpz", NULL, FALSE);
|
||||
m_world->RemoveDonut(*this);
|
||||
local14 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!strncmp(r->GetName(), "dammo", 5)) {
|
||||
Mx3DPointFloat local1f8;
|
||||
Mx3DPointFloat local1e4;
|
||||
|
||||
if (!local14) {
|
||||
if (IsPizza()) {
|
||||
m_world->FUN_10073360(*this, local68);
|
||||
}
|
||||
else {
|
||||
m_world->FUN_10073390(*this, local68);
|
||||
}
|
||||
local1f8 = r->GetLocal2World()[3];
|
||||
local1e4 = m_roi->GetLocal2World()[3];
|
||||
|
||||
m_worldSpeed = -1.0f;
|
||||
local1e4 -= local1f8;
|
||||
|
||||
float radius = r->GetWorldBoundingSphere().Radius();
|
||||
if (local1e4.LenSquared() <= radius * radius) {
|
||||
MxS32 index = -1;
|
||||
if (sscanf(r->GetName(), "dammo%d", &index) != 1) {
|
||||
assert(0);
|
||||
}
|
||||
|
||||
assert(m_world);
|
||||
|
||||
m_world->EatDonut(index);
|
||||
|
||||
if (IsPizza()) {
|
||||
assert(SoundManager()->GetCacheSoundManager());
|
||||
SoundManager()->GetCacheSoundManager()->Play("pzhitdn", NULL, FALSE);
|
||||
m_world->RemovePizza(*this);
|
||||
local14 = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!local14) {
|
||||
if (IsPizza()) {
|
||||
m_world->FUN_10073360(*this, local68);
|
||||
}
|
||||
else {
|
||||
m_world->FUN_10073390(*this, local68);
|
||||
}
|
||||
|
||||
m_worldSpeed = -1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,11 +40,11 @@ Ambulance::Ambulance()
|
||||
m_state = NULL;
|
||||
m_unk0x168 = 0;
|
||||
m_actorId = -1;
|
||||
m_unk0x16c = 0;
|
||||
m_unk0x16e = 0;
|
||||
m_unk0x170 = 0;
|
||||
m_atPoliceTask = 0;
|
||||
m_atBeachTask = 0;
|
||||
m_taskState = Ambulance::e_none;
|
||||
m_lastAction = IsleScript::c_noneIsle;
|
||||
m_unk0x172 = 0;
|
||||
m_enableRandomAudio = 0;
|
||||
m_lastAnimation = IsleScript::c_noneIsle;
|
||||
m_fuel = 1.0;
|
||||
}
|
||||
@ -73,7 +73,7 @@ MxResult Ambulance::Create(MxDSAction& p_dsAction)
|
||||
m_state = (AmbulanceMissionState*) GameState()->GetState("AmbulanceMissionState");
|
||||
if (!m_state) {
|
||||
m_state = new AmbulanceMissionState();
|
||||
m_state->m_unk0x08 = 0;
|
||||
m_state->m_state = AmbulanceMissionState::e_ready;
|
||||
GameState()->RegisterState(m_state);
|
||||
}
|
||||
}
|
||||
@ -173,25 +173,25 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
m_lastAction = IsleScript::c_noneIsle;
|
||||
}
|
||||
else if (objectId == IsleScript::c_hho027en_RunAnim) {
|
||||
m_state->m_unk0x08 = 1;
|
||||
m_state->m_state = AmbulanceMissionState::e_enteredAmbulance;
|
||||
CurrentWorld()->PlaceActor(UserActor());
|
||||
HandleClick();
|
||||
m_unk0x172 = 0;
|
||||
m_enableRandomAudio = 0;
|
||||
TickleManager()->RegisterClient(this, 40000);
|
||||
}
|
||||
else if (objectId == IsleScript::c_hpz047pe_RunAnim || objectId == IsleScript::c_hpz048pe_RunAnim || objectId == IsleScript::c_hpz049bd_RunAnim || objectId == IsleScript::c_hpz053pa_RunAnim) {
|
||||
if (m_unk0x170 == 3) {
|
||||
if (m_taskState == Ambulance::e_finished) {
|
||||
PlayAnimation(IsleScript::c_hpz055pa_RunAnim);
|
||||
m_unk0x170 = 0;
|
||||
m_taskState = Ambulance::e_none;
|
||||
}
|
||||
else {
|
||||
PlayAnimation(IsleScript::c_hpz053pa_RunAnim);
|
||||
}
|
||||
}
|
||||
else if (objectId == IsleScript::c_hpz050bd_RunAnim || objectId == IsleScript::c_hpz052ma_RunAnim) {
|
||||
if (m_unk0x170 == 3) {
|
||||
if (m_taskState == Ambulance::e_finished) {
|
||||
PlayAnimation(IsleScript::c_hpz057ma_RunAnim);
|
||||
m_unk0x170 = 0;
|
||||
m_taskState = Ambulance::e_none;
|
||||
}
|
||||
else {
|
||||
PlayAnimation(IsleScript::c_hpz052ma_RunAnim);
|
||||
@ -201,21 +201,21 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
CurrentWorld()->PlaceActor(UserActor());
|
||||
HandleClick();
|
||||
SpawnPlayer(LegoGameState::e_pizzeriaExterior, TRUE, 0);
|
||||
m_unk0x172 = 0;
|
||||
m_enableRandomAudio = 0;
|
||||
TickleManager()->RegisterClient(this, 40000);
|
||||
|
||||
if (m_unk0x16c != 0) {
|
||||
if (m_atPoliceTask != 0) {
|
||||
StopActions();
|
||||
}
|
||||
}
|
||||
else if (objectId == IsleScript::c_hps116bd_RunAnim || objectId == IsleScript::c_hps118re_RunAnim) {
|
||||
if (objectId == IsleScript::c_hps116bd_RunAnim && m_unk0x170 != 3) {
|
||||
if (objectId == IsleScript::c_hps116bd_RunAnim && m_taskState != Ambulance::e_finished) {
|
||||
PlayAction(IsleScript::c_Avo923In_PlayWav);
|
||||
}
|
||||
|
||||
if (m_unk0x170 == 3) {
|
||||
if (m_taskState == Ambulance::e_finished) {
|
||||
PlayAnimation(IsleScript::c_hps117bd_RunAnim);
|
||||
m_unk0x170 = 0;
|
||||
m_taskState = Ambulance::e_none;
|
||||
}
|
||||
else {
|
||||
PlayAnimation(IsleScript::c_hps118re_RunAnim);
|
||||
@ -225,15 +225,15 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
CurrentWorld()->PlaceActor(UserActor());
|
||||
HandleClick();
|
||||
SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0);
|
||||
m_unk0x172 = 0;
|
||||
m_enableRandomAudio = 0;
|
||||
TickleManager()->RegisterClient(this, 40000);
|
||||
|
||||
if (m_unk0x16e != 0) {
|
||||
if (m_atBeachTask != 0) {
|
||||
StopActions();
|
||||
}
|
||||
}
|
||||
else if (objectId == IsleScript::c_hho142cl_RunAnim || objectId == IsleScript::c_hho143cl_RunAnim || objectId == IsleScript::c_hho144cl_RunAnim) {
|
||||
FUN_10037250();
|
||||
Reset();
|
||||
}
|
||||
}
|
||||
|
||||
@ -244,18 +244,18 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
// FUNCTION: BETA10 0x100230bf
|
||||
MxLong Ambulance::HandleButtonDown(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
if (m_unk0x170 == 1) {
|
||||
if (m_taskState == Ambulance::e_waiting) {
|
||||
LegoROI* roi = PickROI(p_param.GetX(), p_param.GetY());
|
||||
|
||||
if (roi != NULL && !SDL_strcasecmp(roi->GetName(), "ps-gate")) {
|
||||
m_unk0x170 = 3;
|
||||
m_taskState = Ambulance::e_finished;
|
||||
return 1;
|
||||
}
|
||||
|
||||
roi = PickRootROI(p_param.GetX(), p_param.GetY());
|
||||
|
||||
if (roi != NULL && !SDL_strcasecmp(roi->GetName(), "gd")) {
|
||||
m_unk0x170 = 3;
|
||||
m_taskState = Ambulance::e_finished;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
@ -273,9 +273,9 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
}
|
||||
|
||||
if (p_param.GetTrigger() == LegoPathStruct::c_camAnim && p_param.GetData() == 0x0b) {
|
||||
if (m_unk0x16e != 0) {
|
||||
if (m_unk0x16c != 0) {
|
||||
m_state->m_unk0x08 = 2;
|
||||
if (m_atBeachTask != 0) {
|
||||
if (m_atPoliceTask != 0) {
|
||||
m_state->m_state = AmbulanceMissionState::e_prepareAmbulance;
|
||||
|
||||
if (m_lastAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
|
||||
@ -300,7 +300,7 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (m_unk0x16e != 0) {
|
||||
if (m_atBeachTask != 0) {
|
||||
if (m_lastAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
|
||||
}
|
||||
@ -310,7 +310,7 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
}
|
||||
}
|
||||
|
||||
if (m_unk0x16c != 0) {
|
||||
if (m_atPoliceTask != 0) {
|
||||
if (m_lastAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
|
||||
}
|
||||
@ -318,9 +318,9 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
PlayAction(IsleScript::c_Avo915In_PlayWav);
|
||||
}
|
||||
}
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x131 && m_unk0x16e == 0) {
|
||||
m_unk0x16e = 1;
|
||||
m_unk0x170 = 1;
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_s && p_param.GetData() == 0x131 && m_atBeachTask == 0) {
|
||||
m_atBeachTask = 1;
|
||||
m_taskState = Ambulance::e_waiting;
|
||||
|
||||
if (m_lastAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
|
||||
@ -348,9 +348,9 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_camAnim && (p_param.GetData() == 0x22 || p_param.GetData() == 0x23 || p_param.GetData() == 0x24) && m_unk0x16c == 0) {
|
||||
m_unk0x16c = 1;
|
||||
m_unk0x170 = 1;
|
||||
else if (p_param.GetTrigger() == LegoPathStruct::c_camAnim && (p_param.GetData() == 0x22 || p_param.GetData() == 0x23 || p_param.GetData() == 0x24) && m_atPoliceTask == 0) {
|
||||
m_atPoliceTask = 1;
|
||||
m_taskState = Ambulance::e_waiting;
|
||||
|
||||
if (m_lastAction != IsleScript::c_noneIsle) {
|
||||
InvokeAction(Extra::e_stop, *g_isleScript, m_lastAction, NULL);
|
||||
@ -367,15 +367,15 @@ MxLong Ambulance::HandlePathStruct(LegoPathStructNotificationParam& p_param)
|
||||
// FUNCTION: BETA10 0x10023506
|
||||
MxLong Ambulance::HandleClick()
|
||||
{
|
||||
if (((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 != 10) {
|
||||
if (((Act1State*) GameState()->GetState("Act1State"))->m_state != Act1State::e_ambulance) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (m_state->m_unk0x08 == 2) {
|
||||
if (m_state->m_state == AmbulanceMissionState::e_prepareAmbulance) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FUN_10015820(TRUE, 0);
|
||||
Disable(TRUE, 0);
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_ambulance);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
|
||||
@ -390,7 +390,7 @@ MxLong Ambulance::HandleClick()
|
||||
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_AmbulanceDashboard, NULL);
|
||||
ControlManager()->Register(this);
|
||||
|
||||
if (m_state->m_unk0x08 == 1) {
|
||||
if (m_state->m_state == AmbulanceMissionState::e_enteredAmbulance) {
|
||||
SpawnPlayer(LegoGameState::e_hospitalExited, TRUE, 0);
|
||||
m_state->m_startTime = Timer()->GetTime();
|
||||
InvokeAction(Extra::e_start, *g_isleScript, IsleScript::c_pns018rd_RunAnim, NULL);
|
||||
@ -401,9 +401,9 @@ MxLong Ambulance::HandleClick()
|
||||
|
||||
// FUNCTION: LEGO1 0x10036e60
|
||||
// FUNCTION: BETA10 0x100236bb
|
||||
void Ambulance::FUN_10036e60()
|
||||
void Ambulance::Init()
|
||||
{
|
||||
m_state->m_unk0x08 = 2;
|
||||
m_state->m_state = AmbulanceMissionState::e_prepareAmbulance;
|
||||
PlayAnimation(IsleScript::c_hho027en_RunAnim);
|
||||
m_lastAction = IsleScript::c_noneIsle;
|
||||
m_lastAnimation = IsleScript::c_noneIsle;
|
||||
@ -414,7 +414,7 @@ void Ambulance::Exit()
|
||||
{
|
||||
GameState()->m_currentArea = LegoGameState::e_hospitalExterior;
|
||||
StopActions();
|
||||
FUN_10037250();
|
||||
Reset();
|
||||
Leave();
|
||||
}
|
||||
|
||||
@ -440,7 +440,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_param.m_unk0x28 == 1) {
|
||||
if (p_param.m_enabledChild == 1) {
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_AmbulanceArms_Ctl:
|
||||
Exit();
|
||||
@ -457,7 +457,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
case IsleScript::c_AmbulanceHorn_Ctl:
|
||||
MxSoundPresenter* presenter =
|
||||
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "AmbulanceHorn_Sound");
|
||||
presenter->Enable(p_param.m_unk0x28);
|
||||
presenter->Enable(p_param.m_enabledChild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -470,11 +470,11 @@ void Ambulance::ActivateSceneActions()
|
||||
{
|
||||
PlayMusic(JukeboxScript::c_Hospital_Music);
|
||||
|
||||
if (m_state->m_unk0x08 == 1) {
|
||||
m_state->m_unk0x08 = 0;
|
||||
if (m_state->m_state == AmbulanceMissionState::e_enteredAmbulance) {
|
||||
m_state->m_state = AmbulanceMissionState::e_ready;
|
||||
PlayAction(IsleScript::c_ham033cl_PlayWav);
|
||||
}
|
||||
else if (m_unk0x16c != 0 && m_unk0x16e != 0) {
|
||||
else if (m_atPoliceTask != 0 && m_atBeachTask != 0) {
|
||||
IsleScript::Script objectId;
|
||||
|
||||
switch (SDL_rand(2)) {
|
||||
@ -516,8 +516,8 @@ void Ambulance::ActivateSceneActions()
|
||||
// FUNCTION: BETA10 0x100237df
|
||||
MxResult Ambulance::Tickle()
|
||||
{
|
||||
if (m_unk0x172 == 0) {
|
||||
m_unk0x172 = 1;
|
||||
if (m_enableRandomAudio == 0) {
|
||||
m_enableRandomAudio = 1;
|
||||
}
|
||||
else if (m_lastAction == IsleScript::c_noneIsle) {
|
||||
IsleScript::Script objectId;
|
||||
@ -574,14 +574,14 @@ void Ambulance::StopActions()
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10037250
|
||||
void Ambulance::FUN_10037250()
|
||||
void Ambulance::Reset()
|
||||
{
|
||||
StopAction(m_lastAction);
|
||||
BackgroundAudioManager()->RaiseVolume();
|
||||
((Act1State*) GameState()->GetState("Act1State"))->m_unk0x018 = 0;
|
||||
m_state->m_unk0x08 = 0;
|
||||
m_unk0x16e = 0;
|
||||
m_unk0x16c = 0;
|
||||
((Act1State*) GameState()->GetState("Act1State"))->m_state = Act1State::e_none;
|
||||
m_state->m_state = AmbulanceMissionState::e_ready;
|
||||
m_atBeachTask = 0;
|
||||
m_atPoliceTask = 0;
|
||||
g_isleFlags |= Isle::c_playMusic;
|
||||
AnimationManager()->EnableCamAnims(TRUE);
|
||||
AnimationManager()->FUN_1005f6d0(TRUE);
|
||||
@ -629,7 +629,7 @@ void Ambulance::PlayAction(IsleScript::Script p_objectId)
|
||||
// FUNCTION: LEGO1 0x100373a0
|
||||
AmbulanceMissionState::AmbulanceMissionState()
|
||||
{
|
||||
m_unk0x08 = 0;
|
||||
m_state = AmbulanceMissionState::e_ready;
|
||||
m_startTime = 0;
|
||||
m_peScore = 0;
|
||||
m_maScore = 0;
|
||||
|
||||
@ -52,9 +52,9 @@ void Bike::Exit()
|
||||
// FUNCTION: LEGO1 0x100769a0
|
||||
MxLong Bike::HandleClick()
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
FUN_10015820(TRUE, 0);
|
||||
Disable(TRUE, 0);
|
||||
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::Area::e_bike);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE);
|
||||
@ -81,7 +81,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_param.m_unk0x28 == 1) {
|
||||
if (p_param.m_enabledChild == 1) {
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_BikeArms_Ctl:
|
||||
Exit();
|
||||
@ -97,7 +97,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
case IsleScript::c_BikeHorn_Ctl:
|
||||
MxSoundPresenter* presenter =
|
||||
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "BikeHorn_Sound");
|
||||
presenter->Enable(p_param.m_unk0x28);
|
||||
presenter->Enable(p_param.m_enabledChild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
isle->SetDestLocation(LegoGameState::Area::e_infomain);
|
||||
|
||||
Act1State* act1state = (Act1State*) GameState()->GetState("Act1State");
|
||||
act1state->SetUnknown18(0);
|
||||
act1state->SetState(Act1State::e_none);
|
||||
break;
|
||||
}
|
||||
case LegoGameState::Act::e_act2: {
|
||||
@ -80,11 +80,11 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x100151d0
|
||||
MxLong GasStationEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
|
||||
if (state->GetUnknown18() != 8) {
|
||||
state->SetUnknown18(0);
|
||||
if (state->GetState() != Act1State::e_towtrack) {
|
||||
state->SetState(Act1State::e_none);
|
||||
|
||||
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
|
||||
((IslePathActor*) UserActor())->Exit();
|
||||
@ -104,11 +104,11 @@ MxLong GasStationEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x10015270
|
||||
MxLong HospitalEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
|
||||
|
||||
if (act1State->GetUnknown18() != 10) {
|
||||
act1State->SetUnknown18(0);
|
||||
if (act1State->GetState() != Act1State::e_ambulance) {
|
||||
act1State->SetState(Act1State::e_none);
|
||||
|
||||
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
|
||||
((IslePathActor*) UserActor())->Exit();
|
||||
@ -128,11 +128,11 @@ MxLong HospitalEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x10015310
|
||||
MxLong PoliceEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
|
||||
if (state->GetUnknown18() != 10) {
|
||||
state->SetUnknown18(0);
|
||||
if (state->GetState() != Act1State::e_ambulance) {
|
||||
state->SetState(Act1State::e_none);
|
||||
|
||||
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
|
||||
((IslePathActor*) UserActor())->Exit();
|
||||
@ -152,9 +152,9 @@ MxLong PoliceEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x100153b0
|
||||
MxLong BeachHouseEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
state->SetUnknown18(0);
|
||||
state->SetState(Act1State::e_none);
|
||||
|
||||
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
|
||||
((IslePathActor*) UserActor())->Exit();
|
||||
@ -173,9 +173,9 @@ MxLong BeachHouseEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: LEGO1 0x10015450
|
||||
MxLong RaceStandsEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
Act1State* state = (Act1State*) GameState()->GetState("Act1State");
|
||||
state->SetUnknown18(0);
|
||||
state->SetState(Act1State::e_none);
|
||||
|
||||
if (UserActor()->GetActorId() != GameState()->GetActorId()) {
|
||||
((IslePathActor*) UserActor())->Exit();
|
||||
@ -195,7 +195,7 @@ MxLong RaceStandsEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
// FUNCTION: BETA10 0x100256e8
|
||||
MxLong JailEntity::HandleClick(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
if (FUN_1003ef60()) {
|
||||
if (CanExit()) {
|
||||
PlayCamAnim(UserActor(), FALSE, 18, TRUE);
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +45,7 @@ MxLong BumpBouy::Notify(MxParam& p_param)
|
||||
|
||||
Act1State* isleState = (Act1State*) GameState()->GetState("Act1State");
|
||||
assert(isleState);
|
||||
isleState->m_unk0x018 = 5;
|
||||
isleState->m_state = Act1State::e_transitionToJetski;
|
||||
|
||||
Isle* isle = (Isle*) FindWorld(*g_isleScript, IsleScript::c__Isle);
|
||||
assert(isle);
|
||||
|
||||
@ -91,11 +91,11 @@ void DuneBuggy::Exit()
|
||||
// FUNCTION: LEGO1 0x10068060
|
||||
MxLong DuneBuggy::HandleClick()
|
||||
{
|
||||
if (!FUN_1003ef60()) {
|
||||
if (!CanExit()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FUN_10015820(TRUE, 0);
|
||||
Disable(TRUE, 0);
|
||||
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::Area::e_dunecar);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE);
|
||||
@ -124,7 +124,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_param.m_unk0x28 == 1) {
|
||||
if (p_param.m_enabledChild == 1) {
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_DuneCarArms_Ctl:
|
||||
Exit();
|
||||
@ -140,7 +140,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
case IsleScript::c_DuneCarHorn_Ctl:
|
||||
MxSoundPresenter* presenter =
|
||||
(MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound");
|
||||
presenter->Enable(p_param.m_unk0x28);
|
||||
presenter->Enable(p_param.m_enabledChild);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ void Helicopter::Exit()
|
||||
|
||||
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk40,
|
||||
LegoGameState::e_helicopterSpawn,
|
||||
TRUE,
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
@ -121,7 +121,7 @@ void Helicopter::Exit()
|
||||
// FUNCTION: BETA10 0x1002a3db
|
||||
MxLong Helicopter::HandleClick()
|
||||
{
|
||||
if (!FUN_1003ef60()) {
|
||||
if (!CanExit()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -148,7 +148,7 @@ MxLong Helicopter::HandleClick()
|
||||
IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3
|
||||
);
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_copter);
|
||||
FUN_10015820(TRUE, 0);
|
||||
Disable(TRUE, 0);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE);
|
||||
SetActorState(c_disabled);
|
||||
PlayMusic(JukeboxScript::c_Jail_Music);
|
||||
@ -189,7 +189,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
break;
|
||||
}
|
||||
|
||||
if (p_param.m_unk0x28 == 1) {
|
||||
if (p_param.m_enabledChild == 1) {
|
||||
MxU32 isPizza = FALSE;
|
||||
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
@ -214,7 +214,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
|
||||
assert(act1State);
|
||||
if (m_state->m_unk0x08 == 0) {
|
||||
act1State->m_unk0x018 = 4;
|
||||
act1State->m_state = Act1State::e_helicopter;
|
||||
m_state->m_unk0x08 = 1;
|
||||
m_world->RemoveActor(this);
|
||||
InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterTakeOff_Anim, NULL);
|
||||
@ -318,7 +318,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
|
||||
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
|
||||
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
|
||||
assert(act1State);
|
||||
act1State->m_unk0x018 = 4;
|
||||
act1State->m_state = Act1State::e_helicopter;
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk42,
|
||||
TRUE,
|
||||
@ -359,7 +359,7 @@ MxLong Helicopter::HandleEndAnim(LegoEndAnimNotificationParam& p_param)
|
||||
if (GameState()->GetCurrentAct() == LegoGameState::e_act1) {
|
||||
Act1State* act1State = (Act1State*) GameState()->GetState("Act1State");
|
||||
assert(act1State);
|
||||
act1State->m_unk0x018 = 0;
|
||||
act1State->m_state = Act1State::e_none;
|
||||
SpawnPlayer(
|
||||
LegoGameState::e_unk41,
|
||||
TRUE,
|
||||
@ -426,7 +426,7 @@ void Helicopter::Animate(float p_time)
|
||||
v2 *= f2;
|
||||
v2 += v1;
|
||||
|
||||
m_world->GetCameraController()->FUN_100123e0(mat, 0);
|
||||
m_world->GetCameraController()->TransformPointOfView(mat, 0);
|
||||
}
|
||||
else {
|
||||
if (m_state->m_unk0x08 == 4) {
|
||||
@ -459,7 +459,7 @@ void Helicopter::FUN_100042a0(const Matrix4& p_matrix)
|
||||
// the typecast makes this function match for unknown reasons
|
||||
Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28
|
||||
|
||||
m_world->GetCameraController()->FUN_100123b0(local48);
|
||||
m_world->GetCameraController()->GetPointOfView(local48);
|
||||
m_unk0x1a8.SetIdentity();
|
||||
local90 = p_matrix;
|
||||
|
||||
|
||||
@ -153,7 +153,7 @@ void IslePathActor::Exit()
|
||||
|
||||
FUN_1001b660();
|
||||
FUN_10010c30();
|
||||
FUN_1003eda0();
|
||||
ResetViewVelocity();
|
||||
}
|
||||
|
||||
// GLOBAL: LEGO1 0x10102b28
|
||||
@ -355,7 +355,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_PoliceStation_Music
|
||||
);
|
||||
g_spawnLocations[16] = SpawnLocation(
|
||||
LegoGameState::e_unk40,
|
||||
LegoGameState::e_helicopterSpawn,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg02_51",
|
||||
@ -379,7 +379,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[18] = SpawnLocation(
|
||||
LegoGameState::e_unk43,
|
||||
LegoGameState::e_dunebuggySpawn,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg02_35",
|
||||
@ -391,7 +391,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[19] = SpawnLocation(
|
||||
LegoGameState::e_unk44,
|
||||
LegoGameState::e_racecarSpawn,
|
||||
g_isleScript,
|
||||
0,
|
||||
"EDG03_01",
|
||||
@ -403,7 +403,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[20] = SpawnLocation(
|
||||
LegoGameState::e_unk45,
|
||||
LegoGameState::e_jetskiSpawn,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg10_70",
|
||||
@ -475,7 +475,7 @@ void IslePathActor::RegisterSpawnLocations()
|
||||
JukeboxScript::c_noneJukebox
|
||||
);
|
||||
g_spawnLocations[26] = SpawnLocation(
|
||||
LegoGameState::e_unk52,
|
||||
LegoGameState::e_towTrackHookedUp,
|
||||
g_isleScript,
|
||||
0,
|
||||
"edg02_19",
|
||||
@ -598,7 +598,7 @@ void IslePathActor::SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8
|
||||
}
|
||||
|
||||
if (m_cameraFlag) {
|
||||
FUN_1003eda0();
|
||||
ResetViewVelocity();
|
||||
}
|
||||
|
||||
if (p_flags & c_playMusic && g_spawnLocations[i].m_music != JukeboxScript::c_noneJukebox) {
|
||||
@ -632,7 +632,7 @@ void IslePathActor::VTable0xec(MxMatrix p_transform, LegoPathBoundary* p_boundar
|
||||
|
||||
m_roi->SetLocal2World(p_transform);
|
||||
if (m_cameraFlag) {
|
||||
FUN_1003eda0();
|
||||
ResetViewVelocity();
|
||||
FUN_10010c30();
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,7 +69,7 @@ void Jetski::Animate(float p_time)
|
||||
// FUNCTION: LEGO1 0x1007e6f0
|
||||
void Jetski::Exit()
|
||||
{
|
||||
SpawnPlayer(LegoGameState::e_unk45, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3);
|
||||
SpawnPlayer(LegoGameState::e_jetskiSpawn, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3);
|
||||
IslePathActor::Exit();
|
||||
GameState()->m_currentArea = LegoGameState::e_jetski;
|
||||
RemoveFromWorld();
|
||||
@ -83,11 +83,11 @@ void Jetski::Exit()
|
||||
MxLong Jetski::HandleClick()
|
||||
{
|
||||
#ifndef BETA10
|
||||
if (!FUN_1003ef60()) {
|
||||
if (!CanExit()) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FUN_10015820(TRUE, 0);
|
||||
Disable(TRUE, 0);
|
||||
|
||||
((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::Area::e_jetski);
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE);
|
||||
@ -139,7 +139,7 @@ void Jetski::RemoveFromWorld()
|
||||
// FUNCTION: LEGO1 0x1007e8e0
|
||||
MxLong Jetski::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
{
|
||||
if (p_param.m_unk0x28 == 1 && CurrentWorld()->IsA("Isle")) {
|
||||
if (p_param.m_enabledChild == 1 && CurrentWorld()->IsA("Isle")) {
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case IsleScript::c_JetskiArms_Ctl:
|
||||
Exit();
|
||||
@ -164,7 +164,7 @@ void Jetski::ActivateSceneActions()
|
||||
PlayMusic(JukeboxScript::c_JetskiRace_Music);
|
||||
|
||||
Act1State* act1state = (Act1State*) GameState()->GetState("Act1State");
|
||||
if (!act1state->m_unk0x018) {
|
||||
if (!act1state->m_state) {
|
||||
if (act1state->m_unk0x022) {
|
||||
PlayCamAnim(this, FALSE, 68, TRUE);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user