merging master

This commit is contained in:
Tyler Bezera 2020-05-16 01:39:27 -07:00
commit d31896f7ea
440 changed files with 24678 additions and 48765 deletions

1
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -0,0 +1 @@
blank_issues_enabled: false

View File

@ -7,6 +7,16 @@ assignees: ''
---
**WARNING: Please, read this note carefully before submitting a new issue:**
It is important to realise that **this is NOT A SUPPORT FORUM**, this is for reproducible BUGS with raylib ONLY.
There are lots of generous and helpful people ready to help you out on [raylib Discord forum](https://discord.gg/VkzNHUE) or [raylib reddit](https://www.reddit.com/r/raylib/).
Remember that asking for support questions here actively takes developer time away from improving raylib.
---
Please, before submitting a new issue verify and check:
- [ ] I tested it on latest raylib version from master branch

42
.gitignore vendored
View File

@ -30,16 +30,14 @@ Thumbs.db
*.cache
*.ilk
*.log
.vs
[Bb]in
[Dd]ebug/
[Dd]ebug.win32/
[Dd]ebug.DLL/
*.sbr
*.sdf
obj/
[R]elease/
[Rr]elease.win32/
_ReSharper*/
[Tt]est[Rr]esult*
ipch/
@ -54,7 +52,6 @@ packages/
*.a
*.bc
*.so
!raylib.rc.o
# Ignore all examples files
examples/*
@ -62,7 +59,6 @@ examples/*
!examples/*/
# Unignore all examples files with extension
!examples/*.c
!examples/*.lua
!examples/*.png
# Unignore examples Makefile
!examples/Makefile
@ -70,18 +66,6 @@ examples/*
!examples/raylib_compile_execute.bat
!examples/raylib_makefile_example.bat
# Ignore all games files
games/*
# Unignore all games dirs
!games/*/
# Unignore all games files with extension
!games/*.c
!games/*.lua
!games/*.png
# Unignore games makefile
!games/Makefile
!games/Makefile.Android
# Ignore files build by xcode
*.mode*v*
*.pbxuser
@ -96,23 +80,6 @@ xcschememanagement.plist
xcuserdata/
DerivedData/
# Visual Studio project
project/VS2015.UWP/packages
project/VS2017/packages
# Web examples
docs/examples/web/*.html
docs/examples/web/*/*.html
!docs/examples/web/loader.html
!docs/examples/web/core/loader.html
!docs/examples/web/shapes/loader.html
!docs/examples/web/text/loader.html
!docs/examples/web/textures/loader.html
!docs/examples/web/audio/loader.html
!docs/examples/web/physac/loader.html
!docs/examples/web/shaders/loader.html
!docs/examples/web/models/loader.html
# Jetbrains project
.idea/
cmake-build-debug/
@ -122,23 +89,16 @@ CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
TestingIfSymlinkWorks
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
build
!templates/android_project/Makefile
# Unignore These makefiles...
!examples/CMakeLists.txt
!games/CMakeLists.txt
# Ignore Android generated files and folders
templates/android_project/output
# Ignore GNU global tags
GPATH
GRTAGS
GTAGS
.vs

View File

@ -59,7 +59,7 @@ before_install:
if [[ "$ARCH" == *-android ]]; then
export DONT_TEST=1;
export RAYLIB_PACKAGE_SUFFIX="-Android-arm64";
wget https://dl.google.com/android/repository/android-ndk-r17-linux-x86_64.zip;
wget https://dl.google.com/android/repository/android-ndk-r21-linux-x86_64.zip;
unzip -qq android-ndk*.zip;
if [[ "$ARCH" == arm64-* ]]; then
export RAYLIB_PACKAGE_SUFFIX="-Android-arm64";
@ -70,15 +70,14 @@ before_install:
TOOLCHAIN_ARCH=arm;
PREFIX=arm-linux-androideabi-;
fi;
android-ndk*/build/tools/make_standalone_toolchain.py --arch $TOOLCHAIN_ARCH --api 21 --install-dir /tmp/android-toolchain;
export PATH=/tmp/android-toolchain/bin:$PATH;
export PATH=/android-ndk*/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH;
export CC=${PREFIX}clang;
export CXX=${PREFIX}clang++;
export CMAKE_ARCH_ARGS='-DPLATFORM=Android';
elif [ "$ARCH" == "html5" ]; then
export DONT_TEST=1;
export RAYLIB_PACKAGE_SUFFIX="-html5";
docker run --privileged=true -dit --name emscripten -v $(pwd):/src trzeci/emscripten:sdk-incoming-64bit bash;
docker run --privileged=true -dit --name emscripten -v $(pwd):/src trzeci/emscripten:sdk-latest bash;
export CMAKE_ARCH_ARGS='-DPLATFORM=Web -DCMAKE_TOOLCHAIN_FILE=../cmake/emscripten.cmake';
RUNNER='docker exec -it emscripten cmake -E chdir build';
else
@ -134,7 +133,7 @@ script:
- $RUNNER cmake $CMAKE_ARCH_ARGS
-DMACOS_FATLIB=ON
-DSTATIC=$STATIC -DSHARED=$SHARED
-DBUILD_EXAMPLES=ON -DBUILD_GAMES=ON
-DBUILD_EXAMPLES=ON
-DUSE_EXTERNAL_GLFW=$USE_EXTERNAL_GLFW
-DUSE_WAYLAND=$WAYLAND
-DINCLUDE_EVERYTHING=ON

View File

@ -1,28 +1,34 @@
## raylib bindings
Some people ported raylib to other languages in form of bindings or wrappers to the library, here is a list with the ones I'm aware of:
Some people ported raylib to other languages in form of bindings or wrappers to the library.
Here it is a list with the ones I'm aware of:
| name | language | repo |
|:------------------:|:--------------:|----------------------------------------------------------------------|
| raylib | C | https://github.com/raysan5/raylib |
| raylib-cpp | C++ | https://github.com/robloach/raylib-cpp |
| Raylib-cs | C# | https://github.com/ChrisDill/Raylib-cs |
| RaylibSharp | C# | https://github.com/TheLumaio/RaylibSharp |
| RaylibFS | F# | https://github.com/dallinbeutler/RaylibFS |
| raylib_d | D | https://github.com/0xFireball/raylib_d |
| raylib-d | D | https://github.com/onroundit/raylib-d |
| bindbc-raylib | D | https://github.com/o3o/bindbc-raylib |
| raylib-go | Go | https://github.com/gen2brain/raylib-go |
| raylib-goplus | Go | https://github.com/Lachee/raylib-goplus |
| raylib-rs | Rust | https://github.com/deltaphc/raylib-rs |
| raylib-rs | [Rust](https://www.rust-lang.org/) | https://github.com/deltaphc/raylib-rs |
| raylib-lua | Lua | https://github.com/raysan5/raylib-lua |
| raylib-lua-ffi | Lua | https://github.com/raysan5/raylib/issues/693 |
| raylib-lua-sol | Lua | https://github.com/RobLoach/raylib-lua-sol |
| raylib-lua (raylua)| Lua | https://github.com/TSnake41/raylib-lua |
| raylib-luamore | Lua | https://github.com/HDPLocust/raylib-luamore |
| raylib-nelua | [Nelua](https://nelua.io/) | https://github.com/Andre-LA/raylib-nelua-mirror |
| raylib-Nim | Nim | https://gitlab.com/define-private-public/raylib-Nim |
| raylib-nim | Nim | https://github.com/Skrylar/raylib-nim |
| raylib-haskell | Haskell | https://github.com/DevJac/raylib-haskell |
| raylib-Forever | Nim | https://github.com/Guevara-chan/Raylib-Forever |
| raylib-haskell | [Haskell](https://www.haskell.org/) | https://github.com/DevJac/raylib-haskell |
| raylib-cr | Crystal | https://github.com/AregevDev/raylib-cr |
| cray | Crystal | https://gitlab.com/Zatherz/cray |
| cray | Crystal | https://github.com/tapgg/cray |
| raylib.cr | Crystal | https://github.com/sam0x17/raylib.cr |
| raylib-pascal | Pascal | https://github.com/drezgames/raylib-pascal |
| raylib-pas | Pascal | https://github.com/tazdij/raylib-pas |
| Graphics-Raylib | Perl | https://github.com/athreef/Graphics-Raylib |
@ -31,35 +37,45 @@ Some people ported raylib to other languages in form of bindings or wrappers to
| raylib-mruby | mruby | https://github.com/lihaochen910/raylib-mruby |
| raylib-py | Python | https://github.com/overdev/raylib-py |
| raylib-python-cffi | Python | https://github.com/electronstudio/raylib-python-cffi |
| jaylib | Java | https://github.com/electronstudio/jaylib/ |
| raylib-java | Java | https://github.com/XoanaIO/raylib-java |
| node-raylib | Node.js | https://github.com/RobLoach/node-raylib |
| QuickJS-raylib | QuickJS | https://github.com/sntg-p/QuickJS-raylib |
| clj-raylib | [Clojure](https://clojure.org/) | https://github.com/lsevero/clj-raylib |
| node-raylib | [Node.js](https://nodejs.org/en/) | https://github.com/RobLoach/node-raylib |
| QuickJS-raylib | [QuickJS](https://bellard.org/quickjs/) | https://github.com/sntg-p/QuickJS-raylib |
| raylib-js | JavaScript | https://github.com/RobLoach/raylib-js |
| raylib-chaiscript | ChaiScript | https://github.com/RobLoach/raylib-chaiscript |
| raylib-squirrel | Squirrel | https://github.com/RobLoach/raylib-squirrel |
| racket-raylib-2d | Racket | https://github.com/arvyy/racket-raylib-2d |
| raylib-chaiscript | [ChaiScript](http://chaiscript.com/) | https://github.com/RobLoach/raylib-chaiscript |
| raylib-squirrel | [Squirrel](http://www.squirrel-lang.org/) | https://github.com/RobLoach/raylib-squirrel |
| racket-raylib-2d | [Racket](https://racket-lang.org/) | https://github.com/arvyy/racket-raylib-2d |
| raylib-php | PHP | https://github.com/joseph-montanez/raylib-php |
| raylib-php-ffi | PHP | https://github.com/oraoto/raylib-php-ffi |
| raylib-phpcpp | PHP | https://github.com/oraoto/raylib-phpcpp |
| raylib-factor | Factor | https://github.com/Silverbeard00/raylib-factor |
| raylib-haxe | Haxe | https://github.com/ibilon/raylib-haxe |
| ringraylib | Ring | https://github.com/ringpackages/ringraylib |
| raylib-factor | [Factor](https://factorcode.org/) | https://github.com/Silverbeard00/raylib-factor |
| raylib-haxe | [Haxe](https://haxe.org/) | https://github.com/ibilon/raylib-haxe |
| ringraylib | [Ring](http://ring-lang.sourceforge.net/) | https://github.com/ringpackages/ringraylib |
| cl-raylib | Common Lisp | https://github.com/longlene/cl-raylib |
| raylib-scm | Chicken Scheme | https://github.com/yashrk/raylib-scm |
| raylib-chibi | Chibi-Scheme | https://github.com/VincentToups/raylib-chibi |
| Euraylib | Euphoria | https://github.com/gAndy50/Euraylib |
| raylib-wren | Wren | https://github.com/TSnake41/raylib-wren |
| raylib-odin | Odin | https://github.com/kevinw/raylib-odin |
| ray.zig | Zig | https://github.com/BitPuffin/zig-raylib-experiments |
| raylib-Ada | Ada | https://github.com/mimo/raylib-Ada |
| jaylib | Janet | https://github.com/janet-lang/jaylib |
| raykit | Kit | https://github.com/Gamerfiend/raykit |
| vraylib | V | https://github.com/MajorHard/vraylib |
| Euraylib | [Euphoria](https://openeuphoria.org/) | https://github.com/gAndy50/Euraylib |
| raylib-wren | [Wren](http://wren.io/) | https://github.com/TSnake41/raylib-wren |
| raylib-odin | [Odin](https://odin-lang.org/) | https://github.com/kevinw/raylib-odin |
| raylib-zig | [Zig](https://ziglang.org/) | https://github.com/Not-Nik/raylib-zig |
| ray.zig | [Zig](https://ziglang.org/) | https://github.com/BitPuffin/zig-raylib-experiments |
| raylib-Ada | [Ada](https://www.adacore.com/about-ada) | https://github.com/mimo/raylib-Ada |
| jaylib | [Janet](https://janet-lang.org/) | https://github.com/janet-lang/jaylib |
| raykit | [Kit](https://www.kitlang.org/) | https://github.com/Gamerfiend/raykit |
| vraylib | [V](https://vlang.io/) | https://github.com/MajorHard/vraylib |
| ray.mod | [BlitzMax](https://blitzmax.org/) | https://github.com/bmx-ng/ray.mod |
| raylib-mosaic | Mosaic | https://github.com/pluckyporcupine/raylib-mosaic |
| raylib-xdpw | XD Pascal | https://github.com/vtereshkov/raylib-xdpw |
| raylib-carp | Carp | https://github.com/pluckyporcupine/raylib-carp |
| raylib-fb | FreeBasic | https://github.com/IchMagBier/raylib-fb |
| raylib-purebasic | [PureBasic](https://www.purebasic.com/) | https://github.com/D-a-n-i-l-o/raylib-purebasic |
| raylib-ats2 | ATS2 | https://github.com/mephistopheles-8/raylib-ats2 |
| raylib-beef | [Beef](https://www.beeflang.org/) | https://github.com/M0n7y5/raylib-beef |
| raylib.cbl | COBOL | *[code examples](https://github.com/Martinfx/Cobol/tree/master/OpenCobol/Games/raylib)* |
Missing some language? Check the [bindings not yet in this list](https://gist.github.com/raysan5/5764cc5b885183f523fce47f098f3d9b#bindings-not-yet-in-the-official-list) or create a new binding! :)
Missing some language? Feel free to create a new binding! :)
Usually, raylib bindings follow the convention: `raylib-{language}`
Let me know if you're writing a new binding for raylib, I will list it here and I usually
provide the icon/logo for that new language binding.
Let me know if you're writing a new binding for raylib, I will list it here!

View File

@ -1,18 +1,20 @@
changelog
---------
Current Release: raylib 3.0.0 (Feb.2020) -WIP-
Current Release: raylib 3.0.0 (01 April 2020)
-----------------------------------------------
Release: raylib 3.0 (Feb 2020)
Release: raylib 3.0 (01 April 2020)
-----------------------------------------------
KEY CHANGES:
- Global context states used on all modules.
- Custom memory allocators for all modules and dependencies.
- Structures reviewed to reduce size and always used as pass-by-value.
- Centralized file access system and memory data loading.
- Structures reviewed to reduce size and always be used as pass-by-value.
- Tracelog messages completely reviewed and categorized.
- raudio module reviewed to accomodate new Music struct and new miniaudio.
- text module reviewed to improve fonts generation and text management functions.
- examples addition, multiple new examples and categorized examples table.
- Multiple new examples added and categorized examples table.
- GitHub Actions CI implemented for Windows, Linux and macOS.
Detailed changes:
@ -28,13 +30,11 @@ Detailed changes:
[build] REVIEWED: Generation of web examples, by @pamarcos
[build] REVIEWED: Makefiles path to 'shell.html', by @niorad
[build] REVIEWED: VS2017 64bit compilation issues, by @spec-chum
[build] REVIEWED: Multiple fixes on projkects building, by @ChrisDill, @JuDelCo, @electronstudio
[build] REVIEWED: Multiple fixes on projects building, by @ChrisDill, @JuDelCo, @electronstudio
[core] ADDED: Support touch/mouse indistinctly
[core] ADDED: FLAG_WINDOW_ALWAYS_RUN to avoid pause on minimize
[core] ADDED: Config flag SUPPORT_HALFBUSY_WAIT_LOOP
[core] ADDED: RPI mouse cursor point support on native mode
[core] ADDED: BeginScissorMode() - Define screen area for following drawing
[core] ADDED: EndScissorMode() - End scissor mode
[core] ADDED: GetWorldToScreen2D()- Get screen space position for a 2d camera world space position, by @arvyy
[core] ADDED: GetScreenToWorld2D() - Get world space position for a 2d camera screen space position, by @arvyy
[core] ADDED: GetWorldToScreenEx() - Get size position for a 3d world space position
@ -43,8 +43,14 @@ Detailed changes:
[core] ADDED: CompressData() - Compress data (DEFLATE algorythm)
[core] ADDED: DecompressData() - Decompress data (DEFLATE algorythm)
[core] ADDED: GetWindowPosition() - Get window position XY on monitor
[core] ADDED: LoadFileData() - Load file data as byte array (read)
[core] ADDED: SaveFileData() - Save data to file from byte array (write)
[core] ADDED: LoadFileText() - Load text data from file (read), returns a '\0' terminated string
[core] ADDED: SaveFileText() - Save text data to file (write), string must be '\0' terminated
[core] REMOVED: Show raylib logo at initialization
[core] REVIEWED: GetFileName(), security checks
[core] REVIEWED: LoadStorageValue(), by @danimartin82
[core] REVIEWED: SaveStorageValue(), by @danimartin82
[core] REVIEWED: IsMouseButtonReleased(), when press/release events come too fast, by @oswjk
[core] REVIEWED: SetWindowMonitor(), by @DropsOfSerenity
[core] REVIEWED: IsFileExtension() to be case-insensitive
@ -81,6 +87,19 @@ Detailed changes:
[textures] ADDED: LoadAnimatedGIF() - Load animated GIF file
[textures] ADDED: GetImageAlphaBorder() - Get image alpha border rectangle
[textures] ADDED: ImageFromImage() - Create an image from another image piece
[textures] ADDED: ImageClearBackground(), by @iamsouravgupta
[textures] ADDED: ImageDrawPixel(), by @iamsouravgupta
[textures] ADDED: ImageDrawCircle(), by @iamsouravgupta
[textures] ADDED: ImageDrawLineEx(), by @iamsouravgupta
[textures] ADDED: ImageDrawPixelV(), by @RobLoach
[textures] ADDED: ImageDrawCircleV(), by @RobLoach
[textures] ADDED: ImageDrawLineV(), by @RobLoach
[textures] ADDED: ImageDrawRectangleV(), by @RobLoach
[textures] ADDED: ImageDrawRectangleRec(), by @RobLoach
[textures] REVIEWED: ImageDrawPixel(), by @RobLoach
[textures] REVIEWED: ImageDrawLine(), by @RobLoach
[textures] REVIEWED: ImageDrawCircle(), by @RobLoach
[textures] REVIEWED: ImageDrawRectangle(), by @RobLoach
[textures] REVIEWED: ImageDraw(), now it supports color tint parameter
[textures] REVIEWED: ImageResizeCanvas()
[textures] REVIEWED: ImageCrop() with security checks
@ -134,6 +153,7 @@ Detailed changes:
[examples] ADDED: shaders_basic_lighting, by @chriscamacho
[examples] ADDED: shaders_simple_mask, by @chriscamacho
[examples] ADDED: audio_multichannel_sound, by @chriscamacho
[examples] ADDED: shaders_spotlight, by @chriscamacho
[examples] RENAMED: text_sprite_font > text_font_spritefont
[examples] RENAMED: text_ttf_loading > text_font_filters
[examples] RENAMED: text_bmfont_ttf > text_font_loading
@ -142,6 +162,7 @@ Detailed changes:
[examples] REVIEWED: models_obj_loading > models_loading
[examples] REVIEWED: models_materials_pbr, shader issues
[examples] REVIEWED: core_window_letterbox, detailed explanation, by @jotac0
[examples] REVIEWED: core_window_letterbox, virtual mouse, by @anatagawa
[games] ADDED: GGJ2020 game - RE-PAIR
[*] Misc fixes and tweaks, by @yaram, @oraoto, @zatherz, @piecedigital, @Shylie
[*] Update ALL supported projects (Notepad++, VS2017)

7
CMakeLists.txt Normal file → Executable file
View File

@ -3,7 +3,6 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
# Config options
option(BUILD_EXAMPLES "Build the examples." ON)
option(BUILD_GAMES "Build the example games." ON)
option(ENABLE_ASAN "Enable AddressSanitizer (ASAN) for debugging (degrades performance)" OFF)
option(ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan) for debugging" OFF)
option(ENABLE_MSAN "Enable MemorySanitizer (MSan) for debugging (not recommended to run with ASAN)" OFF)
@ -22,8 +21,6 @@ add_if_flag_compiles(-Werror=implicit-function-declaration CMAKE_C_FLAGS)
# src/external/jar_xm.h does shady stuff
add_if_flag_compiles(-fno-strict-aliasing CMAKE_C_FLAGS)
include(CheckFileSystemSymlinkSupport)
if (ENABLE_ASAN)
add_if_flag_compiles(-fno-omit-frame-pointer CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
add_if_flag_compiles(-fsanitize=address CMAKE_C_FLAGS CMAKE_LINKER_FLAGS)
@ -47,8 +44,4 @@ if (${BUILD_EXAMPLES})
add_subdirectory(examples)
endif()
if (${BUILD_GAMES})
add_subdirectory(games)
endif()
enable_testing()

View File

@ -6,8 +6,8 @@ Do you enjoy raylib and want to contribute? Nice! You can help with the followin
- C programming - Can you write/review/test/improve the code?
- Documentation/Tutorials/Example - Can you write some tutorial/example?
- Web Development - Can you help [with the website](https://github.com/raysan5/raylib.com)?
- Porting to other platforms - Can you port and compile raylib on other systems?
- Web Development - Can you help [with the website](https://github.com/raysan5/raylib.com)?
- Testing - Can you find some bugs in raylib?
This document contains a set of guidelines to contribute to the project. These are mostly guidelines, not rules.
@ -16,10 +16,10 @@ Use your best judgement, and feel free to propose changes to this document in a
### raylib philosophy
- raylib is a tool to enjoy videogames programming, every single function in raylib should be a tutorial on itself.
- raylib is SIMPLE and EASY-TO-USE, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not to include it.
- raylib is open source and free; educators and institutions can use this tool to TEACH videogames programming completely by free.
- raylib is **SIMPLE** and **EASY-TO-USE**, I tried to keep it compact with a small set of functions, if a function is too complex or is not clearly useful, better not including it.
- raylib is open source and free; educators and institutions can use this tool to **TEACH** videogames programming completely for free.
- raylib is collaborative; contribution of tutorials / code examples / bug fixes / code comments are highly appreciated.
- raylib's license (and its external libs respective licenses) allow using it for commercial products.
- raylib's license (and its external libs respective licenses) allow using it on commercial projects.
### Some interesting reads to start with
@ -36,7 +36,7 @@ Feel free to review it if required, just take care not to break something.
Despite being written in C, raylib does not follow the standard Hungarian notation for C,
it [follows Pascal-case/camel-case notation](https://github.com/raysan5/raylib/wiki/raylib-coding-conventions),
more common on C# language. All code formatting decisions have been carefully taken
to make it easier for students to read, write and understand code.
to make it easier for students/users to read, write and understand code.
Source code is extensively commented for that purpose, raylib primary learning method is:
@ -133,4 +133,4 @@ contributing (in some way or another) to make the raylib project better. Huge th
- [PompPenguin](https://github.com/PompPenguin) for reviewing 3rd person camera
- [Mohamed Shazan](https://github.com/msmshazan) for adding support for ANGLE graphics backend
Please, if I forget someone in this list, excuse me and send a PR!
Please, if I forget someone in this list, excuse me and send me a PR!

View File

@ -1,19 +1,19 @@
![raylib logo](logo/raylib_256x256.png)
history
-------
introduction
------------
I've developed videogames since 2006 and in 2012 I started teaching videogames development to young people with artistic profile, most of them had never written a single line of code.
I started developing videogames in 2006 and some years later I started teaching videogames development to young people with artistic profile, most of students had never written a single line of code.
I started with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found WinBGI; it was great and it worked very well with students, in just a couple of weeks that people that had never written a single line of code were able to program (and understand) a simple PONG and some of them even a BREAKOUT!
I decided to start with C language basis and, after searching for the most simple and easy-to-use library to teach videogames programming, I found [WinBGI](http://www.codecutter.net/tools/winbgim/); it was great and it worked very well with students, in just a couple of weeks, those students that had never written a single line of code were able to program (and understand) a simple PONG game, some of them even a BREAKOUT!
But WinBGI was not the clearer and most organized lib. There were a lot of things I found confusing and some function names were not clear enough for most of the students; not to mention points like no transparencies support or no hardware acceleration.
But WinBGI was not the clearer and most organized library for my taste. There were lots of things I found confusing and some function names were not clear enough for most of the students; not to mention the lack of transparencies support and no hardware acceleration.
So, I decided to create my own library, hardware accelerated, clear function names, quite organized, well structured, plain C coding and, the most important, primarily intended to learn videogames programming.
Most of my videogames coding experience was in C# and XNA and I really love it (in fact, my students learn C# after C), so, I decided to use C# language notation and XNA naming conventions. That way, students can jump from raylib to XNA, MonoGame or similar libs extremely easily.
My previous videogames development experience was mostly in C# and [XNA](https://en.wikipedia.org/wiki/Microsoft_XNA) and I really loved it, so, I decided to use C# language style notation and XNA naming conventions. That way, students were able to move from raylib to XNA, MonoGame or similar libs extremely easily.
raylib started as a weekend project and after three months of hard work, raylib 1.0 was published on November 2013.
raylib started as a weekend project and after three months of hard work, **raylib 1.0 was published on November 2013**.
Enjoy it.
@ -22,9 +22,9 @@ notes on raylib 1.1
On April 2014, after 6 month of first raylib release, raylib 1.1 has been released. This new version presents a complete internal redesign of the library to support OpenGL 1.1, OpenGL 3.3+ and OpenGL ES 2.0.
A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
- A new module named [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) has been added to the library. This new module translates raylib-OpenGL-style immediate mode functions (i.e. rlVertex3f(), rlBegin(), ...) to different versions of OpenGL (1.1, 3.3+, ES2), selectable by one define.
[rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
- [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) also comes with a second new module named [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h), which includes a bunch of useful functions for 3d-math with vectors, matrices and quaternions.
Some other big changes of this new version have been the support for OGG files loading and stream playing, and the support of DDS texture files (compressed and uncompressed) along with mipmaps support.
@ -37,9 +37,9 @@ On September 2014, after 5 month of raylib 1.1 release, it comes raylib 1.2. Aga
It's been some month of really hard work to accomodate raylib to those new platforms while keeping it easy for the users. On Android, raylib manages internally the activity cicle, as well as the inputs; on Raspberry Pi, a complete raw input system has been written from scratch.
A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed.
- A new display initialization system has been created to support multiple resolutions, adding black bars if required; user only defines desired screen size and it gets properly displayed.
Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode).
- Now raylib can easily deploy games to Android devices and Raspberry Pi (console mode).
Lots of code changes and lot of testing have concluded in this amazing new raylib 1.2.
@ -50,15 +50,15 @@ notes on raylib 1.3
On September 2015, after 1 year of raylib 1.2 release, arrives raylib 1.3. This version adds shaders functionality, improves tremendously textures module and also provides some new modules (camera system, gestures system, immediate-mode gui).
Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder.
- Shaders support is the biggest addition to raylib 1.3, with support for easy shaders loading and use. Loaded shaders can be attached to 3d models or used as fullscreen postrocessing effects. A bunch of postprocessing shaders are also included in this release, check raylib/shaders folder.
Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files.
- Textures module has grown to support most of the internal texture formats available in OpenGL (RGB565, RGB888, RGBA5551, RGBA4444, etc.), including compressed texture formats (DXT, ETC1, ETC2, ASTC, PVRT); raylib 1.3 can load .dds, .pkm, .ktx, .astc and .pvr files.
A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c).
- A brand new [camera](https://github.com/raysan5/raylib/blob/master/src/camera.c) module offers to the user multiple preconfigured ready-to-use camera systems (free camera, 1st person, 3rd person). Camera modes are very easy to use, just check examples: [core_3d_camera_free.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_free.c) and [core_3d_camera_first_person.c](https://github.com/raysan5/raylib/blob/master/examples/core_3d_camera_first_person.c).
New [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
- New [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.h) module simplifies gestures detection on Android and HTML5 programs.
[raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional.
- [raygui](https://github.com/raysan5/raylib/blob/master/src/raygui.h), the new immediate-mode GUI module offers a set of functions to create simple user interfaces, primary intended for tools development. It's still in experimental state but already fully functional.
Most of the examples have been completely rewritten and +10 new examples have been added to show the new raylib features.
@ -69,17 +69,17 @@ notes on raylib 1.4
On February 2016, after 4 months of raylib 1.3 release, it comes raylib 1.4. For this new version, lots of parts of the library have been reviewed, lots of bugs have been solved and some interesting features have been added.
First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage.
- First big addition is a set of [Image manipulation functions](https://github.com/raysan5/raylib/blob/master/src/raylib.h#L673) have been added to crop, resize, colorize, flip, dither and even draw image-to-image or text-to-image. Now a basic image processing can be done before converting the image to texture for usage.
SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
- SpriteFonts system has been improved, adding support for AngelCode fonts (.fnt) and TrueType Fonts (using [stb_truetype](https://github.com/nothings/stb/blob/master/stb_truetype.h) helper library). Now raylib can read standard .fnt font data and also generate at loading a SpriteFont from a TTF file.
New [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
- New [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) physics module for basic 2D physics support. Still in development but already functional. Module comes with some usage examples for basic jump and level interaction and also force-based physic movements.
[raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
- [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) module has been reviewed; some bugs have been solved and the module has been converted to a header-only file for easier portability, optionally, functions can also be used as inline.
[gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
- [gestures](https://github.com/raysan5/raylib/blob/master/src/gestures.c) module has redesigned and simplified, now it can process touch events from any source, including mouse. This way, gestures system can be used on any platform providing an unified way to work with inputs and allowing the user to create multiplatform games with only one source code.
Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
- Raspberry Pi input system has been redesigned to better read raw inputs using generic Linux event handlers (keyboard:`stdin`, mouse:`/dev/input/mouse0`, gamepad:`/dev/input/js0`). Gamepad support has also been added (experimental).
Other important improvements are the functional raycast system for 3D picking, including some ray collision-detection functions,
and the addition of two simple functions for persistent data storage. Now raylib user can save and load game data in a file (only some platforms supported). A simple [easings](https://github.com/raysan5/raylib/blob/master/src/easings.h) module has also been added for values animation.
@ -94,17 +94,17 @@ notes on raylib 1.5
On July 2016, after 5 months of raylib 1.4 release, arrives raylib 1.5. This new version is the biggest boost of the library until now, lots of parts of the library have been redesigned, lots of bugs have been solved and some **AMAZING** new features have been added.
VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
- VR support: raylib supports **Oculus Rift CV1**, one of the most anticipated VR devices in the market. Additionally, raylib supports simulated VR stereo rendering, independent of the VR device; it means, raylib can generate stereo renders with custom head-mounted-display device parameteres, that way, any VR device in the market can be **simulated in any platform** just configuring device parameters (and consequently, lens distortion). To enable VR is [extremely easy](https://github.com/raysan5/raylib/blob/master/examples/core_oculus_rift.c).
New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
- New materials system: now raylib supports standard material properties for 3D models, including diffuse-ambient-specular colors and diffuse-normal-specular textures. Just assign values to standard material and everything is processed internally.
New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material.
- New lighting system: added support for up to 8 configurable lights and 3 light types: **point**, **directional** and **spot** lights. Just create a light, configure its parameters and raylib manages render internally for every 3d object using standard material.
Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
- Complete gamepad support on Raspberry Pi: Gamepad system has been completely redesigned. Now multiple gamepads can be easily configured and used; gamepad data is read and processed in raw mode in a second thread.
Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
- Redesigned physics module: [physac](https://github.com/raysan5/raylib/blob/master/src/physac.h) module has been converted to header only and usage [has been simplified](https://github.com/raysan5/raylib/blob/master/examples/physics_basic_rigidbody.c). Performance has also been singnificantly improved, now physic objects are managed internally in a second thread.
Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck.
- Audio chiptunese support and mixing channels: Added support for module audio music (.xm, .mod) loading and playing. Multiple mixing channels are now also supported. All this features thanks to the amazing work of @kd7tck.
Other additions include a [2D camera system](https://github.com/raysan5/raylib/blob/master/examples/core_2d_camera.c), render textures for offline render (and most comprehensive [postprocessing](https://github.com/raysan5/raylib/blob/master/examples/shaders_postprocessing.c)) or support for legacy OpenGL 2.1 on desktop platforms.
@ -119,17 +119,17 @@ notes on raylib 1.6
On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features:
Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
- Complete [raylib Lua binding](https://github.com/raysan5/raylib-lua). All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
- Completely redesigned [audio module](https://github.com/raysan5/raylib/blob/master/src/raudio.c). Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. [FLAC file format support](https://github.com/raysan5/raylib/blob/master/src/external/dr_flac.h) has also been added. In the same line, [OpenAL Soft](https://github.com/kcat/openal-soft) backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
[Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
- [Physac](https://github.com/victorfisac/Physac) module has been moved to its own repository and it has been improved A LOT, actually, library has been completely rewritten from scratch by [@victorfisac](https://github.com/victorfisac), multiple samples have been added together with countless new features to match current standard 2D physic libraries. Results are amazing!
Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples.
- Camera and gestures modules have been reviewed, highly simplified and ported to single-file header-only libraries for easier portability and usage flexibility. Consequently, camera system usage has been simplified in all examples.
Improved Gamepad support on Windows and Raspberry Pi with the addition of new functions for custom gamepad configurations but supporting by default PS3 and Xbox-based gamepads.
- Improved Gamepad support on Windows and Raspberry Pi with the addition of new functions for custom gamepad configurations but supporting by default PS3 and Xbox-based gamepads.
Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support.
- Improved textures and text functionality, adding new functions for texture filtering control and better TTF/AngelCode fonts loading and generation support.
Build system improvement. Added support for raylib dynamic library generation (raylib.dll) for users that prefer dynamic library linking. Also thinking on advance users, it has been added pre-configured [Visual Studio C++ 2015 solution](https://github.com/raysan5/raylib/tree/master/project/vs2015) with raylib project and C/C++ examples for users that prefer that professional IDE and compiler.
@ -140,15 +140,15 @@ notes on raylib 1.7
On May 2017, around 6 month after raylib 1.6, comes another raylib instalment, raylib 1.7. This time library has been improved a lot in terms of consistency and cleanness. As stated in [this patreon article](https://www.patreon.com/posts/raylib-future-7501034), this new raylib version has focused efforts in becoming more simple and easy-to-use to learn videogames programming. Some highlights of this new version are:
More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, funtions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions!
- More than 30 new functions added to the library, functions to control Window, utils to work with filenames and extensions, functions to draw lines with custom thick, mesh loading, functions for 3d ray collisions detailed detection, funtions for VR simulation and much more... Just check [CHANGELOG](CHANGELOG) for a detailed list of additions!
Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality.
- Support of [configuration flags](https://github.com/raysan5/raylib/issues/200) on every raylib module. Advance users can customize raylib just choosing desired features, defining some configuration flags on modules compilation. That way users can control library size and available functionality.
Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags.
- Improved [build system](https://github.com/raysan5/raylib/blob/master/src/Makefile) for all supported platforms (Windows, Linux, OSX, RPI, Android, HTML5) with a unique Makefile to compile sources. Added support for Android compilation with a custom standalone toolchain and also multiple build compliation flags.
New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems.
- New [examples](http://www.raylib.com/examples.html) and [sample games](http://www.raylib.com/games.html) added. All samples material has been reviewed, removing useless examples and adding more comprehensive ones; all material has been ported to latest raylib version and tested in multiple platforms. Examples folder structure has been improved and also build systems.
Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process...
- Improved library consistency and organization in general. Functions and parameters have been renamed, some parts of the library have been cleaned and simplyfied, some functions has been moved to examples (lighting, Oculus Rift CV1 support) towards a more generic library implementation. Lots of hours have been invested in this process...
Some other features: Gamepad support on HTML5, RPI touch screen support, 32bit audio support, frames timing improvements, public log system, rres file format support, automatic GIF recording...
@ -159,17 +159,17 @@ notes on raylib 1.8
October 2017, around 5 months after latest raylib version, another release is published: raylib 1.8. Again, several modules of the library have been reviewed and some new functionality added. Main changes of this new release are:
[Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
- [Procedural image generation](https://github.com/raysan5/raylib/blob/master/examples/textures/textures_image_generation.c) function, a set of new functions have been added to generate gradients, checked, noise and cellular images from scratch. Image generation could be useful for certain textures or learning pourpouses.
[Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
- [Parametric mesh generation](https://github.com/raysan5/raylib/blob/master/examples/models/models_mesh_generation.c) functions, create 3d meshes from scratch just defining a set of parameters, meshes like cube, sphere, cylinder, torus, knot and more can be very useful for prototyping or for lighting and texture testing.
PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
- PBR Materials support, a completely redesigned shaders and material system allows advance materials definition and usage, with fully customizable shaders. Some new functions have been added to generate the environment textures required for PBR shading and a a new complete [PBR material example](https://github.com/raysan5/raylib/blob/master/examples/models/models_material_pbr.c) is also provided for reference.
Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
- Custom Android APK build pipeline with [simple Makefile](https://github.com/raysan5/raylib/blob/master/templates/simple_game/Makefile). Actually, full code building mechanism based on plain Makefile has been completely reviewed and Android building has been added for sources and also for examples and templates building into final APK package. This way, raylib Android building has been greatly simplified and integrated seamlessly into standard build scripts.
[rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
- [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h) module has been completely reviewed and most of the functions renamed for consistency. This way, standalone usage of rlgl is promoted, with a [complete example provided](https://github.com/raysan5/raylib/blob/master/examples/others/rlgl_standalone.c). rlgl offers a pseudo-OpenGL 1.1 immediate-mode programming-style layer, with backends to multiple OpenGL versions.
[raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
- [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h) library has been also reviewed to align with other advance math libraries like [GLM](https://github.com/g-truc/glm). Matrix math has been improved and simplified, some new Quaternion functions have been added and Vector3 functions have been renamed all around the library for consistency with new Vector2 functionality.
Additionally, as always, examples and templates have been reviewed to work with new version (some new examples have been added), all external libraries have been updated to latest stable version and latest Notepad++ and MinGW have been configured to work with new raylib. For a full list of changes, just check [CHANGELOG](CHANGELOG).
@ -182,17 +182,17 @@ It's been 9 month since last raylib version was published, a lots of things have
In **raylib 2.0** the full API has been carefully reviewed for better consistency, some new functionality has been added and the overall raylib experience has been greatly improved... The key features of new version are:
**Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library.
- **Complete removal of external dependencies.** Finally, raylib does not require external libraries to be installed and linked along with raylib, all required libraries are contained and compiled within raylib. Obviously some external libraries are required but only the strictly platform-dependant ones, the ones that come installed with the OS. So, raylib becomes a self-contained platform-independent games development library.
**Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtly, the perfect low-level companion for raylib audio module!
- **Full redesign of audio module to use the amazing miniaudio library**, along with external dependencies removal, OpenAL library has been replaced by [miniaudio](https://github.com/dr-soft/miniaudio), this brand new library offers automatic dynamic linking with default OS audio systems. Undoubtly, the perfect low-level companion for raylib audio module!
**Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release!
- **Support for continuous integration building*** through AppVeyor and Travis CI. Consequently, raylib GitHub develop branch has been removed, simplyfing the code-base to a single master branch, always stable. Every time a new commit is deployed, library is compiled for **up-to 12 different configurations**, including multiple platforms, 32bit/64bit and multiple compiler options! All those binaries are automatically attached to any new release!
**More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib!
- **More platforms supported and tested**, including BSD family (FreeBSD, openBSD, NetBSD, DragonFly) and Linux-based family platforms (openSUSE, Debian, Ubuntu, Arch, NixOS...). raylib has already been added to some package managers! Oh, and last but not less important, **Android 64bit** is already supported by raylib!
**Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds!
- **Support for TCC compiler!** Thanks to the lack of external dependencies, raylib can now be easily compiled with a **minimal toolchain**, like the one provide by Tiny C Compiler. It opens the door to an amazing future, allowing, for example, static linkage of libtcc for **runtime compilation of raylib-based code**... and the library itself if required! Moreover, TCC is blazing fast, it can compile all raylib in a couple of seconds!
Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired!
- Refactored all raylib configuration #defines into a **centralized `config.h` header**, with more than **40 possible configuration options** to compile a totally customizable raylib version including only desired options like supported file-formats or specific functionality support. It allows generating a trully ligth-weight version of the library if desired!
A part of that, lots of new features, like a brand **new font rendering and packaging system** for TTF fonts with **SDF support** (thanks to the amazing STB headers), new functions for **CPU image data manipulation**, new orthographic 3d camera mode, a complete review of `raymath.h` single-file header-only library for better consistency and performance, new examples and way, [way more](https://github.com/raysan5/raylib/blob/master/CHANGELOG).
@ -203,25 +203,54 @@ notes on raylib 2.5
After almost one years since latest raylib installment, here it is **raylib 2.5**. A lot of work has been put on this new version and consequently I decided to bump versioning several digits. The complete list of changes and additions is humungous, details can be found in the [CHANGELOG](CHANGELOG), and here it is a short recap with the highlight improvements.
New **window management and filesystem functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag.
- New **window management and file system functions** to query monitor information, deal with clipboard, check directory files info and even launch a URL with default system web browser. Experimental **High-DPI monitor support** has also been added through a compile flag.
**Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations.
- **Redesigned Gamepad mechanism**, now generic for all platforms and gamepads, no more specific gamepad configurations.
**Redesigned UWP input system**, now raylib supports UWP seamlessly, previous implementation required a custom input system implemented in user code.
`rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour.
- `rlgl` module has been redesigned to **support a unique buffer for shapes drawing batching**, including LINES, TRIANGLES, QUADS in the same indexed buffer, also added support for multi-buffering if required. Additionally, `rlPushMatrix()`/`rlPopMatrix()` functionality has been reviewed to behave exactly like OpenGL 1.1, `models_rlgl_solar_system` example has been added to illustrate this behaviour.
**VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters.
- **VR simulator** has been reviewed to **allow custom configuration of Head-Mounted-Device parameters and distortion shader**, `core_vr_simulator` has been properly adapted to showcase this new functionality, now the VR simulator is a generic configurable stereo rendering system that allows any VR device simulation with just a few lines of code or even dynamic tweaking of HMD parameters.
Support for **Unicode text drawing**; now raylib processes UTF8 strings on drawing, supporting Unicode codepoints, allowing rendering mostly any existent language (as long as the font with the glyphs is provided). An amazing example showing this feature has also been added: `text_unicode`.
- Support for **Unicode text drawing**; now raylib processes UTF8 strings on drawing, supporting Unicode codepoints, allowing rendering mostly any existent language (as long as the font with the glyphs is provided). An amazing example showing this feature has also been added: `text_unicode`.
Brand **new text management API**, with the addition of multiple functions to deal with string data, including functionality like replace, insert, join, split, append, to uppercase, to lower... Note that most of those functions are intended for text management on rendering, using pre-loaded internal buffers, avoiding new memory allocation that user should free manually.
- Brand **new text management API**, with the addition of multiple functions to deal with string data, including functionality like replace, insert, join, split, append, to uppercase, to lower... Note that most of those functions are intended for text management on rendering, using pre-loaded internal buffers, avoiding new memory allocation that user should free manually.
Multiple **new shapes and textures drawing functions** to support rings (`DrawRing()`, `DrawRingLines()`), circle sectors (`DrawCircleSector()`, `DrawCircleSectorLines()`), rounded rectangles (`DrawRectangleRounded()`, `DrawRectangleRoundedLines()`) and also n-patch textures (`DrawTextureNPatch()`), detailed examples have been added to illustrate all this new functionality.
- Multiple **new shapes and textures drawing functions** to support rings (`DrawRing()`, `DrawRingLines()`), circle sectors (`DrawCircleSector()`, `DrawCircleSectorLines()`), rounded rectangles (`DrawRectangleRounded()`, `DrawRectangleRoundedLines()`) and also n-patch textures (`DrawTextureNPatch()`), detailed examples have been added to illustrate all this new functionality.
Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures.
- Experimental **cubemap support**, to automatically load multiple cubemap layouts (`LoadTextureCubemap()`). It required some internal `rlgl` redesign to allow cubemap textures.
**Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added.
- **Skeletal animation support for 3d models**, this addition implied a redesign of `Model` data structure to accomodate multiple mesh/multiple materials support and bones information. Multiple models functions have been reviewed and added on this process, also **glTF models loading support** has been added.
This is a just a brief list with some of the changes of the new **raylib 2.5** but there is way more, about **70 new functions** have been added and several subsystems have been redesigned. More than **30 new examples** have been created to show the new functionalities and better illustrate already available ones.
It has been a long year of hard work to make raylib a solid technology to develop new products over it.
notes on raylib 3.0
-------------------
After **10 months of intense development**, new raylib version is ready. Despite primary intended as a minor release, the [CHANGELIST](CHANGELOG) has grown so big and the library has changed so much internally that it finally became a major release. Library **internal ABI** has reveived a big redesign and review, targeting portability, integration with other platforms and making it a perfect option for other progamming [language bindings](BINDINGS.md).
- All **global variables** from the multiple raylib modules have been moved to a **global context state**, it has several benefits, first, better code readability with more comprehensive variables naming and categorization (organized by types, i.e. `CORE.Window.display.width`, `CORE.Input.Keyboard.currentKeyState` or `RLGL.State.modelview`). Second, it allows better memory management to load global context state dynamically when required (not at the moment), making it easy to implement a **hot-reloading mechanism** if desired.
- All **memory allocations** on raylib and its dependencies now use `RL_MALLOC`, `RL_FREE` and similar macros. Now users can easely hook their own memory allocations mechanism if desired, having more control over memory allocated internally by the library. Additionally, it makes it easier to port the library to embedded devices where memory control is critical. For more info check raylib issue #1074.
- All **I/O file accesses** from raylib are being moved to **memory data access**, now all I/O file access is centralized into just four functions: `LoadFileData()`, `SaveFileData()`, `LoadFileText()`, `SaveFileText()`. Users can just update those functions to any I/O file system. This change makes it easier to integrate raylib with **Virtual File Systems** or custom I/O file implementations.
- All **raylib data structures** have been reviewed and optimized for pass-by-value usage. One of raylib distinctive design decisions is that most of its functions receive and return data by value. This design makes raylib really simple for newcomers, avoiding pointers and allowing complete access to all structures data in a simple way. The downside is that data is copied on stack every function call and that copy could be costly so, all raylib data structures have been optimized to **stay under 64 bytes** for fast copy and retrieve.
- All **raylib tracelog messages** have been reviewd and categorized for a more comprehensive output information when developing raylib applications, now all display, input, timer, platform, auxiliar libraries, file-accesses, data loading/unloading issues are properly reported with more detailed and visual messages.
- `raudio` module has been internally reviewed to accomodate the new `Music` structure (converted from previous pointer format) and the module has been adapted to the **highly improved** [`miniaudio v0.10`](https://github.com/dr-soft/miniaudio).
- `text` module reviewed to **improve fonts generation** and text management functions, `Font` structure has been redesigned to better accomodate characters data, decoupling individual characters as `Image` glyphs from the font atlas parameters. Several improvements have been made to better support Unicode strings with UTF-8 encoding.
- **Multiple new examples added** (most of them contributed by raylib users) and all examples reviewed for correct execution on most of the supported platforms, specially Web and Raspberry Pi. A detailed categorized table has been created on github for easy examples navigation and code access.
- New **GitHub Actions CI** system has been implemented for Windows, Linux and macOS code and examples compilation on every new commit or PR to make sure library keeps stable and usable with no breaking bugs.
Note that only key changes are listed here but there is way more! About **30 new functions**, multiple functions reviewed, bindings to [+40 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md) and great samples/demos/tutorials [created by the community](https://discord.gg/VkzNHUE), including raylib integration with [Spine](https://github.com/WEREMSOFT/spine-raylib-runtimes), [Unity](https://unitycoder.com/blog/2019/12/09/using-raylib-dll-in-unity/), [Tiled](https://github.com/OnACoffeeBreak/raylib_tiled_import_with_tmx), [Nuklear](http://bedroomcoders.co.uk/implementing-a-3d-gui-with-raylib/), [enet](https://github.com/nxrighthere/NetDynamics) and [more](https://github.com/raysan5/raylib/issues/1079)!
It has been **10 months of improvements** to create the best raylib ever.
Welcome to **raylib 3.0**.

View File

@ -8,11 +8,20 @@ raylib is highly inspired by Borland BGI graphics lib and by XNA framework and i
Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
[![Build Status](https://travis-ci.org/raysan5/raylib.svg?branch=master)](https://travis-ci.org/raysan5/raylib)
[![https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true](https://ci.appveyor.com/api/projects/status/github/raysan5/raylib?svg=true)](https://ci.appveyor.com/project/raysan5/raylib)
[![Chat on Discord](https://img.shields.io/discord/426912293134270465.svg?logo=discord)](https://discord.gg/VkzNHUE)
<br>
[![GitHub contributors](https://img.shields.io/github/contributors/raysan5/raylib)](https://github.com/raysan5/raylib/graphs/contributors)
[![GitHub All Releases](https://img.shields.io/github/downloads/raysan5/raylib/total)](https://github.com/raysan5/raylib/releases)
[![GitHub commits since tagged version](https://img.shields.io/github/commits-since/raysan5/raylib/3.0.0)](https://github.com/raysan5/raylib/commits/master)
[![License](https://img.shields.io/badge/license-zlib%2Flibpng-blue.svg)](LICENSE)
[![Twitter URL](https://img.shields.io/twitter/url/http/shields.io.svg?style=social&label=Follow)](https://twitter.com/raysan5)
[![Chat on Discord](https://img.shields.io/discord/426912293134270465.svg?logo=discord)](https://discord.gg/VkzNHUE)
[![GitHub stars](https://img.shields.io/github/stars/raysan5/raylib?style=social)](https://github.com/raysan5/raylib/stargazers)
[![Twitter Follow](https://img.shields.io/twitter/follow/raysan5?style=social)](https://twitter.com/raysan5)
[![Subreddit subscribers](https://img.shields.io/reddit/subreddit-subscribers/raylib?style=social)](https://www.reddit.com/r/raylib/)
[![Travis (.org)](https://img.shields.io/travis/raysan5/raylib?label=Travis%20CI%20Build%20Status%20-%20Linux,%20OSX,%20Android,%20Windows)](https://travis-ci.org/raysan5/raylib)
[![AppVeyor](https://img.shields.io/appveyor/build/raysan5/raylib?label=AppVeyor%20CI%20Build%20Status%20-%20Windows%20(mingw,%20msvc15))](https://ci.appveyor.com/project/raysan5/raylib)
[![Actions Status](https://github.com/raysan5/raylib/workflows/CI%20-%20Source%20&%20Examples%20-%20Windows/badge.svg)](https://github.com/raysan5/raylib/actions)
[![Actions Status](https://github.com/raysan5/raylib/workflows/CI%20-%20Source%20&%20Examples%20-%20Linux/badge.svg)](https://github.com/raysan5/raylib/actions)
@ -21,46 +30,77 @@ Ready to learn? Jump to [code examples!](http://www.raylib.com/examples.html)
features
--------
- **NO external dependencies**, all required libraries are bundled into raylib
- Multiple platforms supported: **Windows, Linux, MacOS, Android... and many more!**
- Multiple platforms supported: **Windows, Linux, MacOS, Android, HTML5... and more!**
- Written in plain C code (C99) in PascalCase/camelCase notation
- Hardware accelerated with OpenGL (**1.1, 2.1, 3.3 or ES 2.0**)
- **Unique OpenGL abstraction layer** (usable as standalone module): [rlgl](https://github.com/raysan5/raylib/blob/master/src/rlgl.h)
- Multiple **Fonts** formats supported (XNA fonts, AngelCode fonts, TTF)
- Multiple **Fonts** formats supported (TTF, XNA fonts, AngelCode fonts)
- Outstanding texture formats support, including compressed formats (DXT, ETC, ASTC)
- **Full 3D support**, including 3D Shapes, Models, Billboards, Heightmaps and more!
- Flexible Materials system, supporting classic maps and **PBR maps**
- **Animated 3D models** supported (skeletal bones animation)
- Shaders support, including model and postprocessing shaders.
- Shaders support, including model and **postprocessing** shaders.
- **Powerful math module** for Vector, Matrix and Quaternion operations: [raymath](https://github.com/raysan5/raylib/blob/master/src/raymath.h)
- Audio loading and playing with streaming support (WAV, OGG, MP3, FLAC, XM, MOD)
- **VR stereo rendering** support with configurable HMD device parameters
- Huge examples collection with [+95 code examples](https://www.raylib.com/examples.html)!
- Bindings to [+25 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
- Huge examples collection with [+115 code examples](https://github.com/raysan5/raylib/tree/master/examples)!
- Bindings to [+40 programming languages](https://github.com/raysan5/raylib/blob/master/BINDINGS.md)!
- Free and open source.
raylib uses on its [core](https://github.com/raysan5/raylib/blob/master/src/core.c) module the outstanding [GLFW3](http://www.glfw.org/) library, embedded in the form of [rglfw](https://github.com/raysan5/raylib/blob/master/src/rglfw.c) module, to avoid external dependencies.
raylib uses on its [raudio](https://github.com/raysan5/raylib/blob/master/src/raudio.c) module, the amazing [miniaudio](https://github.com/dr-soft/miniaudio) library to support multiple platforms and multiple audio backends.
raylib uses internally multiple single-file header-only libraries to support different fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies) for a detailed list.
raylib uses internally several single-file header-only libraries to support different fileformats loading and saving, all those libraries are embedded with raylib and available in [src/external](https://github.com/raysan5/raylib/tree/master/src/external) directory. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki/raylib-dependencies) for a detailed list.
*On Android platform, `native_app_glue module` module (provided by Android NDK) and native Android libraries are used to manage window/context, inputs and activity life cycle.*
*On Android platform, `native_app_glue` module (provided by Android NDK) and native Android libraries are used to manage window/context, inputs and activity life cycle.*
*On Raspberry Pi platform (native mode), `Videocore API` and `EGL` libraries are used for window/context management. Inputs are processed using `evdev` Linux libraries*
*On Web platform, raylib uses `emscripten` provided libraries for several input events management, specially noticeable the touch events support.*
build and installation
----------------------
Binary releases for Windows, Linux and macOS are available at the [Github Releases page](https://github.com/raysan5/raylib/releases). raylib is also available via multiple package managers on multiple OS distributions. Check [raylib Wiki](https://github.com/raysan5/raylib/wiki) for more info.
raylib binary releases for Windows, Linux and macOS are available at the [Github Releases page](https://github.com/raysan5/raylib/releases).
If you wish to build raylib yourself, [the raylib Wiki](https://github.com/raysan5/raylib/wiki) also contains detailed instructions on how to approach that.
raylib is also available via multiple [package managers](https://github.com/raysan5/raylib/issues/613) on multiple OS distributions.
raylib has been developed using two tools:
#### Installing and building raylib via vcpkg
* Notepad++ (text editor) - [http://notepad-plus-plus.org](http://notepad-plus-plus.org/)
* MinGW (GCC compiler) - [http://www.mingw.org](http://www.mingw.org/)
You can download and install raylib using the [vcpkg](https://github.com/Microsoft/vcpkg) dependency manager:
Those are the tools recommended to enjoy raylib development.
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
vcpkg install raylib
*The raylib port in vcpkg is kept up to date by Microsoft team members and community contributors. If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.*
#### Building raylib on multiple platforms
[raylib Wiki](https://github.com/raysan5/raylib/wiki#development-platforms) contains detailed instructions on building and usage on multiple platforms.
- [Working on Windows](https://github.com/raysan5/raylib/wiki/Working-on-Windows)
- [Working on macOS](https://github.com/raysan5/raylib/wiki/Working-on-macOS)
- [Working on GNU Linux](https://github.com/raysan5/raylib/wiki/Working-on-GNU-Linux)
- [Working on FreeBSD](https://github.com/raysan5/raylib/wiki/Working-on-FreeBSD)
- [Working on Raspberry Pi](https://github.com/raysan5/raylib/wiki/Working-on-Raspberry-Pi)
- [Working for Android](https://github.com/raysan5/raylib/wiki/Working-for-Android)
- [Working for Web (HTML5)](https://github.com/raysan5/raylib/wiki/Working-for-Web-(HTML5))
- [Working for UWP (Universal Window Platform)](https://github.com/raysan5/raylib/wiki/Working-for-UWP)
- [Working anywhere with CMake](https://github.com/raysan5/raylib/wiki/Working-with-CMake)
*Note that Wiki is open for edit, if you find some issue while building raylib for your target platform, feel free to edit the Wiki or open and issue related to it.*
#### Using raylib with multiple IDEs
raylib has been developed on Windows platform using [Notepad++](https://notepad-plus-plus.org/) and [MinGW GCC](http://mingw-w64.org/doku.php) compiler but it can be used with other IDEs on multiple platforms.
[Projects directory](https://github.com/raysan5/raylib/tree/master/projects) contains several ready-to-use **project templates** to build raylib and code examples with multiple IDEs.
*Note that there are lots of IDEs supported, some of the provided templates could require some review, please, if you find some issue with some template or you think they could be improved, feel free to send a PR or open a related issue.*
contact
-------
@ -73,9 +113,9 @@ contact
* Patreon: [https://www.patreon.com/raylib](https://www.patreon.com/raylib)
* YouTube: [https://www.youtube.com/channel/raylib](https://www.youtube.com/channel/UC8WIBkhYb5sBNqXO1mZ7WSQ)
If you are using raylib and you enjoy it, please, join our [Discord server](https://discord.gg/VkzNHUE).
If you are using raylib and enjoying it, please, join our [Discord server](https://discord.gg/VkzNHUE) and let us know! :)
license
-------
raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](LICENSE.md) for further details.
raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, BSD-like license that allows static linking with closed source software. Check [LICENSE](LICENSE) for further details.

View File

@ -3,18 +3,19 @@ roadmap
Here it is a wish-list with features and ideas to improve the library. Note that features listed here are quite high-level and could be long term additions for the library. Current version of raylib is complete and functional but there is a lot of room for improvement.
[raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
[raylib source code](https://github.com/raysan5/raylib/tree/master/src) has some *TODO* marks around code with pending things to review and improve. Check also [GitHub Issues](https://github.com/raysan5/raylib/issues) for further details!
**raylib 3.x**
- [ ] Network module (UDP): `rnet` ([info](https://github.com/raysan5/raylib/issues/753))
- [ ] Custom raylib resource packer: `rres` ([info](https://github.com/raysan5/rres))
- [ ] Trace log messages redesign ([info](https://github.com/raysan5/raylib/issues/1065))
- [ ] Basic CPU/GPU stats system (memory, draws, time...)
- [ ] Continuous Deployment using GitHub Actions
**raylib 3.0**
- [x] Custom memory allocators support
- [x] Global variables moved to global context
- [x] Optimize data structures for pass-by-value
- [x] Custom memory allocators support: `rmem`
- [x] Trace log messages redesign ([info](https://github.com/raysan5/raylib/issues/1065))
- [x] Continuous Integration using GitHub Actions
**raylib 2.5**

View File

@ -6,8 +6,27 @@ The following people has contributed with a generous donation to the raylib proj
## 🥈 Silver Contributors
...
- Jonathan Johnson ([@ecton](https://github.com/ecton))
- Eric J. ([@ProfJski](https://github.com/ProfJski))
## 🥉 Bronze Contributors
...
- minirop ([@minirop](https://github.com/minirop))
- Marc Agüera ([@maguera93](https://github.com/maguera93))
- Daniel Gómez ([@Koocachookies](https://github.com/Koocachookies))
- Sergio ([@anidealgift](https://github.com/anidealgift))
- Pau Fernández ([@pauek](https://github.com/pauek))
- Terry Nguyen ([@terrehbyte](https://github.com/terrehbyte))
- albatros-hmd ([@albatros-hmd](https://github.com/albatros-hmd))
- Grant Haywood ([@cinterloper](https://github.com/cinterloper))
- Robin Mattheussen ([@romatthe](https://github.com/romatthe))
- NimbusFox ([@NimbusFox](https://github.com/NimbusFox))
- Louis Johnson ([@louisgjohnson](https://github.com/louisgjohnson))
- JFons ([@JFonS](https://github.com/JFonS))
- Benjamin Stigsen ([@BenStigsen](https://github.com/BenStigsen))
- Rahul Nair ([@rahulunair](https://github.com/rahulunair))
- Snowminx ([@Gamerfiend](https://github.com/Gamerfiend))
- Dani Martin ([@danimartin82](https://github.com/danimartin82))
- Tommi Sinivuo ([@TommiSinivuo](https://github.com/TommiSinivuo))
- Joakim Wennergren ([@joakimwennergren](https://github.com/joakimwennergren))

View File

@ -39,7 +39,7 @@ before_build:
- cd build
build_script:
- cmake -G %GENERATOR% -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DBUILD_GAMES=%examples% -DINCLUDE_EVERYTHING=ON ..
- cmake -G %GENERATOR% -DCMAKE_BUILD_TYPE=Release -DSTATIC=ON -DSHARED=ON -DBUILD_EXAMPLES=%examples% -DINCLUDE_EVERYTHING=ON ..
- cmake --build . --target install
after_build:

View File

@ -1,13 +0,0 @@
# Populates a ${FILESYSTEM_LACKS_SYMLINKS} variable
message(STATUS "Testing if file system supports symlinks")
execute_process(
COMMAND ${CMAKE_COMMAND} -E create_symlink CMakeLists.txt "${CMAKE_CURRENT_BINARY_DIR}/TestingIfSymlinkWorks"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE FILESYSTEM_LACKS_SYMLINKS
)
If (FILESYSTEM_LACKS_SYMLINKS)
message(STATUS "Testing if file system supports symlinks -- unsupported")
else()
message(STATUS "Testing if file system supports symlinks -- supported")
endif()

View File

@ -81,7 +81,7 @@ if(${PLATFORM} MATCHES "Android")
list(REMOVE_ITEM example_sources ${CMAKE_CURRENT_SOURCE_DIR}/shaders/shaders_basic_lighting.c)
elseif(${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s ASYNCIFY")
# Since WASM is used, ALLOW_MEMORY_GROWTH has no extra overheads
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -s ALLOW_MEMORY_GROWTH=1 --no-heap-copy")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")

View File

@ -25,8 +25,8 @@
# Define required raylib variables
PROJECT_NAME ?= raylib_examples
RAYLIB_VERSION ?= 2.5.0
RAYLIB_API_VERSION ?= 2
RAYLIB_VERSION ?= 3.0.0
RAYLIB_API_VERSION ?= 3
RAYLIB_PATH ?= ..
# Define default options
@ -456,7 +456,8 @@ SHADERS = \
shaders/shaders_eratosthenes \
shaders/shaders_basic_lighting \
shaders/shaders_fog \
shaders/shaders_simple_mask
shaders/shaders_simple_mask \
shaders/shaders_spotlight
AUDIO = \
audio/audio_module_playing \

View File

@ -26,8 +26,10 @@ PLATFORM ?= PLATFORM_ANDROID
RAYLIB_PATH ?= ..\..
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
# Starting in 2019 using ARM64 is mandatory for published apps,
# and minimum required target API is Android 9 (API level 28)
ANDROID_ARCH ?= ARM
ANDROID_API_VERSION = 21
ANDROID_API_VERSION = 28
ifeq ($(ANDROID_ARCH),ARM)
ANDROID_ARCH_NAME = armeabi-v7a
endif
@ -36,11 +38,11 @@ ifeq ($(ANDROID_ARCH),ARM64)
endif
# Required path variables
# NOTE: JAVA_HOME must be set to JDK
JAVA_HOME ?= C:/JavaJDK
# NOTE: JAVA_HOME must be set to JDK (using OpenJDK 13)
JAVA_HOME ?= C:/open-jdk
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_TOOLCHAIN = C:/android-ndk-r21/toolchains/llvm/prebuilt/windows-x86_64
ANDROID_BUILD_TOOLS = $(ANDROID_HOME)/build-tools/29.0.3
ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
# Android project configuration variables
@ -81,13 +83,12 @@ ifeq ($(RAYLIB_LIBTYPE),SHARED)
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
CC = $(ANDROID_TOOLCHAIN)/bin/armv7a-linux-androideabi$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
endif
ifeq ($(ANDROID_ARCH),ARM64)
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android$(ANDROID_API_VERSION)-clang
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
endif
@ -226,7 +227,7 @@ generate_android_manifest:
# 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
if not exist $(PROJECT_BUILD_PATH)/$(PROJECT_NAME).keystore $(JAVA_HOME)/bin/keytool -genkeypair -validity 10000 -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
@ -274,7 +275,7 @@ zipalign_project_apk_package:
# 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
$(ANDROID_PLATFORM_TOOLS)/adb install $(PROJECT_NAME).apk
# Check supported ABI for the device (armeabi-v7a, arm64-v8a, x86, x86_64)
check_device_abi:

View File

@ -185,7 +185,7 @@ Examples showing raylib misc functionality that does not fit in other categories
|----|----------|--------|:----------:|:---:|
| 113 | [raudio_standalone](others/raudio_standalone.c) | | ray | |
| 114 | [rlgl_standalone](others/rlgl_standalone.c) | | ray | |
| 115 | [easings_testbed](others/easings_testbed.c) | | ray | |
| 115 | [easings_testbed](others/easings_testbed.c) | | [Juan Miguel López](https://github.com/flashback-fx) | |
As always contributions are welcome, feel free to send new examples! Here it is an [examples template](examples_template.c) to start with!

View File

@ -51,6 +51,7 @@ int main(void)
}
Music music = LoadMusicStream("resources/mini1111.xm");
music.looping = false;
PlayMusicStream(music);

View File

@ -4,18 +4,19 @@
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* To test examples in Notepad++, provided with default raylib installer package,
* just press F6 and run [raylib_compile_execute] script, it will compile and execute.
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
* You can find all basic examples on [C:\raylib\raylib\examples] directory and
* raylib official webpage: [www.raylib.com]
*
* Enjoy using raylib. :)
*
* This example has been created using raylib 1.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2013-2016 Ramon Santamaria (@raysan5)
* Copyright (c) 2013-2020 Ramon Santamaria (@raysan5)
*
********************************************************************************************/

View File

@ -92,13 +92,13 @@ int main(void)
DrawCircle(259, 152, 39, BLACK);
DrawCircle(259, 152, 34, LIGHTGRAY);
DrawCircle(259 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_X)*20),
152 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
152 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_LEFT_Y)*20), 25, BLACK);
// Draw axis: right joystick
DrawCircle(461, 237, 38, BLACK);
DrawCircle(461, 237, 33, LIGHTGRAY);
DrawCircle(461 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_X)*20),
237 - (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
237 + (GetGamepadAxisMovement(GAMEPAD_PLAYER1, GAMEPAD_AXIS_RIGHT_Y)*20), 25, BLACK);
// Draw axis: left-right triggers
DrawRectangle(170, 30, 15, 70, GRAY);

View File

@ -13,6 +13,8 @@
#include "raylib.h"
#define MAX_TOUCH_POINTS 10
int main(void)
{
// Initialization

View File

@ -1,6 +1,6 @@
/*******************************************************************************************
*
* raylib [core] example - window scale letterbox
* raylib [core] example - window scale letterbox (and virtual mouse)
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -16,6 +16,18 @@
#define max(a, b) ((a)>(b)? (a) : (b))
#define min(a, b) ((a)<(b)? (a) : (b))
// Clamp Vector2 value with min and max and return a new vector2
// NOTE: Required for virtual mouse, to clamp inside virtual game size
Vector2 ClampValue(Vector2 value, Vector2 min, Vector2 max)
{
Vector2 result = value;
result.x = (result.x > max.x)? max.x : result.x;
result.x = (result.x < min.x)? min.x : result.x;
result.y = (result.y > max.y)? max.y : result.y;
result.y = (result.y < min.y)? min.y : result.y;
return result;
}
int main(void)
{
const int windowWidth = 800;
@ -52,6 +64,13 @@ int main(void)
// Recalculate random colors for the bars
for (int i = 0; i < 10; i++) colors[i] = (Color){ GetRandomValue(100, 250), GetRandomValue(50, 150), GetRandomValue(10, 100), 255 };
}
// Update virtual mouse (clamped mouse value behind game screen)
Vector2 mouse = GetMousePosition();
Vector2 virtualMouse = { 0 };
virtualMouse.x = (mouse.x - (GetScreenWidth() - (gameScreenWidth*scale))*0.5f)/scale;
virtualMouse.y = (mouse.y - (GetScreenHeight() - (gameScreenHeight*scale))*0.5f)/scale;
virtualMouse = ClampValue(virtualMouse, (Vector2){ 0, 0 }, (Vector2){ gameScreenWidth, gameScreenHeight });
//----------------------------------------------------------------------------------
// Draw
@ -68,6 +87,9 @@ int main(void)
DrawText("If executed inside a window,\nyou can resize the window,\nand see the screen scaling!", 10, 25, 20, WHITE);
DrawText(TextFormat("Default Mouse: [%i , %i]", (int)mouse.x, (int)mouse.y), 350, 25, 20, GREEN);
DrawText(TextFormat("Virtual Mouse: [%i , %i]", (int)virtualMouse.x, (int)virtualMouse.y), 350, 55, 20, YELLOW);
EndTextureMode();
// Draw RenderTexture2D to window, properly scaled

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 23 KiB

View File

@ -20,7 +20,7 @@
*
* LICENSE: zlib/libpng
*
* Copyright (c) 2015-2017 Ramon Santamaria (@raysan5)
* Copyright (c) 2015-2020 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.
@ -135,7 +135,7 @@
typedef struct float3 { float v[3]; } float3;
typedef struct float16 { float v[16]; } float16;
#include <math.h> // Required for: sinf(), cosf(), tan(), fabs()
#include <math.h> // Required for: sinf(), cosf(), sqrtf(), tan(), fabs()
//----------------------------------------------------------------------------------
// Module Functions Definition - Utils math
@ -148,7 +148,7 @@ RMDEF float Clamp(float value, float min, float max)
return res > max ? max : res;
}
// Calculate linear interpolation between two vectors
// Calculate linear interpolation between two floats
RMDEF float Lerp(float start, float end, float amount)
{
return start + amount*(end - start);
@ -179,6 +179,13 @@ RMDEF Vector2 Vector2Add(Vector2 v1, Vector2 v2)
return result;
}
// Add vector and float value
RMDEF Vector2 Vector2AddValue(Vector2 v, float add)
{
Vector2 result = { v.x + add, v.y + add };
return result;
}
// Subtract two vectors (v1 - v2)
RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
{
@ -186,6 +193,13 @@ RMDEF Vector2 Vector2Subtract(Vector2 v1, Vector2 v2)
return result;
}
// Subtract vector by float value
RMDEF Vector2 Vector2SubtractValue(Vector2 v, float sub)
{
Vector2 result = { v.x - sub, v.y - sub };
return result;
}
// Calculate vector length
RMDEF float Vector2Length(Vector2 v)
{
@ -223,7 +237,7 @@ RMDEF Vector2 Vector2Scale(Vector2 v, float scale)
}
// Multiply vector by vector
RMDEF Vector2 Vector2MultiplyV(Vector2 v1, Vector2 v2)
RMDEF Vector2 Vector2Multiply(Vector2 v1, Vector2 v2)
{
Vector2 result = { v1.x*v2.x, v1.y*v2.y };
return result;
@ -236,15 +250,8 @@ RMDEF Vector2 Vector2Negate(Vector2 v)
return result;
}
// Divide vector by a float value
RMDEF Vector2 Vector2Divide(Vector2 v, float div)
{
Vector2 result = { v.x/div, v.y/div };
return result;
}
// Divide vector by vector
RMDEF Vector2 Vector2DivideV(Vector2 v1, Vector2 v2)
RMDEF Vector2 Vector2Divide(Vector2 v1, Vector2 v2)
{
Vector2 result = { v1.x/v2.x, v1.y/v2.y };
return result;
@ -253,7 +260,7 @@ RMDEF Vector2 Vector2DivideV(Vector2 v1, Vector2 v2)
// Normalize provided vector
RMDEF Vector2 Vector2Normalize(Vector2 v)
{
Vector2 result = Vector2Divide(v, Vector2Length(v));
Vector2 result = Vector2Scale(v, 1/Vector2Length(v));
return result;
}
@ -268,6 +275,14 @@ RMDEF Vector2 Vector2Lerp(Vector2 v1, Vector2 v2, float amount)
return result;
}
// Rotate Vector by float in Degrees.
RMDEF Vector2 Vector2Rotate(Vector2 v, float degs)
{
float rads = degs*DEG2RAD;
Vector2 result = {v.x * cosf(rads) - v.y * sinf(rads) , v.x * sinf(rads) + v.y * cosf(rads) };
return result;
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Vector3 math
//----------------------------------------------------------------------------------
@ -293,6 +308,13 @@ RMDEF Vector3 Vector3Add(Vector3 v1, Vector3 v2)
return result;
}
// Add vector and float value
RMDEF Vector3 Vector3AddValue(Vector3 v, float add)
{
Vector3 result = { v.x + add, v.y + add, v.z + add };
return result;
}
// Subtract two vectors
RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
{
@ -300,15 +322,22 @@ RMDEF Vector3 Vector3Subtract(Vector3 v1, Vector3 v2)
return result;
}
// Subtract vector by float value
RMDEF Vector3 Vector3SubtractValue(Vector3 v, float sub)
{
Vector3 result = { v.x - sub, v.y - sub, v.z - sub };
return result;
}
// Multiply vector by scalar
RMDEF Vector3 Vector3Multiply(Vector3 v, float scalar)
RMDEF Vector3 Vector3Scale(Vector3 v, float scalar)
{
Vector3 result = { v.x*scalar, v.y*scalar, v.z*scalar };
return result;
}
// Multiply vector by vector
RMDEF Vector3 Vector3MultiplyV(Vector3 v1, Vector3 v2)
RMDEF Vector3 Vector3Multiply(Vector3 v1, Vector3 v2)
{
Vector3 result = { v1.x*v2.x, v1.y*v2.y, v1.z*v2.z };
return result;
@ -371,13 +400,6 @@ RMDEF float Vector3Distance(Vector3 v1, Vector3 v2)
return result;
}
// Scale provided vector
RMDEF Vector3 Vector3Scale(Vector3 v, float scale)
{
Vector3 result = { v.x*scale, v.y*scale, v.z*scale };
return result;
}
// Negate provided vector (invert direction)
RMDEF Vector3 Vector3Negate(Vector3 v)
{
@ -385,15 +407,8 @@ RMDEF Vector3 Vector3Negate(Vector3 v)
return result;
}
// Divide vector by a float value
RMDEF Vector3 Vector3Divide(Vector3 v, float div)
{
Vector3 result = { v.x / div, v.y / div, v.z / div };
return result;
}
// Divide vector by vector
RMDEF Vector3 Vector3DivideV(Vector3 v1, Vector3 v2)
RMDEF Vector3 Vector3Divide(Vector3 v1, Vector3 v2)
{
Vector3 result = { v1.x/v2.x, v1.y/v2.y, v1.z/v2.z };
return result;
@ -440,7 +455,7 @@ RMDEF Vector3 Vector3Transform(Vector3 v, Matrix mat)
result.z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14;
return result;
};
}
// Transform a vector by quaternion rotation
RMDEF Vector3 Vector3RotateByQuaternion(Vector3 v, Quaternion q)
@ -553,15 +568,13 @@ RMDEF float3 Vector3ToFloatV(Vector3 v)
// Compute matrix determinant
RMDEF float MatrixDeterminant(Matrix mat)
{
float result = { 0 };
// Cache the matrix values (speed optimization)
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
float a30 = mat.m12, a31 = mat.m13, a32 = mat.m14, a33 = mat.m15;
result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
float result = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
@ -794,6 +807,33 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
return result;
}
// Returns xyz-rotation matrix (angles in radians)
RMDEF Matrix MatrixRotateXYZ(Vector3 ang)
{
Matrix result = MatrixIdentity();
float cosz = cosf(-ang.z);
float sinz = sinf(-ang.z);
float cosy = cosf(-ang.y);
float siny = sinf(-ang.y);
float cosx = cosf(-ang.x);
float sinx = sinf(-ang.x);
result.m0 = cosz * cosy;
result.m4 = (cosz * siny * sinx) - (sinz * cosx);
result.m8 = (cosz * siny * cosx) + (sinz * sinx);
result.m1 = sinz * cosy;
result.m5 = (sinz * siny * sinx) + (cosz * cosx);
result.m9 = (sinz * siny * cosx) - (cosz * sinx);
result.m2 = -siny;
result.m6 = cosy * sinx;
result.m10= cosy * cosx;
return result;
}
// Returns x-rotation matrix (angle in radians)
RMDEF Matrix MatrixRotateX(float angle)
{
@ -1014,6 +1054,34 @@ RMDEF float16 MatrixToFloatV(Matrix mat)
// Module Functions Definition - Quaternion math
//----------------------------------------------------------------------------------
// Add two quaternions
RMDEF Quaternion QuaternionAdd(Quaternion q1, Quaternion q2)
{
Quaternion result = {q1.x + q2.x, q1.y + q2.y, q1.z + q2.z, q1.w + q2.w};
return result;
}
// Add quaternion and float value
RMDEF Quaternion QuaternionAddValue(Quaternion q, float add)
{
Quaternion result = {q.x + add, q.y + add, q.z + add, q.w + add};
return result;
}
// Subtract two quaternions
RMDEF Quaternion QuaternionSubtract(Quaternion q1, Quaternion q2)
{
Quaternion result = {q1.x - q2.x, q1.y - q2.y, q1.z - q2.z, q1.w - q2.w};
return result;
}
// Subtract quaternion and float value
RMDEF Quaternion QuaternionSubtractValue(Quaternion q, float sub)
{
Quaternion result = {q.x - sub, q.y - sub, q.z - sub, q.w - sub};
return result;
}
// Returns identity quaternion
RMDEF Quaternion QuaternionIdentity(void)
{
@ -1082,6 +1150,28 @@ RMDEF Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2)
return result;
}
// Scale quaternion by float value
RMDEF Quaternion QuaternionScale(Quaternion q, float mul)
{
Quaternion result = { 0 };
float qax = q.x, qay = q.y, qaz = q.z, qaw = q.w;
result.x = qax * mul + qaw * mul + qay * mul - qaz * mul;
result.y = qay * mul + qaw * mul + qaz * mul - qax * mul;
result.z = qaz * mul + qaw * mul + qax * mul - qay * mul;
result.w = qaw * mul - qax * mul - qay * mul - qaz * mul;
return result;
}
// Divide two quaternions
RMDEF Quaternion QuaternionDivide(Quaternion q1, Quaternion q2)
{
Quaternion result = {q1.x / q2.x, q1.y / q2.y, q1.z / q2.z, q1.w / q2.w};
return result;
}
// Calculate linear interpolation between two quaternions
RMDEF Quaternion QuaternionLerp(Quaternion q1, Quaternion q2, float amount)
{
@ -1115,8 +1205,8 @@ RMDEF Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
else if (cosHalfTheta > 0.95f) result = QuaternionNlerp(q1, q2, amount);
else
{
float halfTheta = (float) acos(cosHalfTheta);
float sinHalfTheta = (float) sqrt(1.0f - cosHalfTheta*cosHalfTheta);
float halfTheta = acosf(cosHalfTheta);
float sinHalfTheta = sqrtf(1.0f - cosHalfTheta*cosHalfTheta);
if (fabs(sinHalfTheta) < 0.001f)
{
@ -1171,7 +1261,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
if (trace > 0.0f)
{
float s = (float)sqrt(trace + 1)*2.0f;
float s = sqrtf(trace + 1)*2.0f;
float invS = 1.0f/s;
result.w = s*0.25f;
@ -1195,7 +1285,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
}
else if (m11 > m22)
{
float s = (float)sqrt(1.0f + m11 - m00 - m22)*2.0f;
float s = sqrtf(1.0f + m11 - m00 - m22)*2.0f;
float invS = 1.0f/s;
result.w = (mat.m8 - mat.m2)*invS;
@ -1205,7 +1295,7 @@ RMDEF Quaternion QuaternionFromMatrix(Matrix mat)
}
else
{
float s = (float)sqrt(1.0f + m22 - m00 - m11)*2.0f;
float s = sqrtf(1.0f + m22 - m00 - m11)*2.0f;
float invS = 1.0f/s;
result.w = (mat.m1 - mat.m4)*invS;
@ -1295,10 +1385,8 @@ RMDEF void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle
if (fabs(q.w) > 1.0f) q = QuaternionNormalize(q);
Vector3 resAxis = { 0.0f, 0.0f, 0.0f };
float resAngle = 0.0f;
resAngle = 2.0f*(float)acos(q.w);
float den = (float)sqrt(1.0f - q.w*q.w);
float resAngle = 2.0f*acosf(q.w);
float den = sqrtf(1.0f - q.w*q.w);
if (den > 0.0001f)
{

View File

@ -37,7 +37,6 @@ int main(void)
camera.fovy = 45.0f; // Camera field-of-view Y
camera.type = CAMERA_PERSPECTIVE; // Camera mode type
Model model = LoadModel("resources/guy/guy.iqm"); // Load the animated model mesh and basic data
Texture2D texture = LoadTexture("resources/guy/guytex.png"); // Load model texture and set material
SetMaterialTexture(&model.materials[0], MAP_DIFFUSE, texture); // Set model material map texture

View File

@ -2,6 +2,9 @@
*
* raylib [models] example - PBR material
*
* NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
* is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
*
* This example has been created using raylib 1.8 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*

1466
examples/models/raymath.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,219 +0,0 @@
{
"asset": {
"generator": "COLLADA2GLTF",
"version": "2.0"
},
"scene": 0,
"scenes": [
{
"nodes": [
0
]
}
],
"nodes": [
{
"children": [
2,
1
],
"matrix": [
0.009999999776482582,
0.0,
0.0,
0.0,
0.0,
0.009999999776482582,
0.0,
0.0,
0.0,
0.0,
0.009999999776482582,
0.0,
0.0,
0.0,
0.0,
1.0
]
},
{
"matrix": [
-0.7289686799049377,
0.0,
-0.6845470666885376,
0.0,
-0.4252049028873444,
0.7836934328079224,
0.4527972936630249,
0.0,
0.5364750623703003,
0.6211478114128113,
-0.571287989616394,
0.0,
400.1130065917969,
463.2640075683594,
-431.0780334472656,
1.0
],
"camera": 0
},
{
"mesh": 0
}
],
"cameras": [
{
"perspective": {
"aspectRatio": 1.5,
"yfov": 0.6605925559997559,
"zfar": 10000.0,
"znear": 1.0
},
"type": "perspective"
}
],
"meshes": [
{
"primitives": [
{
"attributes": {
"NORMAL": 1,
"POSITION": 2,
"TEXCOORD_0": 3
},
"indices": 0,
"mode": 4,
"material": 0
}
],
"name": "LOD3spShape"
}
],
"accessors": [
{
"bufferView": 0,
"byteOffset": 0,
"componentType": 5123,
"count": 12636,
"max": [
2398
],
"min": [
0
],
"type": "SCALAR"
},
{
"bufferView": 1,
"byteOffset": 0,
"componentType": 5126,
"count": 2399,
"max": [
0.9995989799499512,
0.999580979347229,
0.9984359741210938
],
"min": [
-0.9990839958190918,
-1.0,
-0.9998319745063782
],
"type": "VEC3"
},
{
"bufferView": 1,
"byteOffset": 28788,
"componentType": 5126,
"count": 2399,
"max": [
96.17990112304688,
163.97000122070313,
53.92519760131836
],
"min": [
-69.29850006103516,
9.929369926452637,
-61.32819747924805
],
"type": "VEC3"
},
{
"bufferView": 2,
"byteOffset": 0,
"componentType": 5126,
"count": 2399,
"max": [
0.9833459854125976,
0.9800369739532472
],
"min": [
0.026409000158309938,
0.01996302604675293
],
"type": "VEC2"
}
],
"materials": [
{
"pbrMetallicRoughness": {
"baseColorTexture": {
"index": 0
},
"metallicFactor": 0.0
},
"emissiveFactor": [
0.0,
0.0,
0.0
],
"name": "blinn3-fx"
}
],
"textures": [
{
"sampler": 0,
"source": 0
}
],
"images": [
{
"uri": "DuckCM.png"
}
],
"samplers": [
{
"magFilter": 9729,
"minFilter": 9986,
"wrapS": 10497,
"wrapT": 10497
}
],
"bufferViews": [
{
"buffer": 0,
"byteOffset": 76768,
"byteLength": 25272,
"target": 34963
},
{
"buffer": 0,
"byteOffset": 0,
"byteLength": 57576,
"byteStride": 12,
"target": 34962
},
{
"buffer": 0,
"byteOffset": 57576,
"byteLength": 19192,
"byteStride": 8,
"target": 34962
}
],
"buffers": [
{
"byteLength": 102040,
"uri": "Duck0.bin"
}
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

View File

@ -1,14 +0,0 @@
# Duck
## Screenshot
![screenshot](screenshot/screenshot.png)
## License Information
Copyright 2006 Sony Computer Entertainment Inc.
Licensed under the SCEA Shared Source License, Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at:
http://research.scea.com/scea_shared_source_license.html
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

View File

@ -1,133 +0,0 @@
/*******************************************************************************************
*
* BRDF LUT Generation - Bidirectional reflectance distribution function fragment shader
*
* REF: https://github.com/HectorMF/BRDFGenerator
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
// Constant values
const float PI = 3.14159265359;
const uint MAX_SAMPLES = 1024u;
// Output fragment color
out vec4 finalColor;
vec2 Hammersley(uint i, uint N);
float RadicalInverseVdC(uint bits);
float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
vec2 IntegrateBRDF(float NdotV, float roughness);
float RadicalInverseVdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
// Compute Hammersley coordinates
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), RadicalInverseVdC(i));
}
// Integrate number of importance samples for (roughness and NoV)
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{
float a = roughness*roughness;
float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec);
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
// For IBL k is calculated different
float k = (roughness*roughness)/2.0;
float nom = NdotV;
float denom = NdotV*(1.0 - k) + k;
return nom/denom;
}
// Compute the geometry term for the BRDF given roughness squared, NoV, NoL
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1*ggx2;
}
vec2 IntegrateBRDF(float NdotV, float roughness)
{
float A = 0.0;
float B = 0.0;
vec3 V = vec3(sqrt(1.0 - NdotV*NdotV), 0.0, NdotV);
vec3 N = vec3(0.0, 0.0, 1.0);
for (uint i = 0u; i < MAX_SAMPLES; i++)
{
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
vec2 Xi = Hammersley(i, MAX_SAMPLES); // Compute a Hammersely coordinate
vec3 H = ImportanceSampleGGX(Xi, N, roughness); // Integrate number of importance samples for (roughness and NoV)
vec3 L = normalize(2.0*dot(V, H)*H - V); // Compute reflection vector L
float NdotL = max(L.z, 0.0); // Compute normal dot light
float NdotH = max(H.z, 0.0); // Compute normal dot half
float VdotH = max(dot(V, H), 0.0); // Compute view dot half
if (NdotL > 0.0)
{
float G = GeometrySmith(N, V, L, roughness); // Compute the geometry term for the BRDF given roughness squared, NoV, NoL
float GVis = (G*VdotH)/(NdotH*NdotV); // Compute the visibility term given G, VoH, NoH, NoV, NoL
float Fc = pow(1.0 - VdotH, 5.0); // Compute the fresnel term given VoH
A += (1.0 - Fc)*GVis; // Sum the result given fresnel, geometry, visibility
B += Fc*GVis;
}
}
// Calculate brdf average sample
A /= float(MAX_SAMPLES);
B /= float(MAX_SAMPLES);
return vec2(A, B);
}
void main()
{
// Calculate brdf based on texture coordinates
vec2 brdf = IntegrateBRDF(fragTexCoord.x, fragTexCoord.y);
// Calculate final fragment color
finalColor = vec4(brdf.r, brdf.g, 0.0, 1.0);
}

View File

@ -1,25 +0,0 @@
/*******************************************************************************************
*
* rPBR [shader] - Bidirectional reflectance distribution function vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
// Output vertex attributes (to fragment shader)
out vec2 fragTexCoord;
void main()
{
// Calculate fragment position based on model transformations
fragTexCoord = vertexTexCoord;
// Calculate final vertex position
gl_Position = vec4(vertexPosition, 1.0);
}

View File

@ -1,58 +0,0 @@
/*******************************************************************************************
*
* rPBR [shader] - Irradiance cubemap fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
// Constant values
const float PI = 3.14159265359f;
// Output fragment color
out vec4 finalColor;
void main()
{
// The sample direction equals the hemisphere's orientation
vec3 normal = normalize(fragPosition);
vec3 irradiance = vec3(0.0);
vec3 up = vec3(0.0, 1.0, 0.0);
vec3 right = cross(up, normal);
up = cross(normal, right);
float sampleDelta = 0.025f;
float nrSamples = 0.0f;
for (float phi = 0.0; phi < 2.0*PI; phi += sampleDelta)
{
for (float theta = 0.0; theta < 0.5*PI; theta += sampleDelta)
{
// Spherical to cartesian (in tangent space)
vec3 tangentSample = vec3(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));
// tangent space to world
vec3 sampleVec = tangentSample.x*right + tangentSample.y*up + tangentSample.z*normal;
// Fetch color from environment cubemap
irradiance += texture(environmentMap, sampleVec).rgb*cos(theta)*sin(theta);
nrSamples++;
}
}
// Calculate irradiance average value from samples
irradiance = PI*irradiance*(1.0/float(nrSamples));
// Calculate final fragment color
finalColor = vec4(irradiance, 1.0);
}

View File

@ -1,298 +0,0 @@
/*******************************************************************************************
*
* rPBR [shader] - Physically based rendering fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
#define MAX_REFLECTION_LOD 4.0
#define MAX_DEPTH_LAYER 20
#define MIN_DEPTH_LAYER 10
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light {
int enabled;
int type;
vec3 position;
vec3 target;
vec4 color;
};
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
in vec2 fragTexCoord;
in vec3 fragNormal;
in vec3 fragTangent;
in vec3 fragBinormal;
// Input material values
uniform MaterialProperty albedo;
uniform MaterialProperty normals;
uniform MaterialProperty metalness;
uniform MaterialProperty roughness;
uniform MaterialProperty occlusion;
uniform MaterialProperty emission;
uniform MaterialProperty height;
// Input uniform values
uniform samplerCube irradianceMap;
uniform samplerCube prefilterMap;
uniform sampler2D brdfLUT;
// Input lighting values
uniform Light lights[MAX_LIGHTS];
// Other uniform values
uniform int renderMode;
uniform vec3 viewPos;
vec2 texCoord;
// Constant values
const float PI = 3.14159265359;
// Output fragment color
out vec4 finalColor;
vec3 ComputeMaterialProperty(MaterialProperty property);
float DistributionGGX(vec3 N, vec3 H, float roughness);
float GeometrySchlickGGX(float NdotV, float roughness);
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness);
vec3 fresnelSchlick(float cosTheta, vec3 F0);
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness);
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir);
vec3 ComputeMaterialProperty(MaterialProperty property)
{
vec3 result = vec3(0.0, 0.0, 0.0);
if (property.useSampler == 1) result = texture(property.sampler, texCoord).rgb;
else result = property.color;
return result;
}
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float nom = a2;
float denom = (NdotH2*(a2 - 1.0) + 1.0);
denom = PI*denom*denom;
return nom/denom;
}
float GeometrySchlickGGX(float NdotV, float roughness)
{
float r = (roughness + 1.0);
float k = r*r/8.0;
float nom = NdotV;
float denom = NdotV*(1.0 - k) + k;
return nom/denom;
}
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
{
float NdotV = max(dot(N, V), 0.0);
float NdotL = max(dot(N, L), 0.0);
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
return ggx1*ggx2;
}
vec3 fresnelSchlick(float cosTheta, vec3 F0)
{
return F0 + (1.0 - F0)*pow(1.0 - cosTheta, 5.0);
}
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness)
{
return F0 + (max(vec3(1.0 - roughness), F0) - F0)*pow(1.0 - cosTheta, 5.0);
}
vec2 ParallaxMapping(vec2 texCoords, vec3 viewDir)
{
// Calculate the number of depth layers and calculate the size of each layer
float numLayers = mix(MAX_DEPTH_LAYER, MIN_DEPTH_LAYER, abs(dot(vec3(0.0, 0.0, 1.0), viewDir)));
float layerDepth = 1.0/numLayers;
// Calculate depth of current layer
float currentLayerDepth = 0.0;
// Calculate the amount to shift the texture coordinates per layer (from vector P)
// Note: height amount is stored in height material attribute color R channel (sampler use is independent)
vec2 P = viewDir.xy*height.color.r;
vec2 deltaTexCoords = P/numLayers;
// Store initial texture coordinates and depth values
vec2 currentTexCoords = texCoords;
float currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
while (currentLayerDepth < currentDepthMapValue)
{
// Shift texture coordinates along direction of P
currentTexCoords -= deltaTexCoords;
// Get depth map value at current texture coordinates
currentDepthMapValue = texture(height.sampler, currentTexCoords).r;
// Get depth of next layer
currentLayerDepth += layerDepth;
}
// Get texture coordinates before collision (reverse operations)
vec2 prevTexCoords = currentTexCoords + deltaTexCoords;
// Get depth after and before collision for linear interpolation
float afterDepth = currentDepthMapValue - currentLayerDepth;
float beforeDepth = texture(height.sampler, prevTexCoords).r - currentLayerDepth + layerDepth;
// Interpolation of texture coordinates
float weight = afterDepth/(afterDepth - beforeDepth);
vec2 finalTexCoords = prevTexCoords*weight + currentTexCoords*(1.0 - weight);
return finalTexCoords;
}
void main()
{
// Calculate TBN and RM matrices
mat3 TBN = transpose(mat3(fragTangent, fragBinormal, fragNormal));
// Calculate lighting required attributes
vec3 normal = normalize(fragNormal);
vec3 view = normalize(viewPos - fragPosition);
vec3 refl = reflect(-view, normal);
// Check if parallax mapping is enabled and calculate texture coordinates to use based on height map
// NOTE: remember that 'texCoord' variable must be assigned before calling any ComputeMaterialProperty() function
if (height.useSampler == 1) texCoord = ParallaxMapping(fragTexCoord, view);
else texCoord = fragTexCoord; // Use default texture coordinates
// Fetch material values from texture sampler or color attributes
vec3 color = ComputeMaterialProperty(albedo);
vec3 metal = ComputeMaterialProperty(metalness);
vec3 rough = ComputeMaterialProperty(roughness);
vec3 emiss = ComputeMaterialProperty(emission);
vec3 ao = ComputeMaterialProperty(occlusion);
// Check if normal mapping is enabled
if (normals.useSampler == 1)
{
// Fetch normal map color and transform lighting values to tangent space
normal = ComputeMaterialProperty(normals);
normal = normalize(normal*2.0 - 1.0);
normal = normalize(normal*TBN);
// Convert tangent space normal to world space due to cubemap reflection calculations
refl = normalize(reflect(-view, normal));
}
// Calculate reflectance at normal incidence
vec3 F0 = vec3(0.04);
F0 = mix(F0, color, metal.r);
// Calculate lighting for all lights
vec3 Lo = vec3(0.0);
vec3 lightDot = vec3(0.0);
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
{
// Calculate per-light radiance
vec3 light = vec3(0.0);
vec3 radiance = lights[i].color.rgb;
if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position);
else if (lights[i].type == LIGHT_POINT)
{
light = normalize(lights[i].position - fragPosition);
float distance = length(lights[i].position - fragPosition);
float attenuation = 1.0/(distance*distance);
radiance *= attenuation;
}
// Cook-torrance BRDF
vec3 high = normalize(view + light);
float NDF = DistributionGGX(normal, high, rough.r);
float G = GeometrySmith(normal, view, light, rough.r);
vec3 F = fresnelSchlick(max(dot(high, view), 0.0), F0);
vec3 nominator = NDF*G*F;
float denominator = 4*max(dot(normal, view), 0.0)*max(dot(normal, light), 0.0) + 0.001;
vec3 brdf = nominator/denominator;
// Store to kS the fresnel value and calculate energy conservation
vec3 kS = F;
vec3 kD = vec3(1.0) - kS;
// Multiply kD by the inverse metalness such that only non-metals have diffuse lighting
kD *= 1.0 - metal.r;
// Scale light by dot product between normal and light direction
float NdotL = max(dot(normal, light), 0.0);
// Add to outgoing radiance Lo
// Note: BRDF is already multiplied by the Fresnel so it doesn't need to be multiplied again
Lo += (kD*color/PI + brdf)*radiance*NdotL*lights[i].color.a;
lightDot += radiance*NdotL + brdf*lights[i].color.a;
}
}
// Calculate ambient lighting using IBL
vec3 F = fresnelSchlickRoughness(max(dot(normal, view), 0.0), F0, rough.r);
vec3 kS = F;
vec3 kD = 1.0 - kS;
kD *= 1.0 - metal.r;
// Calculate indirect diffuse
vec3 irradiance = texture(irradianceMap, fragNormal).rgb;
vec3 diffuse = color*irradiance;
// Sample both the prefilter map and the BRDF lut and combine them together as per the Split-Sum approximation
vec3 prefilterColor = textureLod(prefilterMap, refl, rough.r*MAX_REFLECTION_LOD).rgb;
vec2 brdf = texture(brdfLUT, vec2(max(dot(normal, view), 0.0), rough.r)).rg;
vec3 reflection = prefilterColor*(F*brdf.x + brdf.y);
// Calculate final lighting
vec3 ambient = (kD*diffuse + reflection)*ao;
// Calculate fragment color based on render mode
vec3 fragmentColor = ambient + Lo + emiss; // Physically Based Rendering
if (renderMode == 1) fragmentColor = color; // Albedo
else if (renderMode == 2) fragmentColor = normal; // Normals
else if (renderMode == 3) fragmentColor = metal; // Metalness
else if (renderMode == 4) fragmentColor = rough; // Roughness
else if (renderMode == 5) fragmentColor = ao; // Ambient Occlusion
else if (renderMode == 6) fragmentColor = emiss; // Emission
else if (renderMode == 7) fragmentColor = lightDot; // Lighting
else if (renderMode == 8) fragmentColor = kS; // Fresnel
else if (renderMode == 9) fragmentColor = irradiance; // Irradiance
else if (renderMode == 10) fragmentColor = reflection; // Reflection
// Apply HDR tonemapping
fragmentColor = fragmentColor/(fragmentColor + vec3(1.0));
// Apply gamma correction
fragmentColor = pow(fragmentColor, vec3(1.0/2.2));
// Calculate final fragment color
finalColor = vec4(fragmentColor, 1.0);
}

View File

@ -1,49 +0,0 @@
/*******************************************************************************************
*
* rPBR [shader] - Physically based rendering vertex shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
// Input vertex attributes
in vec3 vertexPosition;
in vec2 vertexTexCoord;
in vec3 vertexNormal;
in vec4 vertexTangent;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
// Output vertex attributes (to fragment shader)
out vec3 fragPosition;
out vec2 fragTexCoord;
out vec3 fragNormal;
out vec3 fragTangent;
out vec3 fragBinormal;
void main()
{
// Calculate binormal from vertex normal and tangent
vec3 vertexBinormal = cross(vertexNormal, vec3(vertexTangent));
// Calculate fragment normal based on normal transformations
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
// Calculate fragment position based on model transformations
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0f));
// Send vertex attributes to fragment shader
fragTexCoord = vertexTexCoord;
fragNormal = normalize(normalMatrix*vertexNormal);
fragTangent = normalize(normalMatrix*vec3(vertexTangent));
fragTangent = normalize(fragTangent - dot(fragTangent, fragNormal)*fragNormal);
fragBinormal = normalize(normalMatrix*vertexBinormal);
fragBinormal = cross(fragNormal, fragTangent);
// Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0);
}

View File

@ -1,120 +0,0 @@
/*******************************************************************************************
*
* rPBR [shader] - Prefiltered environment for reflections fragment shader
*
* Copyright (c) 2017 Victor Fisac
*
**********************************************************************************************/
#version 330
#define MAX_SAMPLES 1024u
#define CUBEMAP_RESOLUTION 1024.0
// Input vertex attributes (from vertex shader)
in vec3 fragPosition;
// Input uniform values
uniform samplerCube environmentMap;
uniform float roughness;
// Constant values
const float PI = 3.14159265359f;
// Output fragment color
out vec4 finalColor;
float DistributionGGX(vec3 N, vec3 H, float roughness);
float RadicalInverse_VdC(uint bits);
vec2 Hammersley(uint i, uint N);
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness);
float DistributionGGX(vec3 N, vec3 H, float roughness)
{
float a = roughness*roughness;
float a2 = a*a;
float NdotH = max(dot(N, H), 0.0);
float NdotH2 = NdotH*NdotH;
float nom = a2;
float denom = (NdotH2*(a2 - 1.0) + 1.0);
denom = PI*denom*denom;
return nom/denom;
}
float RadicalInverse_VdC(uint bits)
{
bits = (bits << 16u) | (bits >> 16u);
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
}
vec2 Hammersley(uint i, uint N)
{
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
}
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
{
float a = roughness*roughness;
float phi = 2.0 * PI * Xi.x;
float cosTheta = sqrt((1.0 - Xi.y)/(1.0 + (a*a - 1.0)*Xi.y));
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
// Transform from spherical coordinates to cartesian coordinates (halfway vector)
vec3 H = vec3(cos(phi)*sinTheta, sin(phi)*sinTheta, cosTheta);
// Transform from tangent space H vector to world space sample vector
vec3 up = ((abs(N.z) < 0.999) ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0));
vec3 tangent = normalize(cross(up, N));
vec3 bitangent = cross(N, tangent);
vec3 sampleVec = tangent*H.x + bitangent*H.y + N*H.z;
return normalize(sampleVec);
}
void main()
{
// Make the simplyfying assumption that V equals R equals the normal
vec3 N = normalize(fragPosition);
vec3 R = N;
vec3 V = R;
vec3 prefilteredColor = vec3(0.0);
float totalWeight = 0.0;
for (uint i = 0u; i < MAX_SAMPLES; i++)
{
// Generate a sample vector that's biased towards the preferred alignment direction (importance sampling)
vec2 Xi = Hammersley(i, MAX_SAMPLES);
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
vec3 L = normalize(2.0*dot(V, H)*H - V);
float NdotL = max(dot(N, L), 0.0);
if(NdotL > 0.0)
{
// Sample from the environment's mip level based on roughness/pdf
float D = DistributionGGX(N, H, roughness);
float NdotH = max(dot(N, H), 0.0);
float HdotV = max(dot(H, V), 0.0);
float pdf = D*NdotH/(4.0*HdotV) + 0.0001;
float resolution = CUBEMAP_RESOLUTION;
float saTexel = 4.0*PI/(6.0*resolution*resolution);
float saSample = 1.0/(float(MAX_SAMPLES)*pdf + 0.0001);
float mipLevel = ((roughness == 0.0) ? 0.0 : 0.5*log2(saSample/saTexel));
prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb*NdotL;
totalWeight += NdotL;
}
}
// Calculate prefilter average color
prefilteredColor = prefilteredColor/totalWeight;
// Calculate final fragment color
finalColor = vec4(prefilteredColor, 1.0);
}

View File

@ -0,0 +1,103 @@
/*******************************************************************************************
*
* raylib [others] example - Embedded files loading (Wave and Image)
*
* This example has been created using raylib 3.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Kristian Holmgren (@defutura) and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2020 Kristian Holmgren (@defutura) and Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "resources/audio_data.h" // Wave file exported with ExportWaveAsCode()
#include "resources/image_data.h" // Image file exported with ExportImageAsCode()
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [others] example - embedded files loading");
InitAudioDevice(); // Initialize audio device
// Loaded in CPU memory (RAM) from header file (audio_data.h)
// Same as: Wave wave = LoadWave("sound.wav");
Wave wave = {
.data = AUDIO_DATA,
.sampleCount = AUDIO_SAMPLE_COUNT,
.sampleRate = AUDIO_SAMPLE_RATE,
.sampleSize = AUDIO_SAMPLE_SIZE,
.channels = AUDIO_CHANNELS
};
// Wave converted to Sound to be played
Sound sound = LoadSoundFromWave(wave);
// With a Wave loaded from file, after Sound is loaded, we can unload Wave
// but in our case, Wave is embedded in executable, in program .data segment
// we can not (and should not) try to free that private memory region
//UnloadWave(wave); // Do not unload wave data!
// Loaded in CPU memory (RAM) from header file (image_data.h)
// Same as: Image image = LoadImage("raylib_logo.png");
Image image = {
.data = IMAGE_DATA,
.width = IMAGE_WIDTH,
.height = IMAGE_HEIGHT,
.format = IMAGE_FORMAT,
.mipmaps = 1
};
// Image converted to Texture (VRAM) to be drawn
Texture2D texture = LoadTextureFromImage(image);
// With an Image loaded from file, after Texture is loaded, we can unload Image
// but in our case, Image is embedded in executable, in program .data segment
// we can not (and should not) try to free that private memory region
//UnloadImage(image); // Do not unload image data!
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_SPACE)) PlaySound(sound); // Play sound
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawTexture(texture, screenWidth/2 - texture.width/2, 40, WHITE);
DrawText("raylib logo and sound loaded from header files", 65, 320, 20, LIGHTGRAY);
DrawText("Press SPACE to PLAY the sound!", 200, 360, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadSound(sound); // Unload sound from VRAM
UnloadTexture(texture); // Unload texture from VRAM
CloseAudioDevice(); // Close audio device
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1466
examples/shaders/raymath.h Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,77 @@
#version 100
precision mediump float;
#define MAX_SPOTS 3
struct Spot {
vec2 pos; // window coords of spot
float inner; // inner fully transparent centre radius
float radius; // alpha fades out to this radius
};
uniform Spot spots[MAX_SPOTS]; // Spotlight positions array
uniform float screenWidth; // Width of the screen
void main()
{
float alpha = 1.0;
// Get the position of the current fragment (screen coordinates!)
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
// Find out which spotlight is nearest
float d = 65000.0; // some high value
int fi = -1; // found index
for (int i = 0; i < MAX_SPOTS; i++)
{
for (int j = 0; j < MAX_SPOTS; j++)
{
float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
if (d > dj)
{
d = dj;
fi = i;
}
}
}
// d now equals distance to nearest spot...
// allowing for the different radii of all spotlights
if (fi == 0)
{
if (d > spots[0].radius) alpha = 1.0;
else
{
if (d < spots[0].inner) alpha = 0.0;
else alpha = (d - spots[0].inner)/(spots[0].radius - spots[0].inner);
}
}
else if (fi == 1)
{
if (d > spots[1].radius) alpha = 1.0;
else
{
if (d < spots[1].inner) alpha = 0.0;
else alpha = (d - spots[1].inner)/(spots[1].radius - spots[1].inner);
}
}
else if (fi == 2)
{
if (d > spots[2].radius) alpha = 1.0;
else
{
if (d < spots[2].inner) alpha = 0.0;
else alpha = (d - spots[2].inner)/(spots[2].radius - spots[2].inner);
}
}
// Right hand side of screen is dimly lit,
// could make the threshold value user definable
if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
// could make the black out colour user definable...
gl_FragColor = vec4(0, 0, 0, alpha);
}

View File

@ -0,0 +1,59 @@
#version 120
// Input vertex attributes
attribute vec3 vertexPosition;
attribute vec2 vertexTexCoord;
attribute vec3 vertexNormal;
attribute vec4 vertexColor;
// Input uniform values
uniform mat4 mvp;
uniform mat4 matModel;
// Output vertex attributes (to fragment shader)
varying vec3 fragPosition;
varying vec2 fragTexCoord;
varying vec4 fragColor;
varying vec3 fragNormal;
// NOTE: Add here your custom variables
// https://github.com/glslify/glsl-inverse
mat3 inverse(mat3 m)
{
float a00 = m[0][0], a01 = m[0][1], a02 = m[0][2];
float a10 = m[1][0], a11 = m[1][1], a12 = m[1][2];
float a20 = m[2][0], a21 = m[2][1], a22 = m[2][2];
float b01 = a22*a11 - a12*a21;
float b11 = -a22*a10 + a12*a20;
float b21 = a21*a10 - a11*a20;
float det = a00*b01 + a01*b11 + a02*b21;
return mat3(b01, (-a22*a01 + a02*a21), (a12*a01 - a02*a11),
b11, (a22*a00 - a02*a20), (-a12*a00 + a02*a10),
b21, (-a21*a00 + a01*a20), (a11*a00 - a01*a10))/det;
}
// https://github.com/glslify/glsl-transpose
mat3 transpose(mat3 m)
{
return mat3(m[0][0], m[1][0], m[2][0],
m[0][1], m[1][1], m[2][1],
m[0][2], m[1][2], m[2][2]);
}
void main()
{
// Send vertex attributes to fragment shader
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
fragTexCoord = vertexTexCoord;
fragColor = vertexColor;
mat3 normalMatrix = transpose(inverse(mat3(matModel)));
fragNormal = normalize(normalMatrix*vertexNormal);
// Calculate final vertex position
gl_Position = mvp*vec4(vertexPosition, 1.0);
}

View File

@ -0,0 +1,92 @@
#version 120
// Input vertex attributes (from vertex shader)
varying vec3 fragPosition;
varying vec2 fragTexCoord;
varying vec4 fragColor;
varying vec3 fragNormal;
// Input uniform values
uniform sampler2D texture0;
uniform vec4 colDiffuse;
// NOTE: Add here your custom variables
#define MAX_LIGHTS 4
#define LIGHT_DIRECTIONAL 0
#define LIGHT_POINT 1
struct MaterialProperty {
vec3 color;
int useSampler;
sampler2D sampler;
};
struct Light {
int enabled;
int type;
vec3 position;
vec3 target;
vec4 color;
};
// Input lighting values
uniform Light lights[MAX_LIGHTS];
uniform vec4 ambient;
uniform vec3 viewPos;
uniform float fogDensity;
void main()
{
// Texel color fetching from texture sampler
vec4 texelColor = texture2D(texture0, fragTexCoord);
vec3 lightDot = vec3(0.0);
vec3 normal = normalize(fragNormal);
vec3 viewD = normalize(viewPos - fragPosition);
vec3 specular = vec3(0.0);
// NOTE: Implement here your fragment shader code
for (int i = 0; i < MAX_LIGHTS; i++)
{
if (lights[i].enabled == 1)
{
vec3 light = vec3(0.0);
if (lights[i].type == LIGHT_DIRECTIONAL) light = -normalize(lights[i].target - lights[i].position);
if (lights[i].type == LIGHT_POINT) light = normalize(lights[i].position - fragPosition);
float NdotL = max(dot(normal, light), 0.0);
lightDot += lights[i].color.rgb*NdotL;
float specCo = 0.0;
if (NdotL > 0.0) specCo = pow(max(0.0, dot(viewD, reflect(-(light), normal))), 16.0); // Shine: 16.0
specular += specCo;
}
}
vec4 finalColor = (texelColor*((colDiffuse + vec4(specular,1))*vec4(lightDot, 1.0)));
finalColor += texelColor*(ambient/10.0);
// Gamma correction
finalColor = pow(finalColor, vec4(1.0/2.2));
// Fog calculation
float dist = length(viewPos - fragPosition);
// these could be parameters...
const vec4 fogColor = vec4(0.5, 0.5, 0.5, 1.0);
//const float fogDensity = 0.16;
// Exponential fog
float fogFactor = 1.0/exp((dist*fogDensity)*(dist*fogDensity));
// Linear fog (less nice)
//const float fogStart = 2.0;
//const float fogEnd = 10.0;
//float fogFactor = (fogEnd - dist)/(fogEnd - fogStart);
fogFactor = clamp(fogFactor, 0.0, 1.0);
gl_FragColor = mix(fogColor, finalColor, fogFactor);
}

View File

@ -0,0 +1,65 @@
#version 330
// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec4 fragColor;
// Output fragment color
out vec4 finalColor;
// NOTE: Add here your custom variables
#define MAX_SPOTS 3
struct Spot {
vec2 pos; // window coords of spot
float inner; // inner fully transparent centre radius
float radius; // alpha fades out to this radius
};
uniform Spot spots[MAX_SPOTS]; // Spotlight positions array
uniform float screenWidth; // Width of the screen
void main()
{
float alpha = 1.0;
// Get the position of the current fragment (screen coordinates!)
vec2 pos = vec2(gl_FragCoord.x, gl_FragCoord.y);
// Find out which spotlight is nearest
float d = 65000; // some high value
int fi = -1; // found index
for (int i = 0; i < MAX_SPOTS; i++)
{
for (int j = 0; j < MAX_SPOTS; j++)
{
float dj = distance(pos, spots[j].pos) - spots[j].radius + spots[i].radius;
if (d > dj)
{
d = dj;
fi = i;
}
}
}
// d now equals distance to nearest spot...
// allowing for the different radii of all spotlights
if (fi != -1)
{
if (d > spots[fi].radius) alpha = 1.0;
else
{
if (d < spots[fi].inner) alpha = 0.0;
else alpha = (d - spots[fi].inner) / (spots[fi].radius - spots[fi].inner);
}
}
// Right hand side of screen is dimly lit,
// could make the threshold value user definable
if ((pos.x > screenWidth/2.0) && (alpha > 0.9)) alpha = 0.9;
finalColor = vec4(0, 0, 0, alpha);
}

View File

@ -2,12 +2,8 @@
*
* raylib [shaders] example - Raymarching shapes generation
*
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version.
*
* NOTE: Shaders used in this example are #version 330 (OpenGL 3.3), to test this example
* on OpenGL ES 2.0 platforms (Android, Raspberry Pi, HTML5), use #version 100 shaders
* raylib comes with shaders ready for both versions, check raylib/shaders install folder
* NOTE: This example requires raylib OpenGL 3.3 for shaders support and only #version 330
* is currently supported. OpenGL ES 2.0 platforms are not supported at the moment.
*
* This example has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
@ -20,7 +16,7 @@
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB -> Not supported at this moment
#define GLSL_VERSION 100
#endif

View File

@ -0,0 +1,262 @@
/*******************************************************************************************
*
* raylib [shaders] example - Simple shader mask
*
* This example has been created using raylib 2.5 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Example contributed by Chris Camacho (@codifies - http://bedroomcoders.co.uk/)
* and reviewed by Ramon Santamaria (@raysan5)
*
* Copyright (c) 2019 Chris Camacho (@codifies) and Ramon Santamaria (@raysan5)
*
********************************************************************************************
*
* The shader makes alpha holes in the forground to give the apearance of a top
* down look at a spotlight casting a pool of light...
*
* The right hand side of the screen there is just enough light to see whats
* going on without the spot light, great for a stealth type game where you
* have to avoid the spotlights.
*
* The left hand side of the screen is in pitch dark except for where the spotlights are.
*
* Although this example doesn't scale like the letterbox example, you could integrate
* the two techniques, but by scaling the actual colour of the render texture rather
* than using alpha as a mask.
*
********************************************************************************************/
#include "raylib.h"
#include "raymath.h"
#include <stddef.h>
#include <stdint.h>
#if defined(PLATFORM_DESKTOP)
#define GLSL_VERSION 330
#else // PLATFORM_RPI, PLATFORM_ANDROID, PLATFORM_WEB
#define GLSL_VERSION 100
#endif
#define MAXSPOT 3 // NB must be the same as define in shader
#define numStars 400
// Spot data
typedef struct {
Vector2 pos;
Vector2 vel;
float inner;
float radius;
// Shader locations
unsigned int posLoc;
unsigned int innerLoc;
unsigned int radiusLoc;
} Spot;
// Stars in the star field have a position and velocity
typedef struct Star {
Vector2 pos;
Vector2 vel;
} Star;
void UpdateStar(Star *s);
void ResetStar(Star *s);
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib - shader spotlight");
HideCursor();
Texture texRay = LoadTexture("resources/raysan.png");
Star stars[numStars] = { 0 };
for (int n = 0; n < numStars; n++) ResetStar(&stars[n]);
// Progress all the stars on, so they don't all start in the centre
for (int m = 0; m < screenWidth/2.0; m++)
{
for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
}
int frameCounter = 0;
// Use default vert shader
Shader spotShader = LoadShader(0, FormatText("resources/shaders/glsl%i/spotlight.fs", GLSL_VERSION));
// Get the locations of spots in the shader
Spot spots[MAXSPOT];
/*
unsigned int posLoc;
unsigned int innerLoc;
unsigned int radiusLoc;
*/
for (int i = 0; i < MAXSPOT; i++)
{
char posName[32] = "spots[x].pos\0";
char innerName[32] = "spots[x].inner\0";
char radiusName[32] = "spots[x].radius\0";
posName[6] = '0' + i;
innerName[6] = '0' + i;
radiusName[6] = '0' + i;
spots[i].posLoc = GetShaderLocation(spotShader, posName);
spots[i].innerLoc = GetShaderLocation(spotShader, innerName);
spots[i].radiusLoc = GetShaderLocation(spotShader, radiusName);
}
// tell the shader how wide the screen is so we can have
// a pitch black half and a dimly lit half.
{
unsigned int wLoc = GetShaderLocation(spotShader, "screenWidth");
float sw = (float)GetScreenWidth();
SetShaderValue(spotShader, wLoc, &sw, UNIFORM_FLOAT);
}
// randomise the locations and velocities of the spotlights
// and initialise the shader locations
for (int i = 0; i < MAXSPOT; i++)
{
spots[i].pos.x = GetRandomValue(64, screenWidth - 64);
spots[i].pos.y = GetRandomValue(64, screenHeight - 64);
spots[i].vel = (Vector2){ 0, 0 };
while ((fabs(spots[i].vel.x) + fabs(spots[i].vel.y)) < 2)
{
spots[i].vel.x = GetRandomValue(-40, 40)/10.0;
spots[i].vel.y = GetRandomValue(-40, 40)/10.0;
}
spots[i].inner = 28 * (i + 1);
spots[i].radius = 48 * (i + 1);
SetShaderValue(spotShader, spots[i].posLoc, &spots[i].pos.x, UNIFORM_VEC2);
SetShaderValue(spotShader, spots[i].innerLoc, &spots[i].inner, UNIFORM_FLOAT);
SetShaderValue(spotShader, spots[i].radiusLoc, &spots[i].radius, UNIFORM_FLOAT);
}
SetTargetFPS(60); // Set to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
frameCounter++;
// Move the stars, resetting them if the go offscreen
for (int n = 0; n < numStars; n++) UpdateStar(&stars[n]);
// Update the spots, send them to the shader
for (int i = 0; i < MAXSPOT; i++)
{
if ( i == 0 ) {
Vector2 mp = GetMousePosition();
spots[i].pos.x = mp.x;
spots[i].pos.y = screenHeight - mp.y;
} else {
spots[i].pos.x += spots[i].vel.x;
spots[i].pos.y += spots[i].vel.y;
if (spots[i].pos.x < 64) spots[i].vel.x = -spots[i].vel.x;
if (spots[i].pos.x > screenWidth - 64) spots[i].vel.x = -spots[i].vel.x;
if (spots[i].pos.y < 64) spots[i].vel.y = -spots[i].vel.y;
if (spots[i].pos.y > screenHeight - 64) spots[i].vel.y = -spots[i].vel.y;
}
SetShaderValue(spotShader, spots[i].posLoc, &spots[i].pos.x, UNIFORM_VEC2);
}
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(DARKBLUE);
// Draw stars and bobs
for (int n = 0; n < numStars; n++)
{
// Single pixel is just too small these days!
DrawRectangle(stars[n].pos.x, stars[n].pos.y, 2, 2, WHITE);
}
for (int i = 0; i < 16; i++)
{
DrawTexture(texRay,
(screenWidth/2.0) + cos((frameCounter + i*8)/51.45f)*(screenWidth/2.2) - 32,
(screenHeight/2.0) + sin((frameCounter + i*8)/17.87f)*(screenHeight/4.2),
WHITE);
}
// Draw spot lights
BeginShaderMode(spotShader);
// instead of a blank rectangle you could render here
// a render texture of the full screen used to do screen
// scaling (slight adjustment to shader would be required
// to actually pay attention to the colour!)
DrawRectangle(0,0,screenWidth,screenHeight,WHITE);
EndShaderMode();
DrawFPS(10, 10);
DrawText("Move the mouse!", 10, 30, 20, GREEN);
DrawText("Pitch Black", screenWidth * .2, screenHeight / 2, 20, GREEN);
DrawText("Dark", screenWidth * .66, screenHeight / 2, 20, GREEN);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadTexture(texRay);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
void ResetStar(Star *s)
{
s->pos = (Vector2){ GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
do
{
s->vel.x = (float)GetRandomValue(-1000, 1000)/100.0f;
s->vel.y = (float)GetRandomValue(-1000, 1000)/100.0f;
} while (!(fabs(s->vel.x) + fabs(s->vel.y) > 1));
s->pos = Vector2Add(s->pos, Vector2Multiply(s->vel, (Vector2){ 8, 8 }));
}
void UpdateStar(Star *s)
{
s->pos = Vector2Add(s->pos, s->vel);
if (s->pos.x < 0 || s->pos.x > GetScreenWidth() ||
s->pos.y < 0 || s->pos.y > GetScreenHeight())
{
ResetStar(s);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

View File

@ -35,13 +35,18 @@ int main(void)
ImageDraw(&parrots, cat, (Rectangle){ 0, 0, cat.width, cat.height }, (Rectangle){ 30, 40, cat.width*1.5f, cat.height*1.5f }, WHITE);
ImageCrop(&parrots, (Rectangle){ 0, 50, parrots.width, parrots.height - 100 }); // Crop resulting image
// Draw on the image with a few image draw methods
ImageDrawPixel(&parrots, 10, 10, RAYWHITE);
ImageDrawCircle(&parrots, 10, 10, 5, RAYWHITE);
ImageDrawRectangle(&parrots, 5, 20, 10, 10, RAYWHITE);
UnloadImage(cat); // Unload image from RAM
// Load custom font for frawing on image
Font font = LoadFont("resources/custom_jupiter_crash.png");
// Draw over image using custom font
ImageDrawTextEx(&parrots, (Vector2){ 300, 230 }, font, "PARROTS & CAT", font.baseSize, -2, WHITE);
ImageDrawTextEx(&parrots, font, "PARROTS & CAT", (Vector2){ 300, 230 }, font.baseSize, -2, WHITE);
UnloadFont(font); // Unload custom spritefont (already drawn used on image)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 410 KiB

After

Width:  |  Height:  |  Size: 234 KiB

View File

@ -26,7 +26,7 @@ int main(void)
Font font = LoadFontEx("resources/KAISG.ttf", 64, 0, 0);
// Draw over image using custom font
ImageDrawTextEx(&parrots, (Vector2){ 20.0f, 20.0f }, font, "[Parrots font drawing]", (float)font.baseSize, 0.0f, RED);
ImageDrawTextEx(&parrots, font, "[Parrots font drawing]", (Vector2){ 20.0f, 20.0f }, (float)font.baseSize, 0.0f, RED);
Texture2D texture = LoadTextureFromImage(parrots); // Image converted to texture, uploaded to GPU memory (VRAM)
UnloadImage(parrots); // Once image has been converted to texture and uploaded to VRAM, it can be unloaded from RAM

View File

@ -1,43 +0,0 @@
# Setup the project and settings
project(games)
# Get the source toegher
file(GLOB sources *.c)
set(OUTPUT_EXT)
if(${PLATFORM} MATCHES "Web")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Os -s USE_GLFW=3 -s ASSERTIONS=1 -s WASM=1 -s EMTERPRETIFY=1 -s EMTERPRETIFY_ASYNC=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --shell-file ${CMAKE_SOURCE_DIR}/src/shell.html")
set(OUTPUT_EXT ".html")
# Remove the -rdynamic flag because otherwise emscripten
# does not generate HTML+JS+WASM files, only a non-working
# and fat HTML
string(REPLACE "-rdynamic" "" CMAKE_SHARED_LIBRARY_LINK_C_FLAGS ${CMAKE_SHARED_LIBRARY_LINK_C_FLAGS})
endif()
if (NOT TARGET raylib)
find_package(raylib 2.0 REQUIRED)
endif()
# Do each game
foreach(game_source ${sources})
# Create the basename for the game
get_filename_component(game_name ${game_source} NAME)
string(REPLACE ".c" "${OUTPUT_EXT}" game_name ${game_name})
# Setup the game
add_executable(${game_name} ${game_source})
# Link the libraries
target_link_libraries(${game_name} raylib)
endforeach()
# Do the games with subdirectories
add_subdirectory(drturtle)
add_subdirectory(just_do)
add_subdirectory(koala_seasons)
add_subdirectory(light_my_ritual)
add_subdirectory(skully_escape)
add_subdirectory(wave_collector)

View File

@ -1,398 +0,0 @@
#**************************************************************************************************
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2020 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 ?= raylib_examples
RAYLIB_VERSION ?= 3.0.0
RAYLIB_API_VERSION ?= 3
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:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/fastcomp/emscripten
CLANG_PATH = $(EMSDK_PATH)/fastcomp/bin
PYTHON_PATH = $(EMSDK_PATH)/python/2.7.13.1_64bit/python-2.7.13.amd64
NODE_PATH = $(EMSDK_PATH)/node/12.9.1_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
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 += -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g
ifeq ($(PLATFORM),PLATFORM_WEB)
CFLAGS += -s ASSERTIONS=1 --profiling
endif
else
ifeq ($(PLATFORM),PLATFORM_WEB)
CFLAGS += -Os
else
CFLAGS += -s -O1
endif
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
ifeq ($(BUILD_MODE), RELEASE)
CFLAGS += -Wl,--subsystem,windows
endif
endif
ifeq ($(PLATFORM_OS),LINUX)
ifeq ($(RAYLIB_LIBTYPE),STATIC)
CFLAGS += -D_DEFAULT_SOURCE
endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
# Explicitly enable runtime link to libraylib.so
CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
CFLAGS += -std=gnu99
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0
# -s USE_GLFW=3 # Use glfw3 library (context/input management)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
# -s WASM=0 # disable Web Assembly, emitted by default
# -s EMTERPRETIFY=1 # enable emscripten code interpreter (very slow)
# -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter
# -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# --profiling # include information for code profiling
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation
CFLAGS += -s USE_GLFW=3
# Define a custom shell .html and output extension
CFLAGS += --shell-file $(RAYLIB_PATH)/src/shell.html
EXT = .html
endif
# Define include paths for required headers
# NOTE: Several external required libraries (stb and others)
INCLUDE_PATHS = -I. -I$(RAYLIB_PATH)/src -I$(RAYLIB_PATH)/src/external
# Define additional directories containing required header files
ifeq ($(PLATFORM),PLATFORM_RPI)
# RPI required libraries
INCLUDE_PATHS += -I/opt/vc/include
INCLUDE_PATHS += -I/opt/vc/include/interface/vmcs_host/linux
INCLUDE_PATHS += -I/opt/vc/include/interface/vcos/pthreads
endif
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),BSD)
# Consider -L$(RAYLIB_H_INSTALL_PATH)
INCLUDE_PATHS += -I/usr/local/include
endif
ifeq ($(PLATFORM_OS),LINUX)
# Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs -I$(RAYLIB_H_INSTALL_PATH) -I$(RAYLIB_PATH)/release/include
INCLUDE_PATHS = -I$(RAYLIB_H_INSTALL_PATH) -isystem. -isystem$(RAYLIB_PATH)/src -isystem$(RAYLIB_PATH)/release/include -isystem$(RAYLIB_PATH)/src/external
endif
endif
# Define library paths containing required libs.
LDFLAGS = -L. -L$(RAYLIB_RELEASE_PATH) -L$(RAYLIB_PATH)/src
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),BSD)
# Consider -L$(RAYLIB_INSTALL_PATH)
LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif
ifeq ($(PLATFORM_OS),LINUX)
# Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs
LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH)
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
endif
# Define any libraries required on linking
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation
# NOTE: WinMM library required to set high-res timer resolution
LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
# Required for physac examples
LDLIBS += -static -lpthread
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
# NOTE: Required packages: libegl1-mesa-dev
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
# On X11 requires also below libraries
LDLIBS += -lX11
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
# On Wayland windowing system, additional libraries requires
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
endif
# Explicit link to libc
ifeq ($(RAYLIB_LIBTYPE),SHARED)
LDLIBS += -lc
endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo
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 all source files required
SAMPLES = \
arkanoid \
asteroids \
asteroids_survival \
floppy \
gold_fever \
gorilas \
missile_commander \
pang \
snake \
space_invaders \
tetris \
# typing 'make' will invoke the default target entry
all: $(SAMPLES)
# Generic compilation pattern
# NOTE: Examples must be ready for Android compilation!
%: %.c
ifeq ($(PLATFORM),PLATFORM_ANDROID)
$(MAKE) -f Makefile.Android PROJECT_NAME=$@ PROJECT_SOURCE_FILES=$<
else
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDE_PATHS) $(LDFLAGS) $(LDLIBS) -D$(PLATFORM)
endif
# 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|x-pie-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv
endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
rm -f *.o
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
find . -type f -executable -delete
rm -fv *.o
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done

View File

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

View File

@ -1,323 +0,0 @@
/*******************************************************************************************
*
* raylib - sample game: arkanoid
*
* Sample game Marc Palau and Ramon Santamaria
*
* This game has been created using raylib v1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
//----------------------------------------------------------------------------------
// Some Defines
//----------------------------------------------------------------------------------
#define PLAYER_MAX_LIFE 5
#define LINES_OF_BRICKS 5
#define BRICKS_PER_LINE 20
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum GameScreen { LOGO, TITLE, GAMEPLAY, ENDING } GameScreen;
typedef struct Player {
Vector2 position;
Vector2 size;
int life;
} Player;
typedef struct Ball {
Vector2 position;
Vector2 speed;
int radius;
bool active;
} Ball;
typedef struct Brick {
Vector2 position;
bool active;
} Brick;
//------------------------------------------------------------------------------------
// Global Variables Declaration
//------------------------------------------------------------------------------------
static const int screenWidth = 800;
static const int screenHeight = 450;
static bool gameOver = false;
static bool pause = false;
static Player player = { 0 };
static Ball ball = { 0 };
static Brick brick[LINES_OF_BRICKS][BRICKS_PER_LINE] = { 0 };
static Vector2 brickSize = { 0 };
//------------------------------------------------------------------------------------
// Module Functions Declaration (local)
//------------------------------------------------------------------------------------
static void InitGame(void); // Initialize game
static void UpdateGame(void); // Update game (one frame)
static void DrawGame(void); // Draw game (one frame)
static void UnloadGame(void); // Unload game
static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
InitWindow(screenWidth, screenHeight, "sample game: arkanoid");
InitGame();
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update and Draw
//----------------------------------------------------------------------------------
UpdateDrawFrame();
//----------------------------------------------------------------------------------
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadGame(); // Unload loaded data (textures, sounds, models...)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definitions (local)
//------------------------------------------------------------------------------------
// Initialize game variables
void InitGame(void)
{
brickSize = (Vector2){ GetScreenWidth()/BRICKS_PER_LINE, 40 };
// Initialize player
player.position = (Vector2){ screenWidth/2, screenHeight*7/8 };
player.size = (Vector2){ screenWidth/10, 20 };
player.life = PLAYER_MAX_LIFE;
// Initialize ball
ball.position = (Vector2){ screenWidth/2, screenHeight*7/8 - 30 };
ball.speed = (Vector2){ 0, 0 };
ball.radius = 7;
ball.active = false;
// Initialize bricks
int initialDownPosition = 50;
for (int i = 0; i < LINES_OF_BRICKS; i++)
{
for (int j = 0; j < BRICKS_PER_LINE; j++)
{
brick[i][j].position = (Vector2){ j*brickSize.x + brickSize.x/2, i*brickSize.y + initialDownPosition };
brick[i][j].active = true;
}
}
}
// Update game (one frame)
void UpdateGame(void)
{
if (!gameOver)
{
if (IsKeyPressed('P')) pause = !pause;
if (!pause)
{
// Player movement logic
if (IsKeyDown(KEY_LEFT)) player.position.x -= 5;
if ((player.position.x - player.size.x/2) <= 0) player.position.x = player.size.x/2;
if (IsKeyDown(KEY_RIGHT)) player.position.x += 5;
if ((player.position.x + player.size.x/2) >= screenWidth) player.position.x = screenWidth - player.size.x/2;
// Ball launching logic
if (!ball.active)
{
if (IsKeyPressed(KEY_SPACE))
{
ball.active = true;
ball.speed = (Vector2){ 0, -5 };
}
}
// Ball movement logic
if (ball.active)
{
ball.position.x += ball.speed.x;
ball.position.y += ball.speed.y;
}
else
{
ball.position = (Vector2){ player.position.x, screenHeight*7/8 - 30 };
}
// Collision logic: ball vs walls
if (((ball.position.x + ball.radius) >= screenWidth) || ((ball.position.x - ball.radius) <= 0)) ball.speed.x *= -1;
if ((ball.position.y - ball.radius) <= 0) ball.speed.y *= -1;
if ((ball.position.y + ball.radius) >= screenHeight)
{
ball.speed = (Vector2){ 0, 0 };
ball.active = false;
player.life--;
}
// Collision logic: ball vs player
if (CheckCollisionCircleRec(ball.position, ball.radius,
(Rectangle){ player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y}))
{
if (ball.speed.y > 0)
{
ball.speed.y *= -1;
ball.speed.x = (ball.position.x - player.position.x)/(player.size.x/2)*5;
}
}
// Collision logic: ball vs bricks
for (int i = 0; i < LINES_OF_BRICKS; i++)
{
for (int j = 0; j < BRICKS_PER_LINE; j++)
{
if (brick[i][j].active)
{
// Hit below
if (((ball.position.y - ball.radius) <= (brick[i][j].position.y + brickSize.y/2)) &&
((ball.position.y - ball.radius) > (brick[i][j].position.y + brickSize.y/2 + ball.speed.y)) &&
((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y < 0))
{
brick[i][j].active = false;
ball.speed.y *= -1;
}
// Hit above
else if (((ball.position.y + ball.radius) >= (brick[i][j].position.y - brickSize.y/2)) &&
((ball.position.y + ball.radius) < (brick[i][j].position.y - brickSize.y/2 + ball.speed.y)) &&
((fabs(ball.position.x - brick[i][j].position.x)) < (brickSize.x/2 + ball.radius*2/3)) && (ball.speed.y > 0))
{
brick[i][j].active = false;
ball.speed.y *= -1;
}
// Hit left
else if (((ball.position.x + ball.radius) >= (brick[i][j].position.x - brickSize.x/2)) &&
((ball.position.x + ball.radius) < (brick[i][j].position.x - brickSize.x/2 + ball.speed.x)) &&
((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x > 0))
{
brick[i][j].active = false;
ball.speed.x *= -1;
}
// Hit right
else if (((ball.position.x - ball.radius) <= (brick[i][j].position.x + brickSize.x/2)) &&
((ball.position.x - ball.radius) > (brick[i][j].position.x + brickSize.x/2 + ball.speed.x)) &&
((fabs(ball.position.y - brick[i][j].position.y)) < (brickSize.y/2 + ball.radius*2/3)) && (ball.speed.x < 0))
{
brick[i][j].active = false;
ball.speed.x *= -1;
}
}
}
}
// Game over logic
if (player.life <= 0) gameOver = true;
else
{
gameOver = true;
for (int i = 0; i < LINES_OF_BRICKS; i++)
{
for (int j = 0; j < BRICKS_PER_LINE; j++)
{
if (brick[i][j].active) gameOver = false;
}
}
}
}
}
else
{
if (IsKeyPressed(KEY_ENTER))
{
InitGame();
gameOver = false;
}
}
}
// Draw game (one frame)
void DrawGame(void)
{
BeginDrawing();
ClearBackground(RAYWHITE);
if (!gameOver)
{
// Draw player bar
DrawRectangle(player.position.x - player.size.x/2, player.position.y - player.size.y/2, player.size.x, player.size.y, BLACK);
// Draw player lives
for (int i = 0; i < player.life; i++) DrawRectangle(20 + 40*i, screenHeight - 30, 35, 10, LIGHTGRAY);
// Draw ball
DrawCircleV(ball.position, ball.radius, MAROON);
// Draw bricks
for (int i = 0; i < LINES_OF_BRICKS; i++)
{
for (int j = 0; j < BRICKS_PER_LINE; j++)
{
if (brick[i][j].active)
{
if ((i + j) % 2 == 0) DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, GRAY);
else DrawRectangle(brick[i][j].position.x - brickSize.x/2, brick[i][j].position.y - brickSize.y/2, brickSize.x, brickSize.y, DARKGRAY);
}
}
}
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
}
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
EndDrawing();
}
// Unload game variables
void UnloadGame(void)
{
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
}
// Update and Draw (one frame)
void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
}

View File

@ -1,565 +0,0 @@
/*******************************************************************************************
*
* raylib - sample game: asteroids
*
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
*
* This game has been created using raylib v1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
//----------------------------------------------------------------------------------
// Some Defines
//----------------------------------------------------------------------------------
#define PLAYER_BASE_SIZE 20.0f
#define PLAYER_SPEED 6.0f
#define PLAYER_MAX_SHOOTS 10
#define METEORS_SPEED 2
#define MAX_BIG_METEORS 4
#define MAX_MEDIUM_METEORS 8
#define MAX_SMALL_METEORS 16
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Player {
Vector2 position;
Vector2 speed;
float acceleration;
float rotation;
Vector3 collider;
Color color;
} Player;
typedef struct Shoot {
Vector2 position;
Vector2 speed;
float radius;
float rotation;
int lifeSpawn;
bool active;
Color color;
} Shoot;
typedef struct Meteor {
Vector2 position;
Vector2 speed;
float radius;
bool active;
Color color;
} Meteor;
//------------------------------------------------------------------------------------
// Global Variables Declaration
//------------------------------------------------------------------------------------
static const int screenWidth = 800;
static const int screenHeight = 450;
static bool gameOver = false;
static bool pause = false;
static bool victory = false;
// NOTE: Defined triangle is isosceles with common angles of 70 degrees.
static float shipHeight = 0.0f;
static Player player = { 0 };
static Shoot shoot[PLAYER_MAX_SHOOTS] = { 0 };
static Meteor bigMeteor[MAX_BIG_METEORS] = { 0 };
static Meteor mediumMeteor[MAX_MEDIUM_METEORS] = { 0 };
static Meteor smallMeteor[MAX_SMALL_METEORS] = { 0 };
static int midMeteorsCount = 0;
static int smallMeteorsCount = 0;
static int destroyedMeteorsCount = 0;
//------------------------------------------------------------------------------------
// Module Functions Declaration (local)
//------------------------------------------------------------------------------------
static void InitGame(void); // Initialize game
static void UpdateGame(void); // Update game (one frame)
static void DrawGame(void); // Draw game (one frame)
static void UnloadGame(void); // Unload game
static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
InitWindow(screenWidth, screenHeight, "sample game: asteroids");
InitGame();
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update and Draw
//----------------------------------------------------------------------------------
UpdateDrawFrame();
//----------------------------------------------------------------------------------
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadGame(); // Unload loaded data (textures, sounds, models...)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definitions (local)
//------------------------------------------------------------------------------------
// Initialize game variables
void InitGame(void)
{
int posx, posy;
int velx, vely;
bool correctRange = false;
victory = false;
pause = false;
shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD);
// Initialization player
player.position = (Vector2){screenWidth/2, screenHeight/2 - shipHeight/2};
player.speed = (Vector2){0, 0};
player.acceleration = 0;
player.rotation = 0;
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
player.color = LIGHTGRAY;
destroyedMeteorsCount = 0;
// Initialization shoot
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
shoot[i].position = (Vector2){0, 0};
shoot[i].speed = (Vector2){0, 0};
shoot[i].radius = 2;
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
shoot[i].color = WHITE;
}
for (int i = 0; i < MAX_BIG_METEORS; i++)
{
posx = GetRandomValue(0, screenWidth);
while(!correctRange)
{
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
else correctRange = true;
}
correctRange = false;
posy = GetRandomValue(0, screenHeight);
while(!correctRange)
{
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
else correctRange = true;
}
bigMeteor[i].position = (Vector2){posx, posy};
correctRange = false;
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
while(!correctRange)
{
if (velx == 0 && vely == 0)
{
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
}
else correctRange = true;
}
bigMeteor[i].speed = (Vector2){velx, vely};
bigMeteor[i].radius = 40;
bigMeteor[i].active = true;
bigMeteor[i].color = BLUE;
}
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
{
mediumMeteor[i].position = (Vector2){-100, -100};
mediumMeteor[i].speed = (Vector2){0,0};
mediumMeteor[i].radius = 20;
mediumMeteor[i].active = false;
mediumMeteor[i].color = BLUE;
}
for (int i = 0; i < MAX_SMALL_METEORS; i++)
{
smallMeteor[i].position = (Vector2){-100, -100};
smallMeteor[i].speed = (Vector2){0,0};
smallMeteor[i].radius = 10;
smallMeteor[i].active = false;
smallMeteor[i].color = BLUE;
}
midMeteorsCount = 0;
smallMeteorsCount = 0;
}
// Update game (one frame)
void UpdateGame(void)
{
if (!gameOver)
{
if (IsKeyPressed('P')) pause = !pause;
if (!pause)
{
// Player logic: rotation
if (IsKeyDown(KEY_LEFT)) player.rotation -= 5;
if (IsKeyDown(KEY_RIGHT)) player.rotation += 5;
// Player logic: speed
player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
// Player logic: acceleration
if (IsKeyDown(KEY_UP))
{
if (player.acceleration < 1) player.acceleration += 0.04f;
}
else
{
if (player.acceleration > 0) player.acceleration -= 0.02f;
else if (player.acceleration < 0) player.acceleration = 0;
}
if (IsKeyDown(KEY_DOWN))
{
if (player.acceleration > 0) player.acceleration -= 0.04f;
else if (player.acceleration < 0) player.acceleration = 0;
}
// Player logic: movement
player.position.x += (player.speed.x*player.acceleration);
player.position.y -= (player.speed.y*player.acceleration);
// Collision logic: player vs walls
if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight);
else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight;
if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight);
else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight;
// Player shoot logic
if (IsKeyPressed(KEY_SPACE))
{
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
if (!shoot[i].active)
{
shoot[i].position = (Vector2){ player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight) };
shoot[i].active = true;
shoot[i].speed.x = 1.5*sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
shoot[i].speed.y = 1.5*cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
shoot[i].rotation = player.rotation;
break;
}
}
}
// Shoot life timer
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
if (shoot[i].active) shoot[i].lifeSpawn++;
}
// Shot logic
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
if (shoot[i].active)
{
// Movement
shoot[i].position.x += shoot[i].speed.x;
shoot[i].position.y -= shoot[i].speed.y;
// Collision logic: shoot vs walls
if (shoot[i].position.x > screenWidth + shoot[i].radius)
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
}
else if (shoot[i].position.x < 0 - shoot[i].radius)
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
}
if (shoot[i].position.y > screenHeight + shoot[i].radius)
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
}
else if (shoot[i].position.y < 0 - shoot[i].radius)
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
}
// Life of shoot
if (shoot[i].lifeSpawn >= 60)
{
shoot[i].position = (Vector2){0, 0};
shoot[i].speed = (Vector2){0, 0};
shoot[i].lifeSpawn = 0;
shoot[i].active = false;
}
}
}
// Collision logic: player vs meteors
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
for (int a = 0; a < MAX_BIG_METEORS; a++)
{
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, bigMeteor[a].position, bigMeteor[a].radius) && bigMeteor[a].active) gameOver = true;
}
for (int a = 0; a < MAX_MEDIUM_METEORS; a++)
{
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, mediumMeteor[a].position, mediumMeteor[a].radius) && mediumMeteor[a].active) gameOver = true;
}
for (int a = 0; a < MAX_SMALL_METEORS; a++)
{
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, smallMeteor[a].position, smallMeteor[a].radius) && smallMeteor[a].active) gameOver = true;
}
// Meteors logic: big meteors
for (int i = 0; i < MAX_BIG_METEORS; i++)
{
if (bigMeteor[i].active)
{
// Movement
bigMeteor[i].position.x += bigMeteor[i].speed.x;
bigMeteor[i].position.y += bigMeteor[i].speed.y;
// Collision logic: meteor vs wall
if (bigMeteor[i].position.x > screenWidth + bigMeteor[i].radius) bigMeteor[i].position.x = -(bigMeteor[i].radius);
else if (bigMeteor[i].position.x < 0 - bigMeteor[i].radius) bigMeteor[i].position.x = screenWidth + bigMeteor[i].radius;
if (bigMeteor[i].position.y > screenHeight + bigMeteor[i].radius) bigMeteor[i].position.y = -(bigMeteor[i].radius);
else if (bigMeteor[i].position.y < 0 - bigMeteor[i].radius) bigMeteor[i].position.y = screenHeight + bigMeteor[i].radius;
}
}
// Meteors logic: medium meteors
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
{
if (mediumMeteor[i].active)
{
// Movement
mediumMeteor[i].position.x += mediumMeteor[i].speed.x;
mediumMeteor[i].position.y += mediumMeteor[i].speed.y;
// Collision logic: meteor vs wall
if (mediumMeteor[i].position.x > screenWidth + mediumMeteor[i].radius) mediumMeteor[i].position.x = -(mediumMeteor[i].radius);
else if (mediumMeteor[i].position.x < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.x = screenWidth + mediumMeteor[i].radius;
if (mediumMeteor[i].position.y > screenHeight + mediumMeteor[i].radius) mediumMeteor[i].position.y = -(mediumMeteor[i].radius);
else if (mediumMeteor[i].position.y < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.y = screenHeight + mediumMeteor[i].radius;
}
}
// Meteors logic: small meteors
for (int i = 0; i < MAX_SMALL_METEORS; i++)
{
if (smallMeteor[i].active)
{
// Movement
smallMeteor[i].position.x += smallMeteor[i].speed.x;
smallMeteor[i].position.y += smallMeteor[i].speed.y;
// Collision logic: meteor vs wall
if (smallMeteor[i].position.x > screenWidth + smallMeteor[i].radius) smallMeteor[i].position.x = -(smallMeteor[i].radius);
else if (smallMeteor[i].position.x < 0 - smallMeteor[i].radius) smallMeteor[i].position.x = screenWidth + smallMeteor[i].radius;
if (smallMeteor[i].position.y > screenHeight + smallMeteor[i].radius) smallMeteor[i].position.y = -(smallMeteor[i].radius);
else if (smallMeteor[i].position.y < 0 - smallMeteor[i].radius) smallMeteor[i].position.y = screenHeight + smallMeteor[i].radius;
}
}
// Collision logic: player-shoots vs meteors
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
if ((shoot[i].active))
{
for (int a = 0; a < MAX_BIG_METEORS; a++)
{
if (bigMeteor[a].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, bigMeteor[a].position, bigMeteor[a].radius))
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
bigMeteor[a].active = false;
destroyedMeteorsCount++;
for (int j = 0; j < 2; j ++)
{
if (midMeteorsCount%2 == 0)
{
mediumMeteor[midMeteorsCount].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y};
mediumMeteor[midMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1};
}
else
{
mediumMeteor[midMeteorsCount].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y};
mediumMeteor[midMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED};
}
mediumMeteor[midMeteorsCount].active = true;
midMeteorsCount ++;
}
//bigMeteor[a].position = (Vector2){-100, -100};
bigMeteor[a].color = RED;
a = MAX_BIG_METEORS;
}
}
for (int b = 0; b < MAX_MEDIUM_METEORS; b++)
{
if (mediumMeteor[b].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, mediumMeteor[b].position, mediumMeteor[b].radius))
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
mediumMeteor[b].active = false;
destroyedMeteorsCount++;
for (int j = 0; j < 2; j ++)
{
if (smallMeteorsCount%2 == 0)
{
smallMeteor[smallMeteorsCount].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y};
smallMeteor[smallMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1};
}
else
{
smallMeteor[smallMeteorsCount].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y};
smallMeteor[smallMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED};
}
smallMeteor[smallMeteorsCount].active = true;
smallMeteorsCount ++;
}
//mediumMeteor[b].position = (Vector2){-100, -100};
mediumMeteor[b].color = GREEN;
b = MAX_MEDIUM_METEORS;
}
}
for (int c = 0; c < MAX_SMALL_METEORS; c++)
{
if (smallMeteor[c].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, smallMeteor[c].position, smallMeteor[c].radius))
{
shoot[i].active = false;
shoot[i].lifeSpawn = 0;
smallMeteor[c].active = false;
destroyedMeteorsCount++;
smallMeteor[c].color = YELLOW;
// smallMeteor[c].position = (Vector2){-100, -100};
c = MAX_SMALL_METEORS;
}
}
}
}
}
if (destroyedMeteorsCount == MAX_BIG_METEORS + MAX_MEDIUM_METEORS + MAX_SMALL_METEORS) victory = true;
}
else
{
if (IsKeyPressed(KEY_ENTER))
{
InitGame();
gameOver = false;
}
}
}
// Draw game (one frame)
void DrawGame(void)
{
BeginDrawing();
ClearBackground(RAYWHITE);
if (!gameOver)
{
// Draw spaceship
Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) };
Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
DrawTriangle(v1, v2, v3, MAROON);
// Draw meteors
for (int i = 0; i < MAX_BIG_METEORS; i++)
{
if (bigMeteor[i].active) DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, DARKGRAY);
else DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
}
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
{
if (mediumMeteor[i].active) DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, GRAY);
else DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
}
for (int i = 0; i < MAX_SMALL_METEORS; i++)
{
if (smallMeteor[i].active) DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, GRAY);
else DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
}
// Draw shoot
for (int i = 0; i < PLAYER_MAX_SHOOTS; i++)
{
if (shoot[i].active) DrawCircleV(shoot[i].position, shoot[i].radius, BLACK);
}
if (victory) DrawText("VICTORY", screenWidth/2 - MeasureText("VICTORY", 20)/2, screenHeight/2, 20, LIGHTGRAY);
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
}
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
EndDrawing();
}
// Unload game variables
void UnloadGame(void)
{
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
}
// Update and Draw (one frame)
void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
}

View File

@ -1,375 +0,0 @@
/*******************************************************************************************
*
* raylib - sample game: asteroids survival
*
* Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria
*
* This game has been created using raylib v1.3 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2015 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <math.h>
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
//----------------------------------------------------------------------------------
// Some Defines
//----------------------------------------------------------------------------------
#define PLAYER_BASE_SIZE 20.0f
#define PLAYER_SPEED 6.0f
#define PLAYER_MAX_SHOOTS 10
#define METEORS_SPEED 2
#define MAX_MEDIUM_METEORS 8
#define MAX_SMALL_METEORS 16
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef struct Player {
Vector2 position;
Vector2 speed;
float acceleration;
float rotation;
Vector3 collider;
Color color;
} Player;
typedef struct Meteor {
Vector2 position;
Vector2 speed;
float radius;
bool active;
Color color;
} Meteor;
//------------------------------------------------------------------------------------
// Global Variables Declaration
//------------------------------------------------------------------------------------
static const int screenWidth = 800;
static const int screenHeight = 450;
static int framesCounter = 0;
static bool gameOver = false;
static bool pause = false;
// NOTE: Defined triangle is isosceles with common angles of 70 degrees.
static float shipHeight = 0.0f;
static Player player = { 0 };
static Meteor mediumMeteor[MAX_MEDIUM_METEORS] = { 0 };
static Meteor smallMeteor[MAX_SMALL_METEORS] = { 0 };
//------------------------------------------------------------------------------------
// Module Functions Declaration (local)
//------------------------------------------------------------------------------------
static void InitGame(void); // Initialize game
static void UpdateGame(void); // Update game (one frame)
static void DrawGame(void); // Draw game (one frame)
static void UnloadGame(void); // Unload game
static void UpdateDrawFrame(void); // Update and Draw (one frame)
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
InitWindow(screenWidth, screenHeight, "sample game: asteroids survival");
InitGame();
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60);
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update and Draw
//----------------------------------------------------------------------------------
UpdateDrawFrame();
//----------------------------------------------------------------------------------
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------
UnloadGame(); // Unload loaded data (textures, sounds, models...)
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Definitions (local)
//------------------------------------------------------------------------------------
// Initialize game variables
void InitGame(void)
{
int posx, posy;
int velx, vely;
bool correctRange = false;
pause = false;
framesCounter = 0;
shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD);
// Initialization player
player.position = (Vector2){screenWidth/2, screenHeight/2 - shipHeight/2};
player.speed = (Vector2){0, 0};
player.acceleration = 0;
player.rotation = 0;
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
player.color = LIGHTGRAY;
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
{
posx = GetRandomValue(0, screenWidth);
while(!correctRange)
{
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
else correctRange = true;
}
correctRange = false;
posy = GetRandomValue(0, screenHeight);
while(!correctRange)
{
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
else correctRange = true;
}
correctRange = false;
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
while(!correctRange)
{
if (velx == 0 && vely == 0)
{
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
}
else correctRange = true;
}
mediumMeteor[i].position = (Vector2){posx, posy};
mediumMeteor[i].speed = (Vector2){velx, vely};
mediumMeteor[i].radius = 20;
mediumMeteor[i].active = true;
mediumMeteor[i].color = GREEN;
}
for (int i = 0; i < MAX_SMALL_METEORS; i++)
{
posx = GetRandomValue(0, screenWidth);
while(!correctRange)
{
if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth);
else correctRange = true;
}
correctRange = false;
posy = GetRandomValue(0, screenHeight);
while(!correctRange)
{
if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight);
else correctRange = true;
}
correctRange = false;
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
while(!correctRange)
{
if (velx == 0 && vely == 0)
{
velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED);
}
else correctRange = true;
}
smallMeteor[i].position = (Vector2){posx, posy};
smallMeteor[i].speed = (Vector2){velx, vely};
smallMeteor[i].radius = 10;
smallMeteor[i].active = true;
smallMeteor[i].color = YELLOW;
}
}
// Update game (one frame)
void UpdateGame(void)
{
if (!gameOver)
{
if (IsKeyPressed('P')) pause = !pause;
if (!pause)
{
framesCounter++;
// Player logic
// Rotation
if (IsKeyDown(KEY_LEFT)) player.rotation -= 5;
if (IsKeyDown(KEY_RIGHT)) player.rotation += 5;
// Speed
player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED;
player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED;
// Controller
if (IsKeyDown(KEY_UP))
{
if (player.acceleration < 1) player.acceleration += 0.04f;
}
else
{
if (player.acceleration > 0) player.acceleration -= 0.02f;
else if (player.acceleration < 0) player.acceleration = 0;
}
if (IsKeyDown(KEY_DOWN))
{
if (player.acceleration > 0) player.acceleration -= 0.04f;
else if (player.acceleration < 0) player.acceleration = 0;
}
// Movement
player.position.x += (player.speed.x*player.acceleration);
player.position.y -= (player.speed.y*player.acceleration);
// Wall behaviour for player
if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight);
else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight;
if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight);
else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight;
// Collision Player to meteors
player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12};
for (int a = 0; a < MAX_MEDIUM_METEORS; a++)
{
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, mediumMeteor[a].position, mediumMeteor[a].radius) && mediumMeteor[a].active) gameOver = true;
}
for (int a = 0; a < MAX_SMALL_METEORS; a++)
{
if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, smallMeteor[a].position, smallMeteor[a].radius) && smallMeteor[a].active) gameOver = true;
}
// Meteor logic
for (int i = 0; i < MAX_MEDIUM_METEORS; i++)
{
if (mediumMeteor[i].active)
{
// movement
mediumMeteor[i].position.x += mediumMeteor[i].speed.x;
mediumMeteor[i].position.y += mediumMeteor[i].speed.y;
// wall behaviour
if (mediumMeteor[i].position.x > screenWidth + mediumMeteor[i].radius) mediumMeteor[i].position.x = -(mediumMeteor[i].radius);
else if (mediumMeteor[i].position.x < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.x = screenWidth + mediumMeteor[i].radius;
if (mediumMeteor[i].position.y > screenHeight + mediumMeteor[i].radius) mediumMeteor[i].position.y = -(mediumMeteor[i].radius);
else if (mediumMeteor[i].position.y < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.y = screenHeight + mediumMeteor[i].radius;
}
}
for (int i = 0; i < MAX_SMALL_METEORS; i++)
{
if (smallMeteor[i].active)
{
// movement
smallMeteor[i].position.x += smallMeteor[i].speed.x;
smallMeteor[i].position.y += smallMeteor[i].speed.y;
// wall behaviour
if (smallMeteor[i].position.x > screenWidth + smallMeteor[i].radius) smallMeteor[i].position.x = -(smallMeteor[i].radius);
else if (smallMeteor[i].position.x < 0 - smallMeteor[i].radius) smallMeteor[i].position.x = screenWidth + smallMeteor[i].radius;
if (smallMeteor[i].position.y > screenHeight + smallMeteor[i].radius) smallMeteor[i].position.y = -(smallMeteor[i].radius);
else if (smallMeteor[i].position.y < 0 - smallMeteor[i].radius) smallMeteor[i].position.y = screenHeight + smallMeteor[i].radius;
}
}
}
}
else
{
if (IsKeyPressed(KEY_ENTER))
{
InitGame();
gameOver = false;
}
}
}
// Draw game (one frame)
void DrawGame(void)
{
BeginDrawing();
ClearBackground(RAYWHITE);
if (!gameOver)
{
// Draw spaceship
Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) };
Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) };
DrawTriangle(v1, v2, v3, MAROON);
// Draw meteor
for (int i = 0;i < MAX_MEDIUM_METEORS; i++)
{
if (mediumMeteor[i].active) DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, GRAY);
else DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
}
for (int i = 0;i < MAX_SMALL_METEORS; i++)
{
if (smallMeteor[i].active) DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, DARKGRAY);
else DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, Fade(LIGHTGRAY, 0.3f));
}
DrawText(TextFormat("TIME: %.02f", (float)framesCounter/60), 10, 10, 20, BLACK);
if (pause) DrawText("GAME PAUSED", screenWidth/2 - MeasureText("GAME PAUSED", 40)/2, screenHeight/2 - 40, 40, GRAY);
}
else DrawText("PRESS [ENTER] TO PLAY AGAIN", GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN", 20)/2, GetScreenHeight()/2 - 50, 20, GRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// Unload game variables
void UnloadGame(void)
{
// TODO: Unload all dynamic loaded data (textures, sounds, models...)
}
// Update and Draw (one frame)
void UpdateDrawFrame(void)
{
UpdateGame();
DrawGame();
}

View File

@ -1,20 +0,0 @@

This game sources are licensed under an unmodified zlib/libpng license,
which is an OSI-certified, BSD-like license:
Copyright (c) 2013-2019 Ramon Santamaria (@raysan5)
This software is provided "as-is", without any express or implied warranty. In no event
will the authors be held liable for any damages arising from the use of this software.
Permission is granted to anyone to use this software for any purpose, including commercial
applications, and to alter it and redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that you
wrote the original software. If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be misrepresented
as being the original software.
3. This notice may not be removed or altered from any source distribution.

View File

@ -1,406 +0,0 @@
#**************************************************************************************************
#
# raylib makefile for Desktop platforms, Raspberry Pi, Android and HTML5
#
# Copyright (c) 2013-2020 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 ?= roomba
RAYLIB_VERSION ?= 3.0.0
RAYLIB_API_VERSION ?= 3
RAYLIB_PATH ?= C:\GitHub\raylib
# 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:/emsdk
EMSCRIPTEN_PATH ?= $(EMSDK_PATH)/fastcomp/emscripten
CLANG_PATH = $(EMSDK_PATH)/fastcomp/bin
PYTHON_PATH = $(EMSDK_PATH)/python/2.7.13.1_64bit/python-2.7.13.amd64
NODE_PATH = $(EMSDK_PATH)/node/12.9.1_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
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 += -Wall -std=c99 -D_DEFAULT_SOURCE -Wno-missing-braces
ifeq ($(BUILD_MODE),DEBUG)
CFLAGS += -g
ifeq ($(PLATFORM),PLATFORM_WEB)
CFLAGS += -s ASSERTIONS=1 --profiling
endif
else
ifeq ($(PLATFORM),PLATFORM_WEB)
CFLAGS += -Os
else
CFLAGS += -s -O1
endif
endif
# Additional flags for compiler (if desired)
#CFLAGS += -Wextra -Wmissing-prototypes -Wstrict-prototypes
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),LINUX)
ifeq ($(RAYLIB_LIBTYPE),STATIC)
CFLAGS += -D_DEFAULT_SOURCE
endif
ifeq ($(RAYLIB_LIBTYPE),SHARED)
# Explicitly enable runtime link to libraylib.so
CFLAGS += -Wl,-rpath,$(EXAMPLE_RUNTIME_PATH)
endif
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
CFLAGS += -std=gnu99
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
# -Os # size optimization
# -O2 # optimization level 2, if used, also set --memory-init-file 0
# -s USE_GLFW=3 # Use glfw3 library (context/input management)
# -s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing -> WARNING: Audio buffers could FAIL!
# -s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
# -s USE_PTHREADS=1 # multithreading support
# -s WASM=0 # disable Web Assembly, emitted by default
# -s EMTERPRETIFY=1 # enable emscripten code interpreter (very slow)
# -s EMTERPRETIFY_ASYNC=1 # support synchronous loops by emterpreter
# -s FORCE_FILESYSTEM=1 # force filesystem to load/save files data
# -s ASSERTIONS=1 # enable runtime checks for common memory allocation errors (-O1 and above turn it off)
# --profiling # include information for code profiling
# --memory-init-file 0 # to avoid an external memory initialization code file (.mem)
# --preload-file resources # specify a resources folder for data compilation
CFLAGS += -s USE_GLFW=3 -s TOTAL_MEMORY=16777216 --preload-file resources
# 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),WINDOWS)
# resource file contains windows executable icon and properties
LDFLAGS += $(RAYLIB_PATH)/src/raylib.rc.data
# -Wl,--subsystem,windows hides the console window
ifeq ($(BUILD_MODE), RELEASE)
LDFLAGS += -Wl,--subsystem,windows
endif
endif
ifeq ($(PLATFORM_OS),BSD)
# Consider -L$(RAYLIB_INSTALL_PATH)
LDFLAGS += -L. -Lsrc -L/usr/local/lib
endif
ifeq ($(PLATFORM_OS),LINUX)
# Reset everything.
# Precedence: immediately local, installed version, raysan5 provided libs
LDFLAGS = -L. -L$(RAYLIB_INSTALL_PATH) -L$(RAYLIB_RELEASE_PATH)
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
LDFLAGS += -L/opt/vc/lib
endif
# Define any libraries required on linking
# if you want to link libraries (libname.so or libname.a), use the -lname
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
ifeq ($(PLATFORM_OS),WINDOWS)
# Libraries for Windows desktop compilation
# NOTE: WinMM library required to set high-res timer resolution
LDLIBS = -lraylib -lopengl32 -lgdi32 -lwinmm
# Required for physac examples
LDLIBS += -static -lpthread
endif
ifeq ($(PLATFORM_OS),LINUX)
# Libraries for Debian GNU/Linux desktop compiling
# NOTE: Required packages: libegl1-mesa-dev
LDLIBS = -lraylib -lGL -lm -lpthread -ldl -lrt
# On X11 requires also below libraries
LDLIBS += -lX11
# NOTE: It seems additional libraries are not required any more, latest GLFW just dlopen them
#LDLIBS += -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor
# On Wayland windowing system, additional libraries requires
ifeq ($(USE_WAYLAND_DISPLAY),TRUE)
LDLIBS += -lwayland-client -lwayland-cursor -lwayland-egl -lxkbcommon
endif
# Explicit link to libc
ifeq ($(RAYLIB_LIBTYPE),SHARED)
LDLIBS += -lc
endif
endif
ifeq ($(PLATFORM_OS),OSX)
# Libraries for OSX 10.9 desktop compiling
# NOTE: Required packages: libopenal-dev libegl1-mesa-dev
LDLIBS = -lraylib -framework OpenGL -framework Cocoa -framework IOKit -framework CoreAudio -framework CoreVideo
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 all source files required
PROJECT_SOURCE_FILES ?= \
roomba.c \
screens/screen_logo.c \
screens/screen_title.c \
screens/screen_gameplay.c \
screens/screen_ending.c
# Define all object files from source files
OBJS = $(patsubst %.c, %.o, $(PROJECT_SOURCE_FILES))
# For Android platform we call a custom Makefile.Android
ifeq ($(PLATFORM),PLATFORM_ANDROID)
MAKEFILE_PARAMS = -f Makefile.Android
export PROJECT_NAME
export PROJECT_SOURCE_FILES
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
$(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|x-pie-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -fv
endif
ifeq ($(PLATFORM_OS),OSX)
find . -type f -perm +ugo+x -delete
rm -f *.o
endif
endif
ifeq ($(PLATFORM),PLATFORM_RPI)
find . -type f -executable -delete
rm -fv *.o
endif
ifeq ($(PLATFORM),PLATFORM_WEB)
del *.o *.html *.js
endif
@echo Cleaning done

View File

@ -1,300 +0,0 @@
#**************************************************************************************************
#
# raylib makefile for Android project (APK building)
#
# Copyright (c) 2017 Ramon Santamaria (@raysan5)
#
# This software is provided "as-is", without any express or implied warranty. In no event
# will the authors be held liable for any damages arising from the use of this software.
#
# Permission is granted to anyone to use this software for any purpose, including commercial
# applications, and to alter it and redistribute it freely, subject to the following restrictions:
#
# 1. The origin of this software must not be misrepresented; you must not claim that you
# wrote the original software. If you use this software in a product, an acknowledgment
# in the product documentation would be appreciated but is not required.
#
# 2. Altered source versions must be plainly marked as such, and must not be misrepresented
# as being the original software.
#
# 3. This notice may not be removed or altered from any source distribution.
#
#**************************************************************************************************
# Define required raylib variables
PLATFORM ?= PLATFORM_ANDROID
RAYLIB_PATH ?= ..\..
# Define Android architecture (armeabi-v7a, arm64-v8a, x86, x86-64) and API version
ANDROID_ARCH ?= ARM
ANDROID_API_VERSION = 21
ifeq ($(ANDROID_ARCH),ARM)
ANDROID_ARCH_NAME = armeabi-v7a
endif
ifeq ($(ANDROID_ARCH),ARM64)
ANDROID_ARCH_NAME = arm64-v8a
endif
# Required path variables
# NOTE: JAVA_HOME must be set to JDK
JAVA_HOME ?= C:/JavaJDK
ANDROID_HOME = C:/android-sdk
ANDROID_TOOLCHAIN = C:/android_toolchain_$(ANDROID_ARCH)_API$(ANDROID_API_VERSION)
ANDROID_BUILD_TOOLS = $(ANDROID_HOME)/build-tools/28.0.1
ANDROID_PLATFORM_TOOLS = $(ANDROID_HOME)/platform-tools
# Android project configuration variables
PROJECT_NAME ?= raylib_game
PROJECT_LIBRARY_NAME ?= main
PROJECT_BUILD_PATH ?= android.$(PROJECT_NAME)
PROJECT_RESOURCES_PATH ?= resources
PROJECT_SOURCE_FILES ?= raylib_game.c
# Some source files are placed in directories, when compiling to some
# output directory other than source, that directory must pre-exist.
# Here we get a list of required folders that need to be created on
# code output folder $(PROJECT_BUILD_PATH)\obj to avoid GCC errors.
PROJECT_SOURCE_DIRS = $(sort $(dir $(PROJECT_SOURCE_FILES)))
# Android app configuration variables
APP_LABEL_NAME ?= rGame
APP_COMPANY_NAME ?= raylib
APP_PRODUCT_NAME ?= rgame
APP_VERSION_CODE ?= 1
APP_VERSION_NAME ?= 1.0
APP_ICON_LDPI ?= $(RAYLIB_PATH)\logo\raylib_36x36.png
APP_ICON_MDPI ?= $(RAYLIB_PATH)\logo\raylib_48x48.png
APP_ICON_HDPI ?= $(RAYLIB_PATH)\logo\raylib_72x72.png
APP_SCREEN_ORIENTATION ?= landscape
APP_KEYSTORE_PASS ?= raylib
# Library type used for raylib: STATIC (.a) or SHARED (.so/.dll)
RAYLIB_LIBTYPE ?= STATIC
# Library path for libraylib.a/libraylib.so
RAYLIB_LIB_PATH = $(RAYLIB_PATH)\src
# Shared libs must be added to APK if required
# NOTE: Generated NativeLoader.java automatically load those libraries
ifeq ($(RAYLIB_LIBTYPE),SHARED)
PROJECT_SHARED_LIBS = lib/$(ANDROID_ARCH_NAME)/libraylib.so
endif
# Compiler and archiver
# NOTE: GCC is being deprecated in Android NDK r16
ifeq ($(ANDROID_ARCH),ARM)
CC = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-clang
AR = $(ANDROID_TOOLCHAIN)/bin/arm-linux-androideabi-ar
endif
ifeq ($(ANDROID_ARCH),ARM64)
CC = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-clang
AR = $(ANDROID_TOOLCHAIN)/bin/aarch64-linux-android-ar
endif
# Compiler flags for arquitecture
ifeq ($(ANDROID_ARCH),ARM)
CFLAGS = -std=c99 -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16
endif
ifeq ($(ANDROID_ARCH),ARM64)
CFLAGS = -std=c99 -target aarch64 -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

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -1,16 +0,0 @@
1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,1,1,1,2,2,2,1,1,1,0,0,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,1,1,1,2,2,2,1,1,1,0,0,1,1,1,2,2,2,1,1,1,1,0,0,1,1,1,1,0,0,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,0,0,1,1,1,1,0,0,
0,0,1,1,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,2,2,2,2,2,2,2,2,0,0,1,1,1,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,2,2,2,2,2,2,2,2,0,0,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,
0,0,0,0,0,0,0,0,0,0,2,2,2,0,0,0,0,1,1,0,0,1,2,2,2,2,2,2,2,2,0,0

Binary file not shown.

Before

Width:  |  Height:  |  Size: 883 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -1,34 +0,0 @@
.furniture
.state: 0-Block, 1-Alpha, 2-Breakable
.f setId cellX cellY state counter
.puff and sits
f 3 0 4 0 0
f 3 13 0 0 0
f 3 22 0 0 0
f 3 21 11 0 0
f 2 19 15 0 0
f 2 30 5 0 0
f 4 12 4 0 0
.wood pieces
f 26 3 0 0 0
f 27 4 10 0 0
f 27 24 7 0 0
f 17 30 15 0 0
.kitchen
f 11 0 15 0 0
f 13 0 12 0 0
.sofa and bed (alpha)
f 14 4 7 1 0
f 10 24 11 1 0
.glass and tables (alpha)
f 9 17 4 1 0
f 16 6 4 1 0
f 16 10 15 1 0
f 15 22 15 1 0
.plants (breakable)
f 6 0 6 2 1800
f 6 12 10 2 1800
f 7 17 0 2 1200
f 7 15 15 2 1200
f 8 13 15 2 2000
f 8 24 5 2 2000

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

View File

@ -1,37 +0,0 @@
.tileset
.first line
f 0 0 0 2 2
f 1 2 0 2 2
f 2 4 0 2 2
f 3 6 0 2 2
f 4 8 0 2 2
f 5 10 0 2 2
f 6 12 0 2 2
f 7 14 0 2 2
f 8 16 0 2 2
f 9 18 0 5 6
f 10 23 0 6 6
.second line
f 11 0 2 10 2
f 12 10 2 7 3
.third line
f 13 0 4 2 3
f 14 2 4 8 3
f 15 10 5 2 2
f 16 12 5 3 2
f 17 15 5 2 2
.cups
f 18 17 6 1 1
f 19 18 6 1 1
f 20 19 6 1 1
f 21 20 6 1 1
f 22 21 6 1 1
f 23 22 6 1 1
f 24 23 6 1 1
f 25 24 6 1 1
.four line
f 26 0 7 10 2
f 27 10 7 8 2
f 28 18 7 3 2
f 29 21 7 3 2
f 30 24 7 2 2

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -1,139 +0,0 @@
info face="Starcatcher" size=-64 bold=0 italic=0 charset="ANSI" unicode=0 stretchH=100 smooth=1 aa=1 padding=4,4,4,4 spacing=1,1 outline=0
common lineHeight=63 base=50 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
page id=0 file="star.png"
chars count=135
char id=32 x=416 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=27 page=0 chnl=15
char id=33 x=347 y=360 width=17 height=71 xoffset=-4 yoffset=-4 xadvance=9 page=0 chnl=15
char id=35 x=183 y=0 width=48 height=71 xoffset=-4 yoffset=-4 xadvance=40 page=0 chnl=15
char id=36 x=328 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=37 x=67 y=0 width=62 height=71 xoffset=-4 yoffset=-4 xadvance=55 page=0 chnl=15
char id=38 x=488 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=39 x=266 y=360 width=21 height=71 xoffset=-4 yoffset=-4 xadvance=13 page=0 chnl=15
char id=40 x=471 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=41 x=387 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=42 x=415 y=0 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=43 x=403 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=44 x=309 y=360 width=18 height=71 xoffset=-4 yoffset=-4 xadvance=10 page=0 chnl=15
char id=45 x=82 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=46 x=365 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=7 page=0 chnl=15
char id=47 x=155 y=288 width=29 height=71 xoffset=-4 yoffset=-4 xadvance=21 page=0 chnl=15
char id=48 x=38 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=49 x=188 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=50 x=339 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=51 x=0 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=52 x=35 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=53 x=105 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=54 x=207 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=55 x=433 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=56 x=468 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=57 x=0 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=58 x=399 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=7 page=0 chnl=15
char id=59 x=328 y=360 width=18 height=71 xoffset=-4 yoffset=-4 xadvance=10 page=0 chnl=15
char id=60 x=185 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=61 x=371 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=62 x=221 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=63 x=398 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=25 page=0 chnl=15
char id=64 x=130 y=0 width=52 height=71 xoffset=-4 yoffset=-4 xadvance=44 page=0 chnl=15
char id=65 x=445 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=66 x=209 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=32 page=0 chnl=15
char id=67 x=173 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=68 x=250 y=72 width=39 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=69 x=306 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=70 x=149 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=71 x=112 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=28 page=0 chnl=15
char id=72 x=458 y=0 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=73 x=288 y=360 width=20 height=71 xoffset=-4 yoffset=-4 xadvance=12 page=0 chnl=15
char id=74 x=257 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=75 x=0 y=144 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=76 x=139 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=25 page=0 chnl=15
char id=77 x=85 y=72 width=41 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=78 x=371 y=0 width=43 height=71 xoffset=-4 yoffset=-4 xadvance=35 page=0 chnl=15
char id=79 x=168 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=80 x=75 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=28 page=0 chnl=15
char id=81 x=280 y=0 width=45 height=71 xoffset=-4 yoffset=-4 xadvance=37 page=0 chnl=15
char id=82 x=369 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=83 x=70 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=84 x=43 y=72 width=41 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=85 x=0 y=72 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=86 x=326 y=0 width=44 height=71 xoffset=-4 yoffset=-4 xadvance=36 page=0 chnl=15
char id=87 x=232 y=0 width=47 height=71 xoffset=-4 yoffset=-4 xadvance=39 page=0 chnl=15
char id=88 x=127 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=89 x=290 y=72 width=39 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=90 x=330 y=72 width=38 height=71 xoffset=-4 yoffset=-4 xadvance=30 page=0 chnl=15
char id=91 x=499 y=288 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=92 x=109 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=93 x=499 y=216 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=97 x=302 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=98 x=415 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=99 x=136 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=100 x=124 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=101 x=162 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=102 x=443 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=103 x=0 y=360 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=104 x=240 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=105 x=382 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=8 page=0 chnl=15
char id=106 x=359 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=107 x=483 y=72 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=108 x=55 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=109 x=435 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=110 x=273 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=111 x=31 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=112 x=331 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=113 x=363 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=114 x=273 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=115 x=28 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=116 x=62 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=117 x=93 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=118 x=467 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=119 x=293 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=120 x=185 y=288 width=29 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=121 x=215 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=122 x=244 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=123 x=428 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=124 x=440 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=125 x=452 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=126 x=0 y=0 width=66 height=71 xoffset=-4 yoffset=-4 xadvance=58 page=0 chnl=15
char id=162 x=464 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=163 x=407 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=167 x=476 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=171 x=214 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=187 x=240 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=191 x=500 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=192 x=0 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=193 x=12 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=194 x=24 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=196 x=36 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=199 x=48 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=200 x=60 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=201 x=72 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=202 x=84 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=203 x=96 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=206 x=108 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=207 x=120 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=209 x=132 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=211 x=144 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=212 x=156 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=214 x=168 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=217 x=180 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=218 x=192 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=219 x=204 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=220 x=216 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=223 x=228 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=224 x=240 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=225 x=252 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=226 x=264 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=228 x=276 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=231 x=288 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=232 x=300 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=233 x=312 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=234 x=324 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=235 x=336 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=238 x=348 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=239 x=360 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=243 x=372 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=244 x=384 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=246 x=396 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=249 x=408 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=250 x=420 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=251 x=432 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=252 x=444 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15

Binary file not shown.

Before

Width:  |  Height:  |  Size: 80 KiB

View File

@ -1,139 +0,0 @@
info face="Starcatcher" size=-64 bold=0 italic=0 charset="ANSI" unicode=0 stretchH=100 smooth=1 aa=1 padding=4,4,4,4 spacing=1,1 outline=0
common lineHeight=63 base=50 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
page id=0 file="star2.png"
chars count=135
char id=32 x=416 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=27 page=0 chnl=15
char id=33 x=347 y=360 width=17 height=71 xoffset=-4 yoffset=-4 xadvance=9 page=0 chnl=15
char id=35 x=183 y=0 width=48 height=71 xoffset=-4 yoffset=-4 xadvance=40 page=0 chnl=15
char id=36 x=328 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=37 x=67 y=0 width=62 height=71 xoffset=-4 yoffset=-4 xadvance=55 page=0 chnl=15
char id=38 x=488 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=39 x=266 y=360 width=21 height=71 xoffset=-4 yoffset=-4 xadvance=13 page=0 chnl=15
char id=40 x=471 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=41 x=387 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=42 x=415 y=0 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=43 x=403 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=44 x=309 y=360 width=18 height=71 xoffset=-4 yoffset=-4 xadvance=10 page=0 chnl=15
char id=45 x=82 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=46 x=365 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=7 page=0 chnl=15
char id=47 x=155 y=288 width=29 height=71 xoffset=-4 yoffset=-4 xadvance=21 page=0 chnl=15
char id=48 x=38 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=49 x=188 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=50 x=339 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=51 x=0 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=52 x=35 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=53 x=105 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=54 x=207 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=55 x=433 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=56 x=468 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=57 x=0 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=58 x=399 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=7 page=0 chnl=15
char id=59 x=328 y=360 width=18 height=71 xoffset=-4 yoffset=-4 xadvance=10 page=0 chnl=15
char id=60 x=185 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=61 x=371 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=62 x=221 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=63 x=398 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=25 page=0 chnl=15
char id=64 x=130 y=0 width=52 height=71 xoffset=-4 yoffset=-4 xadvance=44 page=0 chnl=15
char id=65 x=445 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=66 x=209 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=32 page=0 chnl=15
char id=67 x=173 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=68 x=250 y=72 width=39 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=69 x=306 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=70 x=149 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=71 x=112 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=28 page=0 chnl=15
char id=72 x=458 y=0 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=73 x=288 y=360 width=20 height=71 xoffset=-4 yoffset=-4 xadvance=12 page=0 chnl=15
char id=74 x=257 y=144 width=35 height=71 xoffset=-4 yoffset=-4 xadvance=27 page=0 chnl=15
char id=75 x=0 y=144 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=76 x=139 y=216 width=33 height=71 xoffset=-4 yoffset=-4 xadvance=25 page=0 chnl=15
char id=77 x=85 y=72 width=41 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=78 x=371 y=0 width=43 height=71 xoffset=-4 yoffset=-4 xadvance=35 page=0 chnl=15
char id=79 x=168 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=80 x=75 y=144 width=36 height=71 xoffset=-4 yoffset=-4 xadvance=28 page=0 chnl=15
char id=81 x=280 y=0 width=45 height=71 xoffset=-4 yoffset=-4 xadvance=37 page=0 chnl=15
char id=82 x=369 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=83 x=70 y=216 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=84 x=43 y=72 width=41 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=85 x=0 y=72 width=42 height=71 xoffset=-4 yoffset=-4 xadvance=34 page=0 chnl=15
char id=86 x=326 y=0 width=44 height=71 xoffset=-4 yoffset=-4 xadvance=36 page=0 chnl=15
char id=87 x=232 y=0 width=47 height=71 xoffset=-4 yoffset=-4 xadvance=39 page=0 chnl=15
char id=88 x=127 y=72 width=40 height=71 xoffset=-4 yoffset=-4 xadvance=33 page=0 chnl=15
char id=89 x=290 y=72 width=39 height=71 xoffset=-4 yoffset=-4 xadvance=31 page=0 chnl=15
char id=90 x=330 y=72 width=38 height=71 xoffset=-4 yoffset=-4 xadvance=30 page=0 chnl=15
char id=91 x=499 y=288 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=92 x=109 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=93 x=499 y=216 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=97 x=302 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=98 x=415 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=99 x=136 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=100 x=124 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=101 x=162 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=102 x=443 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=103 x=0 y=360 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=104 x=240 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=105 x=382 y=360 width=16 height=71 xoffset=-4 yoffset=-4 xadvance=8 page=0 chnl=15
char id=106 x=359 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=107 x=483 y=72 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=108 x=55 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=109 x=435 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=110 x=273 y=216 width=32 height=71 xoffset=-4 yoffset=-4 xadvance=24 page=0 chnl=15
char id=111 x=31 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=112 x=331 y=288 width=27 height=71 xoffset=-4 yoffset=-4 xadvance=19 page=0 chnl=15
char id=113 x=363 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=114 x=273 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=115 x=28 y=360 width=26 height=71 xoffset=-4 yoffset=-4 xadvance=18 page=0 chnl=15
char id=116 x=62 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=117 x=93 y=288 width=30 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=118 x=467 y=216 width=31 height=71 xoffset=-4 yoffset=-4 xadvance=23 page=0 chnl=15
char id=119 x=293 y=144 width=34 height=71 xoffset=-4 yoffset=-4 xadvance=26 page=0 chnl=15
char id=120 x=185 y=288 width=29 height=71 xoffset=-4 yoffset=-4 xadvance=22 page=0 chnl=15
char id=121 x=215 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=122 x=244 y=288 width=28 height=71 xoffset=-4 yoffset=-4 xadvance=20 page=0 chnl=15
char id=123 x=428 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=124 x=440 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=125 x=452 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=126 x=0 y=0 width=66 height=71 xoffset=-4 yoffset=-4 xadvance=58 page=0 chnl=15
char id=162 x=464 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=163 x=407 y=72 width=37 height=71 xoffset=-4 yoffset=-4 xadvance=29 page=0 chnl=15
char id=167 x=476 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=171 x=214 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=187 x=240 y=360 width=25 height=71 xoffset=-4 yoffset=-4 xadvance=17 page=0 chnl=15
char id=191 x=500 y=360 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=192 x=0 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=193 x=12 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=194 x=24 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=196 x=36 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=199 x=48 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=200 x=60 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=201 x=72 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=202 x=84 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=203 x=96 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=206 x=108 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=207 x=120 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=209 x=132 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=211 x=144 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=212 x=156 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=214 x=168 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=217 x=180 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=218 x=192 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=219 x=204 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=220 x=216 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=223 x=228 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=224 x=240 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=225 x=252 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=226 x=264 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=228 x=276 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=231 x=288 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=232 x=300 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=233 x=312 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=234 x=324 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=235 x=336 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=238 x=348 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=239 x=360 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=243 x=372 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=244 x=384 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=246 x=396 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=249 x=408 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=250 x=420 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=251 x=432 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15
char id=252 x=444 y=432 width=11 height=71 xoffset=-5 yoffset=-4 xadvance=1 page=0 chnl=15

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

View File

@ -1,291 +0,0 @@
/*******************************************************************************************
*
* CAT VS ROOMBA [GLOBAL GAME JAM 2019]
*
* Ah! Home, sweet home! Time for some automatic cleaning...
* if the worst enemy of Roomba allows it... be careful with Cat!
*
* This game has been created using raylib 2.0 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2019 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include "screens/screens.h" // NOTE: Defines global variable: currentScreen
#if defined(PLATFORM_WEB)
#include <emscripten/emscripten.h>
#endif
GameScreen currentScreen = 0;
Font font = { 0 };
Font font2 = { 0 };
Music music = { 0 };
Sound fxCoin = { 0 };
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
const int screenWidth = 1280;
#if defined(TILE_VIEWER_MODE)
const int screenHeight = 1080;
#else
const int screenHeight = 720;
#endif
// Required variables to manage screen transitions (fade-in, fade-out)
static float transAlpha = 0.0f;
static bool onTransition = false;
static bool transFadeOut = false;
static int transFromScreen = -1;
static int transToScreen = -1;
// NOTE: Some global variables that require to be visible for all screens,
// are defined in screens.h (i.e. currentScreen)
//----------------------------------------------------------------------------------
// Local Functions Declaration
//----------------------------------------------------------------------------------
static void ChangeToScreen(int screen); // No transition effect
static void TransitionToScreen(int screen);
static void UpdateTransition(void);
static void DrawTransition(void);
static void UpdateDrawFrame(void); // Update and Draw one frame
//----------------------------------------------------------------------------------
// Main entry point
//----------------------------------------------------------------------------------
int main(void)
{
// Initialization (Note windowTitle is unused on Android)
//---------------------------------------------------------
InitWindow(screenWidth, screenHeight, "CAT VS ROOMBA [GGJ19]");
// Global data loading (assets that must be available in all screens, i.e. fonts)
InitAudioDevice();
font = LoadFont("resources/star.fnt");
font2 = LoadFont("resources/star2.fnt");
music = LoadMusicStream("resources/cat_mouse.mod");
fxCoin = LoadSound("resources/coin.wav");
SetMusicVolume(music, 1.0f);
PlayMusicStream(music);
// Setup and Init first screen
currentScreen = LOGO;
InitLogoScreen();
#if defined(PLATFORM_WEB)
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
#else
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
UpdateDrawFrame();
}
#endif
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload current screen data before closing
switch (currentScreen)
{
case LOGO: UnloadLogoScreen(); break;
case TITLE: UnloadTitleScreen(); break;
case GAMEPLAY: UnloadGameplayScreen(); break;
case ENDING: UnloadEndingScreen(); break;
default: break;
}
// Unload all global loaded data (i.e. fonts) here!
UnloadFont(font);
UnloadFont(font2);
UnloadMusicStream(music);
UnloadSound(fxCoin);
CloseAudioDevice(); // Close audio context
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//----------------------------------------------------------------------------------
// Module specific Functions Definition
//----------------------------------------------------------------------------------
// Change to next screen, no transition
static void ChangeToScreen(int screen)
{
// Unload current screen
switch (currentScreen)
{
case LOGO: UnloadLogoScreen(); break;
case TITLE: UnloadTitleScreen(); break;
case GAMEPLAY: UnloadGameplayScreen(); break;
case ENDING: UnloadEndingScreen(); break;
default: break;
}
// Init next screen
switch (screen)
{
case LOGO: InitLogoScreen(); break;
case TITLE: InitTitleScreen(); break;
case GAMEPLAY: InitGameplayScreen(); break;
case ENDING: InitEndingScreen(); break;
default: break;
}
currentScreen = screen;
}
// Define transition to next screen
static void TransitionToScreen(int screen)
{
onTransition = true;
transFadeOut = false;
transFromScreen = currentScreen;
transToScreen = screen;
transAlpha = 0.0f;
}
// Update transition effect
static void UpdateTransition(void)
{
if (!transFadeOut)
{
transAlpha += 0.02f;
// NOTE: Due to float internal representation, condition jumps on 1.0f instead of 1.05f
// For that reason we compare against 1.01f, to avoid last frame loading stop
if (transAlpha > 1.01f)
{
transAlpha = 1.0f;
// Unload current screen
switch (transFromScreen)
{
case LOGO: UnloadLogoScreen(); break;
case TITLE: UnloadTitleScreen(); break;
case GAMEPLAY: UnloadGameplayScreen(); break;
case ENDING: UnloadEndingScreen(); break;
default: break;
}
// Load next screen
switch (transToScreen)
{
case LOGO: InitLogoScreen(); break;
case TITLE: InitTitleScreen(); break;
case GAMEPLAY: InitGameplayScreen(); break;
case ENDING: InitEndingScreen(); break;
default: break;
}
currentScreen = transToScreen;
// Activate fade out effect to next loaded screen
transFadeOut = true;
}
}
else // Transition fade out logic
{
transAlpha -= 0.02f;
if (transAlpha < -0.01f)
{
transAlpha = 0.0f;
transFadeOut = false;
onTransition = false;
transFromScreen = -1;
transToScreen = -1;
}
}
}
// Draw transition effect (full-screen rectangle)
static void DrawTransition(void)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(BLACK, transAlpha));
}
// Update and draw game frame
static void UpdateDrawFrame(void)
{
// Update
//----------------------------------------------------------------------------------
UpdateMusicStream(music); // NOTE: Music keeps playing between screens
if (!onTransition)
{
switch(currentScreen)
{
case LOGO:
{
UpdateLogoScreen();
if (FinishLogoScreen()) TransitionToScreen(TITLE);
} break;
case TITLE:
{
UpdateTitleScreen();
if (FinishTitleScreen() == 1) TransitionToScreen(OPTIONS);
else if (FinishTitleScreen() == 2) TransitionToScreen(GAMEPLAY);
} break;
case GAMEPLAY:
{
UpdateGameplayScreen();
if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING);
//else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE);
} break;
case ENDING:
{
UpdateEndingScreen();
if (FinishEndingScreen() == 1) TransitionToScreen(TITLE);
} break;
default: break;
}
}
else UpdateTransition(); // Update transition (fade-in, fade-out)
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
switch(currentScreen)
{
case LOGO: DrawLogoScreen(); break;
case TITLE: DrawTitleScreen(); break;
case GAMEPLAY: DrawGameplayScreen(); break;
case ENDING: DrawEndingScreen(); break;
default: break;
}
// Draw full screen rectangle in front of everything
if (onTransition) DrawTransition();
//DrawFPS(10, 10);
EndDrawing();
//----------------------------------------------------------------------------------
}

View File

@ -1,96 +0,0 @@
/**********************************************************************************************
*
* raylib - Advance Game template
*
* Ending Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
#include "screens.h"
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
// Ending screen global variables
static int framesCounter;
static int finishScreen;
static int scrollPositionX;
//----------------------------------------------------------------------------------
// Ending Screen Functions Definition
//----------------------------------------------------------------------------------
// Ending Screen Initialization logic
void InitEndingScreen(void)
{
// TODO: Initialize ENDING screen variables here!
framesCounter = 0;
finishScreen = 0;
PlayMusicStream(music);
}
// Ending Screen Update logic
void UpdateEndingScreen(void)
{
framesCounter++;
scrollPositionX -= 5;
if (scrollPositionX < -GetScreenWidth()) scrollPositionX = 0;
// Press enter or tap to return to TITLE screen
if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP))
{
finishScreen = 1;
PlaySound(fxCoin);
}
}
// Ending Screen Draw logic
void DrawEndingScreen(void)
{
for (int i = 0; i < 64*2*2; i++)
{
DrawRectangle(64*i + scrollPositionX, 0, 64, GetScreenHeight(), (i%2 == 0)? GetColor(0xf3726dff) : GetColor(0xffcf6bff));
}
if (result == 0) DrawTextEx(font2, "YOU LOOSE...", (Vector2){ 350, 200 }, font2.baseSize*2, 2, WHITE);
else if (result == 1) DrawTextEx(font, "YOU WIN!!!", (Vector2){ 380, 200 }, font.baseSize*2, 2, WHITE);
// Draw score
DrawTextEx(font, FormatText("FINAL SCORE: %i", score), (Vector2){ 400, 360 }, font2.baseSize, 2, WHITE);
if ((framesCounter/30)%2) DrawTextEx(font2, "PRESS ENTER to TITLE", (Vector2){ 340, 550 }, font2.baseSize, 2, WHITE);
}
// Ending Screen Unload logic
void UnloadEndingScreen(void)
{
// TODO: Unload ENDING screen variables here!
}
// Ending Screen should finish?
int FinishEndingScreen(void)
{
return finishScreen;
}

View File

@ -1,652 +0,0 @@
/**********************************************************************************************
*
* raylib - Advance Game template
*
* Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
#include "screens.h"
#include "raymath.h"
#include <stdio.h>
#define TILE_REQUIRED_CLEAN_TIME 2 // Frames it takes to clean a dirt level
#define TILE_SCORE_BY_CLEANED_LEVEL 100 // Score by cleanied dirt level
#define TILE_REQUIRED_CLEAN_AREA 28*28 // Required are for actually cleaning tile
#define TILE_SIZE 36 // Tile size, it should match texture
#define MAX_TILES_X 32
#define MAX_TILES_Y 17
#define CAT_TARGET_RADIUS 3 // Target proximity radius
#define CAT_DIRT_CELL_RADIUS 2 // Cells around cat for dirt spreading
#define TIME_LIMIT_SECONDS 180 // Time to complete the level in seconds
#define MAX_SCORE_POPUPS 60 // Maximum simultaneous score pop-ups!
//----------------------------------------------------------------------------------
// Module types
//----------------------------------------------------------------------------------
// One dirt tile type
typedef struct {
Vector2 position; // Relative to top-left corner
int level; // Dirtiness: 0-Clean, 1-2-3-Dirt levels
int state; // Current dirtiness state
int counter; // Frames counter for cleaning
//int time; // Time it takes to make it clean --> Depends on level
//int score; // It depends on the dirt level
bool cleaned; // If it was cleaned (not clean by default)
} Dirtile;
// Score poping-up type
typedef struct {
Vector2 position;
int value;
float alpha;
bool enabled;
} ScorePopup;
// Furniture tile set
typedef struct {
int id; // Furniture tile id
int posX; // Position X on tileset
int posY; // Position Y on tileset
int width; // Furniture piece width
int height; // Furniture piece height
} FurSet;
// Furniture type
typedef struct {
int furId; // Tileset id
int cellX; // Cell position X
int cellY; // Cell position Y
int state; // 0-Block, 1-Alpha, 2-Breakable
int counter; // Counter in case of break
} Furniture;
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
// Gameplay screen global variables
static int framesCounter;
static int timeLevelSeconds;
static bool levelFinished;
static int finishScreen;
const Vector2 roomOffset = { 70, 70 };
static Texture2D roomba;
static Texture2D cat;
static Texture2D dirtiles;
static Texture2D furniture;
#if defined(TILE_VIEWER_MODE)
static Texture2D tracemap;
static Texture2D fursetid;
#endif
static Music catch;
static Sound fxCat[2];
static Sound fxRoomba[3];
static Vector2 roombaPosition = { 100, 100 };
static Vector2 roombaSpeed = { 4, 4 };
static int roombaTilePosX = 0, roombaTilePosY = 0;
static Vector2 catPosition = { 0, 0 };
static Vector2 catTargetPosition = { 0, 0 };
static Vector2 catSpeed = { 3, 3 };
static int catTilePosX = 0, catTilePosY = 0;
static bool catShouldMove = false;
static Vector2 mousePosition = { 0, 0 };
static int mouseTileX = -1, mouseTileY = -1;
static Dirtile tiles[MAX_TILES_X*MAX_TILES_Y] = { 0 };
static ScorePopup popup[MAX_SCORE_POPUPS] = { 0 };
static FurSet furset[32] = { -1 };
static Furniture furmap[40] = { -1 };
static int furnitureCount = 0;
// Furniture collisions map
// 0-block, 1-normal, 2-alpha, 3-breakable
static int furcolmap[MAX_TILES_X*MAX_TILES_Y] = {
1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,3,3,1,1,1,0,0,1,1,1,1,1,1,1,1,
1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,3,3,1,1,1,0,0,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,1,1,1,2,2,2,1,1,1,0,0,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
0,0,1,1,1,1,2,2,2,1,1,1,0,0,1,1,1,2,2,2,1,1,1,1,3,3,1,1,1,1,0,0,
3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,1,1,1,3,3,1,1,1,1,0,0,
3,3,1,1,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,1,1,1,1,0,0,0,0,0,0,0,0,
1,1,1,1,2,2,2,2,2,2,2,2,1,1,1,1,1,2,2,2,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,3,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,0,0,0,0,0,0,0,0,3,3,1,1,1,1,1,1,1,0,0,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,
0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,1,1,
0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,1,1,0,0,1,2,2,2,2,2,2,2,2,0,0,
0,0,0,0,0,0,0,0,0,0,2,2,2,3,3,3,3,1,1,0,0,1,2,2,2,2,2,2,2,2,0,0 };
static bool showObjective = false;
//----------------------------------------------------------------------------------
// Module Functions Definition
//----------------------------------------------------------------------------------
static float GetTileCleanPercent(void);
//----------------------------------------------------------------------------------
// Gameplay Screen Functions Definition
//----------------------------------------------------------------------------------
// Gameplay Screen Initialization logic
void InitGameplayScreen(void)
{
// Initialize GAMEPLAY screen variables here!
framesCounter = 0;
finishScreen = 0;
timeLevelSeconds = TIME_LIMIT_SECONDS;
levelFinished = false;
roomba = LoadTexture("resources/roomba.png");
cat = LoadTexture("resources/cat.png");
dirtiles = LoadTexture("resources/dirtiles.png");
furniture = LoadTexture("resources/furniture.png");
#if defined(TILE_VIEWER_MODE)
tracemap = LoadTexture("resources/tracemap.png");
fursetid = LoadTexture("resources/fursetid.png");
#endif
int furCount = 0;
FILE *fursetFile = fopen("resources/furset.txt", "rt");
if (fursetFile != NULL)
{
char buffer[512] = { 0 };
while (!feof(fursetFile))
{
fgets(buffer, 512, fursetFile);
switch (buffer[0])
{
case 'f':
{
sscanf(buffer, "f %i %i %i %i %i",
&furset[furCount].id,
&furset[furCount].posX,
&furset[furCount].posY,
&furset[furCount].width,
&furset[furCount].height);
furCount++;
} break;
case '.': // This is a comment
default: break;
}
}
fclose(fursetFile);
}
// Position and size come in cell form, not pixels
for (int i = 0; i < furCount; i++)
{
furset[i].posX *= TILE_SIZE;
furset[i].posY *= TILE_SIZE;
furset[i].width *= TILE_SIZE;
furset[i].height *= TILE_SIZE;
}
printf("Furniture SET elements read: %i\n", furCount);
// Init furniture elements
FILE *furnitureFile = fopen("resources/furmap.txt", "rt");
if (furnitureFile != NULL)
{
char buffer[512] = { 0 };
while (!feof(furnitureFile))
{
fgets(buffer, 512, furnitureFile);
switch (buffer[0])
{
case 'f':
{
sscanf(buffer, "f %i %i %i %i %i",
&furmap[furnitureCount].furId,
&furmap[furnitureCount].cellX,
&furmap[furnitureCount].cellY,
&furmap[furnitureCount].state,
&furmap[furnitureCount].counter);
furnitureCount++;
} break;
case '.': // This is a comment
default: break;
}
}
fclose(furnitureFile);
}
printf("Furniture MAP elements read: %i\n", furnitureCount);
// Init dirt tiles
for (int y = 0; y < MAX_TILES_Y; y++)
{
for (int x = 0; x < MAX_TILES_X; x++)
{
tiles[y*MAX_TILES_X + x].position = (Vector2){ roomOffset.x + TILE_SIZE*x, roomOffset.y + TILE_SIZE*y };
if ((furcolmap[y*MAX_TILES_X + x] != 0) &&
(furcolmap[y*MAX_TILES_X + x] != 3))
{
// TODO: Level of dirtiness depends on difficulty level
// Adjust probability of every tile dirt level
int dirt = GetRandomValue(0, 100);
if (dirt < 50) tiles[y*MAX_TILES_X + x].level = 0; // 50% probability
else if (dirt < 70) tiles[y*MAX_TILES_X + x].level = 1; // 20% probability
else if (dirt < 90) tiles[y*MAX_TILES_X + x].level = 2; // 10% probability
else if (dirt < 100) tiles[y*MAX_TILES_X + x].level = 3; // 10% probability
}
else tiles[y*MAX_TILES_X + x].level = 0;
tiles[y*MAX_TILES_X + x].state = tiles[y*MAX_TILES_X + x].level;
tiles[y*MAX_TILES_X + x].counter = (tiles[y*MAX_TILES_X + x].level == 0)? 0 : TILE_REQUIRED_CLEAN_TIME;
tiles[y*MAX_TILES_X + x].cleaned = (tiles[y*MAX_TILES_X + x].level == 0)? true : false;
}
}
// Init score popups
for (int i = 0; i < MAX_SCORE_POPUPS; i++)
{
popup[i].position = (Vector2){ 0, 0 };
popup[i].value = TILE_SCORE_BY_CLEANED_LEVEL;
popup[i].enabled = false;
popup[i].alpha = 1.0f;
}
// Init cat position
catPosition = (Vector2){ 30*TILE_SIZE + roomOffset.x, TILE_SIZE + roomOffset.y };
catTargetPosition = catPosition;
showObjective = true;
// Load music and sounds
fxCat[0] = LoadSound("resources/fxcat01.wav");
fxCat[1] = LoadSound("resources/fxcat02.wav");
fxRoomba[0] = LoadSound("resources/fxrobot01.wav");
fxRoomba[1] = LoadSound("resources/fxrobot02.wav");
fxRoomba[2] = LoadSound("resources/fxrobot03.wav");
catch = LoadMusicStream("resources/catch22.mod");
StopMusicStream(music);
SetMusicVolume(catch, 0.6f);
PlayMusicStream(catch);
result = 0; // Global variable: screens.h
}
// Gameplay Screen Update logic
void UpdateGameplayScreen(void)
{
UpdateMusicStream(catch);
if (showObjective)
{
if (IsKeyPressed(KEY_ENTER))
{
showObjective = false;
PlaySound(fxCoin);
}
return;
}
framesCounter++;
if (framesCounter == 60)
{
timeLevelSeconds--;
if (timeLevelSeconds == 0)
{
levelFinished = true;
finishScreen = 1;
PlaySound(fxCoin);
if (GetTileCleanPercent() >= 80) result = 1;
}
framesCounter = 0;
}
mousePosition = GetMousePosition();
mouseTileX = (int)floorf((mousePosition.x - roomOffset.x)/TILE_SIZE);
mouseTileY = (int)floorf((mousePosition.y - roomOffset.y)/TILE_SIZE);
// Roomba movement logic
Vector2 prevPosition = roombaPosition;
if (IsKeyDown(KEY_D)) roombaPosition.x += roombaSpeed.x;
else if (IsKeyDown(KEY_A)) roombaPosition.x -= roombaSpeed.x;
if (IsKeyDown(KEY_W)) roombaPosition.y -= roombaSpeed.y;
else if (IsKeyDown(KEY_S)) roombaPosition.y += roombaSpeed.y;
// Verify current player position is valid or reset
roombaTilePosX = (int)(floorf(roombaPosition.x - roomOffset.x)/TILE_SIZE);
roombaTilePosY = (int)(floorf(roombaPosition.y - roomOffset.y)/TILE_SIZE);
if ((roombaPosition.x - roomba.width/2 < roomOffset.x) ||
((roombaPosition.x + roomba.width/2) >= (roomOffset.x + MAX_TILES_X*TILE_SIZE)) ||
(roombaPosition.y - roomba.height/2 < roomOffset.y) ||
((roombaPosition.y + roomba.height/2) >= (roomOffset.y + MAX_TILES_Y*TILE_SIZE)) ||
(furcolmap[roombaTilePosY*MAX_TILES_X + roombaTilePosX] == 0) ||
(furcolmap[roombaTilePosY*MAX_TILES_X + roombaTilePosX] == 3)) roombaPosition = prevPosition;
// Dyson movement logic
// if (IsKeyDown(KEY_RIGHT)) dysonPosition.x += dysonSpeed.x;
// else if (IsKeyDown(KEY_LEFT)) dysonPosition.x -= dysonSpeed.x;
// if (IsKeyDown(KEY_UP)) dysonPosition.y -= dysonSpeed.y;
// else if (IsKeyDown(KEY_DOWN)) dysonPosition.y += dysonSpeed.y;
// Check collision area between Roomba and dirt tiles to verify it's beeing cleaned
// TODO: OPTIMIZATION: Check only Roomba surrounding tiles
for (int y = 0; y < MAX_TILES_Y; y++)
{
for (int x = 0; x < MAX_TILES_X; x++)
{
// Check if tile requires cleaning
if (tiles[y*MAX_TILES_X + x].state > 0)
{
// TODO: Get better collision area measure, considering round roomba
Rectangle cleanRec = GetCollisionRec((Rectangle){ tiles[y*MAX_TILES_X + x].position.x, tiles[y*MAX_TILES_X + x].position.y, 36, 36 },
(Rectangle){ roombaPosition.x - roomba.width/2, roombaPosition.y - roomba.height/2, roomba.width, roomba.height });
// Check Roomba is covering at least half of the tile
if ((cleanRec.width*cleanRec.height) > TILE_REQUIRED_CLEAN_AREA)
{
// Start cleaning tile
tiles[y*MAX_TILES_X + x].counter--;
if (tiles[y*MAX_TILES_X + x].counter < 0)
{
tiles[y*MAX_TILES_X + x].state--;
if (tiles[y*MAX_TILES_X + x].state == 0)
{
tiles[y*MAX_TILES_X + x].counter = 0;
score += tiles[y*MAX_TILES_X + x].level*TILE_SCORE_BY_CLEANED_LEVEL;
// Show scoring popup, enable first ready!
for (int i = 0; i < MAX_SCORE_POPUPS; i++)
{
if (!popup[i].enabled)
{
popup[i].position = tiles[y*MAX_TILES_X + x].position;
popup[i].value = TILE_SCORE_BY_CLEANED_LEVEL*tiles[y*MAX_TILES_X + x].level;
popup[i].enabled = true;
popup[i].alpha = 1.0f;
break;
}
}
}
else tiles[y*MAX_TILES_X + x].counter = TILE_REQUIRED_CLEAN_TIME;
}
}
}
}
}
// Update enabled popups!
for (int i = 0; i < MAX_SCORE_POPUPS; i++)
{
if (popup[i].enabled)
{
popup[i].position.y -= 2;
popup[i].alpha -= 0.015f;
if (popup[i].alpha < 0.0f) popup[i].enabled = false;
}
}
// Cat movement logic
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
{
// Check for a valid cell to move on
if ((mousePosition.x > roomOffset.x) && (mousePosition.x < (roomOffset.x + MAX_TILES_X*TILE_SIZE)) &&
(mousePosition.y > roomOffset.y) && (mousePosition.y < (roomOffset.y + MAX_TILES_Y*TILE_SIZE)) &&
furcolmap[mouseTileY*MAX_TILES_X + mouseTileX] != 0)
{
catTargetPosition = GetMousePosition();
catShouldMove = true;
}
}
if (IsMouseButtonPressed(MOUSE_RIGHT_BUTTON)) PlaySound(fxCat[GetRandomValue(0,1)]);
if (IsKeyPressed(KEY_SPACE)) PlaySound(fxRoomba[GetRandomValue(0,2)]);
// Check if cat should move
if (catShouldMove)
{
if (CheckCollisionPointCircle(catPosition, catTargetPosition, CAT_TARGET_RADIUS))
{
catShouldMove = false;
// Spread dirt all around selected cell!
// NOTE: We consider cat drawing offset
catTilePosX = (int)floorf((catPosition.x - cat.width/2 - roomOffset.x)/TILE_SIZE) + 1;
catTilePosY = (int)floorf((catPosition.y - cat.height/2 - 10 - roomOffset.y)/TILE_SIZE) + 1;
// Check if tile includes a dirt element
if (furcolmap[mouseTileY*MAX_TILES_X + mouseTileX] == 3)
{
for (int y = (catTilePosY - CAT_DIRT_CELL_RADIUS); y < (catTilePosY + CAT_DIRT_CELL_RADIUS + 1); y++)
{
for (int x = (catTilePosX - CAT_DIRT_CELL_RADIUS); x < (catTilePosX + CAT_DIRT_CELL_RADIUS + 1); x++)
{
if (((y >= 0) && (y < MAX_TILES_Y) && (x >= 0) && (x < MAX_TILES_X)) &&
(tiles[y*MAX_TILES_X + x].state == 0) &&
(furcolmap[y*MAX_TILES_X + x] != 0) &&
(furcolmap[y*MAX_TILES_X + x] != 3))
{
int dirt = GetRandomValue(0, 100);
if (dirt < 50) tiles[y*MAX_TILES_X + x].level = 0; // 50% probability
else if (dirt < 70) tiles[y*MAX_TILES_X + x].level = 1; // 20% probability
else if (dirt < 90) tiles[y*MAX_TILES_X + x].level = 2; // 10% probability
else if (dirt < 100) tiles[y*MAX_TILES_X + x].level = 3; // 10% probability
tiles[y*MAX_TILES_X + x].state = tiles[y*MAX_TILES_X + x].level;
tiles[y*MAX_TILES_X + x].counter = (tiles[y*MAX_TILES_X + x].level == 0)? 0 : TILE_REQUIRED_CLEAN_TIME;
tiles[y*MAX_TILES_X + x].cleaned = (tiles[y*MAX_TILES_X + x].level == 0)? true : false;
}
}
}
}
}
else
{
Vector2 dir = Vector2Subtract(catTargetPosition, catPosition);
Vector2 dirnorm = Vector2Normalize(dir);
catPosition.x += catSpeed.x*dirnorm.x;
catPosition.y += catSpeed.y*dirnorm.y;
}
}
if (levelFinished)
{
// TODO: Check level finished
}
}
// Gameplay Screen Draw logic
void DrawGameplayScreen(void)
{
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), GetColor(0x57374cff));
// Draw tiles
for (int y = 0; y < MAX_TILES_Y; y++)
{
for (int x = 0; x < MAX_TILES_X; x++)
{
// Draw dirty tiles
DrawTextureRec(dirtiles, (Rectangle){ tiles[y*MAX_TILES_X + x].state*TILE_SIZE, 0, TILE_SIZE, TILE_SIZE },
(Vector2){ roomOffset.x + TILE_SIZE*x, roomOffset.y + TILE_SIZE*y }, WHITE);
// TODO: Draw possible walls
}
}
// Draw starting point for roomba and cat
DrawTextureRec(furniture, (Rectangle){ furset[30].posX, furset[30].posY, furset[30].width, furset[30].height }, roomOffset, WHITE);
DrawTextureRec(furniture, (Rectangle){ furset[29].posX, furset[29].posY, furset[29].width, furset[29].height }, (Vector2){ roomOffset.x + 29*36, roomOffset.y }, WHITE);
DrawTexture(roomba, roombaPosition.x - roomba.width/2, roombaPosition.y - roomba.height/2, WHITE);
DrawTexture(cat, catPosition.x - cat.width/2, catPosition.y - cat.height/2 - 10, WHITE);
float furAlpha = 1.0f;
// Draw home objects
for (int i = 0; i < furnitureCount; i++)
{
if (CheckCollisionCircleRec((Vector2){ roombaPosition.x - roomba.width/2, roombaPosition.y - roomba.height/2 }, roomba.width,
(Rectangle){ roomOffset.x + furmap[i].cellX*TILE_SIZE, roomOffset.y + furmap[i].cellY*TILE_SIZE,
furset[furmap[i].furId].width, furset[furmap[i].furId].height}) && (furmap[i].state == 1))
{
DrawTextureRec(furniture, (Rectangle){ furset[furmap[i].furId].posX, furset[furmap[i].furId].posY, furset[furmap[i].furId].width, furset[furmap[i].furId].height },
(Vector2){ roomOffset.x + furmap[i].cellX*TILE_SIZE, roomOffset.y + furmap[i].cellY*TILE_SIZE }, Fade(WHITE, 0.5f));
}
else
{
DrawTextureRec(furniture, (Rectangle){ furset[furmap[i].furId].posX, furset[furmap[i].furId].posY, furset[furmap[i].furId].width, furset[furmap[i].furId].height },
(Vector2){ roomOffset.x + furmap[i].cellX*TILE_SIZE, roomOffset.y + furmap[i].cellY*TILE_SIZE }, Fade(WHITE, furAlpha));
}
}
#if defined(TILE_VIEWER_MODE)
DrawTexture(tracemap, roomOffset.x, roomOffset.y, Fade(WHITE, 0.5f));
DrawTexture(fursetid, 0, 720, WHITE);
#endif
// TODO: If an object has been used by cat, draw it in gray
// Maybe add a tempo bar for reusing?
// Draw UI
DrawTextEx(font2, "SCORE:", (Vector2){ 80, 10 }, font2.baseSize, 2, WHITE);
DrawTextEx(font, FormatText("%i", score), (Vector2){ 260, 10 }, font.baseSize, 2, WHITE);
DrawTextEx(font2, "CLEAN:", (Vector2){ 500, 10 }, font2.baseSize, 2, WHITE);
DrawTextEx(font, FormatText("%.2f%%", GetTileCleanPercent()), (Vector2){ 690, 10 }, font.baseSize, 2, WHITE);
DrawTextEx(font2, "TIME:", (Vector2){ 950, 10 }, font2.baseSize, 2, WHITE);
DrawTextEx(font, FormatText("%i:%02is", timeLevelSeconds/60, timeLevelSeconds%60), (Vector2){ 1100, 10 }, font.baseSize, 2, WHITE);
// Debug information
//DrawText(FormatText("CatTilePos: [ %i, %i ]", catTilePosX, catTilePosY), roomOffset.x, 690, 20, RAYWHITE);
//DrawText(FormatText("MousePos: [ %i, %i ]", mouseTileX, mouseTileY), 400, 690, 20, RED);
//DrawText(FormatText("RoombaPos: [ %i, %i ]", roombaTilePosX, roombaTilePosY), 600, 690, 20, GREEN);
if ((mouseTileY >= 0) && (mouseTileY < MAX_TILES_Y) && (mouseTileX >= 0) && (mouseTileX < MAX_TILES_X))
{
DrawRectangleLinesEx((Rectangle){ tiles[mouseTileY*MAX_TILES_X + mouseTileX].position.x,
tiles[mouseTileY*MAX_TILES_X + mouseTileX].position.y, TILE_SIZE, TILE_SIZE }, 2, RED);
}
// Draw enabled popups!
for (int i = 0; i < MAX_SCORE_POPUPS; i++)
{
if (popup[i].enabled) DrawText(FormatText("+%i", popup[i].value), popup[i].position.x, popup[i].position.y, 20, Fade(RED, popup[i].alpha));
}
// Show objective
if (showObjective)
{
DrawRectangle(0, 150, GetScreenWidth(), GetScreenHeight() - 300, Fade(DARKGRAY, 0.7f));
DrawTextEx(font2, "OBJECTIVE:", (Vector2){ 500, 240 }, font2.baseSize, 2, WHITE);
DrawTextEx(font, "CLEAN 80% OF THE ROOM", (Vector2){ 300, 320 }, font.baseSize, 2, WHITE);
}
}
// Gameplay Screen Unload logic
void UnloadGameplayScreen(void)
{
// Unload GAMEPLAY screen variables here!
UnloadTexture(roomba);
UnloadTexture(cat);
UnloadTexture(dirtiles);
UnloadTexture(furniture);
UnloadSound(fxCat[0]);
UnloadSound(fxCat[1]);
UnloadSound(fxRoomba[0]);
UnloadSound(fxRoomba[1]);
UnloadSound(fxRoomba[2]);
StopMusicStream(catch);
UnloadMusicStream(catch);
}
// Gameplay Screen should finish?
int FinishGameplayScreen(void)
{
return finishScreen;
}
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
// Check how much cleaning we have done
static float GetTileCleanPercent(void)
{
float value = 0;
int tileLevelsToClean = 0;
int tileLevelsCleaned = 0;
for (int y = 0; y < MAX_TILES_Y; y++)
{
for (int x = 0; x < MAX_TILES_X; x++)
{
if (tiles[y*MAX_TILES_X + x].level > 0)
{
tileLevelsToClean += tiles[y*MAX_TILES_X + x].level;
tileLevelsCleaned += tiles[y*MAX_TILES_X + x].state;
}
}
}
value = ((float)(tileLevelsToClean - tileLevelsCleaned)/tileLevelsToClean)*100.0f;
return value;
}

View File

@ -1,211 +0,0 @@
/**********************************************************************************************
*
* raylib - Advance Game template
*
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
#include "screens.h"
#define LOGO_RECS_SIDE 16
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
// Logo screen global variables
static int framesCounter = 0;
static int finishScreen = 0;
static int logoPositionX = 0;
static int logoPositionY = 0;
static int lettersCount = 0;
static int topSideRecWidth = 0;
static int leftSideRecHeight = 0;
static int bottomSideRecWidth = 0;
static int rightSideRecHeight = 0;
static char raylib[8] = { 0 }; // raylib text array, max 8 letters
static int state = 0; // Tracking animation states (State Machine)
static float alpha = 1.0f; // Useful for fading
//----------------------------------------------------------------------------------
// Logo Screen Functions Definition
//----------------------------------------------------------------------------------
// Logo Screen Initialization logic
void InitLogoScreen(void)
{
// Initialize LOGO screen variables here!
finishScreen = 0;
framesCounter = 0;
lettersCount = 0;
logoPositionX = GetScreenWidth()/2 - 128;
logoPositionY = GetScreenHeight()/2 - 128;
topSideRecWidth = LOGO_RECS_SIDE;
leftSideRecHeight = LOGO_RECS_SIDE;
bottomSideRecWidth = LOGO_RECS_SIDE;
rightSideRecHeight = LOGO_RECS_SIDE;
for (int i = 0; i < 8; i++) raylib[i] = '\0';
state = 0;
alpha = 1.0f;
}
// Logo Screen Update logic
void UpdateLogoScreen(void)
{
// Update LOGO screen variables here!
if (state == 0) // State 0: Small box blinking
{
framesCounter++;
if (framesCounter == 80)
{
state = 1;
framesCounter = 0; // Reset counter... will be used later...
}
}
else if (state == 1) // State 1: Top and left bars growing
{
topSideRecWidth += 8;
leftSideRecHeight += 8;
if (topSideRecWidth == 256) state = 2;
}
else if (state == 2) // State 2: Bottom and right bars growing
{
bottomSideRecWidth += 8;
rightSideRecHeight += 8;
if (bottomSideRecWidth == 256) state = 3;
}
else if (state == 3) // State 3: Letters appearing (one by one)
{
framesCounter++;
if (framesCounter/10) // Every 12 frames, one more letter!
{
lettersCount++;
framesCounter = 0;
}
switch (lettersCount)
{
case 1: raylib[0] = 'r'; break;
case 2: raylib[1] = 'a'; break;
case 3: raylib[2] = 'y'; break;
case 4: raylib[3] = 'l'; break;
case 5: raylib[4] = 'i'; break;
case 6: raylib[5] = 'b'; break;
default: break;
}
// When all letters have appeared...
if (lettersCount >= 10)
{
state = 4;
framesCounter = 0;
}
}
else if (state == 4)
{
framesCounter++;
if (framesCounter > 100)
{
alpha -= 0.02f;
if (alpha <= 0.0f)
{
alpha = 0.0f;
finishScreen = 1;
}
}
}
}
// Logo Screen Draw logic
void DrawLogoScreen(void)
{
if (state == 0)
{
if ((framesCounter/10)%2) DrawRectangle(logoPositionX, logoPositionY, 16, 16, BLACK);
}
else if (state == 1)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
}
else if (state == 2)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, BLACK);
DrawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, BLACK);
DrawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, BLACK);
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, BLACK);
}
else if (state == 3)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
DrawText(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
}
else if (state == 4)
{
DrawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, Fade(BLACK, alpha));
DrawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, Fade(BLACK, alpha));
DrawRectangle(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112, 224, 224, Fade(RAYWHITE, alpha));
DrawText(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48, 50, Fade(BLACK, alpha));
if (framesCounter > 20) DrawText("powered by", logoPositionX, logoPositionY - 27, 20, Fade(DARKGRAY, alpha));
}
}
// Logo Screen Unload logic
void UnloadLogoScreen(void)
{
// Unload LOGO screen variables here!
}
// Logo Screen should finish?
int FinishLogoScreen(void)
{
return finishScreen;
}

View File

@ -1,154 +0,0 @@
/**********************************************************************************************
*
* raylib - Advance Game template
*
* Title Screen Functions Definitions (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "raylib.h"
#include "screens.h"
//----------------------------------------------------------------------------------
// Global Variables Definition (local to this module)
//----------------------------------------------------------------------------------
// Title screen global variables
static int framesCounter;
static int finishScreen;
static int state;
static int scrollPositionX;
static int catPosX;
static int roombaPosX;
static float vsAlpha;
static float vsScale;
static Texture2D cat;
static Texture2D vs;
static Texture2D roomba;
//----------------------------------------------------------------------------------
// Title Screen Functions Definition
//----------------------------------------------------------------------------------
// Title Screen Initialization logic
void InitTitleScreen(void)
{
// TODO: Initialize TITLE screen variables here!
framesCounter = 0;
finishScreen = 0;
cat = LoadTexture("resources/title_cat.png");
vs = LoadTexture("resources/title_vs.png");
roomba = LoadTexture("resources/title_roomba.png");
state = 0;
catPosX = 1760;
roombaPosX = -700;
scrollPositionX = 0;
vsAlpha = 0.0f;
vsScale = 10.0f;
PlayMusicStream(music);
}
// Title Screen Update logic
void UpdateTitleScreen(void)
{
scrollPositionX -= 5;
if (scrollPositionX < -GetScreenWidth()) scrollPositionX = 0;
if (state == 0)
{
catPosX -= 4;
roombaPosX += 3;
if (catPosX < (GetScreenWidth()/2 - cat.width/2)) catPosX = (GetScreenWidth()/2 - cat.width/2);
if (roombaPosX > (GetScreenWidth()/2 - roomba.width/2)) roombaPosX = (GetScreenWidth()/2 - roomba.width/2);
if ((catPosX == (GetScreenWidth()/2 - cat.width/2)) && (roombaPosX == (GetScreenWidth()/2 - roomba.width/2)))
{
state = 1;
framesCounter = 0;
}
}
else if (state == 1)
{
framesCounter++;
vsScale -= 0.1f;
vsAlpha += 0.01f;
if (vsScale < 1.0f) vsScale = 1.0f;
if (vsAlpha > 1.0f) vsAlpha = 1.0f;
if (framesCounter > 160)
{
state = 2;
framesCounter = 0;
}
}
else if (state == 2) framesCounter++;
// Press enter or tap to change to GAMEPLAY screen
if (IsKeyPressed(KEY_ENTER) || IsGestureDetected(GESTURE_TAP))
{
//finishScreen = 1; // OPTIONS
finishScreen = 2; // GAMEPLAY
PlaySound(fxCoin);
}
}
// Title Screen Draw logic
void DrawTitleScreen(void)
{
for (int i = 0; i < 64*2*2; i++)
{
DrawRectangle(64*i + scrollPositionX, 0, 64, GetScreenHeight(), (i%2 == 0)? GetColor(0xf3726dff) : GetColor(0xffcf6bff));
}
DrawTexture(cat, catPosX, 80, WHITE);
DrawTexture(roomba, roombaPosX, 320, WHITE);
if (state > 0)
{
DrawTexturePro(vs, (Rectangle){ 0, 0, vs.width, vs.height }, (Rectangle){ GetScreenWidth()/2, 300, vs.width*vsScale, vs.height*vsScale }, (Vector2){ vs.width/2*vsScale, vs.height/2*vsScale }, 0.0f, Fade(WHITE, vsAlpha));
}
if ((state == 2) && ((framesCounter/30)%2)) DrawTextEx(font2, "PRESS ENTER to START", (Vector2){ 340, 550 }, font2.baseSize, 2, WHITE);
}
// Title Screen Unload logic
void UnloadTitleScreen(void)
{
UnloadTexture(cat);
UnloadTexture(vs);
UnloadTexture(roomba);
}
// Title Screen should finish?
int FinishTitleScreen(void)
{
return finishScreen;
}

View File

@ -1,92 +0,0 @@
/**********************************************************************************************
*
* raylib - Advance Game template
*
* Screens Functions Declarations (Init, Update, Draw, Unload)
*
* Copyright (c) 2014-2019 Ramon Santamaria (@raysan5)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef SCREENS_H
#define SCREENS_H
//#define TILE_VIEWER_MODE
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum GameScreen { LOGO = 0, TITLE, OPTIONS, GAMEPLAY, ENDING } GameScreen;
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
extern GameScreen currentScreen;
extern Font font;
extern Font font2;
extern Music music;
extern Sound fxCoin;
int score;
int result; // 0-Loose, 1-Win
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//----------------------------------------------------------------------------------
// Logo Screen Functions Declaration
//----------------------------------------------------------------------------------
void InitLogoScreen(void);
void UpdateLogoScreen(void);
void DrawLogoScreen(void);
void UnloadLogoScreen(void);
int FinishLogoScreen(void);
//----------------------------------------------------------------------------------
// Title Screen Functions Declaration
//----------------------------------------------------------------------------------
void InitTitleScreen(void);
void UpdateTitleScreen(void);
void DrawTitleScreen(void);
void UnloadTitleScreen(void);
int FinishTitleScreen(void);
//----------------------------------------------------------------------------------
// Gameplay Screen Functions Declaration
//----------------------------------------------------------------------------------
void InitGameplayScreen(void);
void UpdateGameplayScreen(void);
void DrawGameplayScreen(void);
void UnloadGameplayScreen(void);
int FinishGameplayScreen(void);
//----------------------------------------------------------------------------------
// Ending Screen Functions Declaration
//----------------------------------------------------------------------------------
void InitEndingScreen(void);
void UpdateEndingScreen(void);
void DrawEndingScreen(void);
void UnloadEndingScreen(void);
int FinishEndingScreen(void);
#ifdef __cplusplus
}
#endif
#endif // SCREENS_H

View File

@ -1,126 +0,0 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Define current screen
GameScreen currentScreen = TITLE;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
}
} break;
case GAMEPLAY:
{
// Press enter to change to ending screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = ENDING;
}
} break;
case ENDING:
{
// Press enter to change to title screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = TITLE;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
switch (currentScreen)
{
case TITLE:
{
// Draw title screen
DrawRectangle(0, 0, screenWidth, screenHeight, GREEN);
DrawText("TITLE SCREEN", 20, 20, 40, DARKGREEN);
} break;
case GAMEPLAY:
{
// Draw gameplay screen
DrawRectangle(0, 0, screenWidth, screenHeight, RED);
DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON);
} break;
case ENDING:
{
// Draw ending screen
DrawRectangle(0, 0, screenWidth, screenHeight, BLUE);
DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,163 +0,0 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= 8;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to ending screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = ENDING;
}
} break;
case ENDING:
{
// Press enter to change to title screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = TITLE;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
switch (currentScreen)
{
case TITLE:
{
// Draw title screen
DrawText("PRESS ENTER", 450, 420, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw gameplay screen
DrawText("GAMEPLAY SCREEN", 20, 20, 40, MAROON);
} break;
case ENDING:
{
// Draw ending screen
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("ENDING SCREEN", 20, 20, 40, DARKBLUE);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,212 +0,0 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define additional game variables
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= 8;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
if (IsKeyPressed(KEY_SPACE)) gameraMode = !gameraMode;
if (IsKeyPressed(KEY_ENTER)) currentScreen = ENDING;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
}
else
{
DrawTexture(sea, seaScrolling, 0, RED);
DrawTexture(sea, screenWidth + seaScrolling, 0, RED);
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
//DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
DrawRectangle(380, 140, 500, 300, GRAY);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER", 480, 480, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw player
//if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
//else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
if (!gameraMode) DrawRectangleRec(playerBounds, GREEN);
else DrawRectangleRec(playerBounds, ORANGE);
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("GAME OVER", 300, 200, 100, MAROON);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER to REPLAY", 400, 420, 30, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(gamera);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,393 +0,0 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
enemyType[i] = GetRandomValue(0, 3);
// Define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
// Define enemy bounding box
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int foodBar = 0;
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
}
// Enemies speed increase every frame
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
foodBar += 15;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
else
{
// Player die logic
currentScreen = ENDING;
framesCounter = 0;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
if (foodBar == 400)
{
gameraMode = true;
}
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
foodBar = 0;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, BLUE);
DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
}
else
{
DrawTexture(sea, seaScrolling, 0, RED);
DrawTexture(sea, screenWidth + seaScrolling, 0, RED);
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER", 480, 480, 40, BLACK);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
/*
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
*/
// Draw enemies bounding boxes
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], RED); break;
case 1: DrawRectangleRec(enemyBounds[i], RED); break;
case 2: DrawRectangleRec(enemyBounds[i], RED); break;
case 3: DrawRectangleRec(enemyBounds[i], GREEN); break;
default: break;
}
}
}
// Draw gameplay interface
// Draw food bar
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawText("GAME OVER", 300, 200, 100, MAROON);
// Draw blinking text
if ((framesCounter/30) % 2) DrawText("PRESS ENTER to REPLAY", 400, 420, 30, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(gamera);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

View File

@ -1,447 +0,0 @@
/*******************************************************************************************
*
* raylib game - Dr. Turtle & Mr. Gamera
*
* Welcome to raylib!
*
* To test examples, just press F6 and execute raylib_compile_execute script
* Note that compiled executable is placed in the same folder as .c file
*
* You can find all basic examples on C:\raylib\raylib\examples folder or
* raylib official webpage: www.raylib.com
*
* Enjoy using raylib. :)
*
* This game has been created using raylib 1.1 (www.raylib.com)
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
*
* Copyright (c) 2014 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#define MAX_ENEMIES 10
typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
int main()
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 1280;
const int screenHeight = 720;
// Init window
InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
// Load game resources: textures
Texture2D sky = LoadTexture("resources/sky.png");
Texture2D mountains = LoadTexture("resources/mountains.png");
Texture2D sea = LoadTexture("resources/sea.png");
Texture2D title = LoadTexture("resources/title.png");
Texture2D turtle = LoadTexture("resources/turtle.png");
Texture2D gamera = LoadTexture("resources/gamera.png");
Texture2D shark = LoadTexture("resources/shark.png");
Texture2D orca = LoadTexture("resources/orca.png");
Texture2D swhale = LoadTexture("resources/swhale.png");
Texture2D fish = LoadTexture("resources/fish.png");
Texture2D gframe = LoadTexture("resources/gframe.png");
// Load game resources: fonts
Font font = LoadFont("resources/komika.png");
// Define scrolling variables
int backScrolling = 0;
int seaScrolling = 0;
// Define current screen
GameScreen currentScreen = TITLE;
// Define player variables
int playerRail = 1;
Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
bool gameraMode = false;
// Define enemies variables
Rectangle enemyBounds[MAX_ENEMIES];
int enemyRail[MAX_ENEMIES];
int enemyType[MAX_ENEMIES];
bool enemyActive[MAX_ENEMIES];
float enemySpeed = 10;
// Init enemies variables
for (int i = 0; i < MAX_ENEMIES; i++)
{
// Define enemy type (all same probability)
//enemyType[i] = GetRandomValue(0, 3);
// Probability system for enemies type
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
// Define enemy rail
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
// Define additional game variables
int score = 0;
float distance = 0.0f;
int hiscore = 0;
float hidistance = 0.0f;
int foodBar = 0;
int framesCounter = 0;
SetTargetFPS(60); // Setup game frames per second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
framesCounter++;
// Game screens management
switch (currentScreen)
{
case TITLE:
{
// Sea scrolling
seaScrolling -= 2;
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Press enter to change to gameplay screen
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
framesCounter = 0;
}
} break;
case GAMEPLAY:
{
// Background scrolling logic
backScrolling--;
if (backScrolling <= -screenWidth) backScrolling = 0;
// Sea scrolling logic
seaScrolling -= (enemySpeed - 2);
if (seaScrolling <= -screenWidth) seaScrolling = 0;
// Player movement logic
if (IsKeyPressed(KEY_DOWN)) playerRail++;
else if (IsKeyPressed(KEY_UP)) playerRail--;
// Check player not out of rails
if (playerRail > 4) playerRail = 4;
else if (playerRail < 0) playerRail = 0;
// Update player bounds
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
// Enemies activation logic (every 40 frames)
if (framesCounter > 40)
{
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i] == false)
{
enemyActive[i] = true;
i = MAX_ENEMIES;
}
}
framesCounter = 0;
}
// Enemies logic
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
enemyBounds[i].x -= enemySpeed;
}
// Check enemies out of screen
if (enemyBounds[i].x <= 0 - 128)
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
}
if (!gameraMode) enemySpeed += 0.005;
// Check collision player vs enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
{
if (enemyType[i] < 3) // Bad enemies
{
if (gameraMode)
{
if (enemyType[i] == 0) score += 50;
else if (enemyType[i] == 1) score += 150;
else if (enemyType[i] == 2) score += 300;
foodBar += 15;
enemyActive[i] = false;
// After enemy deactivation, reset enemy parameters to be reused
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
}
else
{
// Player die logic
currentScreen = ENDING;
framesCounter = 0;
// Save hiscore and hidistance for next game
if (score > hiscore) hiscore = score;
if (distance > hidistance) hidistance = distance;
}
}
else // Sweet fish
{
enemyActive[i] = false;
enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
// Make sure not two consecutive enemies in the same row
if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
if (!gameraMode) foodBar += 80;
else foodBar += 25;
score += 10;
if (foodBar == 400)
{
gameraMode = true;
}
}
}
}
}
// Gamera mode logic
if (gameraMode)
{
foodBar--;
if (foodBar <= 0)
{
gameraMode = false;
enemySpeed -= 2;
if (enemySpeed < 10) enemySpeed = 10;
}
}
// Update distance counter
distance += 0.5f;
} break;
case ENDING:
{
// Press enter to play again
if (IsKeyPressed(KEY_ENTER))
{
currentScreen = GAMEPLAY;
// Reset player
playerRail = 1;
playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
gameraMode = false;
// Reset enemies data
for (int i = 0; i < MAX_ENEMIES; i++)
{
int enemyProb = GetRandomValue(0, 100);
if (enemyProb < 30) enemyType[i] = 0;
else if (enemyProb < 60) enemyType[i] = 1;
else if (enemyProb < 90) enemyType[i] = 2;
else enemyType[i] = 3;
//enemyType[i] = GetRandomValue(0, 3);
enemyRail[i] = GetRandomValue(0, 4);
enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
enemyActive[i] = false;
}
enemySpeed = 10;
// Reset game variables
score = 0;
distance = 0.0;
foodBar = 0;
framesCounter = 0;
}
} break;
default: break;
}
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
// Draw background (common to all screens)
DrawTexture(sky, 0, 0, WHITE);
DrawTexture(mountains, backScrolling, 0, WHITE);
DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
if (!gameraMode)
{
DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, 227, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, 227, 255});
}
else
{
DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
}
switch (currentScreen)
{
case TITLE:
{
// Draw title
DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.baseSize, 0, WHITE);
} break;
case GAMEPLAY:
{
// Draw water lines
for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
// Draw player
if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
// Draw player bounding box
//if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
//else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
// Draw enemies
for (int i = 0; i < MAX_ENEMIES; i++)
{
if (enemyActive[i])
{
// Draw enemies
switch(enemyType[i])
{
case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
default: break;
}
// Draw enemies bounding boxes
/*
switch(enemyType[i])
{
case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
default: break;
}
*/
}
}
// Draw gameplay interface
DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
DrawRectangle(20, 20, foodBar, 40, ORANGE);
DrawRectangleLines(20, 20, 400, 40, BLACK);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.baseSize, -2, ORANGE);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.baseSize, -2, ORANGE);
if (gameraMode)
{
DrawText("GAMERA MODE", 60, 22, 40, GRAY);
DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
}
} break;
case ENDING:
{
// Draw a transparent black rectangle that covers all screen
DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.baseSize*3, -2, MAROON);
DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.baseSize, -2, GOLD);
DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.baseSize, -2, GOLD);
DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.baseSize, -2, ORANGE);
DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.baseSize, -2, ORANGE);
// Draw blinking text
if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.baseSize, -2, LIGHTGRAY);
} break;
default: break;
}
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
// Unload textures
UnloadTexture(sky);
UnloadTexture(mountains);
UnloadTexture(sea);
UnloadTexture(gframe);
UnloadTexture(title);
UnloadTexture(turtle);
UnloadTexture(shark);
UnloadTexture(orca);
UnloadTexture(swhale);
UnloadTexture(fish);
UnloadTexture(gamera);
// Unload font texture
UnloadFont(font);
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}

Some files were not shown because too many files have changed in this diff Show More