mirror of
https://github.com/4jcraft/4jcraft.git
synced 2026-04-24 08:03:41 +00:00
Merge branch 'dev' into feat/restore-java-gui
This commit is contained in:
commit
cf3defee35
|
|
@ -9,29 +9,16 @@ RUN apt-get update \
|
|||
&& apt-get update \
|
||||
&& apt-get install -y \
|
||||
build-essential \
|
||||
cmake \
|
||||
libglfw3-dev \
|
||||
python3 \
|
||||
ninja-build \
|
||||
meson \
|
||||
libsdl2-dev \
|
||||
libgl-dev \
|
||||
libglu1-mesa-dev \
|
||||
libopenal-dev \
|
||||
libvorbis-dev \
|
||||
libpng-dev \
|
||||
libpthread-stubs0-dev \
|
||||
clang \
|
||||
lld \
|
||||
meson \
|
||||
ninja-build \
|
||||
gcc-15 \
|
||||
g++-15 \
|
||||
libpthread-stubs0-dev
|
||||
# Clean up lol
|
||||
&& apt-get autoremove -y \
|
||||
&& apt-get clean -y \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Set GCC 15 as default
|
||||
RUN update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-15 100 \
|
||||
&& update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-15 100 \
|
||||
&& update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 100 \
|
||||
&& update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100
|
||||
|
||||
ENV DEBIAN_FRONTEND=dialog
|
||||
207
.github/workflows/build-linux.yml
vendored
207
.github/workflows/build-linux.yml
vendored
|
|
@ -1,4 +1,4 @@
|
|||
name: Build Linux Release
|
||||
name: Build (Linux, x86_64)
|
||||
|
||||
on:
|
||||
push:
|
||||
|
|
@ -25,9 +25,6 @@ on:
|
|||
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
|
||||
|
|
@ -35,26 +32,10 @@ jobs:
|
|||
- 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
|
||||
sudo apt-get install -y build-essential python3 ninja-build meson libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-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:
|
||||
|
|
@ -75,7 +56,51 @@ jobs:
|
|||
run: |
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
export CCACHE_DIR="$CCACHE_DIR"
|
||||
meson setup build_meson --wipe --buildtype=release
|
||||
meson setup build_release --wipe --buildtype=release --native-file=./scripts/llvm_native.txt
|
||||
|
||||
- name: Build with Meson
|
||||
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
|
||||
meson compile -C build_release -j $(nproc) -v Minecraft.Client
|
||||
|
||||
- name: Install patchelf
|
||||
run: sudo apt-get install -y patchelf
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: minecraft-client-linux-release_exe-${{ github.sha }}
|
||||
path: build_release/Minecraft.Client/Minecraft.Client
|
||||
retention-days: 7
|
||||
build-linux-debug:
|
||||
runs-on: ubuntu-latest
|
||||
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 ninja-build meson libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev
|
||||
# Set a reasonable ccache size
|
||||
ccache -M 5G || true
|
||||
|
||||
- name: Restore ccache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.ccache
|
||||
key: ${{ runner.os }}-ccache-debug-${{ hashFiles('**/meson.build') }}
|
||||
|
||||
- name: Restore meson cache
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ~/.cache/meson
|
||||
key: ${{ runner.os }}-meson-debug-${{ hashFiles('**/meson.build') }}
|
||||
|
||||
- name: Configure Meson (debug)
|
||||
env:
|
||||
|
|
@ -85,9 +110,9 @@ jobs:
|
|||
run: |
|
||||
mkdir -p "$CCACHE_DIR"
|
||||
export CCACHE_DIR="$CCACHE_DIR"
|
||||
meson setup build_debug --wipe --buildtype=debug
|
||||
meson setup build_debug --wipe --buildtype=debug --native-file=./scripts/llvm_native.txt
|
||||
|
||||
- name: Build with Ninja
|
||||
- name: Build Debug with Meson
|
||||
env:
|
||||
CC: "ccache clang"
|
||||
CXX: "ccache clang++"
|
||||
|
|
@ -95,137 +120,11 @@ jobs:
|
|||
run: |
|
||||
export CCACHE_DIR="${{ runner.temp }}/ccache"
|
||||
# Use all available cores for faster parallel builds
|
||||
ninja -C build_meson -j$(nproc) -v
|
||||
meson compile -C build_debug -j $(nproc) -v Minecraft.Client
|
||||
|
||||
- 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
|
||||
- name: Upload debug executable
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: minecraft-client-linux-${{ github.sha }}
|
||||
path: |
|
||||
out/minecraft-client-linux-*/
|
||||
out/minecraft-client-linux-*-debug/
|
||||
name: minecraft-client-linux-debug_exe-${{ github.sha }}
|
||||
path: build_debug/Minecraft.Client/Minecraft.Client
|
||||
retention-days: 7
|
||||
|
|
|
|||
49
.github/workflows/ci.yml
vendored
49
.github/workflows/ci.yml
vendored
|
|
@ -1,49 +0,0 @@
|
|||
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
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -29,7 +29,7 @@ meson-logs/
|
|||
*.out
|
||||
*.d
|
||||
compile_commands.json
|
||||
|
||||
.clangd
|
||||
|
||||
|
||||
# ----- Scratch / legacy -----
|
||||
|
|
|
|||
|
|
@ -1,536 +1,338 @@
|
|||
// 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/Platform/Common/App_enums.h"
|
||||
#include <GLFW/glfw3.h>
|
||||
#include "../4J.Render/4J_Render.h"
|
||||
#include <SDL2/SDL.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
C_4JInput InputManager;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// 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 const int KEY_COUNT = SDL_NUM_SCANCODES;
|
||||
static const float MOUSE_SCALE = 0.015f;
|
||||
// Vars
|
||||
static bool s_sdlInitialized = false;
|
||||
static bool s_keysCurrent[KEY_COUNT] = {};
|
||||
static bool s_keysPrev[KEY_COUNT] = {};
|
||||
|
||||
static bool s_keysPrev [KEY_COUNT] = {};
|
||||
static bool s_mouseLeftCurrent = false, s_mouseLeftPrev = false;
|
||||
static bool s_mouseRightCurrent = false, s_mouseRightPrev = false;
|
||||
static bool s_menuDisplayed[4] = {};
|
||||
static bool s_prevMenuDisplayed = false;
|
||||
static bool s_snapTaken = false;
|
||||
static float s_accumRelX = 0, s_accumRelY = 0;
|
||||
static float s_snapRelX = 0, s_snapRelY = 0;
|
||||
|
||||
// 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
|
||||
static int s_scrollTicksForButtonPressed = 0;
|
||||
static int s_scrollTicksForGetValue = 0;
|
||||
static int s_scrollTicksSnap = 0;
|
||||
static bool s_scrollSnapTaken = false;
|
||||
|
||||
// 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) {
|
||||
float scaleX = 1;
|
||||
float scaleY = 1;
|
||||
glfwGetWindowContentScale(w, &scaleX, &scaleY);
|
||||
|
||||
x *= scaleX;
|
||||
y *= scaleX;
|
||||
|
||||
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)
|
||||
// We set all the watched keys
|
||||
// I don't know if I'll need to change this if we add chat support soon.
|
||||
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,
|
||||
SDL_SCANCODE_W, SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_D,
|
||||
SDL_SCANCODE_SPACE, SDL_SCANCODE_LSHIFT, SDL_SCANCODE_RSHIFT,
|
||||
SDL_SCANCODE_E, SDL_SCANCODE_Q, SDL_SCANCODE_F,
|
||||
SDL_SCANCODE_C, SDL_SCANCODE_ESCAPE, SDL_SCANCODE_RETURN,
|
||||
SDL_SCANCODE_F3, SDL_SCANCODE_F5,
|
||||
SDL_SCANCODE_UP, SDL_SCANCODE_DOWN, SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT,
|
||||
SDL_SCANCODE_PAGEUP, SDL_SCANCODE_PAGEDOWN,
|
||||
SDL_SCANCODE_TAB, SDL_SCANCODE_LCTRL, SDL_SCANCODE_RCTRL,
|
||||
SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4,
|
||||
SDL_SCANCODE_5, SDL_SCANCODE_6, SDL_SCANCODE_7, SDL_SCANCODE_8,
|
||||
SDL_SCANCODE_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));
|
||||
static inline bool KDown (int sc) { return (sc > 0 && sc < KEY_COUNT) ? s_keysCurrent[sc] : false; }
|
||||
static inline bool KPressed (int sc) { return (sc > 0 && sc < KEY_COUNT) ? !s_keysPrev[sc] && s_keysCurrent[sc] : false; }
|
||||
static inline bool KReleased(int sc) { return (sc > 0 && sc < KEY_COUNT) ? s_keysPrev[sc] && !s_keysCurrent[sc] : false; }
|
||||
|
||||
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;
|
||||
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; }
|
||||
|
||||
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().
|
||||
// get directly into SDL events before the game queue can steal them.
|
||||
// this took me a while.
|
||||
static int SDLCALL EventWatcher(void*, SDL_Event* e) {
|
||||
if (e->type == SDL_MOUSEWHEEL) {
|
||||
int y = e->wheel.y;
|
||||
if (e->wheel.direction == SDL_MOUSEWHEEL_FLIPPED) {
|
||||
y = -y;
|
||||
}
|
||||
s_scrollTicksForGetValue += y;
|
||||
s_scrollTicksForButtonPressed += y;
|
||||
} else if (e->type == SDL_MOUSEBUTTONDOWN) {
|
||||
if (e->button.button == 4) {
|
||||
s_scrollTicksForGetValue++;
|
||||
s_scrollTicksForButtonPressed++;
|
||||
} else if (e->button.button == 5) {
|
||||
s_scrollTicksForGetValue--;
|
||||
s_scrollTicksForButtonPressed--;
|
||||
}
|
||||
} else if (e->type == SDL_MOUSEMOTION) {
|
||||
s_accumRelX += (float)e->motion.xrel;
|
||||
s_accumRelY += (float)e->motion.yrel;
|
||||
}
|
||||
|
||||
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);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// C_4JInput::Tick (called once per frame, BEFORE Present / glfwPollEvents)
|
||||
// ---------------------------------------------------------------------------
|
||||
void C_4JInput::Tick(void) {
|
||||
GLFWwindow *w = getWindow();
|
||||
if (!w) return;
|
||||
static int ScrollSnap() {
|
||||
if (!s_scrollSnapTaken) {
|
||||
s_scrollTicksSnap = s_scrollTicksForButtonPressed;
|
||||
s_scrollTicksForButtonPressed = 0;
|
||||
s_scrollSnapTaken = true;
|
||||
}
|
||||
return s_scrollTicksSnap;
|
||||
}
|
||||
|
||||
static void TakeSnapIfNeeded() {
|
||||
if (!s_snapTaken) {
|
||||
s_snapRelX = s_accumRelX; s_accumRelX = 0;
|
||||
s_snapRelY = s_accumRelY; s_accumRelY = 0;
|
||||
s_snapTaken = true;
|
||||
}
|
||||
}
|
||||
// We initialize the SDL input
|
||||
void C_4JInput::Initialise(int, unsigned char, unsigned char, unsigned char) {
|
||||
if (!s_sdlInitialized) {
|
||||
if (SDL_WasInit(SDL_INIT_VIDEO) == 0) {
|
||||
SDL_Init(SDL_INIT_VIDEO);
|
||||
}
|
||||
SDL_AddEventWatch(EventWatcher, NULL);
|
||||
s_sdlInitialized = true;
|
||||
}
|
||||
|
||||
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 = s_mouseRightCurrent = s_mouseRightPrev = false;
|
||||
s_accumRelX = s_accumRelY = s_snapRelX = s_snapRelY = 0;
|
||||
// i really gotta name these vars better..
|
||||
s_scrollTicksForButtonPressed = s_scrollTicksForGetValue = s_scrollTicksSnap = 0;
|
||||
s_snapTaken = s_scrollSnapTaken = s_prevMenuDisplayed = false;
|
||||
|
||||
if (s_sdlInitialized)
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE);
|
||||
}
|
||||
// Each tick we update the input state by polling SDL, this is where we get the kbd and mouse state.
|
||||
void C_4JInput::Tick() {
|
||||
if (!s_sdlInitialized) 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;
|
||||
s_snapTaken = false;
|
||||
s_scrollSnapTaken = false;
|
||||
s_snapRelX = s_snapRelY = 0;
|
||||
s_scrollTicksSnap = 0;
|
||||
|
||||
// 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);
|
||||
SDL_PumpEvents();
|
||||
|
||||
if (s_menuDisplayed[0]) {
|
||||
s_scrollTicksForGetValue = 0;
|
||||
}
|
||||
|
||||
// 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;
|
||||
const Uint8 *state = SDL_GetKeyboardState(NULL);
|
||||
for (int i = 0; i < s_watchedKeyCount; ++i) {
|
||||
int sc = s_watchedKeys[i];
|
||||
if (sc > 0 && sc < KEY_COUNT) s_keysCurrent[sc] = state[sc] != 0;
|
||||
}
|
||||
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;
|
||||
|
||||
Uint32 btns = SDL_GetMouseState(NULL, NULL);
|
||||
s_mouseLeftCurrent = (btns & SDL_BUTTON(SDL_BUTTON_LEFT)) != 0;
|
||||
s_mouseRightCurrent = (btns & SDL_BUTTON(SDL_BUTTON_RIGHT)) != 0;
|
||||
|
||||
if (!SDL_GetRelativeMouseMode()) {
|
||||
s_accumRelX = 0;
|
||||
s_accumRelY = 0;
|
||||
}
|
||||
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)
|
||||
s_mouseLeftCurrent = (glfwGetMouseButton(w, GLFW_MOUSE_BUTTON_LEFT) == GLFW_PRESS);
|
||||
s_mouseRightCurrent = (glfwGetMouseButton(w, GLFW_MOUSE_BUTTON_RIGHT) == GLFW_PRESS);
|
||||
if (!SDL_GetKeyboardFocus()) {
|
||||
SDL_Window *mf = SDL_GetMouseFocus();
|
||||
if (mf) { SDL_RaiseWindow(mf); SDL_SetWindowGrab(mf, SDL_TRUE); }
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ButtonDown – is action held this frame?
|
||||
// ---------------------------------------------------------------------------
|
||||
bool C_4JInput::ButtonDown(int /*iPad*/, unsigned char ucAction) {
|
||||
int C_4JInput::GetHotbarSlotPressed(int iPad) {
|
||||
if (iPad != 0) return -1;
|
||||
|
||||
constexpr size_t NUM_HOTBAR_SLOTS = 9;
|
||||
|
||||
static const int sc[NUM_HOTBAR_SLOTS] = {
|
||||
SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_3, SDL_SCANCODE_4,
|
||||
SDL_SCANCODE_5, SDL_SCANCODE_6, SDL_SCANCODE_7, SDL_SCANCODE_8,
|
||||
SDL_SCANCODE_9,
|
||||
};
|
||||
static bool s_wasDown[NUM_HOTBAR_SLOTS] = {};
|
||||
|
||||
for (int i = 0; i < NUM_HOTBAR_SLOTS; ++i) {
|
||||
bool down = KDown(sc[i]);
|
||||
bool pressed = down && !s_wasDown[i];
|
||||
s_wasDown[i] = down;
|
||||
if (pressed) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define ACTION_CASES(FN) \
|
||||
case ACTION_MENU_UP: return FN(SDL_SCANCODE_UP); \
|
||||
case ACTION_MENU_DOWN: return FN(SDL_SCANCODE_DOWN); \
|
||||
case ACTION_MENU_LEFT: return FN(SDL_SCANCODE_LEFT); \
|
||||
case ACTION_MENU_RIGHT: return FN(SDL_SCANCODE_RIGHT); \
|
||||
case ACTION_MENU_PAGEUP: return FN(SDL_SCANCODE_PAGEUP); \
|
||||
case ACTION_MENU_PAGEDOWN: return FN(SDL_SCANCODE_PAGEDOWN); \
|
||||
case ACTION_MENU_OK: return FN(SDL_SCANCODE_RETURN); \
|
||||
case ACTION_MENU_CANCEL: return FN(SDL_SCANCODE_ESCAPE); \
|
||||
case MINECRAFT_ACTION_JUMP: return FN(SDL_SCANCODE_SPACE); \
|
||||
case MINECRAFT_ACTION_FORWARD: return FN(SDL_SCANCODE_W); \
|
||||
case MINECRAFT_ACTION_BACKWARD: return FN(SDL_SCANCODE_S); \
|
||||
case MINECRAFT_ACTION_LEFT: return FN(SDL_SCANCODE_A); \
|
||||
case MINECRAFT_ACTION_RIGHT: return FN(SDL_SCANCODE_D); \
|
||||
case MINECRAFT_ACTION_INVENTORY: return FN(SDL_SCANCODE_E); \
|
||||
case MINECRAFT_ACTION_PAUSEMENU: return FN(SDL_SCANCODE_ESCAPE); \
|
||||
case MINECRAFT_ACTION_DROP: return FN(SDL_SCANCODE_Q); \
|
||||
case MINECRAFT_ACTION_CRAFTING: return FN(SDL_SCANCODE_C); \
|
||||
case MINECRAFT_ACTION_RENDER_THIRD_PERSON:return FN(SDL_SCANCODE_F5); \
|
||||
case MINECRAFT_ACTION_GAME_INFO: return FN(SDL_SCANCODE_F3); \
|
||||
case MINECRAFT_ACTION_DPAD_LEFT: return FN(SDL_SCANCODE_LEFT); \
|
||||
case MINECRAFT_ACTION_DPAD_RIGHT: return FN(SDL_SCANCODE_RIGHT); \
|
||||
case MINECRAFT_ACTION_DPAD_UP: return FN(SDL_SCANCODE_UP); \
|
||||
case MINECRAFT_ACTION_DPAD_DOWN: return FN(SDL_SCANCODE_DOWN); \
|
||||
default: return false;
|
||||
|
||||
bool C_4JInput::ButtonDown(int iPad, unsigned char ucAction) {
|
||||
if (iPad != 0) return false;
|
||||
if (ucAction == 255) {
|
||||
for (int i = 0; i < s_watchedKeyCount; ++i)
|
||||
if (s_keysCurrent[s_watchedKeys[i]]) return true;
|
||||
return s_mouseLeftCurrent || s_mouseRightCurrent;
|
||||
}
|
||||
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;
|
||||
case MINECRAFT_ACTION_ACTION: return MouseLDown() || KDown(SDL_SCANCODE_RETURN);
|
||||
case MINECRAFT_ACTION_USE: return MouseRDown() || KDown(SDL_SCANCODE_F);
|
||||
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KDown(SDL_SCANCODE_LSHIFT) || KDown(SDL_SCANCODE_RSHIFT) || KDown(SDL_SCANCODE_LCTRL) || KDown(SDL_SCANCODE_RCTRL);
|
||||
case MINECRAFT_ACTION_LEFT_SCROLL:
|
||||
case ACTION_MENU_LEFT_SCROLL: return ScrollSnap() > 0;
|
||||
case MINECRAFT_ACTION_RIGHT_SCROLL:
|
||||
case ACTION_MENU_RIGHT_SCROLL: return ScrollSnap() < 0;
|
||||
ACTION_CASES(KDown)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ButtonPressed – rising edge (press event this frame)
|
||||
// ---------------------------------------------------------------------------
|
||||
bool C_4JInput::ButtonPressed(int /*iPad*/, unsigned char ucAction) {
|
||||
// The part that handles completing the action of pressing a button.
|
||||
bool C_4JInput::ButtonPressed(int iPad, unsigned char ucAction) {
|
||||
if (iPad != 0 || ucAction == 255) return false;
|
||||
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;
|
||||
case MINECRAFT_ACTION_ACTION: return MouseLPressed() || KPressed(SDL_SCANCODE_RETURN);
|
||||
case MINECRAFT_ACTION_USE: return MouseRPressed() || KPressed(SDL_SCANCODE_F);
|
||||
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KPressed(SDL_SCANCODE_LSHIFT) || KPressed(SDL_SCANCODE_RSHIFT) || KPressed(SDL_SCANCODE_LCTRL) || KPressed(SDL_SCANCODE_RCTRL);
|
||||
case MINECRAFT_ACTION_LEFT_SCROLL:
|
||||
case ACTION_MENU_LEFT_SCROLL: return ScrollSnap() > 0;
|
||||
case MINECRAFT_ACTION_RIGHT_SCROLL:
|
||||
case ACTION_MENU_RIGHT_SCROLL: return ScrollSnap() < 0;
|
||||
ACTION_CASES(KPressed)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ButtonReleased – falling edge (released this frame)
|
||||
// ---------------------------------------------------------------------------
|
||||
bool C_4JInput::ButtonReleased(int /*iPad*/, unsigned char ucAction) {
|
||||
// The part that handles Releasing a button.
|
||||
bool C_4JInput::ButtonReleased(int iPad, unsigned char ucAction) {
|
||||
if (iPad != 0 || ucAction == 255) return false;
|
||||
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;
|
||||
case MINECRAFT_ACTION_ACTION: return MouseLReleased() || KReleased(SDL_SCANCODE_RETURN);
|
||||
case MINECRAFT_ACTION_USE: return MouseRReleased() || KReleased(SDL_SCANCODE_F);
|
||||
case MINECRAFT_ACTION_SNEAK_TOGGLE: return KReleased(SDL_SCANCODE_LSHIFT) || KReleased(SDL_SCANCODE_RSHIFT) || KReleased(SDL_SCANCODE_LCTRL) || KReleased(SDL_SCANCODE_RCTRL);
|
||||
case MINECRAFT_ACTION_LEFT_SCROLL:
|
||||
case ACTION_MENU_LEFT_SCROLL:
|
||||
case MINECRAFT_ACTION_RIGHT_SCROLL:
|
||||
case ACTION_MENU_RIGHT_SCROLL: return false;
|
||||
ACTION_CASES(KReleased)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GetValue – returns 1 if action held, 0 otherwise
|
||||
// ---------------------------------------------------------------------------
|
||||
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool /*bRepeat*/) {
|
||||
unsigned int C_4JInput::GetValue(int iPad, unsigned char ucAction, bool) {
|
||||
if (iPad != 0) return 0;
|
||||
if (ucAction == MINECRAFT_ACTION_LEFT_SCROLL) {
|
||||
if (s_scrollTicksForGetValue > 0) {
|
||||
unsigned int v = (unsigned int)s_scrollTicksForGetValue;
|
||||
s_scrollTicksForGetValue = 0;
|
||||
return v;
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
if (ucAction == MINECRAFT_ACTION_RIGHT_SCROLL) {
|
||||
if (s_scrollTicksForGetValue < 0) {
|
||||
unsigned int v = (unsigned int)(-s_scrollTicksForGetValue);
|
||||
s_scrollTicksForGetValue = 0;
|
||||
return v;
|
||||
}
|
||||
return 0u;
|
||||
}
|
||||
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;
|
||||
// Left stick movement, the one that moves the player around or selects menu options. (Soon be tested.)
|
||||
float C_4JInput::GetJoypadStick_LX(int, bool) {
|
||||
return (KDown(SDL_SCANCODE_D) ? 1.f : 0.f) - (KDown(SDL_SCANCODE_A) ? 1.f : 0.f);
|
||||
}
|
||||
float C_4JInput::GetJoypadStick_LY(int, bool) {
|
||||
return (KDown(SDL_SCANCODE_W) ? 1.f : 0.f) - (KDown(SDL_SCANCODE_S) ? 1.f : 0.f);
|
||||
}
|
||||
// We use mouse movement and convert it into a Right Stick output using logarithmic scaling
|
||||
// This is the most important mouse part. Yet it's so small.
|
||||
static float MouseAxis(float raw) {
|
||||
if (fabsf(raw) < 0.0001f) return 0.f; // from 4j previous code
|
||||
return (raw >= 0.f ? 1.f : -1.f) * sqrtf(fabsf(raw));
|
||||
}
|
||||
// We apply the Stick movement on the R(Right) X(2D Position)
|
||||
float C_4JInput::GetJoypadStick_RX(int, bool) {
|
||||
if (!SDL_GetRelativeMouseMode()) return 0.f;
|
||||
TakeSnapIfNeeded();
|
||||
return MouseAxis(s_snapRelX * MOUSE_SCALE);
|
||||
}
|
||||
// Bis. but with Y(2D Position)
|
||||
float C_4JInput::GetJoypadStick_RY(int, bool) {
|
||||
if (!SDL_GetRelativeMouseMode()) return 0.f;
|
||||
TakeSnapIfNeeded();
|
||||
return MouseAxis(-s_snapRelY * MOUSE_SCALE);
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
unsigned char C_4JInput::GetJoypadLTrigger(int, bool) { return s_mouseRightCurrent ? 255 : 0; }
|
||||
unsigned char C_4JInput::GetJoypadRTrigger(int, bool) { return s_mouseLeftCurrent ? 255 : 0; }
|
||||
// We detect if a Menu is visible on the player's screen to the mouse being stuck.
|
||||
void C_4JInput::SetMenuDisplayed(int iPad, bool bVal) {
|
||||
if (iPad >= 0 && iPad < 4) s_menuDisplayed[iPad] = bVal;
|
||||
if (!s_sdlInitialized || bVal == s_prevMenuDisplayed) return;
|
||||
SDL_SetRelativeMouseMode(bVal ? SDL_FALSE : SDL_TRUE);
|
||||
s_prevMenuDisplayed = 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*/) {}
|
||||
void C_4JInput::CancelAllVerifyInProgress(void) {}
|
||||
|
||||
float C_4JInput::GetMouseX() {
|
||||
return (float)s_lastCursorX;
|
||||
int C_4JInput::GetScrollDelta() {
|
||||
int v = s_scrollTicksForButtonPressed;
|
||||
s_scrollTicksForButtonPressed = 0;
|
||||
return v;
|
||||
}
|
||||
|
||||
float C_4JInput::GetMouseY() {
|
||||
return (float)s_lastCursorY;
|
||||
}
|
||||
void C_4JInput::SetDeadzoneAndMovementRange(unsigned int, unsigned int){}
|
||||
void C_4JInput::SetGameJoypadMaps(unsigned char, unsigned char, unsigned int){}
|
||||
unsigned int C_4JInput::GetGameJoypadMaps(unsigned char, unsigned char){ return 0; }
|
||||
void C_4JInput::SetJoypadMapVal(int, unsigned char){}
|
||||
unsigned char C_4JInput::GetJoypadMapVal(int){ return 0; }
|
||||
void C_4JInput::SetJoypadSensitivity(int, float){}
|
||||
void C_4JInput::SetJoypadStickAxisMap(int, unsigned int, unsigned int){}
|
||||
void C_4JInput::SetJoypadStickTriggerMap(int, unsigned int, unsigned int){}
|
||||
void C_4JInput::SetKeyRepeatRate(float, float){}
|
||||
void C_4JInput::SetDebugSequence(const char*, int(*)(LPVOID), LPVOID){}
|
||||
FLOAT C_4JInput::GetIdleSeconds(int){ return 0.f; }
|
||||
bool C_4JInput::IsPadConnected(int iPad){ return iPad == 0; }
|
||||
|
||||
// Silly check, we check if we have a keyboard.
|
||||
EKeyboardResult C_4JInput::RequestKeyboard(LPCWSTR, LPCWSTR, DWORD, UINT,
|
||||
int(*)(LPVOID, const bool), LPVOID, C_4JInput::EKeyboardMode)
|
||||
{ return EKeyboard_Cancelled; }
|
||||
|
||||
void C_4JInput::GetText(uint16_t *s){ if (s) s[0] = 0; }
|
||||
bool C_4JInput::VerifyStrings(WCHAR**, int, int(*)(LPVOID, STRING_VERIFY_RESPONSE*), LPVOID){ return true; }
|
||||
void C_4JInput::CancelQueuedVerifyStrings(int(*)(LPVOID, STRING_VERIFY_RESPONSE*), LPVOID){}
|
||||
void C_4JInput::CancelAllVerifyInProgress(){}
|
||||
|
|
@ -106,6 +106,8 @@ public:
|
|||
unsigned char GetJoypadRTrigger(int iPad, bool bCheckMenuDisplay=true);
|
||||
|
||||
void SetMenuDisplayed(int iPad, bool bVal);
|
||||
int GetHotbarSlotPressed(int iPad);
|
||||
int GetScrollDelta();
|
||||
|
||||
// EKeyboardResult RequestKeyboard(UINT uiTitle, UINT uiText, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam,EKeyboardMode eMode,C4JStringTable *pStringTable=NULL);
|
||||
// EKeyboardResult RequestKeyboard(UINT uiTitle, LPCWSTR pwchDefault, UINT uiDesc, DWORD dwPad, WCHAR *pwchResult, UINT uiResultSize,int( *Func)(LPVOID,const bool),LPVOID lpParam, EKeyboardMode eMode,C4JStringTable *pStringTable=NULL);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ lib_input = static_library('4J_Input',
|
|||
],
|
||||
)
|
||||
|
||||
# We import SDL2 but not SDL3.. which is a bit sad,
|
||||
sdl_dep = dependency('sdl2', required : false)
|
||||
|
||||
input_dep = declare_dependency(
|
||||
link_with : lib_input,
|
||||
dependencies : [sdl_dep],
|
||||
include_directories : include_directories('.'),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -1,14 +1,11 @@
|
|||
|
||||
// TODO: ADD BETTER COMMENTS.
|
||||
#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 <SDL2/SDL.h>
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <pthread.h>
|
||||
|
|
@ -18,38 +15,53 @@
|
|||
|
||||
C4JRender RenderManager;
|
||||
|
||||
static GLFWwindow *s_window = nullptr;
|
||||
// Hello SDL!
|
||||
static SDL_Window *s_window = nullptr;
|
||||
static SDL_GLContext s_glContext = nullptr;
|
||||
static bool s_shouldClose = false;
|
||||
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_windowWidth = 0;
|
||||
static int s_windowHeight = 0;
|
||||
|
||||
// We set Window size with the monitor's res, so that I can get rid of ugly values.
|
||||
static void SetInitialWindowSize()
|
||||
{
|
||||
int w = 0, h = 0;
|
||||
if (SDL_Init(SDL_INIT_VIDEO) == 0) {
|
||||
SDL_DisplayMode mode;
|
||||
if (SDL_GetCurrentDisplayMode(0, &mode) == 0) {
|
||||
w = (int)(mode.w * 0.4f);
|
||||
h = (int)(mode.h * 0.4f);
|
||||
}
|
||||
}
|
||||
if (w > 0 && h > 0) { s_windowWidth = w; s_windowHeight = h; }
|
||||
else { s_windowWidth = 1280; s_windowHeight = 720; }
|
||||
}
|
||||
// (can't believe i had to rewrite this, i literally did it TODAY.)
|
||||
static int s_reqWidth = 0;
|
||||
static int s_reqHeight = 0;
|
||||
// When we'll have a settings system in order, we'll set bool to that value, right now it's hardcoded.
|
||||
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
|
||||
|
||||
// AMD drivers (especially on Linux/Mesa) can be very sensitive to the number of shared contexts
|
||||
// and concurrent display list compilation. 8 was original, 4 was an attempt to fix it.
|
||||
// 6 covers the 5 concurrent worker threads (update + 3x rebuild + main thread).
|
||||
static const int MAX_SHARED_CONTEXTS = 6;
|
||||
static GLFWwindow *s_sharedContexts[MAX_SHARED_CONTEXTS] = {};
|
||||
// Do not touch exactly this number |
|
||||
static const int MAX_SHARED_CONTEXTS = 6; // <- this one, do not touch
|
||||
static SDL_Window *s_sharedContextWindows[MAX_SHARED_CONTEXTS] = {};
|
||||
static SDL_GLContext s_sharedContexts[MAX_SHARED_CONTEXTS] = {};
|
||||
static int s_sharedContextCount = 0;
|
||||
static int s_nextSharedContext = 0;
|
||||
static pthread_mutex_t s_sharedCtxMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
// Tells thread to do Direct GL calls, just don't touch.
|
||||
static pthread_mutex_t s_glCallMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
// Track which thread is the main (rendering) thread
|
||||
static pthread_t s_mainThread;
|
||||
static bool s_mainThreadSet = false;
|
||||
|
||||
// viewport go brr
|
||||
static void onFramebufferResize(GLFWwindow * /*win*/, int w, int h)
|
||||
static void onFramebufferResize(int w, int h)
|
||||
{
|
||||
if (w < 1) w = 1;
|
||||
if (h < 1) h = 1;
|
||||
|
|
@ -58,48 +70,62 @@ static void onFramebufferResize(GLFWwindow * /*win*/, int w, int h)
|
|||
::glViewport(0, 0, w, h);
|
||||
}
|
||||
|
||||
// Initialize OpenGL & The SDL window.
|
||||
void C4JRender::Initialise()
|
||||
{
|
||||
if (!glfwInit()) {
|
||||
fprintf(stderr, "[4J_Render] Failed to initialise GLFW\n");
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fprintf(stderr, "[4J_Render] Failed to initialise SDL: %s\n", SDL_GetError());
|
||||
return;
|
||||
}
|
||||
GLFWmonitor *primaryMonitor = glfwGetPrimaryMonitor();
|
||||
const GLFWvidmode *mode = primaryMonitor ? glfwGetVideoMode(primaryMonitor) : nullptr;
|
||||
SDL_DisplayMode mode;
|
||||
int haveMode = (SDL_GetCurrentDisplayMode(0, &mode) == 0);
|
||||
|
||||
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;
|
||||
} else if (haveMode) {
|
||||
s_windowWidth = mode.w;
|
||||
s_windowHeight = mode.h;
|
||||
}
|
||||
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);
|
||||
glfwWindowHint(GLFW_DEPTH_BITS, 24);
|
||||
glfwWindowHint(GLFW_STENCIL_BITS, 8);
|
||||
// Setting the sdl_gl ver. Change in future incase we want to use shaders
|
||||
// Yes i'm still using fixed functions, get mad at me
|
||||
// I don't care.
|
||||
// Im not gonna be rewriting the whole renderer.. AGAIN. ;w;
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
|
||||
GLFWmonitor *fsMonitor = s_fullscreen ? primaryMonitor : nullptr;
|
||||
s_window = glfwCreateWindow(s_windowWidth, s_windowHeight,
|
||||
"Minecraft Console Edition", fsMonitor, nullptr);
|
||||
Uint32 winFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE;
|
||||
if (s_fullscreen) winFlags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
s_window = SDL_CreateWindow("Minecraft Console Edition",
|
||||
SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
|
||||
s_windowWidth, s_windowHeight,
|
||||
winFlags);
|
||||
if (!s_window) {
|
||||
fprintf(stderr, "[4J_Render] Failed to create GLFW window\n");
|
||||
glfwTerminate();
|
||||
fprintf(stderr, "[4J_Render] Failed to create SDL window: %s\n", SDL_GetError());
|
||||
SDL_Quit();
|
||||
return;
|
||||
}
|
||||
|
||||
glfwMakeContextCurrent(s_window);
|
||||
glfwSwapInterval(1); // vsync
|
||||
|
||||
// Keep viewport in sync with OS-driven window resizes.
|
||||
glfwSetFramebufferSizeCallback(s_window, onFramebufferResize);
|
||||
s_glContext = SDL_GL_CreateContext(s_window);
|
||||
if (!s_glContext) {
|
||||
fprintf(stderr, "[4J_Render] Failed to create GL context: %s\n", SDL_GetError());
|
||||
SDL_DestroyWindow(s_window);
|
||||
s_window = nullptr;
|
||||
SDL_Quit();
|
||||
return;
|
||||
}
|
||||
SDL_GL_SetSwapInterval(0); // V-Sync Off Please.
|
||||
|
||||
// init opengl
|
||||
int fw, fh; SDL_GetWindowSize(s_window, &fw, &fh); onFramebufferResize(fw, fh);
|
||||
|
||||
// We initialize the OpenGL states. Touching those values makes some funny artifacts appear.
|
||||
::glEnable(GL_TEXTURE_2D);
|
||||
::glEnable(GL_DEPTH_TEST);
|
||||
::glDepthFunc(GL_LEQUAL);
|
||||
|
|
@ -116,7 +142,7 @@ void C4JRender::Initialise()
|
|||
::glViewport(0, 0, s_windowWidth, s_windowHeight);
|
||||
::glEnable(GL_COLOR_MATERIAL);
|
||||
::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
|
||||
// Print the renderer's version incase we change it in the future.
|
||||
printf("[4J_Render] OpenGL %s | %s\n",
|
||||
(const char*)::glGetString(GL_VERSION),
|
||||
(const char*)::glGetString(GL_RENDERER));
|
||||
|
|
@ -126,25 +152,34 @@ void C4JRender::Initialise()
|
|||
pthread_once(&s_glCtxKeyOnce, makeGLCtxKey);
|
||||
s_mainThread = pthread_self();
|
||||
s_mainThreadSet = true;
|
||||
pthread_setspecific(s_glCtxKey, s_window);
|
||||
pthread_setspecific(s_glCtxKey, (void*)s_window);
|
||||
|
||||
// Pre-create shared GL contexts for worker threads (chunk builders etc.)
|
||||
// Must be done on the main thread because GLFW requires it.
|
||||
// Ensure they are invisible so they don't interfere with the window manager.
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_FALSE);
|
||||
|
||||
// Pre-create shared GL contexts for worker threads (chunk builders & other shit etc.)
|
||||
// SDL_GL_SHARE_WITH_CURRENT_CONTEXT my saviour.
|
||||
for (int i = 0; i < MAX_SHARED_CONTEXTS; i++) {
|
||||
s_sharedContexts[i] = glfwCreateWindow(1, 1, "", nullptr, s_window);
|
||||
if (s_sharedContexts[i]) {
|
||||
s_sharedContextCount++;
|
||||
} else {
|
||||
fprintf(stderr, "[4J_Render] WARN: only created %d/%d shared contexts\n", i, MAX_SHARED_CONTEXTS);
|
||||
SDL_Window *w = SDL_CreateWindow("",
|
||||
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
|
||||
1, 1, SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL);
|
||||
if (!w) break;
|
||||
// Ensure sharing
|
||||
// I've been stuck on this for a while. Im stupid..
|
||||
SDL_GL_MakeCurrent(s_window, s_glContext);
|
||||
SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, 1);
|
||||
SDL_GLContext ctx = SDL_GL_CreateContext(w);
|
||||
if (!ctx) {
|
||||
SDL_DestroyWindow(w);
|
||||
break;
|
||||
}
|
||||
s_sharedContextWindows[s_sharedContextCount] = w;
|
||||
s_sharedContexts[s_sharedContextCount] = ctx;
|
||||
s_sharedContextCount++;
|
||||
}
|
||||
glfwWindowHint(GLFW_VISIBLE, GLFW_TRUE);
|
||||
|
||||
// Ensure main thread still has the context
|
||||
glfwMakeContextCurrent(s_window);
|
||||
SDL_GL_MakeCurrent(s_window, s_glContext);
|
||||
fprintf(stderr, "[4J_Render] Created %d shared GL contexts for worker threads\n", s_sharedContextCount);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
@ -156,21 +191,25 @@ void C4JRender::InitialiseContext()
|
|||
|
||||
// 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);
|
||||
SDL_GL_MakeCurrent(s_window, s_glContext);
|
||||
pthread_setspecific(s_glCtxKey, (void*)s_window);
|
||||
return;
|
||||
}
|
||||
|
||||
// Worker thread: check if it already has a shared context
|
||||
GLFWwindow *ctx = (GLFWwindow*)pthread_getspecific(s_glCtxKey);
|
||||
if (ctx) {
|
||||
glfwMakeContextCurrent(ctx);
|
||||
// Worker thread checks if there's a context, we don't want to have multiple contexts.
|
||||
void *ctxPtr = pthread_getspecific(s_glCtxKey);
|
||||
if (ctxPtr) {
|
||||
// ctxPtr -> SDL_GLContext pointer
|
||||
SDL_GLContext ctx = (SDL_GLContext)ctxPtr;
|
||||
int idx = -1;
|
||||
for (int i = 0; i < s_sharedContextCount; ++i) if (s_sharedContexts[i] == ctx) { idx = i; break; }
|
||||
if (idx >= 0 && s_sharedContextWindows[idx]) SDL_GL_MakeCurrent(s_sharedContextWindows[idx], ctx);
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab a pre-created shared context from the pool
|
||||
pthread_mutex_lock(&s_sharedCtxMutex);
|
||||
GLFWwindow *shared = nullptr;
|
||||
SDL_GLContext shared = nullptr;
|
||||
if (s_nextSharedContext < s_sharedContextCount) {
|
||||
shared = s_sharedContexts[s_nextSharedContext++];
|
||||
}
|
||||
|
|
@ -181,7 +220,10 @@ void C4JRender::InitialiseContext()
|
|||
fflush(stderr);
|
||||
return;
|
||||
}
|
||||
glfwMakeContextCurrent(shared);
|
||||
// ewww..... look at line 201-203, we gotta make a function for that....
|
||||
int idx = -1;
|
||||
for (int i = 0; i < s_sharedContextCount; ++i) if (s_sharedContexts[i] == shared) { idx = i; break; }
|
||||
if (idx >= 0 && s_sharedContextWindows[idx]) SDL_GL_MakeCurrent(s_sharedContextWindows[idx], shared);
|
||||
|
||||
// Initialize some basic state for this context to ensure consistent display list recording
|
||||
::glEnable(GL_TEXTURE_2D);
|
||||
|
|
@ -194,7 +236,7 @@ void C4JRender::InitialiseContext()
|
|||
::glEnable(GL_COLOR_MATERIAL);
|
||||
::glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||
|
||||
pthread_setspecific(s_glCtxKey, shared);
|
||||
pthread_setspecific(s_glCtxKey, (void*)shared);
|
||||
fprintf(stderr, "[4J_Render] Assigned shared GL context %p to worker thread %lu\n", (void*)shared, (unsigned long)pthread_self());
|
||||
fflush(stderr);
|
||||
}
|
||||
|
|
@ -202,18 +244,28 @@ void C4JRender::InitialiseContext()
|
|||
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;
|
||||
int w,h; SDL_GetWindowSize(s_window, &w, &h);
|
||||
s_windowWidth = w > 0 ? w : 1;
|
||||
s_windowHeight = h > 0 ? h : 1;
|
||||
::glViewport(0, 0, s_windowWidth, s_windowHeight);
|
||||
}
|
||||
|
||||
void C4JRender::Present()
|
||||
{
|
||||
if (!s_window) return;
|
||||
SDL_Event ev;
|
||||
while (SDL_PollEvent(&ev)) {
|
||||
if (ev.type == SDL_QUIT) s_shouldClose = true;
|
||||
else if (ev.type == SDL_WINDOWEVENT) {
|
||||
if (ev.window.event == SDL_WINDOWEVENT_CLOSE) s_shouldClose = true;
|
||||
else if (ev.window.event == SDL_WINDOWEVENT_RESIZED) onFramebufferResize(ev.window.data1, ev.window.data2);
|
||||
}
|
||||
}
|
||||
// Present the rendered frame after processing input/events to avoid input timing issues
|
||||
::glFlush();
|
||||
glfwSwapBuffers(s_window);
|
||||
glfwPollEvents();
|
||||
// debug log to help diagnose mouse issues
|
||||
// printf("[4J_Render] Presenting frame (mouse lock=%d)\n", s_mouseLocked); fflush(stdout);
|
||||
SDL_GL_SwapWindow(s_window);
|
||||
}
|
||||
|
||||
void C4JRender::SetWindowSize(int w, int h)
|
||||
|
|
@ -229,21 +281,38 @@ void C4JRender::SetFullscreen(bool fs)
|
|||
|
||||
bool C4JRender::ShouldClose()
|
||||
{
|
||||
return !s_window || glfwWindowShouldClose(s_window);
|
||||
return !s_window || s_shouldClose;
|
||||
}
|
||||
|
||||
void C4JRender::Shutdown()
|
||||
{
|
||||
// Destroy the main window and terminate GLFW cleanly so that
|
||||
// Destroy the main window and clean up SDL resources so that
|
||||
// destructors running after the game loop don't touch a dead context.
|
||||
if (s_window)
|
||||
{
|
||||
glfwDestroyWindow(s_window);
|
||||
if (s_glContext) {
|
||||
SDL_GL_DeleteContext(s_glContext);
|
||||
s_glContext = nullptr;
|
||||
}
|
||||
SDL_DestroyWindow(s_window);
|
||||
s_window = nullptr;
|
||||
}
|
||||
glfwTerminate();
|
||||
|
||||
for (int i = 0; i < s_sharedContextCount; ++i) {
|
||||
if (s_sharedContexts[i]) {
|
||||
SDL_GL_DeleteContext(s_sharedContexts[i]);
|
||||
s_sharedContexts[i] = 0;
|
||||
}
|
||||
if (s_sharedContextWindows[i]) {
|
||||
SDL_DestroyWindow(s_sharedContextWindows[i]);
|
||||
s_sharedContextWindows[i] = nullptr;
|
||||
}
|
||||
}
|
||||
s_sharedContextCount = 0;
|
||||
SDL_Quit();
|
||||
}
|
||||
|
||||
// rip glfw. you won't be missed. (i hope)
|
||||
void C4JRender::DoScreenGrabOnNextPresent() {}
|
||||
|
||||
void C4JRender::Clear(int flags)
|
||||
|
|
@ -272,8 +341,8 @@ void C4JRender::MatrixTranslate(float x, float y, float z) { ::glTranslatef(x, y
|
|||
|
||||
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);
|
||||
// We use math from the math lib instead of hardcoding it. How Ugly.
|
||||
::glRotatef(angle * (180.0f / static_cast<float>(M_PI)), x, y, z);
|
||||
}
|
||||
|
||||
void C4JRender::MatrixScale(float x, float y, float z) { ::glScalef(x, y, z); }
|
||||
|
|
@ -284,7 +353,7 @@ void C4JRender::MatrixPerspective(float fovy, float aspect, float zNear, float z
|
|||
}
|
||||
|
||||
void C4JRender::MatrixOrthogonal(float left, float right, float bottom, float top,
|
||||
float zNear, float zFar)
|
||||
float zNear, float zFar)
|
||||
{
|
||||
::glOrtho(left, right, bottom, top, zNear, zFar);
|
||||
}
|
||||
|
|
@ -314,27 +383,29 @@ static GLenum mapPrimType(int pt)
|
|||
|
||||
// Map from ePrimitiveType enum
|
||||
switch (pt) {
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_LIST: return GL_TRIANGLES;
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
|
||||
case C4JRender::PRIMITIVE_TYPE_QUAD_LIST: return GL_QUADS;
|
||||
case C4JRender::PRIMITIVE_TYPE_LINE_LIST: return GL_LINES;
|
||||
case C4JRender::PRIMITIVE_TYPE_LINE_STRIP: return GL_LINE_STRIP;
|
||||
default: return GL_TRIANGLES;
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_LIST: return GL_TRIANGLES;
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_STRIP: return GL_TRIANGLE_STRIP;
|
||||
case C4JRender::PRIMITIVE_TYPE_TRIANGLE_FAN: return GL_TRIANGLE_FAN;
|
||||
case C4JRender::PRIMITIVE_TYPE_QUAD_LIST: return GL_QUADS;
|
||||
case C4JRender::PRIMITIVE_TYPE_LINE_LIST: return GL_LINES;
|
||||
case C4JRender::PRIMITIVE_TYPE_LINE_STRIP: return GL_LINE_STRIP;
|
||||
default: return GL_TRIANGLES;
|
||||
}
|
||||
}
|
||||
|
||||
// clientside awawawa
|
||||
// This is the clientside vertex processing.
|
||||
void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
||||
void *dataIn, eVertexType vType,
|
||||
C4JRender::ePixelShaderType psType)
|
||||
{
|
||||
if (count <= 0 || !dataIn) return;
|
||||
|
||||
// trash trash trash trash
|
||||
pthread_mutex_lock(&s_glCallMutex);
|
||||
|
||||
GLenum mode = mapPrimType((int)PrimitiveType);
|
||||
|
||||
if (vType == VERTEX_TYPE_COMPRESSED) {
|
||||
// NO NEED TO REWRITE IT ALL YAY
|
||||
int16_t *sdata = (int16_t *)dataIn;
|
||||
::glBegin(mode);
|
||||
for (int i = 0; i < count; i++) {
|
||||
|
|
@ -352,7 +423,7 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
|||
|
||||
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
|
||||
// Tesselator does that. Thanks 4J.
|
||||
if (fu >= 1.0f) fu -= 1.0f;
|
||||
|
||||
// Unit 1 (lightmap) UVs
|
||||
|
|
@ -388,8 +459,7 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
|||
::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"
|
||||
// This breaks particle colors.. i think. fixme!
|
||||
if (colorInt != 0) {
|
||||
::glColor4ub(cr, cg, cb, ca);
|
||||
}
|
||||
|
|
@ -397,6 +467,7 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
|||
::glTexCoord2f(fdata[3], fdata[4]);
|
||||
|
||||
// Unit 1 (lightmap) UVs - 0xfe00fe00 is sentinel for "no Unit 1 UVs"
|
||||
// Ugly hack, replace soon.
|
||||
if (tex2Int != 0xfe00fe00) {
|
||||
float u2 = (float)(short)(tex2Int & 0xFFFF) / 256.0f;
|
||||
float v2 = (float)(short)((tex2Int >> 16) & 0xFFFF) / 256.0f;
|
||||
|
|
@ -408,6 +479,8 @@ void C4JRender::DrawVertices(ePrimitiveType PrimitiveType, int count,
|
|||
::glEnd();
|
||||
}
|
||||
::glFlush();
|
||||
|
||||
pthread_mutex_unlock(&s_glCallMutex);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -438,9 +511,9 @@ void C4JRender::CBuffStart(int index, bool /*full*/)
|
|||
|
||||
void C4JRender::CBuffClear(int index)
|
||||
{
|
||||
if (index > 0) {
|
||||
::glNewList(index, GL_COMPILE);
|
||||
::glEndList();
|
||||
if (index > 0) {
|
||||
::glNewList(index, GL_COMPILE);
|
||||
::glEndList();
|
||||
::glFlush();
|
||||
}
|
||||
}
|
||||
|
|
@ -508,9 +581,7 @@ void C4JRender::TextureBindVertex(int 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.
|
||||
// base level is always 0, no mipmaps sadly. I'll add them later.
|
||||
::glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, levels > 0 ? levels - 1 : 0);
|
||||
s_textureLevels = levels;
|
||||
}
|
||||
|
|
@ -519,8 +590,7 @@ 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.
|
||||
// TODO: Check if correct format.
|
||||
::glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA,
|
||||
width, height, 0,
|
||||
GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
|
|
@ -554,7 +624,7 @@ void C4JRender::TextureDynamicUpdateEnd() {}
|
|||
void C4JRender::Tick() {}
|
||||
void C4JRender::UpdateGamma(unsigned short) {}
|
||||
|
||||
// This sucks, but at least better than libpng
|
||||
// Converts RGBA data to the format expected by the texture loader.
|
||||
static HRESULT LoadFromSTB(unsigned char* data, int width, int height, D3DXIMAGE_INFO* pSrcInfo, int** ppDataOut)
|
||||
{
|
||||
int pixelCount = width * height;
|
||||
|
|
@ -614,7 +684,6 @@ HRESULT C4JRender::SaveTextureDataToMemory(void *pOutput, int outputCapacity, in
|
|||
void C4JRender::TextureGetStats() {}
|
||||
void* C4JRender::TextureGetTexture(int idx) { return nullptr; }
|
||||
|
||||
// we handle opengl calls cuz multiplatform is painful!!
|
||||
void C4JRender::StateSetColour(float r, float g, float b, float a)
|
||||
{
|
||||
::glColor4f(r, g, b, a);
|
||||
|
|
@ -755,13 +824,12 @@ 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
|
||||
float dir[4] = {x, y, z, 0.0f}; // TODO: Java seems to do the reverse, gotta check.
|
||||
::glLightfv(GL_LIGHT0 + light, GL_POSITION, dir);
|
||||
}
|
||||
|
||||
|
|
@ -787,11 +855,11 @@ void C4JRender::StateSetTexGenCol(int col, float x, float y, float z, float w, b
|
|||
{
|
||||
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;
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ render_sources = files(
|
|||
lib_render = static_library('4J_Render',
|
||||
render_sources,
|
||||
include_directories : include_directories('.'),
|
||||
dependencies : [png_dep, glfw_dep, gl_dep, thread_dep],
|
||||
dependencies : [sdl2_dep, gl_dep, thread_dep],
|
||||
cpp_args : global_cpp_args + global_cpp_defs + [
|
||||
'-include', meson.current_source_dir() / 'stdafx.h',
|
||||
],
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
class ConsoleInputSource
|
||||
{
|
||||
public:
|
||||
virtual ~ConsoleInputSource(){}
|
||||
virtual void info(const std::wstring& string) = 0;
|
||||
virtual void warn(const std::wstring& string) = 0;
|
||||
virtual std::wstring getConsoleName() = 0;
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ public:
|
|||
bool sneaking;
|
||||
|
||||
Input(); // 4J - added
|
||||
virtual ~Input(){}
|
||||
|
||||
virtual void tick(LocalPlayer *player);
|
||||
|
||||
|
|
@ -19,4 +20,4 @@ private:
|
|||
|
||||
bool lReset;
|
||||
bool rReset;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3194,13 +3194,12 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
ui.SetTooltips( iPad, iA,iB,iX,iY,iLT,iRT,iLB,iRB);
|
||||
|
||||
int wheel = 0;
|
||||
if (InputManager.GetValue(iPad, MINECRAFT_ACTION_LEFT_SCROLL, true) > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL) )
|
||||
{
|
||||
wheel = 1;
|
||||
}
|
||||
else if (InputManager.GetValue(iPad, MINECRAFT_ACTION_RIGHT_SCROLL,true) > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_RIGHT_SCROLL) )
|
||||
{
|
||||
wheel = -1;
|
||||
unsigned int leftTicks = InputManager.GetValue(iPad, MINECRAFT_ACTION_LEFT_SCROLL, true);
|
||||
unsigned int rightTicks = InputManager.GetValue(iPad, MINECRAFT_ACTION_RIGHT_SCROLL, true);
|
||||
if (leftTicks > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL)) {
|
||||
wheel = (int)leftTicks; // positive = left
|
||||
} else if (rightTicks > 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_RIGHT_SCROLL)) {
|
||||
wheel = -(int)rightTicks; // negative = right
|
||||
}
|
||||
if (wheel != 0)
|
||||
{
|
||||
|
|
@ -3223,7 +3222,6 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
options->flySpeed += wheel * .25f;
|
||||
}
|
||||
}
|
||||
|
||||
if( gameMode->isInputAllowed(MINECRAFT_ACTION_ACTION) )
|
||||
{
|
||||
if((player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_ACTION)))
|
||||
|
|
@ -3422,7 +3420,8 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
}
|
||||
|
||||
if ( (player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_PAUSEMENU))
|
||||
#ifdef _DURANGO
|
||||
|
||||
#ifdef _DURANGO
|
||||
|| (player->ullButtonsPressed&(1LL<<ACTION_MENU_GTC_PAUSE))
|
||||
#endif
|
||||
)
|
||||
|
|
@ -3442,6 +3441,7 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
__uint64 ullButtonsPressed=player->ullButtonsPressed;
|
||||
|
||||
bool selected = false;
|
||||
|
||||
#ifdef __PSVITA__
|
||||
// 4J-PB - use the touchscreen for quickselect
|
||||
SceTouchData* pTouchData = InputManager.GetTouchPadData(iPad,false);
|
||||
|
|
@ -3458,6 +3458,14 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
}
|
||||
}
|
||||
#endif
|
||||
{
|
||||
int hotbarSlot = InputManager.GetHotbarSlotPressed(iPad);
|
||||
if (hotbarSlot >= 0 && hotbarSlot <= 9)
|
||||
{
|
||||
player->inventory->selected = hotbarSlot;
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if( selected || wheel != 0 || (player->ullButtonsPressed&(1LL<<MINECRAFT_ACTION_DROP)) )
|
||||
{
|
||||
std::wstring itemName = L"";
|
||||
|
|
@ -3512,7 +3520,14 @@ void Minecraft::tick(bool bFirst, bool bUpdateTextures)
|
|||
int wheel = Mouse.getEventDWheel();
|
||||
if (wheel != 0) {
|
||||
player->inventory.swapPaint(wheel);
|
||||
|
||||
{
|
||||
int hotbarSlot = InputManager.GetHotbarSlotPressed(iPad);
|
||||
if (hotbarSlot >= 0 && gameMode->isInputAllowed(MINECRAFT_ACTION_LEFT_SCROLL))
|
||||
{
|
||||
player->inventory->selected = hotbarSlot;
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
if (options.isFlying) {
|
||||
if (wheel > 0) wheel = 1;
|
||||
if (wheel < 0) wheel = -1;
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ PlayerChunkMap::PlayerChunk::PlayerChunk(int x, int z, PlayerChunkMap *pcm) : po
|
|||
|
||||
PlayerChunkMap::PlayerChunk::~PlayerChunk()
|
||||
{
|
||||
delete changedTiles.data;
|
||||
delete[] changedTiles.data; //4jcraft, changed to []
|
||||
}
|
||||
|
||||
// 4J added - construct an an array of flags that indicate which entities are still waiting to have network packets sent out to say that they have been removed
|
||||
|
|
@ -797,4 +797,4 @@ void PlayerChunkMap::setRadius(int newRadius)
|
|||
assert(radius >= MIN_VIEW_DISTANCE);
|
||||
this->radius = newRadius;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4111,7 +4111,7 @@ void CMinecraftApp::loadStringTable()
|
|||
{
|
||||
byteArray locFile = m_mediaArchive->getFile(localisationFile);
|
||||
m_stringTable = new StringTable(locFile.data, locFile.length);
|
||||
delete locFile.data;
|
||||
delete[] locFile.data;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -285,12 +285,12 @@ __int64 ConsoleSchematicFile::applyBlocksAndData(LevelChunk *chunk, AABB *chunkB
|
|||
PIXBeginNamedEvent(0,"Setting Block data");
|
||||
chunk->setBlockData(blockData);
|
||||
PIXEndNamedEvent();
|
||||
delete blockData.data;
|
||||
delete[] blockData.data; //4jcraft changed to array delete
|
||||
chunk->recalcHeightmapOnly();
|
||||
PIXBeginNamedEvent(0,"Setting Data data");
|
||||
chunk->setDataData(dataData);
|
||||
PIXEndNamedEvent();
|
||||
delete dataData.data;
|
||||
delete[] dataData.data; //4jcraft, same here
|
||||
|
||||
// A basic pass through to roughly do the lighting. At this point of post-processing, we don't have all the neighbouring chunks loaded in,
|
||||
// so any lighting here should be things that won't propagate out of this chunk.
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ protected:
|
|||
|
||||
public:
|
||||
GameRuleDefinition();
|
||||
virtual ~GameRuleDefinition(){}
|
||||
|
||||
virtual ConsoleGameRules::EGameRuleType getActionType() = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ public:
|
|||
// was being mixed in with all the game information as they have
|
||||
// completely different lifespans.
|
||||
|
||||
virtual ~GrSource(){}
|
||||
virtual bool requiresTexturePack()=0;
|
||||
virtual UINT getRequiredTexturePackId()=0;
|
||||
virtual std::wstring getDefaultSaveName()=0;
|
||||
|
|
|
|||
|
|
@ -1108,7 +1108,7 @@ int CGameNetworkManager::ChangeSessionTypeThreadProc( void* lpParam )
|
|||
app.SetXuiServerAction(ProfileManager.GetPrimaryPad(),eXuiServerAction_PauseServer,(void *)TRUE);
|
||||
|
||||
// wait for the server to be in a non-ticking state
|
||||
pServer->m_serverPausedEvent->WaitForSignal(INFINITY);
|
||||
pServer->m_serverPausedEvent->WaitForSignal(INFINITE);
|
||||
|
||||
#if defined(__PS3__) || defined(__ORBIS__) || defined __PSVITA__
|
||||
// Swap these two messages around as one is too long to display at 480
|
||||
|
|
@ -1926,7 +1926,7 @@ void CGameNetworkManager::ServerReadyWait()
|
|||
{
|
||||
if (m_hServerReadyEvent != NULL)
|
||||
{
|
||||
m_hServerReadyEvent->WaitForSignal(INFINITY);
|
||||
m_hServerReadyEvent->WaitForSignal(INFINITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1990,7 +1990,7 @@ void CGameNetworkManager::ServerStoppedWait()
|
|||
{
|
||||
if (m_hServerStoppedEvent != NULL)
|
||||
{
|
||||
m_hServerStoppedEvent->WaitForSignal(INFINITY);
|
||||
m_hServerStoppedEvent->WaitForSignal(INFINITE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ private:
|
|||
|
||||
public:
|
||||
LookAtEntityHint(eTutorial_Hint id, Tutorial *tutorial, int descriptionId, int titleId, eINSTANCEOF type);
|
||||
~LookAtEntityHint();
|
||||
//TODO: 4jcraft added, this was not implemented
|
||||
~LookAtEntityHint(){};
|
||||
|
||||
virtual bool onLookAtEntity(eINSTANCEOF type);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ LookAtTileHint::LookAtTileHint(eTutorial_Hint id, Tutorial *tutorial, int tiles[
|
|||
{
|
||||
m_iTilesCount = tilesLength;
|
||||
|
||||
//TODO: 4jcraft: allocating but never freeing mem, leak
|
||||
m_iTiles= new int [m_iTilesCount];
|
||||
for(unsigned int i=0;i<m_iTilesCount;i++)
|
||||
{
|
||||
|
|
@ -65,4 +66,4 @@ bool LookAtTileHint::onLookAt(int id,int iData)
|
|||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@ private:
|
|||
|
||||
public:
|
||||
LookAtTileHint(eTutorial_Hint id, Tutorial *tutorial, int tiles[], unsigned int tilesLength, int iconOverride = -1, int iData=-1, int iDataOverride = -1);
|
||||
~LookAtTileHint();
|
||||
//TODO: 4jcraft, added, destructor was never implemented
|
||||
~LookAtTileHint(){};
|
||||
|
||||
virtual bool onLookAt(int id, int iData=0);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@ private:
|
|||
|
||||
public:
|
||||
TakeItemHint(eTutorial_Hint id, Tutorial *tutorial, int items[], unsigned int itemsLength);
|
||||
~TakeItemHint();
|
||||
//TODO: 4jcraft, added, it was never implemented
|
||||
virtual ~TakeItemHint(){};
|
||||
|
||||
virtual bool onTake( std::shared_ptr<ItemInstance> item );
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ public:
|
|||
bool m_isFullTutorial;
|
||||
public:
|
||||
Tutorial(int iPad, bool isFullTutorial = false);
|
||||
~Tutorial();
|
||||
virtual ~Tutorial();
|
||||
void tick();
|
||||
|
||||
int getPad() { return m_iPad; }
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ protected:
|
|||
|
||||
public:
|
||||
TutorialHint(eTutorial_Hint id, Tutorial *tutorial, int descriptionId, eHintType type, bool allowFade = true);
|
||||
virtual ~TutorialHint(){}
|
||||
|
||||
eTutorial_Hint getId() { return m_id; }
|
||||
|
||||
|
|
@ -50,4 +51,4 @@ public:
|
|||
virtual bool onLookAtEntity(eINSTANCEOF type);
|
||||
virtual int tick();
|
||||
virtual bool allowFade() { return m_allowFade; }
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glext.h>
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <SDL2/SDL.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
|
@ -23,26 +23,26 @@
|
|||
|
||||
// Iggy GDraw support functions - normally in the Iggy library, stubbed here
|
||||
void * IggyGDrawMallocAnnotated(SINTa size, const char *file, int line) {
|
||||
(void)file; (void)line;
|
||||
return malloc((size_t)size);
|
||||
(void)file; (void)line;
|
||||
return malloc((size_t)size);
|
||||
}
|
||||
|
||||
void IggyGDrawFree(void *ptr) {
|
||||
free(ptr);
|
||||
free(ptr);
|
||||
}
|
||||
|
||||
void IggyGDrawSendWarning(Iggy *f, char const *message, ...) {
|
||||
(void)f;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
fprintf(stderr, "[Iggy GDraw Warning] ");
|
||||
vfprintf(stderr, message, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
(void)f;
|
||||
va_list args;
|
||||
va_start(args, message);
|
||||
fprintf(stderr, "[Iggy GDraw Warning] ");
|
||||
vfprintf(stderr, message, args);
|
||||
fprintf(stderr, "\n");
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
void IggyDiscardVertexBufferCallback(void *owner, void *buf) {
|
||||
(void)owner; (void)buf;
|
||||
(void)owner; (void)buf;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -56,56 +56,56 @@ void IggyDiscardVertexBufferCallback(void *owner, void *buf) {
|
|||
//
|
||||
|
||||
#define GDRAW_GL_EXTENSION_LIST \
|
||||
/* identifier import procname */ \
|
||||
/* GL_ARB_vertex_buffer_object */ \
|
||||
GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \
|
||||
GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \
|
||||
GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \
|
||||
GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \
|
||||
GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \
|
||||
GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \
|
||||
GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \
|
||||
GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", ENABLEVERTEXATTRIBARRAYARB) \
|
||||
GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", DISABLEVERTEXATTRIBARRAYARB) \
|
||||
/* GL_ARB_shader_objects */ \
|
||||
GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \
|
||||
GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \
|
||||
GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \
|
||||
GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \
|
||||
GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
|
||||
GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
|
||||
GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \
|
||||
GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \
|
||||
GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \
|
||||
GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \
|
||||
GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \
|
||||
GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \
|
||||
GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
|
||||
GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
|
||||
GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \
|
||||
GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \
|
||||
GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \
|
||||
/* GL_ARB_vertex_shader */ \
|
||||
GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \
|
||||
/* Missing from WGL but needed by shared code */ \
|
||||
GLE(Uniform1f, "Uniform1fARB", UNIFORM1FARB) \
|
||||
/* GL_EXT_framebuffer_object */ \
|
||||
GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \
|
||||
GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \
|
||||
GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \
|
||||
GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \
|
||||
GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \
|
||||
GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \
|
||||
GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \
|
||||
GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", CHECKFRAMEBUFFERSTATUSEXT) \
|
||||
GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", FRAMEBUFFERRENDERBUFFEREXT) \
|
||||
GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", FRAMEBUFFERTEXTURE2DEXT) \
|
||||
GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \
|
||||
/* GL_EXT_framebuffer_blit */ \
|
||||
GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \
|
||||
/* GL_EXT_framebuffer_multisample */ \
|
||||
GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT",RENDERBUFFERSTORAGEMULTISAMPLEEXT) \
|
||||
/* <end> */
|
||||
/* identifier import procname */ \
|
||||
/* GL_ARB_vertex_buffer_object */ \
|
||||
GLE(GenBuffers, "GenBuffersARB", GENBUFFERSARB) \
|
||||
GLE(DeleteBuffers, "DeleteBuffersARB", DELETEBUFFERSARB) \
|
||||
GLE(BindBuffer, "BindBufferARB", BINDBUFFERARB) \
|
||||
GLE(BufferData, "BufferDataARB", BUFFERDATAARB) \
|
||||
GLE(MapBuffer, "MapBufferARB", MAPBUFFERARB) \
|
||||
GLE(UnmapBuffer, "UnmapBufferARB", UNMAPBUFFERARB) \
|
||||
GLE(VertexAttribPointer, "VertexAttribPointerARB", VERTEXATTRIBPOINTERARB) \
|
||||
GLE(EnableVertexAttribArray, "EnableVertexAttribArrayARB", ENABLEVERTEXATTRIBARRAYARB) \
|
||||
GLE(DisableVertexAttribArray, "DisableVertexAttribArrayARB", DISABLEVERTEXATTRIBARRAYARB) \
|
||||
/* GL_ARB_shader_objects */ \
|
||||
GLE(CreateShader, "CreateShaderObjectARB", CREATESHADEROBJECTARB) \
|
||||
GLE(DeleteShader, "DeleteObjectARB", DELETEOBJECTARB) \
|
||||
GLE(ShaderSource, "ShaderSourceARB", SHADERSOURCEARB) \
|
||||
GLE(CompileShader, "CompileShaderARB", COMPILESHADERARB) \
|
||||
GLE(GetShaderiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
|
||||
GLE(GetShaderInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
|
||||
GLE(CreateProgram, "CreateProgramObjectARB", CREATEPROGRAMOBJECTARB) \
|
||||
GLE(DeleteProgram, "DeleteObjectARB", DELETEOBJECTARB) \
|
||||
GLE(AttachShader, "AttachObjectARB", ATTACHOBJECTARB) \
|
||||
GLE(LinkProgram, "LinkProgramARB", LINKPROGRAMARB) \
|
||||
GLE(GetUniformLocation, "GetUniformLocationARB", GETUNIFORMLOCATIONARB) \
|
||||
GLE(UseProgram, "UseProgramObjectARB", USEPROGRAMOBJECTARB) \
|
||||
GLE(GetProgramiv, "GetObjectParameterivARB", GETOBJECTPARAMETERIVARB) \
|
||||
GLE(GetProgramInfoLog, "GetInfoLogARB", GETINFOLOGARB) \
|
||||
GLE(Uniform1i, "Uniform1iARB", UNIFORM1IARB) \
|
||||
GLE(Uniform4f, "Uniform4fARB", UNIFORM4FARB) \
|
||||
GLE(Uniform4fv, "Uniform4fvARB", UNIFORM4FVARB) \
|
||||
/* GL_ARB_vertex_shader */ \
|
||||
GLE(BindAttribLocation, "BindAttribLocationARB", BINDATTRIBLOCATIONARB) \
|
||||
/* Missing from WGL but needed by shared code */ \
|
||||
GLE(Uniform1f, "Uniform1fARB", UNIFORM1FARB) \
|
||||
/* GL_EXT_framebuffer_object */ \
|
||||
GLE(GenRenderbuffers, "GenRenderbuffersEXT", GENRENDERBUFFERSEXT) \
|
||||
GLE(DeleteRenderbuffers, "DeleteRenderbuffersEXT", DELETERENDERBUFFERSEXT) \
|
||||
GLE(BindRenderbuffer, "BindRenderbufferEXT", BINDRENDERBUFFEREXT) \
|
||||
GLE(RenderbufferStorage, "RenderbufferStorageEXT", RENDERBUFFERSTORAGEEXT) \
|
||||
GLE(GenFramebuffers, "GenFramebuffersEXT", GENFRAMEBUFFERSEXT) \
|
||||
GLE(DeleteFramebuffers, "DeleteFramebuffersEXT", DELETEFRAMEBUFFERSEXT) \
|
||||
GLE(BindFramebuffer, "BindFramebufferEXT", BINDFRAMEBUFFEREXT) \
|
||||
GLE(CheckFramebufferStatus, "CheckFramebufferStatusEXT", CHECKFRAMEBUFFERSTATUSEXT) \
|
||||
GLE(FramebufferRenderbuffer, "FramebufferRenderbufferEXT", FRAMEBUFFERRENDERBUFFEREXT) \
|
||||
GLE(FramebufferTexture2D, "FramebufferTexture2DEXT", FRAMEBUFFERTEXTURE2DEXT) \
|
||||
GLE(GenerateMipmap, "GenerateMipmapEXT", GENERATEMIPMAPEXT) \
|
||||
/* GL_EXT_framebuffer_blit */ \
|
||||
GLE(BlitFramebuffer, "BlitFramebufferEXT", BLITFRAMEBUFFEREXT) \
|
||||
/* GL_EXT_framebuffer_multisample */ \
|
||||
GLE(RenderbufferStorageMultisample, "RenderbufferStorageMultisampleEXT",RENDERBUFFERSTORAGEMULTISAMPLEEXT) \
|
||||
/* <end> */
|
||||
|
||||
#define gdraw_GLx_(id) gdraw_GL_##id
|
||||
#define GDRAW_GLx_(id) GDRAW_GL_##id
|
||||
|
|
@ -125,19 +125,19 @@ GDRAW_GL_EXTENSION_LIST
|
|||
|
||||
static void load_extensions(void)
|
||||
{
|
||||
#define GLE(id, import, procname) gl##id = (PFNGL##procname##PROC) glfwGetProcAddress("gl" import);
|
||||
GDRAW_GL_EXTENSION_LIST
|
||||
#undef GLE
|
||||
#define GLE(id, import, procname) gl##id = (PFNGL##procname##PROC) SDL_GL_GetProcAddress("gl" import);
|
||||
GDRAW_GL_EXTENSION_LIST
|
||||
#undef GLE
|
||||
}
|
||||
|
||||
static void clear_renderstate_platform_specific(void)
|
||||
{
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
}
|
||||
|
||||
static void error_msg_platform_specific(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "[GDraw GL] %s\n", msg);
|
||||
fprintf(stderr, "[GDraw GL] %s\n", msg);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -162,80 +162,80 @@ static void error_msg_platform_specific(const char *msg)
|
|||
|
||||
GDrawFunctions *gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples)
|
||||
{
|
||||
static const TextureFormatDesc tex_formats[] = {
|
||||
{ IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 },
|
||||
{ IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 },
|
||||
{ IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
static const TextureFormatDesc tex_formats[] = {
|
||||
{ IFT_FORMAT_rgba_8888, 1, 1, 4, GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_rgba_4444_LE, 1, 1, 2, GL_RGBA4, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4 },
|
||||
{ IFT_FORMAT_rgba_5551_LE, 1, 1, 2, GL_RGB5_A1, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1 },
|
||||
{ IFT_FORMAT_la_88, 1, 1, 2, GL_LUMINANCE8_ALPHA8, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_la_44, 1, 1, 1, GL_LUMINANCE4_ALPHA4, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_i_8, 1, 1, 1, GL_INTENSITY8, GL_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_i_4, 1, 1, 1, GL_INTENSITY4, GL_ALPHA, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_l_8, 1, 1, 1, GL_LUMINANCE8, GL_LUMINANCE, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_l_4, 1, 1, 1, GL_LUMINANCE4, GL_LUMINANCE, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT1, 4, 4, 8, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT3, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ IFT_FORMAT_DXT5, 4, 4, 16, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, 0, GL_UNSIGNED_BYTE },
|
||||
{ 0, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
GDrawFunctions *funcs;
|
||||
const char *s;
|
||||
GLint n;
|
||||
GDrawFunctions *funcs;
|
||||
const char *s;
|
||||
GLint n;
|
||||
|
||||
// check for the extensions we need
|
||||
s = (const char *) glGetString(GL_EXTENSIONS);
|
||||
if (s == NULL) {
|
||||
fprintf(stderr, "[GDraw GL] glGetString(GL_EXTENSIONS) returned NULL - GL context not current?\n");
|
||||
assert(s != NULL);
|
||||
return NULL;
|
||||
}
|
||||
// check for the extensions we need
|
||||
s = (const char *) glGetString(GL_EXTENSIONS);
|
||||
if (s == NULL) {
|
||||
fprintf(stderr, "[GDraw GL] glGetString(GL_EXTENSIONS) returned NULL - GL context not current?\n");
|
||||
assert(s != NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// check for the extensions we won't work without
|
||||
if (!hasext(s, "GL_ARB_multitexture") ||
|
||||
!hasext(s, "GL_ARB_texture_compression") ||
|
||||
!hasext(s, "GL_ARB_texture_mirrored_repeat") ||
|
||||
!hasext(s, "GL_ARB_texture_non_power_of_two") ||
|
||||
!hasext(s, "GL_ARB_vertex_buffer_object") ||
|
||||
!hasext(s, "GL_EXT_framebuffer_object") ||
|
||||
!hasext(s, "GL_ARB_shader_objects") ||
|
||||
!hasext(s, "GL_ARB_vertex_shader") ||
|
||||
!hasext(s, "GL_ARB_fragment_shader"))
|
||||
{
|
||||
fprintf(stderr, "[GDraw GL] Required GL extensions not available\n");
|
||||
return NULL;
|
||||
}
|
||||
// check for the extensions we won't work without
|
||||
if (!hasext(s, "GL_ARB_multitexture") ||
|
||||
!hasext(s, "GL_ARB_texture_compression") ||
|
||||
!hasext(s, "GL_ARB_texture_mirrored_repeat") ||
|
||||
!hasext(s, "GL_ARB_texture_non_power_of_two") ||
|
||||
!hasext(s, "GL_ARB_vertex_buffer_object") ||
|
||||
!hasext(s, "GL_EXT_framebuffer_object") ||
|
||||
!hasext(s, "GL_ARB_shader_objects") ||
|
||||
!hasext(s, "GL_ARB_vertex_shader") ||
|
||||
!hasext(s, "GL_ARB_fragment_shader"))
|
||||
{
|
||||
fprintf(stderr, "[GDraw GL] Required GL extensions not available\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// if user requests multisampling and HW doesn't support it, bail
|
||||
if (!hasext(s, "GL_EXT_framebuffer_multisample") && msaa_samples > 1)
|
||||
return NULL;
|
||||
// if user requests multisampling and HW doesn't support it, bail
|
||||
if (!hasext(s, "GL_EXT_framebuffer_multisample") && msaa_samples > 1)
|
||||
return NULL;
|
||||
|
||||
load_extensions();
|
||||
funcs = create_context(w, h);
|
||||
if (!funcs)
|
||||
return NULL;
|
||||
load_extensions();
|
||||
funcs = create_context(w, h);
|
||||
if (!funcs)
|
||||
return NULL;
|
||||
|
||||
gdraw->tex_formats = tex_formats;
|
||||
gdraw->tex_formats = tex_formats;
|
||||
|
||||
// check for optional extensions
|
||||
gdraw->has_mapbuffer = true; // part of core VBO extension on regular GL
|
||||
gdraw->has_depth24 = true; // we just assume.
|
||||
gdraw->has_texture_max_level = true; // core on regular GL
|
||||
// check for optional extensions
|
||||
gdraw->has_mapbuffer = true; // part of core VBO extension on regular GL
|
||||
gdraw->has_depth24 = true; // we just assume.
|
||||
gdraw->has_texture_max_level = true; // core on regular GL
|
||||
|
||||
if (hasext(s, "GL_EXT_packed_depth_stencil")) gdraw->has_packed_depth_stencil = true;
|
||||
if (hasext(s, "GL_EXT_packed_depth_stencil")) gdraw->has_packed_depth_stencil = true;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n);
|
||||
gdraw->has_conditional_non_power_of_two = n < 8192;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &n);
|
||||
gdraw->has_conditional_non_power_of_two = n < 8192;
|
||||
|
||||
// clamp number of multisampling levels to max supported
|
||||
if (msaa_samples > 1) {
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &n);
|
||||
gdraw->multisampling = RR_MIN(msaa_samples, n);
|
||||
}
|
||||
// clamp number of multisampling levels to max supported
|
||||
if (msaa_samples > 1) {
|
||||
glGetIntegerv(GL_MAX_SAMPLES, &n);
|
||||
gdraw->multisampling = RR_MIN(msaa_samples, n);
|
||||
}
|
||||
|
||||
opengl_check();
|
||||
opengl_check();
|
||||
|
||||
fprintf(stderr, "[GDraw GL] Context created successfully (%dx%d, msaa=%d)\n", w, h, msaa_samples);
|
||||
return funcs;
|
||||
fprintf(stderr, "[GDraw GL] Context created successfully (%dx%d, msaa=%d)\n", w, h, msaa_samples);
|
||||
return funcs;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -245,12 +245,12 @@ GDrawFunctions *gdraw_GL_CreateContext(S32 w, S32 h, S32 msaa_samples)
|
|||
|
||||
void gdraw_GL_BeginCustomDraw_4J(IggyCustomDrawCallbackRegion *region, F32 *matrix)
|
||||
{
|
||||
// Same as BeginCustomDraw but uses different depth param
|
||||
clear_renderstate();
|
||||
gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, depth_from_id(0), 1);
|
||||
// Same as BeginCustomDraw but uses different depth param
|
||||
clear_renderstate();
|
||||
gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, depth_from_id(0), 1);
|
||||
}
|
||||
|
||||
void gdraw_GL_CalculateCustomDraw_4J(IggyCustomDrawCallbackRegion *region, F32 *matrix)
|
||||
{
|
||||
gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, 0.0f, 0);
|
||||
gdraw_GetObjectSpaceMatrix(matrix, region->o2w, gdraw->projection, 0.0f, 0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ void CConsoleMinecraftApp::ExitGame()
|
|||
}
|
||||
void CConsoleMinecraftApp::FatalLoadError()
|
||||
{
|
||||
app.DebugPrintf("CConsoleMinecraftApp::FatalLoadError - asserting 0 and dying...\n");
|
||||
assert(0);
|
||||
}
|
||||
|
||||
void CConsoleMinecraftApp::CaptureSaveThumbnail()
|
||||
|
|
|
|||
|
|
@ -699,10 +699,6 @@ ProfileManager.Initialise(TITLEID_MINECRAFT,
|
|||
&app.uiGameDefinedDataChangedBitmask
|
||||
);
|
||||
|
||||
byteArray baOptionsIcon = app.getArchiveFile(L"DefaultOptionsImage228x128.png");
|
||||
byteArray baSaveThumbnail = app.getArchiveFile(L"DefaultSaveThumbnail64x64.png");
|
||||
byteArray baSaveImage = app.getArchiveFile(L"DefaultSaveImage228x128.png");
|
||||
|
||||
// set a function to be called when there's a sign in change, so we can exit a level if the primary player signs out
|
||||
ProfileManager.SetSignInChangeCallback(&CConsoleMinecraftApp::SignInChangeCallback,(LPVOID)&app);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ protected:
|
|||
|
||||
public:
|
||||
MultiPlayerGameMode(Minecraft *minecraft, ClientConnection *connection);
|
||||
virtual ~MultiPlayerGameMode(){}
|
||||
static void creativeDestroyBlock(Minecraft *minecraft, MultiPlayerGameMode *gameMode, int x, int y, int z, int face);
|
||||
void adjustPlayer(std::shared_ptr<Player> player);
|
||||
bool isCutScene();
|
||||
|
|
@ -64,4 +65,4 @@ public:
|
|||
virtual bool isInputAllowed(int mapping) { return true; }
|
||||
virtual bool isTutorial() { return false; }
|
||||
virtual Tutorial *getTutorial() { return NULL; }
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ TileRenderer::TileRenderer( LevelSource* level, int xMin, int yMin, int zMin, un
|
|||
|
||||
TileRenderer::~TileRenderer()
|
||||
{
|
||||
delete cache;
|
||||
delete[] cache; //4jcraft, changed to []
|
||||
}
|
||||
|
||||
TileRenderer::TileRenderer( LevelSource* level )
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public:
|
|||
int texHeight;
|
||||
|
||||
Model(); // 4J added
|
||||
virtual ~Model(){}
|
||||
virtual void render(std::shared_ptr<Entity> entity, float time, float r, float bob, float yRot, float xRot, float scale, bool usecompiled) {}
|
||||
virtual void setupAnim(float time, float r, float bob, float yRot, float xRot, float scale, unsigned int uiBitmaskOverrideAnim=0) {}
|
||||
virtual void prepareMobModel(std::shared_ptr<Mob> mob, float time, float r, float a) {}
|
||||
|
|
|
|||
|
|
@ -4,5 +4,6 @@ class BufferedImage;
|
|||
class MemTextureProcessor
|
||||
{
|
||||
public:
|
||||
virtual ~MemTextureProcessor(){}
|
||||
virtual BufferedImage *process(BufferedImage *read) = 0;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ public:
|
|||
using AbstractTexturePack::getResource;
|
||||
|
||||
DLCTexturePack(DWORD id, DLCPack *pack, TexturePack *fallback);
|
||||
~DLCTexturePack();
|
||||
~DLCTexturePack(){};
|
||||
|
||||
virtual std::wstring getResource(const std::wstring& name);
|
||||
virtual DLCPack * getDLCPack();
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class TexturePack
|
|||
public:
|
||||
|
||||
TexturePack() { m_bHasAudio=false;}
|
||||
virtual ~TexturePack(){}
|
||||
virtual bool hasData() = 0;
|
||||
virtual bool hasAudio() { return m_bHasAudio;}
|
||||
virtual void setHasAudio(bool bVal) {m_bHasAudio=bVal;}
|
||||
|
|
|
|||
|
|
@ -60,11 +60,17 @@ void StitchedTexture::freeFrameTextures()
|
|||
|
||||
StitchedTexture::~StitchedTexture()
|
||||
{
|
||||
for(AUTO_VAR(it, frames->begin()); it != frames->end(); ++it)
|
||||
{
|
||||
delete *it;
|
||||
// 4jcraft, added null check
|
||||
// the constructor does not allocate the frames vector.
|
||||
// in some scenarios the destructor/delete is called
|
||||
// without ever calling ::init()
|
||||
if(frames) {
|
||||
for(AUTO_VAR(it, frames->begin()); it != frames->end(); ++it)
|
||||
{
|
||||
delete *it;
|
||||
}
|
||||
delete frames;
|
||||
}
|
||||
delete frames;
|
||||
}
|
||||
|
||||
void StitchedTexture::initUVs(float U0, float V0, float U1, float V1)
|
||||
|
|
@ -351,4 +357,4 @@ int StitchedTexture::getFlags() const
|
|||
bool StitchedTexture::hasOwnData()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,4 +86,4 @@ public:
|
|||
void setFlags(int flags); // 4J added
|
||||
virtual void freeFrameTextures(); // 4J added
|
||||
virtual bool hasOwnData(); // 4J Added
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -193,4 +193,4 @@ Texture *TextureManager::createTexture(const std::wstring &name, int mode, int w
|
|||
// 4J Stu - Don't clamp as it causes issues with how we signal non-mipmmapped textures to the pixel shader
|
||||
//return createTexture(name, mode, width, height, Texture::WM_CLAMP, format, Texture::TFLT_NEAREST, Texture::TFLT_NEAREST, mipmap, NULL);
|
||||
return createTexture(name, mode, width, height, Texture::WM_WRAP, format, Texture::TFLT_NEAREST, Texture::TFLT_NEAREST, mipmap, NULL);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
#pragma once
|
||||
#include "MemoryTracker.h"
|
||||
class ByteBuffer;
|
||||
class IntBuffer;
|
||||
class FloatBuffer;
|
||||
|
|
|
|||
|
|
@ -57,9 +57,8 @@ client = executable('Minecraft.Client',
|
|||
world_dep,
|
||||
gl_dep,
|
||||
glu_dep,
|
||||
glfw_dep,
|
||||
thread_dep,
|
||||
dl_dep,
|
||||
thread_dep,
|
||||
dependency('zlib'),
|
||||
],
|
||||
cpp_args : global_cpp_args + global_cpp_defs + [
|
||||
|
|
@ -86,4 +85,4 @@ custom_target('copy_assets_to_client',
|
|||
'@OUTPUT@',
|
||||
],
|
||||
build_by_default: true,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,9 @@ private:
|
|||
|
||||
public:
|
||||
JumpControl(Mob *mob);
|
||||
virtual ~JumpControl(){}
|
||||
|
||||
void jump();
|
||||
//genuinly, why tf is this VIRTUAL
|
||||
virtual void tick();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ private:
|
|||
|
||||
public:
|
||||
LookControl(Mob *mob);
|
||||
virtual ~LookControl(){}
|
||||
|
||||
void setLookAt(std::shared_ptr<Entity> target, float yMax, float xMax);
|
||||
void setLookAt(double x, double y, double z, float yMax, float xMax);
|
||||
|
|
@ -30,4 +31,4 @@ public:
|
|||
double getWantedX();
|
||||
double getWantedY();
|
||||
double getWantedZ();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ private:
|
|||
|
||||
public:
|
||||
MoveControl(Mob *mob);
|
||||
virtual ~MoveControl(){}
|
||||
|
||||
bool hasWanted();
|
||||
float getSpeed();
|
||||
|
|
@ -31,4 +32,4 @@ public:
|
|||
|
||||
private:
|
||||
float rotlerp(float a, float b, float max);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class Player;
|
|||
class Container
|
||||
{
|
||||
public:
|
||||
virtual ~Container(){}
|
||||
static const int LARGE_MAX_STACK_SIZE = 64;
|
||||
|
||||
virtual unsigned int getContainerSize() = 0;
|
||||
|
|
@ -20,4 +21,4 @@ public:
|
|||
virtual bool stillValid(std::shared_ptr<Player> player) = 0;
|
||||
virtual void startOpen() = 0;
|
||||
virtual void stopOpen() = 0;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ private:
|
|||
|
||||
public:
|
||||
CraftingContainer(AbstractContainerMenu *menu, unsigned int w, unsigned int h);
|
||||
~CraftingContainer();
|
||||
virtual ~CraftingContainer();
|
||||
|
||||
virtual unsigned int getContainerSize();
|
||||
virtual std::shared_ptr<ItemInstance> getItem(unsigned int slot);
|
||||
|
|
@ -29,4 +29,4 @@ public:
|
|||
void startOpen() { } // TODO Auto-generated method stub
|
||||
void stopOpen() { } // TODO Auto-generated method stub
|
||||
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ class Player;
|
|||
class Merchant
|
||||
{
|
||||
public:
|
||||
virtual ~Merchant(){}
|
||||
virtual void setTradingPlayer(std::shared_ptr<Player> player) = 0;
|
||||
virtual std::shared_ptr<Player> getTradingPlayer() = 0;
|
||||
virtual MerchantRecipeList *getOffers(std::shared_ptr<Player> forPlayer) = 0;
|
||||
|
|
@ -14,4 +15,4 @@ public:
|
|||
virtual void notifyTrade(MerchantRecipe *activeRecipe) = 0;
|
||||
virtual void notifyTradeUpdated(std::shared_ptr<ItemInstance> item) = 0;
|
||||
virtual int getDisplayName() = 0;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ private:
|
|||
public:
|
||||
// 4J Stu Added a ctor to init items
|
||||
ResultContainer();
|
||||
virtual ~ResultContainer(){}
|
||||
|
||||
virtual unsigned int getContainerSize();
|
||||
virtual std::shared_ptr<ItemInstance> getItem(unsigned int slot);
|
||||
|
|
@ -23,4 +24,4 @@ public:
|
|||
|
||||
void startOpen() { } // TODO Auto-generated method stub
|
||||
void stopOpen() { } // TODO Auto-generated method stub
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,11 @@ BufferedOutputStream::BufferedOutputStream(OutputStream *out, int size)
|
|||
|
||||
BufferedOutputStream::~BufferedOutputStream()
|
||||
{
|
||||
delete buf.data;
|
||||
//4jcraft, changed to [], deallocates internal buffer
|
||||
//TODO: ArrayWithLength.h doesnt have a destructor.
|
||||
//this wouldnt need to be done manually.
|
||||
//but for some reason the destructor is commented out in the source code?
|
||||
delete[] buf.data;
|
||||
}
|
||||
|
||||
//Flushes this buffered output stream. This forces any buffered output bytes to be written out to the underlying output stream.
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ private:
|
|||
ItemInstance() { _init(-1,0,0); }
|
||||
|
||||
public:
|
||||
~ItemInstance();
|
||||
virtual ~ItemInstance();
|
||||
std::shared_ptr<ItemInstance> remove(int count);
|
||||
|
||||
Item *getItem() const;
|
||||
|
|
@ -151,4 +151,4 @@ public:
|
|||
|
||||
int getBaseRepairCost();
|
||||
void setRepairCost(int cost);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -342,6 +342,6 @@ std::shared_ptr<Packet> MapItem::getUpdatePacket(std::shared_ptr<ItemInstance> i
|
|||
if (data.data == NULL || data.length == 0) return nullptr;
|
||||
|
||||
std::shared_ptr<Packet> retval = std::shared_ptr<Packet>(new ComplexItemDataPacket((short) Item::map->id, (short) itemInstance->getAuxValue(), data));
|
||||
delete data.data;
|
||||
delete[] data.data; //4jcraft, changed to []
|
||||
return retval;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ protected:
|
|||
|
||||
public:
|
||||
Dimension();
|
||||
~Dimension();
|
||||
virtual ~Dimension();
|
||||
virtual ChunkSource *createRandomLevelSource() const;
|
||||
virtual ChunkSource *createFlatLevelSource() const;
|
||||
virtual ChunkStorage *createStorage(File dir);
|
||||
|
|
|
|||
|
|
@ -152,7 +152,7 @@ public:
|
|||
LevelChunk(Level *level, int x, int z);
|
||||
LevelChunk(Level *level, byteArray blocks, int x, int z);
|
||||
LevelChunk(Level *level, int x, int z, LevelChunk *lc);
|
||||
~LevelChunk();
|
||||
virtual ~LevelChunk();
|
||||
|
||||
virtual bool isAt(int x, int z);
|
||||
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ protected:
|
|||
virtual void setTagData(CompoundTag *tag); // 4J - removed CompoundTag *playerTag
|
||||
|
||||
public:
|
||||
virtual ~LevelData(){}
|
||||
virtual __int64 getSeed();
|
||||
virtual int getXSpawn();
|
||||
virtual int getYSpawn();
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public:
|
|||
static const std::wstring NETHER_FOLDER;
|
||||
static const std::wstring ENDER_FOLDER;
|
||||
|
||||
virtual ~LevelStorage(){}
|
||||
virtual LevelData *prepareLevel() = 0;
|
||||
virtual void checkSession() = 0;
|
||||
virtual ChunkStorage *createChunkStorage(Dimension *dimension) = 0;
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ charArray MapItemSavedData::HoldingPlayer::nextUpdatePacket(std::shared_ptr<Item
|
|||
memcpy(lastSentDecorations.data, data.data, data.length);
|
||||
return data;
|
||||
}
|
||||
delete data.data;
|
||||
delete[] data.data; //4jcraft, changed to []
|
||||
}
|
||||
std::shared_ptr<ServerPlayer> servPlayer = std::dynamic_pointer_cast<ServerPlayer>(player);
|
||||
for (int d = 0; d < 10; d++)
|
||||
|
|
|
|||
|
|
@ -19,4 +19,4 @@ public:
|
|||
virtual void saveMapIdLookup() = 0;
|
||||
virtual void deleteMapFilesForPlayer(std::shared_ptr<Player> player) = 0;
|
||||
virtual void saveAllCachedData() = 0;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ private:
|
|||
|
||||
public:
|
||||
SavedData(const std::wstring& id);
|
||||
virtual ~SavedData(){}
|
||||
|
||||
virtual void load(CompoundTag *tag) = 0;
|
||||
virtual void save(CompoundTag *tag) = 0;
|
||||
|
|
@ -22,4 +23,4 @@ public:
|
|||
void setDirty();
|
||||
void setDirty(bool dirty);
|
||||
bool isDirty();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -16,7 +16,13 @@ AwardStatPacket::AwardStatPacket(int statId, int count)
|
|||
{
|
||||
this->statId = statId;
|
||||
|
||||
this->m_paramData.data = (uint8_t *) new int(count);
|
||||
// 4jcraft, changed from (uint8_t*) new int(count); to:
|
||||
// new uint8_t[sizeof(int)];
|
||||
// and memcpy of the integer into the array
|
||||
// reason: operator missmatch, array is deleted with delete[]
|
||||
// and typesafety
|
||||
this->m_paramData.data = new uint8_t[sizeof(int)];
|
||||
memcpy(this->m_paramData.data, &count, sizeof(int));
|
||||
this->m_paramData.length = sizeof(int);
|
||||
}
|
||||
|
||||
|
|
@ -30,7 +36,7 @@ AwardStatPacket::~AwardStatPacket()
|
|||
{
|
||||
if (m_paramData.data != NULL)
|
||||
{
|
||||
delete [] m_paramData.data;
|
||||
delete[] m_paramData.data;
|
||||
m_paramData.data = NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ public:
|
|||
const int id;
|
||||
|
||||
public:
|
||||
PacketStatistics(int id) : id( id ), count( 0 ), totalSize( 0 ), samplesPos( 0 ), firstSampleTime( 0 ) { countSamples[0] = 0; sizeSamples[0] = 0; }
|
||||
PacketStatistics(int id) : count( 0 ), totalSize( 0 ), samplesPos( 0 ), firstSampleTime( 0 ), id( id ) { countSamples[0] = 0; sizeSamples[0] = 0; }
|
||||
void addPacket(int bytes);
|
||||
int getCount();
|
||||
double getAverageSize();
|
||||
|
|
@ -61,6 +61,7 @@ public:
|
|||
const __int64 createTime;
|
||||
|
||||
Packet();
|
||||
virtual ~Packet(){}
|
||||
|
||||
static std::shared_ptr<Packet> getPacket(int id);
|
||||
|
||||
|
|
@ -110,4 +111,4 @@ public:
|
|||
|
||||
protected:
|
||||
static void writeNbt(CompoundTag *tag, DataOutputStream *dos);
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -106,6 +106,7 @@ class GameCommandPacket;
|
|||
class PacketListener
|
||||
{
|
||||
public:
|
||||
virtual ~PacketListener(){}
|
||||
virtual bool isServerPacketListener() = 0;
|
||||
virtual void handleBlockRegionUpdate(std::shared_ptr<BlockRegionUpdatePacket> packet);
|
||||
virtual void onUnhandledPacket(std::shared_ptr<Packet> packet);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ RemoveEntitiesPacket::RemoveEntitiesPacket(intArray ids)
|
|||
|
||||
RemoveEntitiesPacket::~RemoveEntitiesPacket()
|
||||
{
|
||||
delete ids.data;
|
||||
delete[] ids.data; //4jcraft, changed to []
|
||||
}
|
||||
|
||||
void RemoveEntitiesPacket::read(DataInputStream *dis) //throws IOException
|
||||
|
|
|
|||
|
|
@ -12,14 +12,14 @@ AABB::ThreadStorage *AABB::tlsDefault = NULL;
|
|||
|
||||
AABB::ThreadStorage::ThreadStorage()
|
||||
{
|
||||
pool = new AABB[POOL_SIZE];
|
||||
pool = new AABB[POOL_SIZE]; //4jcraft, needs to be deleted with delete[]
|
||||
poolPointer = 0;
|
||||
}
|
||||
|
||||
|
||||
AABB::ThreadStorage::~ThreadStorage()
|
||||
{
|
||||
delete pool;
|
||||
delete[] pool; //4jcraft, changed to []
|
||||
}
|
||||
|
||||
void AABB::CreateNewThreadStorage()
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ public:
|
|||
static const int IS_ALPHA_CUT_OUT = 4;
|
||||
#endif
|
||||
|
||||
virtual ~Icon() {} // added by 4jcraft, needed for abstract class
|
||||
|
||||
virtual int getX() const = 0;
|
||||
virtual int getY() const = 0;
|
||||
virtual int getWidth() const = 0;
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@ protected:
|
|||
|
||||
public:
|
||||
BiomeDecorator(Biome *biome);
|
||||
virtual ~BiomeDecorator(){}
|
||||
|
||||
|
||||
void decorate(Level *level, Random *random, int xo, int zo);
|
||||
|
||||
|
|
@ -72,4 +74,4 @@ protected:
|
|||
void decorateDepthSpan(int count, Feature *feature, int y0, int y1);
|
||||
void decorateDepthAverage(int count, Feature *feature, int yMid, int ySpan);
|
||||
void decorateOres();
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ void BiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h,
|
|||
{
|
||||
BiomeArray tmp = cache->getBiomeBlockAt(x, z);
|
||||
System::arraycopy(tmp, 0, &biomes, 0, w * h);
|
||||
delete tmp.data; // MGH - added, the caching creates this array from the indices now.
|
||||
delete[] tmp.data; // MGH - added, the caching creates this array from the indices now. //4jcraft made it array delete
|
||||
//return biomes;
|
||||
}
|
||||
|
||||
|
|
@ -635,4 +635,4 @@ bool BiomeSource::getIsMatch(float *frac)
|
|||
|
||||
// Consider as suitable if we've got all the critical ones, and in total 9 or more - currently there's 8 critical so this just forces at least 1 more others
|
||||
return ( typeCount >= 9 );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ public:
|
|||
#else
|
||||
static __int64 findSeed(LevelType *generator); // 4J added
|
||||
#endif
|
||||
~BiomeSource();
|
||||
virtual ~BiomeSource();
|
||||
|
||||
public:
|
||||
std::vector<Biome *> getPlayerSpawnBiomes() { return playerSpawnBiomes; }
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
bool HouseFeature::place(Level *level, Random *random, int x, int y, int z)
|
||||
{
|
||||
while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion())
|
||||
while (y > 0 && !level->getMaterial(x, y - 1, z)->blocksMotion()) {
|
||||
y--;
|
||||
|
||||
}
|
||||
int w = random->nextInt(7) + 7;
|
||||
int h = 4 + random->nextInt(3) / 2;
|
||||
int d = random->nextInt(7) + 7;
|
||||
|
|
@ -190,4 +190,4 @@ bool HouseFeature::place(Level *level, Random *random, int x, int y, int z)
|
|||
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,8 +13,9 @@ bool LakeFeature::place(Level *level, Random *random, int x, int y, int z)
|
|||
{
|
||||
x -= 8;
|
||||
z -= 8;
|
||||
while (y > 5 && level->isEmptyTile(x, y, z))
|
||||
while (y > 5 && level->isEmptyTile(x, y, z)) {
|
||||
y--;
|
||||
}
|
||||
if (y <= 4)
|
||||
{
|
||||
return false;
|
||||
|
|
@ -172,4 +173,4 @@ bool LakeFeature::place(Level *level, Random *random, int x, int y, int z)
|
|||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,10 +14,10 @@ protected:
|
|||
|
||||
public:
|
||||
LargeFeature();
|
||||
~LargeFeature();
|
||||
virtual ~LargeFeature();
|
||||
|
||||
virtual void apply(ChunkSource *ChunkSource, Level *level, int xOffs, int zOffs, byteArray blocks);
|
||||
|
||||
protected:
|
||||
virtual void addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks) {}
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,9 +5,9 @@ class TreeFeature : public Feature
|
|||
{
|
||||
private:
|
||||
const int baseHeight;
|
||||
const bool addJungleFeatures;
|
||||
const int trunkType;
|
||||
const int leafType;
|
||||
const bool addJungleFeatures;
|
||||
|
||||
public:
|
||||
TreeFeature(bool doUpdate);
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ BiomeOverrideLayer::BiomeOverrideLayer(int seedMixup) : Layer(seedMixup)
|
|||
#endif
|
||||
if( file == INVALID_HANDLE_VALUE )
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
// DWORD error = GetLastError();
|
||||
//assert(false);
|
||||
app.DebugPrintf("Biome override not found, using plains as default\n");
|
||||
|
||||
|
|
@ -78,4 +78,4 @@ intArray BiomeOverrideLayer::getArea(int xo, int yo, int w, int h)
|
|||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ public:
|
|||
static LayerArray getDefaultLayers(__int64 seed, LevelType *levelType);
|
||||
|
||||
Layer(__int64 seedMixup);
|
||||
virtual ~Layer(){}
|
||||
|
||||
virtual void init(__int64 seed);
|
||||
virtual void initRandom(__int64 x, __int64 y);
|
||||
|
|
@ -33,4 +34,4 @@ protected:
|
|||
|
||||
public:
|
||||
virtual intArray getArea(int xo, int yo, int w, int h) = 0;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ class Synth
|
|||
{
|
||||
public:
|
||||
virtual double getValue(double x, double y) = 0;
|
||||
virtual ~Synth(){}
|
||||
|
||||
doubleArray create(int width, int height);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -188,7 +188,8 @@ LevelChunk *TheEndLevelRandomLevelSource::getChunk(int xOffs, int zOffs)
|
|||
levelChunk->recalcHeightmap();
|
||||
|
||||
//delete blocks.data; // Don't delete the blocks as the array data is actually owned by the chunk now
|
||||
delete biomes.data;
|
||||
//4jcraft changed to []
|
||||
delete[] biomes.data;
|
||||
|
||||
return levelChunk;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ private:
|
|||
int maxPlaceCount;
|
||||
|
||||
PieceWeight(EPieceClass pieceClass, int weight, int maxPlaceCount);
|
||||
virtual ~PieceWeight(){}
|
||||
virtual bool doPlace(int depth);
|
||||
bool isValid();
|
||||
};
|
||||
|
|
|
|||
15
README.md
15
README.md
|
|
@ -23,7 +23,7 @@ At the moment, we're aiming to support the following platforms:
|
|||
- Android (not started)
|
||||
|
||||
> [!WARNING]
|
||||
> There NO Windows support, for that, go to [smartcmd/MinecraftConsoles](https://github.com/smartcmd/MinecraftConsoles/).
|
||||
> There is NO Windows support, for that, go to [smartcmd/MinecraftConsoles](https://github.com/smartcmd/MinecraftConsoles/).
|
||||
|
||||
> All efforts are focused towards a native Linux port, OpenGL rendering pipeline, and modernizing the existing LCE codebase/tooling to make future platform ports easier.
|
||||
>
|
||||
|
|
@ -38,26 +38,19 @@ At the moment, we're aiming to support the following platforms:
|
|||
Install the following packages before building (Debian/Ubuntu names shown):
|
||||
|
||||
```bash
|
||||
sudo apt install \
|
||||
build-essential cmake \
|
||||
libglfw3-dev libgl-dev libglu1-mesa-dev \
|
||||
libopenal-dev libvorbis-dev \
|
||||
libpng-dev libpthread-stubs0-dev
|
||||
sudo apt-get install -y build-essential libsdl2-dev libgl-dev libglu1-mesa-dev libpthread-stubs0-dev
|
||||
```
|
||||
|
||||
#### Arch/Manjaro
|
||||
|
||||
```bash
|
||||
sudo pacman -S base-devel gcc pkgconf cmake glfw-x11 mesa openal libvorbis glu
|
||||
sudo pacman -S base-devel gcc pkgconf cmake sdl2-compat mesa glu
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> If you are on wayland, you may swap `glfw-x11` to `glfw-wayland` for native wayland windowing instead of xwayland.
|
||||
|
||||
#### Fedora/Red Hat/Nobara
|
||||
|
||||
```bash
|
||||
sudo dnf in gcc gcc-c++ make cmake glfw-devel mesa-libGL-devel mesa-libGLU-devel openal-soft-devel libvorbis-devel libpng-devel openssl-devel
|
||||
sudo dnf in gcc gcc-c++ make cmake SDL2-devel mesa-libGL-devel mesa-libGLU-devel openssl-devel
|
||||
```
|
||||
|
||||
#### Docker
|
||||
|
|
|
|||
10
flake.nix
10
flake.nix
|
|
@ -21,19 +21,15 @@
|
|||
{
|
||||
devShells = forAllSystems ({ pkgs }:
|
||||
let
|
||||
libs = with pkgs; [
|
||||
libs = with pkgs; [
|
||||
openssl.dev
|
||||
libGL
|
||||
libGLU
|
||||
glfw
|
||||
libpng
|
||||
sdl2
|
||||
zlib
|
||||
openal
|
||||
libvorbis
|
||||
];
|
||||
packages = with pkgs; [
|
||||
python3
|
||||
gcc15
|
||||
clang
|
||||
lld
|
||||
cmake
|
||||
gnumake
|
||||
|
|
|
|||
|
|
@ -16,10 +16,9 @@ cc = meson.get_compiler('cpp')
|
|||
# system deps
|
||||
gl_dep = dependency('gl')
|
||||
glu_dep = dependency('glu')
|
||||
glfw_dep = dependency('glfw3')
|
||||
png_dep = dependency('libpng')
|
||||
sdl2_dep = dependency('sdl2') # Yes.. i know sdl3 is out, but there's not point upgrading right now except when
|
||||
# someone is gonna ask me "Hey juicey can you make it SDL3?" and i'd be like fuck you and still do it.
|
||||
thread_dep = dependency('threads')
|
||||
dl_dep = cc.find_library('dl')
|
||||
|
||||
# compile flags (chagne ts juicey)
|
||||
global_cpp_args = [
|
||||
|
|
@ -56,4 +55,4 @@ subdir('4J.Profile')
|
|||
subdir('4J.Storage')
|
||||
subdir('Minecraft.Assets')
|
||||
subdir('Minecraft.World')
|
||||
subdir('Minecraft.Client')
|
||||
subdir('Minecraft.Client')
|
||||
|
|
|
|||
Loading…
Reference in a new issue