Merge pull request #12 from raysan5/develop
Integration from develop branch
17
CHANGELOG
@ -1,11 +1,26 @@
|
||||
changelog
|
||||
---------
|
||||
|
||||
Current Release: raylib 1.2 (16 September 2014)
|
||||
Current Release: raylib 1.2.2 (31 December 2014)
|
||||
|
||||
NOTE: Only versions marked as 'Release' are available in installer, updates are only available as source.
|
||||
NOTE: Current Release includes all previous updates.
|
||||
|
||||
-----------------------------------------------
|
||||
Release: raylib 1.2.2 (31 December 2014)
|
||||
-----------------------------------------------
|
||||
[*] Added support for HTML5 compiling (emscripten, asm.js)
|
||||
[core] Corrected bug on input handling (keyboard and mouse)
|
||||
[textures] Renamed function CreateTexture() to LoadTextureFromImage()
|
||||
[textures] Added function ConvertToPOT()
|
||||
[models] Corrected bug on DrawBillboard()
|
||||
[models] Corrected bug on DrawHeightmap()
|
||||
[models] Renamed LoadCubesmap() to LoadCubicmap()
|
||||
[audio] Added function LoadSoundFromWave()
|
||||
[makefile] Added support for Linux compiling
|
||||
[stb] Updated to latest headers versions
|
||||
[*] Lots of tweaks around
|
||||
|
||||
---------------------------------------------------------------
|
||||
Update: raylib 1.2.1 (17 October 2014) (Small Fixes Update)
|
||||
---------------------------------------------------------------
|
||||
|
13
README.md
@ -10,6 +10,9 @@ Allegro and SDL have also been analyzed for reference.
|
||||
|
||||
Want to see how easy is making games with raylib? Jump to [code examples!] (http://www.raylib.com/examples.htm)
|
||||
|
||||
Since version 1.2.2 raylib can compile directly for web (html5) using emscripten and asm.js,
|
||||
to see a demo of raylib features working on web, [check here!] (http://www.raylib.com/raylib_demo.html)
|
||||
|
||||
history
|
||||
-------
|
||||
|
||||
@ -83,7 +86,7 @@ features
|
||||
* Powerful math module for Vector and Matrix operations [raymath]
|
||||
* Audio loading and playing with streaming support (WAV and OGG)
|
||||
* Custom color palette for fancy visuals on raywhite background
|
||||
* Multiple platforms support: Windows, Linux, Mac, **Android** and **Raspberry Pi**
|
||||
* Multiple platforms support: Windows, Linux, Mac, **Android**, **Raspberry Pi** and **HTML5**
|
||||
|
||||
raylib uses on its core module the outstanding [GLFW3] (http://www.glfw.org/) library. The best option by far I found for
|
||||
multiplatform (Windows, Linux, Mac) window/context and input management (clean, focused, great license, well documented, modern, ...).
|
||||
@ -160,6 +163,14 @@ _Step 3._ Navigate from command line to folder raylib/template_android/ and type
|
||||
NOTE: libraylib.a will be generated in folder raylib/src_android/obj/local/armeabi/, it must be copied
|
||||
to Android project; if using raylib/template_android project, copy it to raylib/template_android/jni/libs/.
|
||||
|
||||
**Building raylib sources for Web (HTML5)**
|
||||
|
||||
_Step 1._ Make sure you have installed emscripten SDK:
|
||||
|
||||
> Download latest version from [here].(http://kripken.github.io/emscripten-site/docs/getting_started/downloads.html) I recommend following the portable version installation instructions.
|
||||
|
||||
_Step 2._ TODO
|
||||
|
||||
building examples
|
||||
-----------------
|
||||
|
||||
|
@ -6,16 +6,18 @@ Here it is a list of features I would like to add and functions to improve.
|
||||
|
||||
Around the source code there are some TODO points with pending revisions/bugs and here it is a list of features I would like to add.
|
||||
|
||||
This roadmap is quite outdated... a full list of all the features we are working on should be listed here at some point...
|
||||
|
||||
raylib v1.x
|
||||
|
||||
- [DONE] Review Billboard Drawing functions
|
||||
- [DONE] Review Heightmap Loading and Drawing functions - Load Heightmap directly as a Model
|
||||
- Lighting support (only 3d mode)
|
||||
- [DONE] Simple Collision Detection functions
|
||||
- Default scene Camera controls (zoom, pan, rotate)
|
||||
- [IN PROGRESS] Default scene Camera controls (zoom, pan, rotate)
|
||||
- Basic Procedural Image Generation (Gradient, Checked, Spot, Noise, Cellular)
|
||||
- [DONE] Software mipmapping generation and POT conversion (custom implementation)
|
||||
- TTF fonts support
|
||||
- [IN PROGRESS] TTF fonts support
|
||||
|
||||
Any feature missing? Do you have a request? [Let me know!][raysan5]
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib for Raspberry Pi and Windows desktop
|
||||
#
|
||||
# makefile to compile raylib examples
|
||||
# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,12 +21,19 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform (by default, compile for RPI)
|
||||
# Other possible platforms: PLATFORM_DESKTOP PLATFORM_DESKTOP_LINUX
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile examples to HTML5, they must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
@ -41,6 +46,12 @@ else
|
||||
endif
|
||||
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
@ -49,10 +60,10 @@ else
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP_LINUX)
|
||||
LFLAGS = -L. -L../src
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../src -L/opt/vc/lib
|
||||
LFLAGS = -L. -L../src
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
@ -74,6 +85,10 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# resources file contains windows exe icon
|
||||
@ -81,6 +96,10 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
WINFLAGS = ../src/resources -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# define all object files required
|
||||
EXAMPLES = \
|
||||
core_basic_window \
|
||||
@ -109,7 +128,7 @@ EXAMPLES = \
|
||||
models_billboard \
|
||||
models_obj_loading \
|
||||
models_heightmap \
|
||||
models_cubesmap \
|
||||
models_cubicmap \
|
||||
audio_sound_loading \
|
||||
audio_music_stream \
|
||||
#core_input_gamepad \
|
||||
@ -124,125 +143,125 @@ examples: $(EXAMPLES)
|
||||
|
||||
# compile [core] example - basic window
|
||||
core_basic_window: core_basic_window.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - keyboard input
|
||||
core_input_keys: core_input_keys.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - mouse input
|
||||
core_input_mouse: core_input_mouse.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# compile [core] example - gamepad input
|
||||
core_input_gamepad: core_input_gamepad.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
endif
|
||||
|
||||
# compile [core] example - mouse wheel
|
||||
core_mouse_wheel: core_mouse_wheel.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - generate random values
|
||||
core_random_values: core_random_values.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - color selection (collision detection)
|
||||
core_color_select: core_color_select.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [core] example - 3d mode
|
||||
core_3d_mode: core_3d_mode.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [shapes] example - raylib logo (with basic shapes)
|
||||
shapes_logo_raylib: shapes_logo_raylib.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [shapes] example - basic shapes usage (rectangle, circle, ...)
|
||||
shapes_basic_shapes: shapes_basic_shapes.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [shapes] example - raylib color palette
|
||||
shapes_colors_palette: shapes_colors_palette.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [shapes] example - raylib logo animation
|
||||
shapes_logo_raylib_anim: shapes_logo_raylib_anim.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - raylib logo texture loading
|
||||
textures_logo_raylib: textures_logo_raylib.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - image loading and conversion to texture
|
||||
textures_image_loading: textures_image_loading.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture rectangle drawing
|
||||
textures_rectangle: textures_rectangle.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - compressed texture loading (DDS)
|
||||
textures_compressed_dds: textures_compressed_dds.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture mipmaps generation
|
||||
textures_mipmaps: textures_mipmaps.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [textures] example - texture source and destination rectangles
|
||||
textures_srcrec_dstrec: textures_srcrec_dstrec.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - sprite fonts loading
|
||||
text_sprite_fonts: text_sprite_fonts.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - raylib bitmap fonts (rBMF)
|
||||
text_rbmf_fonts: text_rbmf_fonts.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - text formatting
|
||||
text_format_text: text_format_text.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [text] example - font selection program
|
||||
text_font_select: text_font_select.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - basic geometric 3d shapes
|
||||
models_geometric_shapes: models_geometric_shapes.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - basic window
|
||||
models_planes: models_planes.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - billboard usage
|
||||
models_billboard: models_billboard.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - OBJ model loading
|
||||
models_obj_loading: models_obj_loading.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - heightmap loading
|
||||
models_heightmap: models_heightmap.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [models] example - cubesmap loading
|
||||
models_cubesmap: models_cubesmap.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
models_cubicmap: models_cubicmap.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [audio] example - sound loading and playing (WAV and OGG)
|
||||
audio_sound_loading: audio_sound_loading.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile [audio] example - music stream playing (OGG)
|
||||
audio_music_stream: audio_music_stream.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
@ -253,9 +272,13 @@ else
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP_LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
@ -84,7 +84,7 @@ int main()
|
||||
btnNextInColor = PURPLE;
|
||||
}
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
framesCounter = 20; // Frames button is 'active'
|
||||
btnNextOutColor = MAROON;
|
||||
@ -97,8 +97,8 @@ int main()
|
||||
btnNextOutColor = DARKBLUE;
|
||||
btnNextInColor = SKYBLUE;
|
||||
}
|
||||
|
||||
if (IsMouseButtonReleased(MOUSE_LEFT_BUTTON) && (framesCounter > 0)) framesCounter--;
|
||||
|
||||
if (framesCounter > 0) framesCounter--;
|
||||
|
||||
if (framesCounter == 1) // We change font on frame 1
|
||||
{
|
||||
|
210
games/floppy/floppy.c
Normal file
@ -0,0 +1,210 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib game - Floppy Bird
|
||||
*
|
||||
* 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 (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#define MAX_TUBES 100
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 800;
|
||||
int screenHeight = 450;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "Floppy Bird");
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
Sound coin = LoadSound("resources/coin.wav");
|
||||
Sound jump = LoadSound("resources/jump.wav");
|
||||
|
||||
Texture2D background = LoadTexture("resources/background.png");
|
||||
Texture2D tubes = LoadTexture("resources/tubes.png");
|
||||
Texture2D floppy = LoadTexture("resources/floppy.png");
|
||||
|
||||
Vector2 floppyPos = { 80, screenHeight/2 - floppy.height/2 };
|
||||
|
||||
Vector2 tubesPos[MAX_TUBES];
|
||||
int tubesSpeedX = 2;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
tubesPos[i].x = 400 + 280*i;
|
||||
tubesPos[i].y = -GetRandomValue(0, 120);
|
||||
}
|
||||
|
||||
Rectangle tubesRecs[MAX_TUBES*2];
|
||||
bool tubesActive[MAX_TUBES];
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i].y = tubesPos[i/2].y;
|
||||
tubesRecs[i].width = tubes.width;
|
||||
tubesRecs[i].height = 255;
|
||||
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].y = 600 + tubesPos[i/2].y - 255;
|
||||
tubesRecs[i+1].width = tubes.width;
|
||||
tubesRecs[i+1].height = 255;
|
||||
|
||||
tubesActive[i/2] = true;
|
||||
}
|
||||
|
||||
int backScroll = 0;
|
||||
|
||||
int score = 0;
|
||||
int hiscore = 0;
|
||||
|
||||
bool gameover = false;
|
||||
bool superfx = false;
|
||||
|
||||
SetTargetFPS(60);
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
backScroll--;
|
||||
|
||||
if (backScroll <= -800) backScroll = 0;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES; i++) tubesPos[i].x -= tubesSpeedX;
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
}
|
||||
|
||||
if (IsKeyDown(KEY_SPACE) && !gameover) floppyPos.y -= 3;
|
||||
else floppyPos.y += 1;
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE) && !gameover) PlaySound(jump);
|
||||
|
||||
// Check Collisions
|
||||
for (int i = 0; i < MAX_TUBES*2; i++)
|
||||
{
|
||||
if (CheckCollisionCircleRec((Vector2){ floppyPos.x + floppy.width/2, floppyPos.y + floppy.height/2 }, floppy.width/2, tubesRecs[i]))
|
||||
{
|
||||
gameover = true;
|
||||
}
|
||||
else if ((tubesPos[i/2].x < floppyPos.x) && tubesActive[i/2] && !gameover)
|
||||
{
|
||||
score += 100;
|
||||
tubesActive[i/2] = false;
|
||||
PlaySound(coin);
|
||||
|
||||
superfx = true;
|
||||
|
||||
if (score > hiscore) hiscore = score;
|
||||
}
|
||||
}
|
||||
|
||||
if (gameover && IsKeyPressed(KEY_ENTER))
|
||||
{
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
tubesPos[i].x = 400 + 280*i;
|
||||
tubesPos[i].y = -GetRandomValue(0, 120);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TUBES*2; i += 2)
|
||||
{
|
||||
tubesRecs[i].x = tubesPos[i/2].x;
|
||||
tubesRecs[i].y = tubesPos[i/2].y;
|
||||
|
||||
tubesRecs[i+1].x = tubesPos[i/2].x;
|
||||
tubesRecs[i+1].y = 600 + tubesPos[i/2].y - 255;
|
||||
|
||||
tubesActive[i/2] = true;
|
||||
}
|
||||
|
||||
floppyPos.x = 80;
|
||||
floppyPos.y = screenHeight/2 - floppy.height/2;
|
||||
|
||||
gameover = false;
|
||||
score = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
DrawTexture(background, backScroll, 0, WHITE);
|
||||
DrawTexture(background, screenWidth + backScroll, 0, WHITE);
|
||||
|
||||
if (!gameover)
|
||||
{
|
||||
DrawTextureEx(floppy, floppyPos, 0, 1.0, WHITE);
|
||||
//DrawCircleLines(floppyPos.x + floppy.width/2, floppyPos.y + floppy.height/2, floppy.width/2, RED);
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_TUBES; i++)
|
||||
{
|
||||
if (tubesPos[i].x <= 800) DrawTextureEx(tubes, tubesPos[i], 0, 1.0, WHITE);
|
||||
|
||||
//DrawRectangleLines(tubesRecs[i*2].x, tubesRecs[i*2].y, tubesRecs[i*2].width, tubesRecs[i*2].height, RED);
|
||||
//DrawRectangleLines(tubesRecs[i*2 + 1].x, tubesRecs[i*2 + 1].y, tubesRecs[i*2 + 1].width, tubesRecs[i*2 + 1].height, RED);
|
||||
}
|
||||
|
||||
DrawText(FormatText("%04i", score), 20, 20, 40, PINK);
|
||||
DrawText(FormatText("HI-SCORE: %04i", hiscore), 20, 70, 20, VIOLET);
|
||||
|
||||
if (gameover)
|
||||
{
|
||||
DrawText("GAME OVER", 100, 180, 100, MAROON);
|
||||
DrawText("PRESS ENTER to RETRY!", 280, 280, 20, RED);
|
||||
}
|
||||
|
||||
if (superfx)
|
||||
{
|
||||
DrawRectangle(0, 0, screenWidth, screenHeight, GOLD);
|
||||
superfx = false;
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(background); // Texture unloading
|
||||
UnloadTexture(tubes); // Texture unloading
|
||||
UnloadTexture(floppy); // Texture unloading
|
||||
|
||||
UnloadSound(coin); // Unload sound data
|
||||
UnloadSound(jump); // Unload sound data
|
||||
|
||||
CloseAudioDevice(); // Close audio device
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
BIN
games/floppy/resources/background.png
Normal file
After Width: | Height: | Size: 224 KiB |
BIN
games/floppy/resources/coin.wav
Normal file
BIN
games/floppy/resources/floppy.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
games/floppy/resources/jump.wav
Normal file
BIN
games/floppy/resources/tubes.png
Normal file
After Width: | Height: | Size: 19 KiB |
123
games/raylib_demo/makefile
Normal file
@ -0,0 +1,123 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib - Basic Game
|
||||
#
|
||||
# makefile to compile basic game
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
# 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 raylib platform (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP, PLATFORM_WEB, PLATFORM_RPI
|
||||
PLATFORM ?= PLATFORM_WEB
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O1 -Wall -std=c99
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O1 -Wall -std=c99 -s USE_GLFW=3 -s ASSERTIONS=1 --preload-file resources
|
||||
#-s ALLOW_MEMORY_GROWTH=1 # to allow memory resizing
|
||||
#-s TOTAL_MEMORY=16777216 # to specify heap memory size (default = 16MB)
|
||||
endif
|
||||
|
||||
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
|
||||
# define any directories containing required header files
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LFLAGS = -L.
|
||||
else
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
endif
|
||||
|
||||
# define any libraries to link into executable
|
||||
# if you want to link libraries (libname.so or libname.a), use the -lname
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
# NOTE: OpenAL Soft library should be installed (libopenal1 package)
|
||||
LIBS = -lraylib -lGLESv2 -lEGL -lpthread -lrt -lm -lbcm_host -lopenal
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# resources file contains windows exe icon
|
||||
# -Wl,--subsystem,windows hides the console window
|
||||
WINFLAGS = ../../src/resources -Wl,--subsystem,windows
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
EXT = .html
|
||||
endif
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is qidv_raylib
|
||||
default: raylib_demo
|
||||
|
||||
# compile qidv_raylib
|
||||
raylib_demo: raylib_demo.c
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
rm -f *.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.html *.js
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
# instead of defining every module one by one, we can define a pattern
|
||||
# this pattern below will automatically compile every module defined on $(OBJS)
|
||||
#%.exe : %.c
|
||||
# $(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM)
|
926
games/raylib_demo/raylib_demo.c
Normal file
@ -0,0 +1,926 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib - Talk: QIDV raylib (Learn Videogames Programming)
|
||||
*
|
||||
* Aprende a Programar Videojuegos con raylib
|
||||
*
|
||||
* This talk has been created using raylib v1.2 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#define MAX_BALLS 16
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum TalkScreen { LOADING, LOGO, MODULES, ENDING, PONG } TalkScreen;
|
||||
typedef enum Modules { CORE = 0, SHAPES, TEXTURES, TEXT, MODELS, AUDIO } Modules;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
int screenWidth = 1280;
|
||||
int screenHeight = 720;
|
||||
|
||||
const char msgLoading[30] = "LOADING...";
|
||||
const char msgPressEnter[30] = "Press ENTER to START";
|
||||
|
||||
const char msgCredits[40] = "by RAMON SANTAMARIA [@raysan5]";
|
||||
const char msgWeb[30] = "www.raylib.com";
|
||||
|
||||
const char msgLogoA[40] = "A simple and easy-to-use library";
|
||||
const char msgLogoB[40] = "to learn videogames programming";
|
||||
|
||||
const char msg1[50] = "THIS is a CUSTOM FONT...";
|
||||
const char msg2[50] = "...and ANOTHER CUSTOM ONE...";
|
||||
const char msg3[50] = "...AND ONE MORE! :)";
|
||||
|
||||
bool closeWindow = false;
|
||||
|
||||
int totalTime = 60*60*60; // fps*sec*min
|
||||
int timeCounter = 0;
|
||||
|
||||
TalkScreen currentScreen = LOADING;
|
||||
|
||||
// LOADING screen variables
|
||||
int loadBarWidth = 0;
|
||||
int loadBarMaxWidth = 600;
|
||||
|
||||
// TITLE screen variables
|
||||
SpriteFont fontAlagard;
|
||||
SpriteFont fontPixelplay;
|
||||
SpriteFont fontMecha;
|
||||
SpriteFont fontSetback;
|
||||
SpriteFont fontRomulus;
|
||||
|
||||
Vector2 pongBallPosition;
|
||||
Vector2 pongBallSpeed;
|
||||
Rectangle pongPlayerRec;
|
||||
Rectangle pongEnemyRec;
|
||||
int pongScorePlayer = 0;
|
||||
int pongScoreEnemy = 0;
|
||||
bool pongAutoMode = true;
|
||||
int pongAutoCounter = 0;
|
||||
bool pongPaused = true;
|
||||
|
||||
int lettersCounter = 0;
|
||||
char msgBuffer[120] = { ' ' };
|
||||
|
||||
// LOGO screen variables
|
||||
int logoPositionX;
|
||||
int logoPositionY;
|
||||
|
||||
int raylibLettersCount = 0;
|
||||
|
||||
int topSideRecWidth = 16;
|
||||
int leftSideRecHeight = 16;
|
||||
|
||||
int bottomSideRecWidth = 16;
|
||||
int rightSideRecHeight = 16;
|
||||
|
||||
char raylib[8] = " \0"; // raylib text array, max 8 letters
|
||||
|
||||
int logoScreenState = 0; // Tracking animation states (State Machine)
|
||||
bool msgLogoADone = false;
|
||||
bool msgLogoBDone = false;
|
||||
|
||||
// MODULES screen variables
|
||||
Modules selectedModule = CORE;
|
||||
|
||||
Texture2D raylibWindow;
|
||||
Texture2D raylibWindow01;
|
||||
Texture2D raylibWindow02;
|
||||
Texture2D raylibWindow03;
|
||||
Texture2D platforms;
|
||||
Texture2D raylibLogoB;
|
||||
Texture2D lena;
|
||||
Texture2D mandrill;
|
||||
Texture2D texAlagard;
|
||||
SpriteFont fontMechaC;
|
||||
SpriteFont fontAlagardC;
|
||||
SpriteFont fontJupiterC;
|
||||
|
||||
int coreWindow = 1;
|
||||
|
||||
int windowOffset = 0;
|
||||
Vector2 ballPosition;
|
||||
|
||||
Camera camera;
|
||||
|
||||
Texture2D catTexture;
|
||||
Model cat;
|
||||
|
||||
Sound fxWav;
|
||||
Sound fxOgg;
|
||||
|
||||
Vector2 soundBallsPosition[MAX_BALLS];
|
||||
Color soundBallsColor[MAX_BALLS];
|
||||
bool soundBallsActive[MAX_BALLS];
|
||||
float soundBallsAlpha[MAX_BALLS];
|
||||
int soundBallsRadius[MAX_BALLS];
|
||||
|
||||
float scaleFactor = 0.0f;
|
||||
float timePlayed = 0;
|
||||
|
||||
// ENDING screen variables
|
||||
Texture2D raylibLogoA;
|
||||
|
||||
// Required variables to manage screen transitions (fade-in, fade-out)
|
||||
float transAlpha = 0;
|
||||
bool onTransition = false;
|
||||
bool transFadeOut = false;
|
||||
int transFromScreen = -1;
|
||||
int transToScreen = -1;
|
||||
|
||||
int framesCounter = 0;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Local Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void TransitionToScreen(int screen);
|
||||
void UpdateTransition(void);
|
||||
void DrawTransition(void);
|
||||
|
||||
void UpdateDrawOneFrame(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const char windowTitle[30] = "raylib functionality demo";
|
||||
|
||||
//SetupFlags(FLAG_FULLSCREEN_MODE);
|
||||
InitWindow(screenWidth, screenHeight, windowTitle);
|
||||
|
||||
InitAudioDevice(); // Initialize audio device
|
||||
|
||||
// TITLE screen variables Initialization
|
||||
fontAlagard = LoadSpriteFont("resources/fonts/alagard.rbmf"); // rBMF font loading
|
||||
fontPixelplay = LoadSpriteFont("resources/fonts/pixelplay.rbmf"); // rBMF font loading
|
||||
fontMecha = LoadSpriteFont("resources/fonts/mecha.rbmf"); // rBMF font loading
|
||||
fontSetback = LoadSpriteFont("resources/fonts/setback.rbmf"); // rBMF font loading
|
||||
fontRomulus = LoadSpriteFont("resources/fonts/romulus.rbmf"); // rBMF font loading
|
||||
|
||||
pongBallPosition = (Vector2){ screenWidth/2, screenHeight/2 + 20 };
|
||||
pongBallSpeed = (Vector2){ 6, 6 };
|
||||
pongPlayerRec = (Rectangle){ 20, screenHeight/2 - 50 + 40, 20, 100 };
|
||||
pongEnemyRec = (Rectangle){ screenWidth - 40, screenHeight/2 - 60, 20, 120 };
|
||||
|
||||
// LOGO screen variables Initialization
|
||||
logoPositionX = screenWidth/2 - 128;
|
||||
logoPositionY = screenHeight/2 - 128;
|
||||
|
||||
// MODULES screen variables Initialization
|
||||
raylibWindow = LoadTexture("resources/raylib_window.png");
|
||||
raylibWindow01 = LoadTexture("resources/raylib_window_01.png");
|
||||
raylibWindow02 = LoadTexture("resources/raylib_window_02.png");
|
||||
raylibWindow03 = LoadTexture("resources/raylib_window_03.png");
|
||||
platforms = LoadTexture("resources/platforms.png");
|
||||
raylibLogoB = LoadTexture("resources/raylib_logo128x128.png");
|
||||
lena = LoadTexture("resources/lena.png");
|
||||
mandrill = LoadTexture("resources/mandrill.png");
|
||||
texAlagard = LoadTexture("resources/fonts/custom_alagard.png");
|
||||
fontMechaC = LoadSpriteFont("resources/fonts/custom_mecha.png");
|
||||
fontAlagardC = LoadSpriteFont("resources/fonts/custom_alagard.png");
|
||||
fontJupiterC = LoadSpriteFont("resources/fonts/custom_jupiter_crash.png");
|
||||
|
||||
ballPosition = (Vector2){ 520 + 656/2, 220 + 399/2 };
|
||||
|
||||
camera = (Camera){{ 0.0, 12.0, 15.0 }, { 0.0, 3.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
catTexture = LoadTexture("resources/catsham.png"); // Load model texture
|
||||
cat = LoadModel("resources/cat.obj"); // Load OBJ model
|
||||
SetModelTexture(&cat, catTexture);
|
||||
|
||||
fxWav = LoadSound("resources/audio/weird.wav"); // Load WAV audio file
|
||||
fxOgg = LoadSound("resources/audio/tanatana.ogg"); // Load OGG audio file
|
||||
|
||||
for (int i = 0; i < MAX_BALLS; i++)
|
||||
{
|
||||
soundBallsPosition[i] = (Vector2){ 650 + 560/2 + GetRandomValue(-280, 280), 220 + 200 + GetRandomValue(-200, 200) };
|
||||
soundBallsColor[i] = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
|
||||
soundBallsRadius[i] = GetRandomValue(2, 50);
|
||||
soundBallsAlpha[i] = 1.0f;
|
||||
|
||||
soundBallsActive[i] = false;
|
||||
}
|
||||
|
||||
// ENDING screen variables Initialization
|
||||
raylibLogoA = LoadTexture("resources/raylib_logo.png");
|
||||
|
||||
#ifndef PLATFORM_WEB
|
||||
SetTargetFPS(60);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawOneFrame, 0, 1);
|
||||
#else
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose() && !closeWindow) // Detect window close button or ESC key
|
||||
{
|
||||
UpdateDrawOneFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Unload all loaded data (textures, fonts, audio)
|
||||
UnloadSpriteFont(fontAlagard); // SpriteFont unloading
|
||||
UnloadSpriteFont(fontPixelplay); // SpriteFont unloading
|
||||
UnloadSpriteFont(fontMecha); // SpriteFont unloading
|
||||
UnloadSpriteFont(fontSetback); // SpriteFont unloading
|
||||
UnloadSpriteFont(fontRomulus); // SpriteFont unloading
|
||||
|
||||
UnloadTexture(raylibWindow);
|
||||
UnloadTexture(raylibWindow01);
|
||||
UnloadTexture(raylibWindow02);
|
||||
UnloadTexture(raylibWindow03);
|
||||
UnloadTexture(platforms);
|
||||
UnloadTexture(raylibLogoA);
|
||||
UnloadTexture(raylibLogoB);
|
||||
UnloadTexture(lena);
|
||||
UnloadTexture(mandrill);
|
||||
UnloadTexture(texAlagard);
|
||||
|
||||
UnloadSpriteFont(fontMechaC);
|
||||
UnloadSpriteFont(fontAlagardC);
|
||||
UnloadSpriteFont(fontJupiterC);
|
||||
|
||||
UnloadTexture(catTexture);
|
||||
UnloadModel(cat);
|
||||
|
||||
UnloadSound(fxWav);
|
||||
UnloadSound(fxOgg);
|
||||
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void TransitionToScreen(int screen)
|
||||
{
|
||||
onTransition = true;
|
||||
transFromScreen = currentScreen;
|
||||
transToScreen = screen;
|
||||
}
|
||||
|
||||
void UpdateTransition(void)
|
||||
{
|
||||
if (!transFadeOut)
|
||||
{
|
||||
transAlpha += 0.02f;
|
||||
|
||||
if (transAlpha >= 1.0)
|
||||
{
|
||||
transAlpha = 1.0;
|
||||
currentScreen = transToScreen;
|
||||
transFadeOut = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
}
|
||||
else // Transition fade out logic
|
||||
{
|
||||
transAlpha -= 0.02f;
|
||||
|
||||
if (transAlpha <= 0)
|
||||
{
|
||||
transAlpha = 0;
|
||||
transFadeOut = false;
|
||||
onTransition = false;
|
||||
transFromScreen = -1;
|
||||
transToScreen = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DrawTransition(void)
|
||||
{
|
||||
DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), Fade(RAYWHITE, transAlpha));
|
||||
}
|
||||
|
||||
void UpdateDrawOneFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (!onTransition)
|
||||
{
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOADING:
|
||||
{
|
||||
// Update LOADING screen variables
|
||||
framesCounter++; // Count frames
|
||||
|
||||
if ((loadBarWidth < loadBarMaxWidth) && ((framesCounter%30) == 0)) loadBarWidth++;
|
||||
|
||||
if (IsKeyDown(KEY_SPACE) && (loadBarWidth < loadBarMaxWidth)) loadBarWidth += 4;
|
||||
|
||||
if (IsKeyPressed(KEY_ENTER) && (loadBarWidth >= loadBarMaxWidth)) TransitionToScreen(LOGO);
|
||||
|
||||
} break;
|
||||
case LOGO:
|
||||
{
|
||||
// Update LOGO screen variables
|
||||
if (logoScreenState == 0) // State 0: Small box blinking
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter == 120)
|
||||
{
|
||||
logoScreenState = 1;
|
||||
framesCounter = 0; // Reset counter... will be used later...
|
||||
}
|
||||
}
|
||||
else if (logoScreenState == 1) // State 1: Top and left bars growing
|
||||
{
|
||||
topSideRecWidth += 4;
|
||||
leftSideRecHeight += 4;
|
||||
|
||||
if (topSideRecWidth == 256) logoScreenState = 2;
|
||||
}
|
||||
else if (logoScreenState == 2) // State 2: Bottom and right bars growing
|
||||
{
|
||||
bottomSideRecWidth += 4;
|
||||
rightSideRecHeight += 4;
|
||||
|
||||
if (bottomSideRecWidth == 256)
|
||||
{
|
||||
lettersCounter = 0;
|
||||
for (int i = 0; i < strlen(msgBuffer); i++) msgBuffer[i] = ' ';
|
||||
|
||||
logoScreenState = 3;
|
||||
}
|
||||
}
|
||||
else if (logoScreenState == 3) // State 3: Letters appearing (one by one)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
// Every 12 frames, one more letter!
|
||||
if ((framesCounter%12) == 0) raylibLettersCount++;
|
||||
|
||||
switch (raylibLettersCount)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (raylibLettersCount >= 10)
|
||||
{
|
||||
// Write raylib description messages
|
||||
if ((framesCounter%2) == 0) lettersCounter++;
|
||||
|
||||
if (!msgLogoADone)
|
||||
{
|
||||
if (lettersCounter <= strlen(msgLogoA)) strncpy(msgBuffer, msgLogoA, lettersCounter);
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < strlen(msgBuffer); i++) msgBuffer[i] = ' ';
|
||||
|
||||
lettersCounter = 0;
|
||||
msgLogoADone = true;
|
||||
}
|
||||
}
|
||||
else if (!msgLogoBDone)
|
||||
{
|
||||
if (lettersCounter <= strlen(msgLogoB)) strncpy(msgBuffer, msgLogoB, lettersCounter);
|
||||
else
|
||||
{
|
||||
msgLogoBDone = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Press enter to change to MODULES screen
|
||||
if (IsKeyPressed(KEY_ENTER) && msgLogoBDone) TransitionToScreen(MODULES);
|
||||
else if (IsKeyPressed(KEY_BACKSPACE)) TransitionToScreen(LOGO);
|
||||
|
||||
} break;
|
||||
case MODULES:
|
||||
{
|
||||
// Update MODULES screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (IsKeyPressed(KEY_RIGHT) && (selectedModule < 5))
|
||||
{
|
||||
selectedModule++;
|
||||
framesCounter = 0;
|
||||
}
|
||||
else if (IsKeyPressed(KEY_LEFT) && (selectedModule > 0))
|
||||
{
|
||||
selectedModule--;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (selectedModule == CORE)
|
||||
{
|
||||
if ((framesCounter > 60) && (windowOffset < 40))
|
||||
{
|
||||
windowOffset++;
|
||||
ballPosition.x++;
|
||||
ballPosition.y++;
|
||||
}
|
||||
|
||||
if (framesCounter > 140)
|
||||
{
|
||||
if (IsKeyDown('A')) ballPosition.x -= 5;
|
||||
if (IsKeyDown('D')) ballPosition.x += 5;
|
||||
if (IsKeyDown('W')) ballPosition.y -= 5;
|
||||
if (IsKeyDown('S')) ballPosition.y += 5;
|
||||
|
||||
if (IsKeyPressed('1')) coreWindow = 1;
|
||||
if (IsKeyPressed('2')) coreWindow = 2;
|
||||
if (IsKeyPressed('3')) coreWindow = 3;
|
||||
if (IsKeyPressed('4')) coreWindow = 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedModule == TEXTURES) scaleFactor = (sinf(2*PI/240*framesCounter) + 1.0f)/2;
|
||||
|
||||
if (selectedModule == AUDIO)
|
||||
{
|
||||
if (IsKeyPressed(KEY_SPACE) && !MusicIsPlaying()) PlayMusicStream("resources/audio/guitar_noodling.ogg"); // Play music stream
|
||||
|
||||
if (IsKeyPressed('S'))
|
||||
{
|
||||
StopMusicStream();
|
||||
timePlayed = 0.0f;
|
||||
|
||||
for (int i = 0; i < MAX_BALLS; i++)
|
||||
{
|
||||
soundBallsPosition[i] = (Vector2){ 650 + 560/2 + GetRandomValue(-280, 280), 220 + 200 + GetRandomValue(-200, 200) };
|
||||
soundBallsColor[i] = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
|
||||
soundBallsRadius[i] = GetRandomValue(2, 50);
|
||||
soundBallsAlpha[i] = 1.0f;
|
||||
|
||||
soundBallsActive[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (MusicIsPlaying())
|
||||
{
|
||||
timePlayed = GetMusicTimePlayed() / GetMusicTimeLength() * 100 * 4;
|
||||
|
||||
if ((framesCounter%10) == 0)
|
||||
{
|
||||
for (int i = 0; i < MAX_BALLS; i++)
|
||||
{
|
||||
if (!soundBallsActive[i])
|
||||
{
|
||||
soundBallsActive[i] = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < MAX_BALLS; i++)
|
||||
{
|
||||
if (soundBallsActive[i]) soundBallsAlpha[i] -= 0.005f;
|
||||
|
||||
if (soundBallsAlpha[i] <= 0)
|
||||
{
|
||||
soundBallsActive[i] = false;
|
||||
|
||||
// Reset ball random
|
||||
soundBallsPosition[i] = (Vector2){ 650 + 560/2 + GetRandomValue(-280, 280), 220 + 200 + GetRandomValue(-200, 200) };
|
||||
soundBallsColor[i] = (Color){ GetRandomValue(0, 255), GetRandomValue(0, 255), GetRandomValue(0, 255), 255 };
|
||||
soundBallsRadius[i] = GetRandomValue(2, 60);
|
||||
soundBallsAlpha[i] = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (IsKeyPressed('N')) PlaySound(fxWav);
|
||||
//if (IsKeyPressed('M')) PlaySound(fxOgg);
|
||||
}
|
||||
|
||||
// Press enter to change to ENDING screen
|
||||
if (IsKeyPressed(KEY_ENTER)) TransitionToScreen(ENDING);
|
||||
else if (IsKeyPressed(KEY_BACKSPACE)) TransitionToScreen(LOGO);
|
||||
|
||||
} break;
|
||||
case PONG:
|
||||
{
|
||||
// Update SECRET screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (IsKeyPressed('P')) pongPaused = !pongPaused;
|
||||
|
||||
if (!pongPaused)
|
||||
{
|
||||
pongBallPosition.x += pongBallSpeed.x;
|
||||
pongBallPosition.y += pongBallSpeed.y;
|
||||
|
||||
if ((pongBallPosition.x >= screenWidth - 5) || (pongBallPosition.x <= 5)) pongBallSpeed.x *= -1;
|
||||
if ((pongBallPosition.y >= screenHeight - 5) || (pongBallPosition.y <= 5)) pongBallSpeed.y *= -1;
|
||||
|
||||
if (IsKeyDown(KEY_UP) || IsKeyDown('W'))
|
||||
{
|
||||
pongPlayerRec.y -= 5;
|
||||
pongAutoMode = false;
|
||||
pongAutoCounter = 180;
|
||||
}
|
||||
else if (IsKeyDown(KEY_DOWN) || IsKeyDown('S'))
|
||||
{
|
||||
pongPlayerRec.y += 5;
|
||||
pongAutoMode = false;
|
||||
pongAutoCounter = 180;
|
||||
}
|
||||
else if (pongAutoCounter > 0)
|
||||
{
|
||||
pongAutoCounter--;
|
||||
|
||||
if (pongAutoCounter == 0) pongAutoMode = true;
|
||||
}
|
||||
|
||||
if ((pongBallPosition.x < 600) && pongAutoMode)
|
||||
{
|
||||
if (pongBallPosition.y > (pongPlayerRec.y + pongPlayerRec.height/2)) pongPlayerRec.y += 5;
|
||||
else if (pongBallPosition.y < (pongPlayerRec.y + pongPlayerRec.height/2)) pongPlayerRec.y -= 5;
|
||||
}
|
||||
|
||||
if (pongPlayerRec.y <= 0) pongPlayerRec.y = 0;
|
||||
else if ((pongPlayerRec.y + pongPlayerRec.height) >= screenHeight) pongPlayerRec.y = screenHeight - pongPlayerRec.height;
|
||||
|
||||
if (pongBallPosition.x > screenWidth - 600)
|
||||
{
|
||||
if (pongBallPosition.y > (pongEnemyRec.y + pongEnemyRec.height/2)) pongEnemyRec.y += 5;
|
||||
else if (pongBallPosition.y < (pongEnemyRec.y + pongEnemyRec.height/2)) pongEnemyRec.y -= 5;
|
||||
|
||||
if (pongEnemyRec.y <= 0) pongEnemyRec.y = 0;
|
||||
else if ((pongEnemyRec.y + pongEnemyRec.height) >= screenHeight) pongEnemyRec.y = screenHeight - pongEnemyRec.height;
|
||||
}
|
||||
|
||||
if ((CheckCollisionCircleRec(pongBallPosition, 10, pongPlayerRec)) || (CheckCollisionCircleRec(pongBallPosition, 10, pongEnemyRec))) pongBallSpeed.x *= -1;
|
||||
|
||||
if (pongBallPosition.x >= screenWidth - 5) pongScorePlayer++;
|
||||
else if (pongBallPosition.x <= 5) pongScoreEnemy++;
|
||||
}
|
||||
|
||||
// Press enter to move back to MODULES screen
|
||||
if (IsKeyPressed(KEY_ENTER)) TransitionToScreen(ENDING);
|
||||
if (IsKeyPressed(KEY_BACKSPACE)) TransitionToScreen(ENDING);
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// Update ENDING screen
|
||||
framesCounter++;
|
||||
|
||||
// Press enter to move back to MODULES screen
|
||||
if (IsKeyPressed(KEY_ENTER)) TransitionToScreen(PONG);
|
||||
if (IsKeyPressed(KEY_BACKSPACE)) TransitionToScreen(MODULES);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if ((currentScreen != LOADING) && (timeCounter < totalTime)) timeCounter++;
|
||||
}
|
||||
else UpdateTransition(); // Update transition (fade-in, fade-out)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOADING:
|
||||
{
|
||||
// Draw LOADING screen
|
||||
if ((loadBarWidth < loadBarMaxWidth) && ((framesCounter/40)%2)) DrawText(msgLoading, 360, 240, 40, DARKGRAY);
|
||||
|
||||
DrawRectangle(360 - 4, 300 - 4, loadBarMaxWidth + 8, 60 + 8, LIGHTGRAY);
|
||||
DrawRectangle(360, 300, loadBarWidth - 1, 60, DARKGRAY);
|
||||
DrawRectangleLines(360 - 4, 300 - 5, loadBarMaxWidth + 8, 60 + 8, DARKGRAY);
|
||||
|
||||
if (loadBarWidth >= loadBarMaxWidth)
|
||||
{
|
||||
//DrawText(msgLoading, 360, 240, 40, DARKGRAY);
|
||||
if ((framesCounter/30)%2) DrawText(msgPressEnter, screenWidth/2 - MeasureText(msgPressEnter, 40)/2 + 20, 400, 40, DARKGRAY);
|
||||
}
|
||||
else DrawText("PRESS SPACE to ACCELERATE LOADING! ;)", screenWidth/2 - 200, 400, 20, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
case LOGO:
|
||||
{
|
||||
// Draw LOGO screen
|
||||
if (logoScreenState == 0)
|
||||
{
|
||||
if ((framesCounter/15)%2) DrawRectangle(logoPositionX, logoPositionY - 60, 16, 16, BLACK);
|
||||
}
|
||||
else if (logoScreenState == 1)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY - 60, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY - 60, 16, leftSideRecHeight, BLACK);
|
||||
}
|
||||
else if (logoScreenState == 2)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY - 60, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY - 60, 16, leftSideRecHeight, BLACK);
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY - 60, 16, rightSideRecHeight, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240 - 60, bottomSideRecWidth, 16, BLACK);
|
||||
}
|
||||
else if (logoScreenState == 3)
|
||||
{
|
||||
DrawRectangle(logoPositionX, logoPositionY - 60, topSideRecWidth, 16, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY + 16 - 60, 16, leftSideRecHeight - 32, BLACK);
|
||||
|
||||
DrawRectangle(logoPositionX + 240, logoPositionY + 16 - 60, 16, rightSideRecHeight - 32, BLACK);
|
||||
DrawRectangle(logoPositionX, logoPositionY + 240 - 60, bottomSideRecWidth, 16, BLACK);
|
||||
|
||||
DrawRectangle(screenWidth/2 - 112, screenHeight/2 - 112 - 60, 224, 224, RAYWHITE);
|
||||
|
||||
DrawText(raylib, screenWidth/2 - 44, screenHeight/2 + 48 - 60, 50, BLACK);
|
||||
|
||||
if (!msgLogoADone) DrawText(msgBuffer, screenWidth/2 - MeasureText(msgLogoA, 30)/2, 460, 30, GRAY);
|
||||
else
|
||||
{
|
||||
DrawText(msgLogoA, screenWidth/2 - MeasureText(msgLogoA, 30)/2, 460, 30, GRAY);
|
||||
|
||||
if (!msgLogoBDone) DrawText(msgBuffer, screenWidth/2 - MeasureText(msgLogoB, 30)/2, 510, 30, GRAY);
|
||||
else
|
||||
{
|
||||
DrawText(msgLogoB, screenWidth/2 - MeasureText(msgLogoA, 30)/2, 510, 30, GRAY);
|
||||
|
||||
if ((framesCounter > 90) && ((framesCounter/30)%2)) DrawText("PRESS ENTER to CONTINUE", 930, 650, 20, GRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case MODULES:
|
||||
{
|
||||
// Draw MODULES screen
|
||||
DrawTexture(raylibLogoB, 40, 40, WHITE);
|
||||
DrawText("raylib is composed of 6 main modules:", 128 + 40 + 30, 50, 20, GRAY);
|
||||
|
||||
if (framesCounter < 120)
|
||||
{
|
||||
if (((framesCounter/30)%2) == 0) DrawRectangle(128 + 40 + 30 - 4 + 175*selectedModule, 128 + 40 - 70 - 8 - 4, 158, 78, RED);
|
||||
}
|
||||
else DrawRectangle(128 + 40 + 30 - 4 + 175*selectedModule, 128 + 40 - 70 - 8 - 4, 158, 78, RED);
|
||||
|
||||
if (selectedModule != AUDIO)
|
||||
{
|
||||
DrawTriangle((Vector2){950 - 40, 685 - 10}, (Vector2){950 - 60, 685}, (Vector2){950 - 40, 685 + 10}, GRAY);
|
||||
DrawTriangle((Vector2){950 - 30, 685 - 10}, (Vector2){950 - 30, 685 + 10}, (Vector2){950 - 10, 685}, GRAY);
|
||||
DrawText("PRESS RIGHT or LEFT to EXPLORE MODULES", 960, 680, 10, GRAY);
|
||||
}
|
||||
|
||||
switch (selectedModule)
|
||||
{
|
||||
case CORE:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x5c5a5aff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Open-Close Window", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Drawing Area", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Inputs", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Manage Timming", (Vector2){ 48, 320 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
DrawTextEx(fontRomulus, "Auxiliar Functions", (Vector2){ 48, 350 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x5c5a5aff));
|
||||
|
||||
switch (coreWindow)
|
||||
{
|
||||
case 1: DrawTexture(raylibWindow, 520, 220, WHITE); break;
|
||||
case 2: DrawTextureEx(raylibWindow01, (Vector2){ 450, 220 - 45 }, 0.0f, 4.0f, WHITE); break;
|
||||
case 3: DrawTextureEx(raylibWindow02, (Vector2){ 430, 220 - 40 }, 0.0f, 4.0f, WHITE); break;
|
||||
case 4: DrawTextureEx(raylibWindow03, (Vector2){ 470, 220 - 65 }, 0.0f, 4.0f, WHITE); break;
|
||||
default: DrawTexture(raylibWindow, 520, 220, WHITE); break;
|
||||
}
|
||||
|
||||
if (framesCounter > 140) DrawText("Check the possible windows raylib can run on. PRESS KEY: 1, 2, 3 or 4", 520 + 8 + windowOffset + 160, 220 + windowOffset + 10, 10, LIGHTGRAY);
|
||||
|
||||
DrawText("Compile raylib C code for the folowing platforms:", 48, 400, 10, MAROON);
|
||||
|
||||
DrawTextureRec(platforms, (Rectangle){ 0, 0, platforms.width, platforms.height}, (Vector2){ 75, 420 }, WHITE);
|
||||
|
||||
DrawRectangle(520 + 8 + windowOffset, 220 + 31 + windowOffset, 640, 360, RAYWHITE);
|
||||
DrawRectangleLines(520 + 8 + windowOffset - 1, 220 + 31 + windowOffset - 2, 640 + 2, 360 + 2, GRAY);
|
||||
DrawFPS(520 + 8 + windowOffset + 10, 220 + 31 + windowOffset + 10);
|
||||
|
||||
DrawRectangle(ballPosition.x - 50, ballPosition.y - 50, 100, 100, Fade(MAROON, 0.5f));
|
||||
DrawRectangleRec(GetCollisionRec((Rectangle){ 520 + 8 + windowOffset - 1, 220 + 31 + windowOffset - 1, 640 + 2, 360 + 2 }, (Rectangle){ (int)ballPosition.x - 50, (int)ballPosition.y - 50, 100, 100 }), MAROON);
|
||||
|
||||
if (framesCounter > 140)
|
||||
{
|
||||
DrawTextEx(fontMecha, "MOVE ME", (Vector2){ ballPosition.x - 26, ballPosition.y - 20 }, GetFontBaseSize(fontMecha), 2, BLACK);
|
||||
DrawTextEx(fontMecha, "[ W A S D ]", (Vector2){ ballPosition.x - 36, ballPosition.y }, GetFontBaseSize(fontMecha), 2, BLACK);
|
||||
}
|
||||
} break;
|
||||
case SHAPES:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0xcd5757ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Draw Basic Shapes", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0xcd5757ff));
|
||||
DrawTextEx(fontRomulus, "Basic Collision Detection", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0xcd5757ff));
|
||||
|
||||
DrawCircle(screenWidth/4, 120 + 240, 35, DARKBLUE);
|
||||
DrawCircleGradient(screenWidth/4, 220 + 240, 60, GREEN, SKYBLUE);
|
||||
DrawCircleLines(screenWidth/4, 340 + 240, 80, DARKBLUE);
|
||||
|
||||
DrawRectangle(screenWidth/4*2 - 110, 100 + 180, 220, 100, LIME);
|
||||
DrawRectangleGradient(screenWidth/4*2 - 90, 170 + 240, 180, 130, MAROON, GOLD);
|
||||
DrawRectangleLines(screenWidth/4*2 - 80, 320 + 240, 160, 80, ORANGE);
|
||||
|
||||
DrawTriangle((Vector2){screenWidth/4*3, 60 + 220}, (Vector2){screenWidth/4*3 - 60, 160 + 220}, (Vector2){screenWidth/4*3 + 60, 160 + 220}, VIOLET);
|
||||
|
||||
DrawTriangleLines((Vector2){screenWidth/4*3, 140 + 220}, (Vector2){screenWidth/4*3 - 60, 210 + 260}, (Vector2){screenWidth/4*3 + 60, 210 + 260}, SKYBLUE);
|
||||
|
||||
DrawPoly((Vector2){screenWidth/4*3, 320 + 240}, 6, 80, 0, BROWN);
|
||||
|
||||
} break;
|
||||
case TEXTURES:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x60815aff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load Images and Textures", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x60815aff));
|
||||
DrawTextEx(fontRomulus, "Draw Textures", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x60815aff));
|
||||
|
||||
DrawRectangle(138, 348, 260, 260, GRAY);
|
||||
DrawTexturePro(lena, (Rectangle){ 0, 0, lena.width, lena.height }, (Rectangle){ 140 + 128, 350 + 128, lena.width/2*scaleFactor, lena.height/2*scaleFactor }, (Vector2){ lena.width/4*scaleFactor, lena.height/4*scaleFactor }, 0.0f, WHITE);
|
||||
|
||||
DrawTexture(lena, 600, 180, Fade(WHITE, 0.3f));
|
||||
DrawTextureRec(lena, (Rectangle){ 225, 240, 155, 50 }, (Vector2){ 600 + 256 - 82 + 50, 180 + 241 }, PINK);
|
||||
|
||||
DrawTexturePro(mandrill, (Rectangle){ 0, 0, mandrill.width, mandrill.height }, (Rectangle){ screenWidth/2 - 40, 350 + 128, mandrill.width/2, mandrill.height/2 },
|
||||
(Vector2){ mandrill.width/4, mandrill.height/4 }, framesCounter, GOLD);
|
||||
|
||||
} break;
|
||||
case TEXT:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x377764ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load SpriteFonts", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Draw Text", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
DrawTextEx(fontRomulus, "Text Formatting", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x377764ff));
|
||||
|
||||
DrawTexture(texAlagard, 60, 360, WHITE);
|
||||
|
||||
DrawTextEx(fontMechaC, msg1, (Vector2){ 540 + 168, 210 }, GetFontBaseSize(fontMechaC), -3, WHITE);
|
||||
DrawTextEx(fontAlagardC, msg2, (Vector2){ 460 + 140, 260 }, GetFontBaseSize(fontAlagardC), -2, WHITE);
|
||||
DrawTextEx(fontJupiterC, msg3, (Vector2){ 640 + 70, 300 }, GetFontBaseSize(fontJupiterC), 2, WHITE);
|
||||
|
||||
DrawTextEx(fontAlagard, "It also includes some...", (Vector2){ 650 + 70, 400 }, GetFontBaseSize(fontAlagard)*2, 2, MAROON);
|
||||
DrawTextEx(fontPixelplay, "...free fonts in rBMF format...", (Vector2){ 705 - 26, 450 }, GetFontBaseSize(fontPixelplay)*2, 4, ORANGE);
|
||||
DrawTextEx(fontMecha, "...to be used even in...", (Vector2){ 700 + 40, 500 }, GetFontBaseSize(fontMecha)*2, 4, DARKGREEN);
|
||||
DrawTextEx(fontSetback, "...comercial projects...", (Vector2){ 710, 550 }, GetFontBaseSize(fontSetback)*2, 4, DARKBLUE);
|
||||
DrawTextEx(fontRomulus, "...completely for free!", (Vector2){ 710 + 17, 600 }, GetFontBaseSize(fontRomulus)*2, 3, DARKPURPLE);
|
||||
|
||||
DrawText("This is a custom font spritesheet, raylib can load it automatically!", 228, 360 + 295, 10, GRAY);
|
||||
|
||||
} break;
|
||||
case MODELS:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x417794ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Draw Geometric Models", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Load 3D Models", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
DrawTextEx(fontRomulus, "Draw 3D Models", (Vector2){ 48, 290 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x417794ff));
|
||||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawCube((Vector3){-4, 0, 2}, 2, 5, 2, RED);
|
||||
DrawCubeWires((Vector3){-4, 0, 2}, 2, 5, 2, GOLD);
|
||||
DrawCubeWires((Vector3){-4, 0, -2}, 3, 6, 2, MAROON);
|
||||
|
||||
DrawSphere((Vector3){-1, 0, -2}, 1, GREEN);
|
||||
DrawSphereWires((Vector3){1, 0, 2}, 2, 16, 16, LIME);
|
||||
|
||||
DrawCylinder((Vector3){4, 0, -2}, 1, 2, 3, 4, SKYBLUE);
|
||||
DrawCylinderWires((Vector3){4, 0, -2}, 1, 2, 3, 4, DARKBLUE);
|
||||
DrawCylinderWires((Vector3){4.5, -1, 2}, 1, 1, 2, 6, BROWN);
|
||||
|
||||
DrawCylinder((Vector3){1, 0, -4}, 0, 1.5, 3, 8, GOLD);
|
||||
DrawCylinderWires((Vector3){1, 0, -4}, 0, 1.5, 3, 8, PINK);
|
||||
|
||||
DrawModelEx(cat, (Vector3){ 8.0f, 0.0f, 2.0f }, (Vector3){ 0.0f, 0.5f*framesCounter, 0.0f }, (Vector3){ 0.1f, 0.1f, 0.1f }, WHITE);
|
||||
DrawGizmo((Vector3){ 8.0f, 0.0f, 2.0f });
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
||||
End3dMode();
|
||||
|
||||
DrawFPS(900, 220);
|
||||
|
||||
} break;
|
||||
case AUDIO:
|
||||
{
|
||||
DrawText("This module give you functions to:", 48, 200, 10, GetColor(0x8c7539ff));
|
||||
|
||||
DrawTextEx(fontRomulus, "Load and Play Sounds", (Vector2){ 48, 230 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x8c7539ff));
|
||||
DrawTextEx(fontRomulus, "Play Music (streaming)", (Vector2){ 48, 260 }, GetFontBaseSize(fontRomulus)*2, 4, GetColor(0x8c7539ff));
|
||||
|
||||
DrawText("PRESS SPACE to START PLAYING MUSIC", 135, 350, 20, GRAY);
|
||||
DrawRectangle(150, 390, 400, 12, LIGHTGRAY);
|
||||
DrawRectangle(150, 390, (int)timePlayed, 12, MAROON);
|
||||
|
||||
if (MusicIsPlaying())
|
||||
{
|
||||
DrawText("PRESS 'S' to STOP PLAYING MUSIC", 165, 425, 20, GRAY);
|
||||
|
||||
for (int i = 0; i < MAX_BALLS; i++)
|
||||
{
|
||||
if (soundBallsActive[i]) DrawPoly(soundBallsPosition[i], 18, soundBallsRadius[i], 0.0f, Fade(soundBallsColor[i], soundBallsAlpha[i]));
|
||||
}
|
||||
}
|
||||
|
||||
DrawText("PRESS 'N' to PLAY a SOUND", 200, 540, 20, VIOLET);
|
||||
|
||||
if ((framesCounter/30)%2) DrawText("PRESS ENTER to CONTINUE", 930, 650, 20, GRAY);
|
||||
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
// Draw modules menu
|
||||
DrawRectangle(128 + 40 + 30, 128 + 40 - 70 - 8, 150, 70, GetColor(0x898888ff));
|
||||
DrawRectangle(128 + 40 + 30 + 8, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xe1e1e1ff));
|
||||
DrawText("CORE", 128 + 40 + 30 + 8 + 38, 128 + 40 - 50, 20, GetColor(0x5c5a5aff));
|
||||
|
||||
DrawRectangle(128 + 40 + 30 + 175, 128 + 40 - 70 - 8, 150, 70, GetColor(0xe66666ff));
|
||||
DrawRectangle(128 + 40 + 30 + 8 + 175, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xf0d6d6ff));
|
||||
DrawText("SHAPES", 128 + 40 + 30 + 8 + 175 + 28, 128 + 40 - 50, 20, GetColor(0xcd5757ff));
|
||||
|
||||
DrawRectangle(128 + 40 + 30 + 175*2, 128 + 40 - 70 - 8, 150, 70, GetColor(0x75a06dff));
|
||||
DrawRectangle(128 + 40 + 30 + 8 + 175*2, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xc8eabfff));
|
||||
DrawText("TEXTURES", 128 + 40 + 30 + 175*2 + 8 + 9, 128 + 40 - 50, 20, GetColor(0x60815aff));
|
||||
|
||||
DrawRectangle(128 + 40 + 30 + 175*3, 128 + 40 - 70 - 8, 150, 70, GetColor(0x52b296ff));
|
||||
DrawRectangle(128 + 40 + 30 + 8 + 175*3, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xbef0ddff));
|
||||
DrawText("TEXT", 128 + 40 + 30 + 8 + 175*3 + 38, 128 + 40 - 50, 20, GetColor(0x377764ff));
|
||||
|
||||
DrawRectangle(128 + 40 + 30 + 175*4, 128 + 40 - 70 - 8, 150, 70, GetColor(0x5d9cbdff));
|
||||
DrawRectangle(128 + 40 + 30 + 8 + 175*4, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xbedce8ff));
|
||||
DrawText("MODELS", 128 + 40 + 30 + 8 + 175*4 + 28, 128 + 40 - 50, 20, GetColor(0x417794ff));
|
||||
|
||||
DrawRectangle(128 + 40 + 30 + 175*5, 128 + 40 - 70 - 8, 150, 70, GetColor(0xd3b157ff));
|
||||
DrawRectangle(128 + 40 + 30 + 8 + 175*5, 128 + 40 - 70, 150 - 16, 70 - 16, GetColor(0xebddaeff));
|
||||
DrawText("AUDIO", 128 + 40 + 30 + 8 + 175*5 + 36, 128 + 40 - 50, 20, GetColor(0x8c7539ff));
|
||||
|
||||
} break;
|
||||
case ENDING:
|
||||
{
|
||||
// Draw ENDING screen
|
||||
DrawTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", (Vector2){ screenWidth/2 - MeasureTextEx(fontAlagard, "LEARN VIDEOGAMES PROGRAMMING", GetFontBaseSize(fontAlagard)*4, 4).x/2, 80 }, GetFontBaseSize(fontAlagard)*4, 4, MAROON);
|
||||
|
||||
DrawTexture(raylibLogoA, logoPositionX, logoPositionY - 40, WHITE);
|
||||
|
||||
DrawText(msgWeb, screenWidth/2 - MeasureText(msgWeb, 40)/2, 470, 40, DARKGRAY);
|
||||
|
||||
if (framesCounter > 60) DrawText(msgCredits, screenWidth/2 - MeasureText(msgCredits, 30)/2, 550, 30, GRAY);
|
||||
|
||||
if (framesCounter > 120) if ((framesCounter/30)%2) DrawText("PRESS ENTER to CONTINUE", screenWidth/2 - MeasureText("PRESS ENTER to CONTINUE", 20)/2, 640, 20, LIGHTGRAY);
|
||||
|
||||
} break;
|
||||
case PONG:
|
||||
{
|
||||
// Pong
|
||||
DrawCircleV(pongBallPosition, 10, LIGHTGRAY);
|
||||
DrawRectangleRec(pongPlayerRec, GRAY);
|
||||
DrawRectangleRec(pongEnemyRec, GRAY);
|
||||
|
||||
DrawText(FormatText("%02i", pongScorePlayer), 150, 10, 80, LIGHTGRAY);
|
||||
DrawText(FormatText("%02i", pongScoreEnemy), screenWidth - MeasureText("00", 80) - 150, 10, 80, LIGHTGRAY);
|
||||
|
||||
if (pongPaused) if ((framesCounter/30)%2) DrawText("GAME PAUSED [P]", screenWidth/2 - 100, 40, 20, MAROON);
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (currentScreen != LOADING) DrawRectangle(0, screenHeight - 10, ((float)timeCounter/(float)totalTime)*screenWidth, 10, LIGHTGRAY);
|
||||
|
||||
if (onTransition) DrawTransition();
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
BIN
games/raylib_demo/resources/audio/coin.wav
Normal file
BIN
games/raylib_demo/resources/audio/guitar_noodling.ogg
Normal file
BIN
games/raylib_demo/resources/audio/spring.wav
Normal file
BIN
games/raylib_demo/resources/audio/tanatana.ogg
Normal file
BIN
games/raylib_demo/resources/audio/weird.wav
Normal file
4731
games/raylib_demo/resources/cat.obj
Normal file
BIN
games/raylib_demo/resources/catsham.png
Normal file
After Width: | Height: | Size: 308 KiB |
BIN
games/raylib_demo/resources/catwhite.png
Normal file
After Width: | Height: | Size: 302 KiB |
BIN
games/raylib_demo/resources/fonts/alagard.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/alpha_beta.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/custom_alagard.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
games/raylib_demo/resources/fonts/custom_jupiter_crash.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
games/raylib_demo/resources/fonts/custom_mecha.png
Normal file
After Width: | Height: | Size: 26 KiB |
BIN
games/raylib_demo/resources/fonts/jupiter_crash.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/mecha.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/pixantiqua.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/pixelplay.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/romulus.rbmf
Normal file
BIN
games/raylib_demo/resources/fonts/setback.rbmf
Normal file
BIN
games/raylib_demo/resources/lena.png
Normal file
After Width: | Height: | Size: 463 KiB |
BIN
games/raylib_demo/resources/mandrill.png
Normal file
After Width: | Height: | Size: 613 KiB |
BIN
games/raylib_demo/resources/platforms.png
Normal file
After Width: | Height: | Size: 41 KiB |
BIN
games/raylib_demo/resources/raylib_logo.png
Normal file
After Width: | Height: | Size: 3.7 KiB |
BIN
games/raylib_demo/resources/raylib_logo128x128.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
games/raylib_demo/resources/raylib_window.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
games/raylib_demo/resources/raylib_window_01.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
games/raylib_demo/resources/raylib_window_02.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
games/raylib_demo/resources/raylib_window_03.png
Normal file
After Width: | Height: | Size: 3.0 KiB |
BIN
release/html5/libraylib.bc
Normal file
506
release/html5/raylib.h
Normal file
@ -0,0 +1,506 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib 1.2 (www.raylib.com)
|
||||
*
|
||||
* A simple and easy-to-use library to learn videogames programming
|
||||
*
|
||||
* Features:
|
||||
* Library written in plain C code (C99)
|
||||
* Uses C# PascalCase/camelCase notation
|
||||
* Hardware accelerated with OpenGL (1.1, 3.3+ or ES2)
|
||||
* Unique OpenGL abstraction layer [rlgl]
|
||||
* Powerful fonts module with SpriteFonts support
|
||||
* Multiple textures support, including DDS and mipmaps generation
|
||||
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
|
||||
* Powerful math module for Vector and Matrix operations [raymath]
|
||||
* Audio loading and playing with streaming support (WAV and OGG)
|
||||
* Multiplatform support, including Android devices, Raspberry Pi and HTML5
|
||||
*
|
||||
* Used external libs:
|
||||
* GLFW3 (www.glfw.org) for window/context management and input
|
||||
* GLEW for OpenGL extensions loading (3.3+ and ES2)
|
||||
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
|
||||
* stb_image_write (Sean Barret) for image writting (PNG)
|
||||
* stb_vorbis (Sean Barret) for ogg audio loading
|
||||
* OpenAL Soft for audio device/context management
|
||||
* tinfl for data decompression (DEFLATE algorithm)
|
||||
*
|
||||
* Some design decisions:
|
||||
* 32bit Colors - All defined color are always RGBA
|
||||
* 32bit Textures - All loaded images are converted automatically to RGBA textures
|
||||
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
|
||||
* One custom default font is loaded automatically when InitWindow()
|
||||
* If using OpenGL 3.3+ or ES2, one default shader is loaded automatically (internally defined)
|
||||
*
|
||||
* -- LICENSE (raylib v1.2, September 2014) --
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
* 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 RAYLIB_H
|
||||
#define RAYLIB_H
|
||||
|
||||
// Choose your platform here or just define it at compile time: -DPLATFORM_DESKTOP
|
||||
//#define PLATFORM_DESKTOP // Windows, Linux or OSX
|
||||
//#define PLATFORM_ANDROID // Android device
|
||||
//#define PLATFORM_RPI // Raspberry Pi
|
||||
//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
|
||||
|
||||
// Security check in case no PLATFORM_* defined
|
||||
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
|
||||
#define PLATFORM_DESKTOP
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include <android_native_app_glue.h> // Defines android_app struct
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Some basic Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define DEG2RAD (PI / 180.0f)
|
||||
#define RAD2DEG (180.0f / PI)
|
||||
|
||||
// raylib Config Flags
|
||||
#define FLAG_FULLSCREEN_MODE 1
|
||||
#define FLAG_SHOW_LOGO 2
|
||||
#define FLAG_SHOW_MOUSE_CURSOR 4
|
||||
#define FLAG_CENTERED_MODE 8
|
||||
#define FLAG_MSAA_4X_HINT 16
|
||||
|
||||
// Keyboard Function Keys
|
||||
#define KEY_SPACE 32
|
||||
#define KEY_ESCAPE 256
|
||||
#define KEY_ENTER 257
|
||||
#define KEY_BACKSPACE 259
|
||||
#define KEY_RIGHT 262
|
||||
#define KEY_LEFT 263
|
||||
#define KEY_DOWN 264
|
||||
#define KEY_UP 265
|
||||
#define KEY_F1 290
|
||||
#define KEY_F2 291
|
||||
#define KEY_F3 292
|
||||
#define KEY_F4 293
|
||||
#define KEY_F5 294
|
||||
#define KEY_F6 295
|
||||
#define KEY_F7 296
|
||||
#define KEY_F8 297
|
||||
#define KEY_F9 298
|
||||
#define KEY_F10 299
|
||||
#define KEY_LEFT_SHIFT 340
|
||||
#define KEY_LEFT_CONTROL 341
|
||||
#define KEY_LEFT_ALT 342
|
||||
#define KEY_RIGHT_SHIFT 344
|
||||
#define KEY_RIGHT_CONTROL 345
|
||||
#define KEY_RIGHT_ALT 346
|
||||
|
||||
// Mouse Buttons
|
||||
#define MOUSE_LEFT_BUTTON 0
|
||||
#define MOUSE_RIGHT_BUTTON 1
|
||||
#define MOUSE_MIDDLE_BUTTON 2
|
||||
|
||||
// Gamepad Number
|
||||
#define GAMEPAD_PLAYER1 0
|
||||
#define GAMEPAD_PLAYER2 1
|
||||
#define GAMEPAD_PLAYER3 2
|
||||
#define GAMEPAD_PLAYER4 3
|
||||
|
||||
// Gamepad Buttons
|
||||
// NOTE: Adjusted for a PS3 USB Controller
|
||||
#define GAMEPAD_BUTTON_A 2
|
||||
#define GAMEPAD_BUTTON_B 1
|
||||
#define GAMEPAD_BUTTON_X 3
|
||||
#define GAMEPAD_BUTTON_Y 4
|
||||
#define GAMEPAD_BUTTON_R1 7
|
||||
#define GAMEPAD_BUTTON_R2 5
|
||||
#define GAMEPAD_BUTTON_L1 6
|
||||
#define GAMEPAD_BUTTON_L2 8
|
||||
#define GAMEPAD_BUTTON_SELECT 9
|
||||
#define GAMEPAD_BUTTON_START 10
|
||||
|
||||
// TODO: Review Xbox360 USB Controller Buttons
|
||||
|
||||
// Some Basic Colors
|
||||
// NOTE: Custom raylib color palette for amazing visuals on WHITE background
|
||||
#define LIGHTGRAY (Color){ 200, 200, 200, 255 } // Light Gray
|
||||
#define GRAY (Color){ 130, 130, 130, 255 } // Gray
|
||||
#define DARKGRAY (Color){ 80, 80, 80, 255 } // Dark Gray
|
||||
#define YELLOW (Color){ 253, 249, 0, 255 } // Yellow
|
||||
#define GOLD (Color){ 255, 203, 0, 255 } // Gold
|
||||
#define ORANGE (Color){ 255, 161, 0, 255 } // Orange
|
||||
#define PINK (Color){ 255, 109, 194, 255 } // Pink
|
||||
#define RED (Color){ 230, 41, 55, 255 } // Red
|
||||
#define MAROON (Color){ 190, 33, 55, 255 } // Maroon
|
||||
#define GREEN (Color){ 0, 228, 48, 255 } // Green
|
||||
#define LIME (Color){ 0, 158, 47, 255 } // Lime
|
||||
#define DARKGREEN (Color){ 0, 117, 44, 255 } // Dark Green
|
||||
#define SKYBLUE (Color){ 102, 191, 255, 255 } // Sky Blue
|
||||
#define BLUE (Color){ 0, 121, 241, 255 } // Blue
|
||||
#define DARKBLUE (Color){ 0, 82, 172, 255 } // Dark Blue
|
||||
#define PURPLE (Color){ 200, 122, 255, 255 } // Purple
|
||||
#define VIOLET (Color){ 135, 60, 190, 255 } // Violet
|
||||
#define DARKPURPLE (Color){ 112, 31, 126, 255 } // Dark Purple
|
||||
#define BEIGE (Color){ 211, 176, 131, 255 } // Beige
|
||||
#define BROWN (Color){ 127, 106, 79, 255 } // Brown
|
||||
#define DARKBROWN (Color){ 76, 63, 47, 255 } // Dark Brown
|
||||
|
||||
#define WHITE (Color){ 255, 255, 255, 255 } // White
|
||||
#define BLACK (Color){ 0, 0, 0, 255 } // Black
|
||||
#define BLANK (Color){ 0, 0, 0, 0 } // Blank (Transparent)
|
||||
#define MAGENTA (Color){ 255, 0, 255, 255 } // Magenta
|
||||
#define RAYWHITE (Color){ 245, 245, 245, 255 } // My own White (raylib logo)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
|
||||
// byte type
|
||||
typedef unsigned char byte;
|
||||
|
||||
// Vector2 type
|
||||
typedef struct Vector2 {
|
||||
float x;
|
||||
float y;
|
||||
} Vector2;
|
||||
|
||||
// Vector3 type
|
||||
typedef struct Vector3 {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
} Vector3;
|
||||
|
||||
// Color type, RGBA (32bit)
|
||||
typedef struct Color {
|
||||
unsigned char r;
|
||||
unsigned char g;
|
||||
unsigned char b;
|
||||
unsigned char a;
|
||||
} Color;
|
||||
|
||||
// Rectangle type
|
||||
typedef struct Rectangle {
|
||||
int x;
|
||||
int y;
|
||||
int width;
|
||||
int height;
|
||||
} Rectangle;
|
||||
|
||||
// Image type, bpp always RGBA (32bit)
|
||||
// NOTE: Data stored in CPU memory (RAM)
|
||||
typedef struct Image {
|
||||
Color *pixels;
|
||||
int width;
|
||||
int height;
|
||||
} Image;
|
||||
|
||||
// Texture2D type, bpp always RGBA (32bit)
|
||||
// NOTE: Data stored in GPU memory
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // OpenGL id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
|
||||
// Character type (one font glyph)
|
||||
typedef struct Character {
|
||||
int value; //char value = ' '; (int)value = 32;
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
} Character;
|
||||
|
||||
// SpriteFont type, includes texture and charSet array data
|
||||
typedef struct SpriteFont {
|
||||
Texture2D texture;
|
||||
int numChars;
|
||||
Character *charSet;
|
||||
} SpriteFont;
|
||||
|
||||
// Camera type, defines a camera position/orientation in 3d space
|
||||
typedef struct Camera {
|
||||
Vector3 position;
|
||||
Vector3 target;
|
||||
Vector3 up;
|
||||
} Camera;
|
||||
|
||||
// Vertex data definning a mesh
|
||||
typedef struct VertexData {
|
||||
int vertexCount;
|
||||
float *vertices; // 3 components per vertex
|
||||
float *texcoords; // 2 components per vertex
|
||||
float *normals; // 3 components per vertex
|
||||
unsigned char *colors; // 4 components per vertex
|
||||
} VertexData;
|
||||
|
||||
// 3d Model type
|
||||
// NOTE: If using OpenGL 1.1, loaded in CPU (mesh); if OpenGL 3.3+ loaded in GPU (vaoId)
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
unsigned int textureId;
|
||||
//Matrix transform;
|
||||
} Model;
|
||||
|
||||
// Sound source type
|
||||
typedef struct Sound {
|
||||
unsigned int source;
|
||||
unsigned int buffer;
|
||||
} Sound;
|
||||
|
||||
// Wave type, defines audio wave data
|
||||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//------------------------------------------------------------------------------------
|
||||
// It's lonely here...
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Window and Graphics Device Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
||||
#endif
|
||||
|
||||
void CloseWindow(void); // Close Window and Terminate Context
|
||||
bool WindowShouldClose(void); // Detect if KEY_ESCAPE pressed or Close icon pressed
|
||||
void ToggleFullscreen(void); // Fullscreen toggle (only PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
|
||||
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
|
||||
#endif
|
||||
int GetScreenWidth(void); // Get current screen width
|
||||
int GetScreenHeight(void); // Get current screen height
|
||||
int GetKeyPressed(void); // Get latest key pressed
|
||||
|
||||
void ClearBackground(Color color); // Sets Background Color
|
||||
void BeginDrawing(void); // Setup drawing canvas to start drawing
|
||||
void EndDrawing(void); // End canvas drawing and Swap Buffers (Double Buffering)
|
||||
|
||||
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
|
||||
void End3dMode(void); // Ends 3D mode and returns to default 2D orthographic mode
|
||||
|
||||
void SetTargetFPS(int fps); // Set target FPS (maximum)
|
||||
float GetFPS(void); // Returns current FPS
|
||||
float GetFrameTime(void); // Returns time in seconds for one frame
|
||||
|
||||
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
|
||||
int GetHexValue(Color color); // Returns hexadecimal value for a Color
|
||||
|
||||
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
|
||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
||||
|
||||
void SetupFlags(char flags); // Enable some window configurations
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
bool IsKeyPressed(int key); // Detect if a key has been pressed once
|
||||
bool IsKeyDown(int key); // Detect if a key is being pressed
|
||||
bool IsKeyReleased(int key); // Detect if a key has been released once
|
||||
bool IsKeyUp(int key); // Detect if a key is NOT being pressed
|
||||
|
||||
bool IsMouseButtonPressed(int button); // Detect if a mouse button has been pressed once
|
||||
bool IsMouseButtonDown(int button); // Detect if a mouse button is being pressed
|
||||
bool IsMouseButtonReleased(int button); // Detect if a mouse button has been released once
|
||||
bool IsMouseButtonUp(int button); // Detect if a mouse button is NOT being pressed
|
||||
int GetMouseX(void); // Returns mouse position X
|
||||
int GetMouseY(void); // Returns mouse position Y
|
||||
Vector2 GetMousePosition(void); // Returns mouse position XY
|
||||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
|
||||
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||
bool IsGamepadButtonDown(int gamepad, int button); // Detect if a gamepad button is being pressed
|
||||
bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad button has been released once
|
||||
bool IsGamepadButtonUp(int gamepad, int button); // Detect if a gamepad button is NOT being pressed
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
bool IsScreenTouched(void); // Detect screen touch event
|
||||
int GetTouchX(void); // Returns touch position X
|
||||
int GetTouchY(void); // Returns touch position Y
|
||||
Vector2 GetTouchPosition(void); // Returns touch position XY
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic Shapes Drawing Functions (Module: shapes)
|
||||
//------------------------------------------------------------------------------------
|
||||
void DrawPixel(int posX, int posY, Color color); // Draw a pixel
|
||||
void DrawPixelV(Vector2 position, Color color); // Draw a pixel (Vector version)
|
||||
void DrawLine(int startPosX, int startPosY, int endPosX, int endPosY, Color color); // Draw a line
|
||||
void DrawLineV(Vector2 startPos, Vector2 endPos, Color color); // Draw a line (Vector version)
|
||||
void DrawCircle(int centerX, int centerY, float radius, Color color); // Draw a color-filled circle
|
||||
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2); // Draw a gradient-filled circle
|
||||
void DrawCircleV(Vector2 center, float radius, Color color); // Draw a color-filled circle (Vector version)
|
||||
void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline
|
||||
void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle
|
||||
void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle
|
||||
void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle
|
||||
void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version)
|
||||
void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline
|
||||
void DrawTriangle(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw a color-filled triangle
|
||||
void DrawTriangleLines(Vector2 v1, Vector2 v2, Vector2 v3, Color color); // Draw triangle outline
|
||||
void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color color); // Draw a regular polygon (Vector version)
|
||||
void DrawPolyEx(Vector2 *points, int numPoints, Color color); // Draw a closed polygon defined by points
|
||||
void DrawPolyExLines(Vector2 *points, int numPoints, Color color); // Draw polygon lines
|
||||
|
||||
bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2); // Check collision between two rectangles
|
||||
bool CheckCollisionCircles(Vector2 center1, float radius1, Vector2 center2, float radius2); // Check collision between two circles
|
||||
bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec); // Check collision between circle and rectangle
|
||||
Rectangle GetCollisionRec(Rectangle rec1, Rectangle rec2); // Get collision rectangle for two rectangles collision
|
||||
bool CheckCollisionPointRec(Vector2 point, Rectangle rec); // Check if point is inside rectangle
|
||||
bool CheckCollisionPointCircle(Vector2 point, Vector2 center, float radius); // Check if point is inside circle
|
||||
bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2 p3); // Check if point is inside a triangle
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Texture Loading and Drawing Functions (Module: textures)
|
||||
//------------------------------------------------------------------------------------
|
||||
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
|
||||
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
|
||||
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
|
||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
|
||||
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
|
||||
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
|
||||
float rotation, Color tint);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Font Loading and Text Drawing Functions (Module: text)
|
||||
//------------------------------------------------------------------------------------
|
||||
SpriteFont GetDefaultFont(void); // Get the default SpriteFont
|
||||
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
|
||||
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
|
||||
|
||||
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
|
||||
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
|
||||
int fontSize, int spacing, Color tint);
|
||||
int MeasureText(const char *text, int fontSize); // Measure string width for default font
|
||||
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
|
||||
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
|
||||
void DrawFPS(int posX, int posY); // Shows current FPS on top-left corner
|
||||
const char *FormatText(const char *text, ...); // Formatting of text with variables to 'embed'
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Basic 3d Shapes Drawing Functions (Module: models)
|
||||
//------------------------------------------------------------------------------------
|
||||
void DrawCube(Vector3 position, float width, float height, float lenght, Color color); // Draw cube
|
||||
void DrawCubeV(Vector3 position, Vector3 size, Color color); // Draw cube (Vector version)
|
||||
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color); // Draw cube wires
|
||||
void DrawCubeTexture(Texture2D texture, Vector3 position, float width, float height, float lenght, Color color); // Draw cube textured
|
||||
void DrawSphere(Vector3 centerPos, float radius, Color color); // Draw sphere
|
||||
void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere with extended parameters
|
||||
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
|
||||
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
|
||||
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
|
||||
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
|
||||
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
|
||||
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
|
||||
void DrawGizmo(Vector3 position); // Draw simple gizmo
|
||||
void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale); // Draw gizmo with extended parameters
|
||||
//DrawTorus(), DrawTeapot() are useless...
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Model 3d Loading and Drawing Functions (Module: models)
|
||||
//------------------------------------------------------------------------------------
|
||||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
|
||||
void DrawModel(Model model, Vector3 position, float scale, Color tint); // Draw a model (with texture if set)
|
||||
void DrawModelEx(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color tint); // Draw a model with extended parameters
|
||||
void DrawModelWires(Model model, Vector3 position, float scale, Color color); // Draw a model wires (with texture if set)
|
||||
|
||||
void DrawBillboard(Camera camera, Texture2D texture, Vector3 center, float size, Color tint); // Draw a billboard texture
|
||||
void DrawBillboardRec(Camera camera, Texture2D texture, Rectangle sourceRec, Vector3 center, float size, Color tint); // Draw a billboard texture defined by sourceRec
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
//------------------------------------------------------------------------------------
|
||||
void InitAudioDevice(void); // Initialize audio device and context
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
||||
void UnloadSound(Sound sound); // Unload sound
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
void PauseSound(Sound sound); // Pause a sound
|
||||
void StopSound(Sound sound); // Stop playing a sound
|
||||
bool SoundIsPlaying(Sound sound); // Check if a sound is currently playing
|
||||
void SetSoundVolume(Sound sound, float volume); // Set volume for a sound (1.0 is max level)
|
||||
void SetSoundPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
|
||||
|
||||
void PlayMusicStream(char *fileName); // Start music playing (open stream)
|
||||
void StopMusicStream(void); // Stop music playing (close stream)
|
||||
void PauseMusicStream(void); // Pause music playing
|
||||
void ResumeMusicStream(void); // Resume playing paused music
|
||||
bool MusicIsPlaying(void); // Check if music is playing
|
||||
void SetMusicVolume(float volume); // Set volume for music (1.0 is max level)
|
||||
float GetMusicTimeLength(void); // Get current music time length (in seconds)
|
||||
float GetMusicTimePlayed(void); // Get current music time played (in seconds)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // RAYLIB_H
|
@ -14,7 +14,7 @@
|
||||
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
|
||||
* Powerful math module for Vector and Matrix operations [raymath]
|
||||
* Audio loading and playing with streaming support (WAV and OGG)
|
||||
* Multiplatform support, including Android devices and Raspberry Pi
|
||||
* Multiplatform support, including Android devices, Raspberry Pi and HTML5
|
||||
*
|
||||
* Used external libs:
|
||||
* GLFW3 (www.glfw.org) for window/context management and input
|
||||
@ -63,9 +63,10 @@
|
||||
//#define PLATFORM_DESKTOP // Windows, Linux or OSX
|
||||
//#define PLATFORM_ANDROID // Android device
|
||||
//#define PLATFORM_RPI // Raspberry Pi
|
||||
//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
|
||||
|
||||
// Security check in case no PLATFORM_* defined
|
||||
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI)
|
||||
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
|
||||
#define PLATFORM_DESKTOP
|
||||
#endif
|
||||
|
||||
@ -179,6 +180,9 @@
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
|
||||
// byte type
|
||||
typedef unsigned char byte;
|
||||
|
||||
// Vector2 type
|
||||
typedef struct Vector2 {
|
||||
float x;
|
||||
@ -225,8 +229,13 @@ typedef struct Texture2D {
|
||||
} Texture2D;
|
||||
|
||||
// Character type (one font glyph)
|
||||
// NOTE: Defined in module: text
|
||||
typedef struct Character Character;
|
||||
typedef struct Character {
|
||||
int value; //char value = ' '; (int)value = 32;
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
} Character;
|
||||
|
||||
// SpriteFont type, includes texture and charSet array data
|
||||
typedef struct SpriteFont {
|
||||
@ -267,6 +276,15 @@ typedef struct Sound {
|
||||
unsigned int buffer;
|
||||
} Sound;
|
||||
|
||||
// Wave type, defines audio wave data
|
||||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
@ -281,7 +299,7 @@ extern "C" { // Prevents name mangling of functions
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
||||
#endif
|
||||
|
||||
@ -294,6 +312,7 @@ void SetExitKey(int key); // Set a custom key
|
||||
#endif
|
||||
int GetScreenWidth(void); // Get current screen width
|
||||
int GetScreenHeight(void); // Get current screen height
|
||||
int GetKeyPressed(void); // Get latest key pressed
|
||||
|
||||
void ClearBackground(Color color); // Sets Background Color
|
||||
void BeginDrawing(void); // Setup drawing canvas to start drawing
|
||||
@ -313,13 +332,12 @@ int GetRandomValue(int min, int max); // Returns a random
|
||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
||||
|
||||
void SetupFlags(char flags); // Enable some window configurations
|
||||
|
||||
void ShowLogo(void); // Activates raylib logo at startup
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
bool IsKeyPressed(int key); // Detect if a key has been pressed once
|
||||
bool IsKeyDown(int key); // Detect if a key is being pressed
|
||||
bool IsKeyReleased(int key); // Detect if a key has been released once
|
||||
@ -332,8 +350,11 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
|
||||
int GetMouseX(void); // Returns mouse position X
|
||||
int GetMouseY(void); // Returns mouse position Y
|
||||
Vector2 GetMousePosition(void); // Returns mouse position XY
|
||||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
|
||||
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||
@ -386,9 +407,11 @@ Image LoadImage(const char *fileName);
|
||||
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
|
||||
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps); // Create a Texture2D from Image data (and generate mipmaps)
|
||||
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
|
||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
@ -425,6 +448,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
|
||||
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
|
||||
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
|
||||
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
|
||||
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
|
||||
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
|
||||
@ -438,7 +462,7 @@ void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale);
|
||||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
|
||||
@ -456,6 +480,7 @@ void InitAudioDevice(void); // Initialize au
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
||||
void UnloadSound(Sound sound); // Unload sound
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
|
106
src/audio.c
@ -45,9 +45,14 @@
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define MUSIC_STREAM_BUFFERS 2
|
||||
#define MUSIC_BUFFER_SIZE 4096*2 // PCM data buffer (short) - 16Kb
|
||||
// NOTE: Reduced to avoid frame-stalls on RPI
|
||||
//#define MUSIC_BUFFER_SIZE 4096*8 // PCM data buffer (short) - 64Kb
|
||||
|
||||
#if defined(PLATFORM_RPI)
|
||||
// NOTE: On RPI should be lower to avoid frame-stalls
|
||||
#define MUSIC_BUFFER_SIZE 4096*2 // PCM data buffer (short) - 16Kb (RPI)
|
||||
#else
|
||||
// NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
|
||||
#define MUSIC_BUFFER_SIZE 4096*8 // PCM data buffer (short) - 64Kb
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
@ -69,15 +74,6 @@ typedef struct Music {
|
||||
|
||||
} Music;
|
||||
|
||||
// Wave file data
|
||||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -106,7 +102,7 @@ void InitAudioDevice(void)
|
||||
// Open and initialize a device with default settings
|
||||
ALCdevice *device = alcOpenDevice(NULL);
|
||||
|
||||
if(!device) TraceLog(ERROR, "Could not open audio device");
|
||||
if(!device) TraceLog(ERROR, "Audio device could not be opened");
|
||||
|
||||
ALCcontext *context = alcCreateContext(device, NULL);
|
||||
|
||||
@ -205,12 +201,64 @@ Sound LoadSound(char *fileName)
|
||||
|
||||
// Attach sound buffer to source
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
TraceLog(INFO, "[%s] Sound file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
|
||||
// Unallocate WAV data
|
||||
UnloadWave(wave);
|
||||
|
||||
TraceLog(INFO, "[%s] Sound file loaded successfully", fileName);
|
||||
TraceLog(INFO, "[%s] Sample rate: %i - Channels: %i", fileName, wave.sampleRate, wave.channels);
|
||||
sound.source = source;
|
||||
sound.buffer = buffer;
|
||||
}
|
||||
|
||||
return sound;
|
||||
}
|
||||
|
||||
// Load sound from wave data
|
||||
Sound LoadSoundFromWave(Wave wave)
|
||||
{
|
||||
Sound sound;
|
||||
|
||||
if (wave.data != NULL)
|
||||
{
|
||||
ALenum format = 0;
|
||||
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
|
||||
if (wave.channels == 1)
|
||||
{
|
||||
if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
|
||||
else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
|
||||
}
|
||||
else if (wave.channels == 2)
|
||||
{
|
||||
if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
|
||||
else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
|
||||
}
|
||||
|
||||
// Create an audio source
|
||||
ALuint source;
|
||||
alGenSources(1, &source); // Generate pointer to audio source
|
||||
|
||||
alSourcef(source, AL_PITCH, 1);
|
||||
alSourcef(source, AL_GAIN, 1);
|
||||
alSource3f(source, AL_POSITION, 0, 0, 0);
|
||||
alSource3f(source, AL_VELOCITY, 0, 0, 0);
|
||||
alSourcei(source, AL_LOOPING, AL_FALSE);
|
||||
|
||||
// Convert loaded data to OpenAL buffer
|
||||
//----------------------------------------
|
||||
ALuint buffer;
|
||||
alGenBuffers(1, &buffer); // Generate pointer to buffer
|
||||
|
||||
// Upload sound data to buffer
|
||||
alBufferData(buffer, format, wave.data, wave.dataSize, wave.sampleRate);
|
||||
|
||||
// Attach sound buffer to source
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
// Unallocate WAV data
|
||||
UnloadWave(wave);
|
||||
|
||||
TraceLog(INFO, "[Wave] Sound file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
|
||||
sound.source = source;
|
||||
sound.buffer = buffer;
|
||||
@ -235,7 +283,10 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
||||
|
||||
FILE *rresFile = fopen(rresName, "rb");
|
||||
|
||||
if (!rresFile) TraceLog(WARNING, "[%s] Could not open raylib resource file", rresName);
|
||||
if (rresFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read rres file (basic file check - id)
|
||||
@ -327,12 +378,12 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
||||
|
||||
// Attach sound buffer to source
|
||||
alSourcei(source, AL_BUFFER, buffer);
|
||||
|
||||
TraceLog(INFO, "[%s] Sound loaded successfully from resource (SampleRate: %i, BitRate: %i, Channels: %i)", rresName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
|
||||
// Unallocate WAV data
|
||||
UnloadWave(wave);
|
||||
|
||||
TraceLog(INFO, "[%s] Sound loaded successfully from resource, sample rate: %i", rresName, (int)sampleRate);
|
||||
|
||||
sound.source = source;
|
||||
sound.buffer = buffer;
|
||||
}
|
||||
@ -447,7 +498,10 @@ void PlayMusicStream(char *fileName)
|
||||
// Open audio stream
|
||||
currentMusic.stream = stb_vorbis_open_filename(fileName, NULL, NULL);
|
||||
|
||||
if (currentMusic.stream == NULL) TraceLog(WARNING, "[%s] Could not open ogg audio file", fileName);
|
||||
if (currentMusic.stream == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] OGG audio file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Get file info
|
||||
@ -537,11 +591,13 @@ void ResumeMusicStream(void)
|
||||
// Check if music is playing
|
||||
bool MusicIsPlaying(void)
|
||||
{
|
||||
ALenum state;
|
||||
bool playing = false;
|
||||
ALint state;
|
||||
|
||||
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
|
||||
if (state == AL_PLAYING) playing = true;
|
||||
|
||||
return (state == AL_PLAYING);
|
||||
return playing;
|
||||
}
|
||||
|
||||
// Set volume for music
|
||||
@ -712,9 +768,9 @@ static Wave LoadWAV(const char *fileName)
|
||||
|
||||
wavFile = fopen(fileName, "rb");
|
||||
|
||||
if (!wavFile)
|
||||
if (wavFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] Could not open WAV file", fileName);
|
||||
TraceLog(WARNING, "[%s] WAV file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -766,7 +822,7 @@ static Wave LoadWAV(const char *fileName)
|
||||
wave.channels = waveFormat.numChannels;
|
||||
wave.bitsPerSample = waveFormat.bitsPerSample;
|
||||
|
||||
TraceLog(INFO, "[%s] Wave file loaded successfully", fileName);
|
||||
TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -815,6 +871,8 @@ static Wave LoadOGG(char *fileName)
|
||||
int samplesObtained = stb_vorbis_get_samples_short_interleaved(oggFile, info.channels, wave.data, totalSamplesLength);
|
||||
|
||||
TraceLog(DEBUG, "[%s] Samples obtained: %i", fileName, samplesObtained);
|
||||
|
||||
TraceLog(INFO, "[%s] OGG file loaded successfully (SampleRate: %i, BitRate: %i, Channels: %i)", fileName, wave.sampleRate, wave.bitsPerSample, wave.channels);
|
||||
|
||||
stb_vorbis_close(oggFile);
|
||||
|
||||
|
315
src/core.c
@ -8,6 +8,7 @@
|
||||
* PLATFORM_DESKTOP - Windows, Linux, Mac (OSX)
|
||||
* PLATFORM_ANDROID - Only OpenGL ES 2.0 devices
|
||||
* PLATFORM_RPI - Rapsberry Pi (tested on Raspbian)
|
||||
* PLATFORM_WEB - Emscripten, HTML5
|
||||
*
|
||||
* On PLATFORM_DESKTOP, the external lib GLFW3 (www.glfw.com) is used to manage graphic
|
||||
* device, OpenGL context and input on multiple operating systems (Windows, Linux, OSX).
|
||||
@ -49,7 +50,7 @@
|
||||
#include <string.h> // String function definitions, memset()
|
||||
#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management
|
||||
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
||||
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
|
||||
@ -91,7 +92,7 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// ...
|
||||
#define MAX_TOUCH_POINTS 256
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
@ -101,7 +102,7 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
static GLFWwindow *window; // Native window (graphic device)
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
static struct android_app *app; // Android activity
|
||||
@ -111,7 +112,14 @@ static bool windowReady = false; // Used to detect display initia
|
||||
|
||||
// Gestures detection variables
|
||||
static float tapTouchX, tapTouchY;
|
||||
static int64_t lastTapTime = 0;
|
||||
static float lastTapX = 0, lastTapY = 0;
|
||||
static bool touchTap = false;
|
||||
static bool doubleTap = false;
|
||||
static bool drag = false;
|
||||
static int stdVector[MAX_TOUCH_POINTS];
|
||||
static int indexPosition = 0;
|
||||
const AInputEvent* eventDrag;
|
||||
static int32_t touchId;
|
||||
const int32_t DOUBLE_TAP_TIMEOUT = 300*1000000;
|
||||
const int32_t DOUBLE_TAP_SLOP = 100;
|
||||
@ -160,12 +168,12 @@ static int renderOffsetY = 0; // Offset Y from render area (must b
|
||||
static bool fullscreen = false; // Fullscreen mode (useful only for PLATFORM_DESKTOP)
|
||||
static Matrix downscaleView; // Matrix to downscale view (in case screen size bigger than display size)
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
static const char *windowTitle; // Window text title...
|
||||
static char configFlags = 0;
|
||||
|
||||
static bool customCursor = false; // Tracks if custom cursor has been set
|
||||
static bool cursorOnScreen = true; // Tracks if cursor is inside client area
|
||||
static bool cursorOnScreen = false; // Tracks if cursor is inside client area
|
||||
static Texture2D cursor; // Cursor texture
|
||||
|
||||
static Vector2 mousePosition;
|
||||
@ -183,6 +191,7 @@ static int previousMouseWheelY = 0; // Required to track mouse wheel var
|
||||
static int currentMouseWheelY = 0; // Required to track mouse wheel variation
|
||||
|
||||
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
|
||||
static int lastKeyPressed = -1;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
@ -226,12 +235,17 @@ static void RestoreKeyboard(void); // Restore keyboard syst
|
||||
static void InitGamepad(void); // Init raw gamepad input
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
static void ErrorCallback(int error, const char *description); // GLFW3 Error Callback, runs on GLFW3 error
|
||||
static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, int mods); // GLFW3 Keyboard Callback, runs on key pressed
|
||||
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods); // GLFW3 Mouse Button Callback, runs on mouse button pressed
|
||||
static void CharCallback(GLFWwindow *window, unsigned int key); // GLFW3 Char Key Callback, runs on key pressed (get char value)
|
||||
static void ScrollCallback(GLFWwindow *window, double xoffset, double yoffset); // GLFW3 Srolling Callback, runs on mouse wheel
|
||||
static void CursorEnterCallback(GLFWwindow *window, int enter); // GLFW3 Cursor Enter Callback, cursor enters client area
|
||||
static void WindowSizeCallback(GLFWwindow *window, int width, int height); // GLFW3 WindowSize Callback, runs when window is resized
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable
|
||||
#endif
|
||||
|
||||
@ -243,7 +257,7 @@ static void CommandCallback(struct android_app *app, int32_t cmd); //
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Window and OpenGL Context Functions
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
// Initialize Window and Graphics Context (OpenGL)
|
||||
void InitWindow(int width, int height, const char *title)
|
||||
{
|
||||
@ -348,7 +362,7 @@ void CloseWindow(void)
|
||||
|
||||
rlglClose(); // De-init rlgl
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
@ -380,7 +394,7 @@ void CloseWindow(void)
|
||||
// Detect if KEY_ESCAPE pressed or Close icon pressed
|
||||
bool WindowShouldClose(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return (glfwWindowShouldClose(window));
|
||||
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
return windowShouldClose;
|
||||
@ -402,7 +416,7 @@ void ToggleFullscreen(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
// Set a custom cursor icon/image
|
||||
void SetCustomCursor(const char *cursorImage)
|
||||
{
|
||||
@ -411,6 +425,7 @@ void SetCustomCursor(const char *cursorImage)
|
||||
cursor = LoadTexture(cursorImage);
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
#endif
|
||||
customCursor = true;
|
||||
@ -436,6 +451,12 @@ int GetScreenHeight(void)
|
||||
return screenHeight;
|
||||
}
|
||||
|
||||
// Get the last key pressed
|
||||
int GetKeyPressed(void)
|
||||
{
|
||||
return lastKeyPressed;
|
||||
}
|
||||
|
||||
// Sets Background Color
|
||||
void ClearBackground(Color color)
|
||||
{
|
||||
@ -612,19 +633,13 @@ void ShowLogo(void)
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
// Detect if a key has been pressed once
|
||||
bool IsKeyPressed(int key)
|
||||
{
|
||||
bool pressed = false;
|
||||
|
||||
currentKeyState[key] = IsKeyDown(key);
|
||||
|
||||
if (currentKeyState[key] != previousKeyState[key])
|
||||
{
|
||||
if (currentKeyState[key]) pressed = true;
|
||||
previousKeyState[key] = currentKeyState[key];
|
||||
}
|
||||
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 1)) pressed = true;
|
||||
else pressed = false;
|
||||
|
||||
return pressed;
|
||||
@ -642,13 +657,7 @@ bool IsKeyReleased(int key)
|
||||
{
|
||||
bool released = false;
|
||||
|
||||
currentKeyState[key] = IsKeyUp(key);
|
||||
|
||||
if (currentKeyState[key] != previousKeyState[key])
|
||||
{
|
||||
if (currentKeyState[key]) released = true;
|
||||
previousKeyState[key] = currentKeyState[key];
|
||||
}
|
||||
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
|
||||
else released = false;
|
||||
|
||||
return released;
|
||||
@ -666,13 +675,7 @@ bool IsMouseButtonPressed(int button)
|
||||
{
|
||||
bool pressed = false;
|
||||
|
||||
currentMouseState[button] = IsMouseButtonDown(button);
|
||||
|
||||
if (currentMouseState[button] != previousMouseState[button])
|
||||
{
|
||||
if (currentMouseState[button]) pressed = true;
|
||||
previousMouseState[button] = currentMouseState[button];
|
||||
}
|
||||
if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 1)) pressed = true;
|
||||
else pressed = false;
|
||||
|
||||
return pressed;
|
||||
@ -690,13 +693,7 @@ bool IsMouseButtonReleased(int button)
|
||||
{
|
||||
bool released = false;
|
||||
|
||||
currentMouseState[button] = IsMouseButtonUp(button);
|
||||
|
||||
if (currentMouseState[button] != previousMouseState[button])
|
||||
{
|
||||
if (currentMouseState[button]) released = true;
|
||||
previousMouseState[button] = currentMouseState[button];
|
||||
}
|
||||
if ((currentMouseState[button] != previousMouseState[button]) && (currentMouseState[button] == 0)) released = true;
|
||||
else released = false;
|
||||
|
||||
return released;
|
||||
@ -727,6 +724,16 @@ Vector2 GetMousePosition(void)
|
||||
return mousePosition;
|
||||
}
|
||||
|
||||
// Set mouse position XY
|
||||
void SetMousePosition(Vector2 position)
|
||||
{
|
||||
mousePosition = position;
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetCursorPos(window, position.x, position.y);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Returns mouse wheel movement Y
|
||||
int GetMouseWheelMove(void)
|
||||
{
|
||||
@ -738,7 +745,8 @@ int GetMouseWheelMove(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: Enable gamepad usage on Rapsberr Pi
|
||||
// TODO: Enable gamepad usage on Rapsberry Pi
|
||||
// NOTE: emscripten not implemented
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Detect if a gamepad is available
|
||||
bool IsGamepadAvailable(int gamepad)
|
||||
@ -842,6 +850,18 @@ bool IsScreenTouched(void)
|
||||
return touchTap;
|
||||
}
|
||||
|
||||
bool IsDoubleTap(void)
|
||||
{
|
||||
if (doubleTap) TraceLog(INFO, "DOUBLE TAP gesture detected");
|
||||
|
||||
return doubleTap;
|
||||
}
|
||||
|
||||
bool IsDragGesture(void)
|
||||
{
|
||||
return drag;
|
||||
}
|
||||
|
||||
// Returns touch position X
|
||||
int GetTouchX(void)
|
||||
{
|
||||
@ -861,6 +881,27 @@ Vector2 GetTouchPosition(void)
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
/*bool GetPointer(Vector2 *dragPositions)
|
||||
{
|
||||
//static int stdVector[MAX_TOUCH_POINTS];
|
||||
//static int indexPosition = 0;
|
||||
//if (indexPosition == 0) return false;
|
||||
Vector2 vec_pointers_[];
|
||||
|
||||
//eventDrag
|
||||
int32_t iIndex = FindIndex( eventDrag, vec_pointers_[0] );
|
||||
|
||||
if (iIndex == -1) return false;
|
||||
|
||||
float x = AMotionEvent_getX(eventDrag, iIndex);
|
||||
float y = AMotionEvent_getY(eventDrag, iIndex);
|
||||
|
||||
*dragPositions = Vector2( x, y );
|
||||
|
||||
|
||||
return true;
|
||||
}*/
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -881,11 +922,13 @@ static void InitDisplay(int width, int height)
|
||||
// Downscale matrix is required in case desired screen area is bigger than display area
|
||||
downscaleView = MatrixIdentity();
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwSetErrorCallback(ErrorCallback);
|
||||
|
||||
if (!glfwInit()) TraceLog(ERROR, "Failed to initialize GLFW");
|
||||
|
||||
// NOTE: Getting video modes is not implemented in emscripten GLFW3 version
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// Find monitor resolution
|
||||
const GLFWvidmode *mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
|
||||
|
||||
@ -895,7 +938,11 @@ static void InitDisplay(int width, int height)
|
||||
// Screen size security check
|
||||
if (screenWidth <= 0) screenWidth = displayWidth;
|
||||
if (screenHeight <= 0) screenHeight = displayHeight;
|
||||
|
||||
#elif defined(PLATFORM_WEB)
|
||||
displayWidth = screenWidth;
|
||||
displayHeight = screenHeight;
|
||||
#endif
|
||||
|
||||
glfwDefaultWindowHints(); // Set default windows hints
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||
@ -944,7 +991,9 @@ static void InitDisplay(int width, int height)
|
||||
else
|
||||
{
|
||||
TraceLog(INFO, "Display device initialized successfully");
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
TraceLog(INFO, "Display size: %i x %i", displayWidth, displayHeight);
|
||||
#endif
|
||||
TraceLog(INFO, "Render size: %i x %i", renderWidth, renderHeight);
|
||||
TraceLog(INFO, "Screen size: %i x %i", screenWidth, screenHeight);
|
||||
TraceLog(INFO, "Viewport offsets: %i, %i", renderOffsetX, renderOffsetY);
|
||||
@ -953,6 +1002,8 @@ static void InitDisplay(int width, int height)
|
||||
glfwSetWindowSizeCallback(window, WindowSizeCallback);
|
||||
glfwSetCursorEnterCallback(window, CursorEnterCallback);
|
||||
glfwSetKeyCallback(window, KeyCallback);
|
||||
glfwSetMouseButtonCallback(window, MouseButtonCallback);
|
||||
glfwSetCharCallback(window, CharCallback);
|
||||
glfwSetScrollCallback(window, ScrollCallback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
@ -1116,7 +1167,7 @@ void InitGraphics(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// GLFW3 Error Callback, runs on GLFW3 error
|
||||
static void ErrorCallback(int error, const char *description)
|
||||
{
|
||||
@ -1138,10 +1189,31 @@ static void KeyCallback(GLFWwindow *window, int key, int scancode, int action, i
|
||||
|
||||
// NOTE: Before closing window, while loop must be left!
|
||||
}
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
else if (key == GLFW_KEY_F12 && action == GLFW_PRESS)
|
||||
{
|
||||
TakeScreenshot();
|
||||
}
|
||||
#endif
|
||||
else currentKeyState[key] = action;
|
||||
|
||||
// HACK for GuiTextBox, to deteck back key
|
||||
// TODO: Review...
|
||||
if ((key == 259) && (action == GLFW_PRESS)) lastKeyPressed = 3;
|
||||
}
|
||||
|
||||
// GLFW3 Mouse Button Callback, runs on mouse button pressed
|
||||
static void MouseButtonCallback(GLFWwindow *window, int button, int action, int mods)
|
||||
{
|
||||
currentMouseState[button] = action;
|
||||
}
|
||||
|
||||
// GLFW3 Char Key Callback, runs on key pressed (get char value)
|
||||
static void CharCallback(GLFWwindow *window, unsigned int key)
|
||||
{
|
||||
lastKeyPressed = key;
|
||||
|
||||
//TraceLog(INFO, "Char Callback Key pressed: %i\n", key);
|
||||
}
|
||||
|
||||
// GLFW3 CursorEnter Callback, when cursor enters the window
|
||||
@ -1177,6 +1249,7 @@ static int32_t InputCallback(struct android_app *app, AInputEvent *event)
|
||||
|
||||
if (type == AINPUT_EVENT_TYPE_MOTION)
|
||||
{
|
||||
// Detect TOUCH position
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
// TODO: Seems to work ok but... review!
|
||||
@ -1240,7 +1313,124 @@ static int32_t InputCallback(struct android_app *app, AInputEvent *event)
|
||||
//size_t pointerCount = AMotionEvent_getPointerCount(event);
|
||||
//float AMotionEvent_getPressure(const AInputEvent *motion_event, size_t pointer_index); // 0 to 1
|
||||
//float AMotionEvent_getSize(const AInputEvent *motion_event, size_t pointer_index); // Pressed area
|
||||
|
||||
// Detect DOUBLE TAP event
|
||||
bool tapDetected = touchTap;
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
{
|
||||
int64_t eventTime = AMotionEvent_getEventTime(event);
|
||||
|
||||
if (eventTime - lastTapTime <= DOUBLE_TAP_TIMEOUT)
|
||||
{
|
||||
float x = AMotionEvent_getX(event, 0) - lastTapX;
|
||||
float y = AMotionEvent_getY(event, 0) - lastTapY;
|
||||
|
||||
float densityFactor = 1.0f;
|
||||
|
||||
if ((x*x + y*y) < (DOUBLE_TAP_SLOP*DOUBLE_TAP_SLOP*densityFactor))
|
||||
{
|
||||
// Doubletap detected
|
||||
doubleTap = true;
|
||||
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
if (tapDetected)
|
||||
{
|
||||
lastTapTime = AMotionEvent_getEventTime(event);
|
||||
lastTapX = AMotionEvent_getX(event, 0);
|
||||
lastTapY = AMotionEvent_getY(event, 0);
|
||||
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
|
||||
// Detect DRAG event
|
||||
//int32_t action = AMotionEvent_getAction(event);
|
||||
|
||||
int32_t index = (action & AMOTION_EVENT_ACTION_POINTER_INDEX_MASK) >> AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT;
|
||||
//uint32_t flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
//event_ = event;
|
||||
|
||||
int32_t count = AMotionEvent_getPointerCount(event);
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
{
|
||||
stdVector[indexPosition] = AMotionEvent_getPointerId(event, 0);
|
||||
indexPosition++;
|
||||
TraceLog(INFO, "ACTION_DOWN");
|
||||
|
||||
//ret = GESTURE_STATE_START;
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_DOWN:
|
||||
{
|
||||
stdVector[indexPosition] = AMotionEvent_getPointerId(event, index);
|
||||
indexPosition++;
|
||||
TraceLog(INFO, "ACTION_POINTER_DOWN");
|
||||
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
//int value = stdVector[indexPosition];
|
||||
indexPosition--;
|
||||
//ret = GESTURE_STATE_END;
|
||||
TraceLog(INFO, "ACTION_UP");
|
||||
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_POINTER_UP:
|
||||
{
|
||||
int32_t releasedPointerId = AMotionEvent_getPointerId(event, index);
|
||||
|
||||
int i = 0;
|
||||
for (i = 0; i < MAX_TOUCH_POINTS; i++)
|
||||
{
|
||||
if (stdVector[i] == releasedPointerId)
|
||||
{
|
||||
for (int k = i; k < indexPosition - 1; k++)
|
||||
{
|
||||
stdVector[k] = stdVector[k + 1];
|
||||
}
|
||||
|
||||
//indexPosition--;
|
||||
indexPosition = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i <= 1)
|
||||
{
|
||||
// Reset pinch or drag
|
||||
//if (count == 2) //ret = GESTURE_STATE_START;
|
||||
}
|
||||
TraceLog(INFO, "ACTION_POINTER_UP");
|
||||
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_MOVE:
|
||||
{
|
||||
if (count == 1)
|
||||
{
|
||||
//TraceLog(INFO, "DRAG gesture detected");
|
||||
|
||||
drag = true; //ret = GESTURE_STATE_MOVE;
|
||||
}
|
||||
else break;
|
||||
TraceLog(INFO, "ACTION_MOVE");
|
||||
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_CANCEL: break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
|
||||
return 1;
|
||||
}
|
||||
else if (type == AINPUT_EVENT_TYPE_KEY)
|
||||
@ -1386,7 +1576,7 @@ static void InitTimer(void)
|
||||
// Get current time measure since InitTimer()
|
||||
static double GetTime(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return glfwGetTime();
|
||||
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
struct timespec ts;
|
||||
@ -1400,7 +1590,7 @@ static double GetTime(void)
|
||||
// Get one key state
|
||||
static bool GetKeyStatus(int key)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return glfwGetKey(window, key);
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
// TODO: Check virtual keyboard (?)
|
||||
@ -1415,7 +1605,7 @@ static bool GetKeyStatus(int key)
|
||||
// Get one mouse button state
|
||||
static bool GetMouseButtonStatus(int button)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
return glfwGetMouseButton(window, button);
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
// TODO: Check virtual keyboard (?)
|
||||
@ -1429,7 +1619,7 @@ static bool GetMouseButtonStatus(int button)
|
||||
// Poll (store) all input events
|
||||
static void PollInputEvents(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// Mouse input polling
|
||||
double mouseX;
|
||||
double mouseY;
|
||||
@ -1441,14 +1631,23 @@ static void PollInputEvents(void)
|
||||
|
||||
// Keyboard polling
|
||||
// Automatically managed by GLFW3 through callback
|
||||
|
||||
lastKeyPressed = -1;
|
||||
|
||||
// Register previous keys states
|
||||
for (int i = 0; i < 512; i++) previousKeyState[i] = currentKeyState[i];
|
||||
|
||||
// Register previous mouse states
|
||||
for (int i = 0; i < 3; i++) previousMouseState[i] = currentMouseState[i];
|
||||
|
||||
glfwPollEvents(); // Register keyboard/mouse events
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
|
||||
// TODO: Check virtual keyboard (?)
|
||||
|
||||
// Reset touchTap event
|
||||
// Reset touch events
|
||||
touchTap = false;
|
||||
doubleTap = false;
|
||||
drag = false;
|
||||
|
||||
// Poll Events (registered events)
|
||||
while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0)
|
||||
@ -1597,14 +1796,17 @@ static void PollInputEvents(void)
|
||||
static void InitMouse(void)
|
||||
{
|
||||
// NOTE: We can use /dev/input/mice to read from all available mice
|
||||
if ((mouseStream = open(DEFAULT_MOUSE_DEV, O_RDONLY|O_NONBLOCK)) < 0) TraceLog(WARNING, "Could not open mouse device, no mouse available");
|
||||
if ((mouseStream = open(DEFAULT_MOUSE_DEV, O_RDONLY|O_NONBLOCK)) < 0)
|
||||
{
|
||||
TraceLog(WARNING, "Mouse device could not be opened, no mouse available");
|
||||
}
|
||||
else
|
||||
{
|
||||
mouseReady = true;
|
||||
|
||||
int err = pthread_create(&mouseThreadId, NULL, &MouseThread, NULL);
|
||||
int error = pthread_create(&mouseThreadId, NULL, &MouseThread, NULL);
|
||||
|
||||
if (err != 0) TraceLog(WARNING, "Error creating mouse input event thread");
|
||||
if (error != 0) TraceLog(WARNING, "Error creating mouse input event thread");
|
||||
else TraceLog(INFO, "Mouse device initialized successfully");
|
||||
}
|
||||
}
|
||||
@ -1715,7 +1917,7 @@ static void RestoreKeyboard(void)
|
||||
static void InitGamepad(void)
|
||||
{
|
||||
// TODO: Gamepad support
|
||||
if ((gamepadStream = open(DEFAULT_GAMEPAD_DEV, O_RDONLY|O_NONBLOCK)) < 0) TraceLog(WARNING, "Could not open gamepad device, no gamepad available");
|
||||
if ((gamepadStream = open(DEFAULT_GAMEPAD_DEV, O_RDONLY|O_NONBLOCK)) < 0) TraceLog(WARNING, "Gamepad device could not be opened, no gamepad available");
|
||||
else TraceLog(INFO, "Gamepad device initialized successfully");
|
||||
}
|
||||
#endif
|
||||
@ -1723,7 +1925,7 @@ static void InitGamepad(void)
|
||||
// Copy back buffer to front buffers
|
||||
static void SwapBuffers(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
glfwSwapBuffers(window);
|
||||
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
eglSwapBuffers(display, surface);
|
||||
@ -1737,7 +1939,7 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
|
||||
// Calculate renderWidth and renderHeight, we have the display size (input params) and the desired screen size (global var)
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
TraceLog(WARNING, "DOWNSCALING: Required screen size (%i x %i) is bigger than display size (%i x %i)", screenWidth, screenHeight, displayWidth, displayHeight);
|
||||
TraceLog(WARNING, "DOWNSCALING: Required screen size (%ix%i) is bigger than display size (%ix%i)", screenWidth, screenHeight, displayWidth, displayHeight);
|
||||
|
||||
// Downscaling to fit display with border-bars
|
||||
float widthRatio = (float)displayWidth/(float)screenWidth;
|
||||
@ -1806,6 +2008,7 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
|
||||
// Plays raylib logo appearing animation
|
||||
static void LogoAnimation(void)
|
||||
{
|
||||
#ifndef PLATFORM_WEB
|
||||
int logoPositionX = screenWidth/2 - 128;
|
||||
int logoPositionY = screenHeight/2 - 128;
|
||||
|
||||
@ -1923,6 +2126,8 @@ static void LogoAnimation(void)
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
#endif
|
||||
|
||||
showLogo = false; // Prevent for repeating when reloading window (Android)
|
||||
}
|
||||
|
||||
|
48
src/makefile
@ -1,8 +1,6 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib for Raspberry Pi and Windows desktop
|
||||
#
|
||||
# makefile for library compilation (raylib.a)
|
||||
# raylib makefile for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,9 +21,9 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform (by default, compile for RPI)
|
||||
# Other possible platforms: PLATFORM_DESKTOP PLATFORM_DESKTOP_LINUX
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# define raylib graphics api depending on selected platform
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
@ -37,20 +35,31 @@ else
|
||||
#GRAPHICS = GRAPHICS_API_OPENGL_33 # Uncomment to use OpenGL 3.3
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
GRAPHICS = GRAPHICS_API_OPENGL_ES2
|
||||
endif
|
||||
|
||||
# NOTE: makefiles targets require tab indentation
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
# -Wall turns on most, but not all, compiler warnings
|
||||
# -std=c99 use standard C from 1999 revision
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
CFLAGS = -O1 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99 -fgnu89-inline
|
||||
CFLAGS = -O1 -Wall -std=c99
|
||||
endif
|
||||
|
||||
#CFLAGSEXTRA = -Wextra -Wmissing-prototypes -Wstrict-prototypes
|
||||
|
||||
# define any directories containing required header files
|
||||
@ -69,15 +78,20 @@ default: raylib
|
||||
|
||||
# compile raylib library
|
||||
raylib: $(OBJS)
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
emcc -O1 $(OBJS) -o libraylib.bc
|
||||
else
|
||||
ar rcs libraylib.a $(OBJS)
|
||||
endif
|
||||
|
||||
# compile core module
|
||||
# emcc core.c -o core.bc -DPLATFORM_DESKTOP
|
||||
core.o: core.c
|
||||
$(CC) -c core.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
$(CC) -c core.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile rlgl module
|
||||
rlgl.o: rlgl.c
|
||||
$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(GRAPHICS)
|
||||
$(CC) -c rlgl.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile raymath module
|
||||
raymath.o: raymath.c
|
||||
@ -85,19 +99,19 @@ raymath.o: raymath.c
|
||||
|
||||
# compile shapes module
|
||||
shapes.o: shapes.c
|
||||
$(CC) -c shapes.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
$(CC) -c shapes.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile textures module
|
||||
textures.o: textures.c
|
||||
$(CC) -c textures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
$(CC) -c textures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile text module
|
||||
text.o: text.c
|
||||
$(CC) -c text.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
$(CC) -c text.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile models module
|
||||
models.o: models.c
|
||||
$(CC) -c models.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
$(CC) -c models.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -D$(GRAPHICS)
|
||||
|
||||
# compile audio module
|
||||
audio.o: audio.c
|
||||
@ -119,9 +133,13 @@ else
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP_LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o libraylib.a
|
||||
else
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o libraylib.bc
|
||||
else
|
||||
del *.o libraylib.a
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
93
src/models.c
@ -50,7 +50,7 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// It's lonely here...
|
||||
extern unsigned int whiteTexture;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
@ -66,14 +66,14 @@ static VertexData LoadOBJ(const char *fileName);
|
||||
// NOTE: Cube position is the center position
|
||||
void DrawCube(Vector3 position, float width, float height, float lenght, Color color)
|
||||
{
|
||||
float x = position.x;
|
||||
float y = position.y;
|
||||
float z = position.z;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
|
||||
rlPushMatrix();
|
||||
|
||||
// NOTE: Be careful! Function order matters (rotate -> scale -> translate)
|
||||
//rlTranslatef(0.0f, 0.0f, 0.0f);
|
||||
rlTranslatef(position.x, position.y, position.z);
|
||||
//rlScalef(2.0f, 2.0f, 2.0f);
|
||||
//rlRotatef(45, 0, 1, 0);
|
||||
|
||||
@ -146,12 +146,13 @@ void DrawCubeV(Vector3 position, Vector3 size, Color color)
|
||||
// Draw cube wires
|
||||
void DrawCubeWires(Vector3 position, float width, float height, float lenght, Color color)
|
||||
{
|
||||
float x = position.x;
|
||||
float y = position.y;
|
||||
float z = position.z;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
|
||||
rlPushMatrix();
|
||||
|
||||
rlTranslatef(position.x, position.y, position.z);
|
||||
//rlRotatef(45, 0, 1, 0);
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
@ -445,11 +446,37 @@ void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, fl
|
||||
rlPopMatrix();
|
||||
}
|
||||
|
||||
// Draw a quad
|
||||
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4])
|
||||
{
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(colors[0].r, colors[0].g, colors[0].b, colors[0].a);
|
||||
rlNormal3f(normals[0].x, normals[0].y, normals[0].z);
|
||||
rlTexCoord2f(textcoords[0].x, textcoords[0].y);
|
||||
rlVertex3f(vertices[0].x, vertices[0].y, vertices[0].z);
|
||||
|
||||
rlColor4ub(colors[1].r, colors[1].g, colors[1].b, colors[1].a);
|
||||
rlNormal3f(normals[1].x, normals[1].y, normals[1].z);
|
||||
rlTexCoord2f(textcoords[1].x, textcoords[1].y);
|
||||
rlVertex3f(vertices[1].x, vertices[1].y, vertices[1].z);
|
||||
|
||||
rlColor4ub(colors[2].r, colors[2].g, colors[2].b, colors[2].a);
|
||||
rlNormal3f(normals[2].x, normals[2].y, normals[2].z);
|
||||
rlTexCoord2f(textcoords[2].x, textcoords[2].y);
|
||||
rlVertex3f(vertices[2].x, vertices[2].y, vertices[2].z);
|
||||
|
||||
rlColor4ub(colors[3].r, colors[3].g, colors[3].b, colors[3].a);
|
||||
rlNormal3f(normals[3].x, normals[3].y, normals[3].z);
|
||||
rlTexCoord2f(textcoords[3].x, textcoords[3].y);
|
||||
rlVertex3f(vertices[3].x, vertices[3].y, vertices[3].z);
|
||||
rlEnd();
|
||||
}
|
||||
|
||||
// Draw a plane
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
|
||||
{
|
||||
// NOTE: QUADS usage require defining a texture on OpenGL 3.3+
|
||||
rlEnableTexture(1); // Default white texture
|
||||
if (rlGetVersion() != OPENGL_11) rlEnableTexture(whiteTexture); // Default white texture
|
||||
|
||||
// NOTE: Plane is always created on XZ ground and then rotated
|
||||
rlPushMatrix();
|
||||
@ -471,7 +498,7 @@ void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color)
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
|
||||
rlDisableTexture();
|
||||
if (rlGetVersion() != OPENGL_11) rlDisableTexture();
|
||||
}
|
||||
|
||||
// Draw a plane with divisions
|
||||
@ -743,7 +770,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||
vData.texcoords[tcCounter + 7] = vData.texcoords[tcCounter + 5];
|
||||
|
||||
vData.texcoords[tcCounter + 8] = vData.texcoords[tcCounter + 2];
|
||||
vData.texcoords[tcCounter + 9] = vData.texcoords[tcCounter + 1];
|
||||
vData.texcoords[tcCounter + 9] = vData.texcoords[tcCounter + 3];
|
||||
|
||||
vData.texcoords[tcCounter + 10] = (float)(x+1) / (mapX-1);
|
||||
vData.texcoords[tcCounter + 11] = (float)(z+1) / (mapZ-1);
|
||||
@ -785,7 +812,7 @@ Model LoadHeightmap(Image heightmap, float maxHeight)
|
||||
}
|
||||
|
||||
// Load a map image as a 3d model (cubes based)
|
||||
Model LoadCubesmap(Image cubesmap)
|
||||
Model LoadCubicmap(Image cubesmap)
|
||||
{
|
||||
VertexData vData;
|
||||
|
||||
@ -1041,8 +1068,6 @@ Model LoadCubesmap(Image cubesmap)
|
||||
// Move data from mapVertices temp arays to vertices float array
|
||||
vData.vertexCount = vCounter;
|
||||
|
||||
printf("Vertex count: %i\n", vCounter);
|
||||
|
||||
vData.vertices = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.normals = (float *)malloc(vData.vertexCount * 3 * sizeof(float));
|
||||
vData.texcoords = (float *)malloc(vData.vertexCount * 2 * sizeof(float));
|
||||
@ -1263,6 +1288,12 @@ static VertexData LoadOBJ(const char *fileName)
|
||||
FILE *objFile;
|
||||
|
||||
objFile = fopen(fileName, "rt");
|
||||
|
||||
if (objFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] OBJ file could not be opened", fileName);
|
||||
return vData;
|
||||
}
|
||||
|
||||
// First reading pass: Get numVertex, numNormals, numTexCoords, numTriangles
|
||||
// NOTE: vertex, texcoords and normals could be optimized (to be used indexed on faces definition)
|
||||
@ -1490,4 +1521,36 @@ static VertexData LoadOBJ(const char *fileName)
|
||||
TraceLog(INFO, "[%s] Model loaded successfully in RAM (CPU)", fileName);
|
||||
|
||||
return vData;
|
||||
}
|
||||
}
|
||||
|
||||
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2)
|
||||
{
|
||||
/*
|
||||
// Get min and max vertex to construct bounds (AABB)
|
||||
Vector3 minVertex = tempVertices[0];
|
||||
Vector3 maxVertex = tempVertices[0];
|
||||
|
||||
for (int i = 1; i < tempVertices.Count; i++)
|
||||
{
|
||||
minVertex = Vector3.Min(minVertex, tempVertices[i]);
|
||||
maxVertex = Vector3.Max(maxVertex, tempVertices[i]);
|
||||
}
|
||||
|
||||
bounds = new BoundingBox(minVertex, maxVertex);
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, Vector3 radiusSphere)
|
||||
{
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//BoundingBox GetCollisionArea(BoundingBox box1, BoundingBox box2)
|
33
src/raylib.h
@ -14,7 +14,7 @@
|
||||
* Basic 3d support for Shapes, Models, Heightmaps and Billboards
|
||||
* Powerful math module for Vector and Matrix operations [raymath]
|
||||
* Audio loading and playing with streaming support (WAV and OGG)
|
||||
* Multiplatform support, including Android devices and Raspberry Pi
|
||||
* Multiplatform support, including Android devices, Raspberry Pi and HTML5
|
||||
*
|
||||
* Used external libs:
|
||||
* GLFW3 (www.glfw.org) for window/context management and input
|
||||
@ -63,9 +63,10 @@
|
||||
//#define PLATFORM_DESKTOP // Windows, Linux or OSX
|
||||
//#define PLATFORM_ANDROID // Android device
|
||||
//#define PLATFORM_RPI // Raspberry Pi
|
||||
//#define PLATFORM_WEB // HTML5 (emscripten, asm.js)
|
||||
|
||||
// Security check in case no PLATFORM_* defined
|
||||
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI)
|
||||
#if !defined(PLATFORM_DESKTOP) && !defined(PLATFORM_ANDROID) && !defined(PLATFORM_RPI) && !defined(PLATFORM_WEB)
|
||||
#define PLATFORM_DESKTOP
|
||||
#endif
|
||||
|
||||
@ -275,6 +276,15 @@ typedef struct Sound {
|
||||
unsigned int buffer;
|
||||
} Sound;
|
||||
|
||||
// Wave type, defines audio wave data
|
||||
typedef struct Wave {
|
||||
void *data; // Buffer data pointer
|
||||
unsigned int dataSize; // Data size in bytes
|
||||
unsigned int sampleRate;
|
||||
short bitsPerSample;
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
@ -289,7 +299,7 @@ extern "C" { // Prevents name mangling of functions
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitWindow(int width, int height, struct android_app *state); // Init Android activity
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#elif defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
void InitWindow(int width, int height, const char *title); // Initialize Window and OpenGL Graphics
|
||||
#endif
|
||||
|
||||
@ -302,6 +312,7 @@ void SetExitKey(int key); // Set a custom key
|
||||
#endif
|
||||
int GetScreenWidth(void); // Get current screen width
|
||||
int GetScreenHeight(void); // Get current screen height
|
||||
int GetKeyPressed(void); // Get latest key pressed
|
||||
|
||||
void ClearBackground(Color color); // Sets Background Color
|
||||
void BeginDrawing(void); // Setup drawing canvas to start drawing
|
||||
@ -321,13 +332,12 @@ int GetRandomValue(int min, int max); // Returns a random
|
||||
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0f to 1.0f
|
||||
|
||||
void SetupFlags(char flags); // Enable some window configurations
|
||||
|
||||
void ShowLogo(void); // Activates raylib logo at startup
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
bool IsKeyPressed(int key); // Detect if a key has been pressed once
|
||||
bool IsKeyDown(int key); // Detect if a key is being pressed
|
||||
bool IsKeyReleased(int key); // Detect if a key has been released once
|
||||
@ -340,8 +350,11 @@ bool IsMouseButtonUp(int button); // Detect if a mouse but
|
||||
int GetMouseX(void); // Returns mouse position X
|
||||
int GetMouseY(void); // Returns mouse position Y
|
||||
Vector2 GetMousePosition(void); // Returns mouse position XY
|
||||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
bool IsGamepadAvailable(int gamepad); // Detect if a gamepad is available
|
||||
Vector2 GetGamepadMovement(int gamepad); // Return axis movement vector for a gamepad
|
||||
bool IsGamepadButtonPressed(int gamepad, int button); // Detect if a gamepad button has been pressed once
|
||||
@ -394,9 +407,11 @@ Image LoadImage(const char *fileName);
|
||||
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
|
||||
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps); // Create a Texture2D from Image data (and generate mipmaps)
|
||||
Texture2D LoadTextureFromImage(Image image, bool genMipmaps); // Load a texture from image data (and generate mipmaps)
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps); // [DEPRECATED] Same as LoadTextureFromImage()
|
||||
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
|
||||
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
|
||||
void ConvertToPOT(Image *image, Color fillColor); // Convert image to POT (power-of-two)
|
||||
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
|
||||
void DrawTextureV(Texture2D texture, Vector2 position, Color tint); // Draw a Texture2D with position defined as Vector2
|
||||
@ -433,6 +448,7 @@ void DrawSphereEx(Vector3 centerPos, float radius, int rings, int slices, Color
|
||||
void DrawSphereWires(Vector3 centerPos, float radius, int rings, int slices, Color color); // Draw sphere wires
|
||||
void DrawCylinder(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone
|
||||
void DrawCylinderWires(Vector3 position, float radiusTop, float radiusBottom, float height, int slices, Color color); // Draw a cylinder/cone wires
|
||||
void DrawQuad(Vector3 vertices[4], Vector2 textcoords[4], Vector3 normals[4], Color colors[4]); // Draw a quad
|
||||
void DrawPlane(Vector3 centerPos, Vector2 size, Vector3 rotation, Color color); // Draw a plane
|
||||
void DrawPlaneEx(Vector3 centerPos, Vector2 size, Vector3 rotation, int slicesX, int slicesZ, Color color); // Draw a plane with divisions
|
||||
void DrawGrid(int slices, float spacing); // Draw a grid (centered at (0, 0, 0))
|
||||
@ -446,7 +462,7 @@ void DrawGizmoEx(Vector3 position, Vector3 rotation, float scale);
|
||||
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
|
||||
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
|
||||
Model LoadHeightmap(Image heightmap, float maxHeight); // Load a heightmap image as a 3d model
|
||||
Model LoadCubesmap(Image cubesmap); // Load a map image as a 3d model (cubes based)
|
||||
Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
void UnloadModel(Model model); // Unload 3d model from memory
|
||||
void SetModelTexture(Model *model, Texture2D texture); // Link a texture to a model
|
||||
|
||||
@ -464,6 +480,7 @@ void InitAudioDevice(void); // Initialize au
|
||||
void CloseAudioDevice(void); // Close the audio device and context (and music stream)
|
||||
|
||||
Sound LoadSound(char *fileName); // Load sound to memory
|
||||
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
||||
void UnloadSound(Sound sound); // Unload sound
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
|
@ -329,8 +329,6 @@ void MatrixInvert(Matrix *mat)
|
||||
// Calculate the invert determinant (inlined to avoid double-caching)
|
||||
float invDet = 1/(b00*b11 - b01*b10 + b02*b09 + b03*b08 - b04*b07 + b05*b06);
|
||||
|
||||
printf("%f\n", invDet);
|
||||
|
||||
temp.m0 = (a11*b11 - a12*b10 + a13*b09)*invDet;
|
||||
temp.m1 = (-a01*b11 + a02*b10 - a03*b09)*invDet;
|
||||
temp.m2 = (a31*b05 - a32*b04 + a33*b03)*invDet;
|
||||
@ -492,6 +490,48 @@ Matrix MatrixRotate(float angleX, float angleY, float angleZ)
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Matrix MatrixRotate(float angle, float x, float y, float z)
|
||||
{
|
||||
Matrix result = MatrixIdentity();
|
||||
|
||||
float c = cosf(angle*DEG2RAD); // cosine
|
||||
float s = sinf(angle*DEG2RAD); // sine
|
||||
float c1 = 1.0f - c; // 1 - c
|
||||
|
||||
float m0 = result.m0, m4 = result.m4, m8 = result.m8, m12 = result.m12,
|
||||
m1 = result.m1, m5 = result.m5, m9 = result.m9, m13 = result.m13,
|
||||
m2 = result.m2, m6 = result.m6, m10 = result.m10, m14 = result.m14;
|
||||
|
||||
// build rotation matrix
|
||||
float r0 = x * x * c1 + c;
|
||||
float r1 = x * y * c1 + z * s;
|
||||
float r2 = x * z * c1 - y * s;
|
||||
float r4 = x * y * c1 - z * s;
|
||||
float r5 = y * y * c1 + c;
|
||||
float r6 = y * z * c1 + x * s;
|
||||
float r8 = x * z * c1 + y * s;
|
||||
float r9 = y * z * c1 - x * s;
|
||||
float r10= z * z * c1 + c;
|
||||
|
||||
// multiply rotation matrix
|
||||
result.m0 = r0*m0 + r4*m1 + r8*m2;
|
||||
result.m1 = r1*m0 + r5*m1 + r9*m2;
|
||||
result.m2 = r2*m0 + r6*m1 + r10*m2;
|
||||
result.m4 = r0*m4 + r4*m5 + r8*m6;
|
||||
result.m5 = r1*m4 + r5*m5 + r9*m6;
|
||||
result.m6 = r2*m4 + r6*m5 + r10*m6;
|
||||
result.m8 = r0*m8 + r4*m9 + r8*m10;
|
||||
result.m9 = r1*m8 + r5*m9 + r9*m10;
|
||||
result.m10 = r2*m8 + r6*m9 + r10*m10;
|
||||
result.m12 = r0*m12+ r4*m13 + r8*m14;
|
||||
result.m13 = r1*m12+ r5*m13 + r9*m14;
|
||||
result.m14 = r2*m12+ r6*m13 + r10*m14;
|
||||
|
||||
return result;
|
||||
}
|
||||
*/
|
||||
|
||||
// Create rotation matrix from axis and angle
|
||||
// TODO: Test this function
|
||||
// NOTE: NO prototype defined!
|
||||
@ -559,8 +599,8 @@ Matrix MatrixFromAxisAngle2(Vector3 axis, float angle)
|
||||
float axisX = axis.x, axisY = axis.y, axisZ = axis.y;
|
||||
|
||||
// Calculate angles
|
||||
float cosres = (float)cos(-angle);
|
||||
float sinres = (float)sin(-angle);
|
||||
float cosres = (float)cos(angle);
|
||||
float sinres = (float)sin(angle);
|
||||
float t = 1.0f - cosres;
|
||||
|
||||
// Do the conversion math once
|
||||
@ -668,6 +708,7 @@ Matrix MatrixScale(float x, float y, float z)
|
||||
|
||||
// Returns transformation matrix for a given translation, rotation and scale
|
||||
// NOTE: Transformation order is rotation -> scale -> translation
|
||||
// NOTE: Rotation angles should come in radians
|
||||
Matrix MatrixTransform(Vector3 translation, Vector3 rotation, Vector3 scale)
|
||||
{
|
||||
Matrix result = MatrixIdentity();
|
||||
|
@ -55,7 +55,7 @@
|
||||
} Vector3;
|
||||
#endif
|
||||
|
||||
// Matrix type (OpenGL style 4x4 - right handed)
|
||||
// Matrix type (OpenGL style 4x4 - right handed, column major)
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12;
|
||||
float m1, m5, m9, m13;
|
||||
@ -107,9 +107,9 @@ Matrix MatrixIdentity(void); // Returns identity matr
|
||||
Matrix MatrixAdd(Matrix left, Matrix right); // Add two matrices
|
||||
Matrix MatrixSubstract(Matrix left, Matrix right); // Substract two matrices (left - right)
|
||||
Matrix MatrixTranslate(float x, float y, float z); // Returns translation matrix
|
||||
Matrix MatrixRotate(float angleX, float angleY, float angleZ); // Returns rotation matrix
|
||||
Matrix MatrixRotateAroundAxis(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis
|
||||
Matrix MatrixRotateAroundAxis2(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (test another implemntation)
|
||||
Matrix MatrixRotate(float axisX, float axisY, float axisZ); // Returns rotation matrix
|
||||
Matrix MatrixFromAxisAngle(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis
|
||||
Matrix MatrixFromAxisAngle2(Vector3 axis, float angle); // Returns rotation matrix for an angle around an specified axis (test another implemntation)
|
||||
Matrix MatrixFromQuaternion(Quaternion q); // Returns rotation matrix for a given quaternion
|
||||
Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
|
||||
Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
|
||||
|
70
src/rlgl.c
@ -168,21 +168,23 @@ static Vector3 *tempBuffer;
|
||||
static int tempBufferCount = 0;
|
||||
static bool useTempBuffer = false;
|
||||
|
||||
// White texture useful for plain color polys (required by shader)
|
||||
static GLuint whiteTexture;
|
||||
|
||||
// Support for VAOs (OpenGL ES2 could not support VAO extensions)
|
||||
static bool vaoSupported = false;
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: VAO functionality is exposed through extensions (OES)
|
||||
// emscripten does not support VAOs
|
||||
static PFNGLGENVERTEXARRAYSOESPROC glGenVertexArrays;
|
||||
static PFNGLBINDVERTEXARRAYOESPROC glBindVertexArray;
|
||||
static PFNGLDELETEVERTEXARRAYSOESPROC glDeleteVertexArrays;
|
||||
static PFNGLISVERTEXARRAYOESPROC glIsVertexArray;
|
||||
#endif
|
||||
|
||||
// White texture useful for plain color polys (required by shader)
|
||||
// NOTE: It's required in shapes and models modules!
|
||||
unsigned int whiteTexture;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -298,10 +300,21 @@ void rlRotatef(float angleDeg, float x, float y, float z)
|
||||
// TODO: Support rotation in multiple axes
|
||||
Matrix rot = MatrixIdentity();
|
||||
|
||||
// OPTION 1: It works...
|
||||
if (x == 1) rot = MatrixRotateX(angleDeg*DEG2RAD);
|
||||
else if (y == 1) rot = MatrixRotateY(angleDeg*DEG2RAD);
|
||||
else if (z == 1) rot = MatrixRotateZ(angleDeg*DEG2RAD);
|
||||
|
||||
|
||||
// OPTION 2: Requires review...
|
||||
//Vector3 vec = (Vector3){ 0, 1, 0 };
|
||||
//VectorNormalize(&vec);
|
||||
//rot = MatrixFromAxisAngle(vec, angleDeg*DEG2RAD); // Working?
|
||||
|
||||
// OPTION 3: TODO: Review, it doesn't work!
|
||||
//Vector3 vec = (Vector3){ x, y, z };
|
||||
//VectorNormalize(&vec);
|
||||
//rot = MatrixRotate(angleDeg*vec.x, angleDeg*vec.x, angleDeg*vec.x);
|
||||
|
||||
MatrixTranspose(&rot);
|
||||
|
||||
*currentMatrix = MatrixMultiply(*currentMatrix, rot);
|
||||
@ -760,10 +773,13 @@ void rlglInit(void)
|
||||
#endif
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: emscripten does not support VAOs natively, it uses emulation and it reduces overall performance...
|
||||
#if !defined(PLATFORM_WEB)
|
||||
glGenVertexArrays = (PFNGLGENVERTEXARRAYSOESPROC)eglGetProcAddress("glGenVertexArraysOES");
|
||||
glBindVertexArray = (PFNGLBINDVERTEXARRAYOESPROC)eglGetProcAddress("glBindVertexArrayOES");
|
||||
glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSOESPROC)eglGetProcAddress("glDeleteVertexArraysOES");
|
||||
glIsVertexArray = (PFNGLISVERTEXARRAYOESPROC)eglGetProcAddress("glIsVertexArrayOES");
|
||||
#endif
|
||||
|
||||
if (glGenVertexArrays == NULL) TraceLog(WARNING, "Could not initialize VAO extensions, VAOs not supported");
|
||||
else
|
||||
@ -848,8 +864,8 @@ void rlglInit(void)
|
||||
|
||||
whiteTexture = rlglLoadTexture(pixels, 1, 1, false);
|
||||
|
||||
if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture created successfully", whiteTexture);
|
||||
else TraceLog(WARNING, "Base white texture could not be created");
|
||||
if (whiteTexture != 0) TraceLog(INFO, "[TEX ID %i] Base white texture loaded successfully", whiteTexture);
|
||||
else TraceLog(WARNING, "Base white texture could not be loaded");
|
||||
|
||||
// Init draw calls tracking system
|
||||
draws = (DrawCall *)malloc(sizeof(DrawCall)*MAX_DRAWS_BY_TEXTURE);
|
||||
@ -1113,6 +1129,8 @@ void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scal
|
||||
#if defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
glUseProgram(shaderProgram); // Use our shader
|
||||
|
||||
VectorScale(&rotation, DEG2RAD);
|
||||
|
||||
// Get transform matrix (rotation -> scale -> translation)
|
||||
Matrix transform = MatrixTransform(position, rotation, scale);
|
||||
Matrix modelviewworld = MatrixMultiply(transform, modelview);
|
||||
@ -1305,7 +1323,8 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, bool ge
|
||||
|
||||
#if defined(GRAPHICS_API_OPENGL_33)
|
||||
// NOTE: We define internal (GPU) format as GL_RGBA8 (probably BGRA8 in practice, driver takes care)
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
//glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // OpenGL
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // WebGL
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: On embedded systems, we let the driver choose the best internal format
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
|
||||
@ -1324,7 +1343,7 @@ unsigned int rlglLoadTexture(unsigned char *data, int width, int height, bool ge
|
||||
// Unbind current texture
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
TraceLog(INFO, "[TEX ID %i] Texture created successfully (%i x %i)", id, width, height);
|
||||
TraceLog(INFO, "[TEX ID %i] Texture created successfully (%ix%i)", id, width, height);
|
||||
|
||||
return id;
|
||||
}
|
||||
@ -1347,7 +1366,7 @@ Model rlglLoadModel(VertexData mesh)
|
||||
#elif defined(GRAPHICS_API_OPENGL_33) || defined(GRAPHICS_API_OPENGL_ES2)
|
||||
model.textureId = 1; // Default whiteTexture
|
||||
|
||||
GLuint vaoModel; // Vertex Array Objects (VAO)
|
||||
GLuint vaoModel = 0; // Vertex Array Objects (VAO)
|
||||
GLuint vertexBuffer[3]; // Vertex Buffer Objects (VBO)
|
||||
|
||||
if (vaoSupported)
|
||||
@ -1562,6 +1581,7 @@ static GLuint LoadDefaultShaders(void)
|
||||
char fShaderStr[] = " #version 110 \n" // NOTE: Equivalent to version 100 on ES2
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
char fShaderStr[] = " #version 100 \n" // NOTE: Must be defined this way! 110 doesn't work!
|
||||
"precision mediump float; \n" // WebGL, required for emscripten
|
||||
#endif
|
||||
"uniform sampler2D texture0; \n"
|
||||
"varying vec2 fragTexCoord; \n"
|
||||
@ -1673,33 +1693,35 @@ static GLuint LoadShaders(char *vertexFileName, char *fragmentFileName)
|
||||
}
|
||||
|
||||
// Read shader text file
|
||||
static char *TextFileRead(char *fn)
|
||||
static char *TextFileRead(char *fileName)
|
||||
{
|
||||
FILE *fp;
|
||||
FILE *textFile;
|
||||
char *text = NULL;
|
||||
|
||||
int count=0;
|
||||
|
||||
if (fn != NULL)
|
||||
if (fileName != NULL)
|
||||
{
|
||||
fp = fopen(fn,"rt");
|
||||
textFile = fopen(fileName,"rt");
|
||||
|
||||
if (fp != NULL)
|
||||
if (textFile != NULL)
|
||||
{
|
||||
fseek(fp, 0, SEEK_END);
|
||||
count = ftell(fp);
|
||||
rewind(fp);
|
||||
fseek(textFile, 0, SEEK_END);
|
||||
count = ftell(textFile);
|
||||
rewind(textFile);
|
||||
|
||||
if (count > 0)
|
||||
{
|
||||
text = (char *)malloc(sizeof(char) * (count+1));
|
||||
count = fread(text, sizeof(char), count, fp);
|
||||
count = fread(text, sizeof(char), count, textFile);
|
||||
text[count] = '\0';
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
fclose(textFile);
|
||||
}
|
||||
else TraceLog(WARNING, "[%s] Text file could not be opened", fileName);
|
||||
}
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
@ -1798,7 +1820,7 @@ static void InitializeBuffersGPU(void)
|
||||
glGenVertexArrays(1, &vaoTriangles);
|
||||
glBindVertexArray(vaoTriangles);
|
||||
}
|
||||
|
||||
|
||||
// Create buffers for our vertex data
|
||||
glGenBuffers(2, trianglesBuffer);
|
||||
|
||||
@ -1823,7 +1845,7 @@ static void InitializeBuffersGPU(void)
|
||||
glGenVertexArrays(1, &vaoQuads);
|
||||
glBindVertexArray(vaoQuads);
|
||||
}
|
||||
|
||||
|
||||
// Create buffers for our vertex data
|
||||
glGenBuffers(4, quadsBuffer);
|
||||
|
||||
@ -1859,6 +1881,8 @@ static void InitializeBuffersGPU(void)
|
||||
}
|
||||
|
||||
// Update VBOs with vertex array data
|
||||
// TODO: If there is not vertex data, buffers doesn't need to be updated (vertexCount > 0)
|
||||
// TODO: If no data changed on the CPU arrays --> No need to update GPU arrays every frame!
|
||||
static void UpdateBuffers(void)
|
||||
{
|
||||
// Activate Lines VAO
|
||||
@ -1973,7 +1997,7 @@ static int GenerateMipmaps(unsigned char *data, int baseWidth, int baseHeight)
|
||||
j++;
|
||||
}
|
||||
|
||||
TraceLog(DEBUG, "Mipmap base (%i, %i)", width, height);
|
||||
TraceLog(DEBUG, "Mipmap base (%ix%i)", width, height);
|
||||
|
||||
for (int mip = 1; mip < mipmapCount; mip++)
|
||||
{
|
||||
@ -2044,7 +2068,7 @@ static pixel *GenNextMipmap(pixel *srcData, int srcWidth, int srcHeight)
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(DEBUG, "Mipmap generated successfully (%i, %i)", width, height);
|
||||
TraceLog(DEBUG, "Mipmap generated successfully (%ix%i)", width, height);
|
||||
|
||||
return mipmap;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
// Choose opengl version here or just define it at compile time: -DGRAPHICS_API_OPENGL_33
|
||||
//#define GRAPHICS_API_OPENGL_11 // Only available on PLATFORM_DESKTOP
|
||||
//#define GRAPHICS_API_OPENGL_33 // Only available on PLATFORM_DESKTOP
|
||||
//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI
|
||||
//#define GRAPHICS_API_OPENGL_ES2 // Only available on PLATFORM_ANDROID or PLATFORM_RPI or PLATFORM_WEB
|
||||
|
||||
// Security check in case no GRAPHICS_API_OPENGL_* defined
|
||||
#if !defined(GRAPHICS_API_OPENGL_11) && !defined(GRAPHICS_API_OPENGL_33) && !defined(GRAPHICS_API_OPENGL_ES2)
|
||||
@ -72,8 +72,9 @@
|
||||
#define MAX_TRIANGLES_BATCH 4096
|
||||
#define MAX_QUADS_BATCH 4096
|
||||
#elif defined(GRAPHICS_API_OPENGL_ES2)
|
||||
// NOTE: Reduce memory sizes for embedded systems (RPI)
|
||||
#define MAX_LINES_BATCH 2048 // Critical for wire shapes (sphere)
|
||||
// NOTE: Reduce memory sizes for embedded systems (RPI and HTML5)
|
||||
// NOTE: On HTML5 (emscripten) this is allocated on heap, by default it's only 16MB!...just take care...
|
||||
#define MAX_LINES_BATCH 1024 // Critical for wire shapes (sphere)
|
||||
#define MAX_TRIANGLES_BATCH 2048 // Critical for some shapes (sphere)
|
||||
#define MAX_QUADS_BATCH 1024 // Be careful with text, every letter maps a quad
|
||||
#endif
|
||||
|
@ -44,7 +44,7 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
// It's lonely here...
|
||||
extern unsigned int whiteTexture;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
@ -197,7 +197,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||
else if ((rlGetVersion() == OPENGL_33) || (rlGetVersion() == OPENGL_ES_20))
|
||||
{
|
||||
// NOTE: This shape uses QUADS to avoid drawing order issues (view rlglDraw)
|
||||
rlEnableTexture(1); // Default white texture
|
||||
rlEnableTexture(whiteTexture); // Default white texture
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
2824
src/stb_image.h
204
src/text.c
@ -63,7 +63,6 @@ static SpriteFont defaultFont; // Default font provided by raylib
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool PixelIsMagenta(Color p); // Check if a pixel is magenta
|
||||
static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Character **charSet); // Parse image pixel data to obtain character set measures
|
||||
static int GetNextPOT(int num); // Calculate next power-of-two value for a given value
|
||||
static SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
||||
|
||||
extern void LoadDefaultFont(void);
|
||||
@ -135,7 +134,7 @@ extern void LoadDefaultFont(void)
|
||||
if (counter > 256) counter = 0; // Security check...
|
||||
}
|
||||
|
||||
defaultFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
|
||||
defaultFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
UnloadImage(image);
|
||||
|
||||
// Reconstruct charSet using charsWidth[], charsHeight, charsDivisor, numChars
|
||||
@ -168,7 +167,7 @@ extern void LoadDefaultFont(void)
|
||||
else currentPosX = testPosX;
|
||||
}
|
||||
|
||||
TraceLog(INFO, "Default font loaded successfully");
|
||||
TraceLog(INFO, "[TEX ID %i] Default font loaded successfully", defaultFont.texture.id);
|
||||
}
|
||||
|
||||
extern void UnloadDefaultFont(void)
|
||||
@ -195,9 +194,10 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
Image image = LoadImage(fileName);
|
||||
|
||||
// At this point we have a pixel array with all the data...
|
||||
|
||||
TraceLog(INFO, "[%s] SpriteFont image loaded: %i x %i", fileName, image.width, image.height);
|
||||
|
||||
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
ConvertToPOT(&image, MAGENTA);
|
||||
#endif
|
||||
// Process bitmap Font pixel data to get measures (Character array)
|
||||
// spriteFont.charSet data is filled inside the function and memory is allocated!
|
||||
int numChars = ParseImageData(image.pixels, image.width, image.height, &spriteFont.charSet);
|
||||
@ -207,40 +207,8 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
|
||||
spriteFont.numChars = numChars;
|
||||
|
||||
// Convert image font to POT image before conversion to texture
|
||||
// NOTE: Not required, we skip this step
|
||||
/*
|
||||
// Just add the required amount of pixels at the right and bottom sides of image...
|
||||
int potWidth = GetNextPOT(image.width);
|
||||
int potHeight = GetNextPOT(image.height);
|
||||
|
||||
// Check if POT texture generation is required (if texture is not already POT)
|
||||
if ((potWidth != image.width) || (potHeight != image.height))
|
||||
{
|
||||
Color *imgDataPixelPOT = NULL;
|
||||
|
||||
// Generate POT array from NPOT data
|
||||
imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
|
||||
for (int j = 0; j < potHeight; j++)
|
||||
{
|
||||
for (int i = 0; i < potWidth; i++)
|
||||
{
|
||||
if ((j < image.height) && (i < image.width)) imgDataPixelPOT[j*potWidth + i] = image.pixels[j*image.width + i];
|
||||
else imgDataPixelPOT[j*potWidth + i] = MAGENTA;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "SpriteFont texture converted to POT: %ix%i", potWidth, potHeight);
|
||||
|
||||
free(image.pixels);
|
||||
|
||||
image.pixels = imgDataPixelPOT;
|
||||
image.width = potWidth;
|
||||
image.height = potHeight;
|
||||
}
|
||||
*/
|
||||
spriteFont.texture = CreateTexture(image, false); // Convert loaded image to OpenGL texture
|
||||
spriteFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
|
||||
UnloadImage(image);
|
||||
}
|
||||
|
||||
@ -475,23 +443,6 @@ static int ParseImageData(Color *imgDataPixel, int imgWidth, int imgHeight, Char
|
||||
return index;
|
||||
}
|
||||
|
||||
// Calculate next power-of-two value for a given num
|
||||
static int GetNextPOT(int num)
|
||||
{
|
||||
if (num != 0)
|
||||
{
|
||||
num--;
|
||||
num |= (num >> 1); // Or first 2 bits
|
||||
num |= (num >> 2); // Or next 2 bits
|
||||
num |= (num >> 4); // Or next 4 bits
|
||||
num |= (num >> 8); // Or next 8 bits
|
||||
num |= (num >> 16); // Or next 16 bits
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
// Load a rBMF font file (raylib BitMap Font)
|
||||
static SpriteFont LoadRBMF(const char *fileName)
|
||||
{
|
||||
@ -517,91 +468,96 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
Image image;
|
||||
|
||||
rbmfInfoHeader rbmfHeader;
|
||||
unsigned int *rbmfFileData;
|
||||
unsigned char *rbmfCharWidthData;
|
||||
unsigned int *rbmfFileData = NULL;
|
||||
unsigned char *rbmfCharWidthData = NULL;
|
||||
|
||||
int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
|
||||
|
||||
FILE *rbmfFile = fopen(fileName, "rb"); // Define a pointer to bitmap file and open it in read-binary mode
|
||||
|
||||
// TODO: Check if file could be loaded! (rbmfFile == NULL)?
|
||||
|
||||
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
|
||||
|
||||
TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
|
||||
|
||||
spriteFont.numChars = (int)rbmfHeader.numChars;
|
||||
|
||||
image.width = (int)rbmfHeader.imgWidth;
|
||||
image.height = (int)rbmfHeader.imgHeight;
|
||||
|
||||
int numPixelBits = rbmfHeader.imgWidth * rbmfHeader.imgHeight / 32;
|
||||
|
||||
rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int));
|
||||
|
||||
for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
|
||||
|
||||
rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char));
|
||||
|
||||
for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
|
||||
|
||||
// Re-construct image from rbmfFileData
|
||||
//-----------------------------------------
|
||||
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
|
||||
|
||||
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
|
||||
|
||||
int counter = 0; // Font data elements counter
|
||||
|
||||
// Fill image data (convert from bit to pixel!)
|
||||
for (int i = 0; i < image.width * image.height; i += 32)
|
||||
if (rbmfFile == NULL)
|
||||
{
|
||||
for (int j = 31; j >= 0; j--)
|
||||
TraceLog(WARNING, "[%s] rBMF font file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
fread(&rbmfHeader, sizeof(rbmfInfoHeader), 1, rbmfFile);
|
||||
|
||||
TraceLog(INFO, "[%s] Loading rBMF file, size: %ix%i, numChars: %i, charHeight: %i", fileName, rbmfHeader.imgWidth, rbmfHeader.imgHeight, rbmfHeader.numChars, rbmfHeader.charHeight);
|
||||
|
||||
spriteFont.numChars = (int)rbmfHeader.numChars;
|
||||
|
||||
image.width = (int)rbmfHeader.imgWidth;
|
||||
image.height = (int)rbmfHeader.imgHeight;
|
||||
|
||||
int numPixelBits = rbmfHeader.imgWidth * rbmfHeader.imgHeight / 32;
|
||||
|
||||
rbmfFileData = (unsigned int *)malloc(numPixelBits * sizeof(unsigned int));
|
||||
|
||||
for(int i = 0; i < numPixelBits; i++) fread(&rbmfFileData[i], sizeof(unsigned int), 1, rbmfFile);
|
||||
|
||||
rbmfCharWidthData = (unsigned char *)malloc(spriteFont.numChars * sizeof(unsigned char));
|
||||
|
||||
for(int i = 0; i < spriteFont.numChars; i++) fread(&rbmfCharWidthData[i], sizeof(unsigned char), 1, rbmfFile);
|
||||
|
||||
// Re-construct image from rbmfFileData
|
||||
//-----------------------------------------
|
||||
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
|
||||
|
||||
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
|
||||
|
||||
int counter = 0; // Font data elements counter
|
||||
|
||||
// Fill image data (convert from bit to pixel!)
|
||||
for (int i = 0; i < image.width * image.height; i += 32)
|
||||
{
|
||||
if (BIT_CHECK(rbmfFileData[counter], j)) image.pixels[i+j] = WHITE;
|
||||
for (int j = 31; j >= 0; j--)
|
||||
{
|
||||
if (BIT_CHECK(rbmfFileData[counter], j)) image.pixels[i+j] = WHITE;
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
||||
|
||||
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
||||
spriteFont.texture = LoadTextureFromImage(image, false);
|
||||
UnloadImage(image); // Unload image data
|
||||
|
||||
spriteFont.texture = CreateTexture(image, false);
|
||||
UnloadImage(image); // Unload image data
|
||||
//TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);
|
||||
|
||||
TraceLog(INFO, "[%s] Starting charSet reconstruction", fileName);
|
||||
// Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
|
||||
spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data
|
||||
|
||||
// Reconstruct charSet using rbmfCharWidthData, rbmfHeader.charHeight, charsDivisor, rbmfHeader.numChars
|
||||
spriteFont.charSet = (Character *)malloc(spriteFont.numChars * sizeof(Character)); // Allocate space for our character data
|
||||
int currentLine = 0;
|
||||
int currentPosX = charsDivisor;
|
||||
int testPosX = charsDivisor;
|
||||
|
||||
int currentLine = 0;
|
||||
int currentPosX = charsDivisor;
|
||||
int testPosX = charsDivisor;
|
||||
|
||||
for (int i = 0; i < spriteFont.numChars; i++)
|
||||
{
|
||||
spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i;
|
||||
spriteFont.charSet[i].x = currentPosX;
|
||||
spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
|
||||
spriteFont.charSet[i].w = (int)rbmfCharWidthData[i];
|
||||
spriteFont.charSet[i].h = (int)rbmfHeader.charHeight;
|
||||
|
||||
testPosX += (spriteFont.charSet[i].w + charsDivisor);
|
||||
|
||||
if (testPosX > spriteFont.texture.width)
|
||||
for (int i = 0; i < spriteFont.numChars; i++)
|
||||
{
|
||||
currentLine++;
|
||||
currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
|
||||
testPosX = currentPosX;
|
||||
spriteFont.charSet[i].value = (int)rbmfHeader.firstChar + i;
|
||||
spriteFont.charSet[i].x = currentPosX;
|
||||
spriteFont.charSet[i].y = charsDivisor + currentLine * ((int)rbmfHeader.charHeight + charsDivisor);
|
||||
spriteFont.charSet[i].w = (int)rbmfCharWidthData[i];
|
||||
spriteFont.charSet[i].h = (int)rbmfHeader.charHeight;
|
||||
|
||||
spriteFont.charSet[i].x = charsDivisor;
|
||||
spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
|
||||
testPosX += (spriteFont.charSet[i].w + charsDivisor);
|
||||
|
||||
if (testPosX > spriteFont.texture.width)
|
||||
{
|
||||
currentLine++;
|
||||
currentPosX = 2 * charsDivisor + (int)rbmfCharWidthData[i];
|
||||
testPosX = currentPosX;
|
||||
|
||||
spriteFont.charSet[i].x = charsDivisor;
|
||||
spriteFont.charSet[i].y = charsDivisor + currentLine * (rbmfHeader.charHeight + charsDivisor);
|
||||
}
|
||||
else currentPosX = testPosX;
|
||||
}
|
||||
else currentPosX = testPosX;
|
||||
|
||||
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
|
||||
}
|
||||
|
||||
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
|
||||
|
||||
|
||||
fclose(rbmfFile);
|
||||
|
||||
free(rbmfFileData); // Now we can free loaded data from RAM memory
|
||||
|
173
src/textures.c
@ -126,9 +126,9 @@ Image LoadImage(const char *fileName)
|
||||
image.width = imgWidth;
|
||||
image.height = imgHeight;
|
||||
|
||||
TraceLog(INFO, "[%s] Image loaded successfully", fileName);
|
||||
TraceLog(INFO, "[%s] Image loaded successfully (%ix%i)", fileName, image.width, image.height);
|
||||
}
|
||||
else TraceLog(WARNING, "[%s] Image could not be loaded, file format not recognized", fileName);
|
||||
else TraceLog(WARNING, "[%s] Image could not be loaded, file not recognized", fileName);
|
||||
}
|
||||
else if (strcmp(GetExtension(fileName),"dds") == 0)
|
||||
{
|
||||
@ -175,8 +175,6 @@ Image LoadImage(const char *fileName)
|
||||
// Load an image from rRES file (raylib Resource)
|
||||
Image LoadImageFromRES(const char *rresName, int resId)
|
||||
{
|
||||
// TODO: rresName could be directly a char array with all the data! --> support it! :P
|
||||
|
||||
Image image;
|
||||
bool found = false;
|
||||
|
||||
@ -189,7 +187,10 @@ Image LoadImageFromRES(const char *rresName, int resId)
|
||||
|
||||
FILE *rresFile = fopen(rresName, "rb");
|
||||
|
||||
if (!rresFile) TraceLog(WARNING, "[%s] Could not open raylib resource file", rresName);
|
||||
if (rresFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Read rres file (basic file check - id)
|
||||
@ -295,6 +296,11 @@ Image LoadImageFromRES(const char *rresName, int resId)
|
||||
Texture2D LoadTexture(const char *fileName)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
// Init texture to default values
|
||||
texture.id = 0;
|
||||
texture.width = 0;
|
||||
texture.height = 0;
|
||||
|
||||
if (strcmp(GetExtension(fileName),"dds") == 0)
|
||||
{
|
||||
@ -334,10 +340,13 @@ Texture2D LoadTexture(const char *fileName)
|
||||
else
|
||||
{
|
||||
Image image = LoadImage(fileName);
|
||||
|
||||
|
||||
if (image.pixels != NULL)
|
||||
{
|
||||
texture = CreateTexture(image, false);
|
||||
#if defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
ConvertToPOT(&image, BLANK);
|
||||
#endif
|
||||
texture = LoadTextureFromImage(image, false);
|
||||
UnloadImage(image);
|
||||
}
|
||||
}
|
||||
@ -345,13 +354,66 @@ Texture2D LoadTexture(const char *fileName)
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load a texture from image data
|
||||
// NOTE: image is not unloaded, it must be done manually
|
||||
Texture2D LoadTextureFromImage(Image image, bool genMipmaps)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
// Init texture to default values
|
||||
texture.id = 0;
|
||||
texture.width = 0;
|
||||
texture.height = 0;
|
||||
|
||||
if ((image.pixels != NULL) && (image.width > 0) && (image.height > 0))
|
||||
{
|
||||
unsigned char *imgData = malloc(image.width * image.height * 4);
|
||||
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < image.width * image.height * 4; i += 4)
|
||||
{
|
||||
imgData[i] = image.pixels[j].r;
|
||||
imgData[i+1] = image.pixels[j].g;
|
||||
imgData[i+2] = image.pixels[j].b;
|
||||
imgData[i+3] = image.pixels[j].a;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
// NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
|
||||
texture.id = rlglLoadTexture(imgData, image.width, image.height, genMipmaps);
|
||||
|
||||
texture.width = image.width;
|
||||
texture.height = image.height;
|
||||
|
||||
free(imgData);
|
||||
}
|
||||
else TraceLog(WARNING, "Texture could not be loaded, image data is not valid");
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// [DEPRECATED] Load a texture from image data
|
||||
// NOTE: Use LoadTextureFromImage() instead
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
texture = LoadTextureFromImage(image, genMipmaps);
|
||||
|
||||
TraceLog(INFO, "Created texture id: %i", texture.id);
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
// Load an image as texture from rRES file (raylib Resource)
|
||||
Texture2D LoadTextureFromRES(const char *rresName, int resId)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
Image image = LoadImageFromRES(rresName, resId);
|
||||
texture = CreateTexture(image, false);
|
||||
texture = LoadTextureFromImage(image, false);
|
||||
UnloadImage(image);
|
||||
|
||||
return texture;
|
||||
@ -369,6 +431,41 @@ void UnloadTexture(Texture2D texture)
|
||||
rlDeleteTextures(texture.id);
|
||||
}
|
||||
|
||||
// Convert image to POT (power-of-two)
|
||||
// NOTE: Requirement on OpenGL ES 2.0 (RPI, HTML5)
|
||||
void ConvertToPOT(Image *image, Color fillColor)
|
||||
{
|
||||
// Just add the required amount of pixels at the right and bottom sides of image...
|
||||
int potWidth = GetNextPOT(image->width);
|
||||
int potHeight = GetNextPOT(image->height);
|
||||
|
||||
// Check if POT texture generation is required (if texture is not already POT)
|
||||
if ((potWidth != image->width) || (potHeight != image->height))
|
||||
{
|
||||
Color *imgDataPixelPOT = NULL;
|
||||
|
||||
// Generate POT array from NPOT data
|
||||
imgDataPixelPOT = (Color *)malloc(potWidth * potHeight * sizeof(Color));
|
||||
|
||||
for (int j = 0; j < potHeight; j++)
|
||||
{
|
||||
for (int i = 0; i < potWidth; i++)
|
||||
{
|
||||
if ((j < image->height) && (i < image->width)) imgDataPixelPOT[j*potWidth + i] = image->pixels[j*image->width + i];
|
||||
else imgDataPixelPOT[j*potWidth + i] = fillColor;
|
||||
}
|
||||
}
|
||||
|
||||
TraceLog(WARNING, "Image converted to POT: (%ix%i) -> (%ix%i)", image->width, image->height, potWidth, potHeight);
|
||||
|
||||
free(image->pixels);
|
||||
|
||||
image->pixels = imgDataPixelPOT;
|
||||
image->width = potWidth;
|
||||
image->height = potHeight;
|
||||
}
|
||||
}
|
||||
|
||||
// Draw a Texture2D
|
||||
void DrawTexture(Texture2D texture, int posX, int posY, Color tint)
|
||||
{
|
||||
@ -436,49 +533,13 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
|
||||
rlDisableTexture();
|
||||
}
|
||||
|
||||
// Create a texture from an image
|
||||
// NOTE: image is not unloaded, iot must be done manually
|
||||
Texture2D CreateTexture(Image image, bool genMipmaps)
|
||||
{
|
||||
Texture2D texture;
|
||||
|
||||
// Init texture to default values
|
||||
texture.id = 0;
|
||||
texture.width = 0;
|
||||
texture.height = 0;
|
||||
|
||||
if (image.pixels != NULL)
|
||||
{
|
||||
unsigned char *imgData = malloc(image.width * image.height * 4);
|
||||
|
||||
int j = 0;
|
||||
|
||||
for (int i = 0; i < image.width * image.height * 4; i += 4)
|
||||
{
|
||||
imgData[i] = image.pixels[j].r;
|
||||
imgData[i+1] = image.pixels[j].g;
|
||||
imgData[i+2] = image.pixels[j].b;
|
||||
imgData[i+3] = image.pixels[j].a;
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
// NOTE: rlglLoadTexture() can generate mipmaps (POT image required)
|
||||
texture.id = rlglLoadTexture(imgData, image.width, image.height, genMipmaps);
|
||||
|
||||
texture.width = image.width;
|
||||
texture.height = image.height;
|
||||
|
||||
free(imgData);
|
||||
}
|
||||
else TraceLog(WARNING, "Texture could not be created, image data is not valid");
|
||||
|
||||
return texture;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Loading DDS image data (compressed or uncompressed)
|
||||
// NOTE: Compressed data loading not supported on OpenGL 1.1
|
||||
ImageEx LoadDDS(const char *fileName)
|
||||
static ImageEx LoadDDS(const char *fileName)
|
||||
{
|
||||
#define FOURCC_DXT1 0x31545844 // Equivalent to "DXT1" in ASCII
|
||||
#define FOURCC_DXT3 0x33545844 // Equivalent to "DXT3" in ASCII
|
||||
@ -528,12 +589,18 @@ ImageEx LoadDDS(const char *fileName)
|
||||
|
||||
ImageEx image;
|
||||
ddsHeader header;
|
||||
|
||||
image.data = NULL;
|
||||
image.width = 0;
|
||||
image.height = 0;
|
||||
image.mipmaps = 0;
|
||||
image.compFormat = 0;
|
||||
|
||||
FILE *ddsFile = fopen(fileName, "rb");
|
||||
|
||||
if (ddsFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "DDS File could not be opened");
|
||||
TraceLog(WARNING, "[%s] DDS image file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -544,7 +611,7 @@ ImageEx LoadDDS(const char *fileName)
|
||||
|
||||
if (strncmp(filecode, "DDS ", 4) != 0)
|
||||
{
|
||||
TraceLog(WARNING, "DDS File does not seem to be valid");
|
||||
TraceLog(WARNING, "[%s] DDS file does not seem to be a valid image", fileName);
|
||||
fclose(ddsFile);
|
||||
}
|
||||
else
|
||||
@ -636,7 +703,7 @@ ImageEx LoadDDS(const char *fileName)
|
||||
// Loading PKM image data (ETC1/ETC2 compression)
|
||||
// NOTE: KTX is the standard Khronos Group compression format (ETC1/ETC2, mipmaps)
|
||||
// PKM is a much simpler file format used mainly to contain a single ETC1/ETC2 compressed image (no mipmaps)
|
||||
ImageEx LoadPKM(const char *fileName)
|
||||
static ImageEx LoadPKM(const char *fileName)
|
||||
{
|
||||
// If OpenGL ES 2.0. the following format could be supported (ETC1):
|
||||
//GL_ETC1_RGB8_OES
|
||||
@ -679,7 +746,7 @@ ImageEx LoadPKM(const char *fileName)
|
||||
|
||||
if (pkmFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] PKM File could not be opened", fileName);
|
||||
TraceLog(WARNING, "[%s] PKM image file could not be opened", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -690,7 +757,7 @@ ImageEx LoadPKM(const char *fileName)
|
||||
|
||||
if (strncmp(filecode, "PKM ", 4) != 0)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] PKM File does not seem to be valid", fileName);
|
||||
TraceLog(WARNING, "[%s] PKM file does not seem to be a valid image", fileName);
|
||||
fclose(pkmFile);
|
||||
}
|
||||
else
|
||||
|
46
src/utils.c
@ -133,18 +133,25 @@ void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int he
|
||||
|
||||
FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
|
||||
|
||||
// NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
|
||||
fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
|
||||
fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
|
||||
|
||||
// Write pixel data to file
|
||||
for (int y = 0; y < height ; y++)
|
||||
if (bmpFile == NULL)
|
||||
{
|
||||
for (int x = 0; x < width; x++)
|
||||
TraceLog(WARNING, "[%s] BMP file could not be created", fileName);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
|
||||
fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
|
||||
fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
|
||||
|
||||
// Write pixel data to file
|
||||
for (int y = 0; y < height ; y++)
|
||||
{
|
||||
fputc(imgData[(x*4)+2 + (y*width*4)], bmpFile);
|
||||
fputc(imgData[(x*4)+1 + (y*width*4)], bmpFile);
|
||||
fputc(imgData[(x*4) + (y*width*4)], bmpFile);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
fputc(imgData[(x*4)+2 + (y*width*4)], bmpFile);
|
||||
fputc(imgData[(x*4)+1 + (y*width*4)], bmpFile);
|
||||
fputc(imgData[(x*4) + (y*width*4)], bmpFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -157,7 +164,9 @@ void WritePNG(const char *fileName, unsigned char *imgData, int width, int heigh
|
||||
{
|
||||
stbi_write_png(fileName, width, height, 4, imgData, width*4); // It WORKS!!!
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) || defined(PLATFORM_WEB)
|
||||
// Outputs a trace log message (INFO, ERROR, WARNING)
|
||||
// NOTE: If a file has been init, output log is written there
|
||||
void TraceLog(int msgType, const char *text, ...)
|
||||
@ -262,6 +271,23 @@ const char *GetExtension(const char *fileName)
|
||||
return (dot + 1);
|
||||
}
|
||||
|
||||
// Calculate next power-of-two value for a given num
|
||||
int GetNextPOT(int num)
|
||||
{
|
||||
if (num != 0)
|
||||
{
|
||||
num--;
|
||||
num |= (num >> 1); // Or first 2 bits
|
||||
num |= (num >> 2); // Or next 2 bits
|
||||
num |= (num >> 4); // Or next 4 bits
|
||||
num |= (num >> 8); // Or next 8 bits
|
||||
num |= (num >> 16); // Or next 16 bits
|
||||
num++;
|
||||
}
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
@ -77,6 +77,7 @@ void WritePNG(const char *fileName, unsigned char *imgData, int width, int heigh
|
||||
|
||||
void TraceLog(int msgType, const char *text, ...); // Outputs a trace log message
|
||||
const char *GetExtension(const char *fileName); // Returns extension of a filename
|
||||
int GetNextPOT(int num); // Calculate next power-of-two value for a given num
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
void InitAssetManager(AAssetManager *manager); // Initialize asset manager from android app
|
||||
|