forked from tas/major_tom
Implement four feature phases: Phase 1 - Pause menu: extract bitmap font into shared engine/font module, add MODE_PAUSED with Resume/Restart/Quit overlay. Phase 2 - Laser turret hazard: ENT_LASER_TURRET with charge/fire/ cooldown state machine, per-pixel beam raycast, two variants (fixed and tracking). Registered in entity registry with editor icons. Phase 3 - Charger and Spawner enemies: charger ground patrol with detect/telegraph/charge/stun cycle (2s charge timeout), spawner that periodically creates grunts up to a global cap of 3. Phase 4 - Mars campaign: two handcrafted levels (mars01 surface, mars02 base), mars_tileset.png, PARALLAX_STYLE_MARS with salmon sky and red mesas, THEME_MARS_SURFACE/THEME_MARS_BASE for the procedural generator with per-theme gravity/tileset/parallax. Moon campaign now chains moon03 -> mars01 -> mars02 -> victory. Also fix review findings: deterministic seed on generated level restart, NULL checks on calloc in spawn functions, charge timeout to prevent infinite charge on flat terrain, and stop suppressing stderr in Makefile web-serve target so real errors are visible.
220 lines
7.3 KiB
Makefile
220 lines
7.3 KiB
Makefile
# JNR Engine - 2D Side-Scroller Engine
|
|
# =====================================
|
|
|
|
# ── Platform detection ──────────────────────────
|
|
ifdef WASM
|
|
# Emscripten / WebAssembly build
|
|
CC := emcc
|
|
CFLAGS := -Wall -Wextra -std=c11 -I include -I src \
|
|
-sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sUSE_SDL_MIXER=2 \
|
|
-sSDL2_IMAGE_FORMATS='["png"]' \
|
|
-sSDL2_MIXER_FORMATS='["ogg"]'
|
|
LDFLAGS := -sUSE_SDL=2 -sUSE_SDL_IMAGE=2 -sUSE_SDL_MIXER=2 \
|
|
-sSDL2_IMAGE_FORMATS='["png"]' \
|
|
-sSDL2_MIXER_FORMATS='["ogg"]' \
|
|
-sALLOW_MEMORY_GROWTH=1 \
|
|
-sEXPORTED_FUNCTIONS='["_main","_editor_upload_flag_ptr","_editor_save_flag_ptr","_editor_load_flag_ptr","_editor_load_vfs_file","_malloc","_free"]' \
|
|
-sEXPORTED_RUNTIME_METHODS='["UTF8ToString","stringToUTF8","lengthBytesUTF8"]' \
|
|
--preload-file assets \
|
|
--shell-file web/shell.html
|
|
|
|
BIN := dist-web/jnr.html
|
|
OBJ_DIR := build-wasm
|
|
|
|
else ifdef WINDOWS
|
|
# Cross-compile for Windows using MinGW
|
|
CC := x86_64-w64-mingw32-gcc
|
|
WINDRES := x86_64-w64-mingw32-windres
|
|
|
|
WIN_SDL2 := deps/win64/SDL2-2.30.11/x86_64-w64-mingw32
|
|
WIN_SDL2_IMAGE := deps/win64/SDL2_image-2.8.4/x86_64-w64-mingw32
|
|
WIN_SDL2_MIXER := deps/win64/SDL2_mixer-2.8.0/x86_64-w64-mingw32
|
|
|
|
CFLAGS := -Wall -Wextra -std=c11 -I include -I src \
|
|
-I$(WIN_SDL2)/include -I$(WIN_SDL2)/include/SDL2 \
|
|
-I$(WIN_SDL2_IMAGE)/include -I$(WIN_SDL2_IMAGE)/include/SDL2 \
|
|
-I$(WIN_SDL2_MIXER)/include -I$(WIN_SDL2_MIXER)/include/SDL2
|
|
LDFLAGS := -L$(WIN_SDL2)/lib -L$(WIN_SDL2_IMAGE)/lib -L$(WIN_SDL2_MIXER)/lib \
|
|
-lmingw32 -lSDL2main -lSDL2 -lSDL2_image -lSDL2_mixer -lm \
|
|
-mwindows
|
|
|
|
BIN := jnr.exe
|
|
OBJ_DIR := build-win64
|
|
|
|
else
|
|
# Native Linux build
|
|
CC := gcc
|
|
CFLAGS := -Wall -Wextra -std=c11 -I include -I src
|
|
LDFLAGS :=
|
|
|
|
# SDL2 flags via pkg-config
|
|
SDL_CFLAGS := $(shell sdl2-config --cflags)
|
|
SDL_LDFLAGS := $(shell sdl2-config --libs) -lSDL2_image -lSDL2_mixer -lm
|
|
|
|
CFLAGS += $(SDL_CFLAGS)
|
|
LDFLAGS += $(SDL_LDFLAGS)
|
|
|
|
BIN := jnr
|
|
OBJ_DIR := build
|
|
|
|
endif
|
|
|
|
# ── Build modes ─────────────────────────────────
|
|
ifdef DEBUG
|
|
CFLAGS += -g -O0 -DDEBUG
|
|
else
|
|
CFLAGS += -O2 -DNDEBUG
|
|
endif
|
|
|
|
# ── Source files ────────────────────────────────
|
|
SRC_ENGINE := $(wildcard src/engine/*.c)
|
|
SRC_GAME := $(wildcard src/game/*.c)
|
|
SRC_MAIN := src/main.c
|
|
SRC_ALL := $(SRC_ENGINE) $(SRC_GAME) $(SRC_MAIN)
|
|
|
|
# ── Object files ────────────────────────────────
|
|
OBJ_ALL := $(SRC_ALL:src/%.c=$(OBJ_DIR)/%.o)
|
|
|
|
# ── Targets ─────────────────────────────────────
|
|
.PHONY: all clean run debug windows deploy serve web web-serve k8s
|
|
|
|
all: $(BIN)
|
|
|
|
# On WASM builds the shell template is baked into the output HTML,
|
|
# so re-link whenever it changes.
|
|
ifdef WASM
|
|
EXTRA_LINK_DEPS := web/shell.html
|
|
endif
|
|
|
|
$(BIN): $(OBJ_ALL) $(EXTRA_LINK_DEPS) | outdirs
|
|
$(CC) $(OBJ_ALL) -o $@ $(LDFLAGS)
|
|
|
|
outdirs:
|
|
@mkdir -p $(dir $(BIN))
|
|
|
|
$(OBJ_DIR)/%.o: src/%.c | dirs
|
|
$(CC) $(CFLAGS) -c $< -o $@
|
|
|
|
dirs:
|
|
@mkdir -p $(OBJ_DIR)/engine $(OBJ_DIR)/game
|
|
|
|
clean:
|
|
rm -rf build build-win64 build-wasm jnr jnr.exe dist-win64 dist-web
|
|
|
|
run: all
|
|
./$(BIN)
|
|
|
|
debug:
|
|
$(MAKE) DEBUG=1 all
|
|
|
|
# ── WebAssembly / Emscripten ────────────────────
|
|
# Requires: source ~/emsdk/emsdk_env.sh (or wherever emsdk is installed)
|
|
#
|
|
# Usage:
|
|
# make web Build Wasm + HTML
|
|
# make web-serve Build + start local server on port 8080
|
|
#
|
|
web:
|
|
@mkdir -p dist-web
|
|
$(MAKE) WASM=1 all
|
|
@cp dist-web/jnr.html dist-web/index.html
|
|
@echo ""
|
|
@echo "Web build ready in dist-web/"
|
|
@echo "Serve with: make web-serve"
|
|
|
|
WEB_PORT := 8080
|
|
|
|
web-serve: web
|
|
@echo ""
|
|
@echo "Serving at http://localhost:$(WEB_PORT)/jnr.html"
|
|
@echo "Ctrl+C to stop."
|
|
@python3 -m http.server $(WEB_PORT) --directory dist-web || \
|
|
python -m http.server $(WEB_PORT) --directory dist-web || \
|
|
echo "Error: Python not found. Install python3 to serve."
|
|
|
|
# ── Windows cross-compilation ───────────────────
|
|
WIN_DIST := dist-win64
|
|
WIN_DLL_SDL2 := deps/win64/SDL2-2.30.11/x86_64-w64-mingw32/bin
|
|
WIN_DLL_SDL2_IMAGE := deps/win64/SDL2_image-2.8.4/x86_64-w64-mingw32/bin
|
|
WIN_DLL_SDL2_MIXER := deps/win64/SDL2_mixer-2.8.0/x86_64-w64-mingw32/bin
|
|
|
|
windows:
|
|
$(MAKE) WINDOWS=1 all
|
|
@mkdir -p $(WIN_DIST)
|
|
@cp jnr.exe $(WIN_DIST)/
|
|
@cp $(WIN_DLL_SDL2)/SDL2.dll $(WIN_DIST)/
|
|
@cp $(WIN_DLL_SDL2_IMAGE)/*.dll $(WIN_DIST)/ 2>/dev/null || true
|
|
@cp $(WIN_DLL_SDL2_MIXER)/*.dll $(WIN_DIST)/ 2>/dev/null || true
|
|
@cp -r assets $(WIN_DIST)/
|
|
@echo ""
|
|
@echo "Windows build ready in $(WIN_DIST)/"
|
|
@echo "Copy the $(WIN_DIST) folder to a Windows machine and run jnr.exe"
|
|
|
|
# ── Fast deploy to Windows ──────────────────────
|
|
# Builds, zips, and serves via HTTP for easy download.
|
|
#
|
|
# Usage:
|
|
# On Linux: make deploy
|
|
# On Windows: see printed instructions
|
|
#
|
|
DEPLOY_PORT := 9000
|
|
DEPLOY_ZIP := jnr-latest.zip
|
|
|
|
deploy: windows
|
|
@cd $(WIN_DIST) && zip -qr ../$(DEPLOY_ZIP) .
|
|
@echo ""
|
|
@echo "============================================"
|
|
@echo " Build ready: $(DEPLOY_ZIP)"
|
|
@echo "============================================"
|
|
@echo ""
|
|
@echo "Option 1 - SCP (run on Windows PowerShell):"
|
|
@echo ""
|
|
@echo ' scp USER@HOST:$(CURDIR)/$(DEPLOY_ZIP) $$env:USERPROFILE\Desktop\jnr-latest.zip'
|
|
@echo ""
|
|
@echo "Option 2 - HTTP download (starting server...):"
|
|
@echo ""
|
|
@HOST_IP=$$(hostname -I | awk '{print $$1}'); \
|
|
echo " In PowerShell:"; \
|
|
echo ""; \
|
|
echo " Invoke-WebRequest http://$$HOST_IP:$(DEPLOY_PORT)/$(DEPLOY_ZIP) -OutFile ~\Desktop\jnr-latest.zip"; \
|
|
echo ""; \
|
|
echo " Ctrl+C to stop server."; \
|
|
echo ""; \
|
|
python3 -m http.server $(DEPLOY_PORT) --bind 0.0.0.0 2>/dev/null || \
|
|
python -m http.server $(DEPLOY_PORT) --bind 0.0.0.0 2>/dev/null || \
|
|
echo "Python not found - use SCP instead."
|
|
|
|
# Just rebuild exe + assets (skip DLL copy if they haven't changed)
|
|
quick:
|
|
$(MAKE) WINDOWS=1 all
|
|
@cp jnr.exe $(WIN_DIST)/
|
|
@rsync -a --delete assets/ $(WIN_DIST)/assets/ 2>/dev/null || cp -r assets $(WIN_DIST)/
|
|
@cd $(WIN_DIST) && zip -qr ../$(DEPLOY_ZIP) .
|
|
@echo "Updated $(DEPLOY_ZIP)"
|
|
|
|
# ── Kubernetes (k3s) deployment ─────────────────
|
|
# Builds the web version, packages it into a container image,
|
|
# imports it into k3s, and applies the manifests.
|
|
#
|
|
# Usage:
|
|
# make k8s Build + deploy to local k3s
|
|
#
|
|
K8S_IMAGE := jnr-web
|
|
K8S_TAG := latest
|
|
|
|
k8s: web
|
|
@echo ""
|
|
@echo "Building container image $(K8S_IMAGE):$(K8S_TAG)..."
|
|
@command -v podman >/dev/null 2>&1 && \
|
|
podman build -t $(K8S_IMAGE):$(K8S_TAG) . || \
|
|
docker build -t $(K8S_IMAGE):$(K8S_TAG) .
|
|
@echo "Importing image into k3s..."
|
|
@command -v podman >/dev/null 2>&1 && \
|
|
podman save $(K8S_IMAGE):$(K8S_TAG) | sudo k3s ctr images import - || \
|
|
docker save $(K8S_IMAGE):$(K8S_TAG) | sudo k3s ctr images import -
|
|
@echo "Applying manifests..."
|
|
@sudo k3s kubectl apply -f k8s/
|
|
@echo ""
|
|
@echo "Deployed. Check status with:"
|
|
@echo " sudo k3s kubectl get pods -l app=jnr-web"
|