Initial commit

This commit is contained in:
vylion 2020-06-21 16:43:44 +02:00
commit 8418010c1e
10 changed files with 1099 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
game

61
.vscode/c_cpp_properties.json vendored Normal file
View file

@ -0,0 +1,61 @@
{
"configurations": [
{
"name": "Win32",
"includePath": [
"C:/raylib/raylib/src/**",
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GRAPHICS_API_OPENGL_33",
"PLATFORM_DESKTOP"
],
"compilerPath": "C:/raylib/mingw/bin/gcc.exe",
"cStandard": "c99",
"cppStandard": "c++14",
"intelliSenseMode": "gcc-x64"
},
{
"name": "Mac",
"includePath": [
"<path_to_raylib>/src/**",
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GRAPHICS_API_OPENGL_33",
"PLATFORM_DESKTOP"
],
"macFrameworkPath": [
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk/System/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "clang-x64"
},
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE",
"GRAPHICS_API_OPENGL_33",
"PLATFORM_DESKTOP"
],
"compilerPath": "/usr/bin/g++",
"cStandard": "c11",
"cppStandard": "c++14",
"intelliSenseMode": "gcc-x64"
}
],
"version": 4
}

60
.vscode/launch.json vendored Normal file
View file

@ -0,0 +1,60 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/game",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": false
}
],
"windows": {
"miDebuggerPath": "C:/raylib/mingw/bin/gdb.exe",
},
"osx": {
"MIMode": "lldb"
},
"linux": {
"miDebuggerPath": "/usr/bin/gdb",
},
"preLaunchTask": "build debug"
},
{
"name": "Run",
"type": "cppdbg",
"request": "launch",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"program": "${workspaceFolder}/game",
"MIMode": "gdb",
"windows": {
"program": "${workspaceFolder}/game.exe",
"miDebuggerPath": "C:/raylib/mingw/bin/gdb.exe"
},
"osx": {
"MIMode": "lldb"
},
"linux": {
"miDebuggerPath": "/usr/bin/gdb"
},
"preLaunchTask": "build release",
}
]
}

72
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,72 @@
{
"files.exclude": {
"**/.git": true,
"**/.svn": true,
"**/.hg": true,
"**/CVS": true,
"**/.DS_Store": true,
"**/*.o": true,
"**/*.exe": true,
},
"files.associations": {
"array": "cpp",
"atomic": "cpp",
"hash_map": "cpp",
"bit": "cpp",
"*.tcc": "cpp",
"cctype": "cpp",
"chrono": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdint": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"deque": "cpp",
"list": "cpp",
"map": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"iterator": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"random": "cpp",
"ratio": "cpp",
"string": "cpp",
"string_view": "cpp",
"system_error": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"istream": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"ostream": "cpp",
"ranges": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"stop_token": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp",
"valarray": "cpp"
}
}

67
.vscode/tasks.json vendored Normal file
View file

@ -0,0 +1,67 @@
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "build debug",
"type": "process",
"command": "make",
"args": [
"PLATFORM=PLATFORM_DESKTOP",
"BUILD_MODE=DEBUG"
],
"windows": {
"command": "C:/raylib/mingw/bin/mingw32-make.exe",
"args": [
"RAYLIB_PATH=C:/raylib/raylib",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c",
"BUILD_MODE=DEBUG"
],
},
"osx": {
"args": [
"RAYLIB_PATH=<path_to_raylib>/raylib",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c",
"BUILD_MODE=DEBUG"
],
},
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": [
"$gcc"
]
},
{
"label": "build release",
"type": "process",
"command": "make",
"args": [
"PLATFORM=PLATFORM_DESKTOP",
],
"windows": {
"command": "C:/raylib/mingw/bin/mingw32-make.exe",
"args": [
"RAYLIB_PATH=C:/raylib/raylib",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c"
],
},
"osx": {
"args": [
"RAYLIB_PATH=<path_to_raylib>/raylib",
"PROJECT_NAME=${fileBasenameNoExtension}",
"OBJS=${fileBasenameNoExtension}.c"
],
},
"group": "build",
"problemMatcher": [
"$gcc"
]
}
]
}

409
Makefile Normal file
View file

