From 2c1d55fc308495863db91cd75b705a822d0eb26e Mon Sep 17 00:00:00 2001 From: Attila Uygun Date: Sat, 29 Jul 2023 22:50:29 +0200 Subject: [PATCH] Replace the build system with gn No support for APKs, Java code etc. Keep using gradle for Android for now. --- .gn | 2 + .vscode/c_cpp_properties.json | 36 ++++ .vscode/launch.json | 5 +- .vscode/tasks.json | 39 ++++ BUILD.gn | 6 + README.md | 45 ++-- assets/BUILD.gn | 45 ++++ assets/engine/BUILD.gn | 11 + build/BUILD.gn | 298 ++++++++++++++++++++++++++ build/BUILDCONFIG.gn | 71 ++++++ build/linux/Makefile | 283 ------------------------ build/toolchain/gcc/BUILD.gn | 118 ++++++++++ build/toolchain/msvc/BUILD.gn | 90 ++++++++ build/toolchain/msvc/copy.py | 21 ++ src/base/BUILD.gn | 24 +++ src/base/misc.h | 43 ++-- src/demo/BUILD.gn | 25 +++ src/engine/BUILD.gn | 88 ++++++++ src/engine/platform/platform_linux.cc | 25 ++- src/hello_world/BUILD.gn | 10 + src/hello_world/hello_world.cc | 35 +++ src/third_party/BUILD.gn | 91 ++++++++ 22 files changed, 1088 insertions(+), 323 deletions(-) create mode 100644 .gn create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/tasks.json create mode 100644 BUILD.gn create mode 100644 assets/BUILD.gn create mode 100644 assets/engine/BUILD.gn create mode 100644 build/BUILD.gn create mode 100644 build/BUILDCONFIG.gn delete mode 100644 build/linux/Makefile create mode 100644 build/toolchain/gcc/BUILD.gn create mode 100644 build/toolchain/msvc/BUILD.gn create mode 100644 build/toolchain/msvc/copy.py create mode 100644 src/base/BUILD.gn create mode 100644 src/demo/BUILD.gn create mode 100644 src/engine/BUILD.gn create mode 100644 src/hello_world/BUILD.gn create mode 100644 src/hello_world/hello_world.cc create mode 100644 src/third_party/BUILD.gn diff --git a/.gn b/.gn new file mode 100644 index 0000000..e5b6d4a --- /dev/null +++ b/.gn @@ -0,0 +1,2 @@ +# The location of the build configuration file. +buildconfig = "//build/BUILDCONFIG.gn" diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..ff66e7d --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,36 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "OS_LINUX" + ] + }, + { + "name": "Mac", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "OS_MAC" + ], + "macFrameworkPath": [ + "/System/Library/Frameworks", + "/Library/Frameworks" + ] + }, + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [ + "OS_WIN" + ] + } + ], + "version": 4 +} diff --git a/.vscode/launch.json b/.vscode/launch.json index f8a5095..1b9f2e6 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -8,10 +8,10 @@ "name": "(gdb) Launch", "type": "cppdbg", "request": "launch", - "program": "${workspaceFolder}/build/linux/demo_x86_64_debug", + "program": "${workspaceFolder}/out/debug/demo", "args": [], "stopAtEntry": false, - "cwd": "${workspaceFolder}/build/linux", + "cwd": "${workspaceFolder}/out/debug", "environment": [], "console": "externalTerminal", "MIMode": "gdb", @@ -22,6 +22,7 @@ "ignoreFailures": true } ] + "preLaunchTask": "Build project", } ] } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..032507f --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,39 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build project", + "type": "shell", + "linux": { + "command": "~/code/work/chromium/src/third_party/ninja/ninja", + "problemMatcher": [ + "$gcc" + ] + }, + "osx": { + "command": "ninja", + "problemMatcher": [ + "$gcc" + ] + }, + "windows": { + "command": "ninja.exe", + "problemMatcher": [ + "$msCompile" + ] + }, + "args": [ + "-C", + "${workspaceFolder}/out/debug" + ], + "options": { + "cwd": "${workspaceFolder}" + }, + "group": { + "kind": "build", + "isDefault": true + }, + "detail": "Build the project with ninja." + } + ] +} diff --git a/BUILD.gn b/BUILD.gn new file mode 100644 index 0000000..edaf7e1 --- /dev/null +++ b/BUILD.gn @@ -0,0 +1,6 @@ +group("kaliber") { + deps = [ + "//src/demo", + "//src/hello_world", + ] +} diff --git a/README.md b/README.md index 7dfef4c..54a39eb 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,38 @@ +## Kaliber + A simple, cross-platform 2D game engine with OpenGL and Vulkan renderers. Supports Linux and Android platforms. This is a personal hobby project. I've published a little game on [Google Play](https://play.google.com/store/apps/details?id=com.woom.game) based on this engine. Full game code and assets are included in this repository. -#### Building the demo -Linux: + +## Pre-requisities for all platforms except Android: + +Install: +* GN: https://gn.googlesource.com/gn/ + +## Building from the command-line: + +### All platforms except Android: +Setup: ```text -cd build/linux -make +gn gen out/release +gn gen --args='is_debug=true' out/debug ``` -Android: +Building and running: +```text +ninja -C out/debug +./out/debug/hello_world +./out/debug/demo +``` +### Android: ```text cd build/android -./gradlew :app:assembleRelease +./gradlew :app:installDebug ``` -#### Third-party libraries: + +## Third-party libraries: + [glew](https://github.com/nigels-com/glew), [jsoncpp](https://github.com/open-source-parsers/jsoncpp), [minimp3](https://github.com/lieff/minimp3), @@ -28,17 +46,10 @@ cd build/android [vulkan-sdk](https://vulkan.lunarg.com), [volk](https://github.com/zeux/volk) -#### Hello World example: -Simply shows a rotating "Hello Wolrd!". -```cpp -#include "base/interpolation.h" -#include "engine/animator.h" -#include "engine/asset/image.h" -#include "engine/engine.h" -#include "engine/game.h" -#include "engine/game_factory.h" -#include "engine/image_quad.h" +## Hello World example: +Shows a smoothly rotating "Hello Wolrd!". +```cpp class HelloWorld final : public eng::Game { public: ~HelloWorld() final = default; diff --git a/assets/BUILD.gn b/assets/BUILD.gn new file mode 100644 index 0000000..aee3ea6 --- /dev/null +++ b/assets/BUILD.gn @@ -0,0 +1,45 @@ +copy("assets") { + sources = [ + "bead.png", + "boss_explosion.mp3", + "boss_intro.mp3", + "Boss_ok_lvl2.png", + "Boss_ok_lvl3.png", + "Boss_ok.png", + "BUILD.gn", + "chromatic_aberration.glsl_fragment", + "chromatic_aberration.glsl_vertex", + "enemy_anims_01_frames_ok.png", + "enemy_anims_02_frames_ok.png", + "enemy_anims_blast_ok.png", + "enemy_anims_flare_ok.png", + "enemy_ray_ok.png", + "enemy_target_single_ok.png", + "explosion.mp3", + "Game_2_Boss.mp3", + "Game_2_Main.mp3", + "hit.mp3", + "laser.mp3", + "menu_click.mp3", + "menu_icons.png", + "no_nuke.mp3", + "nuke_frames.png", + "nuke_pack_OK.png", + "nuke.mp3", + "PixelCaps!.ttf", + "powerup-pick.mp3", + "powerup-spawn.mp3", + "renderer_logo.png", + "shield.mp3", + "sky_without_nebula.glsl_fragment", + "sky_without_nebula.glsl_vertex", + "sky.glsl_fragment", + "sky.glsl_vertex", + "stealth.mp3", + "woom_enemy_shield.png", + "woom_logo_start_frames_01.png", + "woom_logo_start_frames_02-03.png", + ] + + outputs = ["$root_out_dir/assets/{{source_file_part}}"] +} diff --git a/assets/engine/BUILD.gn b/assets/engine/BUILD.gn new file mode 100644 index 0000000..9d96d85 --- /dev/null +++ b/assets/engine/BUILD.gn @@ -0,0 +1,11 @@ +copy("engine") { + sources = [ + "pass_through.glsl_fragment", + "pass_through.glsl_vertex", + "RobotoMono-Regular.ttf", + "solid.glsl_fragment", + "solid.glsl_vertex", + ] + + outputs = ["$root_out_dir/assets/engine/{{source_file_part}}"] +} diff --git a/build/BUILD.gn b/build/BUILD.gn new file mode 100644 index 0000000..eb9367d --- /dev/null +++ b/build/BUILD.gn @@ -0,0 +1,298 @@ +config("default") { + if (is_android) { + defines = [ "OS_ANDROID" ] + } else if (is_ios) { + defines = [ "OS_IOS" ] + } else if (is_linux) { + defines = [ "OS_LINUX" ] + } else if (is_mac) { + defines = [ "OS_MAC" ] + } else if (is_win) { + defines = [ "OS_WIN" ] + } + if (is_ios || is_mac) { + defines += [ "OS_APPLE" ] + } + + cflags_cc = [] + if (is_win) { + cflags_cc += [ "/std:c++20" ] + } else { + cflags_cc += [ "-std=c++20" ] + } + + cflags = [] + if (is_win) { + cflags += [ + "/permissive-", # Don't enable nonconforming code to compile. + "/EHsc", # Use C++ exception handling. + "/Gd", # __cdecl calling convention. + "/utf-8", # Set Source and Executable character set. + ] + defines += [ + # Windows headers from MS and third party expects these to be set. + "_WINDOWS", + "_UNICODE", + "UNICODE", + + # Don't want MS specific extensions for C stdlib functions. + "_CRT_SECURE_NO_WARNINGS", + + # Clean up the Windows headers. + "WIN32_LEAN_AND_MEAN", + "NOMINMAX", + ] + } else { + # cflags += [ + # "-fstrict-aliasing", # Optimizations allowed for type aliasing. + # "-fvisibility=hidden", # Only let symbols be visible inside it's own + # # library. + # ] + # cflags_cc += [ + # "-fvisibility-inlines-hidden", # Inline methods may not generate symbols. + # # "-stdlib=libc++", + # ] + + if (is_linux) { + # cflags += [ + # "-fPIC", # Emit position-independent code suitable for dynamic linking. + # ] + libs = [ + "pthread", # Use the POSIX thread library. + ] + } else if (is_mac) { + asmflags = [ + "-target", + "arm64-apple-macos11", + ] + cflags += [ + # "-fPIC", # Emit position-independent code suitable for dynamic linking. + "-target", + "arm64-apple-macos11", + ] + ldflags = [ + "-target", + "arm64-apple-macos11", + ] + } + } + + # Avoid relative paths everywhere. + include_dirs = [ + # "//", + "//src", + ] +} + +config("debug") { + defines = [ "_DEBUG" ] + + if (is_win) { + cflags = [ + "/GS", # Buffer security checks (buffer overruns). + "/sdl", # Enable additional security features and warnings. + "/RTC1", # Enable fast run-time checks. + "/Od", # Disable optimizations. + "/fp:precise", # Floating points are predictable. + "/MDd", # Link with multithread debug DLL run-time libraries. + "/Z7", # Produce obj files that contain full symbolic debugging + # information. + ] + ldflags = [ "/DEBUG:FASTLINK" ] # Reference the debug symbols in the obj + # files instead of a PDB file. + } else { + cflags = [ + "-g", # Debug symbols. + # TODO: This makes it hard to step through code on Linux. + # "-Og", # Optimizations that works well with debugger. + ] + + if (is_unix) { + defines += [ + "_GLIBCXX_DEBUG=1", # Enable asserts in stl headers. + ] + } + } +} + +config("release") { + defines = [ "NDEBUG" ] + + if (is_win) { + cflags = [ + "/GL", # Link-time code generation / Whole program optimization. + "/Gy", # Allows converting inline functions to separate functions. + "/O2", # Optimize for maximum speed. + "/Oi", # Enable intrinsics. + "/fp:fast", # Floating points are fast. + "/MD", # Link with multithread release DLL run-time libraries. + + # "/arch:AVX2", # Minimum CPU architecture. + ] + ldflags = [ + "/LTCG", # Link time code generation. + "/OPT:ICF", # COMDAT (common data) folding, e.g. vtables and big inline + # functions that can't be inlined, but also if identical code + # happens to be generated though common math operations or + # similar. + "/OPT:REF", # Eliminate unreferenced code and data. + ] + } else { + cflags = [ + "-Ofast", # Full optimization and disregard strict standard compliance. + "-fno-math-errno", # Do not check or set errno for invalid input to sqrt + # and other math functions. + ] + + # cflags += [ + # # Generate machine code for the current developer computer. + # # TODO: This needs to be set properly before release. + # "-march=native", + # ] + + if (is_apple) { + ldflags = [ "-dead-strip" ] + } else { + # Place both data and functions in it's their own sections. + # Linker optimization that allows for smaller binaries. + cflags += [ + "-fdata-sections", + "-ffunction-sections", + ] + ldflags = [ "-Wl,--gc-sections" ] + } + } +} + +config("warnings") { + if (is_win) { + cflags = [ + "/WX", # Treat warnings as errors. + "/Wall", # Enable all warnings. + + # Disable the following warnings: + "/wd4061", # enumerator in switch with a default case not explicitly + # handled by a case label. + "/wd4100", # unreferenced format parameter. + "/wd4324", # structure was padded due to alignment specifier + "/wd4371", # layout of class may have changed from a previous version of + # the compiler due to better packing of member + "/wd4514", # unreferenced inline function has been removed. + "/wd4710", # function not inlined + "/wd4711", # function selected for automatic inline expansion + "/wd4820", # padding added after data member. + "/wd5045", # compiler will insert Spectre mitigation for memory load if + # switch specified. + + # TODO: Not sure how I feel about these conversion warnings. + "/wd4244", # conversion, possible loss of data. 'int' to 'float' + "/wd4267", # conversion, possible loss of data. + "/wd4305", # truncation from 'double' to 'float'. + "/wd4365", # conversion, signed/unsigned mismatch. + "/wd5219", # conversion, possible loss of data. 'int' to 'float' + + # Possible compiler bug? Needs investigation. + "/wd4668", # '__STDC_WANT_SECURE_LIB__' is not defined as a preprocessor + # macro, replacing with '0' for '#if/#elif' + + # TODO: + "/wd4263", # member function does not override any base class virtual + # member function + "/wd4264", # no override available for virtual member function, function + # is hidden + "/wd4266", # no override available for virtual member function from base, + # function is hidden + "/wd4355", # 'this' used in base member initializer list + "/wd4457", # declaration hides function parameter + "/wd4464", # relative include path contains '..'. + "/wd4625", # copy constructor was implicitly defined as deleted + "/wd4626", # assignment operator was implicitly defined as deleted + "/wd4706", # assignment withing conditional expression. + "/wd4774", # format string expected in argument X is not a string literal + "/wd4828", # The file contains a character that is illegal in the current + # source character set + "/wd4946", # reinterpret_cast used between related + "/wd5026", # move constructor was implicitly defined as deleted + "/wd5027", # move assignment operator was implicitly defined as deleted + "/wd5039", # pointer or reference to potentially throwing function passed + # to 'extern "C"' function under -EHc. Undefined behavior may + # occur if this function throws an exception. + + # TODO: I don't understand these or how to fix them: + "/wd4458", # declaration hides class member + # [ GameObject::rtti ] + "/wd4582", # constructor is not implicitly called + # [ intersection.h Contact ] + "/wd4623", # default constructor was implicitly defined as deleted + # [ intersection.h Contact ] + "/wd5243", # using incomplete class can cause potential one definition + # rule violation due to ABI limitation + ] + + defines = [ + "_CRT_NONSTDC_NO_DEPRECATE", + "_SILENCE_CXX17_STRSTREAM_DEPRECATION_WARNING", + ] + } else if (is_mac) { + cflags = [ + "-Wno-deprecated-declarations", + "-Wno-inconsistent-missing-override", + "-Wno-pointer-sign", + ] + } else { + cflags = [ + # Enable as much warnings as possible. + "-Werror", # Make all warnings into errors. + "-Wall", # Enable (almost) all warnings. + "-Wextra", # Enable even more warnings. + + # "-Wpedantic", # Issue warnings demanded by strict ISO C/C++ and reject + # forbidden extensions. + "-Wvla", # Warn if variable-length array is used in code. + + # Disable the following warnings: + "-Wno-unused-parameter", + ] + } +} + +config("executable") { + if (is_android) { + ldflags = [ + "-pie", + "-rdynamic", + ] + } else if (is_linux) { + # ldflags = [ + # "-rdynamic", # Tell linker to expose all symbols, not only used ones. + # # Needed for some uses of dlopen and for backtraces within + # # the program. + # "-Wl,-rpath,\$ORIGIN", # Add directory to runtime library search path. + # ] + } else if (is_mac) { + ldflags = [ "-Wl,-rpath,@loader_path/." ] + } else if (is_win) { + ldflags = [ + "/DYNAMICBASE", # Use address space layout randomization. + "/INCREMENTAL:NO", # Incremental linking interferes with both ninja and + # release optimizations. + + # Leave the target architecture to environment settings. + # "/MACHINE:X64", + ] + } +} + +# TODO: This needs some more investigation. +# Is it possible to avoid setting it and rely on defaults? +# Some tools will be console apps while games will be gui apps. +# GLFW seems to be using console in debug mode and gui in release mode. +if (is_win) { + config("win_gui") { + ldflags = [ "/SUBSYSTEM:WINDOWS" ] + } + + config("win_console") { + ldflags = [ "/SUBSYSTEM:CONSOLE" ] + } +} diff --git a/build/BUILDCONFIG.gn b/build/BUILDCONFIG.gn new file mode 100644 index 0000000..438e41d --- /dev/null +++ b/build/BUILDCONFIG.gn @@ -0,0 +1,71 @@ +declare_args() { + is_debug = false +} + +# Platform detection +if (target_os == "") { + target_os = host_os +} +if (current_os == "") { + current_os = target_os +} + +is_android = current_os == "android" +is_ios = current_os == "ios" +is_linux = current_os == "linux" +is_mac = current_os == "mac" +is_win = current_os == "win" + +is_apple = is_mac || is_ios +is_desktop = is_mac || is_linux || is_win +is_mobile = is_android || is_ios +is_unix = is_android || is_linux + +# Optional build components +have_vulkan = false + +if (target_cpu == "") { + if (is_mobile) { + target_cpu = "arm64" + } else { + target_cpu = host_cpu + } +} +if (target_cpu == "x86_64") { + target_cpu = "x64" +} +if (current_cpu == "") { + current_cpu = target_cpu +} + +# Set defaults +_default_config = [ + "//build:default", + "//build:warnings", +] + +if (is_debug) { + _default_config += [ "//build:debug" ] +} else { + _default_config += [ "//build:release" ] +} + +set_defaults("executable") { + configs = [ "//build:executable" ] + _default_config +} +set_defaults("static_library") { + configs = _default_config +} +set_defaults("shared_library") { + configs = _default_config +} +set_defaults("source_set") { + configs = _default_config +} + +if (is_win) { + set_default_toolchain("//build/toolchain/msvc") +} else { + # Clang behaves like GCC in most cases. + set_default_toolchain("//build/toolchain/gcc") +} diff --git a/build/linux/Makefile b/build/linux/Makefile deleted file mode 100644 index 7516917..0000000 --- a/build/linux/Makefile +++ /dev/null @@ -1,283 +0,0 @@ -.DEFAULT_GOAL := all - -# --- Input variables --- - -BUILD ?= release -ifeq ($(findstring $(BUILD),debug release),) - $(error BUILD must be set to debug or release) -endif - -# Build all executables by default. -APPS ?= demo - -# If the VERBOSE flag isn't set, then mute superfluous output. -ifeq ($(VERBOSE),) - HUSH_COMPILE = @echo "Compiling $<"; - HUSH_LINK = @echo "Linking $@"; - HUSH_GENERATE = @echo "Generating $@"; - HUSH_CLEAN = @ -endif - -# --- Internal variables --- - -ARCH := $(shell uname -p) -SRC_ROOT := $(abspath ../../src) -OUTPUT_DIR := $(abspath .) -INTERMEDIATE_DIR := $(OUTPUT_DIR)/obj -BUILD_DIR := $(INTERMEDIATE_DIR)/$(BUILD) - -ARFLAGS = r -LDFLAGS = -lX11 -lGL -pthread -lasound -ldl - -# Always enable debug information. -CFLAGS += -g - -# Enable extra warnings and make all warnings into errors. -CFLAGS += -Wextra -Werror - -# Flags to generate dependency information. -CFLAGS += -MD -MP -MT $@ - -# Predefined flags. -ifeq ($(BUILD), debug) - CFLAGS += -D_DEBUG - CFLAGS += -D_GLIBCXX_DEBUG -endif - -# Enable compiler optimizations for everything except debug. -# Note that a very aggresssive optimization level is used and it may not be -# valid for all standard compliant programs. Reduce this level on individual -# files or modules as needed. -ifneq ($(BUILD), debug) - CFLAGS += -Ofast -endif - -# Flag to turn on extended instruction sets for the compiler. -CFLAGS += -msse2 - -# Let C++ inherit all C flags. -CXXFLAGS = $(CFLAGS) -I$(SRC_ROOT) - -# Enable C++20 -CXXFLAGS += -std=c++20 - -# Vulkan config -CFLAGS += -DVK_USE_PLATFORM_XLIB_KHR -CFLAGS += -DVMA_STATIC_VULKAN_FUNCTIONS=1 -CFLAGS += -I$(SRC_ROOT)/third_party/vulkan/include -CXXFLAGS += -I$(SRC_ROOT)/third_party/glslang - -# --- Internal functions --- - -app_exe = $(OUTPUT_DIR)/$(1)_$(ARCH)_$(BUILD) -objs_from_src = $(patsubst $(SRC_ROOT)/%, $(BUILD_DIR)/%.o, $(basename $(1))) -objs_from_src_in = $(call objs_from_src, $(shell find $(1) -name "*.cc" -o -name "*.cpp" -o -name "*.c")) - -# --- Base --- - -BASE_SRC := \ - $(SRC_ROOT)/base/collusion_test.cc \ - $(SRC_ROOT)/base/log.cc \ - $(SRC_ROOT)/base/task_runner.cc \ - $(SRC_ROOT)/base/thread_pool.cc \ - $(SRC_ROOT)/base/timer.cc - -BASE_LIB := $(BUILD_DIR)/libengine.a -BASE_OBJS := $(call objs_from_src, $(BASE_SRC)) -LIBS += $(BASE_LIB) -OBJS += $(BASE_OBJS) - -$(BASE_LIB): $(BASE_OBJS) - -# --- Engine --- - -ENGINE_SRC := \ - $(SRC_ROOT)/engine/animatable.cc \ - $(SRC_ROOT)/engine/animator.cc \ - $(SRC_ROOT)/engine/asset/font.cc \ - $(SRC_ROOT)/engine/asset/image.cc \ - $(SRC_ROOT)/engine/asset/mesh.cc \ - $(SRC_ROOT)/engine/asset/shader_source.cc \ - $(SRC_ROOT)/engine/asset/sound.cc \ - $(SRC_ROOT)/engine/audio/audio_bus.cc \ - $(SRC_ROOT)/engine/audio/audio_mixer.cc \ - $(SRC_ROOT)/engine/audio/audio_sink_alsa.cc \ - $(SRC_ROOT)/engine/audio/mixer_input.cc \ - $(SRC_ROOT)/engine/audio/sinc_resampler.cc \ - $(SRC_ROOT)/engine/drawable.cc \ - $(SRC_ROOT)/engine/engine.cc \ - $(SRC_ROOT)/engine/image_quad.cc \ - $(SRC_ROOT)/engine/persistent_data.cc \ - $(SRC_ROOT)/engine/platform/asset_file_linux.cc \ - $(SRC_ROOT)/engine/platform/asset_file.cc \ - $(SRC_ROOT)/engine/platform/platform_linux.cc \ - $(SRC_ROOT)/engine/renderer/geometry.cc \ - $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl_linux.cc \ - $(SRC_ROOT)/engine/renderer/opengl/renderer_opengl.cc \ - $(SRC_ROOT)/engine/renderer/renderer_types.cc \ - $(SRC_ROOT)/engine/renderer/shader.cc \ - $(SRC_ROOT)/engine/renderer/texture.cc \ - $(SRC_ROOT)/engine/renderer/vulkan/renderer_vulkan_linux.cc \ - $(SRC_ROOT)/engine/renderer/vulkan/renderer_vulkan.cc \ - $(SRC_ROOT)/engine/renderer/vulkan/vulkan_context_linux.cc \ - $(SRC_ROOT)/engine/renderer/vulkan/vulkan_context.cc \ - $(SRC_ROOT)/engine/solid_quad.cc \ - $(SRC_ROOT)/engine/sound_player.cc - -ENGINE_LIB := $(BUILD_DIR)/libengine.a -ENGINE_OBJS := $(call objs_from_src, $(ENGINE_SRC)) -LIBS += $(ENGINE_LIB) -OBJS += $(ENGINE_OBJS) - -$(ENGINE_LIB): $(ENGINE_OBJS) - -# --- Third-party --- - -# Ignore warnings. -THIRD_PARTY_CFLAGS = $(CFLAGS) -THIRD_PARTY_CFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CFLAGS)) - -THIRD_PARTY_CXXFLAGS = $(CXXFLAGS) -THIRD_PARTY_CXXFLAGS := $(filter-out -Wextra -Werror, $(THIRD_PARTY_CXXFLAGS)) - -THIRD_PARTY_SRC := \ - $(SRC_ROOT)/third_party/glew/glew.c \ - $(SRC_ROOT)/third_party/glslang/glslang/GenericCodeGen/CodeGen.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/GenericCodeGen/Link.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/attribute.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/Constant.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/glslang_tab.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/InfoSink.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/Initialize.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/Intermediate.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/intermOut.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/IntermTraverse.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/iomapper.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/limits.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/linkValidate.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/parseConst.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/ParseContextBase.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/ParseHelper.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/PoolAlloc.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/preprocessor/Pp.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/propagateNoContraction.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/reflection.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/RemoveTree.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/Scan.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/ShaderLang.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/SymbolTable.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/MachineIndependent/Versions.cpp \ - $(SRC_ROOT)/third_party/glslang/glslang/OSDependent/Unix/ossource.cpp \ - $(SRC_ROOT)/third_party/glslang/OGLCompilersDLL/InitializeDll.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/disassemble.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/doc.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/GlslangToSpv.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/InReadableOrder.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/Logger.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/SpvBuilder.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/SpvPostProcess.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/SPVRemapper.cpp \ - $(SRC_ROOT)/third_party/glslang/SPIRV/SpvTools.cpp \ - $(SRC_ROOT)/third_party/jsoncpp/jsoncpp.cpp \ - $(SRC_ROOT)/third_party/spirv-reflect/spirv_reflect.c \ - $(SRC_ROOT)/third_party/stb/stb_image.c \ - $(SRC_ROOT)/third_party/texture_compressor/dxt_encoder_internals.cc \ - $(SRC_ROOT)/third_party/texture_compressor/dxt_encoder.cc \ - $(SRC_ROOT)/third_party/texture_compressor/texture_compressor_etc1.cc \ - $(SRC_ROOT)/third_party/texture_compressor/texture_compressor.cc \ - $(SRC_ROOT)/third_party/vma/vk_mem_alloc.cpp \ - $(SRC_ROOT)/third_party/volk/volk.c - -$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.c - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CC) -c $(THIRD_PARTY_CFLAGS) -o $@ $< - -$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cc - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $< - -$(BUILD_DIR)/third_party/%.o: $(SRC_ROOT)/third_party/%.cpp - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CXX) -c $(THIRD_PARTY_CXXFLAGS) -o $@ $< - -THIRD_PARTY_LIB := $(BUILD_DIR)/libthirdparty.a -THIRD_PARTY_OBJS := $(call objs_from_src, $(THIRD_PARTY_SRC)) -LIBS += $(THIRD_PARTY_LIB) -OBJS += $(THIRD_PARTY_OBJS) - -$(THIRD_PARTY_LIB): $(THIRD_PARTY_OBJS) - -# --- demo application --- - -ifneq ($(filter demo,$(APPS)),) - -DEMO_SRC := \ - $(SRC_ROOT)/demo/credits.cc \ - $(SRC_ROOT)/demo/demo.cc \ - $(SRC_ROOT)/demo/enemy.cc \ - $(SRC_ROOT)/demo/hud.cc \ - $(SRC_ROOT)/demo/menu.cc \ - $(SRC_ROOT)/demo/player.cc \ - $(SRC_ROOT)/demo/sky_quad.cc - -DEMO_EXE := $(call app_exe,demo) -DEMO_OBJS := $(call objs_from_src, $(DEMO_SRC)) -EXES += $(DEMO_EXE) -OBJS += $(DEMO_OBJS) - -$(DEMO_EXE): $(DEMO_OBJS) $(LIBS) - -endif - -# --- Build rules --- - -# Dependencies. -DEPS = $(OBJS:.o=.d) --include $(DEPS) - -.PHONY: all clean cleanall help - -all: $(EXES) - -clean: - @echo "Cleaning..." - $(HUSH_CLEAN) $(RM) -r $(BUILD_DIR) - -cleanall: - @echo "Cleaning all..." - $(HUSH_CLEAN) $(RM) -r $(INTERMEDIATE_DIR) - -help: - @echo "BUILD = Build mode. One of:" - @echo " debug (no optimizations)" - @echo " release (optimizations, the default)" - @echo "APPS = Applications to build. Defaults to all." - @echo "VERBOSE = Full output from commands if set." - -# It's important that libraries are specified last as Ubuntu uses "ld --as-needed" by default. -# Only the static libraries referenced by the object files will be linked into the executable. -# Beware that circular dependencies doesn't work with this flag. -$(EXES): - @mkdir -p $(@D) - $(HUSH_LINK) $(CXX) -o $@ $^ $(LDFLAGS) - -$(BUILD_DIR)/%.a: - @mkdir -p $(@D) - $(HUSH_GENERATE) $(AR) $(ARFLAGS) $@ $^ - -$(BUILD_DIR)/%.o: $(SRC_ROOT)/%.c - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CC) -c $(CFLAGS) -o $@ $< - -$(BUILD_DIR)/%.o: $(SRC_ROOT)/%.cc - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CXX) -c $(CXXFLAGS) -o $@ $< - -$(BUILD_DIR)/%.o: $(SRC_ROOT)/%.cpp - @mkdir -p $(@D) - $(HUSH_COMPILE) $(CXX) -c $(CXXFLAGS) -o $@ $< diff --git a/build/toolchain/gcc/BUILD.gn b/build/toolchain/gcc/BUILD.gn new file mode 100644 index 0000000..503fe29 --- /dev/null +++ b/build/toolchain/gcc/BUILD.gn @@ -0,0 +1,118 @@ +# Note that this uses the 'cc' and 'c++' environment variables or links that +# should map to GCC on linux systems and clang on macs. + +# This also means that you can install clang or another compiler and it should +# automatically use that instead. + +toolchain("gcc") { + lib_switch = "-l" + lib_dir_switch = "-L" + + tool("asm") { + depfile = "{{output}}.d" + command = "cc -MD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}" + depsformat = "gcc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] + description = "assemble {{source}}" + } + + tool("cc") { + depfile = "{{output}}.d" + command = "cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}" + depsformat = "gcc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] + description = "compile {{output}}" + } + + tool("cxx") { + depfile = "{{output}}.d" + command = "c++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}" + depsformat = "gcc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] + description = "compile {{output}}" + } + + tool("objc") { + depfile = "{{output}}.d" + command = "cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_c}} {{cflags_objc}} -c {{source}} -o {{output}}" + depsformat = "gcc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] + description = "compile {{output}}" + } + + tool("objcxx") { + depfile = "{{output}}.d" + command = "c++ -MMD -MF $depfile {{defines}} {{include_dirs}} {{framework_dirs}} {{cflags}} {{cflags_cc}} {{cflags_objcc}} -c {{source}} -o {{output}}" + depsformat = "gcc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o" ] + description = "compile {{output}}" + } + + if (is_apple) { + not_needed([ "ar" ]) # libtool is used instead. + } + + tool("alink") { + if (is_apple) { + command = + "libtool -static -o {{output}} -no_warning_for_no_symbols {{inputs}}" + } else { + command = "rm -f {{output}} && ar rcs {{output}} {{inputs}}" + } + outputs = + [ "{{target_out_dir}}/{{target_output_name}}{{output_extension}}" ] + default_output_extension = ".a" + output_prefix = "lib" + description = "link {{target_output_name}}{{output_extension}}" + } + + tool("solink") { + soname = "{{target_output_name}}{{output_extension}}" + sofile = "{{output_dir}}/$soname" + rspfile = soname + ".rsp" + if (is_apple) { + os_specific_option = "-install_name @executable_path/$sofile" + rspfile_content = "{{inputs}} {{solibs}} {{libs}}" + } else { + os_specific_option = "-Wl,-soname=$soname" + rspfile_content = "-Wl,--whole-archive {{inputs}} {{solibs}} -Wl,--no-whole-archive {{libs}}" + } + command = "c++ -shared {{ldflags}} {{frameworks}} -o $sofile $os_specific_option @$rspfile" + default_output_extension = ".so" + default_output_dir = "{{root_out_dir}}" + outputs = [ sofile ] + link_output = sofile + depend_output = sofile + output_prefix = "lib" + description = "link $soname" + } + + tool("link") { + outfile = "{{target_output_name}}{{output_extension}}" + rspfile = "$outfile.rsp" + rspfile_content = "{{inputs}}" + if (is_apple) { + command = "c++ {{ldflags}} {{solibs}} {{libs}} {{frameworks}} -o $outfile @$rspfile" + } else { + command = "c++ {{ldflags}} -o $outfile -Wl,--start-group @$rspfile {{solibs}} -Wl,--end-group {{libs}}" + } + default_output_dir = "{{root_out_dir}}" + outputs = [ outfile ] + description = "link $outfile" + } + + tool("stamp") { + command = "touch {{output}}" + description = "stamp {{output}}" + } + + tool("copy") { + command = "cp -af {{source}} {{output}}" + description = "copy {{source}} {{output}}" + } +} diff --git a/build/toolchain/msvc/BUILD.gn b/build/toolchain/msvc/BUILD.gn new file mode 100644 index 0000000..8c4a07f --- /dev/null +++ b/build/toolchain/msvc/BUILD.gn @@ -0,0 +1,90 @@ +toolchain("msvc") { + lib_switch = "" + lib_dir_switch = "/LIBPATH:" + + tool("asm") { + command = "ml.exe {{asmflags}} /nologo /c /Fo {{output}} {{source}}" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj" ] + description = "assemble {{source}}" + } + + tool("cc") { + pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" + command = "cl.exe /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" + depsformat = "msvc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj" ] + description = "compile {{source}}" + } + + tool("cxx") { + pdbname = "{{target_out_dir}}/{{label_name}}_c.pdb" + command = "cl.exe /nologo /showIncludes /FC {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} /c {{source}} /Fo{{output}} /Fd\"$pdbname\"" + depsformat = "msvc" + outputs = + [ "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.obj" ] + description = "compile {{source}}" + } + + tool("alink") { + rspfile = "{{output}}.rsp" + command = "lib.exe /nologo {{arflags}} /OUT:{{output}} @$rspfile" + outputs = [ "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" ] + default_output_extension = ".lib" + default_output_dir = "{{target_out_dir}}" + rspfile_content = "{{inputs_newline}}" + description = "link {{output}}" + } + + tool("solink") { + dllname = "{{output_dir}}/{{target_output_name}}{{output_extension}}" + libname = "${dllname}.lib" + pdbname = "${dllname}.pdb" + rspfile = "${dllname}.rsp" + command = "link.exe /nologo /IMPLIB:$libname /DLL /OUT:$dllname /PDB:$pdbname @$rspfile" + outputs = [ + dllname, + libname, + pdbname, + ] + default_output_extension = ".dll" + default_output_dir = "{{root_out_dir}}" + link_output = libname + depend_output = libname + runtime_outputs = [ + dllname, + pdbname, + ] + rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" + description = "link {{output}}" + } + + tool("link") { + exename = "{{root_out_dir}}/{{target_output_name}}{{output_extension}}" + pdbname = "$exename.pdb" + rspfile = "$exename.rsp" + command = "link.exe /nologo /OUT:$exename /PDB:$pdbname @$rspfile" + default_output_extension = ".exe" + default_output_dir = "{{root_out_dir}}" + outputs = [ exename ] + rspfile_content = "{{inputs_newline}} {{libs}} {{solibs}} {{ldflags}}" + description = "link {{output}}" + } + + tool("stamp") { + command = "cmd.exe /c echo > {{output}}" + description = "stamp {{output}}" + } + + tool("copy") { + # Note: The build in copy command can't handle forward slashes as path separators. + # Use a python script as a work around. + # command = "cmd.exe /c copy /Y {{source}} {{output}}" + + copy_cmd = rebase_path("copy.py") + command = "python \"$copy_cmd\" {{source}} {{output}}" + + description = "copy {{source}} {{output}}" + } +} diff --git a/build/toolchain/msvc/copy.py b/build/toolchain/msvc/copy.py new file mode 100644 index 0000000..fbf79f1 --- /dev/null +++ b/build/toolchain/msvc/copy.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python + +import os +import shutil +import sys + +src, dst = sys.argv[1:] + +if os.path.exists(dst): + if os.path.isdir(dst): + shutil.rmtree(dst) + else: + os.remove(dst) + +if os.path.isdir(src): + shutil.copytree(src, dst) +else: + shutil.copy2(src, dst) + + # https://github.com/ninja-build/ninja/issues/1554 + os.utime(dst, None) diff --git a/src/base/BUILD.gn b/src/base/BUILD.gn new file mode 100644 index 0000000..cbe19d7 --- /dev/null +++ b/src/base/BUILD.gn @@ -0,0 +1,24 @@ +source_set("base") { + sources = [ + "closure.h", + "collusion_test.cc", + "collusion_test.h", + "file.h", + "hash.h", + "interpolation.h", + "log.cc", + "log.h", + "mem.h", + "misc.h", + "random.h", + "task_runner.cc", + "task_runner.h", + "thread_pool.cc", + "thread_pool.h", + "timer.cc", + "timer.h", + "vecmath.h", + ] + + deps = [] +} diff --git a/src/base/misc.h b/src/base/misc.h index e12d6ed..b8a4573 100644 --- a/src/base/misc.h +++ b/src/base/misc.h @@ -1,31 +1,42 @@ #ifndef BASE_MISC_H #define BASE_MISC_H +#include + #define CRASH *((int*)nullptr) = 0; namespace base { -// ToDo: x86 has the bsr instruction. -inline int GetHighestBitPos(int value) { - return (0xFFFF0000 & value ? value &= 0xFFFF0000, 1 : 0) * 0x10 + - (0xFF00FF00 & value ? value &= 0xFF00FF00, 1 : 0) * 0x08 + - (0xF0F0F0F0 & value ? value &= 0xF0F0F0F0, 1 : 0) * 0x04 + - (0xCCCCCCCC & value ? value &= 0xCCCCCCCC, 1 : 0) * 0x02 + - (0xAAAAAAAA & value ? 1 : 0) * 0x01; +inline uint32_t GetHighestBitPos(uint32_t value) { + uint32_t result = 0; + if (0xFFFF0000 & value) { + value &= 0xFFFF0000; + result += 0x10; + } + if (0xFF00FF00 & value) { + value &= 0xFF00FF00; + result += 0x8; + } + if (0xF0F0F0F0 & value) { + value &= 0xF0F0F0F0; + result += 0x04; + } + if (0xCCCCCCCC & value) { + value &= 0xCCCCCCCC; + result += 0x02; + } + if (0xAAAAAAAA & value) { + result += 0x01; + } + return result; } -// Get the highest set bit in an integer number -inline int GetHighestBit(int value) { - return 0x1 << GetHighestBitPos(value); -} - -// Check if the given integer is a power of two, ie if only one bit is set. inline bool IsPow2(int value) { - return GetHighestBit(value) == value; + return ((value & (value - 1)) == 0); } -inline int RoundUpToPow2(int val) { - int i = GetHighestBit(val); +inline uint32_t RoundUpToPow2(uint32_t val) { + uint32_t i = 1 << GetHighestBitPos(val); return val == i ? val : i << 1; } diff --git a/src/demo/BUILD.gn b/src/demo/BUILD.gn new file mode 100644 index 0000000..c399e49 --- /dev/null +++ b/src/demo/BUILD.gn @@ -0,0 +1,25 @@ +executable("demo") { + sources = [ + "credits.cc", + "credits.h", + "damage_type.h", + "demo.cc", + "demo.h", + "enemy.cc", + "enemy.h", + "hud.cc", + "hud.h", + "menu.cc", + "menu.h", + "player.cc", + "player.h", + "sky_quad.cc", + "sky_quad.h", + ] + + deps = [ + "//assets", + "//src/base", + "//src/engine", + ] +} diff --git a/src/engine/BUILD.gn b/src/engine/BUILD.gn new file mode 100644 index 0000000..90c29e2 --- /dev/null +++ b/src/engine/BUILD.gn @@ -0,0 +1,88 @@ +source_set("engine") { + sources = [ + "animatable.cc", + "animatable.h", + "animator.cc", + "animator.h", + "asset/font.cc", + "asset/font.h", + "asset/image.cc", + "asset/image.h", + "asset/mesh.cc", + "asset/mesh.h", + "asset/shader_source.cc", + "asset/shader_source.h", + "asset/sound.cc", + "asset/sound.h", + "audio/audio_bus.cc", + "audio/audio_bus.h", + "audio/audio_mixer.cc", + "audio/audio_mixer.h", + "audio/audio_sink.h", + "audio/mixer_input.cc", + "audio/mixer_input.h", + "audio/sinc_resampler.cc", + "audio/sinc_resampler.h", + "drawable.cc", + "drawable.h", + "engine.cc", + "engine.h", + "game.h", + "game_factory.h", + "image_quad.cc", + "image_quad.h", + "input_event.h", + "persistent_data.cc", + "persistent_data.h", + "platform/asset_file.cc", + "platform/asset_file.h", + "platform/platform.h", + "platform/platform_observer.h", + "renderer/geometry.cc", + "renderer/geometry.h", + "renderer/opengl/opengl.h", + "renderer/opengl/renderer_opengl.cc", + "renderer/opengl/renderer_opengl.h", + "renderer/render_resource.h", + "renderer/renderer.h", + "renderer/renderer_types.cc", + "renderer/renderer_types.h", + "renderer/shader.cc", + "renderer/shader.h", + "renderer/texture.cc", + "renderer/texture.h", + "renderer/vulkan/renderer_vulkan.cc", + "renderer/vulkan/vulkan_context.cc", + "solid_quad.cc", + "solid_quad.h", + "sound_player.cc", + "sound_player.h", + ] + + ldflags = [] + libs = [] + + if (target_os == "linux") { + sources += [ + "audio/audio_sink_alsa.cc", + "audio/audio_sink_alsa.h", + "platform/asset_file_linux.cc", + "platform/platform_linux.cc", + "renderer/opengl/renderer_opengl_linux.cc", + "renderer/vulkan/renderer_vulkan_linux.cc", + "renderer/vulkan/vulkan_context_linux.cc", + ] + + libs += [ + "X11", + "GL", + "asound", + ] + } + + deps = [ + "//assets/engine", + "//src/base", + "//src/third_party", + ] +} diff --git a/src/engine/platform/platform_linux.cc b/src/engine/platform/platform_linux.cc index 51c8868..3a10433 100644 --- a/src/engine/platform/platform_linux.cc +++ b/src/engine/platform/platform_linux.cc @@ -1,5 +1,8 @@ #include "engine/platform/platform.h" +#include +#include +#include #include #include "base/log.h" @@ -16,13 +19,25 @@ void KaliberMain(Platform* platform); Platform::Platform() { LOG(0) << "Initializing platform."; - root_path_ = "../../"; - LOG(0) << "Root path: " << root_path_.c_str(); - + root_path_ = "./"; data_path_ = "./"; - LOG(0) << "Data path: " << data_path_.c_str(); - shared_data_path_ = "./"; + + char dest[PATH_MAX]; + memset(dest, 0, sizeof(dest)); + if (readlink("/proc/self/exe", dest, PATH_MAX) > 0) { + std::string path = dest; + std::size_t last_slash_pos = path.find_last_of('/'); + if (last_slash_pos != std::string::npos) + path = path.substr(0, last_slash_pos + 1); + + root_path_ = path; + data_path_ = path; + shared_data_path_ = path; + } + + LOG(0) << "Root path: " << root_path_.c_str(); + LOG(0) << "Data path: " << data_path_.c_str(); LOG(0) << "Shared data path: " << shared_data_path_.c_str(); bool res = CreateWindow(800, 1205); diff --git a/src/hello_world/BUILD.gn b/src/hello_world/BUILD.gn new file mode 100644 index 0000000..ff4555c --- /dev/null +++ b/src/hello_world/BUILD.gn @@ -0,0 +1,10 @@ +executable("hello_world") { + sources = [ + "hello_world.cc", + ] + + deps = [ + "//src/base", + "//src/engine", + ] +} diff --git a/src/hello_world/hello_world.cc b/src/hello_world/hello_world.cc new file mode 100644 index 0000000..97b07f0 --- /dev/null +++ b/src/hello_world/hello_world.cc @@ -0,0 +1,35 @@ +#include "base/interpolation.h" +#include "engine/animator.h" +#include "engine/asset/image.h" +#include "engine/engine.h" +#include "engine/game.h" +#include "engine/game_factory.h" +#include "engine/image_quad.h" + +class HelloWorld final : public eng::Game { + public: + ~HelloWorld() final = default; + + bool Initialize() final { + eng::Engine::Get().SetImageSource( + "hello_world_image", + std::bind(&eng::Engine::Print, &eng::Engine::Get(), "Hello World!", + base::Vector4f(1, 1, 1, 0))); + + hello_world_.Create("hello_world_image"); + hello_world_.SetVisible(true); + animator_.Attach(&hello_world_); + animator_.SetRotation(base::PI2f, 3, + std::bind(base::SmootherStep, std::placeholders::_1)); + animator_.Play(eng::Animator::kRotation, true); + return true; + } + + private: + eng::ImageQuad hello_world_; + eng::Animator animator_; +}; + +DECLARE_GAME_BEGIN +DECLARE_GAME(HelloWorld) +DECLARE_GAME_END diff --git a/src/third_party/BUILD.gn b/src/third_party/BUILD.gn new file mode 100644 index 0000000..689664e --- /dev/null +++ b/src/third_party/BUILD.gn @@ -0,0 +1,91 @@ +config("third_party_config") { + include_dirs = [ + "vulkan/include", + "glslang", + ] + + if (target_os == "linux") { + defines = [ "VK_USE_PLATFORM_XLIB_KHR" ] + } +} + +source_set("third_party") { + public_configs = [ ":third_party_config" ] + + sources = [ + "glslang/OGLCompilersDLL/InitializeDll.cpp", + "glslang/SPIRV/GlslangToSpv.cpp", + "glslang/SPIRV/InReadableOrder.cpp", + "glslang/SPIRV/Logger.cpp", + "glslang/SPIRV/SPVRemapper.cpp", + "glslang/SPIRV/SpvBuilder.cpp", + "glslang/SPIRV/SpvPostProcess.cpp", + "glslang/SPIRV/SpvTools.cpp", + "glslang/SPIRV/disassemble.cpp", + "glslang/SPIRV/doc.cpp", + "glslang/glslang/GenericCodeGen/CodeGen.cpp", + "glslang/glslang/GenericCodeGen/Link.cpp", + "glslang/glslang/MachineIndependent/Constant.cpp", + "glslang/glslang/MachineIndependent/InfoSink.cpp", + "glslang/glslang/MachineIndependent/Initialize.cpp", + "glslang/glslang/MachineIndependent/IntermTraverse.cpp", + "glslang/glslang/MachineIndependent/Intermediate.cpp", + "glslang/glslang/MachineIndependent/ParseContextBase.cpp", + "glslang/glslang/MachineIndependent/ParseHelper.cpp", + "glslang/glslang/MachineIndependent/PoolAlloc.cpp", + "glslang/glslang/MachineIndependent/RemoveTree.cpp", + "glslang/glslang/MachineIndependent/Scan.cpp", + "glslang/glslang/MachineIndependent/ShaderLang.cpp", + "glslang/glslang/MachineIndependent/SpirvIntrinsics.cpp", + "glslang/glslang/MachineIndependent/SymbolTable.cpp", + "glslang/glslang/MachineIndependent/Versions.cpp", + "glslang/glslang/MachineIndependent/attribute.cpp", + "glslang/glslang/MachineIndependent/glslang_tab.cpp", + "glslang/glslang/MachineIndependent/intermOut.cpp", + "glslang/glslang/MachineIndependent/iomapper.cpp", + "glslang/glslang/MachineIndependent/limits.cpp", + "glslang/glslang/MachineIndependent/linkValidate.cpp", + "glslang/glslang/MachineIndependent/parseConst.cpp", + "glslang/glslang/MachineIndependent/preprocessor/Pp.cpp", + "glslang/glslang/MachineIndependent/preprocessor/PpAtom.cpp", + "glslang/glslang/MachineIndependent/preprocessor/PpContext.cpp", + "glslang/glslang/MachineIndependent/preprocessor/PpScanner.cpp", + "glslang/glslang/MachineIndependent/preprocessor/PpTokens.cpp", + "glslang/glslang/MachineIndependent/propagateNoContraction.cpp", + "glslang/glslang/MachineIndependent/reflection.cpp", + "glslang/glslang/OSDependent/Unix/ossource.cpp", + "jsoncpp/json.h", + "jsoncpp/jsoncpp.cpp", + "minimp3/minimp3.h", + "minimp3/minimp3_ex.h", + "spirv-reflect/spirv_reflect.c", + "stb/stb_image.c", + "stb/stb_image.h", + "stb/stb_truetype.h", + "texture_compressor/dxt_encoder.cc", + "texture_compressor/dxt_encoder.h", + "texture_compressor/dxt_encoder_implementation_autogen.h", + "texture_compressor/dxt_encoder_internals.cc", + "texture_compressor/dxt_encoder_internals.h", + "texture_compressor/texture_compressor.cc", + "texture_compressor/texture_compressor.h", + "texture_compressor/texture_compressor_etc1.cc", + "texture_compressor/texture_compressor_etc1.h", + "vma/vk_mem_alloc.cpp", + "volk/volk.c", + ] + + defines = [ "VMA_STATIC_VULKAN_FUNCTIONS=1" ] + + if (target_os == "linux") { + sources += [ + "glew/glew.c", + "glew/glew.h", + "glew/glxew.h", + ] + } + + configs -= [ "//build:warnings" ] + + deps = [] +}