Compare commits

...

2 Commits

Author SHA1 Message Date
ef426d2df0 refactor Makefile 2023-07-19 20:56:37 +03:00
6a7266b524 add crude compilation to web platform 2023-07-19 20:56:31 +03:00
7 changed files with 220 additions and 97 deletions

4
.gitignore vendored
View File

@ -1,5 +1,3 @@
include
lib
bin
build
.cache
compile_commands.json

3
.gitmodules vendored
View File

@ -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

166
Makefile
View File

@ -1,103 +1,127 @@
# 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
TOP_BUILD_DIR := build
EXECUTABLE := boids-playground
WEB_SHELL := src/shell.html
SUBMODULES_PATH := depends
COMPILER_FLAGS := -std=c++17
LINKER_FLAGS := -lraylib
# SOURCES := $(wildcard src/*.cpp)
SOURCES := src/main.cpp
# ----------------- Prepare variables for targets ------------------
EXT :=
EMSDK_PATH := $(SUBMODULES_PATH)/emsdk
RAYLIB_PLATFORM := PLATFORM_DESKTOP
COMPILER_FLAGS += -I$(SUBMODULES_PATH)/raylib/src
COMPILER_FLAGS += -I$(SUBMODULES_PATH)/raylib-cpp/include
# 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
# 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
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)
RAYLIB_PLATFORM := PLATFORM_WEB
CXX := 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
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/src,./include,rlgl.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
EMSDK_QUIET=1 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)
# 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)
serve $(BUILD_DIR) $(ARGS)
else
$(MAIN_TARGET) $(ARGS)
endif
# Clean up all relevant files
clean:
$(RM) $(call platformpth, $(buildDir)/*)
$(RM) $(BUILD_DIR)

2
compile_flags.txt Normal file
View File

@ -0,0 +1,2 @@
-Idepends/raylib-cpp/include/
-Idepends/raylib/src/

1
depends/emsdk Submodule

@ -0,0 +1 @@
Subproject commit b6df670bdb7cc696804495306e99a604f6641b38

View File

@ -4,9 +4,16 @@
#include <cmath>
#include <optional>
#ifdef PLATFORM_WEB
#include <emscripten/emscripten.h>
#endif
#include "boid-playground.hpp"
#include "raycast.cpp"
static World g_world;
static Visuals g_visuals;
static float vector2_atan2(Vector2 a) {
return std::atan2(a.y, a.x);
}
@ -316,6 +323,21 @@ static void world_draw(World *world, Visuals *visuals) {
}
}
void UpdateDrawFrame() {
// TODO: Show this on screen
// LogTrace("%d", count_out_of_bounds_boids(&world));
world_update(&g_world);
// Draw
BeginDrawing();
ClearBackground(RAYWHITE);
world_draw(&g_world, &g_visuals);
EndDrawing();
}
int main() {
SetTraceLogLevel(LOG_TRACE);
@ -324,18 +346,15 @@ int main() {
raylib::Color text_color(LIGHTGRAY);
raylib::Window window(screen_width, screen_height, "Boid Playground");
window.SetState(FLAG_VSYNC_HINT);
SetTargetFPS(60);
g_world.size = { (float)screen_width, (float)screen_height };
World world;
world.size = { (float)screen_width, (float)screen_height };
Visuals visuals;
float border = visuals.boid_edge_size;
float border = g_visuals.boid_edge_size;
for (int i = 0; i < 100; i++) {
Boid boid;
boid_rand_init(&world, &boid, border);
world.boids.push_back(boid);
boid_rand_init(&g_world, &boid, border);
g_world.boids.push_back(boid);
}
// world.boids.push_back({
@ -349,21 +368,14 @@ int main() {
// .speed = world.boid_min_speed
// });
// Main game loop
while (!window.ShouldClose()) {
// TODO: Show this on screen
// LogTrace("%d", count_out_of_bounds_boids(&world));
world_update(&world);
// Draw
BeginDrawing();
ClearBackground(RAYWHITE);
world_draw(&world, &visuals);
EndDrawing();
}
#ifdef PLATFORM_WEB
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60);
while (!window.ShouldClose()) {
UpdateDrawFrame();
}
#endif
return 0;
}

83
src/shell.html Normal file
View File

@ -0,0 +1,83 @@
<!doctype html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>raylib web game</title>
<meta name="title" content="raylib web game">
<meta name="description" content="New raylib web videogame, developed using raylib videogames library">
<meta name="keywords" content="raylib, games, html5, programming, C, C++, library, learn, videogames">
<meta name="viewport" content="width=device-width">
<!-- Open Graph metatags for sharing -->
<meta property="og:title" content="raylib web game">
<meta property="og:image:type" content="image/png">
<meta property="og:image" content="https://www.raylib.com/common/img/raylib_logo.png">
<meta property="og:site_name" content="raylib.com">
<meta property="og:url" content="https://www.raylib.com/games.html">
<meta property="og:description" content="New raylib web videogame, developed using raylib videogames library">
<!-- Twitter metatags for sharing -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@raysan5">
<meta name="twitter:title" content="raylib web game">
<meta name="twitter:image" content="https://www.raylib.com/common/raylib_logo.png">
<meta name="twitter:url" content="https://www.raylib.com/games.html">
<meta name="twitter:description" content="New raylib web game, developed using raylib videogames library">
<!-- Favicon -->
<link rel="shortcut icon" href="https://www.raylib.com/favicon.ico">
<style>
body { margin: 0px; }
canvas.emscripten { border: 0px none; background-color: black; }
</style>
<script type='text/javascript' src="https://cdn.jsdelivr.net/gh/eligrey/FileSaver.js/dist/FileSaver.min.js">
</script>
<script type='text/javascript'>
function saveFileFromMEMFSToDisk(memoryFSname, localFSname) // This can be called by C/C++ code
{
var isSafari = false; // Not supported, navigator.userAgent access is being restricted
//var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
var data = FS.readFile(memoryFSname);
var blob;
if (isSafari) blob = new Blob([data.buffer], { type: "application/octet-stream" });
else blob = new Blob([data.buffer], { type: "application/octet-binary" });
// NOTE: SaveAsDialog is a browser setting. For example, in Google Chrome,
// in Settings/Advanced/Downloads section you have a setting:
// 'Ask where to save each file before downloading' - which you can set true/false.
// If you enable this setting it would always ask you and bring the SaveAsDialog
saveAs(blob, localFSname);
}
</script>
</head>
<body>
<canvas class=emscripten id=canvas oncontextmenu=event.preventDefault() tabindex=-1></canvas>
<p id="output" />
<script>
var Module = {
print: (function() {
var element = document.getElementById('output');
if (element) element.value = ''; // clear browser cache
return function(text) {
if (arguments.length > 1) text = Array.prototype.slice.call(arguments).join(' ');
console.log(text);
if (element) {
element.value += text + "\n";
element.scrollTop = element.scrollHeight; // focus on bottom
}
};
})(),
canvas: (function() {
var canvas = document.getElementById('canvas');
return canvas;
})()
};
</script>
{{{ SCRIPT }}}
</body>
</html>