@ -0,0 +1,409 @@
#**************************************************************************************************
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose, including commercial
# applications, and to alter it and redistribute it freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not claim that you
# wrote the original software. If you use this software in a product, an acknowledgment
# in the product documentation would be appreciated but is not required.
#
# 2. Altered source versions must be plainly marked as such, and must not be misrepresented
# as being the original software.
#
# 3. This notice may not be removed or altered from any source distribution.
#
#**************************************************************************************************
.PHONY: all clean
# Define required raylib variables
PROJECT_NAME ?= game
RAYLIB_VERSION ?= 2.5.0
RAYLIB_API_VERSION ?= 251
RAYLIB_PATH ?= ..\..
# Define compiler path on Windows
COMPILER_PATH ?= C:/raylib/mingw/bin
# Define default options
# One of PLATFORM_DESKTOP, PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
PLATFORM ?= PLATFORM_DESKTOP
# Locations of your newly installed library and associated headers. See ../src/Makefile
# On Linux, if you have installed raylib but cannot compile the examples, check that
# the *_INSTALL_PATH values here are the same as those in src/Makefile or point to known locations.
# To enable system-wide compile-time and runtime linking to libraylib.so, run ../src/$ sudo make install RAYLIB_LIBTYPE_SHARED.
# To enable compile-time linking to a special version of libraylib.so, change these variables here.
# To enable runtime linking to a special version of libraylib.so, see EXAMPLE_RUNTIME_PATH below.
# If there is a libraylib in both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH, at runtime,
# the library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over the one at RAYLIB_INSTALL_PATH.
# RAYLIB_INSTALL_PATH should be the desired full path to libraylib. No relative paths.
DESTDIR ?= /usr/local
RAYLIB_INSTALL_PATH ?= $(DESTDIR)/lib
# RAYLIB_H_INSTALL_PATH locates the installed raylib header and associated source files.
RAYLIB_H_INSTALL_PATH ?= $(DESTDIR)/include
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
# Build mode for project: DEBUG or RELEASE
BUILD_MODE ?= RELEASE
# Use external GLFW library instead of rglfw module
# TODO: Review usage on Linux. Target version of choice. Switch on -lglfw or -lglfw3
USE_EXTERNAL_GLFW ?= FALSE
# Use Wayland display server protocol on Linux desktop
# by default it uses X11 windowing system
USE_WAYLAND_DISPLAY ?= FALSE
# Determine PLATFORM_OS in case PLATFORM_DESKTOP selected
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
# No uname.exe on MinGW!, but OS=Windows_NT on Windows!
# ifeq ($(UNAME),Msys) -> Windows
ifeq ($(OS),Windows_NT)
PLATFORM_OS=WINDOWS
export PATH := $(COMPILER_PATH):$(PATH)
else
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
endif
ifeq ($(UNAMEOS),FreeBSD)
PLATFORM_OS=BSD
endif
ifeq ($(UNAMEOS),OpenBSD)
PLATFORM_OS=BSD
endif
ifeq ($(UNAMEOS),NetBSD)
PLATFORM_OS=BSD
endif
ifeq ($(UNAMEOS),DragonFly)
PLATFORM_OS=BSD
endif
ifeq ($(UNAMEOS),Darwin)
PLATFORM_OS=OSX
endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
UNAMEOS=$(shell uname)
ifeq ($(UNAMEOS),Linux)
PLATFORM_OS=LINUX
endif
endif
# RAYLIB_PATH adjustment for different platforms.
# If using GNU make, we can get the full path to the top of the tree. Windows? BSD?
# Required for ldconfig or other tools that do not perform path expansion.
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),LINUX)
RAYLIB_PREFIX ?= ..
RAYLIB_PATH = $(realpath $(RAYLIB_PREFIX))
endif
endif
# Default path for raylib on Raspberry Pi, if installed in different path, update it!
# This is not currently used by src/Makefile. Not sure of its origin or usage. Refer to wiki.
# TODO: update install: target in src/Makefile for RPI, consider relation to LINUX.
ifeq ($(PLATFORM),PLATFORM_RPI)
RAYLIB_PATH ?= /home/pi/raylib
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Emscripten required variables
EMSDK_PATH ?= C:/emsdk
EMSCRIPTEN_VERSION ?= 1.38.31
CLANG_VERSION = e$(EMSCRIPTEN_VERSION)_64bit
PYTHON_VERSION = 2.7.13.1_64bit\python-2.7.13.amd64
NODE_VERSION = 8.9.1_64bit
export PATH = $(EMSDK_PATH);$(EMSDK_PATH)\clang\$(CLANG_VERSION);$(EMSDK_PATH)\node\$(NODE_VERSION)\bin;$(EMSDK_PATH)\python\$(PYTHON_VERSION);$(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION);C:\raylib\MinGW\bin:$$(PATH)
EMSCRIPTEN = $(EMSDK_PATH)\emscripten\$(EMSCRIPTEN_VERSION)
endif
# Define raylib release directory for compiled library.
# RAYLIB_RELEASE_PATH points to provided binaries or your freshly built version
RAYLIB_RELEASE_PATH ?= $(RAYLIB_PATH)/src
# EXAMPLE_RUNTIME_PATH embeds a custom runtime location of libraylib.so or other desired libraries
# into each example binary compiled with RAYLIB_LIBTYPE=SHARED. It defaults to RAYLIB_RELEASE_PATH
# so that these examples link at runtime with your version of libraylib.so in ../release/libs/linux
# without formal installation from ../src/Makefile. It aids portability and is useful if you have
# multiple versions of raylib, have raylib installed to a non-standard location, or want to
# bundle libraylib.so with your game. Change it to your liking.
# NOTE: If, at runtime, there is a libraylib.so at both EXAMPLE_RUNTIME_PATH and RAYLIB_INSTALL_PATH,
# The library at EXAMPLE_RUNTIME_PATH, if present, will take precedence over RAYLIB_INSTALL_PATH,
# Implemented for LINUX below with CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
# To see the result, run readelf -d core/core_basic_window; looking at the RPATH or RUNPATH attribute.
# To see which libraries a built example is linking to, ldd core/core_basic_window;
# Look for libraylib.so.1 => $(RAYLIB_INSTALL_PATH)/libraylib.so.1 or similar listing.
EXAMPLE_RUNTIME_PATH ?= $(RAYLIB_RELEASE_PATH)
# Define default C compiler: gcc
# NOTE: define g++ compiler if using C++
CC = g++
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),OSX)
# OSX default compiler
CC = clang
endif
ifeq ($(PLATFORM_OS),BSD)
# FreeBSD, OpenBSD, NetBSD, DragonFly default compiler
CC = clang
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
ifeq ($(USE_RPI_CROSS_COMPILER),TRUE)
# Define RPI cross-compiler
#CC = armv6j-hardfloat-linux-gnueabi-gcc
CC = $(RPI_TOOLCHAIN)/bin/arm-linux-gnueabihf-gcc
endif
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# HTML5 emscripten compiler
# WARNING: To compile to HTML5, code must be redesigned
# to use emscripten.h and emscripten_set_main_loop()
CC = emcc
endif
# Define default make program: Mingw32-make
MAKE = mingw32-make
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),LINUX)
MAKE = make
endif
ifeq ($(PLATFORM_OS),OSX)
MAKE = make
endif
endif
# Define compiler flags:
# -O0 defines optimization level (no optimization, better for debugging)
# -O1 defines optimization level
# -g include debug information on compilation
# -s strip unnecessary data from build -> do not use in debug builds
# -Wall turns on most, but not all, compiler warnings
# -std=c99 defines C language mode (standard C from 1999 revision)
# -std=gnu99 defines C language mode (GNU C from 1999 revision)
# -Wno-missing-braces ignore invalid warning (GCC bug 53119)
# -D_DEFAULT_SOURCE use with -std=c99 on Linux and PLATFORM_WEB, required for timespec
CFLAGS += -Wall -std=c++14 -D_DEFAULT_SOURCE -Wno-missing-braces
ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g -O0
else
CFLAGS += -s -O1
endif
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
# resource file contains windows executable icon and properties
# -Wl,--subsystem,windows hides the console window
CFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data -Wl,--subsystem,windows
endif
ifeq ($(PLATFORM_OS),LINUX)
ifeq ($(RAYLIB_LIBTYPE),STATIC)
CFLAGS += -D_DEFAULT_SOURCE
endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
# Explicitly enable runtime link to libraylib.so
CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
CFLAGS += -std=gnu99
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0
# -s USE_GLFW=3 # Use glfw3 library (context/input management)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
# -s WASM=0 # disable Web Assembly, emitted by default
# -s EMTERPRETIFY=1 # enable emscripten code interpreter (very slow)
# -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter
# -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# --profiling # include information for code profiling
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation
CFLAGS += -Os -s USE_GLFW=3 -s TOTAL_MEMORY=16777216 --preload-file resources
ifeq ($(BUILD_MODE), DEBUG)
CFLAGS += -s ASSERTIONS=1 --profiling
endif
# Define a custom shell .html and output extension
CFLAGS += --shell-file $(RAYLIB_PATH)/src/shell.html
EXT = .html
endif
# Define include paths for required headers
# NOTE: Several external required libraries (stb and others)
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
# Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
# RPI required libraries
INCLUDE_PATHS += -I/opt/vc/include
INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),BSD)
# Consider -L$(RAYLIB_H_INSTALL_PATH)
INCLUDE_PATHS += -I/usr/local/include
endif
ifeq ($(PLATFORM_OS),LINUX)
# Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
endif
endif
# Define library paths containing required libs.
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),BSD)
# Consider -L$(RAYLIB_INSTALL_PATH)
LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif
ifeq ($(PLATFORM_OS),LINUX)
# Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs
LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH)
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
endif
# Define any libraries required on linking
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation
# NOTE: WinMM library required to set high-res timer resolution
LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
# Required for physac examples
#LDLIBS += -static -lpthread
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
# NOTE: Required packages: libegl1-mesa-dev
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
# On X11 requires also below libraries
LDLIBS += -lX11
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
# On Wayland windowing system, additional libraries requires
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
endif
# Explicit link to libc
ifeq ($(RAYLIB_LIBTYPE),SHARED)
LDLIBS += -lc
endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -framework OpenGL -framework OpenAL -framework Cocoa
endif
ifeq ($(PLATFORM_OS),BSD)
# Libraries for FreeBSD, OpenBSD, NetBSD, DragonFly desktop compiling
# NOTE: Required packages: mesa-libs
LDLIBS = -lraylib -lGL -lpthread -lm
# On XWindow requires also below libraries
LDLIBS += -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
endif
ifeq ($(USE_EXTERNAL_GLFW),TRUE)
# NOTE: It could require additional packages installed: libglfw3-dev
LDLIBS += -lglfw
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
# Libraries for Raspberry Pi compiling
# NOTE: Required packages: libasound2-dev (ALSA)
LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# Libraries for web (HTML5) compiling
LDLIBS = $(RAYLIB_RELEASE_PATH)/libraylib.bc
endif
# Define a recursive wildcard function
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
# Define all source files required
SRC_DIR = src
OBJ_DIR = obj
# Define all object files from source files
SRC = $(call rwildcard, *.c, *.h)
#OBJS = $(SRC:$(SRC_DIR)/%.c=$(OBJ_DIR)/%.o)
OBJS ?= main.cpp helpers.cpp
# For Android platform we call a custom Makefile.Android
ifeq ($(PLATFORM),PLATFORM_ANDROID)
MAKEFILE_PARAMS = -f Makefile.Android
export PROJECT_NAME
export SRC_DIR
else
MAKEFILE_PARAMS = $(PROJECT_NAME)
endif
# Default target entry
# NOTE: We call this Makefile target or Makefile.Android target
all:
$(MAKE) $(MAKEFILE_PARAMS)
# Project target defined by PROJECT_NAME
$(PROJECT_NAME): $(OBJS)
$(CC) -o $(PROJECT_NAME)$(EXT) $(OBJS) $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
# Compile source files
# NOTE: This pattern will compile every module defined on $(OBJS)
#%.o: %.c
$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDE_PATHS) -D$(PLATFORM)
# Clean everything
clean:
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
del *.o *.exe /s
endif
ifeq ($(PLATFORM_OS),LINUX)
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv
endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
rm -f *.o
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
find . -type f -executable -delete
rm -fv *.o
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done

