Author SHA1 Message Date
ThePixelMoonandGitHub 87c9733e09 Merge pull request #80 from zukrmn/fix/linux-compiler-warnings
fix: resolve high-severity Linux compiler warnings
2026-03-07 03:23:05 +02:00
zukrmn e3fc6ebe52 fix: resolve high-severity Linux compiler warnings 2026-03-06 22:57:02 +00:00
Leah AndersonandGitHub 41314fa873 Merge pull request #72 from MrShrekThird/dev
Update CONTRIBUTING.md
2026-03-06 11:41:18 -07:00
MrShrekThirdandGitHub 04cadcf953 Removed README.md link lol 2026-03-06 18:37:31 +00:00
MrShrekThirdandGitHub daf43609ca Update CONTRIBUTING.md with README link
Added a note to visit README.md for compilation instructions.
2026-03-06 18:25:52 +00:00
MrShrekThirdandGitHub 42e84f9f4a Update CONTRIBUTING.md
Removed outdated and redundant compilation instructions.
2026-03-06 18:19:13 +00:00
JuiceyDevandGitHub dc57bf5634 Merge pull request #62 from 4jcraft/fix/byte-typealias
fix: remove `byte` type alias
2026-03-06 18:40:36 +01:00
JuiceyDevandGitHub a875a6ef98 Merge pull request #69 from 4jcraft/refactor/optional-llvm-toolchain
refactor(build): make `lld` optional and recommend clang/llvm in README
2026-03-06 18:35:19 +01:00
Tropical 79404297d1 docs: remove mention of discord server unavailability 2026-03-06 11:07:07 -06:00
Tropical 6778dc7f92 refactor(build): make lld optional and recommend clang/llvm in README 2026-03-06 10:26:49 -06:00
JuiceyDevandGitHub 14aeba8992 Merge pull request #67 from zukrmn/add-devcontainer-and-fix-deps
docs: add devcontainer and missing libpng-dev dependency
2026-03-06 16:46:27 +01:00
zukrmn ff7276be18 docs: add devcontainer and missing libpng-dev dependency 2026-03-06 15:30:21 +00:00
ThePixelMoon a0c92dacc6 4J.Render: use stb_image 2026-03-06 14:54:55 +02:00
Tropical 0dd1654dec docs: undo accidental comment replacement 2026-03-06 05:13:40 -06:00
Tropical b8c4e96409 fix: more replacement mistakes 2026-03-06 05:09:17 -06:00
Tropical 6c56d884e5 fix: undo some mistakes 2026-03-06 05:06:27 -06:00
Tropical 15af35eef2 fix: remove byte type alias 2026-03-06 05:03:37 -06:00
DecalOverdoseandGitHub 09eae49d21 Merge pull request #48 from create-juicey-app/dev
hmmm forkss yum.. hmmmhpph.. hmmh yummy
2026-03-06 14:08:10 +04:00
JuiceyDev 3f7249d5e5 datastream 2026-03-06 11:03:12 +01:00
JuiceyDev 76b441dd91 network packet 2026-03-06 10:51:07 +01:00
Tropical 29cc47183f Merge remote-tracking branch 'origin/dev' into create-juicey-app/dev 2026-03-06 03:43:13 -06:00
JuiceyDev d99ef6a1b8 socket UGUHH 2026-03-06 10:28:41 +01:00
JuiceyDev 38cc63e441 ci: build and bundle debug binary alongside release 2026-03-06 10:07:32 +01:00
Tropical edb475212c docs: clarify that Common needs to be at the cwd 2026-03-06 02:38:40 -06:00
JuiceyDev 6928c42b1a ci: upload dir directly (no tar.gz), exclude libc/glibc from bundled libs 2026-03-06 09:14:21 +01:00
Tropical 546042c8b1 docs: remove redundant sentence about windows crosscompilation 2026-03-06 02:03:22 -06:00
Tropical 29346e056c chore: nuke CMake and visual studio solutions
bye
2026-03-06 02:01:20 -06:00
JuiceyDev 8a334fb5c0 ci: only trigger on source/build file changes, not docs/README 2026-03-06 08:57:31 +01:00
Tropical ab6387ea7e docs: clarify binary location 2026-03-06 01:55:06 -06:00
Tropical 50f433b932 docs: add lld install instructions 2026-03-06 01:52:26 -06:00
JuiceyDev ce988d99f5 ci: bundle binary + shared libs + run.sh + README in artifact 2026-03-06 08:51:57 +01:00
JuiceyDev d5db5cc071 fix: guard CXuiStringTable StringTable global from Linux unity builds to prevent class shadowing 2026-03-06 08:43:47 +01:00
Tropical 35b0781f47 docs: add instructions to hard reset builddir 2026-03-06 01:33:29 -06:00
JuiceyDev 57ed1aab14 fix: prevent zlib Byte typedef clash with project class Byte under clang 2026-03-06 08:32:04 +01:00
Tropical 379d7d9ee5 docs: move running section below 2026-03-06 01:30:48 -06:00
Tropical 09721f8c91 docs: add instructions for checking GCC version 2026-03-06 01:29:03 -06:00
Tropical 1a8a969ef8 docs: update README with new build instructions 2026-03-06 01:24:25 -06:00
JuiceyDev e7f98a2410 fix: use system zlib in Minecraft.World to avoid Byte typedef conflict with clang unity build 2026-03-06 08:24:07 +01:00
JuiceyDev bafbdc62a1 bwbwa 2026-03-06 08:10:29 +01:00
JuiceyDev 50d28ade69 filez 2026-03-06 08:03:07 +01:00
JuiceyDev 834e0e6e72 Merge branch 'dev' of https://github.com/create-juicey-app/4jcraft-juicefork into dev 2026-03-06 07:31:28 +01:00
JuiceyDev 9dd73aaa0d udjfjdkd 2026-03-06 07:31:16 +01:00
Tropical 953d7257d3 Merge branch 'dev' of https://github.com/create-juicey-app/4jcraft-juicefork into juice-dev 2026-03-06 00:18:34 -06:00
Tropical 7baf1cbfa1 refactor: clean up meson build scripts, use in-tree zlib 2026-03-06 00:17:31 -06:00
JuiceyDev 17ac8deddf hhhhh 2026-03-06 07:13:57 +01:00
JuiceyDev fa88145b1f aye fuck off 2026-03-06 06:42:23 +01:00
JuiceyDev 24ee5b5455 the architect and the builder 2026-03-06 06:38:24 +01:00
JuiceyDev c55ed7b261 game compiles 2026-03-06 06:13:22 +01:00
JuiceyDev 5b45dacb1c added basic CI 2026-03-06 02:05:15 +01:00
JuiceyDev baab1724ff fix include 2026-03-06 02:02:49 +01:00
JuiceyDev b04a2369b6 meson basic intergration 2026-03-06 01:59:57 +01:00
JuiceyDev dd43a13f74 Merge branch 'dev' of https://github.com/create-juicey-app/4jcraft-juicefork into dev 2026-03-06 00:34:40 +01:00
JuiceyDev fddd777399 fixed font 2026-03-06 00:34:36 +01:00
JuiceyDevandGitHub 423a9f5fca Fix formatting of CMake reset instructions in README 2026-03-06 00:33:13 +01:00
JuiceyDevandGitHub 1848accdb7 added temp indicator 2026-03-06 00:32:28 +01:00
JuiceyDev 1f37e1d422 some updates 2026-03-06 00:28:53 +01:00
JuiceyDev 2f7962cbb2 woah 2026-03-06 00:19:13 +01:00
JuiceyDev 65a9c99215 YES PLEASE 2026-03-06 00:01:26 +01:00
JuiceyDev fa9d517227 fdkgsekgdqsgf 2026-03-05 23:37:27 +01:00
JuiceyDevandGitHub 06afba4d34 Merge branch 'dev' into dev 2026-03-05 22:33:38 +01:00
JuiceyDev c43ccdf441 e 2026-03-05 22:28:28 +01:00
JuiceyDev 6b6fa9a6b0 find my renderers - slenderman or some shit 2026-03-05 22:28:13 +01:00
JuiceyDev ad50bf21d4 shit renderer 2026-03-05 21:31:54 +01:00
JuiceyDev 60ad8c291e fuck you git 2026-03-05 20:31:54 +01:00
JuiceyDev a8846c9f46 larp renderer 2026-03-05 20:27:14 +01:00
JuiceyDev c391d290ec Networking Fixes & Updates 2026-03-05 20:03:06 +01:00
JuiceyDev 44b4ba84c2 Horrible code alert 2026-03-05 19:06:07 +01:00
JuiceyDev cb4e0e82b7 Basic IGGY renderer implementation, do not PR. 2026-03-05 16:54:56 +01:00
JuiceyDev 299564be0a FIX 2026-03-05 14:07:07 +01:00
JuiceyDev a1f1681ce7 Starting IGGY impl 2026-03-05 14:02:05 +01:00
JuiceyDev e7dfce35d4 feat: enhance Linux rendering support and clean up unused UI code 2026-03-05 13:31:12 +01:00
JuiceyDev 470308f177 chore: gitignore Linux/ build output, Common symlink, x64/ 2026-03-05 11:49:42 +01:00
JuiceyDev 6c5a675f3c fix: correct stale include paths after folder refactor 2026-03-05 11:40:43 +01:00
JuiceyDev 70a5f01070 feat: OpenGL rendering implementation (GLFW/OpenGL 2.1 pipeline) 2026-03-05 11:18:20 +01:00
632 changed files with 86763 additions and 8892 deletions
+36
View File
@@ -0,0 +1,36 @@
FROM mcr.microsoft.com/devcontainers/cpp:1-ubuntu-24.04
ENV DEBIAN_FRONTEND=noninteractive
# Dependencies
RUN apt-get update \
&& apt-get install -y software-properties-common \
&& add-apt-repository -y ppa:ubuntu-toolchain-r/test \
&& apt-get update \
&& apt-get install -y \
build-essential \
cmake \
libglfw3-dev \
libgl-dev \
libglu1-mesa-dev \
libopenal-dev \
libvorbis-dev \
libpng-dev \
libpthread-stubs0-dev \
lld \
meson \
ninja-build \
gcc-15 \
g++-15 \
# Clean up lol
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/*
# Set GCC 15 as default
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 100 \
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 100 \
&& update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 100 \
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100
ENV DEBIAN_FRONTEND=dialog
+17
View File
@@ -0,0 +1,17 @@
{
"name": "4JCraft Dev Container",
"build": {
"dockerfile": "Dockerfile"
},
"customizations": {
"vscode": {
"settings": {},
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"mesonbuild.mesonbuild"
]
}
},
"remoteUser": "vscode"
}
+231
View File
@@ -0,0 +1,231 @@
name: Build Linux Release
on:
push:
paths:
- '**.cpp'
- '**.h'
- '**.c'
- '**/meson.build'
- 'meson.build'
- '**/CMakeLists.txt'
- 'CMakeLists.txt'
- '.github/workflows/build-linux.yml'
pull_request:
paths:
- '**.cpp'
- '**.h'
- '**.c'
- '**/meson.build'
- 'meson.build'
- '**/CMakeLists.txt'
- 'CMakeLists.txt'
- '.github/workflows/build-linux.yml'
jobs:
build-linux:
runs-on: ubuntu-latest
concurrency:
group: build-linux-${{ github.ref }}
cancel-in-progress: true
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential python3 python3-pip python3-setuptools libgl1-mesa-dev libglu1-mesa-dev libglfw3-dev libpng-dev pkg-config clang lld ccache libssl-dev
# Set a reasonable ccache size
ccache -M 5G || true
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Cache pip packages
uses: actions/cache@v4
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('.github/workflows/build-linux.yml') }}
- name: Install Meson and Ninja (pip)
run: |
python -m pip install --upgrade pip
pip install meson ninja
- name: Restore ccache
uses: actions/cache@v4
with:
path: ~/.ccache
key: ${{ runner.os }}-ccache-${{ hashFiles('**/meson.build') }}
- name: Restore meson cache
uses: actions/cache@v4
with:
path: ~/.cache/meson
key: ${{ runner.os }}-meson-${{ hashFiles('**/meson.build') }}
- name: Configure Meson
env:
CC: "ccache clang"
CXX: "ccache clang++"
CCACHE_DIR: ${{ runner.temp }}/ccache
run: |
mkdir -p "$CCACHE_DIR"
export CCACHE_DIR="$CCACHE_DIR"
meson setup build_meson --wipe --buildtype=release
- name: Configure Meson (debug)
env:
CC: "ccache clang"
CXX: "ccache clang++"
CCACHE_DIR: ${{ runner.temp }}/ccache
run: |
mkdir -p "$CCACHE_DIR"
export CCACHE_DIR="$CCACHE_DIR"
meson setup build_debug --wipe --buildtype=debug
- name: Build with Ninja
env:
CC: "ccache clang"
CXX: "ccache clang++"
CCACHE_DIR: ${{ runner.temp }}/ccache
run: |
export CCACHE_DIR="${{ runner.temp }}/ccache"
# Use all available cores for faster parallel builds
ninja -C build_meson -j$(nproc) -v
- name: Build Debug with Ninja
env:
CC: "ccache clang"
CXX: "ccache clang++"
CCACHE_DIR: ${{ runner.temp }}/ccache
run: |
export CCACHE_DIR="${{ runner.temp }}/ccache"
ninja -C build_debug -j$(nproc) -v
- name: Install patchelf
run: sudo apt-get install -y patchelf
- name: Bundle executable + libraries
env:
GITHUB_SHA: ${{ github.sha }}
run: |
set -euo pipefail
EXE_PATH=build_meson/Minecraft.Client/Minecraft.Client
if [ ! -f "$EXE_PATH" ]; then
echo "ERROR: expected executable at $EXE_PATH" >&2
ls -la build_meson || true
exit 1
fi
SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-8)
BUNDLE=out/minecraft-client-linux-${SHORT_SHA}
mkdir -p "$BUNDLE/lib"
# Copy the binary
cp "$EXE_PATH" "$BUNDLE/Minecraft.Client"
# Collect non-system shared library dependencies and copy them in.
# Exclude glibc/libstdc++/libgcc — these are ABI-specific and must
# come from the user's system, not from the build runner.
ldd "$EXE_PATH" \
| awk '/=>/ { print $3 }' \
| grep -v '^(' \
| grep -Ev '/(libc|libm|libdl|libpthread|librt|libgcc_s|libstdc\+\+|ld-linux)[^/]*\.so' \
| sort -u \
| while read -r lib; do
[ -f "$lib" ] && cp "$lib" "$BUNDLE/lib/" || true
done
# Patch the binary RPATH so it finds libs in ./lib at runtime
patchelf --set-rpath '$ORIGIN/lib' "$BUNDLE/Minecraft.Client"
# Write a launcher script
cat > "$BUNDLE/run.sh" << 'RUNEOF'
#!/usr/bin/env bash
# 4JCraft Linux launcher
# -------------------------------------------------------------------
# IMPORTANT: Before running, copy the "Common" assets folder from
# https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly
# (LCEWindows64.zip → extract → copy "Common" next to this script)
# -------------------------------------------------------------------
DIR="$(cd "$(dirname "$0")" && pwd)"
if [ ! -d "$DIR/Common" ]; then
echo "ERROR: Missing 'Common' assets folder."
echo "Download LCEWindows64.zip from:"
echo " https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly"
echo "Extract it and copy the 'Common' folder next to this run.sh file."
exit 1
fi
cd "$DIR"
exec ./Minecraft.Client "$@"
RUNEOF
chmod +x "$BUNDLE/run.sh"
# Write a README
cat > "$BUNDLE/README.txt" << 'EOF'
4JCraft Linux Build
===================
This bundle contains:
Minecraft.Client - compiled Linux binary
lib/ - all required shared libraries (GL, GLFW, png, zlib, X11 etc.)
run.sh - launcher script
To run:
1. Download LCEWindows64.zip from the MinecraftConsoles nightly release:
https://github.com/smartcmd/MinecraftConsoles/releases/tag/nightly
2. Extract it and copy the "Common" folder into this directory
(so you have Common/ sitting next to run.sh)
3. Run: ./run.sh [--width W] [--height H] [--fullscreen]
EOF
echo "Bundle ready: $BUNDLE"
ls -lh "$BUNDLE" "$BUNDLE/lib"
- name: Bundle debug executable + libraries
env:
GITHUB_SHA: ${{ github.sha }}
run: |
set -euo pipefail
EXE_PATH=build_debug/Minecraft.Client/Minecraft.Client
if [ ! -f "$EXE_PATH" ]; then
echo "ERROR: expected debug executable at $EXE_PATH" >&2
ls -la build_debug || true
exit 1
fi
SHORT_SHA=$(echo "$GITHUB_SHA" | cut -c1-8)
BUNDLE=out/minecraft-client-linux-${SHORT_SHA}-debug
mkdir -p "$BUNDLE/lib"
# Copy the binary
cp "$EXE_PATH" "$BUNDLE/Minecraft.Client.debug"
# Collect non-system shared library dependencies and copy them in.
ldd "$EXE_PATH" \
| awk '/=>/ { print $3 }' \
| grep -v '^(' \
| grep -Ev '/(libc|libm|libdl|libpthread|librt|libgcc_s|libstdc\+\+|ld-linux)[^/]*\.so' \
| sort -u \
| while read -r lib; do
[ -f "$lib" ] && cp "$lib" "$BUNDLE/lib/" || true
done
# Patch the binary RPATH so it finds libs in ./lib at runtime
patchelf --set-rpath '$ORIGIN/lib' "$BUNDLE/Minecraft.Client.debug"
# Keep a copy of the unstripped debug binary (symbols are already present in debug build)
echo "Debug bundle ready: $BUNDLE"
ls -lh "$BUNDLE" "$BUNDLE/lib"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: minecraft-client-linux-${{ github.sha }}
path: |
out/minecraft-client-linux-*/
out/minecraft-client-linux-*-debug/
retention-days: 7
+49
View File
@@ -0,0 +1,49 @@
name: CI Build
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.x'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential pkg-config ca-certificates curl git \
libgl1-mesa-dev libglu1-mesa-dev libglfw3-dev libpng-dev libx11-dev \
libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libudev-dev
- name: Install Meson and Ninja (pip)
run: |
python -m pip install --upgrade pip
pip install meson ninja
- name: Configure Meson
run: |
meson setup build_meson --wipe --buildtype=release
- name: Build with Ninja
run: |
ninja -C build_meson -v
- name: Package build output
run: |
tar -czf minecraft-binaries.tar.gz -C build_meson .
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: minecraft-binaries
path: minecraft-binaries.tar.gz
+35 -9
View File
@@ -1,24 +1,50 @@
# ----- Build output directories -----
build/ build/
builddir/
.cache/ .cache/
.idea/ .idea/
build_meson/
build_meson2/
build_meson_new/
build_meson_test/
cmake-build-debug/ cmake-build-debug/
# CMake generated # Final binaries and platform output
/Linux/
/x64/
# CMake generated artifacts
CMakeCache.txt CMakeCache.txt
CMakeFiles/ CMakeFiles/
cmake_install.cmake cmake_install.cmake
Makefile Makefile
compile_commands.json
# IDE / editor # Meson generated artifacts (inside source tree, e.g. per-subdir)
*.swp meson-private/
*.swo meson-info/
*~ meson-logs/
.vscode/
*.code-workspace
# Compiled objects / binaries # Compiler/linker intermediates
*.o *.o
*.a *.a
*.so *.so
*.so.*
*.out *.out
*.d
compile_commands.json
# ----- Runtime-created symlinks / scratch -----
# Asset symlink created at runtime for working directory resolution
Common
# ----- Scratch / legacy -----
oldimpl/
# ----- IDE / editor -----
.cache/
.idea/
.vscode/
*.code-workspace
*.swp
*.swo
*~
+530 -28
View File
@@ -1,34 +1,536 @@
// 4J_Input.cpp - GLFW keyboard + mouse input for the Linux port
// Replaces the SDL2 oldimpl with GLFW equivalents.
// Uses glfwGetCurrentContext() to get the window the render manager created,
// avoiding a coupling dependency on 4J_Render.h.
#include "4J_Input.h" #include "4J_Input.h"
#include "../Minecraft.Client/Build/Common/App_enums.h"
#include <GLFW/glfw3.h>
#include <math.h>
#include <string.h>
#include <stdio.h>
C_4JInput InputManager; C_4JInput InputManager;
void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC) {} // ---------------------------------------------------------------------------
void C_4JInput::Tick(void) {} // State - all static to avoid adding new fields to C_4JInput
void C_4JInput::SetDeadzoneAndMovementRange(unsigned int uiDeadzone, unsigned int uiMovementRangeMax) {} // ---------------------------------------------------------------------------
void C_4JInput::SetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction, unsigned int uiActionVal) {}
unsigned int C_4JInput::GetGameJoypadMaps(unsigned char ucMap, unsigned char ucAction) { return 0; } static const int KEY_COUNT = GLFW_KEY_LAST + 1; // 349 on GLFW 3
void C_4JInput::SetJoypadMapVal(int iPad, unsigned char ucMap) {}
unsigned char C_4JInput::GetJoypadMapVal(int iPad) { return 0; } static bool s_keysCurrent[KEY_COUNT] = {};
void C_4JInput::SetJoypadSensitivity(int iPad, float fSensitivity) {} static bool s_keysPrev[KEY_COUNT] = {};
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool bRepeat) { return 0; }
bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction) { return false; } static bool s_mouseLeftCurrent = false, s_mouseLeftPrev = false;
bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction) { return false; } static bool s_mouseRightCurrent = false, s_mouseRightPrev = false;
bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction) { return false; }
void C_4JInput::SetJoypadStickAxisMap(int iPad, unsigned int uiFrom, unsigned int uiTo) {} // Accumulated cursor delta from the GLFW cursor-pos callback.
void C_4JInput::SetJoypadStickTriggerMap(int iPad, unsigned int uiFrom, unsigned int uiTo) {} // Snapshotted into s_frameRelX/Y at Tick() start, then reset to 0.
void C_4JInput::SetKeyRepeatRate(float fRepeatDelaySecs, float fRepeatRateSecs) {} static double s_lastCursorX = 0.0, s_lastCursorY = 0.0;
void C_4JInput::SetDebugSequence(const char *chSequenceA, int(*Func)(LPVOID), LPVOID lpParam) {} static bool s_cursorInitialized = false;
FLOAT C_4JInput::GetIdleSeconds(int iPad) { return 0.0f; } static float s_mouseAccumX = 0.0f, s_mouseAccumY = 0.0f; // callback accumulator
bool C_4JInput::IsPadConnected(int iPad) { return iPad == 0; } static float s_frameRelX = 0.0f, s_frameRelY = 0.0f; // per-frame snapshot
float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay) { return 0.0f; }
float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay) { return 0.0f; } // Scroll wheel
float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay) { return 0.0f; } static float s_scrollAccum = 0.0f; // callback accumulator
float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay) { return 0.0f; } static float s_scrollFrame = 0.0f; // current frame snapshot
unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay) { return 0; } static float s_scrollPrevFrame = 0.0f;
unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay) { return 0; }
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) {} // Mouse lock / menu state
EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR Title, LPCWSTR Text, DWORD dwPad, UINT uiMaxChars, int(*Func)(LPVOID, const bool), LPVOID lpParam, C_4JInput::EKeyboardMode eMode) { return EKeyboard_Cancelled; } static bool s_mouseLocked = false;
static bool s_menuDisplayed[4] = {};
static bool s_prevMenuDisplayed = true; // start as "in menu" so auto-lock triggers after first frame
// Sensitivity: scales raw pixel delta before sqrt-compression
// Smaller value = less mouse movement per pixel
static const float MOUSE_SCALE = 0.012f;
// ---------------------------------------------------------------------------
// GLFW window (obtained lazily via glfwGetCurrentContext on the render thread)
// ---------------------------------------------------------------------------
static GLFWwindow *s_inputWindow = nullptr;
static GLFWwindow *getWindow() {
if (!s_inputWindow) {
s_inputWindow = glfwGetCurrentContext();
}
return s_inputWindow;
}
// ---------------------------------------------------------------------------
// GLFW callbacks
// ---------------------------------------------------------------------------
static void onCursorPos(GLFWwindow * /*w*/, double x, double y) {
if (s_cursorInitialized) {
s_mouseAccumX += (float)(x - s_lastCursorX);
s_mouseAccumY += (float)(y - s_lastCursorY);
} else {
s_cursorInitialized = true;
}
s_lastCursorX = x;
s_lastCursorY = y;
}
static void onScroll(GLFWwindow * /*w*/, double /*xoffset*/, double yoffset) {
s_scrollAccum += (float)yoffset;
}
// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------
static inline bool KDown(int key) {
return (key >= 0 && key < KEY_COUNT) ? s_keysCurrent[key] : false;
}
static inline bool KPressed(int key) {
return (key >= 0 && key < KEY_COUNT) ? (s_keysCurrent[key] && !s_keysPrev[key]) : false;
}
static inline bool KReleased(int key) {
return (key >= 0 && key < KEY_COUNT) ? (!s_keysCurrent[key] && s_keysPrev[key]) : false;
}
static inline bool MouseLDown() { return s_mouseLeftCurrent; }
static inline bool MouseLPressed() { return s_mouseLeftCurrent && !s_mouseLeftPrev; }
static inline bool MouseLReleased() { return !s_mouseLeftCurrent && s_mouseLeftPrev; }
static inline bool MouseRDown() { return s_mouseRightCurrent; }
static inline bool MouseRPressed() { return s_mouseRightCurrent && !s_mouseRightPrev; }
static inline bool MouseRReleased() { return !s_mouseRightCurrent && s_mouseRightPrev; }
static inline bool WheelUp() { return s_scrollFrame > 0.1f; }
static inline bool WheelDown() { return s_scrollFrame < -0.1f; }
static inline bool WheelUpEdge() { return s_scrollFrame > 0.1f && s_scrollPrevFrame <= 0.1f; }
static inline bool WheelDownEdge() { return s_scrollFrame < -0.1f && s_scrollPrevFrame >= -0.1f; }
// Keys to snapshot each Tick (avoid iterating all 349 entries)
static const int s_watchedKeys[] = {
GLFW_KEY_W, GLFW_KEY_A, GLFW_KEY_S, GLFW_KEY_D,
GLFW_KEY_SPACE, GLFW_KEY_LEFT_SHIFT, GLFW_KEY_RIGHT_SHIFT,
GLFW_KEY_E, GLFW_KEY_Q, GLFW_KEY_F,
GLFW_KEY_ESCAPE, GLFW_KEY_ENTER,
GLFW_KEY_F3, GLFW_KEY_F5,
GLFW_KEY_UP, GLFW_KEY_DOWN, GLFW_KEY_LEFT, GLFW_KEY_RIGHT,
GLFW_KEY_PAGE_UP, GLFW_KEY_PAGE_DOWN,
GLFW_KEY_TAB,
GLFW_KEY_LEFT_CONTROL, GLFW_KEY_RIGHT_CONTROL,
GLFW_KEY_1, GLFW_KEY_2, GLFW_KEY_3, GLFW_KEY_4, GLFW_KEY_5,
GLFW_KEY_6, GLFW_KEY_7, GLFW_KEY_8, GLFW_KEY_9,
};
static const int s_watchedKeyCount = (int)(sizeof(s_watchedKeys) / sizeof(s_watchedKeys[0]));
// ---------------------------------------------------------------------------
// C_4JInput::Initialise
// ---------------------------------------------------------------------------
void C_4JInput::Initialise(int /*iInputStateC*/, unsigned char /*ucMapC*/,
unsigned char /*ucActionC*/, unsigned char /*ucMenuActionC*/) {
memset(s_keysCurrent, 0, sizeof(s_keysCurrent));
memset(s_keysPrev, 0, sizeof(s_keysPrev));
memset(s_menuDisplayed, 0, sizeof(s_menuDisplayed));
s_mouseLeftCurrent = s_mouseLeftPrev = false;
s_mouseRightCurrent = s_mouseRightPrev = false;
s_mouseAccumX = s_mouseAccumY = 0.0f;
s_frameRelX = s_frameRelY = 0.0f;
s_scrollAccum = s_scrollFrame = s_scrollPrevFrame = 0.0f;
s_mouseLocked = false;
s_prevMenuDisplayed = true; // triggers auto-lock once game leaves first menu
s_cursorInitialized = false;
GLFWwindow *w = getWindow();
if (w) {
glfwSetCursorPosCallback(w, onCursorPos);
glfwSetScrollCallback(w, onScroll);
// NOTE: GLFW_RAW_MOUSE_MOTION must only be set when cursor mode is
// GLFW_CURSOR_DISABLED (Wayland zwp_relative_pointer_v1 requirement).
// It is activated at the cursor-lock call sites below in Tick().
}
printf("[4J_Input] GLFW input initialised\n");
printf(" WASD=move Mouse=look LMB=attack RMB=use\n");
printf(" Space=jump LShift=sneak E=inventory Q=drop Esc=pause\n");
printf(" F5=3rd-person F3=debug Scroll=hotbar\n");
fflush(stdout);
}
// ---------------------------------------------------------------------------
// C_4JInput::Tick (called once per frame, BEFORE Present / glfwPollEvents)
// ---------------------------------------------------------------------------
void C_4JInput::Tick(void) {
GLFWwindow *w = getWindow();
if (!w) return;
// 1. Save previous frame
memcpy(s_keysPrev, s_keysCurrent, sizeof(s_keysCurrent));
s_mouseLeftPrev = s_mouseLeftCurrent;
s_mouseRightPrev = s_mouseRightCurrent;
s_scrollPrevFrame = s_scrollFrame;
// 2. Snapshot current keyboard state for watched keys
for (int i = 0; i < s_watchedKeyCount; i++) {
int k = s_watchedKeys[i];
s_keysCurrent[k] = (glfwGetKey(w, k) == GLFW_PRESS);
}
// 3. Snapshot and reset scroll accumulator
s_scrollFrame = s_scrollAccum;
s_scrollAccum = 0.0f;
// 4. Mouse-lock management based on menu display state
bool menuNow = s_menuDisplayed[0];
if (menuNow && s_mouseLocked) {
// Re-entered a menu → release mouse cursor
s_mouseLocked = false;
if (glfwRawMouseMotionSupported())
glfwSetInputMode(w, GLFW_RAW_MOUSE_MOTION, GLFW_FALSE);
glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
// Discard stale delta so the view doesn't jerk on re-lock
s_mouseAccumX = s_mouseAccumY = 0.0f;
s_cursorInitialized = false;
}
if (!menuNow && s_prevMenuDisplayed && !s_mouseLocked) {
// Left the menu → lock mouse for look control
s_mouseLocked = true;
glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
// Enable raw (un-accelerated) relative motion now that cursor is disabled.
// On Wayland this activates zwp_relative_pointer_v1 for sub-pixel precise
// mouse deltas; on X11 it bypasses the compositor acceleration curve.
if (glfwRawMouseMotionSupported())
glfwSetInputMode(w, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
s_mouseAccumX = s_mouseAccumY = 0.0f;
s_cursorInitialized = false;
}
s_prevMenuDisplayed = menuNow;
// 5. Snapshot and reset mouse delta from callback
s_frameRelX = s_mouseAccumX;
s_frameRelY = s_mouseAccumY;
s_mouseAccumX = s_mouseAccumY = 0.0f;
// 6. Mouse buttons (only meaningful when locked in-game)
if (s_mouseLocked) {
s_mouseLeftCurrent = (glfwGetMouseButton(w, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
s_mouseRightCurrent = (glfwGetMouseButton(w, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
} else {
// Not locked. Allow a left-click to re-lock (if not in a menu)
bool lclick = (glfwGetMouseButton(w, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
if (!menuNow && lclick) {
s_mouseLocked = true;
glfwSetInputMode(w, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
if (glfwRawMouseMotionSupported())
glfwSetInputMode(w, GLFW_RAW_MOUSE_MOTION, GLFW_TRUE);
s_mouseAccumX = s_mouseAccumY = 0.0f;
s_cursorInitialized = false;
}
s_mouseLeftCurrent = false;
s_mouseRightCurrent = false;
s_frameRelX = s_frameRelY = 0.0f;
}
}
// ---------------------------------------------------------------------------
// ButtonDown is action held this frame?
// ---------------------------------------------------------------------------
bool C_4JInput::ButtonDown(int /*iPad*/, unsigned char ucAction) {
switch (ucAction) {
// ---- Menu navigation ----
case ACTION_MENU_UP: return KDown(GLFW_KEY_UP) || KDown(GLFW_KEY_W);
case ACTION_MENU_DOWN: return KDown(GLFW_KEY_DOWN) || KDown(GLFW_KEY_S);
case ACTION_MENU_LEFT: return KDown(GLFW_KEY_LEFT) || KDown(GLFW_KEY_A);
case ACTION_MENU_RIGHT: return KDown(GLFW_KEY_RIGHT) || KDown(GLFW_KEY_D);
case ACTION_MENU_A:
case ACTION_MENU_OK:
return KDown(GLFW_KEY_ENTER) || KDown(GLFW_KEY_SPACE);
case ACTION_MENU_B:
case ACTION_MENU_CANCEL:
return KDown(GLFW_KEY_ESCAPE);
case ACTION_MENU_X: return KDown(GLFW_KEY_F);
case ACTION_MENU_Y: return KDown(GLFW_KEY_E);
case ACTION_MENU_PAGEUP: return KDown(GLFW_KEY_PAGE_UP) || KDown(GLFW_KEY_LEFT_SHIFT);
case ACTION_MENU_PAGEDOWN: return KDown(GLFW_KEY_PAGE_DOWN) || KDown(GLFW_KEY_RIGHT_SHIFT);
case ACTION_MENU_RIGHT_SCROLL: return KDown(GLFW_KEY_RIGHT_SHIFT) || WheelUp();
case ACTION_MENU_LEFT_SCROLL: return KDown(GLFW_KEY_LEFT_SHIFT) || WheelDown();
case ACTION_MENU_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_UP: return KDown(GLFW_KEY_UP);
case ACTION_MENU_OTHER_STICK_DOWN: return KDown(GLFW_KEY_DOWN);
case ACTION_MENU_OTHER_STICK_LEFT: return KDown(GLFW_KEY_LEFT);
case ACTION_MENU_OTHER_STICK_RIGHT: return KDown(GLFW_KEY_RIGHT);
case ACTION_MENU_PAUSEMENU: return KDown(GLFW_KEY_ESCAPE);
// ---- Minecraft in-game ----
case MINECRAFT_ACTION_JUMP: return KDown(GLFW_KEY_SPACE);
case MINECRAFT_ACTION_FORWARD: return KDown(GLFW_KEY_W);
case MINECRAFT_ACTION_BACKWARD: return KDown(GLFW_KEY_S);
case MINECRAFT_ACTION_LEFT: return KDown(GLFW_KEY_A);
case MINECRAFT_ACTION_RIGHT: return KDown(GLFW_KEY_D);
// Look axes are handled by analog stick RX/RY (mouse)
case MINECRAFT_ACTION_LOOK_LEFT: return false;
case MINECRAFT_ACTION_LOOK_RIGHT: return false;
case MINECRAFT_ACTION_LOOK_UP: return false;
case MINECRAFT_ACTION_LOOK_DOWN: return false;
case MINECRAFT_ACTION_USE: return MouseRDown();
case MINECRAFT_ACTION_ACTION: return MouseLDown();
case MINECRAFT_ACTION_LEFT_SCROLL: return WheelDown();
case MINECRAFT_ACTION_RIGHT_SCROLL: return WheelUp();
case MINECRAFT_ACTION_INVENTORY: return KDown(GLFW_KEY_E);
case MINECRAFT_ACTION_PAUSEMENU: return KDown(GLFW_KEY_ESCAPE);
case MINECRAFT_ACTION_DROP: return KDown(GLFW_KEY_Q);
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KDown(GLFW_KEY_LEFT_SHIFT);
case MINECRAFT_ACTION_CRAFTING: return KDown(GLFW_KEY_F);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KDown(GLFW_KEY_F5);
case MINECRAFT_ACTION_GAME_INFO: return KDown(GLFW_KEY_F3);
case MINECRAFT_ACTION_DPAD_LEFT: return KDown(GLFW_KEY_LEFT);
case MINECRAFT_ACTION_DPAD_RIGHT: return KDown(GLFW_KEY_RIGHT);
case MINECRAFT_ACTION_DPAD_UP: return KDown(GLFW_KEY_UP);
case MINECRAFT_ACTION_DPAD_DOWN: return KDown(GLFW_KEY_DOWN);
default: return false;
}
}
// ---------------------------------------------------------------------------
// ButtonPressed rising edge (press event this frame)
// ---------------------------------------------------------------------------
bool C_4JInput::ButtonPressed(int /*iPad*/, unsigned char ucAction) {
switch (ucAction) {
case ACTION_MENU_UP: return KPressed(GLFW_KEY_UP) || KPressed(GLFW_KEY_W);
case ACTION_MENU_DOWN: return KPressed(GLFW_KEY_DOWN) || KPressed(GLFW_KEY_S);
case ACTION_MENU_LEFT: return KPressed(GLFW_KEY_LEFT) || KPressed(GLFW_KEY_A);
case ACTION_MENU_RIGHT: return KPressed(GLFW_KEY_RIGHT) || KPressed(GLFW_KEY_D);
case ACTION_MENU_A:
case ACTION_MENU_OK:
return KPressed(GLFW_KEY_ENTER) || KPressed(GLFW_KEY_SPACE);
case ACTION_MENU_B:
case ACTION_MENU_CANCEL:
return KPressed(GLFW_KEY_ESCAPE);
case ACTION_MENU_X: return KPressed(GLFW_KEY_F);
case ACTION_MENU_Y: return KPressed(GLFW_KEY_E);
case ACTION_MENU_PAGEUP: return KPressed(GLFW_KEY_PAGE_UP) || KPressed(GLFW_KEY_LEFT_SHIFT);
case ACTION_MENU_PAGEDOWN: return KPressed(GLFW_KEY_PAGE_DOWN) || KPressed(GLFW_KEY_RIGHT_SHIFT);
case ACTION_MENU_RIGHT_SCROLL: return KPressed(GLFW_KEY_RIGHT_SHIFT) || WheelUpEdge();
case ACTION_MENU_LEFT_SCROLL: return KPressed(GLFW_KEY_LEFT_SHIFT) || WheelDownEdge();
case ACTION_MENU_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_UP: return KPressed(GLFW_KEY_UP);
case ACTION_MENU_OTHER_STICK_DOWN: return KPressed(GLFW_KEY_DOWN);
case ACTION_MENU_OTHER_STICK_LEFT: return KPressed(GLFW_KEY_LEFT);
case ACTION_MENU_OTHER_STICK_RIGHT: return KPressed(GLFW_KEY_RIGHT);
case ACTION_MENU_PAUSEMENU: return KPressed(GLFW_KEY_ESCAPE);
case MINECRAFT_ACTION_JUMP: return KPressed(GLFW_KEY_SPACE);
case MINECRAFT_ACTION_FORWARD: return KPressed(GLFW_KEY_W);
case MINECRAFT_ACTION_BACKWARD: return KPressed(GLFW_KEY_S);
case MINECRAFT_ACTION_LEFT: return KPressed(GLFW_KEY_A);
case MINECRAFT_ACTION_RIGHT: return KPressed(GLFW_KEY_D);
case MINECRAFT_ACTION_LOOK_LEFT:
case MINECRAFT_ACTION_LOOK_RIGHT:
case MINECRAFT_ACTION_LOOK_UP:
case MINECRAFT_ACTION_LOOK_DOWN:
return false;
case MINECRAFT_ACTION_USE: return MouseRPressed();
case MINECRAFT_ACTION_ACTION: return MouseLPressed();
case MINECRAFT_ACTION_LEFT_SCROLL: return WheelDownEdge();
case MINECRAFT_ACTION_RIGHT_SCROLL: return WheelUpEdge();
case MINECRAFT_ACTION_INVENTORY: return KPressed(GLFW_KEY_E);
case MINECRAFT_ACTION_PAUSEMENU: return KPressed(GLFW_KEY_ESCAPE);
case MINECRAFT_ACTION_DROP: return KPressed(GLFW_KEY_Q);
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KPressed(GLFW_KEY_LEFT_SHIFT);
case MINECRAFT_ACTION_CRAFTING: return KPressed(GLFW_KEY_F);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KPressed(GLFW_KEY_F5);
case MINECRAFT_ACTION_GAME_INFO: return KPressed(GLFW_KEY_F3);
case MINECRAFT_ACTION_DPAD_LEFT: return KPressed(GLFW_KEY_LEFT);
case MINECRAFT_ACTION_DPAD_RIGHT: return KPressed(GLFW_KEY_RIGHT);
case MINECRAFT_ACTION_DPAD_UP: return KPressed(GLFW_KEY_UP);
case MINECRAFT_ACTION_DPAD_DOWN: return KPressed(GLFW_KEY_DOWN);
default: return false;
}
}
// ---------------------------------------------------------------------------
// ButtonReleased falling edge (released this frame)
// ---------------------------------------------------------------------------
bool C_4JInput::ButtonReleased(int /*iPad*/, unsigned char ucAction) {
switch (ucAction) {
case ACTION_MENU_UP: return KReleased(GLFW_KEY_UP) || KReleased(GLFW_KEY_W);
case ACTION_MENU_DOWN: return KReleased(GLFW_KEY_DOWN) || KReleased(GLFW_KEY_S);
case ACTION_MENU_LEFT: return KReleased(GLFW_KEY_LEFT) || KReleased(GLFW_KEY_A);
case ACTION_MENU_RIGHT: return KReleased(GLFW_KEY_RIGHT) || KReleased(GLFW_KEY_D);
case ACTION_MENU_A:
case ACTION_MENU_OK:
return KReleased(GLFW_KEY_ENTER) || KReleased(GLFW_KEY_SPACE);
case ACTION_MENU_B:
case ACTION_MENU_CANCEL:
return KReleased(GLFW_KEY_ESCAPE);
case ACTION_MENU_X: return KReleased(GLFW_KEY_F);
case ACTION_MENU_Y: return KReleased(GLFW_KEY_E);
case ACTION_MENU_PAGEUP: return KReleased(GLFW_KEY_PAGE_UP) || KReleased(GLFW_KEY_LEFT_SHIFT);
case ACTION_MENU_PAGEDOWN: return KReleased(GLFW_KEY_PAGE_DOWN) || KReleased(GLFW_KEY_RIGHT_SHIFT);
case ACTION_MENU_RIGHT_SCROLL: return KReleased(GLFW_KEY_RIGHT_SHIFT);
case ACTION_MENU_LEFT_SCROLL: return KReleased(GLFW_KEY_LEFT_SHIFT);
case ACTION_MENU_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_PRESS: return false;
case ACTION_MENU_OTHER_STICK_UP: return KReleased(GLFW_KEY_UP);
case ACTION_MENU_OTHER_STICK_DOWN: return KReleased(GLFW_KEY_DOWN);
case ACTION_MENU_OTHER_STICK_LEFT: return KReleased(GLFW_KEY_LEFT);
case ACTION_MENU_OTHER_STICK_RIGHT: return KReleased(GLFW_KEY_RIGHT);
case ACTION_MENU_PAUSEMENU: return KReleased(GLFW_KEY_ESCAPE);
case MINECRAFT_ACTION_JUMP: return KReleased(GLFW_KEY_SPACE);
case MINECRAFT_ACTION_FORWARD: return KReleased(GLFW_KEY_W);
case MINECRAFT_ACTION_BACKWARD: return KReleased(GLFW_KEY_S);
case MINECRAFT_ACTION_LEFT: return KReleased(GLFW_KEY_A);
case MINECRAFT_ACTION_RIGHT: return KReleased(GLFW_KEY_D);
case MINECRAFT_ACTION_LOOK_LEFT:
case MINECRAFT_ACTION_LOOK_RIGHT:
case MINECRAFT_ACTION_LOOK_UP:
case MINECRAFT_ACTION_LOOK_DOWN:
return false;
case MINECRAFT_ACTION_USE: return MouseRReleased();
case MINECRAFT_ACTION_ACTION: return MouseLReleased();
case MINECRAFT_ACTION_LEFT_SCROLL: return false; // scroll wheel has no "release"
case MINECRAFT_ACTION_RIGHT_SCROLL: return false;
case MINECRAFT_ACTION_INVENTORY: return KReleased(GLFW_KEY_E);
case MINECRAFT_ACTION_PAUSEMENU: return KReleased(GLFW_KEY_ESCAPE);
case MINECRAFT_ACTION_DROP: return KReleased(GLFW_KEY_Q);
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KReleased(GLFW_KEY_LEFT_SHIFT);
case MINECRAFT_ACTION_CRAFTING: return KReleased(GLFW_KEY_F);
case MINECRAFT_ACTION_RENDER_THIRD_PERSON: return KReleased(GLFW_KEY_F5);
case MINECRAFT_ACTION_GAME_INFO: return KReleased(GLFW_KEY_F3);
case MINECRAFT_ACTION_DPAD_LEFT: return KReleased(GLFW_KEY_LEFT);
case MINECRAFT_ACTION_DPAD_RIGHT: return KReleased(GLFW_KEY_RIGHT);
case MINECRAFT_ACTION_DPAD_UP: return KReleased(GLFW_KEY_UP);
case MINECRAFT_ACTION_DPAD_DOWN: return KReleased(GLFW_KEY_DOWN);
default: return false;
}
}
// ---------------------------------------------------------------------------
// GetValue returns 1 if action held, 0 otherwise
// ---------------------------------------------------------------------------
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool /*bRepeat*/) {
return ButtonDown(iPad, ucAction) ? 1u : 0u;
}
// ---------------------------------------------------------------------------
// Analog sticks
//
// Left stick = WASD keyboard (±1.0)
// Right stick = mouse delta with sqrt-compression to linearise the quadratic
// look-speed formula used by the console game code:
// turnSpeed = rx * |rx| * 50 * sensitivity
// Passing sqrt(|raw|)*sign(raw) makes turn speed proportional
// to raw pixel delta, giving a natural mouse feel.
// ---------------------------------------------------------------------------
float C_4JInput::GetJoypadStick_LX(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
// Return 0 while cursor is still in menu mode so Input::tick()'s
// lReset guard sees a zero-stick frame during the menu->game transition.
// Once s_mouseLocked becomes true (cursor captured for gameplay), return
// the real WASD values.
if (!s_mouseLocked) return 0.0f;
float v = 0.0f;
if (KDown(GLFW_KEY_A)) v -= 1.0f;
if (KDown(GLFW_KEY_D)) v += 1.0f;
return v;
}
float C_4JInput::GetJoypadStick_LY(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
if (!s_mouseLocked) return 0.0f;
float v = 0.0f;
if (KDown(GLFW_KEY_W)) v -= 1.0f; // W = forward = negative Y on consoles
if (KDown(GLFW_KEY_S)) v += 1.0f;
return v;
}
float C_4JInput::GetJoypadStick_RX(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
if (!s_mouseLocked) return 0.0f;
float raw = s_frameRelX * MOUSE_SCALE;
float absRaw = fabsf(raw);
if (absRaw > 1.0f) absRaw = 1.0f;
if (absRaw < 0.0001f) return 0.0f;
return (raw >= 0.0f ? 1.0f : -1.0f) * sqrtf(absRaw);
}
float C_4JInput::GetJoypadStick_RY(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
if (!s_mouseLocked) return 0.0f;
float raw = s_frameRelY * MOUSE_SCALE;
float absRaw = fabsf(raw);
if (absRaw > 1.0f) absRaw = 1.0f;
if (absRaw < 0.0001f) return 0.0f;
return (raw >= 0.0f ? 1.0f : -1.0f) * sqrtf(absRaw);
}
// Left trigger = right mouse button (use/place)
// Right trigger = left mouse button (attack/destroy)
unsigned char C_4JInput::GetJoypadLTrigger(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
return s_mouseRightCurrent ? 255 : 0;
}
unsigned char C_4JInput::GetJoypadRTrigger(int /*iPad*/, bool /*bCheckMenuDisplay*/) {
return s_mouseLeftCurrent ? 255 : 0;
}
// ---------------------------------------------------------------------------
// Joypad map / sensitivity stubs (not meaningful for keyboard+mouse)
// ---------------------------------------------------------------------------
void C_4JInput::SetDeadzoneAndMovementRange(unsigned int /*uiDeadzone*/, unsigned int /*uiMovementRangeMax*/) {}
void C_4JInput::SetGameJoypadMaps(unsigned char /*ucMap*/, unsigned char /*ucAction*/, unsigned int /*uiActionVal*/) {}
unsigned int C_4JInput::GetGameJoypadMaps(unsigned char /*ucMap*/, unsigned char /*ucAction*/) { return 0; }
void C_4JInput::SetJoypadMapVal(int /*iPad*/, unsigned char /*ucMap*/) {}
unsigned char C_4JInput::GetJoypadMapVal(int /*iPad*/) { return 0; }
void C_4JInput::SetJoypadSensitivity(int /*iPad*/, float /*fSensitivity*/) {}
void C_4JInput::SetJoypadStickAxisMap(int /*iPad*/, unsigned int /*uiFrom*/, unsigned int /*uiTo*/) {}
void C_4JInput::SetJoypadStickTriggerMap(int /*iPad*/, unsigned int /*uiFrom*/, unsigned int /*uiTo*/) {}
void C_4JInput::SetKeyRepeatRate(float /*fRepeatDelaySecs*/, float /*fRepeatRateSecs*/) {}
void C_4JInput::SetDebugSequence(const char * /*chSequenceA*/, int(*/*Func*/)(LPVOID), LPVOID /*lpParam*/) {}
FLOAT C_4JInput::GetIdleSeconds(int /*iPad*/) { return 0.0f; }
bool C_4JInput::IsPadConnected(int iPad) { return iPad == 0; } // slot 0 = keyboard+mouse
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) {
if (iPad >= 0 && iPad < 4) s_menuDisplayed[iPad] = bVal;
}
// ---------------------------------------------------------------------------
// Keyboard (text entry) / string verification stubs
// ---------------------------------------------------------------------------
EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR /*Title*/, LPCWSTR /*Text*/, DWORD /*dwPad*/,
UINT /*uiMaxChars*/,
int(*/*Func*/)(LPVOID, const bool), LPVOID /*lpParam*/,
C_4JInput::EKeyboardMode /*eMode*/) {
return EKeyboard_Cancelled;
}
void C_4JInput::GetText(uint16_t *UTF16String) { if (UTF16String) UTF16String[0] = 0; } void C_4JInput::GetText(uint16_t *UTF16String) { if (UTF16String) UTF16String[0] = 0; }
bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int(*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) { return true; } bool C_4JInput::VerifyStrings(WCHAR ** /*pwStringA*/, int /*iStringC*/,
void C_4JInput::CancelQueuedVerifyStrings(int(*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) {} int(*/*Func*/)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID /*lpParam*/) { return true; }
void C_4JInput::CancelQueuedVerifyStrings(int(*/*Func*/)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID /*lpParam*/) {}
void C_4JInput::CancelAllVerifyInProgress(void) {} void C_4JInput::CancelAllVerifyInProgress(void) {}
-23
View File
@@ -1,23 +0,0 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
project(4J_Input CXX)
add_library(${PROJECT_NAME})
target_sources(${PROJECT_NAME}
PRIVATE
4J_Input.cpp
INP_ForceFeedback.cpp
INP_Keyboard.cpp
INP_Main.cpp
INP_StringCheck.cpp
stdafx.cpp
../Minecraft.Client/Platform/Linux/Stubs/LinuxStubs.h
)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Mimic cmake converter behaviour
target_precompile_headers(${PROJECT_NAME} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h>"
)
+21
View File
@@ -0,0 +1,21 @@
input_sources = files(
'4J_Input.cpp',
'INP_ForceFeedback.cpp',
'INP_Keyboard.cpp',
'INP_Main.cpp',
'INP_StringCheck.cpp',
'stdafx.cpp',
)
lib_input = static_library('4J_Input',
input_sources,
include_directories : include_directories('.'),
cpp_args : global_cpp_args + global_cpp_defs + [
'-include', meson.current_source_dir() / 'stdafx.h',
],
)
input_dep = declare_dependency(
link_with : lib_input,
include_directories : include_directories('.'),
)
-23
View File
@@ -1,23 +0,0 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
project(4J_Profile CXX)
add_library(${PROJECT_NAME})
target_sources(${PROJECT_NAME}
PRIVATE
4J_Profile.cpp
PRO_AwardManager.cpp
PRO_Data.cpp
PRO_Main.cpp
PRO_RichPresence.cpp
PRO_Sys.cpp
stdafx.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Mimic cmake converter behaviour
target_precompile_headers(${PROJECT_NAME} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h>"
)
+22
View File
@@ -0,0 +1,22 @@
profile_sources = files(
'4J_Profile.cpp',
'PRO_AwardManager.cpp',
'PRO_Data.cpp',
'PRO_Main.cpp',
'PRO_RichPresence.cpp',
'PRO_Sys.cpp',
'stdafx.cpp',
)
# 4jprofile stink
lib_profile = static_library('4J_Profile',
profile_sources,
include_directories : include_directories('.'),
cpp_args : global_cpp_args + global_cpp_defs + [
'-include', meson.current_source_dir() / 'stdafx.h',
],
)
profile_dep = declare_dependency(
link_with : lib_profile,
include_directories : include_directories('.'),
)
+709 -145
View File
@@ -1,197 +1,761 @@
#include "4J_Render.h" #include "4J_Render.h"
#include <cstring> #include <cstring>
#include <cstdlib> // getenv
#define GL_GLEXT_PROTOTYPES
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
#include <GLFW/glfw3.h>
#include <cstdio>
#include <cmath>
#include <pthread.h>
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"
C4JRender RenderManager; C4JRender RenderManager;
static float s_identityMatrix[16] = {1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1}; static GLFWwindow *s_window = nullptr;
static int s_textureLevels = 1;
static int s_windowWidth = 1280; // updated to actual framebuffer size each frame
static int s_windowHeight = 720;
static int s_reqWidth = 0; // 0 = auto-detect from primary monitor
static int s_reqHeight = 0;
static bool s_fullscreen = false;
// Thread-local storage for per-thread shared GL contexts.
// The main thread uses s_window directly; worker threads get invisible
// windows that share objects (textures, display lists) with s_window.
static pthread_key_t s_glCtxKey;
static pthread_once_t s_glCtxKeyOnce = PTHREAD_ONCE_INIT;
static void makeGLCtxKey() { pthread_key_create(&s_glCtxKey, nullptr); }
// Pre-created pool of shared contexts for worker threads
static const int MAX_SHARED_CONTEXTS = 8;
static GLFWwindow *s_sharedContexts[MAX_SHARED_CONTEXTS] = {};
static int s_sharedContextCount = 0;
static int s_nextSharedContext = 0;
static pthread_mutex_t s_sharedCtxMutex = PTHREAD_MUTEX_INITIALIZER;
// Track which thread is the main (rendering) thread
static pthread_t s_mainThread;
static bool s_mainThreadSet = false;
void C4JRender::Initialise()
{
#if defined(__linux__) && (GLFW_VERSION_MAJOR > 3 || (GLFW_VERSION_MAJOR == 3 && GLFW_VERSION_MINOR >= 4))
// If the session is a native Wayland session, tell GLFW to use the Wayland
// backend instead of falling back to XWayland. This enables proper cursor
// confine-and-hide (zwp_confined_pointer_v1 + zwp_relative_pointer_v1) which
// is required for correct first-person mouse input on Wayland compositors.
if (getenv("WAYLAND_DISPLAY")) {
glfwInitHint(GLFW_PLATFORM, GLFW_PLATFORM_WAYLAND);
fprintf(stderr, "[4J_Render] Wayland session detected — requesting native Wayland backend\n");
}
#endif
if (!glfwInit()) {
fprintf(stderr, "[4J_Render] Failed to initialise GLFW\n");
return;
}
// Resolve window dimensions: use caller-requested size, or fall back to
// the primary monitor's native resolution so the window fits any display.
GLFWmonitor *primaryMonitor = glfwGetPrimaryMonitor();
const GLFWvidmode *mode = primaryMonitor ? glfwGetVideoMode(primaryMonitor) : nullptr;
if (s_reqWidth > 0 && s_reqHeight > 0) {
s_windowWidth = s_reqWidth;
s_windowHeight = s_reqHeight;
} else if (mode) {
s_windowWidth = mode->width;
s_windowHeight = mode->height;
}
fprintf(stderr, "[4J_Render] Window %dx%d fullscreen=%s\n",
s_windowWidth, s_windowHeight, s_fullscreen ? "yes" : "no");
fflush(stderr);
// opengl 2.1!!!
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 2);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
GLFWmonitor *fsMonitor = s_fullscreen ? primaryMonitor : nullptr;
s_window = glfwCreateWindow(s_windowWidth, s_windowHeight,
"Minecraft Console Edition", fsMonitor, nullptr);
if (!s_window) {
fprintf(stderr, "[4J_Render] Failed to create GLFW window\n");
glfwTerminate();
return;
}
glfwMakeContextCurrent(s_window);
glfwSwapInterval(1); // vsync
// init opengl
::glEnable(GL_TEXTURE_2D);
::glEnable(GL_DEPTH_TEST);
::glDepthFunc(GL_LEQUAL);
::glClearDepth(1.0);
::glEnable(GL_ALPHA_TEST);
::glAlphaFunc(GL_GREATER, 0.1f);
::glEnable(GL_BLEND);
::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
::glEnable(GL_CULL_FACE);
::glCullFace(GL_BACK);
::glShadeModel(GL_SMOOTH);
::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
::glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
::glViewport(0, 0, s_windowWidth, s_windowHeight);
::glEnable(GL_COLOR_MATERIAL);
::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
printf("[4J_Render] OpenGL %s | %s\n",
(const char*)::glGetString(GL_VERSION),
(const char*)::glGetString(GL_RENDERER));
fflush(stdout);
// Tag this as the main rendering thread
pthread_once(&s_glCtxKeyOnce, makeGLCtxKey);
s_mainThread = pthread_self();
s_mainThreadSet = true;
pthread_setspecific(s_glCtxKey, s_window);
// Pre-create shared GL contexts for worker threads (chunk builders etc.)
// Must be done on the main thread because GLFW requires it.
for (int i = 0; i < MAX_SHARED_CONTEXTS; i++) {
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
s_sharedContexts[i] = glfwCreateWindow(1, 1, "", nullptr, s_window);
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
if (s_sharedContexts[i]) {
s_sharedContextCount++;
} else {
fprintf(stderr, "[4J_Render] WARN: only created %d/%d shared contexts\n", i, MAX_SHARED_CONTEXTS);
break;
}
}
// Ensure main thread still has the context
glfwMakeContextCurrent(s_window);
fprintf(stderr, "[4J_Render] Created %d shared GL contexts for worker threads\n", s_sharedContextCount);
fflush(stderr);
}
void C4JRender::InitialiseContext()
{
if (!s_window) return;
pthread_once(&s_glCtxKeyOnce, makeGLCtxKey);
// Main thread reclaiming context (e.g. after startup thread finishes)
if (s_mainThreadSet && pthread_equal(pthread_self(), s_mainThread)) {
glfwMakeContextCurrent(s_window);
pthread_setspecific(s_glCtxKey, s_window);
return;
}
// Worker thread: check if it already has a shared context
GLFWwindow *ctx = (GLFWwindow*)pthread_getspecific(s_glCtxKey);
if (ctx) {
glfwMakeContextCurrent(ctx);
return;
}
// Grab a pre-created shared context from the pool
pthread_mutex_lock(&s_sharedCtxMutex);
GLFWwindow *shared = nullptr;
if (s_nextSharedContext < s_sharedContextCount) {
shared = s_sharedContexts[s_nextSharedContext++];
}
pthread_mutex_unlock(&s_sharedCtxMutex);
if (!shared) {
fprintf(stderr, "[4J_Render] ERROR: no shared GL contexts left for worker thread!\n");
return;
}
glfwMakeContextCurrent(shared);
pthread_setspecific(s_glCtxKey, shared);
fprintf(stderr, "[4J_Render] Assigned shared GL context %p to worker thread\n", (void*)shared);
fflush(stderr);
}
void C4JRender::StartFrame()
{
if (!s_window) return;
glfwGetFramebufferSize(s_window, &s_windowWidth, &s_windowHeight);
if (s_windowWidth < 1) s_windowWidth = 1;
if (s_windowHeight < 1) s_windowHeight = 1;
::glViewport(0, 0, s_windowWidth, s_windowHeight);
}
void C4JRender::Present()
{
if (!s_window) return;
::glFlush();
glfwSwapBuffers(s_window);
glfwPollEvents();
}
void C4JRender::SetWindowSize(int w, int h)
{
s_reqWidth = (w > 0) ? w : 0;
s_reqHeight = (h > 0) ? h : 0;
}
void C4JRender::SetFullscreen(bool fs)
{
s_fullscreen = fs;
}
bool C4JRender::ShouldClose()
{
return !s_window || glfwWindowShouldClose(s_window);
}
void C4JRender::Shutdown()
{
// Destroy the main window and terminate GLFW cleanly so that
// destructors running after the game loop don't touch a dead context.
if (s_window)
{
glfwDestroyWindow(s_window);
s_window = nullptr;
}
glfwTerminate();
}
void C4JRender::Tick() {}
void C4JRender::UpdateGamma(unsigned short usGamma) {}
void C4JRender::MatrixMode(int type) {}
void C4JRender::MatrixSetIdentity() {}
void C4JRender::MatrixTranslate(float x, float y, float z) {}
void C4JRender::MatrixRotate(float angle, float x, float y, float z) {}
void C4JRender::MatrixScale(float x, float y, float z) {}
void C4JRender::MatrixPerspective(float fovy, float aspect, float zNear, float zFar) {}
void C4JRender::MatrixOrthogonal(float left, float right, float bottom, float top, float zNear, float zFar) {}
void C4JRender::MatrixPop() {}
void C4JRender::MatrixPush() {}
void C4JRender::MatrixMult(float *mat) {}
const float* C4JRender::MatrixGet(int type) { return s_identityMatrix; }
void C4JRender::Set_matrixDirty() {}
void C4JRender::Initialise() {}
void C4JRender::InitialiseContext() {}
void C4JRender::StartFrame() {}
void C4JRender::DoScreenGrabOnNextPresent() {} void C4JRender::DoScreenGrabOnNextPresent() {}
void C4JRender::Present() {}
void C4JRender::Clear(int flags) {} void C4JRender::Clear(int flags)
void C4JRender::SetClearColour(const float colourRGBA[4]) {} {
::glClear(flags);
}
void C4JRender::SetClearColour(const float colourRGBA[4])
{
::glClearColor(colourRGBA[0], colourRGBA[1], colourRGBA[2], colourRGBA[3]);
}
bool C4JRender::IsWidescreen() { return true; } bool C4JRender::IsWidescreen() { return true; }
bool C4JRender::IsHiDef() { return true; } bool C4JRender::IsHiDef() { return true; }
void C4JRender::CaptureThumbnail(ImageFileBuffer *pngOut) {} void C4JRender::GetFramebufferSize(int &width, int &height) { width = s_windowWidth; height = s_windowHeight; }
void C4JRender::CaptureScreen(ImageFileBuffer *jpgOut, XSOCIAL_PREVIEWIMAGE *previewOut) {} void C4JRender::CaptureThumbnail(ImageFileBuffer *) {}
void C4JRender::BeginConditionalSurvey(int identifier) {} void C4JRender::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {}
void C4JRender::BeginConditionalSurvey(int) {}
void C4JRender::EndConditionalSurvey() {} void C4JRender::EndConditionalSurvey() {}
void C4JRender::BeginConditionalRendering(int identifier) {} void C4JRender::BeginConditionalRendering(int){}
void C4JRender::EndConditionalRendering() {} void C4JRender::EndConditionalRendering() {}
void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count, void *dataIn, eVertexType vType, C4JRender::ePixelShaderType psType) {}
void C4JRender::MatrixMode(int type) { ::glMatrixMode(type); }
void C4JRender::MatrixSetIdentity() { ::glLoadIdentity(); }
void C4JRender::MatrixTranslate(float x, float y, float z) { ::glTranslatef(x, y, z); }
void C4JRender::MatrixRotate(float angle, float x, float y, float z)
{
// can't fucking afford pi
::glRotatef(angle * (180.0f / 3.14159265358979f), x, y, z);
}
void C4JRender::MatrixScale(float x, float y, float z) { ::glScalef(x, y, z); }
void C4JRender::MatrixPerspective(float fovy, float aspect, float zNear, float zFar)
{
::gluPerspective((double)fovy, (double)aspect, (double)zNear, (double)zFar);
}
void C4JRender::MatrixOrthogonal(float left, float right, float bottom, float top,
float zNear, float zFar)
{
::glOrtho(left, right, bottom, top, zNear, zFar);
}
void C4JRender::MatrixPop() { ::glPopMatrix(); }
void C4JRender::MatrixPush() { ::glPushMatrix(); }
void C4JRender::MatrixMult(float *mat) { ::glMultMatrixf(mat); }
const float* C4JRender::MatrixGet(int type)
{
static float mat[16];
::glGetFloatv(type, mat);
return mat;
}
void C4JRender::Set_matrixDirty() {} // immediate-mode
static GLenum mapPrimType(int pt)
{
switch (pt) {
case 0: return GL_TRIANGLES; // C4JRender::PRIMITIVE_TYPE_TRIANGLE_LIST
case GL_LINES: return GL_LINES;
case GL_LINE_STRIP: return GL_LINE_STRIP;
case GL_TRIANGLES: return GL_TRIANGLES;
case GL_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
case GL_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
case GL_QUADS: return GL_QUADS;
default: return GL_TRIANGLES;
}
}
// clientside awawawa
void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
void *dataIn, eVertexType vType,
C4JRender::ePixelShaderType psType)
{
if (count <= 0 || !dataIn) return;
GLenum mode = mapPrimType((int)PrimitiveType);
if (vType == VERTEX_TYPE_COMPRESSED) {
// Compact terrain vertex: 8 × int16_t = 16 bytes per vertex
// Layout: [x*1024, y*1024, z*1024, RGB565-32768, u*8192, v*8192, tex2u, tex2v]
// Always use glBegin/glEnd — works correctly both inside and outside display lists.
int16_t *sdata = (int16_t *)dataIn;
::glBegin(mode);
for (int i = 0; i < count; i++) {
int16_t *vert = sdata + i * 8;
float x = vert[0] / 1024.0f;
float y = vert[1] / 1024.0f;
float z = vert[2] / 1024.0f;
// Unpack RGB565 colour (Tesselator stores as packedcol - 32768 to fit in int16)
unsigned short packedColor = (unsigned short)((int)vert[3] + 32768);
float r = ((packedColor >> 11) & 0x1f) / 31.0f;
float g = ((packedColor >> 5) & 0x3f) / 63.0f;
float b = ( packedColor & 0x1f) / 31.0f;
float fu = vert[4] / 8192.0f;
float fv = vert[5] / 8192.0f;
// Strip mipmap-disable flag: Tesselator adds +1.0 (= +8192) to u when mipmaps off
if (fu >= 1.0f) fu -= 1.0f;
::glColor3f(r, g, b);
::glTexCoord2f(fu, fv);
::glVertex3f(x, y, z);
}
::glEnd();
} else {
// Standard (non-compact) vertex: 8 × int32 = 32 bytes per vertex
// Layout: [x(f), y(f), z(f), u(f), v(f), color(RGBA packed), normal, tex2]
// Color byte-order fix for little-endian (x86/x64):
// Console code stores color as int col = (r<<24)|(g<<16)|(b<<8)|a
// In little-endian memory the bytes are: [a, b, g, r] at increasing addresses.
// Read as: col[3]=r, col[2]=g, col[1]=b, col[0]=a.
// Always use glBegin/glEnd — safe for both display-list compilation and immediate mode.
// (glVertexPointer/glDrawArrays inside glNewList record a stale pointer, not the data.)
unsigned int *idata = (unsigned int *)dataIn;
::glBegin(mode);
for (int i = 0; i < count; i++) {
float *fdata = (float *)(idata + i * 8);
unsigned int colorInt = idata[i * 8 + 5];
unsigned char cr = (colorInt >> 24) & 0xFF;
unsigned char cg = (colorInt >> 16) & 0xFF;
unsigned char cb = (colorInt >> 8) & 0xFF;
unsigned char ca = colorInt & 0xFF;
unsigned int normalInt = idata[i * 8 + 6];
int8_t nx = (int8_t)( normalInt & 0xFF);
int8_t ny = (int8_t)((normalInt >> 8) & 0xFF);
int8_t nz = (int8_t)((normalInt >> 16) & 0xFF);
::glNormal3f(nx / 127.0f, ny / 127.0f, nz / 127.0f);
// Only override current GL color when the vertex actually carries one.
// colorInt == 0 is the Tesselator sentinel for "no colour set"
// (alpha=0 with all channels zero). Skipping glColor4ub here lets
// sky/fog colour set before glCallList() pass through unchanged.
if (colorInt != 0) {
::glColor4ub(cr, cg, cb, ca);
}
::glTexCoord2f(fdata[3], fdata[4]);
::glVertex3f(fdata[0], fdata[1], fdata[2]);
}
::glEnd();
}
}
void C4JRender::CBuffLockStaticCreations() {} void C4JRender::CBuffLockStaticCreations() {}
int C4JRender::CBuffCreate(int count) { return 0; }
void C4JRender::CBuffDelete(int first, int count) {} int C4JRender::CBuffCreate(int count)
void C4JRender::CBuffStart(int index, bool full) {} {
void C4JRender::CBuffClear(int index) {} return (int)::glGenLists(count);
int C4JRender::CBuffSize(int index) { return 0; } }
void C4JRender::CBuffEnd() {}
bool C4JRender::CBuffCall(int index, bool full) { return false; } void C4JRender::CBuffDelete(int first, int count)
{
if (first > 0 && count > 0) ::glDeleteLists(first, count);
}
void C4JRender::CBuffStart(int index, bool /*full*/)
{
if (index > 0) ::glNewList(index, GL_COMPILE);
}
void C4JRender::CBuffClear(int index)
{
if (index > 0) { ::glNewList(index, GL_COMPILE); ::glEndList(); }
}
int C4JRender::CBuffSize(int /*index*/) { return 0; }
void C4JRender::CBuffEnd()
{
::glEndList();
}
bool C4JRender::CBuffCall(int index, bool /*full*/)
{
if (index <= 0) return false;
if (::glIsList(index)) { ::glCallList(index); return true; }
return false;
}
void C4JRender::CBuffTick() {} void C4JRender::CBuffTick() {}
void C4JRender::CBuffDeferredModeStart() {} void C4JRender::CBuffDeferredModeStart() {}
void C4JRender::CBuffDeferredModeEnd() {} void C4JRender::CBuffDeferredModeEnd() {}
int C4JRender::TextureCreate() { return 0; }
void C4JRender::TextureFree(int idx) {}
void C4JRender::TextureBind(int idx) {} int C4JRender::TextureCreate()
void C4JRender::TextureBindVertex(int idx) {} {
void C4JRender::TextureSetTextureLevels(int levels) {} GLuint id = 0;
int C4JRender::TextureGetTextureLevels() { return 1; } ::glGenTextures(1, &id);
void C4JRender::TextureData(int width, int height, void *data, int level, eTextureFormat format) {} return (int)id;
void C4JRender::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void *data, int level) {} }
void C4JRender::TextureSetParam(int param, int value) {}
void C4JRender::TextureFree(int idx)
{
GLuint id = (GLuint)idx;
::glDeleteTextures(1, &id);
}
void C4JRender::TextureBind(int idx)
{
if (idx < 0) {
::glBindTexture(GL_TEXTURE_2D, 0);
} else {
::glBindTexture(GL_TEXTURE_2D, (GLuint)idx);
}
}
void C4JRender::TextureBindVertex(int idx)
{
// No-op on desktop OpenGL. On consoles this binds a lightmap to the vertex shader
// sampler. On desktop GL 2.1 fixed-function there is no vertex texture concept;
// lighting is handled via vertex colors. Binding anything here OVERRIDES GL_TEXTURE0
// after the call (because the game calls glTexParameteri on whatever is active),
// causing the terrain atlas filter params to be corrupted or the lightmap to appear
// on terrain instead of the atlas. Leave it as a no-op.
(void)idx;
}
void C4JRender::TextureSetTextureLevels(int levels)
{
// Set GL_TEXTURE_MAX_LEVEL so OpenGL knows how many mip levels this texture has.
// Without this, the default is 1000, and any texture that doesn't upload all 1000
// levels is considered "incomplete" and renders as white.
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels > 0 ? levels - 1 : 0);
s_textureLevels = levels;
}
int C4JRender::TextureGetTextureLevels() { return s_textureLevels; }
void C4JRender::TextureData(int width, int height, void *data, int level,
eTextureFormat /*format*/)
{
// Game produces [r,g,b,a] bytes via the non-Xbox transferFromImage/loadTexture paths.
// Use GL_RGBA so OpenGL interprets them correctly. GL_BGRA would swap R and B channels.
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA,
width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, data);
// For the base level (0), force the texture to be non-mipmapped and pixel-crisp.
// glGenerateMipmap() was previously called here as a "safety net", but on Mesa/Nvidia
// drivers it silently resets GL_TEXTURE_MIN_FILTER to the OpenGL spec default
// (GL_NEAREST_MIPMAP_LINEAR), overriding the GL_NEAREST set before this call.
// Fix: set GL_TEXTURE_MAX_LEVEL=0 (only sample level 0) and re-enforce GL_NEAREST.
// The game manually uploads explicit mip levels 1..N-1 after this call anyway,
// so we don't need glGenerateMipmap() as a completeness safety net.
if (level == 0) {
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
}
}
void C4JRender::TextureDataUpdate(int xoffset, int yoffset,
int width, int height,
void *data, int level)
{
::glTexSubImage2D(GL_TEXTURE_2D, level, xoffset, yoffset,
width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
void C4JRender::TextureSetParam(int param, int value)
{
::glTexParameteri(GL_TEXTURE_2D, param, value);
}
void C4JRender::TextureDynamicUpdateStart() {} void C4JRender::TextureDynamicUpdateStart() {}
void C4JRender::TextureDynamicUpdateEnd() {} void C4JRender::TextureDynamicUpdateEnd() {}
// really don't know if this is nessesary but didn't find any other functions to load images properly as a png..
// im sorry.
#ifdef __linux__
#include <png.h>
#include <stdio.h>
#include <string.h>
static HRESULT LoadPNGFromRows(png_structp png, png_infop info, D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut) void C4JRender::Tick() {}
void C4JRender::UpdateGamma(unsigned short) {}
// This sucks, but at least better than libpng
static HRESULT LoadFromSTB(unsigned char* data, int width, int height, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
{ {
int width = png_get_image_width(png, info); int pixelCount = width * height;
int height = png_get_image_height(png, info); int* pixels = new int[pixelCount];
png_byte color_type = png_get_color_type(png, info);
png_byte bit_depth = png_get_bit_depth(png, info);
if (bit_depth == 16) png_set_strip_16(png); for (int i = 0; i < pixelCount; i++)
if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png);
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_gray_1_2_4_to_8(png);
if (png_get_valid(png, info, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png);
if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_PALETTE)
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png);
png_read_update_info(png, info);
unsigned char *buf = new unsigned char[width * height * 4];
png_bytep *rows = new png_bytep[height];
for (int y = 0; y < height; y++)
rows[y] = buf + y * width * 4;
png_read_image(png, rows);
delete[] rows;
// considering i worked on previous projects with raw pngs,,,,,
int *pixels = new int[width * height];
for (int i = 0; i < width * height; i++)
{ {
unsigned char r = buf[i * 4 + 0]; unsigned char r = data[i * 4 + 0];
unsigned char g = buf[i * 4 + 1]; unsigned char g = data[i * 4 + 1];
unsigned char b = buf[i * 4 + 2]; unsigned char b = data[i * 4 + 2];
unsigned char a = buf[i * 4 + 3]; unsigned char a = data[i * 4 + 3];
//pixels[i] = (a << 24) | (b << 16) | (g << 8) | r;
pixels[i] = (a << 24) | (r << 16) | (g << 8) | b; pixels[i] = (a << 24) | (r << 16) | (g << 8) | b;
} }
delete[] buf;
if (pSrcInfo)
{
pSrcInfo->Width = width; pSrcInfo->Width = width;
pSrcInfo->Height = height; pSrcInfo->Height = height;
}
*ppDataOut = pixels; *ppDataOut = pixels;
return S_OK; return S_OK;
} }
HRESULT C4JRender::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) HRESULT C4JRender::LoadTextureData(const char* szFilename, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
{ {
FILE *fp = fopen(szFilename, "rb"); int width, height, channels;
if (!fp) return E_FAIL;
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); unsigned char* data = stbi_load(szFilename, &width, &height, &channels, 4);
if (!png) { fclose(fp); return E_FAIL; } if (!data)
png_infop info = png_create_info_struct(png); return E_FAIL;
if (!info) { png_destroy_read_struct(&png, NULL, NULL); fclose(fp); return E_FAIL; }
if (setjmp(png_jmpbuf(png))) { png_destroy_read_struct(&png, &info, NULL); fclose(fp); return E_FAIL; }
png_init_io(png, fp); HRESULT hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
png_read_info(png, info);
HRESULT hr = LoadPNGFromRows(png, info, pSrcInfo, ppDataOut); stbi_image_free(data);
png_destroy_read_struct(&png, &info, NULL);
fclose(fp);
return hr; return hr;
} }
struct PNGMemReader { const unsigned char *data; png_size_t pos; png_size_t size; };
static void png_mem_read(png_structp png, png_bytep out, png_size_t len)
{
PNGMemReader *r = (PNGMemReader *)png_get_io_ptr(png);
if (r->pos + len > r->size) len = r->size - r->pos;
memcpy(out, r->data + r->pos, len);
r->pos += len;
}
HRESULT C4JRender::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut) HRESULT C4JRender::LoadTextureData(BYTE* pbData, DWORD dwBytes, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
{ {
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); int width, height, channels;
if (!png) return E_FAIL;
png_infop info = png_create_info_struct(png);
if (!info) { png_destroy_read_struct(&png, NULL, NULL); return E_FAIL; }
if (setjmp(png_jmpbuf(png))) { png_destroy_read_struct(&png, &info, NULL); return E_FAIL; }
PNGMemReader reader = { pbData, 0, dwBytes }; unsigned char* data = stbi_load_from_memory(pbData, dwBytes, &width, &height, &channels, 4);
png_set_read_fn(png, &reader, png_mem_read); if (!data)
png_read_info(png, info); return E_FAIL;
HRESULT hr = LoadPNGFromRows(png, info, pSrcInfo, ppDataOut); HRESULT hr = LoadFromSTB(data, width, height, pSrcInfo, ppDataOut);
png_destroy_read_struct(&png, &info, NULL);
stbi_image_free(data);
return hr; return hr;
} }
#else
HRESULT C4JRender::LoadTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut) { return S_OK; }
HRESULT C4JRender::LoadTextureData(BYTE *pbData, DWORD dwBytes, D3DXIMAGE_INFO *pSrcInfo, int **ppDataOut) { return S_OK; }
#endif
HRESULT C4JRender::SaveTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcInfo, int *ppDataOut) { return S_OK; } HRESULT C4JRender::SaveTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcInfo, int *ppDataOut) { return S_OK; }
HRESULT C4JRender::SaveTextureDataToMemory(void *pOutput, int outputCapacity, int *outputLength, int width, int height, int *ppDataIn) { return S_OK; } HRESULT C4JRender::SaveTextureDataToMemory(void *pOutput, int outputCapacity, int *outputLength, int width, int height, int *ppDataIn) { return S_OK; }
void C4JRender::TextureGetStats() {} void C4JRender::TextureGetStats() {}
void* C4JRender::TextureGetTexture(int idx) { return nullptr; } void* C4JRender::TextureGetTexture(int idx) { return nullptr; }
void C4JRender::StateSetColour(float r, float g, float b, float a) {}
void C4JRender::StateSetDepthMask(bool enable) {} // we handle opengl calls cuz multiplatform is painful!!
void C4JRender::StateSetBlendEnable(bool enable) {} void C4JRender::StateSetColour(float r, float g, float b, float a)
void C4JRender::StateSetBlendFunc(int src, int dst) {} {
void C4JRender::StateSetBlendFactor(unsigned int colour) {} ::glColor4f(r, g, b, a);
void C4JRender::StateSetAlphaFunc(int func, float param) {} }
void C4JRender::StateSetDepthFunc(int func) {}
void C4JRender::StateSetFaceCull(bool enable) {} void C4JRender::StateSetDepthMask(bool enable)
void C4JRender::StateSetFaceCullCW(bool enable) {} {
void C4JRender::StateSetLineWidth(float width) {} ::glDepthMask(enable ? GL_TRUE : GL_FALSE);
void C4JRender::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha) {} }
void C4JRender::StateSetDepthTestEnable(bool enable) {}
void C4JRender::StateSetAlphaTestEnable(bool enable) {} void C4JRender::StateSetBlendEnable(bool enable)
void C4JRender::StateSetDepthSlopeAndBias(float slope, float bias) {} {
void C4JRender::StateSetFogEnable(bool enable) {} if (enable) ::glEnable(GL_BLEND); else ::glDisable(GL_BLEND);
void C4JRender::StateSetFogMode(int mode) {} }
void C4JRender::StateSetFogNearDistance(float dist) {}
void C4JRender::StateSetFogFarDistance(float dist) {} void C4JRender::StateSetBlendFunc(int src, int dst)
void C4JRender::StateSetFogDensity(float density) {} {
void C4JRender::StateSetFogColour(float red, float green, float blue) {} ::glBlendFunc(src, dst);
void C4JRender::StateSetLightingEnable(bool enable) {} }
void C4JRender::StateSetVertexTextureUV(float u, float v) {}
void C4JRender::StateSetLightColour(int light, float red, float green, float blue) {} void C4JRender::StateSetBlendFactor(unsigned int colour)
void C4JRender::StateSetLightAmbientColour(float red, float green, float blue) {} {
void C4JRender::StateSetLightDirection(int light, float x, float y, float z) {} // colour is 0xAARRGGBB packed
void C4JRender::StateSetLightEnable(int light, bool enable) {} float a = ((colour >> 24) & 0xFF) / 255.0f;
void C4JRender::StateSetViewport(eViewportType viewportType) {} float r = ((colour >> 16) & 0xFF) / 255.0f;
void C4JRender::StateSetEnableViewportClipPlanes(bool enable) {} float g = ((colour >> 8) & 0xFF) / 255.0f;
void C4JRender::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace) {} float b = ( colour & 0xFF) / 255.0f;
void C4JRender::StateSetStencil(int Function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask) {} ::glBlendColor(r, g, b, a);
void C4JRender::StateSetForceLOD(int LOD) {} }
void C4JRender::StateSetAlphaFunc(int func, float param)
{
::glAlphaFunc(func, param);
}
void C4JRender::StateSetDepthFunc(int func)
{
::glDepthFunc(func);
}
void C4JRender::StateSetFaceCull(bool enable)
{
if (enable) ::glEnable(GL_CULL_FACE); else ::glDisable(GL_CULL_FACE);
}
void C4JRender::StateSetFaceCullCW(bool enable)
{
::glFrontFace(enable ? GL_CW : GL_CCW);
}
void C4JRender::StateSetLineWidth(float width)
{
::glLineWidth(width);
}
void C4JRender::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha)
{
::glColorMask(red, green, blue, alpha);
}
void C4JRender::StateSetDepthTestEnable(bool enable)
{
if (enable) ::glEnable(GL_DEPTH_TEST); else ::glDisable(GL_DEPTH_TEST);
}
void C4JRender::StateSetAlphaTestEnable(bool enable)
{
if (enable) ::glEnable(GL_ALPHA_TEST); else ::glDisable(GL_ALPHA_TEST);
}
void C4JRender::StateSetDepthSlopeAndBias(float slope, float bias)
{
if (slope != 0.0f || bias != 0.0f) {
::glEnable(GL_POLYGON_OFFSET_FILL);
::glPolygonOffset(slope, bias);
} else {
::glDisable(GL_POLYGON_OFFSET_FILL);
}
}
void C4JRender::StateSetFogEnable(bool enable)
{
if (enable) ::glEnable(GL_FOG); else ::glDisable(GL_FOG);
}
void C4JRender::StateSetFogMode(int mode)
{
::glFogi(GL_FOG_MODE, mode);
}
void C4JRender::StateSetFogNearDistance(float dist)
{
::glFogf(GL_FOG_START, dist);
}
void C4JRender::StateSetFogFarDistance(float dist)
{
::glFogf(GL_FOG_END, dist);
}
void C4JRender::StateSetFogDensity(float density)
{
::glFogf(GL_FOG_DENSITY, density);
}
void C4JRender::StateSetFogColour(float red, float green, float blue)
{
float c[4] = {red, green, blue, 1.0f};
::glFogfv(GL_FOG_COLOR, c);
}
void C4JRender::StateSetLightingEnable(bool enable)
{
if (enable) {
::glEnable(GL_LIGHTING);
// Enable color material so glColor calls set material ambient+diffuse
::glEnable(GL_COLOR_MATERIAL);
::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
} else {
::glDisable(GL_LIGHTING);
::glDisable(GL_COLOR_MATERIAL);
}
}
void C4JRender::StateSetVertexTextureUV(float u, float v)
{
::glMultiTexCoord2f(GL_TEXTURE1, u, v);
}
void C4JRender::StateSetLightColour(int light, float red, float green, float blue)
{
float diffuse[4] = {red, green, blue, 1.0f};
::glLightfv(GL_LIGHT0 + light, GL_DIFFUSE, diffuse);
}
void C4JRender::StateSetLightAmbientColour(float red, float green, float blue)
{
float ambient[4] = {red, green, blue, 1.0f};
float model[4] = {red, green, blue, 1.0f};
::glLightModelfv(GL_LIGHT_MODEL_AMBIENT, model);
// Also set on light 0 as a fallback incase
::glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
}
void C4JRender::StateSetLightDirection(int light, float x, float y, float z)
{
float dir[4] = {x, y, z, 0.0f}; // w=0 → directional light
::glLightfv(GL_LIGHT0 + light, GL_POSITION, dir);
}
void C4JRender::StateSetLightEnable(int light, bool enable)
{
GLenum l = GL_LIGHT0 + light;
if (enable) ::glEnable(l); else ::glDisable(l);
}
void C4JRender::StateSetViewport(eViewportType viewportType)
{
// Use the full framebuffer for all viewport types
::glViewport(0, 0, s_windowWidth, s_windowHeight);
}
void C4JRender::StateSetEnableViewportClipPlanes(bool enable)
{
// Clip planes not commonly used in the legacy path
if (enable) ::glEnable(GL_CLIP_PLANE0); else ::glDisable(GL_CLIP_PLANE0);
}
void C4JRender::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace)
{
GLenum coord;
switch (col) {
case 0: coord = GL_S; break;
case 1: coord = GL_T; break;
case 2: coord = GL_R; break;
case 3: coord = GL_Q; break;
default: coord = GL_S; break;
}
float plane[4] = {x, y, z, w};
GLenum planeMode = eyeSpace ? GL_EYE_PLANE : GL_OBJECT_PLANE;
::glTexGeni(coord, GL_TEXTURE_GEN_MODE,
eyeSpace ? GL_EYE_LINEAR : GL_OBJECT_LINEAR);
::glTexGenfv(coord, planeMode, plane);
}
void C4JRender::StateSetStencil(int Function, uint8_t stencil_ref,
uint8_t stencil_func_mask,
uint8_t stencil_write_mask)
{
::glEnable(GL_STENCIL_TEST);
::glStencilFunc(Function, stencil_ref, stencil_func_mask);
::glStencilMask(stencil_write_mask);
}
void C4JRender::StateSetForceLOD(int LOD) {} // No LOD bias in legacy GL path
void C4JRender::BeginEvent(LPCWSTR eventName) {} void C4JRender::BeginEvent(LPCWSTR eventName) {}
void C4JRender::EndEvent() {} void C4JRender::EndEvent() {}
void C4JRender::Suspend() {} void C4JRender::Suspend() {}
+9
View File
@@ -63,6 +63,10 @@ public:
// Core // Core
void Initialise(); void Initialise();
void InitialiseContext(); void InitialiseContext();
// Call before Initialise() to override window size and/or fullscreen mode.
// If not called, the primary monitor's native resolution is used.
void SetWindowSize(int w, int h);
void SetFullscreen(bool fs);
void StartFrame(); void StartFrame();
void DoScreenGrabOnNextPresent(); void DoScreenGrabOnNextPresent();
void Present(); void Present();
@@ -70,6 +74,7 @@ public:
void SetClearColour(const float colourRGBA[4]); void SetClearColour(const float colourRGBA[4]);
bool IsWidescreen(); bool IsWidescreen();
bool IsHiDef(); bool IsHiDef();
void GetFramebufferSize(int &width, int &height);
void CaptureThumbnail(ImageFileBuffer *pngOut); void CaptureThumbnail(ImageFileBuffer *pngOut);
void CaptureScreen(ImageFileBuffer *jpgOut, XSOCIAL_PREVIEWIMAGE *previewOut); void CaptureScreen(ImageFileBuffer *jpgOut, XSOCIAL_PREVIEWIMAGE *previewOut);
void BeginConditionalSurvey(int identifier); void BeginConditionalSurvey(int identifier);
@@ -206,6 +211,10 @@ public:
void Suspend(); void Suspend();
bool Suspended(); bool Suspended();
void Resume(); void Resume();
// Linux window management
bool ShouldClose();
void Shutdown();
}; };
-30
View File
@@ -1,30 +0,0 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
project(4J_Render CXX)
add_library(${PROJECT_NAME})
target_sources(${PROJECT_NAME}
PRIVATE
4J_Render.cpp
RendererCbuff.cpp
RendererCore.cpp
RendererMatrix.cpp
RendererState.cpp
RendererTexture.cpp
RendererVertex.cpp
stdafx.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# giving a boost on the next macos implmentation
if(UNIX AND NOT APPLE)
find_package(PNG REQUIRED)
target_link_libraries(${PROJECT_NAME} PRIVATE PNG::PNG)
endif()
# Mimic cmake converter behaviour
target_precompile_headers(${PROJECT_NAME} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h>"
)
+24
View File
@@ -0,0 +1,24 @@
render_sources = files(
'4J_Render.cpp',
'RendererCbuff.cpp',
'RendererCore.cpp',
'RendererMatrix.cpp',
'RendererState.cpp',
'RendererTexture.cpp',
'RendererVertex.cpp',
'stdafx.cpp',
)
lib_render = static_library('4J_Render',
render_sources,
include_directories : include_directories('.'),
dependencies : [png_dep, glfw_dep, gl_dep, thread_dep],
cpp_args : global_cpp_args + global_cpp_defs + [
'-include', meson.current_source_dir() / 'stdafx.h',
],
)
render_dep = declare_dependency(
link_with : lib_render,
include_directories : include_directories('.'),
)
File diff suppressed because it is too large Load Diff
-21
View File
@@ -1,21 +0,0 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
project(4J_Storage CXX)
add_library(${PROJECT_NAME})
target_sources(${PROJECT_NAME}
PRIVATE
4J_Storage.cpp
STO_DLC.cpp
STO_Main.cpp
STO_SaveGame.cpp
stdafx.cpp
)
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
# Mimic cmake converter behaviour
target_precompile_headers(${PROJECT_NAME} PRIVATE
"$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_CURRENT_SOURCE_DIR}/stdafx.h>"
)
+20
View File
@@ -0,0 +1,20 @@
storage_sources = files(
'4J_Storage.cpp',
'stdafx.cpp',
'STO_DLC.cpp',
'STO_Main.cpp',
'STO_SaveGame.cpp',
)
lib_storage = static_library('4J_Storage',
storage_sources,
include_directories : include_directories('.'),
cpp_args : global_cpp_args + global_cpp_defs + [
'-include', meson.current_source_dir() / 'stdafx.h',
],
)
storage_dep = declare_dependency(
link_with : lib_storage,
include_directories : include_directories('.'),
)
-65
View File
@@ -1,65 +0,0 @@
################################################################################
# Command for variable_watch. This command issues error message, if a variable
# is changed. If variable PROPERTY_READER_GUARD_DISABLED is TRUE nothing happens
# variable_watch(<variable> property_reader_guard)
################################################################################
function(property_reader_guard VARIABLE ACCESS VALUE CURRENT_LIST_FILE STACK)
if("${PROPERTY_READER_GUARD_DISABLED}")
return()
endif()
if("${ACCESS}" STREQUAL "MODIFIED_ACCESS")
message(FATAL_ERROR
" Variable ${VARIABLE} is not supposed to be changed.\n"
" It is used only for reading target property ${VARIABLE}.\n"
" Use\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}\" \"<value>\")\n"
" or\n"
" set_target_properties(\"<target>\" PROPERTIES \"${VARIABLE}_<CONFIG>\" \"<value>\")\n"
" instead.\n")
endif()
endfunction()
################################################################################
# Create variable <name> with generator expression that expands to value of
# target property <name>_<CONFIG>. If property is empty or not set then property
# <name> is used instead. Variable <name> has watcher property_reader_guard that
# doesn't allow to edit it.
# create_property_reader(<name>)
# Input:
# name - Name of watched property and output variable
################################################################################
function(create_property_reader NAME)
set(PROPERTY_READER_GUARD_DISABLED TRUE)
set(CONFIG_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}_$<UPPER_CASE:$<CONFIG>>>>")
set(IS_CONFIG_VALUE_EMPTY "$<STREQUAL:${CONFIG_VALUE},>")
set(GENERAL_VALUE "$<TARGET_GENEX_EVAL:${PROPS_TARGET},$<TARGET_PROPERTY:${PROPS_TARGET},${NAME}>>")
set("${NAME}" "$<IF:${IS_CONFIG_VALUE_EMPTY},${GENERAL_VALUE},${CONFIG_VALUE}>" PARENT_SCOPE)
variable_watch("${NAME}" property_reader_guard)
endfunction()
################################################################################
# Set property $<name>_${PROPS_CONFIG_U} of ${PROPS_TARGET} to <value>
# set_config_specific_property(<name> <value>)
# Input:
# name - Prefix of property name
# value - New value
################################################################################
function(set_config_specific_property NAME VALUE)
set_target_properties("${PROPS_TARGET}" PROPERTIES "${NAME}_${PROPS_CONFIG_U}" "${VALUE}")
endfunction()
################################################################################
create_property_reader("TARGET_NAME")
create_property_reader("OUTPUT_DIRECTORY")
set_config_specific_property("TARGET_NAME" "${PROPS_TARGET}")
set_config_specific_property("OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("LIBRARY_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("RUNTIME_OUTPUT_NAME" "${TARGET_NAME}")
set_config_specific_property("ARCHIVE_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("LIBRARY_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
set_config_specific_property("RUNTIME_OUTPUT_DIRECTORY" "${OUTPUT_DIRECTORY}")
-12
View File
@@ -1,12 +0,0 @@
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
if(MSVC)
create_property_reader("DEFAULT_CXX_EXCEPTION_HANDLING")
create_property_reader("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT")
set_target_properties("${PROPS_TARGET}" PROPERTIES MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
set_config_specific_property("DEFAULT_CXX_EXCEPTION_HANDLING" "/EHsc")
set_config_specific_property("DEFAULT_CXX_DEBUG_INFORMATION_FORMAT" "/Zi")
endif()
-12
View File
@@ -1,12 +0,0 @@
include("${CMAKE_CURRENT_LIST_DIR}/Default.cmake")
set_config_specific_property("OUTPUT_DIRECTORY" "${CMAKE_CURRENT_SOURCE_DIR}$<$<NOT:$<STREQUAL:${CMAKE_VS_PLATFORM_NAME},Win32>>:/${CMAKE_VS_PLATFORM_NAME}>/${PROPS_CONFIG}")
get_target_property(${PROPS_TARGET}_BINARY_DIR ${PROPS_TARGET} BINARY_DIR)
set(DEFAULT_FORTRAN_MODULES_DIR "${${PROPS_TARGET}_BINARY_DIR}/${PROPS_TARGET}.Modules.dir")
set_target_properties(${PROPS_TARGET} PROPERTIES Fortran_MODULE_DIRECTORY ${DEFAULT_FORTRAN_MODULES_DIR})
if(${CMAKE_GENERATOR} MATCHES "Visual Studio")
# Hack for visual studio generator (https://gitlab.kitware.com/cmake/cmake/issues/19552)
add_custom_command(TARGET ${PROPS_TARGET} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory $<TARGET_PROPERTY:${PROPS_TARGET},Fortran_MODULE_DIRECTORY>/${CMAKE_CFG_INTDIR})
endif()
-234
View File
@@ -1,234 +0,0 @@
# utils file for projects came from visual studio solution with cmake-converter.
################################################################################
# Wrap each token of the command with condition
################################################################################
cmake_policy(PUSH)
cmake_policy(SET CMP0054 NEW)
macro(prepare_commands)
unset(TOKEN_ROLE)
unset(COMMANDS)
foreach(TOKEN ${ARG_COMMANDS})
if("${TOKEN}" STREQUAL "COMMAND")
set(TOKEN_ROLE "KEYWORD")
elseif("${TOKEN_ROLE}" STREQUAL "KEYWORD")
set(TOKEN_ROLE "CONDITION")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(TOKEN_ROLE "COMMAND")
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
set(TOKEN_ROLE "ARG")
endif()
if("${TOKEN_ROLE}" STREQUAL "KEYWORD")
list(APPEND COMMANDS "${TOKEN}")
elseif("${TOKEN_ROLE}" STREQUAL "CONDITION")
set(CONDITION ${TOKEN})
elseif("${TOKEN_ROLE}" STREQUAL "COMMAND")
list(APPEND COMMANDS "$<$<NOT:${CONDITION}>:${DUMMY}>$<${CONDITION}:${TOKEN}>")
elseif("${TOKEN_ROLE}" STREQUAL "ARG")
list(APPEND COMMANDS "$<${CONDITION}:${TOKEN}>")
endif()
endforeach()
endmacro()
cmake_policy(POP)
################################################################################
# Transform all the tokens to absolute paths
################################################################################
macro(prepare_output)
unset(OUTPUT)
foreach(TOKEN ${ARG_OUTPUT})
if(IS_ABSOLUTE ${TOKEN})
list(APPEND OUTPUT "${TOKEN}")
else()
list(APPEND OUTPUT "${CMAKE_CURRENT_SOURCE_DIR}/${TOKEN}")
endif()
endforeach()
endmacro()
################################################################################
# Parse add_custom_command_if args.
#
# Input:
# PRE_BUILD - Pre build event option
# PRE_LINK - Pre link event option
# POST_BUILD - Post build event option
# TARGET - Target
# OUTPUT - List of output files
# DEPENDS - List of files on which the command depends
# COMMANDS - List of commands(COMMAND condition1 commannd1 args1 COMMAND
# condition2 commannd2 args2 ...)
# Output:
# OUTPUT - Output files
# DEPENDS - Files on which the command depends
# COMMENT - Comment
# PRE_BUILD - TRUE/FALSE
# PRE_LINK - TRUE/FALSE
# POST_BUILD - TRUE/FALSE
# TARGET - Target name
# COMMANDS - Prepared commands(every token is wrapped in CONDITION)
# NAME - Unique name for custom target
# STEP - PRE_BUILD/PRE_LINK/POST_BUILD
################################################################################
function(add_custom_command_if_parse_arguments)
cmake_parse_arguments("ARG" "PRE_BUILD;PRE_LINK;POST_BUILD" "TARGET;COMMENT" "DEPENDS;OUTPUT;COMMANDS" ${ARGN})
if(WIN32)
set(DUMMY "cd.")
elseif(UNIX)
set(DUMMY "true")
endif()
prepare_commands()
prepare_output()
set(DEPENDS "${ARG_DEPENDS}")
set(COMMENT "${ARG_COMMENT}")
set(PRE_BUILD "${ARG_PRE_BUILD}")
set(PRE_LINK "${ARG_PRE_LINK}")
set(POST_BUILD "${ARG_POST_BUILD}")
set(TARGET "${ARG_TARGET}")
if(PRE_BUILD)
set(STEP "PRE_BUILD")
elseif(PRE_LINK)
set(STEP "PRE_LINK")
elseif(POST_BUILD)
set(STEP "POST_BUILD")
endif()
set(NAME "${TARGET}_${STEP}")
set(OUTPUT "${OUTPUT}" PARENT_SCOPE)
set(DEPENDS "${DEPENDS}" PARENT_SCOPE)
set(COMMENT "${COMMENT}" PARENT_SCOPE)
set(PRE_BUILD "${PRE_BUILD}" PARENT_SCOPE)
set(PRE_LINK "${PRE_LINK}" PARENT_SCOPE)
set(POST_BUILD "${POST_BUILD}" PARENT_SCOPE)
set(TARGET "${TARGET}" PARENT_SCOPE)
set(COMMANDS "${COMMANDS}" PARENT_SCOPE)
set(STEP "${STEP}" PARENT_SCOPE)
set(NAME "${NAME}" PARENT_SCOPE)
endfunction()
################################################################################
# Add conditional custom command
#
# Generating Files
# The first signature is for adding a custom command to produce an output:
# add_custom_command_if(
# <OUTPUT output1 [output2 ...]>
# <COMMANDS>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [DEPENDS [depends...]]
# [COMMENT comment]
#
# Build Events
# add_custom_command_if(
# <TARGET target>
# <PRE_BUILD | PRE_LINK | POST_BUILD>
# <COMMAND condition command1 [args1...]>
# [COMMAND condition command2 [args2...]]
# [COMMENT comment]
#
# Input:
# output - Output files the command is expected to produce
# condition - Generator expression for wrapping the command
# command - Command-line(s) to execute at build time.
# args - Command`s args
# depends - Files on which the command depends
# comment - Display the given message before the commands are executed at
# build time.
# PRE_BUILD - Run before any other rules are executed within the target
# PRE_LINK - Run after sources have been compiled but before linking the
# binary
# POST_BUILD - Run after all other rules within the target have been
# executed
################################################################################
function(add_custom_command_if)
add_custom_command_if_parse_arguments(${ARGN})
if(OUTPUT AND TARGET)
message(FATAL_ERROR "Wrong syntax. A TARGET and OUTPUT can not both be specified.")
endif()
if(OUTPUT)
add_custom_command(OUTPUT ${OUTPUT}
${COMMANDS}
DEPENDS ${DEPENDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
elseif(TARGET)
if(PRE_BUILD AND NOT ${CMAKE_GENERATOR} MATCHES "Visual Studio")
add_custom_target(
${NAME}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
add_dependencies(${TARGET} ${NAME})
else()
add_custom_command(
TARGET ${TARGET}
${STEP}
${COMMANDS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT ${COMMENT})
endif()
else()
message(FATAL_ERROR "Wrong syntax. A TARGET or OUTPUT must be specified.")
endif()
endfunction()
################################################################################
# Use props file for a target and configs
# use_props(<target> <configs...> <props_file>)
# Inside <props_file> there are following variables:
# PROPS_TARGET - <target>
# PROPS_CONFIG - One of <configs...>
# PROPS_CONFIG_U - Uppercase PROPS_CONFIG
# Input:
# target - Target to apply props file
# configs - Build configurations to apply props file
# props_file - CMake script
################################################################################
macro(use_props TARGET CONFIGS PROPS_FILE)
set(PROPS_TARGET "${TARGET}")
foreach(PROPS_CONFIG ${CONFIGS})
string(TOUPPER "${PROPS_CONFIG}" PROPS_CONFIG_U)
get_filename_component(ABSOLUTE_PROPS_FILE "${PROPS_FILE}" ABSOLUTE BASE_DIR "${CMAKE_CURRENT_LIST_DIR}")
if(EXISTS "${ABSOLUTE_PROPS_FILE}")
include("${ABSOLUTE_PROPS_FILE}")
else()
message(WARNING "Corresponding cmake file from props \"${ABSOLUTE_PROPS_FILE}\" doesn't exist")
endif()
endforeach()
endmacro()
################################################################################
# Add compile options to source file
# source_file_compile_options(<source_file> [compile_options...])
# Input:
# source_file - Source file
# compile_options - Options to add to COMPILE_FLAGS property
################################################################################
function(source_file_compile_options SOURCE_FILE)
if("${ARGC}" LESS_EQUAL "1")
return()
endif()
get_source_file_property(COMPILE_OPTIONS "${SOURCE_FILE}" COMPILE_OPTIONS)
if(COMPILE_OPTIONS)
list(APPEND COMPILE_OPTIONS ${ARGN})
else()
set(COMPILE_OPTIONS "${ARGN}")
endif()
set_source_files_properties("${SOURCE_FILE}" PROPERTIES COMPILE_OPTIONS "${COMPILE_OPTIONS}")
endfunction()
################################################################################
# Default properties of visual studio projects
################################################################################
set(DEFAULT_CXX_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultCXX.cmake")
set(DEFAULT_Fortran_PROPS "${CMAKE_CURRENT_LIST_DIR}/DefaultFortran.cmake")
-117
View File
@@ -1,117 +0,0 @@
cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
#specify the usage of gcc-15 for the compiler
set(CMAKE_C_COMPILER "gcc-15")
set(CMAKE_CXX_COMPILER "g++-15")
project(MinecraftConsoles C CXX)
################################################################################
# Set target arch type if empty. Visual studio solution generator provides it.
################################################################################
set(CMAKE_VS_PLATFORM_NAME "Linux")
set(CMAKE_CXX_STANDARD 11)
################################################################################
# Global configuration types
################################################################################
set(CMAKE_CONFIGURATION_TYPES
"ContentPackage"
"ContentPackage_NO_TU"
"CONTENTPACKAGE_SYMBOLS"
"Debug"
"Release"
"ReleaseForArt"
CACHE STRING "" FORCE
)
################################################################################
# Global compiler options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_C_FLAGS "")
set(CMAKE_C_FLAGS_CONTENTPACKAGE "")
set(CMAKE_C_FLAGS_CONTENTPACKAGE_NO_TU "")
set(CMAKE_C_FLAGS_CONTENTPACKAGE_SYMBOLS "")
set(CMAKE_C_FLAGS_DEBUG "")
set(CMAKE_C_FLAGS_RELEASE "")
set(CMAKE_C_FLAGS_RELEASEFORART "")
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_CONTENTPACKAGE "")
set(CMAKE_CXX_FLAGS_CONTENTPACKAGE_NO_TU "")
set(CMAKE_CXX_FLAGS_CONTENTPACKAGE_SYMBOLS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELEASEFORART "")
endif()
################################################################################
# Global linker options
################################################################################
if(MSVC)
# remove default flags provided with CMake for MSVC
set(CMAKE_EXE_LINKER_FLAGS "")
set(CMAKE_MODULE_LINKER_FLAGS "")
set(CMAKE_SHARED_LINKER_FLAGS "")
set(CMAKE_STATIC_LINKER_FLAGS "")
set(CMAKE_EXE_LINKER_FLAGS_CONTENTPACKAGE "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_CONTENTPACKAGE "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_CONTENTPACKAGE "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_CONTENTPACKAGE "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_CONTENTPACKAGE_NO_TU "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_CONTENTPACKAGE_NO_TU "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_CONTENTPACKAGE_NO_TU "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_CONTENTPACKAGE_NO_TU "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_CONTENTPACKAGE_SYMBOLS "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_CONTENTPACKAGE_SYMBOLS "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_CONTENTPACKAGE_SYMBOLS "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_CONTENTPACKAGE_SYMBOLS "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_DEBUG "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASE "${CMAKE_STATIC_LINKER_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_RELEASEFORART "${CMAKE_EXE_LINKER_FLAGS}")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASEFORART "${CMAKE_MODULE_LINKER_FLAGS}")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASEFORART "${CMAKE_SHARED_LINKER_FLAGS}")
set(CMAKE_STATIC_LINKER_FLAGS_RELEASEFORART "${CMAKE_STATIC_LINKER_FLAGS}")
endif()
################################################################################
# Nuget packages function stub.
################################################################################
function(use_package TARGET PACKAGE VERSION)
message(WARNING "No implementation of use_package. Create yours. "
"Package \"${PACKAGE}\" with version \"${VERSION}\" "
"for target \"${TARGET}\" is ignored!")
endfunction()
################################################################################
# Common utils
################################################################################
include(CMake/Utils.cmake)
################################################################################
# Additional Global Settings(add specific info there)
################################################################################
include(CMake/GlobalSettingsInclude.cmake OPTIONAL)
################################################################################
# Use solution folders feature
################################################################################
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
################################################################################
# Sub-projects
################################################################################
add_subdirectory(4J.Input)
add_subdirectory(4J.Profile)
add_subdirectory(4J.Render)
add_subdirectory(4J.Storage)
add_subdirectory(Minecraft.Client/Build Minecraft.Client)
add_subdirectory(Minecraft.World/Build Minecraft.World)
-8
View File
@@ -24,11 +24,3 @@ Simple rules for publishing code:
Make sure your code compiles before making a pull request! and make sure that it's readable Make sure your code compiles before making a pull request! and make sure that it's readable
Remember ALL your changes will be licensed under GNU General Public License V3.0. Remember ALL your changes will be licensed under GNU General Public License V3.0.
## Compiling the project:
> [!NOTE]
> The project is currently in a non-compilable state (as of 3/3/2026)
1. Install CMake, Make, GCC (>= 15.0), G++ (>= 15.0).
2. Create a new directory named build after cloning the repository.
3. Enter the new directory and run `cmake ..` and then run `make`
File diff suppressed because it is too large Load Diff
@@ -7729,7 +7729,7 @@ unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, __int64 see
if(hasSeed) if(hasSeed)
{ {
strcpy((char *)bTextMetadata,"4J_SEED"); strcpy((char *)bTextMetadata,"4J_SEED");
snprintf((char *)&bTextMetadata[8], 42, NULL, seed); snprintf((char *)&bTextMetadata[8], 42, "%lld", (long long)seed);
// get the length // get the length
iTextMetadataBytes+=8; iTextMetadataBytes+=8;
@@ -104,7 +104,7 @@ void GameRuleManager::loadGameRules(DLCPack *pack)
{ {
DLCGameRulesHeader *dlcHeader = (DLCGameRulesHeader *)pack->getFile(DLCManager::e_DLCType_GameRulesHeader, i); DLCGameRulesHeader *dlcHeader = (DLCGameRulesHeader *)pack->getFile(DLCManager::e_DLCType_GameRulesHeader, i);
DWORD dSize; DWORD dSize;
byte *dData = dlcHeader->getData(dSize); uint8_t *dData = dlcHeader->getData(dSize);
LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(); LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions();
// = loadGameRules(dData, dSize); //, strings); // = loadGameRules(dData, dSize); //, strings);
@@ -126,7 +126,7 @@ void GameRuleManager::loadGameRules(DLCPack *pack)
DLCGameRulesFile *dlcFile = (DLCGameRulesFile *)pack->getFile(DLCManager::e_DLCType_GameRules, i); DLCGameRulesFile *dlcFile = (DLCGameRulesFile *)pack->getFile(DLCManager::e_DLCType_GameRules, i);
DWORD dSize; DWORD dSize;
byte *dData = dlcFile->getData(dSize); uint8_t *dData = dlcFile->getData(dSize);
LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions(); LevelGenerationOptions *createdLevelGenerationOptions = new LevelGenerationOptions();
// = loadGameRules(dData, dSize); //, strings); // = loadGameRules(dData, dSize); //, strings);
@@ -142,7 +142,7 @@ void GameRuleManager::loadGameRules(DLCPack *pack)
} }
} }
LevelGenerationOptions *GameRuleManager::loadGameRules(byte *dIn, UINT dSize) LevelGenerationOptions *GameRuleManager::loadGameRules(uint8_t *dIn, UINT dSize)
{ {
LevelGenerationOptions *lgo = new LevelGenerationOptions(); LevelGenerationOptions *lgo = new LevelGenerationOptions();
lgo->setGrSource( new JustGrSource() ); lgo->setGrSource( new JustGrSource() );
@@ -153,7 +153,7 @@ LevelGenerationOptions *GameRuleManager::loadGameRules(byte *dIn, UINT dSize)
} }
// 4J-JEV: Reverse of saveGameRules. // 4J-JEV: Reverse of saveGameRules.
void GameRuleManager::loadGameRules(LevelGenerationOptions *lgo, byte *dIn, UINT dSize) void GameRuleManager::loadGameRules(LevelGenerationOptions *lgo, uint8_t *dIn, UINT dSize)
{ {
app.DebugPrintf("GameRuleManager::LoadingGameRules:\n"); app.DebugPrintf("GameRuleManager::LoadingGameRules:\n");
@@ -240,7 +240,7 @@ void GameRuleManager::loadGameRules(LevelGenerationOptions *lgo, byte *dIn, UINT
} }
// 4J-JEV: Reverse of loadGameRules. // 4J-JEV: Reverse of loadGameRules.
void GameRuleManager::saveGameRules(byte **dOut, UINT *dSize) void GameRuleManager::saveGameRules(uint8_t **dOut, UINT *dSize)
{ {
if (m_currentGameRuleDefinitions == NULL && if (m_currentGameRuleDefinitions == NULL &&
m_currentLevelGenerationOptions == NULL) m_currentLevelGenerationOptions == NULL)
@@ -373,7 +373,7 @@ void GameRuleManager::writeRuleFile(DataOutputStream *dos)
m_currentGameRuleDefinitions->write(dos); m_currentGameRuleDefinitions->write(dos);
} }
bool GameRuleManager::readRuleFile(LevelGenerationOptions *lgo, byte *dIn, UINT dSize, StringTable *strings) //(DLCGameRulesFile *dlcFile, StringTable *strings) bool GameRuleManager::readRuleFile(LevelGenerationOptions *lgo, uint8_t *dIn, UINT dSize, StringTable *strings) //(DLCGameRulesFile *dlcFile, StringTable *strings)
{ {
bool levelGenAdded = false; bool levelGenAdded = false;
bool gameRulesAdded = false; bool gameRulesAdded = false;
@@ -667,11 +667,42 @@ void GameRuleManager::loadDefaultGameRules()
if ( app.m_dlcManager.readDLCDataFile(dwFilesProcessed,fpTutorial,pack,true) ) if ( app.m_dlcManager.readDLCDataFile(dwFilesProcessed,fpTutorial,pack,true) )
{ {
app.m_dlcManager.addPack(pack); app.m_dlcManager.addPack(pack);
if (!m_levelGenerators.getLevelGenerators()->empty())
{
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL)); m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL));
m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME)); m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME));
} }
else delete pack; else
{
app.DebugPrintf("loadDefaultGameRules: Tutorial.pck parsed OK but no level generators were added (missing GameRules/LevelGenerationOptions tag?)\n");
} }
}
else
{
app.DebugPrintf("loadDefaultGameRules: readDLCDataFile failed for Tutorial.pck (version too old, IO error, or DLC_TYPE_GameRules not found)\n");
delete pack;
}
}
else
{
app.DebugPrintf("loadDefaultGameRules: Tutorial.pck not found in archive\n");
}
// Linux/PC port fallback: if Tutorial.pck parsing didn't populate level generators
// (e.g. DLC version mismatch, missing GameRules tag), create a minimal placeholder so
// the game doesn't crash with vector::at(0) in LoadTrial().
if (m_levelGenerators.getLevelGenerators()->empty())
{
app.DebugPrintf("loadDefaultGameRules: creating minimal fallback LevelGenerationOptions\n");
LevelGenerationOptions *lgo = new LevelGenerationOptions();
lgo->setGrSource(new JustGrSource());
lgo->setSrc(LevelGenerationOptions::eSrc_tutorial);
lgo->setWorldName(app.GetString(IDS_PLAY_TUTORIAL));
lgo->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME));
lgo->setLoadedData();
addLevelGenerationOptions(lgo);
}
/*StringTable *strings = new StringTable(baStrings.data, baStrings.length); /*StringTable *strings = new StringTable(baStrings.data, baStrings.length);
LevelGenerationOptions *lgo = new LevelGenerationOptions(); LevelGenerationOptions *lgo = new LevelGenerationOptions();
lgo->setGrSource( new JustGrSource() ); lgo->setGrSource( new JustGrSource() );
@@ -40,10 +40,10 @@ public:
void loadGameRules(DLCPack *); void loadGameRules(DLCPack *);
LevelGenerationOptions *loadGameRules(byte *dIn, UINT dSize); LevelGenerationOptions *loadGameRules(uint8_t *dIn, UINT dSize);
void loadGameRules(LevelGenerationOptions *lgo, byte *dIn, UINT dSize); void loadGameRules(LevelGenerationOptions *lgo, uint8_t *dIn, UINT dSize);
void saveGameRules(byte **dOut, UINT *dSize); void saveGameRules(uint8_t **dOut, UINT *dSize);
private: private:
LevelGenerationOptions *readHeader(DLCGameRulesHeader *grh); LevelGenerationOptions *readHeader(DLCGameRulesHeader *grh);
@@ -51,7 +51,7 @@ private:
void writeRuleFile(DataOutputStream *dos); void writeRuleFile(DataOutputStream *dos);
public: public:
bool readRuleFile(LevelGenerationOptions *lgo, byte *dIn, UINT dSize, StringTable *strings); //(DLCGameRulesFile *dlcFile, StringTable *strings); bool readRuleFile(LevelGenerationOptions *lgo, uint8_t *dIn, UINT dSize, StringTable *strings); //(DLCGameRulesFile *dlcFile, StringTable *strings);
private: private:
void readAttributes(DataInputStream *dis, vector<wstring> *tagsAndAtts, GameRuleDefinition *rule); void readAttributes(DataInputStream *dis, vector<wstring> *tagsAndAtts, GameRuleDefinition *rule);
@@ -9,6 +9,8 @@ const wstring LeaderboardManager::filterNames[eNumFilterModes] =
L"Friends", L"MyScore", L"TopRank" L"Friends", L"MyScore", L"TopRank"
}; };
LeaderboardManager *LeaderboardManager::m_instance = NULL;
void LeaderboardManager::DeleteInstance() void LeaderboardManager::DeleteInstance()
{ {
delete m_instance; delete m_instance;
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiDLCPriceTag L"XuiDLCPriceTag" #define IDC_XuiDLCPriceTag L"XuiDLCPriceTag"
#define IDC_XuiDLCBackground L"XuiDLCBackground" #define IDC_XuiDLCBackground L"XuiDLCBackground"
#define IDC_XuiDLCBanner L"XuiDLCBanner" #define IDC_XuiDLCBanner L"XuiDLCBanner"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_XuiHTMLMessage L"XuiHTMLMessage" #define IDC_XuiHTMLMessage L"XuiHTMLMessage"
#define IDC_NewUpdate L"NewUpdate" #define IDC_NewUpdate L"NewUpdate"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_XuiHTMLMessage L"XuiHTMLMessage" #define IDC_XuiHTMLMessage L"XuiHTMLMessage"
#define IDC_NewUpdate L"NewUpdate" #define IDC_NewUpdate L"NewUpdate"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_AnvilText L"AnvilText" #define IDC_AnvilText L"AnvilText"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_BottomLeftAnchorPoint L"BottomLeftAnchorPoint" #define IDC_BottomLeftAnchorPoint L"BottomLeftAnchorPoint"
#define IDC_TopLeftAnchorPoint L"TopLeftAnchorPoint" #define IDC_TopLeftAnchorPoint L"TopLeftAnchorPoint"
#define IDC_XuiDarkOverlay L"XuiDarkOverlay" #define IDC_XuiDarkOverlay L"XuiDarkOverlay"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiDarkOverlay L"XuiDarkOverlay" #define IDC_XuiDarkOverlay L"XuiDarkOverlay"
#define IDC_Background L"Background" #define IDC_Background L"Background"
#define IDC_Logo L"Logo" #define IDC_Logo L"Logo"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiDarkOverlay L"XuiDarkOverlay" #define IDC_XuiDarkOverlay L"XuiDarkOverlay"
#define IDC_Background L"Background" #define IDC_Background L"Background"
#define IDC_Logo L"Logo" #define IDC_Logo L"Logo"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiBack1 L"XuiBack1" #define IDC_XuiBack1 L"XuiBack1"
#define IDC_XuiLabel1 L"XuiLabel1" #define IDC_XuiLabel1 L"XuiLabel1"
#define IDC_XuiBack2 L"XuiBack2" #define IDC_XuiBack2 L"XuiBack2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiBack1 L"XuiBack1" #define IDC_XuiBack1 L"XuiBack1"
#define IDC_XuiLabel1 L"XuiLabel1" #define IDC_XuiLabel1 L"XuiLabel1"
#define IDC_XuiBack2 L"XuiBack2" #define IDC_XuiBack2 L"XuiBack2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiBack1 L"XuiBack1" #define IDC_XuiBack1 L"XuiBack1"
#define IDC_XuiLabel1 L"XuiLabel1" #define IDC_XuiLabel1 L"XuiLabel1"
#define IDC_XuiBack2 L"XuiBack2" #define IDC_XuiBack2 L"XuiBack2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
#define IDC_Progress L"Progress" #define IDC_Progress L"Progress"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
#define IDC_Progress L"Progress" #define IDC_Progress L"Progress"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
#define IDC_Progress L"Progress" #define IDC_Progress L"Progress"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Controller L"Controller" #define IDC_Controller L"Controller"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Controller L"Controller" #define IDC_Controller L"Controller"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Controller L"Controller" #define IDC_Controller L"Controller"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_MainPanel L"MainPanel" #define IDC_MainPanel L"MainPanel"
#define IDC_TabImage1 L"TabImage1" #define IDC_TabImage1 L"TabImage1"
#define IDC_TabImage2 L"TabImage2" #define IDC_TabImage2 L"TabImage2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Background L"Background" #define IDC_Background L"Background"
#define IDC_XuiText1 L"XuiText1" #define IDC_XuiText1 L"XuiText1"
#define IDC_XuiText2 L"XuiText2" #define IDC_XuiText2 L"XuiText2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Background L"Background" #define IDC_Background L"Background"
#define IDC_XuiText1 L"XuiText1" #define IDC_XuiText1 L"XuiText1"
#define IDC_XuiText2 L"XuiText2" #define IDC_XuiText2 L"XuiText2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_ExitGame L"ExitGame" #define IDC_ExitGame L"ExitGame"
#define IDC_Respawn L"Respawn" #define IDC_Respawn L"Respawn"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_ExitGame L"ExitGame" #define IDC_ExitGame L"ExitGame"
#define IDC_Respawn L"Respawn" #define IDC_Respawn L"Respawn"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_ExitGame L"ExitGame" #define IDC_ExitGame L"ExitGame"
#define IDC_Respawn L"Respawn" #define IDC_Respawn L"Respawn"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiImage1 L"XuiImage1" #define IDC_XuiImage1 L"XuiImage1"
#define IDC_XuiCheckbox1 L"XuiCheckbox1" #define IDC_XuiCheckbox1 L"XuiCheckbox1"
#define IDC_XuiCheckbox2 L"XuiCheckbox2" #define IDC_XuiCheckbox2 L"XuiCheckbox2"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiCheckbox1 L"XuiCheckbox1" #define IDC_XuiCheckbox1 L"XuiCheckbox1"
#define IDC_XuiCheckbox2 L"XuiCheckbox2" #define IDC_XuiCheckbox2 L"XuiCheckbox2"
#define IDC_XuiCheckbox3 L"XuiCheckbox3" #define IDC_XuiCheckbox3 L"XuiCheckbox3"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_icon L"icon" #define IDC_icon L"icon"
#define IDC_itemName L"itemName" #define IDC_itemName L"itemName"
#define IDC_itemId L"itemId" #define IDC_itemId L"itemId"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_StartX L"StartX" #define IDC_StartX L"StartX"
#define IDC_StartY L"StartY" #define IDC_StartY L"StartY"
#define IDC_StartZ L"StartZ" #define IDC_StartZ L"StartZ"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_CamX L"CamX" #define IDC_CamX L"CamX"
#define IDC_CamZ L"CamZ" #define IDC_CamZ L"CamZ"
#define IDC_YRot L"YRot" #define IDC_YRot L"YRot"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_XuiCheckbox1 L"XuiCheckbox1" #define IDC_XuiCheckbox1 L"XuiCheckbox1"
#define IDC_SceneDebug L"SceneDebug" #define IDC_SceneDebug L"SceneDebug"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_ItemsList L"ItemsList" #define IDC_ItemsList L"ItemsList"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_DebugTips L"DebugTips" #define IDC_DebugTips L"DebugTips"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_DebugTips L"DebugTips" #define IDC_DebugTips L"DebugTips"
@@ -1,2 +1,3 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_DebugTips L"DebugTips" #define IDC_DebugTips L"DebugTips"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Tip L"Tip" #define IDC_Tip L"Tip"
#define IDC_Status L"Status" #define IDC_Status L"Status"
#define IDC_Title L"Title" #define IDC_Title L"Title"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiButton1 L"XuiButton1" #define IDC_XuiButton1 L"XuiButton1"
#define IDC_XuiButton2 L"XuiButton2" #define IDC_XuiButton2 L"XuiButton2"
#define IDC_XuiButton3 L"XuiButton3" #define IDC_XuiButton3 L"XuiButton3"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiButton1 L"XuiButton1" #define IDC_XuiButton1 L"XuiButton1"
#define IDC_XuiButton2 L"XuiButton2" #define IDC_XuiButton2 L"XuiButton2"
#define IDC_XuiButton3 L"XuiButton3" #define IDC_XuiButton3 L"XuiButton3"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiButton1 L"XuiButton1" #define IDC_XuiButton1 L"XuiButton1"
#define IDC_XuiButton2 L"XuiButton2" #define IDC_XuiButton2 L"XuiButton2"
#define IDC_XuiButton3 L"XuiButton3" #define IDC_XuiButton3 L"XuiButton3"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiImageNetherPortal L"XuiImageNetherPortal" #define IDC_XuiImageNetherPortal L"XuiImageNetherPortal"
#define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal" #define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal"
#define IDC_XuiImageTheEnd L"XuiImageTheEnd" #define IDC_XuiImageTheEnd L"XuiImageTheEnd"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd" #define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd"
#define IDC_XuiImageTheEnd L"XuiImageTheEnd" #define IDC_XuiImageTheEnd L"XuiImageTheEnd"
#define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal" #define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_control_ListItem L"control_ListItem" #define IDC_control_ListItem L"control_ListItem"
#define IDC_HowToListButtons L"HowToListButtons" #define IDC_HowToListButtons L"HowToListButtons"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd" #define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd"
#define IDC_XuiImageTheEnd L"XuiImageTheEnd" #define IDC_XuiImageTheEnd L"XuiImageTheEnd"
#define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal" #define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Crosshair L"Crosshair" #define IDC_Crosshair L"Crosshair"
#define IDC_Box L"Box" #define IDC_Box L"Box"
#define IDC_Inventory1 L"Inventory1" #define IDC_Inventory1 L"Inventory1"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Crosshair L"Crosshair" #define IDC_Crosshair L"Crosshair"
#define IDC_Box L"Box" #define IDC_Box L"Box"
#define IDC_Inventory1 L"Inventory1" #define IDC_Inventory1 L"Inventory1"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_Crosshair L"Crosshair" #define IDC_Crosshair L"Crosshair"
#define IDC_Box L"Box" #define IDC_Box L"Box"
#define IDC_Inventory1 L"Inventory1" #define IDC_Inventory1 L"Inventory1"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_CheckboxTNT L"CheckboxTNT" #define IDC_CheckboxTNT L"CheckboxTNT"
#define IDC_CheckboxFireSpreads L"CheckboxFireSpreads" #define IDC_CheckboxFireSpreads L"CheckboxFireSpreads"
#define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer" #define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer"
@@ -1,3 +1,4 @@
#pragma once
#define IDC_CheckboxTNT L"CheckboxTNT" #define IDC_CheckboxTNT L"CheckboxTNT"
#define IDC_CheckboxFireSpreads L"CheckboxFireSpreads" #define IDC_CheckboxFireSpreads L"CheckboxFireSpreads"
#define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer" #define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer"

Some files were not shown because too many files have changed in this diff Show More