18 Commits

Author SHA1 Message Date
Ray
9ef6850cc4 Update build_examples_windows.yml 2026-07-18 17:52:07 +02:00
Ray
3094389a2a Update analyze_codeql.yml 2026-07-18 17:49:35 +02:00
Ray
b812c18e6b Merge branch 'master' of https://github.com/raysan5/raylib 2026-07-18 17:14:10 +02:00
Ray
6c6a248be8 Update rcore.c 2026-07-18 17:14:03 +02:00
ce6ac7d8c7 rlparser: update raylib_api.* by CI 2026-07-18 14:50:44 +00:00
Ray
baa9a4df51 REVIEWED: ImageToImage(), reorganize conditionals checks optimization, align brackets 2026-07-18 16:50:28 +02:00
Ray
58e03dbc6c REVIEWED: TakeScreenshot() to support absolute paths 2026-07-18 16:45:28 +02:00
Ray
cfccb83ddd ADDED: IsPathAbsolute() to check absolute paths 2026-07-18 16:44:41 +02:00
Ray
b806e3d2ec Replaced comments text given by provided 2026-07-18 16:44:10 +02:00
Ray
0725811224 Added a note reminder 2026-07-18 16:43:04 +02:00
5b1445b381 FIXED: ImageFromImage() heap-buffer-overflow on compressed formats (#5991) 2026-07-17 23:22:35 +02:00
aa088e42d1 fix static link deps (#5990) 2026-07-17 23:12:57 +02:00
7aceceb467 Fix logging format for automation event capacity warning (#5986)
Co-authored-by: gideons <gse@newspacesystems.com>
2026-07-17 20:31:26 +02:00
Ray
66bb527d22 Update README.md 2026-07-16 15:10:46 +02:00
Ray
f1d44c166f REMOVED: Unmaintained project: VS2019-Android 2026-07-16 15:08:46 +02:00
Ray
9c834d6e4d Merge branch 'master' of https://github.com/raysan5/raylib 2026-07-16 15:08:35 +02:00
Ray
742ccb390a REMOVED: Unmaintained project: 4coder 2026-07-16 15:08:12 +02:00
Ray
62a74a342c Update README.md 2026-07-16 15:05:32 +02:00
29 changed files with 621 additions and 2747 deletions

View File

@ -71,7 +71,7 @@ jobs:
# Initializes the CodeQL tools for scanning. # Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v4
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file. # If you wish to specify custom queries, you can do so here or in a config file.
@ -90,7 +90,7 @@ jobs:
cmake --build . --config $BUILD_TYPE cmake --build . --config $BUILD_TYPE
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v4
with: with:
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"
upload: false upload: false
@ -99,7 +99,7 @@ jobs:
# Filter out rules with low severity or high false positve rate # Filter out rules with low severity or high false positve rate
# Also filter out warnings in third-party code # Also filter out warnings in third-party code
- name: Filter out unwanted errors and warnings - name: Filter out unwanted errors and warnings
uses: advanced-security/filter-sarif@v1 uses: advanced-security/filter-sarif@v1.1
with: with:
patterns: | patterns: |
-**:cpp/path-injection -**:cpp/path-injection
@ -121,7 +121,7 @@ jobs:
output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif output: ${{ steps.step1.outputs.sarif-output }}/cpp.sarif
- name: Upload CodeQL results to code scanning - name: Upload CodeQL results to code scanning
uses: github/codeql-action/upload-sarif@v2 uses: github/codeql-action/upload-sarif@v4
with: with:
sarif_file: ${{ steps.step1.outputs.sarif-output }} sarif_file: ${{ steps.step1.outputs.sarif-output }}
category: "/language:${{matrix.language}}" category: "/language:${{matrix.language}}"

View File

@ -25,7 +25,7 @@ jobs:
- uses: actions/checkout@master - uses: actions/checkout@master
- name: Add MSBuild to PATH - name: Add MSBuild to PATH
uses: microsoft/setup-msbuild@v1 uses: microsoft/setup-msbuild@v3
- name: Build Library (MSVC16) - name: Build Library (MSVC16)
run: | run: |

View File

@ -1,401 +0,0 @@
#**************************************************************************************************
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2026 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 ?= 4.2.0
RAYLIB_PATH ?= ..\..
# 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
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:/raylib/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/upstream/emscripten
CLANG_PATH = $(EMSDK_PATH)/upstream/bin
PYTHON_PATH = $(EMSDK_PATH)/python/3.13.3_64bit
NODE_PATH = $(EMSDK_PATH)/node/22.16.0_64bit/bin
export PATH = $(EMSDK_PATH);$(EMSCRIPTEN_PATH);$(CLANG_PATH);$(NODE_PATH);$(PYTHON_PATH);C:\raylib\MinGW\bin:$$(PATH)
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 = gcc
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:
# -O1 defines optimization level
# -g include debug information on compilation
# -s strip unnecessary data from build
# -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 += -O1 -s -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g
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
# -sUSE_GLFW=3 # Use glfw3 library (context/input management)
# -sALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -sTOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB) (67108864 = 64MB)
# -sUSE_PTHREADS=1 # multithreading support
# -sWASM=0 # disable Web Assembly, emitted by default
# -sASYNCIFY # lets synchronous C/C++ code interact with asynchronous JS
# -sFORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -sASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# -sMINIFY_HTML=0 # minify generated html from shell.html
# --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
# --source-map-base # allow debugging in browser with source map
# --shell-file shell.html # define a custom shell .html and output extension
CFLAGS += -Os -sUSE_GLFW=3 -sTOTAL_MEMORY=16777216 --preload-file resources -sMINIFY_HTML=0
ifeq ($(BUILD_MODE), DEBUG)
CFLAGS += -sASSERTIONS=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
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.c
# 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

View File

@ -1,300 +0,0 @@
#**************************************************************************************************
#
# raylib makefile for Android project (APK building)
#
# Copyright (c) 2017 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.
#
#**************************************************************************************************
# Define required raylib variables
PLATFORM ?= PLATFORM_ANDROID
RAYLIB_PATH ?= ..\..
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
ANDROID_ARCH ?= ARM
ANDROID_API_VERSION = 21
ifeq ($(ANDROID_ARCH),ARM)
ANDROID_ARCH_NAME = armeabi-v7a
endif
ifeq ($(ANDROID_ARCH),ARM64)
ANDROID_ARCH_NAME = arm64-v8a
endif
# Required path variables
# NOTE: JAVA_HOME must be set to JDK
JAVA_HOME ?= C:/JavaJDK
ANDROID_HOME = C:/android-sdk
ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
ANDROID_BUILD_TOOLS = $(ANDROID_HOME)/build-tools/28.0.1
ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
# Android project configuration variables
PROJECT_NAME ?= raylib_game
PROJECT_LIBRARY_NAME ?= main
PROJECT_BUILD_PATH ?= android.$(PROJECT_NAME)
PROJECT_RESOURCES_PATH ?= resources
PROJECT_SOURCE_FILES ?= raylib_game.c
# Some source files are placed in directories, when compiling to some
# output directory other than source, that directory must pre-exist.
# Here we get a list of required folders that need to be created on
# code output folder $(PROJECT_BUILD_PATH)\obj to avoid GCC errors.
PROJECT_SOURCE_DIRS = $(sort $(dir $(PROJECT_SOURCE_FILES)))
# Android app configuration variables
APP_LABEL_NAME ?= rGame
APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
# Library path for libraylib.a/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\src
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/$(ANDROID_ARCH_NAME)/libraylib.so
endif
# Compiler and archiver
# NOTE: GCC is being deprecated in Android NDK r16
ifeq ($(ANDROID_ARCH),ARM)
CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
endif
ifeq ($(ANDROID_ARCH),ARM64)
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
endif
# Compiler flags for arquitecture
ifeq ($(ANDROID_ARCH),ARM)
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
endif
ifeq ($(ANDROID_ARCH),ARM64)
CFLAGS = -std=c99 -mfix-cortex-a53-835769
endif
# Compilation functions attributes options
CFLAGS += -ffunction-sections -funwind-tables -fstack-protector-strong -fPIC
# Compiler options for the linker
CFLAGS += -Wall -Wa,--noexecstack -Wformat -Werror=format-security -no-canonical-prefixes
# Preprocessor macro definitions
CFLAGS += -DANDROID -DPLATFORM_ANDROID -D__ANDROID_API__=$(ANDROID_API_VERSION)
# Paths containing required header files
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external/android/native_app_glue
# Linker options
LDFLAGS = -Wl,-soname,lib$(PROJECT_LIBRARY_NAME).so -Wl,--exclude-libs,libatomic.a
LDFLAGS += -Wl,--build-id -Wl,--no-undefined -Wl,-z,noexecstack -Wl,-z,relro -Wl,-z,now -Wl,--warn-shared-textrel -Wl,--fatal-warnings
# Force linking of library module to define symbol
LDFLAGS += -u ANativeActivity_onCreate
# Library paths containing required libs
LDFLAGS += -L. -L$(PROJECT_BUILD_PATH)/obj -L$(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME) -L$(ANDROID_TOOLCHAIN)\sysroot\usr\lib
# Define any libraries to link into executable
# if you want to link libraries (libname.so or libname.a), use the -lname
LDLIBS = -lm -lc -lraylib -llog -landroid -lEGL -lGLESv2 -lOpenSLES -ldl
# Generate target objects list from PROJECT_SOURCE_FILES
OBJS = $(patsubst %.c, $(PROJECT_BUILD_PATH)/obj/%.o, $(PROJECT_SOURCE_FILES))
# Android APK building process... some steps required...
# NOTE: typing 'make' will invoke the default target entry called 'all',
all: create_temp_project_dirs \
copy_project_required_libs \
copy_project_resources \
generate_loader_script \
generate_android_manifest \
generate_apk_keystore \
config_project_package \
compile_project_code \
compile_project_class \
compile_project_class_dex \
create_project_apk_package \
sign_project_apk_package \
zipalign_project_apk_package
# Create required temp directories for APK building
create_temp_project_dirs:
if not exist $(PROJECT_BUILD_PATH) mkdir $(PROJECT_BUILD_PATH)
if not exist $(PROJECT_BUILD_PATH)\obj mkdir $(PROJECT_BUILD_PATH)\obj
if not exist $(PROJECT_BUILD_PATH)\src mkdir $(PROJECT_BUILD_PATH)\src
if not exist $(PROJECT_BUILD_PATH)\src\com mkdir $(PROJECT_BUILD_PATH)\src\com
if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)
if not exist $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME) mkdir $(PROJECT_BUILD_PATH)\src\com\$(APP_COMPANY_NAME)\$(APP_PRODUCT_NAME)
if not exist $(PROJECT_BUILD_PATH)\lib mkdir $(PROJECT_BUILD_PATH)\lib
if not exist $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME) mkdir $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME)
if not exist $(PROJECT_BUILD_PATH)\bin mkdir $(PROJECT_BUILD_PATH)\bin
if not exist $(PROJECT_BUILD_PATH)\res mkdir $(PROJECT_BUILD_PATH)\res
if not exist $(PROJECT_BUILD_PATH)\res\drawable-ldpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-ldpi
if not exist $(PROJECT_BUILD_PATH)\res\drawable-mdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-mdpi
if not exist $(PROJECT_BUILD_PATH)\res\drawable-hdpi mkdir $(PROJECT_BUILD_PATH)\res\drawable-hdpi
if not exist $(PROJECT_BUILD_PATH)\res\values mkdir $(PROJECT_BUILD_PATH)\res\values
if not exist $(PROJECT_BUILD_PATH)\assets mkdir $(PROJECT_BUILD_PATH)\assets
if not exist $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) mkdir $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH)
if not exist $(PROJECT_BUILD_PATH)\obj\screens mkdir $(PROJECT_BUILD_PATH)\obj\screens
$(foreach dir, $(PROJECT_SOURCE_DIRS), $(call create_dir, $(dir)))
define create_dir
if not exist $(PROJECT_BUILD_PATH)\obj\$(1) mkdir $(PROJECT_BUILD_PATH)\obj\$(1)
endef
# Copy required shared libs for integration into APK
# NOTE: If using shared libs they are loaded by generated NativeLoader.java
copy_project_required_libs:
ifeq ($(RAYLIB_LIBTYPE),SHARED)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.so $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME)\libraylib.so
endif
ifeq ($(RAYLIB_LIBTYPE),STATIC)
copy /Y $(RAYLIB_LIB_PATH)\libraylib.a $(PROJECT_BUILD_PATH)\lib\$(ANDROID_ARCH_NAME)\libraylib.a
endif
# Copy project required resources: strings.xml, icon.png, assets
# NOTE: Required strings.xml is generated and game resources are copied to assets folder
# TODO: Review xcopy usage, it can not be found in some systems!
copy_project_resources:
copy $(APP_ICON_LDPI) $(PROJECT_BUILD_PATH)\res\drawable-ldpi\icon.png /Y
copy $(APP_ICON_MDPI) $(PROJECT_BUILD_PATH)\res\drawable-mdpi\icon.png /Y
copy $(APP_ICON_HDPI) $(PROJECT_BUILD_PATH)\res\drawable-hdpi\icon.png /Y
@echo ^<?xml version="1.0" encoding="utf-8"^?^> > $(PROJECT_BUILD_PATH)/res/values/strings.xml
@echo ^<resources^>^<string name="app_name"^>$(APP_LABEL_NAME)^</string^>^</resources^> >> $(PROJECT_BUILD_PATH)/res/values/strings.xml
if exist $(PROJECT_RESOURCES_PATH) C:\Windows\System32\xcopy $(PROJECT_RESOURCES_PATH) $(PROJECT_BUILD_PATH)\assets\$(PROJECT_RESOURCES_PATH) /Y /E /F
# Generate NativeLoader.java to load required shared libraries
# NOTE: Probably not the bet way to generate this file... but it works.
generate_loader_script:
@echo package com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME); > $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo. >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo public class NativeLoader extends android.app.NativeActivity { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo static { >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
ifeq ($(RAYLIB_LIBTYPE),SHARED)
@echo System.loadLibrary("raylib"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
endif
@echo System.loadLibrary("$(PROJECT_LIBRARY_NAME)"); >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
@echo } >> $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
# Generate AndroidManifest.xml with all the required options
# NOTE: Probably not the bet way to generate this file... but it works.
generate_android_manifest:
@echo ^<?xml version="1.0" encoding="utf-8"^?^> > $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<manifest xmlns:android="http://schemas.android.com/apk/res/android" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo package="com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME)" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo android:versionCode="$(APP_VERSION_CODE)" android:versionName="$(APP_VERSION_NAME)" ^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<uses-sdk android:minSdkVersion="$(ANDROID_API_VERSION)" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<uses-feature android:glEsVersion="0x00020000" android:required="true" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<application android:allowBackup="false" android:label="@string/app_name" android:icon="@drawable/icon" ^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<activity android:name="com.$(APP_COMPANY_NAME).$(APP_PRODUCT_NAME).NativeLoader" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo android:theme="@android:style/Theme.NoTitleBar.Fullscreen" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo android:configChanges="orientation|keyboardHidden|screenSize" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo android:screenOrientation="$(APP_SCREEN_ORIENTATION)" android:launchMode="singleTask" >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo android:clearTaskOnLaunch="true"^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<meta-data android:name="android.app.lib_name" android:value="$(PROJECT_LIBRARY_NAME)" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<intent-filter^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<action android:name="android.intent.action.MAIN" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^<category android:name="android.intent.category.LAUNCHER" /^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^</intent-filter^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^</activity^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^</application^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
@echo ^</manifest^> >> $(PROJECT_BUILD_PATH)/AndroidManifest.xml
# Generate storekey for APK signing: $(PROJECT_NAME).keystore
# NOTE: Configure here your Distinguished Names (-dname) if required!
generate_apk_keystore:
if not exist $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore $(JAVA_HOME)/bin/keytool -genkeypair -validity 1000 -dname "CN=$(APP_COMPANY_NAME),O=Android,C=ES" -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -alias $(PROJECT_NAME)Key -keyalg RSA
# Config project package and resource using AndroidManifest.xml and res/values/strings.xml
# NOTE: Generates resources file: src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java
config_project_package:
$(ANDROID_BUILD_TOOLS)/aapt package -f -m -S $(PROJECT_BUILD_PATH)/res -J $(PROJECT_BUILD_PATH)/src -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -I $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar
# Compile native_app_glue code as static library: obj/libnative_app_glue.a
compile_native_app_glue:
$(CC) -c $(RAYLIB_PATH)/src/external/android/native_app_glue/android_native_app_glue.c -o $(PROJECT_BUILD_PATH)/obj/native_app_glue.o $(CFLAGS)
$(AR) rcs $(PROJECT_BUILD_PATH)/obj/libnative_app_glue.a $(PROJECT_BUILD_PATH)/obj/native_app_glue.o
# Compile project code into a shared library: lib/lib$(PROJECT_LIBRARY_NAME).so
compile_project_code: $(OBJS)
$(CC) -o $(PROJECT_BUILD_PATH)/lib/$(ANDROID_ARCH_NAME)/lib$(PROJECT_LIBRARY_NAME).so $(OBJS) -shared $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS)
# Compile all .c files required into object (.o) files
# NOTE: Those files will be linked into a shared library
$(PROJECT_BUILD_PATH)/obj/%.o:%.c
$(CC) -c $^ -o $@ $(INCLUDE_PATHS) $(CFLAGS) --sysroot=$(ANDROID_TOOLCHAIN)/sysroot
# Compile project .java code into .class (Java bytecode)
compile_project_class:
$(JAVA_HOME)/bin/javac -verbose -source 1.7 -target 1.7 -d $(PROJECT_BUILD_PATH)/obj -bootclasspath $(JAVA_HOME)/jre/lib/rt.jar -classpath $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar;$(PROJECT_BUILD_PATH)/obj -sourcepath $(PROJECT_BUILD_PATH)/src $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/R.java $(PROJECT_BUILD_PATH)/src/com/$(APP_COMPANY_NAME)/$(APP_PRODUCT_NAME)/NativeLoader.java
# Compile .class files into Dalvik executable bytecode (.dex)
# NOTE: Since Android 5.0, Dalvik interpreter (JIT) has been replaced by ART (AOT)
compile_project_class_dex:
$(ANDROID_BUILD_TOOLS)/dx --verbose --dex --output=$(PROJECT_BUILD_PATH)/bin/classes.dex $(PROJECT_BUILD_PATH)/obj
# Create Android APK package: bin/$(PROJECT_NAME).unsigned.apk
# NOTE: Requires compiled classes.dex and lib$(PROJECT_LIBRARY_NAME).so
# NOTE: Use -A resources to define additional directory in which to find raw asset files
create_project_apk_package:
$(ANDROID_BUILD_TOOLS)/aapt package -f -M $(PROJECT_BUILD_PATH)/AndroidManifest.xml -S $(PROJECT_BUILD_PATH)/res -A $(PROJECT_BUILD_PATH)/assets -I $(ANDROID_HOME)/platforms/android-$(ANDROID_API_VERSION)/android.jar -F $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_BUILD_PATH)/bin
cd $(PROJECT_BUILD_PATH) && $(ANDROID_BUILD_TOOLS)/aapt add bin/$(PROJECT_NAME).unsigned.apk lib/$(ANDROID_ARCH_NAME)/lib$(PROJECT_LIBRARY_NAME).so $(PROJECT_SHARED_LIBS)
# Create signed APK package using generated Key: bin/$(PROJECT_NAME).signed.apk
sign_project_apk_package:
$(JAVA_HOME)/bin/jarsigner -keystore $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore -storepass $(APP_KEYSTORE_PASS) -keypass $(APP_KEYSTORE_PASS) -signedjar $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).unsigned.apk $(PROJECT_NAME)Key
# Create zip-aligned APK package: $(PROJECT_NAME).apk
zipalign_project_apk_package:
$(ANDROID_BUILD_TOOLS)/zipalign -f 4 $(PROJECT_BUILD_PATH)/bin/$(PROJECT_NAME).signed.apk $(PROJECT_NAME).apk
# Install $(PROJECT_NAME).apk to default emulator/device
# NOTE: Use -e (emulator) or -d (device) parameters if required
install:
$(ANDROID_PLATFORM_TOOLS)/adb install --abi $(ANDROID_ARCH_NAME) -rds $(PROJECT_NAME).apk
# Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
check_device_abi:
$(ANDROID_PLATFORM_TOOLS)/adb shell getprop ro.product.cpu.abi
# Monitorize output log coming from device, only raylib tag
logcat:
$(ANDROID_PLATFORM_TOOLS)/adb logcat -c
$(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
# Install and monitorize $(PROJECT_NAME).apk to default emulator/device
deploy:
$(ANDROID_PLATFORM_TOOLS)/adb install -r $(PROJECT_NAME).apk
$(ANDROID_PLATFORM_TOOLS)/adb logcat -c
$(ANDROID_PLATFORM_TOOLS)/adb logcat raylib:V *:S
#$(ANDROID_PLATFORM_TOOLS)/adb logcat *:W
# Clean everything
clean:
del $(PROJECT_BUILD_PATH)\* /f /s /q
rmdir $(PROJECT_BUILD_PATH) /s /q
@echo Cleaning done

View File

@ -1,40 +0,0 @@
#include <math.h>
#include "raylib.h"
int main()
{
int screenWidth = 800;
int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib");
Camera cam;
cam.position = (Vector3){ 0.0f, 10.0f, 8.f };
cam.target = (Vector3){ 0.0f, 0.0f, 0.0f };
cam.up = (Vector3){ 0.0f, 1.f, 0.0f };
cam.fovy = 60.0f;
Vector3 cubePos = { 0.0f, 0.0f, 0.0f };
SetTargetFPS(60);
while (!WindowShouldClose())
{
cam.position.x = sin(GetTime())*10.0f;
cam.position.z = cos(GetTime())*10.0f;
BeginDrawing();
ClearBackground(RAYWHITE);
BeginMode3D(cam);
DrawCube(cubePos, 2.f, 2.f, 2.f, RED);
DrawCubeWires(cubePos, 2.f, 2.f, 2.f, MAROON);
DrawGrid(10, 1.f);
EndMode3D();
DrawText("This is a raylib example", 10, 40, 20, DARKGRAY);
DrawFPS(10, 10);
EndDrawing();
}
CloseWindow();
return 0;
}

View File

@ -1,54 +0,0 @@
version(1);
project_name = "raylib-example";
patterns = {
"*.cpp",
"*.c",
"*.h",
"*.bat",
"*.sh",
"*.4coder",
"Makefile",
};
blacklist_patterns = {
".*",
};
load_paths = {
{ { {".", .relative = true, .recursive = true, } }, .os = "win" },
{ { {".", .relative = true, .recursive = true, } }, .os = "linux" },
{ { {".", .relative = true, .recursive = true, } }, .os = "mac" },
};
command_list = {
{ .name = "clean",
.out = "*clean*", .footer_panel = true, .save_dirty_files = false, .cursor_at_end = true,
.cmd = {
{"mingw32-make clean", .os = "win"},
{"make clean", .os = "linux"},
{"make clean", .os = "mac"},
},
},
{ .name = "build",
.out = "*compile*", .footer_panel = true, .save_dirty_files = true, .cursor_at_end = false,
.cmd = {
{"mingw32-make", .os = "win"},
{"make", .os = "linux"},
{"make", .os = "mac"},
},
},
{ .name = "run",
.out = "*run*", .footer_panel = true, .save_dirty_files = false, .cursor_at_end = true,
.cmd = {
{".\game.exe", .os = "win"},
{"./game", .os = "linux"},
{"./game", .os = "mac"},
},
},
};
fkey_command[3] = "clean";
fkey_command[4] = "build";
fkey_command[5] = "run";

View File

@ -4,15 +4,14 @@ This folder contains raylib templates for some common IDEs.
IDE | Platform(s) | Source | Example(s) IDE | Platform(s) | Source | Example(s)
----| ------------| :-------: | :-----: ----| ------------| :-------: | :-----:
[4coder](http://4coder.net/) | Windows | ❌ | ✔️
[Builder](https://wiki.gnome.org/Apps/Builder) | Linux | ❌ | ✔️ [Builder](https://wiki.gnome.org/Apps/Builder) | Linux | ❌ | ✔️
[CMake](https://cmake.org/) | Windows, Linux, macOS, Web | ✔️ | ✔️ [CMake](https://cmake.org/) | Windows, Linux, macOS, Web | ✔️ | ✔️
[CodeBlocks](http://www.codeblocks.org/) | Windows, Linux, macOS | ❌ | ✔️ [CodeBlocks](http://www.codeblocks.org/) | Windows, Linux, macOS | ❌ | ✔️
[Geany](https://www.geany.org/) | Windows, Linux | ✔️ | ✔️ [Geany](https://www.geany.org/) | Windows, Linux | ✔️ | ✔️
[Notepad++](https://notepad-plus-plus.org/) | Windows | ✔️ | ✔️ [Notepad++](https://notepad-plus-plus.org/) | Windows, Web | ✔️ | ✔️
[SublimeText](https://www.sublimetext.com/) | Windows, Linux, macOS | ✔️ | ✔️ [SublimeText](https://www.sublimetext.com/) | Windows, Linux, macOS | ✔️ | ✔️
[VS2019](https://www.visualstudio.com) | Windows | ✔️ | ✔️ [VS2022](https://www.visualstudio.com) | Windows | ✔️ | ✔️
[VSCode](https://code.visualstudio.com/) | Windows, macOS | ❌ | ✔️ [VSCode](https://code.visualstudio.com/) | Windows, Linux, macOS | ❌ | ✔️
[Zig](https://ziglang.org) | Windows, Linux, macOS, Web | ✔️ | ✔️ [Zig](https://ziglang.org) | Windows, Linux, macOS, Web | ✔️ | ✔️
scripts | Windows, Linux, macOS | ✔️ | ✔️ scripts | Windows, Linux, macOS | ✔️ | ✔️

View File

@ -1,75 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31702.278
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "raylib_android", "raylib_android", "{5C24BC76-8848-40EA-9BBB-A544648D8D5B}"
EndProject
Project("{39E2626F-3545-4960-A6E8-258AD8476CE5}") = "raylib_android.Packaging", "raylib_android\raylib_android.Packaging\raylib_android.Packaging.androidproj", "{B2231F0D-52DA-4C55-8998-5886F766553C}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "raylib_android.NativeActivity", "raylib_android\raylib_android.NativeActivity\raylib_android.NativeActivity.vcxproj", "{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.ActiveCfg = Debug|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Build.0 = Debug|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM.Deploy.0 = Debug|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Build.0 = Debug|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|ARM64.Deploy.0 = Debug|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.ActiveCfg = Debug|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Build.0 = Debug|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x64.Deploy.0 = Debug|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.ActiveCfg = Debug|x86
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Build.0 = Debug|x86
{B2231F0D-52DA-4C55-8998-5886F766553C}.Debug|x86.Deploy.0 = Debug|x86
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.ActiveCfg = Release|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Build.0 = Release|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM.Deploy.0 = Release|ARM
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.ActiveCfg = Release|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Build.0 = Release|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|ARM64.Deploy.0 = Release|ARM64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.ActiveCfg = Release|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Build.0 = Release|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x64.Deploy.0 = Release|x64
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.ActiveCfg = Release|x86
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Build.0 = Release|x86
{B2231F0D-52DA-4C55-8998-5886F766553C}.Release|x86.Deploy.0 = Release|x86
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.ActiveCfg = Debug|ARM
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM.Build.0 = Debug|ARM
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|ARM64.Build.0 = Debug|ARM64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.ActiveCfg = Debug|x64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x64.Build.0 = Debug|x64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.ActiveCfg = Debug|x86
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Debug|x86.Build.0 = Debug|x86
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.ActiveCfg = Release|ARM
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM.Build.0 = Release|ARM
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.ActiveCfg = Release|ARM64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|ARM64.Build.0 = Release|ARM64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.ActiveCfg = Release|x64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x64.Build.0 = Release|x64
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.ActiveCfg = Release|x86
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{B2231F0D-52DA-4C55-8998-5886F766553C} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B}
{BFB31759-4FCA-4503-BC7C-A97F705EFDB2} = {5C24BC76-8848-40EA-9BBB-A544648D8D5B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B7ED0AA6-6B00-40AC-BF71-526D5BEEFC78}
EndGlobalSection
EndGlobal

View File

@ -1,437 +0,0 @@
/*
* Copyright (C) 2010 The Android Open Source Project
*
* лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия");
*этот файл можно использовать только в соответствии с лицензией.
*Копию лицензии можно получить на веб-сайте
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ",
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых.
* См. лицензию для получения информации об определенных разрешениях по использованию языка и
* ограничениях в рамках лицензии.
*
*/
#include <jni.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/resource.h>
#include "android_native_app_glue.h"
#include <android/log.h>
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "threaded_app", __VA_ARGS__))
#define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR, "threaded_app", __VA_ARGS__))
/* Для отладочных построений необходимо всегда включать трассировку отладки в этой библиотеке*/
#ifndef NDEBUG
# define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, "threaded_app", __VA_ARGS__))
#else
# define LOGV(...) ((void)0)
#endif
static void free_saved_state(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->savedState != NULL) {
free(android_app->savedState);
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
}
int8_t android_app_read_cmd(struct android_app* android_app) {
int8_t cmd;
if (read(android_app->msgread, &cmd, sizeof(cmd)) == sizeof(cmd)) {
switch (cmd) {
case APP_CMD_SAVE_STATE:
free_saved_state(android_app);
break;
}
return cmd;
} else {
LOGE("No data on command pipe!");
}
return -1;
}
static void print_cur_config(struct android_app* android_app) {
char lang[2], country[2];
AConfiguration_getLanguage(android_app->config, lang);
AConfiguration_getCountry(android_app->config, country);
LOGV("Config: mcc=%d mnc=%d lang=%c%c cnt=%c%c orien=%d touch=%d dens=%d "
"keys=%d nav=%d keysHid=%d navHid=%d sdk=%d size=%d long=%d "
"modetype=%d modenight=%d",
AConfiguration_getMcc(android_app->config),
AConfiguration_getMnc(android_app->config),
lang[0], lang[1], country[0], country[1],
AConfiguration_getOrientation(android_app->config),
AConfiguration_getTouchscreen(android_app->config),
AConfiguration_getDensity(android_app->config),
AConfiguration_getKeyboard(android_app->config),
AConfiguration_getNavigation(android_app->config),
AConfiguration_getKeysHidden(android_app->config),
AConfiguration_getNavHidden(android_app->config),
AConfiguration_getSdkVersion(android_app->config),
AConfiguration_getScreenSize(android_app->config),
AConfiguration_getScreenLong(android_app->config),
AConfiguration_getUiModeType(android_app->config),
AConfiguration_getUiModeNight(android_app->config));
}
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_INPUT_CHANGED:
LOGV("APP_CMD_INPUT_CHANGED\n");
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
android_app->inputQueue = android_app->pendingInputQueue;
if (android_app->inputQueue != NULL) {
LOGV("Attaching input queue to looper");
AInputQueue_attachLooper(android_app->inputQueue,
android_app->looper, LOOPER_ID_INPUT, NULL,
&android_app->inputPollSource);
}
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_INIT_WINDOW:
LOGV("APP_CMD_INIT_WINDOW\n");
pthread_mutex_lock(&android_app->mutex);
android_app->window = android_app->pendingWindow;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_TERM_WINDOW:
LOGV("APP_CMD_TERM_WINDOW\n");
pthread_cond_broadcast(&android_app->cond);
break;
case APP_CMD_RESUME:
case APP_CMD_START:
case APP_CMD_PAUSE:
case APP_CMD_STOP:
LOGV("activityState=%d\n", cmd);
pthread_mutex_lock(&android_app->mutex);
android_app->activityState = cmd;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_CONFIG_CHANGED:
LOGV("APP_CMD_CONFIG_CHANGED\n");
AConfiguration_fromAssetManager(android_app->config,
android_app->activity->assetManager);
print_cur_config(android_app);
break;
case APP_CMD_DESTROY:
LOGV("APP_CMD_DESTROY\n");
android_app->destroyRequested = 1;
break;
}
}
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd) {
switch (cmd) {
case APP_CMD_TERM_WINDOW:
LOGV("APP_CMD_TERM_WINDOW\n");
pthread_mutex_lock(&android_app->mutex);
android_app->window = NULL;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_SAVE_STATE:
LOGV("APP_CMD_SAVE_STATE\n");
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
break;
case APP_CMD_RESUME:
free_saved_state(android_app);
break;
}
}
static void android_app_destroy(struct android_app* android_app) {
LOGV("android_app_destroy!");
free_saved_state(android_app);
pthread_mutex_lock(&android_app->mutex);
if (android_app->inputQueue != NULL) {
AInputQueue_detachLooper(android_app->inputQueue);
}
AConfiguration_delete(android_app->config);
android_app->destroyed = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
// После этого нельзя изменять объект android_app.
}
static void process_input(struct android_app* app, struct android_poll_source* source) {
AInputEvent* event = NULL;
while (AInputQueue_getEvent(app->inputQueue, &event) >= 0) {
LOGV("New input event: type=%d\n", AInputEvent_getType(event));
if (AInputQueue_preDispatchEvent(app->inputQueue, event)) {
continue;
}
int32_t handled = 0;
if (app->onInputEvent != NULL) handled = app->onInputEvent(app, event);
AInputQueue_finishEvent(app->inputQueue, event, handled);
}
}
static void process_cmd(struct android_app* app, struct android_poll_source* source) {
int8_t cmd = android_app_read_cmd(app);
android_app_pre_exec_cmd(app, cmd);
if (app->onAppCmd != NULL) app->onAppCmd(app, cmd);
android_app_post_exec_cmd(app, cmd);
}
static void* android_app_entry(void* param) {
struct android_app* android_app = (struct android_app*)param;
android_app->config = AConfiguration_new();
AConfiguration_fromAssetManager(android_app->config, android_app->activity->assetManager);
print_cur_config(android_app);
android_app->cmdPollSource.id = LOOPER_ID_MAIN;
android_app->cmdPollSource.app = android_app;
android_app->cmdPollSource.process = process_cmd;
android_app->inputPollSource.id = LOOPER_ID_INPUT;
android_app->inputPollSource.app = android_app;
android_app->inputPollSource.process = process_input;
ALooper* looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
ALooper_addFd(looper, android_app->msgread, LOOPER_ID_MAIN, ALOOPER_EVENT_INPUT, NULL,
&android_app->cmdPollSource);
android_app->looper = looper;
pthread_mutex_lock(&android_app->mutex);
android_app->running = 1;
pthread_cond_broadcast(&android_app->cond);
pthread_mutex_unlock(&android_app->mutex);
android_main(android_app);
android_app_destroy(android_app);
return NULL;
}
// --------------------------------------------------------------------
// Взаимодействие NativeАctivity (вызванное из основного потока)
// --------------------------------------------------------------------
static struct android_app* android_app_create(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
struct android_app* android_app = (struct android_app*)malloc(sizeof(struct android_app));
memset(android_app, 0, sizeof(struct android_app));
android_app->activity = activity;
pthread_mutex_init(&android_app->mutex, NULL);
pthread_cond_init(&android_app->cond, NULL);
if (savedState != NULL) {
android_app->savedState = malloc(savedStateSize);
android_app->savedStateSize = savedStateSize;
memcpy(android_app->savedState, savedState, savedStateSize);
}
int msgpipe[2];
if (pipe(msgpipe)) {
LOGE("could not create pipe: %s", strerror(errno));
return NULL;
}
android_app->msgread = msgpipe[0];
android_app->msgwrite = msgpipe[1];
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
pthread_create(&android_app->thread, &attr, android_app_entry, android_app);
// Дождитесь запуска потока.
pthread_mutex_lock(&android_app->mutex);
while (!android_app->running) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
return android_app;
}
static void android_app_write_cmd(struct android_app* android_app, int8_t cmd) {
if (write(android_app->msgwrite, &cmd, sizeof(cmd)) != sizeof(cmd)) {
LOGE("Failure writing android_app cmd: %s\n", strerror(errno));
}
}
static void android_app_set_input(struct android_app* android_app, AInputQueue* inputQueue) {
pthread_mutex_lock(&android_app->mutex);
android_app->pendingInputQueue = inputQueue;
android_app_write_cmd(android_app, APP_CMD_INPUT_CHANGED);
while (android_app->inputQueue != android_app->pendingInputQueue) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_window(struct android_app* android_app, ANativeWindow* window) {
pthread_mutex_lock(&android_app->mutex);
if (android_app->pendingWindow != NULL) {
android_app_write_cmd(android_app, APP_CMD_TERM_WINDOW);
}
android_app->pendingWindow = window;
if (window != NULL) {
android_app_write_cmd(android_app, APP_CMD_INIT_WINDOW);
}
while (android_app->window != android_app->pendingWindow) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_set_activity_state(struct android_app* android_app, int8_t cmd) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, cmd);
while (android_app->activityState != cmd) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
}
static void android_app_free(struct android_app* android_app) {
pthread_mutex_lock(&android_app->mutex);
android_app_write_cmd(android_app, APP_CMD_DESTROY);
while (!android_app->destroyed) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
pthread_mutex_unlock(&android_app->mutex);
close(android_app->msgread);
close(android_app->msgwrite);
pthread_cond_destroy(&android_app->cond);
pthread_mutex_destroy(&android_app->mutex);
free(android_app);
}
static void onDestroy(ANativeActivity* activity) {
LOGV("Destroy: %p\n", activity);
android_app_free((struct android_app*)activity->instance);
}
static void onStart(ANativeActivity* activity) {
LOGV("Start: %p\n", activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_START);
}
static void onResume(ANativeActivity* activity) {
LOGV("Resume: %p\n", activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_RESUME);
}
static void* onSaveInstanceState(ANativeActivity* activity, size_t* outLen) {
struct android_app* android_app = (struct android_app*)activity->instance;
void* savedState = NULL;
LOGV("SaveInstanceState: %p\n", activity);
pthread_mutex_lock(&android_app->mutex);
android_app->stateSaved = 0;
android_app_write_cmd(android_app, APP_CMD_SAVE_STATE);
while (!android_app->stateSaved) {
pthread_cond_wait(&android_app->cond, &android_app->mutex);
}
if (android_app->savedState != NULL) {
savedState = android_app->savedState;
*outLen = android_app->savedStateSize;
android_app->savedState = NULL;
android_app->savedStateSize = 0;
}
pthread_mutex_unlock(&android_app->mutex);
return savedState;
}
static void onPause(ANativeActivity* activity) {
LOGV("Pause: %p\n", activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_PAUSE);
}
static void onStop(ANativeActivity* activity) {
LOGV("Stop: %p\n", activity);
android_app_set_activity_state((struct android_app*)activity->instance, APP_CMD_STOP);
}
static void onConfigurationChanged(ANativeActivity* activity) {
struct android_app* android_app = (struct android_app*)activity->instance;
LOGV("ConfigurationChanged: %p\n", activity);
android_app_write_cmd(android_app, APP_CMD_CONFIG_CHANGED);
}
static void onLowMemory(ANativeActivity* activity) {
struct android_app* android_app = (struct android_app*)activity->instance;
LOGV("LowMemory: %p\n", activity);
android_app_write_cmd(android_app, APP_CMD_LOW_MEMORY);
}
static void onWindowFocusChanged(ANativeActivity* activity, int focused) {
LOGV("WindowFocusChanged: %p -- %d\n", activity, focused);
android_app_write_cmd((struct android_app*)activity->instance,
focused ? APP_CMD_GAINED_FOCUS : APP_CMD_LOST_FOCUS);
}
static void onNativeWindowCreated(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowCreated: %p -- %p\n", activity, window);
android_app_set_window((struct android_app*)activity->instance, window);
}
static void onNativeWindowDestroyed(ANativeActivity* activity, ANativeWindow* window) {
LOGV("NativeWindowDestroyed: %p -- %p\n", activity, window);
android_app_set_window((struct android_app*)activity->instance, NULL);
}
static void onInputQueueCreated(ANativeActivity* activity, AInputQueue* queue) {
LOGV("InputQueueCreated: %p -- %p\n", activity, queue);
android_app_set_input((struct android_app*)activity->instance, queue);
}
static void onInputQueueDestroyed(ANativeActivity* activity, AInputQueue* queue) {
LOGV("InputQueueDestroyed: %p -- %p\n", activity, queue);
android_app_set_input((struct android_app*)activity->instance, NULL);
}
void ANativeActivity_onCreate(ANativeActivity* activity,
void* savedState, size_t savedStateSize) {
LOGV("Creating: %p\n", activity);
activity->callbacks->onDestroy = onDestroy;
activity->callbacks->onStart = onStart;
activity->callbacks->onResume = onResume;
activity->callbacks->onSaveInstanceState = onSaveInstanceState;
activity->callbacks->onPause = onPause;
activity->callbacks->onStop = onStop;
activity->callbacks->onConfigurationChanged = onConfigurationChanged;
activity->callbacks->onLowMemory = onLowMemory;
activity->callbacks->onWindowFocusChanged = onWindowFocusChanged;
activity->callbacks->onNativeWindowCreated = onNativeWindowCreated;
activity->callbacks->onNativeWindowDestroyed = onNativeWindowDestroyed;
activity->callbacks->onInputQueueCreated = onInputQueueCreated;
activity->callbacks->onInputQueueDestroyed = onInputQueueDestroyed;
activity->instance = android_app_create(activity, savedState, savedStateSize);
}

View File

@ -1,344 +0,0 @@
/*
* © 2010 The Android Open Source Project
*
* Лицензировано по лицензии Apache License, версия 2.0 ( "Лицензия");
*этот файл можно использовать только в соответствии с лицензией.
*Копию лицензии можно получить на веб-сайте
*
* http://www.apache.org/licenses/LICENSE-2.0
*
*Если только не требуется в соответствии с применимым законодательством или согласовано в письменном виде, программное обеспечение
* распространяется в рамках лицензии на УСЛОВИЯХ "КАК ЕСТЬ",
* БЕЗ ГАРАНТИЙ И УСЛОВИЙ ЛЮБОГО РОДА, явно выраженных и подразумеваемых.
* См. лицензию для получения информации об определенных разрешениях по использованию языка и
* ограничениях в рамках лицензии.
*
*/
#ifndef _ANDROID_NATIVE_APP_GLUE_H
#define _ANDROID_NATIVE_APP_GLUE_H
#include <poll.h>
#include <pthread.h>
#include <sched.h>
#include <android/configuration.h>
#include <android/looper.h>
#include <android/native_activity.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* Интерфейс NativeActivity, предоставленный <android/native_activity.h>,
* основан на наборе предоставленных приложением обратных вызовов, которые вызываются
*основным потоком действия при возникновении определенных событий.
*
* Это означает, что ни один из данных обратных вызовов _не_ _должен_ блокироваться, иначе
* существует риск принудительного закрытия приложения системой. Эта модель программирования
* прямая, простая, но имеет ограничения.
*
* Статическая библиотека threaded_native_app используется для обеспечения другой
* модели выполнения, в которой приложение может реализовать свой собственный цикл главного события
* в другом потоке вместо этого. Это работает так:
*
* 1/ Приложение должно предоставить функцию с именем android_main(), которая
* будет вызываться при создании действия в новом потоке,
* отличающемся от основного потока действия.
*
* 2/ android_main() получает указатель на допустимую структуру android_app,
* которая содержит ссылки на другие важные объекты, например экземпляр объекта
* ANativeActivity, где выполняется приложение.
*
* 3/ Объект android_app содержит экземпляр ALooper, который уже
* ожидает две важных вещи:
*
* - событий жизненного цикла действия (например, "pause", "resume"). См. объявления APP_CMD_XXX
* ниже.
*
* - входных событий, поступающих из очереди AInputQueue, присоединенной к действию.
*
* Каждое из этих событий соответствует идентификатору ALooper, возвращенному
* ALooper_pollOnce со значениями LOOPER_ID_MAIN и LOOPER_ID_INPUT,
*, соответственно.
*
* Ваше приложение может использовать тот же ALooper для прослушивания дополнительных
* дескрипторов файла. Они могут быть основаны либо на обратных вызовах, либо поступают с идентификаторами возврата,
* начинающимися с LOOPER_ID_USER.
*
* 4/ При получении события LOOPER_ID_MAIN или LOOPER_ID_INPUT
* возвращенные данные будут указывать на структуру android_poll_source. Для нее
* можно вызвать функцию process() и заполнить android_app->onAppCmd
* и android_app->onInputEvent, для того чтобы они вызывались для вашей собственной обработки
* события.
*
* Вместо этого можно вызвать функции нижнего уровня для чтения и обработки
* данных непосредственно... посмотрите на реализации process_cmd() и process_input()
* в приклеивании, чтобы выяснить, как это делается.
*
* См. пример "native-activity" в NDK с
* полной демонстрацией использования. Также посмотрите JavaDoc в NativeActivity.
*/
struct android_app;
/**
* Данные, связанные с ALooper fd, которые будут возвращаться как outData
* при готовности данных в этом источнике.
*/
struct android_poll_source {
// Идентификатор данного источника. Может быть LOOPER_ID_MAIN или
// LOOPER_ID_INPUT.
int32_t id;
// android_app, с которым связан данный идентификатор.
struct android_app* app;
// Функция, вызываемая для стандартной обработки данных из
// этого источника.
void (*process)(struct android_app* app, struct android_poll_source* source);
};
/**
* Это интерфейс стандартного кода приклеивания поточного
* приложения. В этой модели код приложения выполняется
* в своем собственном потоке, отдельном от основного потока процесса.
* Не требуется связь данного потока с ВМ Java
*, хотя это необходимо для выполнения вызовов JNI любых
* объектов Java.
*/
struct android_app {
// Приложение может поместить указатель на свой собственный объект состояния
// здесь, если нужно.
void* userData;
// Введите здесь код функции для обработки основных команд приложения (APP_CMD_*)
void (*onAppCmd)(struct android_app* app, int32_t cmd);
// Введите здесь код функции для обработки входных событий. Сейчас
// событие уже было предварительно отправлено и будет завершено при
// возврате. Верните 1, если событие обработано, 0 — для любой диспетчеризации
// по умолчанию.
int32_t (*onInputEvent)(struct android_app* app, AInputEvent* event);
// Экземпляр объекта ANativeActivity, в котором выполняется это приложение.
ANativeActivity* activity;
// Текущая конфигурация, в которой выполняется это приложение.
AConfiguration* config;
// Это последнее сохраненное состояние экземпляра, предоставленное во время создания.
// Значение равно NULL, если состояния не было. Можно использовать это по мере необходимости;
// память останется доступной до вызова android_app_exec_cmd() для
// APP_CMD_RESUME, после чего она будет освобождена, а savedState получит значение NULL.
// Эти переменные необходимо изменять только при обработке APP_CMD_SAVE_STATE,
// когда их значения будут инициализироваться в NULL и можно будет выполнить malloc для
// состояния и поместить здесь информацию. В этом случае память будет
// освобождена позднее.
void* savedState;
size_t savedStateSize;
// ALooper, связанный с потоком приложения.
ALooper* looper;
// Если значение не равно NULL, то это входная очередь, из которой приложение будет
// получать входные события пользователя.
AInputQueue* inputQueue;
// Если значение не равно NULL, то это поверхность окна, в котором приложение может рисовать.
ANativeWindow* window;
// Текущий прямоугольник содержимого окна. Это область, в которой
// должно помещаться содержимое окна, чтобы его видел пользователь.
ARect contentRect;
// Текущее состояние действия приложения. Может быть APP_CMD_START,
// APP_CMD_RESUME, APP_CMD_PAUSE или APP_CMD_STOP; см. ниже.
int activityState;
// Значение не равно нулю, когда NativeActivity приложения
// разрушается и ожидает завершения потока приложения.
int destroyRequested;
// -------------------------------------------------
// Ниже показан "частная" реализация кода прилипания.
pthread_mutex_t mutex;
pthread_cond_t cond;
int msgread;
int msgwrite;
pthread_t thread;
struct android_poll_source cmdPollSource;
struct android_poll_source inputPollSource;
int running;
int stateSaved;
int destroyed;
int redrawNeeded;
AInputQueue* pendingInputQueue;
ANativeWindow* pendingWindow;
ARect pendingContentRect;
};
enum {
/**
* Идентификатор данных Looper команд, поступающих из основного потока приложения, который
* возвращается как идентификатор от ALooper_pollOnce(). Данные для этого идентификатора
* являются указателем на структуру android_poll_source.
* Их можно извлечь и обработать с помощью android_app_read_cmd()
* и android_app_exec_cmd().
*/
LOOPER_ID_MAIN = 1,
/**
* Идентификатор данных Looper событий, поступающий из AInputQueue окна
* приложения, который возвращается как идентификатор из
* ALooper_pollOnce(). Данные этого идентификатора являются указателем на структуру
* android_poll_source. Их можно прочитать через объект inputQueue
* приложения android_app.
*/
LOOPER_ID_INPUT = 2,
/**
* Запуск определяемых пользователем идентификаторов ALooper.
*/
LOOPER_ID_USER = 3,
};
enum {
/**
* Команда из основного потока: AInputQueue изменена. После обработки
* этой команды android_app->inputQueue будет обновлена в новую очередь
* (или NULL).
*/
APP_CMD_INPUT_CHANGED,
/**
* Команда из основного потока: новое окно ANativeWindow готово к использованию. После
* получения этой команды окно android_app-> будет содержать новую поверхность
*окна.
*/
APP_CMD_INIT_WINDOW,
/**
* Команда из основного потока: существующее окно ANativeWindow необходимо
* прекратить. После получения этой команды окно android_app->по-прежнему
* содержит существующее окно; после вызова android_app_exec_cmd
* оно получит значение NULL.
*/
APP_CMD_TERM_WINDOW,
/**
* Команда из основного потока: текущее окно ANativeWindow изменило размер.
* Перерисуйте согласно новом размеру.
*/
APP_CMD_WINDOW_RESIZED,
/**
* Команда из основного потока: системе необходимо, чтобы текущее окно ANativeWindow
* было перерисовано. Необходимо перерисовать окно перед ее передачей в
* android_app_exec_cmd(), чтобы избежать переходных сбоев рисования.
*/
APP_CMD_WINDOW_REDRAW_NEEDED,
/**
* Команда из основного потока: область содержимого окна изменена
* таким образом, что из функционального ввода окно показывается или скрывается. Можно
* найти новый прямоугольник содержимого в android_app::contentRect.
*/
APP_CMD_CONTENT_RECT_CHANGED,
/**
* Команда из основного потока: окно действия приложения получило
* фокус ввода.
*/
APP_CMD_GAINED_FOCUS,
/**
* Команда из основного потока: окно действия приложения потеряло
* фокус ввода.
*/
APP_CMD_LOST_FOCUS,
/**
* Команда из основного потока: изменена текущая конфигурация устройства.
*/
APP_CMD_CONFIG_CHANGED,
/**
* Команда из основного потока: системе не хватает памяти.
* Попробуйте уменьшить использование памяти.
*/
APP_CMD_LOW_MEMORY,
/**
* Команда из основного потока: действие приложения было запущено.
*/
APP_CMD_START,
/**
* Команда из основного потока: действие приложения было возобновлено.
*/
APP_CMD_RESUME,
/**
* Команда из основного потока: приложение должно создать новое сохраненное состояние
* для себя, чтобы восстанавливаться из него позднее в случае необходимости. Если вы сохранили состояние,
* выделите его с использованием malloc и поместите в android_app.savedState с
* размером android_app.savedStateSize. Память будет освобождена
* позднее.
*/
APP_CMD_SAVE_STATE,
/**
* Команда из основного потока: пауза в действии приложения.
*/
APP_CMD_PAUSE,
/**
* Команда из основного потока: действие приложения было остановлено.
*/
APP_CMD_STOP,
/**
* Команда из основного потока: действие приложения уничтожается,
* и ожидает очистки потока приложения и выхода перед обработкой.
*/
APP_CMD_DESTROY,
};
/**
* Вызовите, когда ALooper_pollAll() возвращает LOOPER_ID_MAIN, при чтении следующего сообщения команды
*приложения.
*/
int8_t android_app_read_cmd(struct android_app* android_app);
/**
* Вызовите с помощью команды, возвращенной android_app_read_cmd() для выполнения
* начальной предварительной обработки данной команды. Можно выполнить собственные
* действия для команды после вызова этой функции.
*/
void android_app_pre_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Вызовите с помощью команды, возвращенной android_app_read_cmd(), для
* окончательной предварительной обработки данной команды. Необходимо завершить собственные
* действия с командой до вызова этой функции.
*/
void android_app_post_exec_cmd(struct android_app* android_app, int8_t cmd);
/**
* Это функция, которую должен реализовать код приложения, представляет собой
* главный вход в приложение.
*/
extern void android_main(struct android_app* app);
#ifdef __cplusplus
}
#endif
#endif /* _ANDROID_NATIVE_APP_GLUE_H */

View File

@ -1,64 +0,0 @@
/*******************************************************************************************
*
* raylib [core] example - Basic window
*
* This example has been created using raylib 3.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by <user_name> (@<user_github>) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2021 <user_name> (@<user_github>)
* Adapt for Visual Studio: Vadim Boev (Kronka Dev)
*
********************************************************************************************/
#include "android_native_app_glue.h"
#include "../../../../src/raylib.h"
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window");
// TODO: Load resources / Initialize variables at this point
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// TODO: Update variables / Implement example logic at this point
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// TODO: Draw everything that requires to be drawn at this point:
DrawText("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); // Example
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// TODO: Unload all loaded resources at this point
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,226 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{bfb31759-4fca-4503-bc7c-a97f705efdb2}</ProjectGuid>
<Keyword>Android</Keyword>
<RootNamespace>raylib_android</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<ApplicationType>Android</ApplicationType>
<ApplicationTypeRevision>3.0</ApplicationTypeRevision>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
<AndroidAPILevel>android-29</AndroidAPILevel>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>Clang_5_0</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<TargetName>libmain</TargetName>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsC</CompileAs>
<CLanguageStandard>c99</CLanguageStandard>
<CppLanguageStandard>Default</CppLanguageStandard>
<PrecompiledHeaderCompileAs>CompileAsC</PrecompiledHeaderCompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);EGL;GLESv2;log;android;c;m;raylib</LibraryDependencies>
<AdditionalLibraryDirectories>../../../../src/;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsC</CompileAs>
<CLanguageStandard>c99</CLanguageStandard>
<CppLanguageStandard>Default</CppLanguageStandard>
<PrecompiledHeaderCompileAs>CompileAsC</PrecompiledHeaderCompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
<AdditionalLibraryDirectories>.;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<ClCompile>
<PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<CompileAs>CompileAsCpp</CompileAs>
</ClCompile>
<Link>
<LibraryDependencies>%(LibraryDependencies);GLESv1_CM;EGL;</LibraryDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="android_native_app_glue.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="android_native_app_glue.c" />
<ClCompile Include="main.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClInclude Include="android_native_app_glue.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="android_native_app_glue.c" />
<ClCompile Include="main.c" />
</ItemGroup>
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>

View File

@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Changes made to Package Name should also be reflected in the Debugging - Package Name property, in the Property Pages -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.$(ApplicationName)" android:versionCode="1" android:versionName="1.0">
<!-- This is the platform API where NativeActivity was introduced. -->
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>
<!-- This .apk has no Java code itself, so set hasCode to false. -->
<application android:label="@string/app_name" android:hasCode="false">
<!-- Our activity is the built-in NativeActivity framework class.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:configChanges="orientation|keyboardHidden|screenSize" android:screenOrientation="landscape">
<!-- Tell NativeActivity the name of our .so -->
<meta-data android:name="android.app.lib_name" android:value="main"/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="$(projectname)" default="help">
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var. -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file contains project specific properties such as
project target, and library dependencies. Lower level build properties are
stored in ant.properties
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure ANDROID_HOME environment variable is correctly set."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
<target name="-pre-compile">
<path id="project.all.jars.path">
<path path="${toString:project.all.jars.path}"/>
<fileset dir="${jar.libs.dir}">
<include name="*.jar"/>
</fileset>
</path>
</target>
</project>

View File

@ -1,3 +0,0 @@
# Project target
target=$(androidapilevel)
# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir=

View File

@ -1,134 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM64">
<Configuration>Debug</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM64">
<Configuration>Release</Configuration>
<Platform>ARM64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x86">
<Configuration>Debug</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x86">
<Configuration>Release</Configuration>
<Platform>x86</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<RootNamespace>raylib_android</RootNamespace>
<MinimumVisualStudioVersion>14.0</MinimumVisualStudioVersion>
<ProjectVersion>1.0</ProjectVersion>
<ProjectGuid>{b2231f0d-52da-4c55-8998-5886f766553c}</ProjectGuid>
</PropertyGroup>
<Import Project="$(AndroidTargetsPath)\Android.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'" Label="Configuration">
<UseDebugLibraries>true</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'" Label="Configuration">
<UseDebugLibraries>false</UseDebugLibraries>
<ConfigurationType>Application</ConfigurationType>
</PropertyGroup>
<Import Project="$(AndroidTargetsPath)\Android.props" />
<ImportGroup Label="ExtensionSettings" />
<ImportGroup Label="Shared" />
<PropertyGroup Label="UserMacros" />
<PropertyGroup />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<AntPackage>
<AndroidAppLibName>$(RootNamespace)</AndroidAppLibName>
</AntPackage>
</ItemDefinitionGroup>
<ItemGroup>
<Content Include="res\values\strings.xml" />
<AntBuildXml Include="build.xml" />
<AndroidManifest Include="AndroidManifest.xml" />
<AntProjectPropertiesFile Include="project.properties" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\raylib_android.NativeActivity\raylib_android.NativeActivity.vcxproj">
<Project>{bfb31759-4fca-4503-bc7c-a97f705efdb2}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(AndroidTargetsPath)\Android.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">raylib_android.Packaging</string>
</resources>

View File

@ -107,6 +107,20 @@ endif ()
target_link_libraries(raylib PRIVATE $<BUILD_INTERFACE:${LIBS_PRIVATE}>) target_link_libraries(raylib PRIVATE $<BUILD_INTERFACE:${LIBS_PRIVATE}>)
target_link_libraries(raylib PUBLIC ${LIBS_PUBLIC}) target_link_libraries(raylib PUBLIC ${LIBS_PUBLIC})
# Static libraries must export their private link dependencies for installed consumers.
# LINK_ONLY keeps those dependencies out of the compile interface.
if (NOT BUILD_SHARED_LIBS)
set(raylib_install_private_libs ${LIBS_PRIVATE})
if (NOT glfw3_FOUND)
list(REMOVE_ITEM raylib_install_private_libs glfw)
endif()
foreach(lib IN LISTS raylib_install_private_libs)
target_link_libraries(raylib INTERFACE $<INSTALL_INTERFACE:$<LINK_ONLY:${lib}>>)
endforeach()
endif()
# Sets some compile time definitions for the pre-processor # Sets some compile time definitions for the pre-processor
# If CUSTOMIZE_BUILD option is on you will not use config.h by default # If CUSTOMIZE_BUILD option is on you will not use config.h by default
# and you will be able to select more build options # and you will be able to select more build options

View File

@ -1154,14 +1154,15 @@ RLAPI long GetFileModTime(const char *fileName); // Get file
RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png') RLAPI const char *GetFileExtension(const char *fileName); // Get pointer to extension for a filename string (includes dot: '.png')
RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string RLAPI const char *GetFileName(const char *filePath); // Get pointer to filename for a path string
RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string) RLAPI const char *GetFileNameWithoutExt(const char *filePath); // Get filename string without extension (uses static string)
RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a given fileName with path (uses static string) RLAPI const char *GetDirectoryPath(const char *filePath); // Get full path for a provided fileName with path (uses static string)
RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a given path (uses static string) RLAPI const char *GetPrevDirectoryPath(const char *dirPath); // Get previous directory path for a provided path (uses static string)
RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string) RLAPI const char *GetWorkingDirectory(void); // Get current working directory (uses static string)
RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string) RLAPI const char *GetApplicationDirectory(void); // Get the directory of the running application (uses static string)
RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success RLAPI int MakeDirectory(const char *dirPath); // Create directories (including full path requested), returns 0 on success
RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success RLAPI int ChangeDirectory(const char *dirPath); // Change working directory, returns 0 on success
RLAPI bool IsPathFile(const char *path); // Check if given path points to a file RLAPI bool IsPathFile(const char *path); // Check if provided path points to a file
RLAPI bool IsPathDirectory(const char *path); // Check if given path points to a directory RLAPI bool IsPathDirectory(const char *path); // Check if provided path points to a directory
RLAPI bool IsPathAbsolute(const char *path); // Check if provided path is an absolute path
RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS RLAPI bool IsFileNameValid(const char *fileName); // Check if fileName is valid for the platform/OS
RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan RLAPI FilePathList LoadDirectoryFiles(const char *dirPath); // Load directory filepaths, files and directories, no subdirs scan
RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*' RLAPI FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); // Load directory filepaths with extension filtering and subdir scan; some filters available: '*.*','FILES*','DIRS*'
@ -1240,7 +1241,7 @@ RLAPI void SetMouseCursor(int cursor); // Set mouse curso
RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size) RLAPI int GetTouchX(void); // Get touch position X for touch point 0 (relative to screen size)
RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size) RLAPI int GetTouchY(void); // Get touch position Y for touch point 0 (relative to screen size)
RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size) RLAPI Vector2 GetTouchPosition(int index); // Get touch position XY for a touch point index (relative to screen size)
RLAPI int GetTouchPointId(int index); // Get touch point identifier for given index RLAPI int GetTouchPointId(int index); // Get touch point identifier for provided index
RLAPI int GetTouchPointCount(void); // Get number of touch points RLAPI int GetTouchPointCount(void); // Get number of touch points
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
@ -1327,7 +1328,7 @@ RLAPI void DrawSplineSegmentCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vecto
RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point RLAPI void DrawSplineSegmentBezierQuadratic(Vector2 p1, Vector2 c2, Vector2 p3, float thick, Color color); // Draw spline segment: Quadratic Bezier, 2 points, 1 control point
RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points RLAPI void DrawSplineSegmentBezierCubic(Vector2 p1, Vector2 c2, Vector2 c3, Vector2 p4, float thick, Color color); // Draw spline segment: Cubic Bezier, 2 points, 2 control points
// Spline segment point evaluation functions, for a given t [0.0f .. 1.0f] // Spline segment point evaluation functions, for a provided t [0.0f .. 1.0f]
RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear RLAPI Vector2 GetSplinePointLinear(Vector2 startPos, Vector2 endPos, float t); // Get (evaluate) spline point: Linear
RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline RLAPI Vector2 GetSplinePointBasis(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: B-Spline
RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom RLAPI Vector2 GetSplinePointCatmullRom(Vector2 p1, Vector2 p2, Vector2 p3, Vector2 p4, float t); // Get (evaluate) spline point: Catmull-Rom
@ -1417,7 +1418,7 @@ RLAPI Color GetImageColor(Image image, int x, int y);
// Image drawing functions // Image drawing functions
// NOTE: Image software-rendering functions (CPU) // NOTE: Image software-rendering functions (CPU)
RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with given color RLAPI void ImageClearBackground(Image *dst, Color color); // Clear image background with provided color
RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image RLAPI void ImageDrawPixel(Image *dst, int posX, int posY, Color color); // Draw pixel within an image
RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version) RLAPI void ImageDrawPixelV(Image *dst, Vector2 position, Color color); // Draw pixel within an image (Vector version)
RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image RLAPI void ImageDrawLine(Image *dst, int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw line within an image

View File

@ -1804,7 +1804,6 @@ void UnloadRandomSequence(int *sequence)
} }
// Takes a screenshot of current screen // Takes a screenshot of current screen
// NOTE: Provided fileName should not contain paths, saving to working directory
void TakeScreenshot(const char *fileName) void TakeScreenshot(const char *fileName)
{ {
#if SUPPORT_MODULE_RTEXTURES #if SUPPORT_MODULE_RTEXTURES
@ -1819,7 +1818,8 @@ void TakeScreenshot(const char *fileName)
Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 }; Image image = { imgData, (int)((float)CORE.Window.render.width*scale.x), (int)((float)CORE.Window.render.height*scale.y), 1, PIXELFORMAT_UNCOMPRESSED_R8G8B8A8 };
char path[MAX_FILEPATH_LENGTH] = { 0 }; char path[MAX_FILEPATH_LENGTH] = { 0 };
snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName)); if (!IsPathAbsolute(fileName)) snprintf(path, MAX_FILEPATH_LENGTH, "%s", TextFormat("%s/%s", CORE.Storage.basePath, fileName));
else snprintf(path, MAX_FILEPATH_LENGTH, "%s", fileName);
ExportImage(image, path); // WARNING: Module required: rtextures ExportImage(image, path); // WARNING: Module required: rtextures
RL_FREE(imgData); RL_FREE(imgData);
@ -2522,7 +2522,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
return fileName; return fileName;
} }
// Get directory for a given filePath // Get directory for a provided filePath
const char *GetDirectoryPath(const char *filePath) const char *GetDirectoryPath(const char *filePath)
{ {
/* /*
@ -2569,7 +2569,7 @@ const char *GetDirectoryPath(const char *filePath)
return dirPath; return dirPath;
} }
// Get previous directory path for a given path // Get previous directory path for a provided path
const char *GetPrevDirectoryPath(const char *dirPath) const char *GetPrevDirectoryPath(const char *dirPath)
{ {
static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 }; static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 };
@ -2819,7 +2819,7 @@ int ChangeDirectory(const char *dirPath)
return result; return result;
} }
// Check if given path point to a file // Check if provided path point to a file
bool IsPathFile(const char *path) bool IsPathFile(const char *path)
{ {
bool result = false; bool result = false;
@ -2832,7 +2832,7 @@ bool IsPathFile(const char *path)
return result; return result;
} }
// Check if given path point to a directory // Check if provided path point to a directory
bool IsPathDirectory(const char *path) bool IsPathDirectory(const char *path)
{ {
bool result = false; bool result = false;
@ -2842,6 +2842,28 @@ bool IsPathDirectory(const char *path)
return result; return result;
} }
// Check if provided path is an absolute path
bool IsPathAbsolute(const char *path)
{
int result = false;
if ((path != NULL) && (path[0] != '\0'))
{
#if defined(_WIN32)
// UNC path (\\server\share)
if ((path[0] == '\\') && (path[1] == '\\')) result = true;
// Drive letter (e.g. C:\ or D:/)
else if (isalpha((unsigned char)path[0]) && (path[1] == ':') &&
((path[2] == '\\') || (path[2] == '/'))) result = true;
#else
// POSIX: must start with /
if (path[0] == '/') result = true;
#endif
}
return result;
}
// Check if fileName is valid for the platform/OS // Check if fileName is valid for the platform/OS
bool IsFileNameValid(const char *fileName) bool IsFileNameValid(const char *fileName)
{ {
@ -3608,7 +3630,7 @@ AutomationEventList LoadAutomationEventList(const char *fileName)
counter++; counter++;
} }
else TRACELOG(LOG_WARNING, "AUTOMATION: Event goes beyond automated list capacity (MAX: %i): %s", buffer, list.capacity); else TRACELOG(LOG_WARNING, "AUTOMATION: Event goes beyond automated list capacity (MAX: %u): %s", list.capacity, buffer);
} break; } break;
default: break; default: break;
} }
@ -4214,7 +4236,7 @@ Vector2 GetTouchPosition(int index)
return position; return position;
} }
// Get touch point identifier for given index // Get touch point identifier for provided index
int GetTouchPointId(int index) int GetTouchPointId(int index)
{ {
int id = -1; int id = -1;

View File

@ -3793,6 +3793,10 @@ unsigned char *rlReadScreenPixels(int width, int height)
{ {
unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char)); unsigned char *imgData = (unsigned char *)RL_CALLOC(width*height*4, sizeof(unsigned char));
// NOTE: Buffer retrieved is GL_FRONT in single-buffered configurations
// and GL_BACK in double-buffered configurations, make sure to call it at the end of frame
//glReadBuffer(GL_BACK);
// NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer // NOTE: glReadPixels() returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
// WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly! // WARNING: Getting alpha channel! Be careful, it can be transparent if not cleared properly!
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, imgData);

View File

@ -1230,25 +1230,34 @@ Image ImageFromImage(Image image, Rectangle rec)
{ {
Image result = { 0 }; Image result = { 0 };
// Basic rectangle validation: size smaller than image size // Security check to avoid program crash
if ((rec.x >= 0) && (rec.y >= 0) && (rec.width > 0) && (rec.height > 0) && if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
(((int)rec.x + (int)rec.width) <= image.width) &&
(((int)rec.y + (int)rec.height) <= image.height))
{
int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
result.width = (int)rec.width; if (image.format < PIXELFORMAT_COMPRESSED_DXT1_RGB)
result.height = (int)rec.height; {
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1); // Basic rectangle validation: size smaller than image size
result.format = image.format; if ((rec.x >= 0) && (rec.y >= 0) && (rec.width > 0) && (rec.height > 0) &&
result.mipmaps = 1; (((int)rec.x + (int)rec.width) <= image.width) &&
(((int)rec.y + (int)rec.height) <= image.height))
for (int y = 0; y < (int)rec.height; y++)
{ {
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel, ((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel, (int)rec.width*bytesPerPixel); int bytesPerPixel = GetPixelDataSize(1, 1, image.format);
result.width = (int)rec.width;
result.height = (int)rec.height;
result.data = RL_CALLOC((int)rec.width*(int)rec.height*bytesPerPixel, 1);
result.format = image.format;
result.mipmaps = 1;
for (int y = 0; y < (int)rec.height; y++)
{
memcpy(((unsigned char *)result.data) + y*(int)rec.width*bytesPerPixel,
((unsigned char *)image.data) + ((y + (int)rec.y)*image.width + (int)rec.x)*bytesPerPixel,
(int)rec.width*bytesPerPixel);
}
} }
} else TRACELOG(LOG_WARNING, "IMAGE: ImageToImage(), rectangle provided not valid");
else TRACELOG(LOG_WARNING, "IMAGE: Rectangle provided for ImageToImage not valid"); }
else TRACELOG(LOG_WARNING, "IMAGE: Image manipulation not supported for compressed formats");
return result; return result;
} }

View File

@ -4603,7 +4603,7 @@
}, },
{ {
"name": "GetDirectoryPath", "name": "GetDirectoryPath",
"description": "Get full path for a given fileName with path (uses static string)", "description": "Get full path for a provided fileName with path (uses static string)",
"returnType": "const char *", "returnType": "const char *",
"params": [ "params": [
{ {
@ -4614,7 +4614,7 @@
}, },
{ {
"name": "GetPrevDirectoryPath", "name": "GetPrevDirectoryPath",
"description": "Get previous directory path for a given path (uses static string)", "description": "Get previous directory path for a provided path (uses static string)",
"returnType": "const char *", "returnType": "const char *",
"params": [ "params": [
{ {
@ -4657,7 +4657,7 @@
}, },
{ {
"name": "IsPathFile", "name": "IsPathFile",
"description": "Check if given path points to a file", "description": "Check if provided path points to a file",
"returnType": "bool", "returnType": "bool",
"params": [ "params": [
{ {
@ -4668,7 +4668,18 @@
}, },
{ {
"name": "IsPathDirectory", "name": "IsPathDirectory",
"description": "Check if given path points to a directory", "description": "Check if provided path points to a directory",
"returnType": "bool",
"params": [
{
"type": "const char *",
"name": "path"
}
]
},
{
"name": "IsPathAbsolute",
"description": "Check if provided path is an absolute path",
"returnType": "bool", "returnType": "bool",
"params": [ "params": [
{ {
@ -5379,7 +5390,7 @@
}, },
{ {
"name": "GetTouchPointId", "name": "GetTouchPointId",
"description": "Get touch point identifier for given index", "description": "Get touch point identifier for provided index",
"returnType": "int", "returnType": "int",
"params": [ "params": [
{ {
@ -8099,7 +8110,7 @@
}, },
{ {
"name": "ImageClearBackground", "name": "ImageClearBackground",
"description": "Clear image background with given color", "description": "Clear image background with provided color",
"returnType": "void", "returnType": "void",
"params": [ "params": [
{ {

View File

@ -4135,7 +4135,7 @@ return {
}, },
{ {
name = "GetDirectoryPath", name = "GetDirectoryPath",
description = "Get full path for a given fileName with path (uses static string)", description = "Get full path for a provided fileName with path (uses static string)",
returnType = "const char *", returnType = "const char *",
params = { params = {
{type = "const char *", name = "filePath"} {type = "const char *", name = "filePath"}
@ -4143,7 +4143,7 @@ return {
}, },
{ {
name = "GetPrevDirectoryPath", name = "GetPrevDirectoryPath",
description = "Get previous directory path for a given path (uses static string)", description = "Get previous directory path for a provided path (uses static string)",
returnType = "const char *", returnType = "const char *",
params = { params = {
{type = "const char *", name = "dirPath"} {type = "const char *", name = "dirPath"}
@ -4177,7 +4177,7 @@ return {
}, },
{ {
name = "IsPathFile", name = "IsPathFile",
description = "Check if given path points to a file", description = "Check if provided path points to a file",
returnType = "bool", returnType = "bool",
params = { params = {
{type = "const char *", name = "path"} {type = "const char *", name = "path"}
@ -4185,7 +4185,15 @@ return {
}, },
{ {
name = "IsPathDirectory", name = "IsPathDirectory",
description = "Check if given path points to a directory", description = "Check if provided path points to a directory",
returnType = "bool",
params = {
{type = "const char *", name = "path"}
}
},
{
name = "IsPathAbsolute",
description = "Check if provided path is an absolute path",
returnType = "bool", returnType = "bool",
params = { params = {
{type = "const char *", name = "path"} {type = "const char *", name = "path"}
@ -4671,7 +4679,7 @@ return {
}, },
{ {
name = "GetTouchPointId", name = "GetTouchPointId",
description = "Get touch point identifier for given index", description = "Get touch point identifier for provided index",
returnType = "int", returnType = "int",
params = { params = {
{type = "int", name = "index"} {type = "int", name = "index"}
@ -6071,7 +6079,7 @@ return {
}, },
{ {
name = "ImageClearBackground", name = "ImageClearBackground",
description = "Clear image background with given color", description = "Clear image background with provided color",
returnType = "void", returnType = "void",
params = { params = {
{type = "Image *", name = "dst"}, {type = "Image *", name = "dst"},

View File

@ -3001,13 +3001,13 @@
((type "const char *") (name "filePath")))) ((type "const char *") (name "filePath"))))
((name "GetDirectoryPath") ((name "GetDirectoryPath")
(description "Get full path for a given fileName with path (uses static string)") (description "Get full path for a provided fileName with path (uses static string)")
(return-type "const char *") (return-type "const char *")
(params (params
((type "const char *") (name "filePath")))) ((type "const char *") (name "filePath"))))
((name "GetPrevDirectoryPath") ((name "GetPrevDirectoryPath")
(description "Get previous directory path for a given path (uses static string)") (description "Get previous directory path for a provided path (uses static string)")
(return-type "const char *") (return-type "const char *")
(params (params
((type "const char *") (name "dirPath")))) ((type "const char *") (name "dirPath"))))
@ -3033,13 +3033,19 @@
((type "const char *") (name "dirPath")))) ((type "const char *") (name "dirPath"))))
((name "IsPathFile") ((name "IsPathFile")
(description "Check if given path points to a file") (description "Check if provided path points to a file")
(return-type "bool") (return-type "bool")
(params (params
((type "const char *") (name "path")))) ((type "const char *") (name "path"))))
((name "IsPathDirectory") ((name "IsPathDirectory")
(description "Check if given path points to a directory") (description "Check if provided path points to a directory")
(return-type "bool")
(params
((type "const char *") (name "path"))))
((name "IsPathAbsolute")
(description "Check if provided path is an absolute path")
(return-type "bool") (return-type "bool")
(params (params
((type "const char *") (name "path")))) ((type "const char *") (name "path"))))
@ -3414,7 +3420,7 @@
((type "int") (name "index")))) ((type "int") (name "index"))))
((name "GetTouchPointId") ((name "GetTouchPointId")
(description "Get touch point identifier for given index") (description "Get touch point identifier for provided index")
(return-type "int") (return-type "int")
(params (params
((type "int") (name "index")))) ((type "int") (name "index"))))
@ -4544,7 +4550,7 @@
((type "int") (name "y")))) ((type "int") (name "y"))))
((name "ImageClearBackground") ((name "ImageClearBackground")
(description "Clear image background with given color") (description "Clear image background with provided color")
(return-type "void") (return-type "void")
(params (params
((type "Image *") (name "dst")) ((type "Image *") (name "dst"))

File diff suppressed because it is too large Load Diff

View File

@ -681,7 +681,7 @@
<Param type="unsigned int" name="frames" desc="" /> <Param type="unsigned int" name="frames" desc="" />
</Callback> </Callback>
</Callbacks> </Callbacks>
<Functions count="612"> <Functions count="613">
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context"> <Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
<Param type="int" name="width" desc="" /> <Param type="int" name="width" desc="" />
<Param type="int" name="height" desc="" /> <Param type="int" name="height" desc="" />
@ -1099,10 +1099,10 @@
<Function name="GetFileNameWithoutExt" retType="const char *" paramCount="1" desc="Get filename string without extension (uses static string)"> <Function name="GetFileNameWithoutExt" retType="const char *" paramCount="1" desc="Get filename string without extension (uses static string)">
<Param type="const char *" name="filePath" desc="" /> <Param type="const char *" name="filePath" desc="" />
</Function> </Function>
<Function name="GetDirectoryPath" retType="const char *" paramCount="1" desc="Get full path for a given fileName with path (uses static string)"> <Function name="GetDirectoryPath" retType="const char *" paramCount="1" desc="Get full path for a provided fileName with path (uses static string)">
<Param type="const char *" name="filePath" desc="" /> <Param type="const char *" name="filePath" desc="" />
</Function> </Function>
<Function name="GetPrevDirectoryPath" retType="const char *" paramCount="1" desc="Get previous directory path for a given path (uses static string)"> <Function name="GetPrevDirectoryPath" retType="const char *" paramCount="1" desc="Get previous directory path for a provided path (uses static string)">
<Param type="const char *" name="dirPath" desc="" /> <Param type="const char *" name="dirPath" desc="" />
</Function> </Function>
<Function name="GetWorkingDirectory" retType="const char *" paramCount="0" desc="Get current working directory (uses static string)"> <Function name="GetWorkingDirectory" retType="const char *" paramCount="0" desc="Get current working directory (uses static string)">
@ -1115,10 +1115,13 @@
<Function name="ChangeDirectory" retType="int" paramCount="1" desc="Change working directory, returns 0 on success"> <Function name="ChangeDirectory" retType="int" paramCount="1" desc="Change working directory, returns 0 on success">
<Param type="const char *" name="dirPath" desc="" /> <Param type="const char *" name="dirPath" desc="" />
</Function> </Function>
<Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if given path points to a file"> <Function name="IsPathFile" retType="bool" paramCount="1" desc="Check if provided path points to a file">
<Param type="const char *" name="path" desc="" /> <Param type="const char *" name="path" desc="" />
</Function> </Function>
<Function name="IsPathDirectory" retType="bool" paramCount="1" desc="Check if given path points to a directory"> <Function name="IsPathDirectory" retType="bool" paramCount="1" desc="Check if provided path points to a directory">
<Param type="const char *" name="path" desc="" />
</Function>
<Function name="IsPathAbsolute" retType="bool" paramCount="1" desc="Check if provided path is an absolute path">
<Param type="const char *" name="path" desc="" /> <Param type="const char *" name="path" desc="" />
</Function> </Function>
<Function name="IsFileNameValid" retType="bool" paramCount="1" desc="Check if fileName is valid for the platform/OS"> <Function name="IsFileNameValid" retType="bool" paramCount="1" desc="Check if fileName is valid for the platform/OS">
@ -1319,7 +1322,7 @@
<Function name="GetTouchPosition" retType="Vector2" paramCount="1" desc="Get touch position XY for a touch point index (relative to screen size)"> <Function name="GetTouchPosition" retType="Vector2" paramCount="1" desc="Get touch position XY for a touch point index (relative to screen size)">
<Param type="int" name="index" desc="" /> <Param type="int" name="index" desc="" />
</Function> </Function>
<Function name="GetTouchPointId" retType="int" paramCount="1" desc="Get touch point identifier for given index"> <Function name="GetTouchPointId" retType="int" paramCount="1" desc="Get touch point identifier for provided index">
<Param type="int" name="index" desc="" /> <Param type="int" name="index" desc="" />
</Function> </Function>
<Function name="GetTouchPointCount" retType="int" paramCount="0" desc="Get number of touch points"> <Function name="GetTouchPointCount" retType="int" paramCount="0" desc="Get number of touch points">
@ -2039,7 +2042,7 @@
<Param type="int" name="x" desc="" /> <Param type="int" name="x" desc="" />
<Param type="int" name="y" desc="" /> <Param type="int" name="y" desc="" />
</Function> </Function>
<Function name="ImageClearBackground" retType="void" paramCount="2" desc="Clear image background with given color"> <Function name="ImageClearBackground" retType="void" paramCount="2" desc="Clear image background with provided color">
<Param type="Image *" name="dst" desc="" /> <Param type="Image *" name="dst" desc="" />
<Param type="Color" name="color" desc="" /> <Param type="Color" name="color" desc="" />
</Function> </Function>