172
helpers.cpp Normal file
View file

@ -0,0 +1,172 @@
#include "helpers.h"
bool operator==(const Vector2 &v, const Vector2 &w)
{
return v.x == w.x and v.y == w.y;
}
Vector2 operator-(const Vector2 &v, const Vector2 &w)
{
return Vector2{v.x - w.x, v.y - w.y};
}
Vector2 operator+(const Vector2 &v, const Vector2 &w)
{
return Vector2{v.x + w.x, v.y + w.y};
}
Color darkenBy(const Color &c, int amount)
{
return Color{std::max(c.r - amount, 0), std::max(c.g - amount, 0), std::max(c.b - amount, 0)};
}
/* This fucntion tells us wether a loop pqr is clockwise, counterclockwise,
* or if they're colinear */
Orientation orientation(const Point &p, const Point &q, const Point &r)
{
Vector2 pq = p - q;
Vector2 pr = p - r;
float o = pq.x * pr.y - pr.x * pq.y;
if (o > 0)
return CW;
else if (o < 0)
return CCW;
return CL;
}
bool sharedEndpoint(const LineSegment &s, const LineSegment &t)
{
return s.first == t.first or s.second == t.second or s.first == t.second or s.second == t.second;
}
/* This function checks if a point p is inside a rectangle of diagonal t
*/
bool insideRectangle(const LineSegment &t, const Point &p)
{
float x_min = std::min(t.first.x, t.second.x);
float y_min = std::min(t.first.y, t.second.y);
float x_max = std::max(t.first.x, t.second.x);
float y_max = std::max(t.first.y, t.second.y);
return ((p.x >= x_min and p.x <= x_max) and
(p.y >= y_min and p.y <= y_max));
}
bool insideRectangle(const LineSegment &t, const LineSegment &s)
{
return insideRectangle(t, s.first) and insideRectangle(t, s.second);
}
bool intersect(const LineSegment &s, const LineSegment &t)
{
int t1 = orientation(s.first, s.second, t.first);
int t2 = orientation(s.first, s.second, t.second);
int s1 = orientation(t.first, t.second, s.first);
int s2 = orientation(t.first, t.second, s.second);
// They cross at a middle point
if (t1 != t2 and s1 != s2)
return true;
// s.first lies inside t
if (t1 == 0 and insideRectangle(t, s.first))
return true;
// s.second lies inside t
if (t2 == 0 and insideRectangle(t, s.second))
return true;
// t.first lies inside s
if (s1 == 0 and insideRectangle(s, t.first))
return true;
// t.second lies inside s
if (s2 == 0 and insideRectangle(s, t.second))
return true;
return false;
}
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour, std::string &desc)
{
colour = GRAY;
desc = "No intersection";
int t1 = orientation(s.first, s.second, t.first);
int t2 = orientation(s.first, s.second, t.second);
int s1 = orientation(t.first, t.second, s.first);
int s2 = orientation(t.first, t.second, s.second);
//Segment t has endpoints on either side of s
if ((t1 < 0) != (t2 < 0))
{
//Segment s has endpoints on either side of t
if ((s1 < 0) != (s2 < 0))
{
desc = "Intersection in a middle point (red)";
colour = RED;
}
//Segment s has just one endpoint on the line over segment t
else if ((s1 > 0) != (s2 > 0))
{
desc = "Endpoint on the intersection (green)";
colour = GREEN;
}
}
//Segment t has just one endpoint on the line over segment s
else if ((t1 > 0) != (t2 > 0))
{
//Segment t and segment s share an endpoint
if (sharedEndpoint(s, t))
{
desc = "Intersection at a shared endpoint (dark green)";
colour = DARKGREEN;
}
//Segment s has endpoints on either side of t
else if ((s1 < 0) != (s2 < 0))
{
desc = "Endpoint on the intersection (green)";
colour = GREEN;
}
}
//Segment t has both endpoints on the line over segment s
else if ((t1 == 0) and (t2 == 0))
{
desc = " on a shared line";
//Segment s and segment t share one endpoint
if (sharedEndpoint(s, t))
{
//Segment s and t share both endpoints
if (sharedEndpoint(s, t))
{
desc = "Full overlap (purple)";
colour = PURPLE;
}
else
{
desc = "Intersection at a shared endpoint (pink)";
colour = PINK;
}
}
//Segment t has one endpoint inside the rectangle covering both endpoints of s
//Since t's endpoints are already on the line over s, this means having it on s
else if (insideRectangle(s, t))
{
desc = "Overlap (intersection)" + desc + " (dark blue)";
colour = DARKBLUE;
}
//Segment t has both endpoints on the line over s, but none inside s
else
{
desc = "No intersection, but" + desc + " (blue)";
colour = BLUE;
}
}
}
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour)
{
std::string unused;
classifyIntersection(s, t, colour, unused);
}

