From 63627d9c7a20f5a0a40299f93fbfd920feb7dbd4 Mon Sep 17 00:00:00 2001 From: Rokas Puzonas Date: Thu, 20 Jul 2023 03:10:09 +0300 Subject: [PATCH] add wasm support --- .gitignore | 4 +- .gitmodules | 3 + Makefile | 172 +++++++++++++++++++++++++++------------------- README.md | 29 ++++---- compile_flags.txt | 2 + depends/emsdk | 1 + src/main.cpp | 47 +++++++------ src/shell.html | 96 ++++++++++++++++++++++++++ 8 files changed, 247 insertions(+), 107 deletions(-) create mode 100644 compile_flags.txt create mode 160000 depends/emsdk create mode 100644 src/shell.html diff --git a/.gitignore b/.gitignore index fc687bf..378eac2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1 @@ -include -lib -bin +build diff --git a/.gitmodules b/.gitmodules index d039609..db63b3b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "depends/raylib"] path = depends/raylib url = https://github.com/raysan5/raylib +[submodule "depends/emsdk"] + path = depends/emsdk + url = git@github.com:emscripten-core/emsdk.git diff --git a/Makefile b/Makefile index 057ec5f..5c1862a 100644 --- a/Makefile +++ b/Makefile @@ -1,102 +1,134 @@ -# Copyright (c) 2020 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr) -# -# This code is released under an unmodified zlib license. -# For conditions of distribution and use, please see: -# https://opensource.org/licenses/Zlib +# ------------------------ Config ----------------------- -# Define custom functions -rwildcard = $(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)) -platformpth = $(subst /,$(PATHSEP),$1) +# PLATFORM can be 'web' or 'desktop' +PLATFORM ?= desktop -# Set global macros -buildDir := bin -executable := app -target := $(buildDir)/$(executable) -sources := $(call rwildcard,src/,*.cpp) -objects := $(patsubst src/%, $(buildDir)/%, $(patsubst %.cpp, %.o, $(sources))) -depends := $(patsubst %.o, %.d, $(objects)) -compileFlags := -std=c++17 -I include -linkFlags = -L lib/$(platform) -l raylib +SHELL := /bin/zsh +TOP_BUILD_DIR := build +EXECUTABLE := app +WEB_SHELL := src/shell.html +SUBMODULES_PATH := depends + +COMPILER_FLAGS := -std=c++17 +LINKER_FLAGS := -lraylib + +SOURCES := $(wildcard src/*.cpp) + +# ----------------- Prepare variables for targets ------------------ + +EXT := +EMSDK_PATH := $(SUBMODULES_PATH)/emsdk +RAYLIB_PLATFORM := PLATFORM_DESKTOP -# Check for Windows ifeq ($(OS), Windows_NT) - # Set Windows macros - platform := Windows CXX ?= g++ - linkFlags += -Wl,--allow-multiple-definition -pthread -lopengl32 -lgdi32 -lwinmm -mwindows -static -static-libgcc -static-libstdc++ - libGenDir := src THEN := && - PATHSEP := \$(BLANK) MKDIR := -mkdir -p RM := -del /q - COPY = -robocopy "$(call platformpth,$1)" "$(call platformpth,$2)" $3 -else - # Check for MacOS/Linux - UNAMEOS := $(shell uname) - ifeq ($(UNAMEOS), Linux) - # Set Linux macros - platform := Linux - CXX ?= g++ - linkFlags += -l GL -l m -l pthread -l dl -l rt -l X11 - endif - ifeq ($(UNAMEOS), Darwin) - # Set macOS macros - platform := macOS - CXX ?= clang++ - linkFlags += -framework CoreVideo -framework IOKit -framework Cocoa -framework GLUT -framework OpenGL - libGenDir := src - endif + COPY = -robocopy "$1" "$2" $3 + EXT = .exe + MOVE := move - # Set UNIX macros + OS_NAME := windows + LINKER_FLAGS += -Wl,--allow-multiple-definition -pthread -lopengl32 + LINKER_FLAGS += -lgdi32 -lwinmm -mwindows -static -static-libgcc -static-libstdc++ +else + CXX ?= g++ THEN := ; - PATHSEP := / MKDIR := mkdir -p RM := rm -rf - COPY = cp $1$(PATHSEP)$3 $2 + COPY = cp $1/$3 $2 + MOVE := mv + + OS_NAME := linux + LINKER_FLAGS += -lGL -lm -lpthread -ldl -lrt -lX11 endif -# Lists phony targets for Makefile -.PHONY: all setup submodules execute clean +BUILD_NAME := $(OS_NAME)-$(PLATFORM) +BUILD_DIR := $(TOP_BUILD_DIR)/$(BUILD_NAME) +RAYLIB_RELEASE_PATH := $(TOP_BUILD_DIR)/raylib-$(BUILD_NAME) -# Default target, compiles, executes and cleans -all: $(target) execute clean +OBJECTS := $(patsubst src/%, $(BUILD_DIR)/%, $(patsubst %.cpp, %.o, $(SOURCES))) +OBJECT_DEPENDS := $(patsubst %.o, %.d, $(OBJECTS)) + +LIB_DEPENDENCIES := +ifeq ($(PLATFORM), web) + export EMSDK_QUIET=1 + RAYLIB_PLATFORM := PLATFORM_WEB + CXX := source $(SUBMODULES_PATH)/emsdk/emsdk_env.sh $(THEN) emcc + EXT = .html + + EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten + COMPILER_FLAGS += -I$(EMSCRIPTEN_PATH)/cache/sysroot/include + LINKER_FLAGS += -s USE_GLFW=3 + LINKER_FLAGS += -s FORCE_FILESYSTEM=1 + LINKER_FLAGS += $(RAYLIB_RELEASE_PATH)/libraylib.a + LINKER_FLAGS += --shell-file $(WEB_SHELL) + LIB_DEPENDENCIES += emsdk +endif + +COMPILER_FLAGS += -I$(SUBMODULES_PATH)/raylib-cpp/include +COMPILER_FLAGS += -I$(SUBMODULES_PATH)/raylib/src + +LINKER_FLAGS += -L$(RAYLIB_RELEASE_PATH) +MAIN_TARGET := $(BUILD_DIR)/$(EXECUTABLE)$(EXT) + +# ------------------------ Targets ----------------------- + +# Add all rules from dependency files +-include $(OBJECT_DEPENDS) + +.DEFAULT_GOAL := all + +# Lists phony targets for Makefile +.PHONY: all setup submodules run clean emsdk + +# Default target, compiles, runss and cleans +all: clean $(MAIN_TARGET) run # Sets up the project for compiling, generates includes and libs -setup: include lib +setup: lib # Pull and update the the build submodules submodules: git submodule update --init --recursive -# Copy the relevant header files into includes -include: submodules - $(MKDIR) $(call platformpth, ./include) - $(call COPY,depends/raylib/src,./include,raylib.h) - $(call COPY,depends/raylib/src,./include,raymath.h) - $(call COPY,depends/raylib-cpp/include,./include,*.hpp) - # Build the raylib static library file and copy it into lib -lib: submodules - cd depends/raylib/src $(THEN) "$(MAKE)" PLATFORM=PLATFORM_DESKTOP - $(MKDIR) $(call platformpth, lib/$(platform)) - $(call COPY,depends/raylib/src/$(libGenDir),lib/$(platform),libraylib.a) +lib: submodules $(LIB_DEPENDENCIES) + $(MKDIR) $(RAYLIB_RELEASE_PATH) + cd $(SUBMODULES_PATH)/raylib/src $(THEN) \ + "$(MAKE)" \ + PLATFORM=$(RAYLIB_PLATFORM) \ + EMSDK_PATH=$(EMSDK_PATH) \ + RAYLIB_RELEASE_PATH=../../../$(RAYLIB_RELEASE_PATH) -B + +# Install and activate emscripten +emsdk: submodules + cd $(SUBMODULES_PATH)/emsdk $(THEN) ./emsdk install latest + cd $(SUBMODULES_PATH)/emsdk $(THEN) ./emsdk activate latest + # source $(SUBMODULES_PATH)/emsdk/emsdk_env.sh # Link the program and create the executable -$(target): $(objects) - $(CXX) $(objects) -o $(target) $(linkFlags) - -# Add all rules from dependency files --include $(depends) +$(MAIN_TARGET): $(OBJECTS) + $(CXX) $(OBJECTS) -o $(MAIN_TARGET) $(LINKER_FLAGS) -D$(RAYLIB_PLATFORM) +ifeq ($(PLATFORM), web) + $(MOVE) $(MAIN_TARGET) $(BUILD_DIR)/index.html +endif # Compile objects to the build directory -$(buildDir)/%.o: src/%.cpp Makefile - $(MKDIR) $(call platformpth, $(@D)) - $(CXX) -MMD -MP -c $(compileFlags) $< -o $@ $(CXXFLAGS) +$(BUILD_DIR)/%.o: src/%.cpp Makefile + $(MKDIR) $(BUILD_DIR) + # \ + $(CXX) -MMD -MP -c $(COMPILER_FLAGS) $< -o $@ $(CXXFLAGS) -D$(RAYLIB_PLATFORM) # Run the executable -execute: - $(target) $(ARGS) +run: +ifeq ($(PLATFORM), web) + python -m http.server 8080 -d $(BUILD_DIR) +else + $(MAIN_TARGET) $(ARGS) +endif # Clean up all relevant files clean: - $(RM) $(call platformpth, $(buildDir)/*) + $(RM) $(BUILD_DIR) diff --git a/README.md b/README.md index 67d75f3..c10d1e6 100644 --- a/README.md +++ b/README.md @@ -28,12 +28,24 @@ $ make setup $ make ``` +For web: +```console +$ make setup PLATFORM=web +$ make PLATFORM=web +``` + #### Windows ```console > mingw32-make setup > mingw32-make ``` +For web: +```console +> mingw32-make setup PLATFORM=web +> mingw32-make PLATFORM=web +``` + The first command will clone in the lastest C++ bindings and targeted version of raylib, copy across any relevant header files into `/includes`, and build a static library file from them, placing it in `/lib`. The second command then compiles, runs and cleans up your project using the source code in `/src/main.cpp`. *If a window pops up, congratulations, you've successfully built the project and you can now start programming your game!* @@ -51,13 +63,13 @@ By using the following Make commands instead of the default target, we can skip #### macOS & Linux ```console -$ make bin/app; make execute +$ make build/app; make run ``` #### Windows ```console -> mingw32-make bin/app && mingw32-make execute +> mingw32-make build/app && mingw32-make run ``` Using this method can save you a huge amount of time compiling *(in reality, just a few seconds)* each time you make a small change to your code! If you want to know more about how it works, you should have a read through [the docs entry explaining the Makefile](docs/MakefileExplanation.md). @@ -114,18 +126,7 @@ $ make CXX=g++ > mingw32-make CXX=g++ ``` -## Contributing - -### How do I contribute? -It's pretty simple actually: - -1. Fork it from [here](https://github.com/CapsCollective/raylib-cpp-starter/fork) -2. Create your feature branch (`git checkout -b cool-new-feature`) -3. Commit your changes (`git commit -m "Added some feature"`) -4. Push to the branch (`git push origin cool-new-feature`) -5. Create a new pull request for it! - -### Contributors +## Contributors - [J-Mo63](https://github.com/J-Mo63) Jonathan Moallem - co-creator, maintainer - [Raelr](https://github.com/Raelr) Aryeh Zinn - co-creator, maintainer - [mTvare6](https://github.com/mTvare6) mTvare6 - contributor diff --git a/compile_flags.txt b/compile_flags.txt new file mode 100644 index 0000000..f634c0e --- /dev/null +++ b/compile_flags.txt @@ -0,0 +1,2 @@ +-Idepends/raylib-cpp/include/ +-Idepends/raylib/src/ diff --git a/depends/emsdk b/depends/emsdk new file mode 160000 index 0000000..b6df670 --- /dev/null +++ b/depends/emsdk @@ -0,0 +1 @@ +Subproject commit b6df670bdb7cc696804495306e99a604f6641b38 diff --git a/src/main.cpp b/src/main.cpp index d5dd4d7..b225f5c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,29 +1,36 @@ #include +#ifdef PLATFORM_WEB + #include +#endif + +void UpdateDrawFrame() { + // Update + + // Draw + BeginDrawing(); + ClearBackground(RAYWHITE); + DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); + EndDrawing(); +} + int main() { - // Initialization - int screenWidth = 800; - int screenHeight = 450; + int screen_width = 800; + int screen_height = 450; - raylib::Color textColor(LIGHTGRAY); - raylib::Window w(screenWidth, screenHeight, "Raylib C++ Starter Kit Example"); - + raylib::Window window(screen_width, screen_height, "Raylib C++ Starter Kit"); + +#ifdef PLATFORM_WEB + emscripten_set_main_loop(UpdateDrawFrame, 0, 1); +#else SetTargetFPS(60); - - // Main game loop - while (!w.ShouldClose()) // Detect window close button or ESC key - { - // Update - - // TODO: Update your variables here - - // Draw - BeginDrawing(); - ClearBackground(RAYWHITE); - textColor.DrawText("Congrats! You created your first window!", 190, 200, 20); - EndDrawing(); + while (!window.ShouldClose()) { + UpdateDrawFrame(); } +#endif + + window.Close(); return 0; -} \ No newline at end of file +} diff --git a/src/shell.html b/src/shell.html new file mode 100644 index 0000000..2809ed7 --- /dev/null +++ b/src/shell.html @@ -0,0 +1,96 @@ + + + + + + + raylib web game + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+ + {{{ SCRIPT }}} + + +