mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-27 00:23:37 +00:00
Merge pull request #48 from create-juicey-app/dev
hmmm forkss yum.. hmmmhpph.. hmmh yummy
This commit is contained in:
commit
09eae49d21
231
.github/workflows/build-linux.yml
vendored
Normal file
231
.github/workflows/build-linux.yml
vendored
Normal 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
.github/workflows/ci.yml
vendored
Normal file
49
.github/workflows/ci.yml
vendored
Normal 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
|
||||
44
.gitignore
vendored
44
.gitignore
vendored
|
|
@ -1,24 +1,50 @@
|
|||
# ----- Build output directories -----
|
||||
build/
|
||||
builddir/
|
||||
.cache/
|
||||
.idea/
|
||||
build_meson/
|
||||
build_meson2/
|
||||
build_meson_new/
|
||||
build_meson_test/
|
||||
cmake-build-debug/
|
||||
|
||||
# CMake generated
|
||||
# Final binaries and platform output
|
||||
/Linux/
|
||||
/x64/
|
||||
|
||||
# CMake generated artifacts
|
||||
CMakeCache.txt
|
||||
CMakeFiles/
|
||||
cmake_install.cmake
|
||||
Makefile
|
||||
compile_commands.json
|
||||
|
||||
# IDE / editor
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
# Meson generated artifacts (inside source tree, e.g. per-subdir)
|
||||
meson-private/
|
||||
meson-info/
|
||||
meson-logs/
|
||||
|
||||
# Compiled objects / binaries
|
||||
# Compiler/linker intermediates
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
*.so.*
|
||||
*.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
|
||||
*~
|
||||
|
|
|
|||
|
|
@ -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 "../Minecraft.Client/Build/Common/App_enums.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
C_4JInput InputManager;
|
||||
|
||||
void C_4JInput::Initialise(int iInputStateC, unsigned char ucMapC, unsigned char ucActionC, unsigned char ucMenuActionC) {}
|
||||
void C_4JInput::Tick(void) {}
|
||||
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) {}
|
||||
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; }
|
||||
bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction) { return false; }
|
||||
bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction) { return false; }
|
||||
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; }
|
||||
float C_4JInput::GetJoypadStick_LX(int iPad, bool bCheckMenuDisplay) { return 0.0f; }
|
||||
float C_4JInput::GetJoypadStick_LY(int iPad, bool bCheckMenuDisplay) { return 0.0f; }
|
||||
float C_4JInput::GetJoypadStick_RX(int iPad, bool bCheckMenuDisplay) { return 0.0f; }
|
||||
float C_4JInput::GetJoypadStick_RY(int iPad, bool bCheckMenuDisplay) { return 0.0f; }
|
||||
unsigned char C_4JInput::GetJoypadLTrigger(int iPad, bool bCheckMenuDisplay) { return 0; }
|
||||
unsigned char C_4JInput::GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay) { return 0; }
|
||||
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) {}
|
||||
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; }
|
||||
// ---------------------------------------------------------------------------
|
||||
// State - all static to avoid adding new fields to C_4JInput
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static const int KEY_COUNT = GLFW_KEY_LAST + 1; // 349 on GLFW 3
|
||||
|
||||
static bool s_keysCurrent[KEY_COUNT] = {};
|
||||
static bool s_keysPrev[KEY_COUNT] = {};
|
||||
|
||||
static bool s_mouseLeftCurrent = false, s_mouseLeftPrev = false;
|
||||
static bool s_mouseRightCurrent = false, s_mouseRightPrev = false;
|
||||
|
||||
// Accumulated cursor delta from the GLFW cursor-pos callback.
|
||||
// Snapshotted into s_frameRelX/Y at Tick() start, then reset to 0.
|
||||
static double s_lastCursorX = 0.0, s_lastCursorY = 0.0;
|
||||
static bool s_cursorInitialized = false;
|
||||
static float s_mouseAccumX = 0.0f, s_mouseAccumY = 0.0f; // callback accumulator
|
||||
static float s_frameRelX = 0.0f, s_frameRelY = 0.0f; // per-frame snapshot
|
||||
|
||||
// Scroll wheel
|
||||
static float s_scrollAccum = 0.0f; // callback accumulator
|
||||
static float s_scrollFrame = 0.0f; // current frame snapshot
|
||||
static float s_scrollPrevFrame = 0.0f;
|
||||
|
||||
// Mouse lock / menu state
|
||||
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; }
|
||||
bool C_4JInput::VerifyStrings(WCHAR **pwStringA, int iStringC, int(*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) { return true; }
|
||||
void C_4JInput::CancelQueuedVerifyStrings(int(*Func)(LPVOID, STRING_VERIFY_RESPONSE *), LPVOID lpParam) {}
|
||||
bool C_4JInput::VerifyStrings(WCHAR ** /*pwStringA*/, int /*iStringC*/,
|
||||
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) {}
|
||||
|
|
|
|||
|
|
@ -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
4J.Input/meson.build
Normal file
21
4J.Input/meson.build
Normal 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('.'),
|
||||
)
|
||||
|
|
@ -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
4J.Profile/meson.build
Normal file
22
4J.Profile/meson.build
Normal 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('.'),
|
||||
)
|
||||
|
|
@ -1,62 +1,500 @@
|
|||
#include "4J_Render.h"
|
||||
#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>
|
||||
|
||||
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::DoScreenGrabOnNextPresent() {}
|
||||
|
||||
void C4JRender::Clear(int flags)
|
||||
{
|
||||
::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::IsHiDef() { return true; }
|
||||
void C4JRender::GetFramebufferSize(int &width, int &height) { width = s_windowWidth; height = s_windowHeight; }
|
||||
void C4JRender::CaptureThumbnail(ImageFileBuffer *) {}
|
||||
void C4JRender::CaptureScreen(ImageFileBuffer *, XSOCIAL_PREVIEWIMAGE *) {}
|
||||
void C4JRender::BeginConditionalSurvey(int) {}
|
||||
void C4JRender::EndConditionalSurvey() {}
|
||||
void C4JRender::BeginConditionalRendering(int){}
|
||||
void C4JRender::EndConditionalRendering() {}
|
||||
|
||||
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() {}
|
||||
|
||||
int C4JRender::CBuffCreate(int count)
|
||||
{
|
||||
return (int)::glGenLists(count);
|
||||
}
|
||||
|
||||
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::CBuffDeferredModeStart() {}
|
||||
void C4JRender::CBuffDeferredModeEnd() {}
|
||||
|
||||
|
||||
int C4JRender::TextureCreate()
|
||||
{
|
||||
GLuint id = 0;
|
||||
::glGenTextures(1, &id);
|
||||
return (int)id;
|
||||
}
|
||||
|
||||
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::TextureDynamicUpdateEnd() {}
|
||||
|
||||
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::Present() {}
|
||||
void C4JRender::Clear(int flags) {}
|
||||
void C4JRender::SetClearColour(const float colourRGBA[4]) {}
|
||||
bool C4JRender::IsWidescreen() { return true; }
|
||||
bool C4JRender::IsHiDef() { return true; }
|
||||
void C4JRender::CaptureThumbnail(ImageFileBuffer *pngOut) {}
|
||||
void C4JRender::CaptureScreen(ImageFileBuffer *jpgOut, XSOCIAL_PREVIEWIMAGE *previewOut) {}
|
||||
void C4JRender::BeginConditionalSurvey(int identifier) {}
|
||||
void C4JRender::EndConditionalSurvey() {}
|
||||
void C4JRender::BeginConditionalRendering(int identifier) {}
|
||||
void C4JRender::EndConditionalRendering() {}
|
||||
void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count, void *dataIn, eVertexType vType, C4JRender::ePixelShaderType psType) {}
|
||||
void C4JRender::CBuffLockStaticCreations() {}
|
||||
int C4JRender::CBuffCreate(int count) { return 0; }
|
||||
void C4JRender::CBuffDelete(int first, int count) {}
|
||||
void C4JRender::CBuffStart(int index, bool full) {}
|
||||
void C4JRender::CBuffClear(int index) {}
|
||||
int C4JRender::CBuffSize(int index) { return 0; }
|
||||
void C4JRender::CBuffEnd() {}
|
||||
bool C4JRender::CBuffCall(int index, bool full) { return false; }
|
||||
void C4JRender::CBuffTick() {}
|
||||
void C4JRender::CBuffDeferredModeStart() {}
|
||||
void C4JRender::CBuffDeferredModeEnd() {}
|
||||
int C4JRender::TextureCreate() { return 0; }
|
||||
void C4JRender::TextureFree(int idx) {}
|
||||
void C4JRender::TextureBind(int idx) {}
|
||||
void C4JRender::TextureBindVertex(int idx) {}
|
||||
void C4JRender::TextureSetTextureLevels(int levels) {}
|
||||
int C4JRender::TextureGetTextureLevels() { return 1; }
|
||||
void C4JRender::TextureData(int width, int height, void *data, int level, eTextureFormat format) {}
|
||||
void C4JRender::TextureDataUpdate(int xoffset, int yoffset, int width, int height, void *data, int level) {}
|
||||
void C4JRender::TextureSetParam(int param, int value) {}
|
||||
void C4JRender::TextureDynamicUpdateStart() {}
|
||||
void C4JRender::TextureDynamicUpdateEnd() {}
|
||||
void C4JRender::UpdateGamma(unsigned short) {}
|
||||
// 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__
|
||||
|
|
@ -161,37 +599,204 @@ HRESULT C4JRender::SaveTextureData(const char *szFilename, D3DXIMAGE_INFO *pSrcI
|
|||
HRESULT C4JRender::SaveTextureDataToMemory(void *pOutput, int outputCapacity, int *outputLength, int width, int height, int *ppDataIn) { return S_OK; }
|
||||
void C4JRender::TextureGetStats() {}
|
||||
void* C4JRender::TextureGetTexture(int idx) { return nullptr; }
|
||||
void C4JRender::StateSetColour(float r, float g, float b, float a) {}
|
||||
void C4JRender::StateSetDepthMask(bool enable) {}
|
||||
void C4JRender::StateSetBlendEnable(bool enable) {}
|
||||
void C4JRender::StateSetBlendFunc(int src, int dst) {}
|
||||
void C4JRender::StateSetBlendFactor(unsigned int colour) {}
|
||||
void C4JRender::StateSetAlphaFunc(int func, float param) {}
|
||||
void C4JRender::StateSetDepthFunc(int func) {}
|
||||
void C4JRender::StateSetFaceCull(bool enable) {}
|
||||
void C4JRender::StateSetFaceCullCW(bool enable) {}
|
||||
void C4JRender::StateSetLineWidth(float width) {}
|
||||
void C4JRender::StateSetWriteEnable(bool red, bool green, bool blue, bool alpha) {}
|
||||
void C4JRender::StateSetDepthTestEnable(bool enable) {}
|
||||
void C4JRender::StateSetAlphaTestEnable(bool enable) {}
|
||||
void C4JRender::StateSetDepthSlopeAndBias(float slope, float bias) {}
|
||||
void C4JRender::StateSetFogEnable(bool enable) {}
|
||||
void C4JRender::StateSetFogMode(int mode) {}
|
||||
void C4JRender::StateSetFogNearDistance(float dist) {}
|
||||
void C4JRender::StateSetFogFarDistance(float dist) {}
|
||||
void C4JRender::StateSetFogDensity(float density) {}
|
||||
void C4JRender::StateSetFogColour(float red, float green, float blue) {}
|
||||
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::StateSetLightAmbientColour(float red, float green, float blue) {}
|
||||
void C4JRender::StateSetLightDirection(int light, float x, float y, float z) {}
|
||||
void C4JRender::StateSetLightEnable(int light, bool enable) {}
|
||||
void C4JRender::StateSetViewport(eViewportType viewportType) {}
|
||||
void C4JRender::StateSetEnableViewportClipPlanes(bool enable) {}
|
||||
void C4JRender::StateSetTexGenCol(int col, float x, float y, float z, float w, bool eyeSpace) {}
|
||||
void C4JRender::StateSetStencil(int Function, uint8_t stencil_ref, uint8_t stencil_func_mask, uint8_t stencil_write_mask) {}
|
||||
void C4JRender::StateSetForceLOD(int LOD) {}
|
||||
|
||||
// we handle opengl calls cuz multiplatform is painful!!
|
||||
void C4JRender::StateSetColour(float r, float g, float b, float a)
|
||||
{
|
||||
::glColor4f(r, g, b, a);
|
||||
}
|
||||
|
||||
void C4JRender::StateSetDepthMask(bool enable)
|
||||
{
|
||||
::glDepthMask(enable ? GL_TRUE : GL_FALSE);
|
||||
}
|
||||
|
||||
void C4JRender::StateSetBlendEnable(bool enable)
|
||||
{
|
||||
if (enable) ::glEnable(GL_BLEND); else ::glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
void C4JRender::StateSetBlendFunc(int src, int dst)
|
||||
{
|
||||
::glBlendFunc(src, dst);
|
||||
}
|
||||
|
||||
void C4JRender::StateSetBlendFactor(unsigned int colour)
|
||||
{
|
||||
// colour is 0xAARRGGBB packed
|
||||
float a = ((colour >> 24) & 0xFF) / 255.0f;
|
||||
float r = ((colour >> 16) & 0xFF) / 255.0f;
|
||||
float g = ((colour >> 8) & 0xFF) / 255.0f;
|
||||
float b = ( colour & 0xFF) / 255.0f;
|
||||
::glBlendColor(r, g, b, a);
|
||||
}
|
||||
|
||||
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::EndEvent() {}
|
||||
void C4JRender::Suspend() {}
|
||||
|
|
|
|||
|
|
@ -63,6 +63,10 @@ public:
|
|||
// Core
|
||||
void Initialise();
|
||||
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 DoScreenGrabOnNextPresent();
|
||||
void Present();
|
||||
|
|
@ -70,6 +74,7 @@ public:
|
|||
void SetClearColour(const float colourRGBA[4]);
|
||||
bool IsWidescreen();
|
||||
bool IsHiDef();
|
||||
void GetFramebufferSize(int &width, int &height);
|
||||
void CaptureThumbnail(ImageFileBuffer *pngOut);
|
||||
void CaptureScreen(ImageFileBuffer *jpgOut, XSOCIAL_PREVIEWIMAGE *previewOut);
|
||||
void BeginConditionalSurvey(int identifier);
|
||||
|
|
@ -206,6 +211,10 @@ public:
|
|||
void Suspend();
|
||||
bool Suspended();
|
||||
void Resume();
|
||||
|
||||
// Linux window management
|
||||
bool ShouldClose();
|
||||
void Shutdown();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
4J.Render/meson.build
Normal file
24
4J.Render/meson.build
Normal 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('.'),
|
||||
)
|
||||
|
|
@ -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
4J.Storage/meson.build
Normal file
20
4J.Storage/meson.build
Normal 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('.'),
|
||||
)
|
||||
|
|
@ -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}")
|
||||
|
|
@ -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()
|
||||
|
|
@ -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()
|
||||
|
|
@ -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
CMakeLists.txt
117
CMakeLists.txt
|
|
@ -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)
|
||||
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -7729,7 +7729,7 @@ unsigned int CMinecraftApp::CreateImageTextData(PBYTE bTextMetadata, __int64 see
|
|||
if(hasSeed)
|
||||
{
|
||||
strcpy((char *)bTextMetadata,"4J_SEED");
|
||||
snprintf((char *)&bTextMetadata[8], 42, NULL, seed);
|
||||
snprintf((char *)&bTextMetadata[8], 42, "%lld", (long long)seed);
|
||||
|
||||
// get the length
|
||||
iTextMetadataBytes+=8;
|
||||
|
|
|
|||
|
|
@ -667,11 +667,42 @@ void GameRuleManager::loadDefaultGameRules()
|
|||
if ( app.m_dlcManager.readDLCDataFile(dwFilesProcessed,fpTutorial,pack,true) )
|
||||
{
|
||||
app.m_dlcManager.addPack(pack);
|
||||
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL));
|
||||
m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME));
|
||||
if (!m_levelGenerators.getLevelGenerators()->empty())
|
||||
{
|
||||
m_levelGenerators.getLevelGenerators()->at(0)->setWorldName(app.GetString(IDS_PLAY_TUTORIAL));
|
||||
m_levelGenerators.getLevelGenerators()->at(0)->setDefaultSaveName(app.GetString(IDS_TUTORIALSAVENAME));
|
||||
}
|
||||
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 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);
|
||||
LevelGenerationOptions *lgo = new LevelGenerationOptions();
|
||||
lgo->setGrSource( new JustGrSource() );
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ const wstring LeaderboardManager::filterNames[eNumFilterModes] =
|
|||
L"Friends", L"MyScore", L"TopRank"
|
||||
};
|
||||
|
||||
LeaderboardManager *LeaderboardManager::m_instance = NULL;
|
||||
|
||||
void LeaderboardManager::DeleteInstance()
|
||||
{
|
||||
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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiDLCPriceTag L"XuiDLCPriceTag"
|
||||
#define IDC_XuiDLCBackground L"XuiDLCBackground"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_XuiHTMLMessage L"XuiHTMLMessage"
|
||||
#define IDC_NewUpdate L"NewUpdate"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_XuiHTMLMessage L"XuiHTMLMessage"
|
||||
#define IDC_NewUpdate L"NewUpdate"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_AnvilText L"AnvilText"
|
||||
#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_TopLeftAnchorPoint L"TopLeftAnchorPoint"
|
||||
#define IDC_XuiDarkOverlay L"XuiDarkOverlay"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiDarkOverlay L"XuiDarkOverlay"
|
||||
#define IDC_Background L"Background"
|
||||
#define IDC_Logo L"Logo"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiDarkOverlay L"XuiDarkOverlay"
|
||||
#define IDC_Background L"Background"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiBack1 L"XuiBack1"
|
||||
#define IDC_XuiLabel1 L"XuiLabel1"
|
||||
#define IDC_XuiBack2 L"XuiBack2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiBack1 L"XuiBack1"
|
||||
#define IDC_XuiLabel1 L"XuiLabel1"
|
||||
#define IDC_XuiBack2 L"XuiBack2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiBack1 L"XuiBack1"
|
||||
#define IDC_XuiLabel1 L"XuiLabel1"
|
||||
#define IDC_XuiBack2 L"XuiBack2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Status L"Status"
|
||||
#define IDC_Title L"Title"
|
||||
#define IDC_Progress L"Progress"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Status L"Status"
|
||||
#define IDC_Title L"Title"
|
||||
#define IDC_Progress L"Progress"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Status L"Status"
|
||||
#define IDC_Title L"Title"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Controller L"Controller"
|
||||
#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_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_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_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_MainPanel L"MainPanel"
|
||||
#define IDC_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_MainPanel L"MainPanel"
|
||||
#define IDC_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_MainPanel L"MainPanel"
|
||||
#define IDC_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_MainPanel L"MainPanel"
|
||||
#define IDC_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_MainPanel L"MainPanel"
|
||||
#define IDC_TabImage1 L"TabImage1"
|
||||
#define IDC_TabImage2 L"TabImage2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Background L"Background"
|
||||
#define IDC_XuiText1 L"XuiText1"
|
||||
#define IDC_XuiText2 L"XuiText2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Background L"Background"
|
||||
#define IDC_XuiText1 L"XuiText1"
|
||||
#define IDC_XuiText2 L"XuiText2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_ExitGame L"ExitGame"
|
||||
#define IDC_Respawn L"Respawn"
|
||||
#define IDC_Title L"Title"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_ExitGame L"ExitGame"
|
||||
#define IDC_Respawn L"Respawn"
|
||||
#define IDC_Title L"Title"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_ExitGame L"ExitGame"
|
||||
#define IDC_Respawn L"Respawn"
|
||||
#define IDC_Title L"Title"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiImage1 L"XuiImage1"
|
||||
#define IDC_XuiCheckbox1 L"XuiCheckbox1"
|
||||
#define IDC_XuiCheckbox2 L"XuiCheckbox2"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiCheckbox1 L"XuiCheckbox1"
|
||||
#define IDC_XuiCheckbox2 L"XuiCheckbox2"
|
||||
#define IDC_XuiCheckbox3 L"XuiCheckbox3"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_icon L"icon"
|
||||
#define IDC_itemName L"itemName"
|
||||
#define IDC_itemId L"itemId"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_StartX L"StartX"
|
||||
#define IDC_StartY L"StartY"
|
||||
#define IDC_StartZ L"StartZ"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CamX L"CamX"
|
||||
#define IDC_CamZ L"CamZ"
|
||||
#define IDC_YRot L"YRot"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_XuiCheckbox1 L"XuiCheckbox1"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_control_ListItem L"control_ListItem"
|
||||
#define IDC_ItemsList L"ItemsList"
|
||||
#define IDC_control_ListItem L"control_ListItem"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#define IDC_DebugTips L"DebugTips"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#define IDC_DebugTips L"DebugTips"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#define IDC_Status L"Status"
|
||||
#define IDC_Title L"Title"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#define IDC_Status L"Status"
|
||||
#define IDC_Title L"Title"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Tip L"Tip"
|
||||
#define IDC_Status L"Status"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiButton1 L"XuiButton1"
|
||||
#define IDC_XuiButton2 L"XuiButton2"
|
||||
#define IDC_XuiButton3 L"XuiButton3"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiButton1 L"XuiButton1"
|
||||
#define IDC_XuiButton2 L"XuiButton2"
|
||||
#define IDC_XuiButton3 L"XuiButton3"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiButton1 L"XuiButton1"
|
||||
#define IDC_XuiButton2 L"XuiButton2"
|
||||
#define IDC_XuiButton3 L"XuiButton3"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiImageNetherPortal L"XuiImageNetherPortal"
|
||||
#define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal"
|
||||
#define IDC_XuiImageTheEnd L"XuiImageTheEnd"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd"
|
||||
#define IDC_XuiImageTheEnd L"XuiImageTheEnd"
|
||||
#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"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_control_ListItem L"control_ListItem"
|
||||
#define IDC_control_ListItem L"control_ListItem"
|
||||
#define IDC_HowToListButtons L"HowToListButtons"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_XuiHtmlControlTheEnd L"XuiHtmlControlTheEnd"
|
||||
#define IDC_XuiImageTheEnd L"XuiImageTheEnd"
|
||||
#define IDC_XuiHtmlControlNetherPortal L"XuiHtmlControlNetherPortal"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Crosshair L"Crosshair"
|
||||
#define IDC_Box L"Box"
|
||||
#define IDC_Inventory1 L"Inventory1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Crosshair L"Crosshair"
|
||||
#define IDC_Box L"Box"
|
||||
#define IDC_Inventory1 L"Inventory1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_Crosshair L"Crosshair"
|
||||
#define IDC_Box L"Box"
|
||||
#define IDC_Inventory1 L"Inventory1"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxTNT L"CheckboxTNT"
|
||||
#define IDC_CheckboxFireSpreads L"CheckboxFireSpreads"
|
||||
#define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxTNT L"CheckboxTNT"
|
||||
#define IDC_CheckboxFireSpreads L"CheckboxFireSpreads"
|
||||
#define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxTNT L"CheckboxTNT"
|
||||
#define IDC_CheckboxFireSpreads L"CheckboxFireSpreads"
|
||||
#define IDC_ButtonTeleportToPlayer L"ButtonTeleportToPlayer"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxHostInvisible L"CheckboxHostInvisible"
|
||||
#define IDC_CheckboxHostHunger L"CheckboxHostHunger"
|
||||
#define IDC_CheckboxHostFly L"CheckboxHostFly"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxHostInvisible L"CheckboxHostInvisible"
|
||||
#define IDC_CheckboxHostHunger L"CheckboxHostHunger"
|
||||
#define IDC_CheckboxHostFly L"CheckboxHostFly"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
#pragma once
|
||||
#define IDC_CheckboxHostInvisible L"CheckboxHostInvisible"
|
||||
#define IDC_CheckboxHostHunger L"CheckboxHostHunger"
|
||||
#define IDC_CheckboxHostFly L"CheckboxHostFly"
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue