# 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"