33
helpers.h Normal file
View file

@ -0,0 +1,33 @@
#ifndef HELPERS_H
#include <utility>
#include <string>
#include <random>
#include <time.h>
#include "raymath.h"
typedef Vector2 Point;
typedef std::pair<Point, Point> LineSegment;
enum Orientation
{
CW = 1,
CCW = -1,
CL = 0
};
bool operator==(const Vector2 &v, const Vector2 &w);
Vector2 operator-(const Vector2 &v, const Vector2 &w);
Vector2 operator+(const Vector2 &v, const Vector2 &w);
Color darkenBy(const Color &c, int amount);
Orientation orientation(const Point &p, const Point &q, const Point &r);
bool sharedEndpoint(const LineSegment &s, const LineSegment &t);
bool insideRectangle(const LineSegment &t, const Point &p);
bool insideRectangle(const LineSegment &t, const LineSegment &s);
bool intersect(const LineSegment &s, const LineSegment &t);
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour, std::string &desc);
void classifyIntersection(const LineSegment &s, const LineSegment &t, Color &colour);
#endif // !HELPERS_H

16
main.code-workspace Normal file
View file

@ -0,0 +1,16 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"files.associations": {
"raylib.h": "c",
"math.h": "c",
"blocks.h": "c",
"stdio.h": "c",
"*.m": "c"
}
}
}

208
main.cpp Normal file
View file

@ -0,0 +1,208 @@
/*******************************************************************************************
*
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013-2020 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <chrono>
#include "raylib.h"
#include "helpers.h"
using time_point = std::chrono::steady_clock::time_point;
struct ColorSegment
{
LineSegment l;
Color c;
uint id;
std::set<uint> crossed_by;
};
void DrawColorSegment(const ColorSegment &cl)
{
DrawLine(cl.l.first.x, cl.l.first.y, cl.l.second.x, cl.l.second.y, cl.c);
}
void DrawLines(const std::vector<ColorSegment> &lines)
{
for (uint i = 0; i < lines.size(); ++i)
{
DrawColorSegment(lines[i]);
}
}
void crossLines(ColorSegment &s, ColorSegment &t)
{
Color c;
classifyIntersection(s.l, t.l, c);
s.c = c;
t.c = darkenBy(c, 10);
}
void crossingNaive(std::vector<ColorSegment> &lines)
{
bool crossed = false;
for (uint i = 0; i < lines.size(); ++i)
{
for (uint j = i + 1; j < lines.size() && !crossed; ++j)
{
bool crossed = intersect(lines[i].l, lines[j].l);
if (crossed)
{
lines[i].crossed_by.insert(j);
lines[j].crossed_by.insert(i);
lines[i].c = RED;
lines[j].c = RED;
}
}
}
}
bool sort_by_x(const ColorSegment &s, const ColorSegment &t)
{
return s.l.first.x < t.l.first.x;
}
void crossingSweep(std::vector<ColorSegment> &lines)
{
std::sort(lines.begin(), lines.end(), sort_by_x);
}
enum States
{
INIT = 0,
NAIVE,
SWEEP
};
States operator++(States &s)
{
if (s == SWEEP)
return s;
int si = static_cast<int>(s);
return s = static_cast<States>(++si);
}
States operator--(States &s)
{
if (s == INIT)
return s;
int si = static_cast<int>(s);
return s = static_cast<States>(--si);
}
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 900;
bool close = false;
const int nols = 80; // Number of lines
// Initialize random engine
std::random_device rd;
std::mt19937_64 gen(rd()); // Delete "_64" in a 32 bit system
std::uniform_int_distribution<> distrx(0, screenWidth);
std::uniform_int_distribution<> distry(0, screenHeight);
std::vector<ColorSegment> lines, naive_lines, sweep_lines;
// Generate random lines
for (uint i = 0; i < nols; ++i)
{
LineSegment l = LineSegment{Point{distrx(gen), distry(gen)}, Point{distrx(gen), distry(gen)}};
//std::cout << "(" << l.first.x << "," << l.first.y << ") (" << l.second.x << "," << l.second.y << std::endl;
ColorSegment cl = ColorSegment{l, BLACK};
lines.push_back(cl);
}
// Copy initial lines vector for each algorithm
naive_lines = lines;
sweep_lines = lines;
// Test naive algorithm
time_point begin_naive = std::chrono::steady_clock::now();
crossingNaive(naive_lines);
time_point end_naive = std::chrono::steady_clock::now();
// Test sweep algorithm
time_point begin_sweep = std::chrono::steady_clock::now();
crossingSweep(sweep_lines);
time_point end_sweep = std::chrono::steady_clock::now();
std::cout << "Naive elapsed time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end_naive - begin_naive).count() << " ns" << std::endl;
std::cout << "Sweep elapsed time: " << std::chrono::duration_cast<std::chrono::nanoseconds>(end_sweep - begin_sweep).count() << " ns" << std::endl;
States state = INIT;
InitWindow(screenWidth, screenHeight, "raylib");
SetTargetFPS(30); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose() and !close) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_RIGHT))
++state;
else if (IsKeyPressed(KEY_LEFT))
--state;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
switch (state)
{
case INIT:
DrawLines(lines);
break;
case NAIVE:
DrawLines(naive_lines);
break;
case SWEEP:
DrawLines(sweep_lines);
break;
default:
break;
}
DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}