mirror of
https://github.com/raysan5/raylib.git
synced 2026-08-25 13:48:27 -04:00
Compare commits
16 Commits
patch-1
...
b812c18e6b
| Author | SHA1 | Date | |
|---|---|---|---|
| b812c18e6b | |||
| 6c6a248be8 | |||
| ce6ac7d8c7 | |||
| baa9a4df51 | |||
| 58e03dbc6c | |||
| cfccb83ddd | |||
| b806e3d2ec | |||
| 0725811224 | |||
| 5b1445b381 | |||
| aa088e42d1 | |||
| 7aceceb467 | |||
| 66bb527d22 | |||
| f1d44c166f | |||
| 9c834d6e4d | |||
| 742ccb390a | |||
| 62a74a342c |
@ -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
|
||||
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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";
|
||||
@ -4,15 +4,14 @@ This folder contains raylib templates for some common IDEs.
|
||||
|
||||
IDE | Platform(s) | Source | Example(s)
|
||||
----| ------------| :-------: | :-----:
|
||||
[4coder](http://4coder.net/) | Windows | ❌ | ✔️
|
||||
[Builder](https://wiki.gnome.org/Apps/Builder) | Linux | ❌ | ✔️
|
||||
[CMake](https://cmake.org/) | Windows, Linux, macOS, Web | ✔️ | ✔️
|
||||
[CodeBlocks](http://www.codeblocks.org/) | Windows, Linux, macOS | ❌ | ✔️
|
||||
[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 | ✔️ | ✔️
|
||||
[VS2019](https://www.visualstudio.com) | Windows | ✔️ | ✔️
|
||||
[VSCode](https://code.visualstudio.com/) | Windows, macOS | ❌ | ✔️
|
||||
[VS2022](https://www.visualstudio.com) | Windows | ✔️ | ✔️
|
||||
[VSCode](https://code.visualstudio.com/) | Windows, Linux, macOS | ❌ | ✔️
|
||||
[Zig](https://ziglang.org) | Windows, Linux, macOS, Web | ✔️ | ✔️
|
||||
scripts | Windows, Linux, macOS | ✔️ | ✔️
|
||||
|
||||
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
@ -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 */
|
||||
@ -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;
|
||||
}
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup />
|
||||
</Project>
|
||||
@ -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>
|
||||
@ -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>
|
||||
@ -1,3 +0,0 @@
|
||||
# Project target
|
||||
target=$(androidapilevel)
|
||||
# Provide path to the directory where prebuilt external jar files are by setting jar.libs.dir=
|
||||
@ -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>
|
||||
@ -1,4 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">raylib_android.Packaging</string>
|
||||
</resources>
|
||||
@ -107,6 +107,20 @@ endif ()
|
||||
target_link_libraries(raylib PRIVATE $<BUILD_INTERFACE:${LIBS_PRIVATE}>)
|
||||
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
|
||||
# If CUSTOMIZE_BUILD option is on you will not use config.h by default
|
||||
# and you will be able to select more build options
|
||||
|
||||
15
src/raylib.h
15
src/raylib.h
@ -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 *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 *GetDirectoryPath(const char *filePath); // Get full path for a given 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 *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 provided path (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 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 bool IsPathFile(const char *path); // Check if given path points to a file
|
||||
RLAPI bool IsPathDirectory(const char *path); // Check if given path points to a directory
|
||||
RLAPI bool IsPathFile(const char *path); // Check if provided path points to a file
|
||||
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 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*'
|
||||
@ -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 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 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
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -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 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 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
|
||||
@ -1417,7 +1418,7 @@ RLAPI Color GetImageColor(Image image, int x, int y);
|
||||
|
||||
// Image drawing functions
|
||||
// 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 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
|
||||
|
||||
38
src/rcore.c
38
src/rcore.c
@ -1804,7 +1804,6 @@ void UnloadRandomSequence(int *sequence)
|
||||
}
|
||||
|
||||
// Takes a screenshot of current screen
|
||||
// NOTE: Provided fileName should not contain paths, saving to working directory
|
||||
void TakeScreenshot(const char *fileName)
|
||||
{
|
||||
#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 };
|
||||
|
||||
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
|
||||
RL_FREE(imgData);
|
||||
@ -2522,7 +2522,7 @@ const char *GetFileNameWithoutExt(const char *filePath)
|
||||
return fileName;
|
||||
}
|
||||
|
||||
// Get directory for a given filePath
|
||||
// Get directory for a provided filePath
|
||||
const char *GetDirectoryPath(const char *filePath)
|
||||
{
|
||||
/*
|
||||
@ -2569,7 +2569,7 @@ const char *GetDirectoryPath(const char *filePath)
|
||||
return dirPath;
|
||||
}
|
||||
|
||||
// Get previous directory path for a given path
|
||||
// Get previous directory path for a provided path
|
||||
const char *GetPrevDirectoryPath(const char *dirPath)
|
||||
{
|
||||
static char prevDirPath[MAX_FILEPATH_LENGTH] = { 0 };
|
||||
@ -2819,7 +2819,7 @@ int ChangeDirectory(const char *dirPath)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if given path point to a file
|
||||
// Check if provided path point to a file
|
||||
bool IsPathFile(const char *path)
|
||||
{
|
||||
bool result = false;
|
||||
@ -2832,7 +2832,7 @@ bool IsPathFile(const char *path)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Check if given path point to a directory
|
||||
// Check if provided path point to a directory
|
||||
bool IsPathDirectory(const char *path)
|
||||
{
|
||||
bool result = false;
|
||||
@ -2842,6 +2842,28 @@ bool IsPathDirectory(const char *path)
|
||||
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
|
||||
bool IsFileNameValid(const char *fileName)
|
||||
{
|
||||
@ -3608,7 +3630,7 @@ AutomationEventList LoadAutomationEventList(const char *fileName)
|
||||
|
||||
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;
|
||||
default: break;
|
||||
}
|
||||
@ -4214,7 +4236,7 @@ Vector2 GetTouchPosition(int index)
|
||||
return position;
|
||||
}
|
||||
|
||||
// Get touch point identifier for given index
|
||||
// Get touch point identifier for provided index
|
||||
int GetTouchPointId(int index)
|
||||
{
|
||||
int id = -1;
|
||||
|
||||
@ -3793,6 +3793,10 @@ unsigned char *rlReadScreenPixels(int width, int height)
|
||||
{
|
||||
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
|
||||
// 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);
|
||||
|
||||
@ -1230,6 +1230,11 @@ Image ImageFromImage(Image image, Rectangle rec)
|
||||
{
|
||||
Image result = { 0 };
|
||||
|
||||
// Security check to avoid program crash
|
||||
if ((image.data == NULL) || (image.width == 0) || (image.height == 0)) return result;
|
||||
|
||||
if (image.format < PIXELFORMAT_COMPRESSED_DXT1_RGB)
|
||||
{
|
||||
// Basic rectangle validation: size smaller than image size
|
||||
if ((rec.x >= 0) && (rec.y >= 0) && (rec.width > 0) && (rec.height > 0) &&
|
||||
(((int)rec.x + (int)rec.width) <= image.width) &&
|
||||
@ -1245,10 +1250,14 @@ Image ImageFromImage(Image image, Rectangle rec)
|
||||
|
||||
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);
|
||||
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: Rectangle provided for ImageToImage not valid");
|
||||
else TRACELOG(LOG_WARNING, "IMAGE: ImageToImage(), rectangle provided not valid");
|
||||
}
|
||||
else TRACELOG(LOG_WARNING, "IMAGE: Image manipulation not supported for compressed formats");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -4603,7 +4603,7 @@
|
||||
},
|
||||
{
|
||||
"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 *",
|
||||
"params": [
|
||||
{
|
||||
@ -4614,7 +4614,7 @@
|
||||
},
|
||||
{
|
||||
"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 *",
|
||||
"params": [
|
||||
{
|
||||
@ -4657,7 +4657,7 @@
|
||||
},
|
||||
{
|
||||
"name": "IsPathFile",
|
||||
"description": "Check if given path points to a file",
|
||||
"description": "Check if provided path points to a file",
|
||||
"returnType": "bool",
|
||||
"params": [
|
||||
{
|
||||
@ -4668,7 +4668,18 @@
|
||||
},
|
||||
{
|
||||
"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",
|
||||
"params": [
|
||||
{
|
||||
@ -5379,7 +5390,7 @@
|
||||
},
|
||||
{
|
||||
"name": "GetTouchPointId",
|
||||
"description": "Get touch point identifier for given index",
|
||||
"description": "Get touch point identifier for provided index",
|
||||
"returnType": "int",
|
||||
"params": [
|
||||
{
|
||||
@ -8099,7 +8110,7 @@
|
||||
},
|
||||
{
|
||||
"name": "ImageClearBackground",
|
||||
"description": "Clear image background with given color",
|
||||
"description": "Clear image background with provided color",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
|
||||
@ -4135,7 +4135,7 @@ return {
|
||||
},
|
||||
{
|
||||
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 *",
|
||||
params = {
|
||||
{type = "const char *", name = "filePath"}
|
||||
@ -4143,7 +4143,7 @@ return {
|
||||
},
|
||||
{
|
||||
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 *",
|
||||
params = {
|
||||
{type = "const char *", name = "dirPath"}
|
||||
@ -4177,7 +4177,7 @@ return {
|
||||
},
|
||||
{
|
||||
name = "IsPathFile",
|
||||
description = "Check if given path points to a file",
|
||||
description = "Check if provided path points to a file",
|
||||
returnType = "bool",
|
||||
params = {
|
||||
{type = "const char *", name = "path"}
|
||||
@ -4185,7 +4185,15 @@ return {
|
||||
},
|
||||
{
|
||||
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",
|
||||
params = {
|
||||
{type = "const char *", name = "path"}
|
||||
@ -4671,7 +4679,7 @@ return {
|
||||
},
|
||||
{
|
||||
name = "GetTouchPointId",
|
||||
description = "Get touch point identifier for given index",
|
||||
description = "Get touch point identifier for provided index",
|
||||
returnType = "int",
|
||||
params = {
|
||||
{type = "int", name = "index"}
|
||||
@ -6071,7 +6079,7 @@ return {
|
||||
},
|
||||
{
|
||||
name = "ImageClearBackground",
|
||||
description = "Clear image background with given color",
|
||||
description = "Clear image background with provided color",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "Image *", name = "dst"},
|
||||
|
||||
@ -3001,13 +3001,13 @@
|
||||
((type "const char *") (name "filePath"))))
|
||||
|
||||
((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 *")
|
||||
(params
|
||||
((type "const char *") (name "filePath"))))
|
||||
|
||||
((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 *")
|
||||
(params
|
||||
((type "const char *") (name "dirPath"))))
|
||||
@ -3033,13 +3033,19 @@
|
||||
((type "const char *") (name "dirPath"))))
|
||||
|
||||
((name "IsPathFile")
|
||||
(description "Check if given path points to a file")
|
||||
(description "Check if provided path points to a file")
|
||||
(return-type "bool")
|
||||
(params
|
||||
((type "const char *") (name "path"))))
|
||||
|
||||
((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")
|
||||
(params
|
||||
((type "const char *") (name "path"))))
|
||||
@ -3414,7 +3420,7 @@
|
||||
((type "int") (name "index"))))
|
||||
|
||||
((name "GetTouchPointId")
|
||||
(description "Get touch point identifier for given index")
|
||||
(description "Get touch point identifier for provided index")
|
||||
(return-type "int")
|
||||
(params
|
||||
((type "int") (name "index"))))
|
||||
@ -4544,7 +4550,7 @@
|
||||
((type "int") (name "y"))))
|
||||
|
||||
((name "ImageClearBackground")
|
||||
(description "Clear image background with given color")
|
||||
(description "Clear image background with provided color")
|
||||
(return-type "void")
|
||||
(params
|
||||
((type "Image *") (name "dst"))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -681,7 +681,7 @@
|
||||
<Param type="unsigned int" name="frames" desc="" />
|
||||
</Callback>
|
||||
</Callbacks>
|
||||
<Functions count="612">
|
||||
<Functions count="613">
|
||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||
<Param type="int" name="width" 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)">
|
||||
<Param type="const char *" name="filePath" desc="" />
|
||||
</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="" />
|
||||
</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="" />
|
||||
</Function>
|
||||
<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">
|
||||
<Param type="const char *" name="dirPath" desc="" />
|
||||
</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="" />
|
||||
</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="" />
|
||||
</Function>
|
||||
<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)">
|
||||
<Param type="int" name="index" desc="" />
|
||||
</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="" />
|
||||
</Function>
|
||||
<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="y" desc="" />
|
||||
</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="Color" name="color" desc="" />
|
||||
</Function>
|
||||
|
||||
Reference in New Issue
Block a user