commit
a59433e7a3
10
.gitignore
vendored
10
.gitignore
vendored
@ -1,13 +1,6 @@
|
||||
# Ignore generated files
|
||||
# ...
|
||||
|
||||
# Ignore compiled binaries
|
||||
src/*.o
|
||||
src/*.exe
|
||||
examples/*.o
|
||||
examples/*.exe
|
||||
templates/*.exe
|
||||
|
||||
# Ignore Android generated files and folders
|
||||
src_android/obj/
|
||||
templates/android_project/bin/
|
||||
@ -48,6 +41,9 @@ _ReSharper*/
|
||||
[Tt]est[Rr]esult*
|
||||
ipch/
|
||||
*.opensdf
|
||||
|
||||
# Ignore compiled binaries
|
||||
*.o
|
||||
*.exe
|
||||
!tools/rrem.exe
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
|
||||
# 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()
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
@ -113,20 +113,20 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -lGLEW -lGL -lopenal
|
||||
endif
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
# libraries for Raspberry Pi compiling
|
||||
@ -327,8 +327,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
|
86
examples/models_custom_shader.c
Normal file
86
examples/models_custom_shader.c
Normal file
@ -0,0 +1,86 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [models] example - Load and draw a 3d model (OBJ)
|
||||
*
|
||||
* This example has been created using raylib 1.0 (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
int screenWidth = 1280;
|
||||
int screenHeight = 720;
|
||||
|
||||
InitWindow(screenWidth, screenHeight, "raylib [models] example - custom shader");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
Camera camera = {{ 10.0, 8.0, 10.0 }, { 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 }};
|
||||
|
||||
Texture2D texture = LoadTexture("resources/catsham.png"); // Load model texture
|
||||
Shader shader = LoadShader("resources/shaders/custom.vs", "resources/shaders/custom.fs");
|
||||
//Shader poste = LoadShader("resources/shaders/custom.vs", "resources/shaders/pixel.fs");
|
||||
|
||||
Model cat = LoadModel("resources/cat.obj"); // Load OBJ model
|
||||
|
||||
SetModelTexture(&cat, texture); // Bind texture to model
|
||||
//SetModelShader(&cat, poste);
|
||||
|
||||
Vector3 catPosition = { 0.0, 0.0, 0.0 }; // Set model position
|
||||
|
||||
SetPostproShader(shader);
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (IsKeyDown(KEY_LEFT)) catPosition.x -= 0.2;
|
||||
if (IsKeyDown(KEY_RIGHT)) catPosition.x += 0.2;
|
||||
if (IsKeyDown(KEY_UP)) catPosition.z -= 0.2;
|
||||
if (IsKeyDown(KEY_DOWN)) catPosition.z += 0.2;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
Begin3dMode(camera);
|
||||
|
||||
DrawModel(cat, catPosition, 0.1f, WHITE); // Draw 3d model with texture
|
||||
|
||||
DrawGrid(10.0, 1.0); // Draw a grid
|
||||
|
||||
DrawGizmo(catPosition); // Draw gizmo
|
||||
|
||||
End3dMode();
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
UnloadTexture(texture); // Unload texture
|
||||
UnloadModel(cat); // Unload model
|
||||
UnloadShader(shader);
|
||||
//UnloadShader(poste);
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
19
examples/resources/shaders/base.vs
Normal file
19
examples/resources/shaders/base.vs
Normal file
@ -0,0 +1,19 @@
|
||||
#version 110
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec4 vertexColor;
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 modelviewMatrix;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
gl_Position = projectionMatrix*modelviewMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
16
examples/resources/shaders/custom.fs
Normal file
16
examples/resources/shaders/custom.fs
Normal file
@ -0,0 +1,16 @@
|
||||
#version 330
|
||||
|
||||
uniform sampler2D texture0;
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
uniform vec4 tintColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture2D(texture0, fragTexCoord)*tintColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
gl_FragColor = vec4(gray, gray, gray, tintColor.a);
|
||||
}
|
16
examples/resources/shaders/custom.vs
Normal file
16
examples/resources/shaders/custom.vs
Normal file
@ -0,0 +1,16 @@
|
||||
#version 330
|
||||
|
||||
attribute vec3 vertexPosition;
|
||||
attribute vec2 vertexTexCoord;
|
||||
attribute vec3 vertexNormal;
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 modelviewMatrix;
|
||||
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
fragTexCoord = vertexTexCoord;
|
||||
gl_Position = projectionMatrix*modelviewMatrix*vec4(vertexPosition, 1.0);
|
||||
}
|
15
examples/resources/shaders/grayscale.fs
Normal file
15
examples/resources/shaders/grayscale.fs
Normal file
@ -0,0 +1,15 @@
|
||||
#version 110
|
||||
|
||||
uniform sampler2D texture0;
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 base = texture2D(texture0, fragTexCoord)*fragColor;
|
||||
|
||||
// Convert to grayscale using NTSC conversion weights
|
||||
float gray = dot(base.rgb, vec3(0.299, 0.587, 0.114));
|
||||
|
||||
gl_FragColor = vec4(gray, gray, gray, base.a);
|
||||
}
|
BIN
external/glfw3/glfw3.dll
vendored
BIN
external/glfw3/glfw3.dll
vendored
Binary file not shown.
1982
external/glfw3/include/GLFW/glfw3.h
vendored
1982
external/glfw3/include/GLFW/glfw3.h
vendored
File diff suppressed because it is too large
Load Diff
212
external/glfw3/include/GLFW/glfw3native.h
vendored
212
external/glfw3/include/GLFW/glfw3native.h
vendored
@ -1,5 +1,5 @@
|
||||
/*************************************************************************
|
||||
* GLFW 3.0 - www.glfw.org
|
||||
* GLFW 3.1 - www.glfw.org
|
||||
* A library for OpenGL, window and input
|
||||
*------------------------------------------------------------------------
|
||||
* Copyright (c) 2002-2006 Marcus Geelnard
|
||||
@ -40,13 +40,13 @@ extern "C" {
|
||||
|
||||
/*! @defgroup native Native access
|
||||
*
|
||||
* **By using the native API, you assert that you know what you're doing and
|
||||
* how to fix problems caused by using it. If you don't, you shouldn't be
|
||||
* using it.**
|
||||
* **By using the native access functions you assert that you know what you're
|
||||
* doing and how to fix problems caused by using them. If you don't, you
|
||||
* shouldn't be using them.**
|
||||
*
|
||||
* Before the inclusion of @ref glfw3native.h, you must define exactly one
|
||||
* window API macro and exactly one context API macro. Failure to do this
|
||||
* will cause a compile-time error.
|
||||
* window system API macro and exactly one context creation API macro. Failure
|
||||
* to do this will cause a compile-time error.
|
||||
*
|
||||
* The available window API macros are:
|
||||
* * `GLFW_EXPOSE_NATIVE_WIN32`
|
||||
@ -71,8 +71,13 @@ extern "C" {
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
// This is a workaround for the fact that glfw3.h needs to export APIENTRY (for
|
||||
// example to allow applications to correctly declare a GL_ARB_debug_output
|
||||
// callback) but windows.h assumes no one will define APIENTRY before it does
|
||||
#undef APIENTRY
|
||||
#include <windows.h>
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#if defined(__OBJC__)
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#else
|
||||
@ -80,8 +85,9 @@ extern "C" {
|
||||
#endif
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/extensions/Xrandr.h>
|
||||
#else
|
||||
#error "No window API specified"
|
||||
#error "No window API selected"
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
@ -93,7 +99,7 @@ extern "C" {
|
||||
#elif defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
#include <EGL/egl.h>
|
||||
#else
|
||||
#error "No context API specified"
|
||||
#error "No context API selected"
|
||||
#endif
|
||||
|
||||
|
||||
@ -102,8 +108,49 @@ extern "C" {
|
||||
*************************************************************************/
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WIN32)
|
||||
/*! @brief Returns the adapter device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded adapter device name (for example `\\.\DISPLAY1`)
|
||||
* of the specified monitor, or `NULL` if an [error](@ref error_handling)
|
||||
* occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the display device name of the specified monitor.
|
||||
*
|
||||
* @return The UTF-8 encoded display device name (for example
|
||||
* `\\.\DISPLAY1\Monitor0`) of the specified monitor, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI const char* glfwGetWin32Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `HWND` of the specified window.
|
||||
* @return The `HWND` of the specified window.
|
||||
*
|
||||
* @return The `HWND` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
@ -111,15 +158,48 @@ GLFWAPI HWND glfwGetWin32Window(GLFWwindow* window);
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_WGL)
|
||||
/*! @brief Returns the `HGLRC` of the specified window.
|
||||
* @return The `HGLRC` of the specified window.
|
||||
*
|
||||
* @return The `HGLRC` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI HGLRC glfwGetWGLContext(GLFWwindow* window);
|
||||
#endif
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_COCOA)
|
||||
/*! @brief Returns the `CGDirectDisplayID` of the specified monitor.
|
||||
*
|
||||
* @return The `CGDirectDisplayID` of the specified monitor, or
|
||||
* `kCGNullDirectDisplay` if an [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI CGDirectDisplayID glfwGetCocoaMonitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `NSWindow` of the specified window.
|
||||
* @return The `NSWindow` of the specified window.
|
||||
*
|
||||
* @return The `NSWindow` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
@ -127,7 +207,16 @@ GLFWAPI id glfwGetCocoaWindow(GLFWwindow* window);
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_NSGL)
|
||||
/*! @brief Returns the `NSOpenGLContext` of the specified window.
|
||||
* @return The `NSOpenGLContext` of the specified window.
|
||||
*
|
||||
* @return The `NSOpenGLContext` of the specified window, or `nil` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
@ -135,12 +224,61 @@ GLFWAPI id glfwGetNSGLContext(GLFWwindow* window);
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_X11)
|
||||
/*! @brief Returns the `Display` used by GLFW.
|
||||
* @return The `Display` used by GLFW.
|
||||
*
|
||||
* @return The `Display` used by GLFW, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Display* glfwGetX11Display(void);
|
||||
|
||||
/*! @brief Returns the `RRCrtc` of the specified monitor.
|
||||
*
|
||||
* @return The `RRCrtc` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RRCrtc glfwGetX11Adapter(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `RROutput` of the specified monitor.
|
||||
*
|
||||
* @return The `RROutput` of the specified monitor, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.1.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI RROutput glfwGetX11Monitor(GLFWmonitor* monitor);
|
||||
|
||||
/*! @brief Returns the `Window` of the specified window.
|
||||
* @return The `Window` of the specified window.
|
||||
*
|
||||
* @return The `Window` of the specified window, or `None` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
@ -148,7 +286,16 @@ GLFWAPI Window glfwGetX11Window(GLFWwindow* window);
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_GLX)
|
||||
/*! @brief Returns the `GLXContext` of the specified window.
|
||||
* @return The `GLXContext` of the specified window.
|
||||
*
|
||||
* @return The `GLXContext` of the specified window, or `NULL` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
@ -156,17 +303,46 @@ GLFWAPI GLXContext glfwGetGLXContext(GLFWwindow* window);
|
||||
|
||||
#if defined(GLFW_EXPOSE_NATIVE_EGL)
|
||||
/*! @brief Returns the `EGLDisplay` used by GLFW.
|
||||
* @return The `EGLDisplay` used by GLFW.
|
||||
*
|
||||
* @return The `EGLDisplay` used by GLFW, or `EGL_NO_DISPLAY` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLDisplay glfwGetEGLDisplay(void);
|
||||
|
||||
/*! @brief Returns the `EGLContext` of the specified window.
|
||||
* @return The `EGLContext` of the specified window.
|
||||
*
|
||||
* @return The `EGLContext` of the specified window, or `EGL_NO_CONTEXT` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLContext glfwGetEGLContext(GLFWwindow* window);
|
||||
|
||||
/*! @brief Returns the `EGLSurface` of the specified window.
|
||||
* @return The `EGLSurface` of the specified window.
|
||||
*
|
||||
* @return The `EGLSurface` of the specified window, or `EGL_NO_SURFACE` if an
|
||||
* [error](@ref error_handling) occurred.
|
||||
*
|
||||
* @par Thread Safety
|
||||
* This function may be called from any thread. Access is not synchronized.
|
||||
*
|
||||
* @par History
|
||||
* Added in GLFW 3.0.
|
||||
*
|
||||
* @ingroup native
|
||||
*/
|
||||
GLFWAPI EGLSurface glfwGetEGLSurface(GLFWwindow* window);
|
||||
|
BIN
external/glfw3/lib/linux/libglfw3.a
vendored
Normal file
BIN
external/glfw3/lib/linux/libglfw3.a
vendored
Normal file
Binary file not shown.
BIN
external/glfw3/lib/win32/libglfw3.a
vendored
BIN
external/glfw3/lib/win32/libglfw3.a
vendored
Binary file not shown.
BIN
external/glfw3/lib/win32/libglfw3dll.a
vendored
BIN
external/glfw3/lib/win32/libglfw3dll.a
vendored
Binary file not shown.
358
games/just_do_GGJ2015/src/just_do.c
Normal file
358
games/just_do_GGJ2015/src/just_do.c
Normal file
@ -0,0 +1,358 @@
|
||||
/*******************************************************************************************
|
||||
*
|
||||
* JUST DO - Global Game Jam 2015 Videogame
|
||||
* Experimental puzzle game that lets the user try to find a logic solution to
|
||||
* different shape-color-based situations.
|
||||
*
|
||||
* Developed by: Ramon Santamaria (Ray San)
|
||||
*
|
||||
* This game has been created using raylib (www.raylib.com)
|
||||
* raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
|
||||
*
|
||||
* raylib - Copyright (c) 2015 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens/screens.h" // NOTE: Defines currentScreen
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
const int screenWidth = 1280; // Moved to screens.h
|
||||
const int screenHeight = 720; // Moved to screens.h
|
||||
|
||||
// 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;
|
||||
|
||||
//static Sound levelWin;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Local Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void TransitionToScreen(int screen);
|
||||
void UpdateTransition(void);
|
||||
void DrawTransition(void);
|
||||
|
||||
void UpdateDrawFrame(void); // Update and Draw one frame
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main entry point
|
||||
//----------------------------------------------------------------------------------
|
||||
int main(void)
|
||||
{
|
||||
// Initialization
|
||||
//---------------------------------------------------------
|
||||
const char windowTitle[30] = "JUST DO";
|
||||
|
||||
//SetupFlags(FLAG_FULLSCREEN_MODE);
|
||||
InitWindow(screenWidth, screenHeight, windowTitle);
|
||||
|
||||
// TODO: Load global data here (assets that must be available in all screens, i.e. fonts)
|
||||
InitAudioDevice();
|
||||
|
||||
levelWin = LoadSound("resources/win.wav");
|
||||
|
||||
// Setup and Init first screen
|
||||
currentScreen = LOGO;
|
||||
InitLogoScreen();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
|
||||
#else
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!WindowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
|
||||
if (IsKeyPressed(KEY_SPACE)) PlaySound(levelWin);
|
||||
|
||||
UpdateDrawFrame();
|
||||
}
|
||||
#endif
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// TODO: Unload all global loaded data (i.e. fonts) here!
|
||||
UnloadSound(levelWin);
|
||||
|
||||
CloseAudioDevice();
|
||||
|
||||
CloseWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Local Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
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 UpdateDrawFrame(void)
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (!onTransition)
|
||||
{
|
||||
if (IsKeyPressed('0'))
|
||||
{
|
||||
TransitionToScreen(LEVEL00);
|
||||
InitLevel00Screen();
|
||||
}
|
||||
else if (IsKeyPressed('1'))
|
||||
{
|
||||
TransitionToScreen(LEVEL01);
|
||||
InitLevel01Screen();
|
||||
}
|
||||
else if (IsKeyPressed('2'))
|
||||
{
|
||||
TransitionToScreen(LEVEL02);
|
||||
InitLevel02Screen();
|
||||
}
|
||||
else if (IsKeyPressed('3'))
|
||||
{
|
||||
TransitionToScreen(LEVEL03);
|
||||
InitLevel03Screen();
|
||||
}
|
||||
else if (IsKeyPressed('4'))
|
||||
{
|
||||
TransitionToScreen(LEVEL04);
|
||||
InitLevel04Screen();
|
||||
}
|
||||
else if (IsKeyPressed('5'))
|
||||
{
|
||||
TransitionToScreen(LEVEL05);
|
||||
InitLevel05Screen();
|
||||
}
|
||||
else if (IsKeyPressed('6'))
|
||||
{
|
||||
TransitionToScreen(LEVEL06);
|
||||
InitLevel06Screen();
|
||||
}
|
||||
else if (IsKeyPressed('7'))
|
||||
{
|
||||
TransitionToScreen(LEVEL07);
|
||||
InitLevel07Screen();
|
||||
}
|
||||
else if (IsKeyPressed('8'))
|
||||
{
|
||||
TransitionToScreen(LEVEL08);
|
||||
InitLevel08Screen();
|
||||
}
|
||||
else if (IsKeyPressed('9'))
|
||||
{
|
||||
TransitionToScreen(LEVEL09);
|
||||
InitLevel08Screen();
|
||||
}
|
||||
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO:
|
||||
{
|
||||
UpdateLogoScreen();
|
||||
|
||||
if (FinishLogoScreen())
|
||||
{
|
||||
UnloadLogoScreen();
|
||||
TransitionToScreen(LEVEL00);
|
||||
InitLevel00Screen();
|
||||
|
||||
PlayMusicStream("resources/ambient.ogg");
|
||||
SetMusicVolume(0.6f);
|
||||
}
|
||||
} break;
|
||||
case LEVEL00:
|
||||
{
|
||||
UpdateLevel00Screen();
|
||||
|
||||
if (FinishLevel00Screen())
|
||||
{
|
||||
UnloadLevel00Screen();
|
||||
TransitionToScreen(LEVEL01);
|
||||
InitLevel01Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL01:
|
||||
{
|
||||
UpdateLevel01Screen();
|
||||
|
||||
if (FinishLevel01Screen())
|
||||
{
|
||||
UnloadLevel01Screen();
|
||||
TransitionToScreen(LEVEL02);
|
||||
InitLevel02Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL02:
|
||||
{
|
||||
UpdateLevel02Screen();
|
||||
|
||||
if (FinishLevel02Screen())
|
||||
{
|
||||
UnloadLevel02Screen();
|
||||
TransitionToScreen(LEVEL03);
|
||||
InitLevel03Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL03:
|
||||
{
|
||||
UpdateLevel03Screen();
|
||||
|
||||
if (FinishLevel03Screen())
|
||||
{
|
||||
UnloadLevel03Screen();
|
||||
TransitionToScreen(LEVEL04);
|
||||
InitLevel04Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL04:
|
||||
{
|
||||
UpdateLevel04Screen();
|
||||
|
||||
if (FinishLevel04Screen())
|
||||
{
|
||||
UnloadLevel04Screen();
|
||||
TransitionToScreen(LEVEL05);
|
||||
InitLevel05Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL05:
|
||||
{
|
||||
UpdateLevel05Screen();
|
||||
|
||||
if (FinishLevel05Screen())
|
||||
{
|
||||
UnloadLevel05Screen();
|
||||
TransitionToScreen(LEVEL06);
|
||||
InitLevel06Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL06:
|
||||
{
|
||||
UpdateLevel06Screen();
|
||||
|
||||
if (FinishLevel06Screen())
|
||||
{
|
||||
UnloadLevel06Screen();
|
||||
TransitionToScreen(LEVEL07);
|
||||
InitLevel07Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL07:
|
||||
{
|
||||
UpdateLevel07Screen();
|
||||
|
||||
if (FinishLevel07Screen())
|
||||
{
|
||||
UnloadLevel07Screen();
|
||||
TransitionToScreen(LEVEL08);
|
||||
InitLevel08Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL08:
|
||||
{
|
||||
UpdateLevel08Screen();
|
||||
|
||||
if (FinishLevel08Screen())
|
||||
{
|
||||
UnloadLevel08Screen();
|
||||
TransitionToScreen(LEVEL09);
|
||||
InitLevel09Screen();
|
||||
}
|
||||
} break;
|
||||
case LEVEL09:
|
||||
{
|
||||
UpdateLevel09Screen();
|
||||
|
||||
if (FinishLevel09Screen())
|
||||
{
|
||||
UnloadLevel09Screen();
|
||||
TransitionToScreen(LEVEL00);
|
||||
InitLevel00Screen();
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
else UpdateTransition(); // Update transition (fade-in, fade-out)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
switch(currentScreen)
|
||||
{
|
||||
case LOGO: DrawLogoScreen(); break;
|
||||
case LEVEL00: DrawLevel00Screen(); break;
|
||||
case LEVEL01: DrawLevel01Screen(); break;
|
||||
case LEVEL02: DrawLevel02Screen(); break;
|
||||
case LEVEL03: DrawLevel03Screen(); break;
|
||||
case LEVEL04: DrawLevel04Screen(); break;
|
||||
case LEVEL05: DrawLevel05Screen(); break;
|
||||
case LEVEL06: DrawLevel06Screen(); break;
|
||||
case LEVEL07: DrawLevel07Screen(); break;
|
||||
case LEVEL08: DrawLevel08Screen(); break;
|
||||
case LEVEL09: DrawLevel09Screen(); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
if (onTransition) DrawTransition();
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
246
games/just_do_GGJ2015/src/makefile
Normal file
246
games/just_do_GGJ2015/src/makefile
Normal file
@ -0,0 +1,246 @@
|
||||
#**************************************************************************************************
|
||||
#
|
||||
# raylib - Advance Game
|
||||
#
|
||||
# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# 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 to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
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
|
||||
else
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
CFLAGS = -O2 -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 -I../../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src -L../../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -lGLEW -lGL -lopenal
|
||||
endif
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
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
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
LIBS = ../../src/libraylib.bc
|
||||
endif
|
||||
|
||||
# define additional parameters and flags for windows
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
screens/screen_logo.o \
|
||||
screens/screen_level00.o \
|
||||
screens/screen_level01.o \
|
||||
screens/screen_level02.o \
|
||||
screens/screen_level03.o \
|
||||
screens/screen_level04.o \
|
||||
screens/screen_level05.o \
|
||||
screens/screen_level06.o \
|
||||
screens/screen_level07.o \
|
||||
screens/screen_level08.o \
|
||||
screens/screen_level09.o \
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is just_do
|
||||
default: just_do
|
||||
|
||||
# compile just_do
|
||||
just_do: just_do.c $(SCREENS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screen LOGO
|
||||
screens/screen_logo.o: screens/screen_logo.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL00
|
||||
screens/screen_level00.o: screens/screen_level00.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL01
|
||||
screens/screen_level01.o: screens/screen_level01.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL02
|
||||
screens/screen_level02.o: screens/screen_level02.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL03
|
||||
screens/screen_level03.o: screens/screen_level03.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL04
|
||||
screens/screen_level04.o: screens/screen_level04.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL05
|
||||
screens/screen_level05.o: screens/screen_level05.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL06
|
||||
screens/screen_level06.o: screens/screen_level06.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL07
|
||||
screens/screen_level07.o: screens/screen_level07.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL08
|
||||
screens/screen_level08.o: screens/screen_level08.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile screen LEVEL09
|
||||
screens/screen_level09.o: screens/screen_level09.c
|
||||
$(CC) -c $< -o $@ $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
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)
|
BIN
games/just_do_GGJ2015/src/resources/ambient.ogg
Normal file
BIN
games/just_do_GGJ2015/src/resources/ambient.ogg
Normal file
Binary file not shown.
BIN
games/just_do_GGJ2015/src/resources/win.wav
Normal file
BIN
games/just_do_GGJ2015/src/resources/win.wav
Normal file
Binary file not shown.
167
games/just_do_GGJ2015/src/screens/screen_level00.c
Normal file
167
games/just_do_GGJ2015/src/screens/screen_level00.c
Normal file
@ -0,0 +1,167 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level00 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level00 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle boundsU, boundsO;
|
||||
|
||||
static bool mouseOverU = false;
|
||||
static bool mouseOverO = false;
|
||||
static bool placedU = false;
|
||||
static bool placedO = false;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level00 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level00 Screen Initialization logic
|
||||
void InitLevel00Screen(void)
|
||||
{
|
||||
// Initialize Level00 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
boundsU = (Rectangle){GetScreenWidth()/2 - 265, -200, MeasureText("U", 160) + 40, 160 };
|
||||
boundsO = (Rectangle){GetScreenWidth() - 370, -30, MeasureText("O", 160) + 40, 160 };
|
||||
}
|
||||
|
||||
// Level00 Screen Update logic
|
||||
void UpdateLevel00Screen(void)
|
||||
{
|
||||
// Update Level00 screen variables here!
|
||||
if (!done) framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (!placedU) boundsU.y += 2;
|
||||
|
||||
if (boundsU.y >= GetScreenHeight()) boundsU.y = -boundsU.height;
|
||||
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointRec(mousePos, boundsU))
|
||||
{
|
||||
mouseOverU = true;
|
||||
|
||||
if (!placedU && IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if ((boundsU.y > GetScreenHeight()/2 - 110) && ((boundsU.y + boundsU.height) < (GetScreenHeight()/2 + 100)))
|
||||
{
|
||||
placedU = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else mouseOverU = false;
|
||||
|
||||
if (CheckCollisionPointRec(mousePos, boundsO))
|
||||
{
|
||||
mouseOverO = true;
|
||||
|
||||
if (!placedO && IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) boundsO.y += 100;
|
||||
|
||||
if (boundsO.y >= (GetScreenHeight()/2 - 130)) placedO = true;
|
||||
}
|
||||
else mouseOverO = false;
|
||||
|
||||
if (placedO && placedU)
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 30) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level00 Screen Draw logic
|
||||
void DrawLevel00Screen(void)
|
||||
{
|
||||
// Draw Level00 screen
|
||||
DrawText("U", boundsU.x, boundsU.y + 10, 160, GRAY);
|
||||
DrawText("J", GetScreenWidth()/2 - MeasureText("JUST DO", 160)/2, GetScreenHeight()/2 - 80, 160, GRAY);
|
||||
DrawText("ST D", GetScreenWidth()/2 - MeasureText("JUST DO", 160)/2 + 210, GetScreenHeight()/2 - 80, 160, GRAY);
|
||||
DrawText("O", boundsO.x, boundsO.y + 10, 160, GRAY);
|
||||
|
||||
DrawText("by RAMON SANTAMARIA (@raysan5)", 370, GetScreenHeight()/2 + 100, 30, Fade(LIGHTGRAY, 0.4f));
|
||||
|
||||
if (mouseOverU && !placedU) DrawRectangleLines(boundsU.x - 20, boundsU.y, boundsU.width, boundsU.height, Fade(LIGHTGRAY, 0.8f));
|
||||
//DrawRectangleBordersRec(boundsU, -20, 0, 20, Fade(RED, 0.3f));
|
||||
|
||||
if (mouseOverO && !placedO) DrawRectangleLines(boundsO.x - 20, boundsO.y, boundsO.width, boundsO.height, Fade(LIGHTGRAY, 0.8f));
|
||||
//DrawRectangleBordersRec(boundsO, -20, 0, 20, Fade(RED, 0.3f));
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 00", GetScreenWidth()/2 - MeasureText("LEVEL 00", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 00", GetScreenWidth()/2 - MeasureText("LEVEL 00", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level00 Screen Unload logic
|
||||
void UnloadLevel00Screen(void)
|
||||
{
|
||||
// TODO: Unload Level00 screen variables here!
|
||||
}
|
||||
|
||||
// Level00 Screen should finish?
|
||||
int FinishLevel00Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
void DrawRectangleBordersRec(Rectangle rec, int offsetX, int offsetY, int borderSize, Color col)
|
||||
{
|
||||
DrawRectangle(rec.x + offsetX, rec.y + offsetY, rec.width, borderSize, col);
|
||||
DrawRectangle(rec.x + offsetX, rec.y + borderSize + offsetY, borderSize, rec.height - borderSize*2, col);
|
||||
DrawRectangle(rec.x + rec.width - borderSize + offsetX, rec.y + borderSize + offsetY, borderSize, rec.height - borderSize*2, col);
|
||||
DrawRectangle(rec.x + offsetX, rec.y + rec.height - borderSize + offsetY, rec.width, borderSize, col);
|
||||
}
|
163
games/just_do_GGJ2015/src/screens/screen_level01.c
Normal file
163
games/just_do_GGJ2015/src/screens/screen_level01.c
Normal file
@ -0,0 +1,163 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level01 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level01 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle innerLeftRec, outerLeftRec;
|
||||
static Rectangle innerRightRec, outerRightRec;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level01 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level01 Screen Initialization logic
|
||||
void InitLevel01Screen(void)
|
||||
{
|
||||
// Initialize Level01 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
outerLeftRec = (Rectangle){ 0, 0, GetScreenWidth()/2, GetScreenHeight() };
|
||||
outerRightRec = (Rectangle){ GetScreenWidth()/2, 0, GetScreenWidth()/2, GetScreenHeight() };
|
||||
|
||||
innerLeftRec = (Rectangle){ GetScreenWidth()/4 - 200, GetScreenHeight()/2 - 200, 400, 400};
|
||||
innerRightRec = (Rectangle){ GetScreenWidth()/2 + GetScreenWidth()/4 - 200, GetScreenHeight()/2 - 200, 400, 400};
|
||||
}
|
||||
|
||||
// Level01 Screen Update logic
|
||||
void UpdateLevel01Screen(void)
|
||||
{
|
||||
// Update Level01 screen
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), innerLeftRec))
|
||||
{
|
||||
if (innerRightRec.width > 0)
|
||||
{
|
||||
innerRightRec.x += 20;
|
||||
innerRightRec.y += 20;
|
||||
innerRightRec.width -= 40;
|
||||
innerRightRec.height -= 40;
|
||||
}
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), innerRightRec))
|
||||
{
|
||||
if (innerLeftRec.width > 0)
|
||||
{
|
||||
innerLeftRec.x += 20;
|
||||
innerLeftRec.y += 20;
|
||||
innerLeftRec.width -= 40;
|
||||
innerLeftRec.height -= 40;
|
||||
}
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), outerLeftRec))
|
||||
{
|
||||
innerLeftRec.x -= 20;
|
||||
innerLeftRec.y -= 20;
|
||||
innerLeftRec.width += 40;
|
||||
innerLeftRec.height += 40;
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), outerRightRec))
|
||||
{
|
||||
innerRightRec.x -= 20;
|
||||
innerRightRec.y -= 20;
|
||||
innerRightRec.width += 40;
|
||||
innerRightRec.height += 40;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (((innerRightRec.width == 0) && (innerLeftRec.height >= GetScreenHeight())) ||
|
||||
((innerLeftRec.width == 0) && (innerRightRec.height >= GetScreenHeight())))
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level01 Screen Draw logic
|
||||
void DrawLevel01Screen(void)
|
||||
{
|
||||
// Draw Level01 screen
|
||||
if (!levelFinished) DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), LIGHTGRAY);
|
||||
else DrawRectangle(60, 60, GetScreenWidth() - 120, GetScreenHeight() - 120, LIGHTGRAY);
|
||||
|
||||
DrawRectangleRec(outerLeftRec, GRAY);
|
||||
DrawRectangleRec(innerLeftRec, RAYWHITE);
|
||||
DrawRectangleRec(outerRightRec, RAYWHITE);
|
||||
DrawRectangleRec(innerRightRec, GRAY);
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 01", GetScreenWidth()/2 - MeasureText("LEVEL 01", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 01", GetScreenWidth()/2 - MeasureText("LEVEL 01", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level01 Screen Unload logic
|
||||
void UnloadLevel01Screen(void)
|
||||
{
|
||||
// TODO: Unload Level01 screen variables here!
|
||||
}
|
||||
|
||||
// Level01 Screen should finish?
|
||||
int FinishLevel01Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
170
games/just_do_GGJ2015/src/screens/screen_level02.c
Normal file
170
games/just_do_GGJ2015/src/screens/screen_level02.c
Normal file
@ -0,0 +1,170 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level02 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level02 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Vector2 bouncingBallPos;
|
||||
static float bouncingBallRadius = 40;
|
||||
static Vector2 bouncingBallSpeed;
|
||||
|
||||
static Vector2 holeCirclePos;
|
||||
static float holeCircleRadius = 50;
|
||||
|
||||
static bool ballOnHole = false;
|
||||
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level02 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
float Vector2Distance(Vector2 v1, Vector2 v2);
|
||||
|
||||
// Level02 Screen Initialization logic
|
||||
void InitLevel02Screen(void)
|
||||
{
|
||||
// TODO: Initialize Level02 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
bouncingBallPos = (Vector2){ 120, 80 };
|
||||
bouncingBallSpeed = (Vector2){ 6, 8 };
|
||||
holeCirclePos = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 };
|
||||
}
|
||||
|
||||
// Level02 Screen Update logic
|
||||
void UpdateLevel02Screen(void)
|
||||
{
|
||||
// Update Level02 screen
|
||||
framesCounter++;
|
||||
|
||||
if (!ballOnHole)
|
||||
{
|
||||
bouncingBallPos.x += bouncingBallSpeed.x;
|
||||
bouncingBallPos.y += bouncingBallSpeed.y;
|
||||
|
||||
if (((bouncingBallPos.x - bouncingBallRadius) <= 0) || ((bouncingBallPos.x + bouncingBallRadius) >= GetScreenWidth())) bouncingBallSpeed.x *= -1;
|
||||
if (((bouncingBallPos.y - bouncingBallRadius) <= 0) || ((bouncingBallPos.y + bouncingBallRadius) >= GetScreenHeight())) bouncingBallSpeed.y *= -1;
|
||||
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
if (CheckCollisionPointCircle(mousePos, bouncingBallPos, 120))
|
||||
{
|
||||
bouncingBallPos.x = GetRandomValue(80, 1200);
|
||||
bouncingBallPos.y = GetRandomValue(80, 650);
|
||||
}
|
||||
|
||||
if (CheckCollisionPointCircle(mousePos, holeCirclePos, 120))
|
||||
{
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
holeCirclePos = mousePos;
|
||||
|
||||
if ((holeCirclePos.x - holeCircleRadius) <= 0) holeCirclePos.x = holeCircleRadius;
|
||||
else if ((holeCirclePos.x + holeCircleRadius) >= GetScreenWidth()) holeCirclePos.x = GetScreenWidth() - holeCircleRadius;
|
||||
|
||||
if ((holeCirclePos.y - holeCircleRadius) <= 0) holeCirclePos.y = holeCircleRadius;
|
||||
else if ((holeCirclePos.y + holeCircleRadius) >= GetScreenHeight()) holeCirclePos.y = GetScreenHeight() - holeCircleRadius;
|
||||
}
|
||||
}
|
||||
|
||||
if (Vector2Distance(bouncingBallPos, holeCirclePos) < 20)
|
||||
{
|
||||
ballOnHole = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (ballOnHole && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level02 Screen Draw logic
|
||||
void DrawLevel02Screen(void)
|
||||
{
|
||||
// Draw Level02 screen
|
||||
|
||||
DrawCircleV(holeCirclePos, holeCircleRadius, LIGHTGRAY);
|
||||
DrawCircleV(bouncingBallPos, bouncingBallRadius, DARKGRAY);
|
||||
|
||||
DrawCircleLines(bouncingBallPos.x, bouncingBallPos.y, 120, Fade(LIGHTGRAY, 0.8f));
|
||||
|
||||
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 02", GetScreenWidth()/2 - MeasureText("LEVEL 02", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 02", GetScreenWidth()/2 - MeasureText("LEVEL 02", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level02 Screen Unload logic
|
||||
void UnloadLevel02Screen(void)
|
||||
{
|
||||
// TODO: Unload Level02 screen variables here!
|
||||
}
|
||||
|
||||
// Level02 Screen should finish?
|
||||
int FinishLevel02Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
// Calculate distance between two points
|
||||
float Vector2Distance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
float dx = v2.x - v1.x;
|
||||
float dy = v2.y - v1.y;
|
||||
|
||||
result = sqrt(dx*dx + dy*dy);
|
||||
|
||||
return result;
|
||||
}
|
134
games/just_do_GGJ2015/src/screens/screen_level03.c
Normal file
134
games/just_do_GGJ2015/src/screens/screen_level03.c
Normal file
@ -0,0 +1,134 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level03 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level03 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle holeRec, pieceRec;
|
||||
static bool showPiece = false;
|
||||
static bool pieceSelected = false;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level03 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level03 Screen Initialization logic
|
||||
void InitLevel03Screen(void)
|
||||
{
|
||||
// Initialize Level03 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
holeRec = (Rectangle){ GetScreenWidth()/2 - 50, GetScreenHeight()/2 - 50, 100, 100 };
|
||||
pieceRec = (Rectangle){ 200, 400, 100, 100 };
|
||||
}
|
||||
|
||||
// Level03 Screen Update logic
|
||||
void UpdateLevel03Screen(void)
|
||||
{
|
||||
// Update Level03 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
Vector2 mousePos = GetMousePosition();
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePos, holeRec)) showPiece = true;
|
||||
else showPiece = false;
|
||||
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointRec(mousePos, pieceRec))
|
||||
{
|
||||
pieceSelected = true;
|
||||
|
||||
pieceRec.x = ((int)mousePos.x - 50);
|
||||
pieceRec.y = ((int)mousePos.y - 50);
|
||||
}
|
||||
}
|
||||
|
||||
if ((pieceRec.x == holeRec.x) && !(CheckCollisionPointRec(mousePos, holeRec)))
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level03 Screen Draw logic
|
||||
void DrawLevel03Screen(void)
|
||||
{
|
||||
// Draw Level03 screen
|
||||
DrawRectangleRec(holeRec, GRAY);
|
||||
DrawRectangleRec(pieceRec, RAYWHITE);
|
||||
|
||||
if (showPiece) DrawRectangleLines(pieceRec.x, pieceRec.y, pieceRec.width, pieceRec.height, Fade(LIGHTGRAY, 0.8f));
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 03", GetScreenWidth()/2 - MeasureText("LEVEL 03", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 03", GetScreenWidth()/2 - MeasureText("LEVEL 03", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level03 Screen Unload logic
|
||||
void UnloadLevel03Screen(void)
|
||||
{
|
||||
// TODO: Unload Level03 screen variables here!
|
||||
}
|
||||
|
||||
// Level03 Screen should finish?
|
||||
int FinishLevel03Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
147
games/just_do_GGJ2015/src/screens/screen_level04.c
Normal file
147
games/just_do_GGJ2015/src/screens/screen_level04.c
Normal file
@ -0,0 +1,147 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level04 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level04 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Vector2 circlesCenter;
|
||||
static float innerCircleRadius = 40;
|
||||
static float outerCircleRadius = 300;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level04 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level04 Screen Initialization logic
|
||||
void InitLevel04Screen(void)
|
||||
{
|
||||
// Initialize Level04 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
circlesCenter = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 };
|
||||
}
|
||||
|
||||
// Level04 Screen Update logic
|
||||
void UpdateLevel04Screen(void)
|
||||
{
|
||||
// Update Level04 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (IsMouseButtonDown(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointCircle(GetMousePosition(), circlesCenter, innerCircleRadius))
|
||||
{
|
||||
innerCircleRadius += 2;
|
||||
}
|
||||
else if (CheckCollisionPointCircle(GetMousePosition(), circlesCenter, outerCircleRadius))
|
||||
{
|
||||
outerCircleRadius += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
outerCircleRadius -= 2;
|
||||
|
||||
if (outerCircleRadius <= 260) outerCircleRadius = 260;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!done)
|
||||
{
|
||||
innerCircleRadius -= 2;
|
||||
if (outerCircleRadius > 300) outerCircleRadius -= 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (innerCircleRadius >= 270) innerCircleRadius = 270;
|
||||
else if (innerCircleRadius <= 40) innerCircleRadius = 40;
|
||||
|
||||
if (outerCircleRadius >= 600) outerCircleRadius = 600;
|
||||
|
||||
if (innerCircleRadius >= outerCircleRadius)
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level04 Screen Draw logic
|
||||
void DrawLevel04Screen(void)
|
||||
{
|
||||
// Draw Level04 screen here!
|
||||
//DrawRectangle(0, 0, GetScreenWidth(), GetScreenHeight(), GRAY);
|
||||
DrawCircleV(circlesCenter, outerCircleRadius, GRAY);
|
||||
DrawCircleV(circlesCenter, innerCircleRadius, RAYWHITE);
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 04", GetScreenWidth()/2 - MeasureText("LEVEL 04", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 04", GetScreenWidth()/2 - MeasureText("LEVEL 04", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level04 Screen Unload logic
|
||||
void UnloadLevel04Screen(void)
|
||||
{
|
||||
// TODO: Unload Level04 screen variables here!
|
||||
}
|
||||
|
||||
// Level04 Screen should finish?
|
||||
int FinishLevel04Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
185
games/just_do_GGJ2015/src/screens/screen_level05.c
Normal file
185
games/just_do_GGJ2015/src/screens/screen_level05.c
Normal file
@ -0,0 +1,185 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level05 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#define NUM_CIRCLES 10
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level05 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Vector2 circleCenter;
|
||||
static float circleRadius[NUM_CIRCLES];
|
||||
static bool circleLocked[NUM_CIRCLES];
|
||||
static Color circleColor[NUM_CIRCLES];
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level05 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool CheckColor(Color col1, Color col2);
|
||||
|
||||
// Level05 Screen Initialization logic
|
||||
void InitLevel05Screen(void)
|
||||
{
|
||||
// Initialize Level05 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
circleCenter = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 };
|
||||
|
||||
for (int i = 0; i < NUM_CIRCLES; i++)
|
||||
{
|
||||
circleRadius[i] = 760/NUM_CIRCLES*(NUM_CIRCLES - i);
|
||||
circleLocked[i] = false;
|
||||
}
|
||||
|
||||
// That's a dirty hack to give sonme coherence to this puzzle...
|
||||
circleColor[9] = GRAY;
|
||||
circleColor[8] = RAYWHITE;
|
||||
circleColor[7] = RAYWHITE;
|
||||
circleColor[6] = GRAY;
|
||||
circleColor[5] = RAYWHITE;
|
||||
circleColor[4] = GRAY;
|
||||
circleColor[3] = GRAY;
|
||||
circleColor[2] = GRAY;
|
||||
circleColor[1] = RAYWHITE;
|
||||
circleColor[0] = GRAY;
|
||||
}
|
||||
|
||||
// Level05 Screen Update logic
|
||||
void UpdateLevel05Screen(void)
|
||||
{
|
||||
// Update Level05 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
for (int i = NUM_CIRCLES - 1; i >= 0; i--)
|
||||
{
|
||||
if (CheckCollisionPointCircle(GetMousePosition(), circleCenter, circleRadius[i]))
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
if (CheckColor(circleColor[8], GRAY)) circleColor[8] = RAYWHITE;
|
||||
else circleColor[8] = GRAY;
|
||||
}
|
||||
else if (i == 2)
|
||||
{
|
||||
if (CheckColor(circleColor[5], GRAY)) circleColor[5] = RAYWHITE;
|
||||
else circleColor[5] = GRAY;
|
||||
}
|
||||
else if (i == 3)
|
||||
{
|
||||
if (CheckColor(circleColor[6], GRAY)) circleColor[6] = RAYWHITE;
|
||||
else circleColor[6] = GRAY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (CheckColor(circleColor[i], GRAY)) circleColor[i] = RAYWHITE;
|
||||
else circleColor[i] = GRAY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check all cicles done
|
||||
for (int i = 0; i < NUM_CIRCLES; i++)
|
||||
{
|
||||
done = true;
|
||||
|
||||
if (CheckColor(circleColor[i], RAYWHITE))
|
||||
{
|
||||
done = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//if (done) PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level05 Screen Draw logic
|
||||
void DrawLevel05Screen(void)
|
||||
{
|
||||
// Draw Level05 screen
|
||||
for (int i = 0; i < NUM_CIRCLES; i++)
|
||||
{
|
||||
DrawPoly(circleCenter, 64, circleRadius[i], 0.0f, circleColor[i]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 05", GetScreenWidth()/2 - MeasureText("LEVEL 05", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 05", GetScreenWidth()/2 - MeasureText("LEVEL 05", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level05 Screen Unload logic
|
||||
void UnloadLevel05Screen(void)
|
||||
{
|
||||
// TODO: Unload Level05 screen variables here!
|
||||
}
|
||||
|
||||
// Level05 Screen should finish?
|
||||
int FinishLevel05Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
static bool CheckColor(Color col1, Color col2)
|
||||
{
|
||||
return ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a));
|
||||
}
|
156
games/just_do_GGJ2015/src/screens/screen_level06.c
Normal file
156
games/just_do_GGJ2015/src/screens/screen_level06.c
Normal file
@ -0,0 +1,156 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level06 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level06 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle centerRec;
|
||||
|
||||
static Rectangle movingRecs[4];
|
||||
static int speedRecs[4];
|
||||
static bool stoppedRec[4];
|
||||
static int mouseOverNum = -1;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level06 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level06 Screen Initialization logic
|
||||
void InitLevel06Screen(void)
|
||||
{
|
||||
// Initialize Level06 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
centerRec = (Rectangle){ GetScreenWidth()/2 - 100, 0, 200, GetScreenHeight() };
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
movingRecs[i] = (Rectangle){ GetRandomValue(0, 5)*150, (i*150) + 90, 100, 100 };
|
||||
stoppedRec[i] = false;
|
||||
speedRecs[i] = GetRandomValue(4, 8);
|
||||
}
|
||||
}
|
||||
|
||||
// Level06 Screen Update logic
|
||||
void UpdateLevel06Screen(void)
|
||||
{
|
||||
// Update Level06 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (!stoppedRec[i]) movingRecs[i].x += speedRecs[i];
|
||||
|
||||
if (movingRecs[i].x >= GetScreenWidth()) movingRecs[i].x = -movingRecs[i].width;
|
||||
|
||||
if (CheckCollisionPointRec(GetMousePosition(), movingRecs[i]))
|
||||
{
|
||||
mouseOverNum = i;
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (i == 0) stoppedRec[3] = !stoppedRec[3];
|
||||
else if (i == 1) stoppedRec[2] = !stoppedRec[2];
|
||||
else if (i == 2) stoppedRec[0] = !stoppedRec[0];
|
||||
else if (i == 3) stoppedRec[1] = !stoppedRec[1];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if all boxes are aligned
|
||||
if (((movingRecs[0].x > centerRec.x) && ((movingRecs[0].x + movingRecs[0].width) < (centerRec.x + centerRec.width))) &&
|
||||
((movingRecs[1].x > centerRec.x) && ((movingRecs[1].x + movingRecs[1].width) < (centerRec.x + centerRec.width))) &&
|
||||
((movingRecs[2].x > centerRec.x) && ((movingRecs[2].x + movingRecs[2].width) < (centerRec.x + centerRec.width))) &&
|
||||
((movingRecs[3].x > centerRec.x) && ((movingRecs[3].x + movingRecs[3].width) < (centerRec.x + centerRec.width))))
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level06 Screen Draw logic
|
||||
void DrawLevel06Screen(void)
|
||||
{
|
||||
// Draw Level06 screen
|
||||
DrawRectangleRec(centerRec, LIGHTGRAY);
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
DrawRectangleRec(movingRecs[i], GRAY);
|
||||
}
|
||||
|
||||
if (!done & (mouseOverNum >= 0)) DrawRectangleLines(movingRecs[mouseOverNum].x - 5, movingRecs[mouseOverNum].y - 5, movingRecs[mouseOverNum].width + 10, movingRecs[mouseOverNum].height + 10, Fade(LIGHTGRAY, 0.8f));
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 06", GetScreenWidth()/2 - MeasureText("LEVEL 06", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 06", GetScreenWidth()/2 - MeasureText("LEVEL 06", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level06 Screen Unload logic
|
||||
void UnloadLevel06Screen(void)
|
||||
{
|
||||
// TODO: Unload Level06 screen variables here!
|
||||
}
|
||||
|
||||
// Level06 Screen should finish?
|
||||
int FinishLevel06Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
178
games/just_do_GGJ2015/src/screens/screen_level07.c
Normal file
178
games/just_do_GGJ2015/src/screens/screen_level07.c
Normal file
@ -0,0 +1,178 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level07 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level07 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Vector2 leftCirclePos, middleCirclePos, rightCirclePos;
|
||||
static Vector2 leftBtnPos, middleBtnPos, rightBtnPos;
|
||||
static float circleRadius = 100;
|
||||
static float btnRadius = 80;
|
||||
|
||||
static bool leftCircleActive, middleCircleActive, rightCircleActive;
|
||||
static Color leftCircleColor, middleCircleColor, rightCircleColor;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level07 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool CheckColor(Color col1, Color col2);
|
||||
|
||||
// Level07 Screen Initialization logic
|
||||
void InitLevel07Screen(void)
|
||||
{
|
||||
// Initialize Level07 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
leftCirclePos = (Vector2){ GetScreenWidth()/2 - 340, GetScreenHeight()/2 - 100 };
|
||||
middleCirclePos = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 - 100 };
|
||||
rightCirclePos = (Vector2){ GetScreenWidth()/2 + 340, GetScreenHeight()/2 - 100 };
|
||||
|
||||
leftBtnPos = (Vector2){ GetScreenWidth()/2 - 340, GetScreenHeight()/2 + 120 };
|
||||
middleBtnPos = (Vector2){ GetScreenWidth()/2, GetScreenHeight()/2 + 120 };
|
||||
rightBtnPos = (Vector2){ GetScreenWidth()/2 + 340, GetScreenHeight()/2 + 120 };
|
||||
|
||||
leftCircleActive = false;
|
||||
middleCircleActive = true;
|
||||
rightCircleActive = false;
|
||||
|
||||
leftCircleColor = GRAY;
|
||||
middleCircleColor = GRAY;
|
||||
rightCircleColor = GRAY;
|
||||
}
|
||||
|
||||
// Level07 Screen Update logic
|
||||
void UpdateLevel07Screen(void)
|
||||
{
|
||||
// Update Level07 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointCircle(GetMousePosition(), leftBtnPos, btnRadius)) leftCircleActive = !leftCircleActive;
|
||||
else if (CheckCollisionPointCircle(GetMousePosition(), middleBtnPos, btnRadius)) middleCircleActive = !middleCircleActive;
|
||||
else if (CheckCollisionPointCircle(GetMousePosition(), rightBtnPos, btnRadius)) rightCircleActive = !rightCircleActive;
|
||||
|
||||
if (rightCircleActive && CheckCollisionPointCircle(GetMousePosition(), leftCirclePos, circleRadius))
|
||||
{
|
||||
if (CheckColor(leftCircleColor, GRAY)) leftCircleColor = LIGHTGRAY;
|
||||
else leftCircleColor = GRAY;
|
||||
}
|
||||
|
||||
if (middleCircleActive && CheckCollisionPointCircle(GetMousePosition(), middleCirclePos, circleRadius))
|
||||
{
|
||||
if (CheckColor(middleCircleColor, GRAY)) middleCircleColor = LIGHTGRAY;
|
||||
else middleCircleColor = GRAY;
|
||||
}
|
||||
|
||||
if (rightCircleActive && leftCircleActive && CheckCollisionPointCircle(GetMousePosition(), rightCirclePos, circleRadius))
|
||||
{
|
||||
if (CheckColor(rightCircleColor, GRAY)) rightCircleColor = LIGHTGRAY;
|
||||
else rightCircleColor = GRAY;
|
||||
}
|
||||
}
|
||||
|
||||
// Check all cicles done
|
||||
if (CheckColor(leftCircleColor, LIGHTGRAY) && CheckColor(middleCircleColor, LIGHTGRAY) && CheckColor(rightCircleColor, LIGHTGRAY) &&
|
||||
!leftCircleActive && !middleCircleActive && !rightCircleActive)
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level07 Screen Draw logic
|
||||
void DrawLevel07Screen(void)
|
||||
{
|
||||
// Draw Level07 screen here!
|
||||
DrawCircleV(leftCirclePos, circleRadius, leftCircleColor);
|
||||
DrawCircleV(middleCirclePos, circleRadius, middleCircleColor);
|
||||
DrawCircleV(rightCirclePos, circleRadius, rightCircleColor);
|
||||
|
||||
if (leftCircleActive) DrawCircleV(leftBtnPos, btnRadius, GRAY);
|
||||
else DrawCircleV(leftBtnPos, btnRadius, LIGHTGRAY);
|
||||
|
||||
if (middleCircleActive) DrawCircleV(middleBtnPos, btnRadius, GRAY);
|
||||
else DrawCircleV(middleBtnPos, btnRadius, LIGHTGRAY);
|
||||
|
||||
if (rightCircleActive) DrawCircleV(rightBtnPos, btnRadius, GRAY);
|
||||
else DrawCircleV(rightBtnPos, btnRadius, LIGHTGRAY);
|
||||
|
||||
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 07", GetScreenWidth()/2 - MeasureText("LEVEL 07", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 07", GetScreenWidth()/2 - MeasureText("LEVEL 07", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level07 Screen Unload logic
|
||||
void UnloadLevel07Screen(void)
|
||||
{
|
||||
// TODO: Unload Level07 screen variables here!
|
||||
}
|
||||
|
||||
// Level07 Screen should finish?
|
||||
int FinishLevel07Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
static bool CheckColor(Color col1, Color col2)
|
||||
{
|
||||
return ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a));
|
||||
}
|
157
games/just_do_GGJ2015/src/screens/screen_level08.c
Normal file
157
games/just_do_GGJ2015/src/screens/screen_level08.c
Normal file
@ -0,0 +1,157 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level08 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level08 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle leftColumnRec, middleColumnRec, rightColumnRec;
|
||||
static Rectangle movingBox;
|
||||
static int moveSpeed = 4;
|
||||
|
||||
static bool leftColumnActive, middleColumnActive, rightColumnActive;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level08 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level08 Screen Initialization logic
|
||||
void InitLevel08Screen(void)
|
||||
{
|
||||
// TODO: Initialize Level08 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
movingBox = (Rectangle){ 20, GetScreenHeight()/2 - 20, 40, 40 };
|
||||
|
||||
leftColumnRec = (Rectangle){ 240, 0, 100, GetScreenHeight() };
|
||||
middleColumnRec = (Rectangle){ GetScreenWidth()/2 - 50, 0, 100, GetScreenHeight() };
|
||||
rightColumnRec = (Rectangle){ 920, 0, 100, GetScreenHeight() };
|
||||
|
||||
leftColumnActive = true;
|
||||
middleColumnActive = false;
|
||||
rightColumnActive = true;
|
||||
}
|
||||
|
||||
// Level08 Screen Update logic
|
||||
void UpdateLevel08Screen(void)
|
||||
{
|
||||
// Update Level08 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
movingBox.x += moveSpeed;
|
||||
|
||||
if (movingBox.x <= 0) moveSpeed *= -1;
|
||||
|
||||
if ((leftColumnActive && (CheckCollisionRecs(leftColumnRec, movingBox))) ||
|
||||
(middleColumnActive && (CheckCollisionRecs(middleColumnRec, movingBox))) ||
|
||||
(rightColumnActive && (CheckCollisionRecs(rightColumnRec, movingBox)))) moveSpeed *= -1;
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), leftColumnRec))
|
||||
{
|
||||
middleColumnActive = false;
|
||||
rightColumnActive = true;
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), middleColumnRec))
|
||||
{
|
||||
rightColumnActive = false;
|
||||
leftColumnActive = true;
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), rightColumnRec))
|
||||
{
|
||||
leftColumnActive = false;
|
||||
middleColumnActive = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (movingBox.x >= 1100)
|
||||
{
|
||||
done = true;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level08 Screen Draw logic
|
||||
void DrawLevel08Screen(void)
|
||||
{
|
||||
// Draw Level08 screen
|
||||
DrawRectangle(1100, GetScreenHeight()/2 - 20, 40, 40, GRAY);
|
||||
|
||||
DrawRectangleRec(movingBox, LIGHTGRAY);
|
||||
|
||||
if (leftColumnActive) DrawRectangleRec(leftColumnRec, GRAY);
|
||||
if (middleColumnActive) DrawRectangleRec(middleColumnRec, GRAY);
|
||||
if (rightColumnActive) DrawRectangleRec(rightColumnRec, GRAY);
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 08", GetScreenWidth()/2 - MeasureText("LEVEL 08", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 08", GetScreenWidth()/2 - MeasureText("LEVEL 08", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level08 Screen Unload logic
|
||||
void UnloadLevel08Screen(void)
|
||||
{
|
||||
// TODO: Unload Level08 screen variables here!
|
||||
}
|
||||
|
||||
// Level08 Screen should finish?
|
||||
int FinishLevel08Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
199
games/just_do_GGJ2015/src/screens/screen_level09.c
Normal file
199
games/just_do_GGJ2015/src/screens/screen_level09.c
Normal file
@ -0,0 +1,199 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level09 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#define NUM_BOXES 21
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level09 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle bwRecs[NUM_BOXES];
|
||||
static Color bwColors[NUM_BOXES];
|
||||
static bool activated[NUM_BOXES];
|
||||
static int resetCounter = 0;
|
||||
static bool enableCounter = 0;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level09 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static bool CheckColor(Color col1, Color col2);
|
||||
|
||||
// Level09 Screen Initialization logic
|
||||
void InitLevel09Screen(void)
|
||||
{
|
||||
// Initialize Level09 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
for (int i = 0; i < NUM_BOXES; i++)
|
||||
{
|
||||
bwRecs[i].x = GetScreenWidth()/7*(i%7);
|
||||
bwRecs[i].y = GetScreenHeight()/3*(i/7);
|
||||
bwRecs[i].width = GetScreenWidth()/7;
|
||||
bwRecs[i].height = GetScreenHeight()/3;
|
||||
|
||||
activated[i] = false;
|
||||
|
||||
if (i%2 == 0) bwColors[i] = LIGHTGRAY;
|
||||
else bwColors[i] = GRAY;
|
||||
}
|
||||
|
||||
bwColors[10] = RAYWHITE;
|
||||
}
|
||||
|
||||
// Level09 Screen Update logic
|
||||
void UpdateLevel09Screen(void)
|
||||
{
|
||||
// Update Level09 screen variables here!
|
||||
framesCounter++;
|
||||
if (enableCounter) resetCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
for (int i = 0; i < NUM_BOXES; i++)
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), bwRecs[i]))
|
||||
{
|
||||
if (i == 10)
|
||||
{
|
||||
if (CheckColor(bwColors[i], RAYWHITE))
|
||||
{
|
||||
bwColors[i] = LIGHTGRAY;
|
||||
enableCounter = true;
|
||||
resetCounter = 0;
|
||||
activated[1] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
bwColors[i] = RAYWHITE;
|
||||
enableCounter = false;
|
||||
resetCounter = 5*60;
|
||||
|
||||
for (int i = 0; i < NUM_BOXES; i++) activated[i] = false;
|
||||
}
|
||||
}
|
||||
else if ((i%2 == 1) && enableCounter)
|
||||
{
|
||||
if (activated[i])
|
||||
{
|
||||
bwColors[i] = LIGHTGRAY;
|
||||
if (i != 19) activated[i + 2] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (resetCounter > (4*60 + 10))
|
||||
{
|
||||
for (int i = 0; i < NUM_BOXES; i++)
|
||||
{
|
||||
if (i%2 == 0) bwColors[i] = LIGHTGRAY;
|
||||
else bwColors[i] = GRAY;
|
||||
|
||||
activated[i] = false;
|
||||
}
|
||||
|
||||
bwColors[10] = RAYWHITE;
|
||||
enableCounter = false;
|
||||
resetCounter = 0;
|
||||
}
|
||||
|
||||
for (int i = 0; i < NUM_BOXES; i++)
|
||||
{
|
||||
done = true;
|
||||
|
||||
if (!CheckColor(bwColors[i], LIGHTGRAY))
|
||||
{
|
||||
done = false;
|
||||
return;
|
||||
}
|
||||
|
||||
//if (done) PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level09 Screen Draw logic
|
||||
void DrawLevel09Screen(void)
|
||||
{
|
||||
// Draw Level09 screen
|
||||
for (int i = 0; i < NUM_BOXES; i++)
|
||||
{
|
||||
DrawRectangleRec(bwRecs[i], bwColors[i]);
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(RAYWHITE, 0.6f));
|
||||
DrawText("LEVEL 09", GetScreenWidth()/2 - MeasureText("LEVEL 09", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 09", GetScreenWidth()/2 - MeasureText("LEVEL 09", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level09 Screen Unload logic
|
||||
void UnloadLevel09Screen(void)
|
||||
{
|
||||
// TODO: Unload Level09 screen variables here!
|
||||
}
|
||||
|
||||
// Level09 Screen should finish?
|
||||
int FinishLevel09Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
||||
|
||||
static bool CheckColor(Color col1, Color col2)
|
||||
{
|
||||
return ((col1.r == col2.r) && (col1.g == col2.g) && (col1.b == col2.b) && (col1.a == col2.a));
|
||||
}
|
153
games/just_do_GGJ2015/src/screens/screen_level10.c
Normal file
153
games/just_do_GGJ2015/src/screens/screen_level10.c
Normal file
@ -0,0 +1,153 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Level10 Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level10 screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
static Rectangle leftColumnRec, middleColumnRec, rightColumnRec;
|
||||
static Rectangle movingBox;
|
||||
static int moveSpeed = 4;
|
||||
|
||||
static bool leftColumnActive, middleColumnActive, rightColumnActive;
|
||||
|
||||
static bool done = false;
|
||||
static int levelTimeSec = 0;
|
||||
static bool levelFinished = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level10 Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Level10 Screen Initialization logic
|
||||
void InitLevel10Screen(void)
|
||||
{
|
||||
// TODO: Initialize Level10 screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
movingBox = (Rectangle){ 20, GetScreenHeight()/2 - 20, 40, 40 };
|
||||
|
||||
leftColumnRec = (Rectangle){ 240, 0, 100, GetScreenHeight() };
|
||||
middleColumnRec = (Rectangle){ GetScreenWidth()/2 - 50, 0, 100, GetScreenHeight() };
|
||||
rightColumnRec = (Rectangle){ 920, 0, 100, GetScreenHeight() };
|
||||
|
||||
leftColumnActive = true;
|
||||
middleColumnActive = false;
|
||||
rightColumnActive = true;
|
||||
}
|
||||
|
||||
// Level10 Screen Update logic
|
||||
void UpdateLevel10Screen(void)
|
||||
{
|
||||
// Update Level10 screen variables here!
|
||||
framesCounter++;
|
||||
|
||||
if (!done)
|
||||
{
|
||||
movingBox.x += moveSpeed;
|
||||
|
||||
if (movingBox.x <= 0) moveSpeed *= -1;
|
||||
|
||||
if ((leftColumnActive && (CheckCollisionRecs(leftColumnRec, movingBox))) ||
|
||||
(middleColumnActive && (CheckCollisionRecs(middleColumnRec, movingBox))) ||
|
||||
(rightColumnActive && (CheckCollisionRecs(rightColumnRec, movingBox)))) moveSpeed *= -1;
|
||||
|
||||
if (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))
|
||||
{
|
||||
if (CheckCollisionPointRec(GetMousePosition(), leftColumnRec))
|
||||
{
|
||||
middleColumnActive = false;
|
||||
rightColumnActive = true;
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), middleColumnRec))
|
||||
{
|
||||
rightColumnActive = false;
|
||||
leftColumnActive = true;
|
||||
}
|
||||
else if (CheckCollisionPointRec(GetMousePosition(), rightColumnRec))
|
||||
{
|
||||
leftColumnActive = false;
|
||||
middleColumnActive = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (movingBox.x >= 1100) done = true;
|
||||
|
||||
if (done && !levelFinished)
|
||||
{
|
||||
levelTimeSec = framesCounter/60;
|
||||
levelFinished = true;
|
||||
framesCounter = 0;
|
||||
}
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if ((framesCounter > 90) && (IsMouseButtonPressed(MOUSE_LEFT_BUTTON))) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Level10 Screen Draw logic
|
||||
void DrawLevel10Screen(void)
|
||||
{
|
||||
// Draw Level10 screen
|
||||
DrawRectangle(1100, GetScreenHeight()/2 - 20, 40, 40, GRAY);
|
||||
|
||||
DrawRectangleRec(movingBox, LIGHTGRAY);
|
||||
|
||||
if (leftColumnActive) DrawRectangleRec(leftColumnRec, GRAY);
|
||||
if (middleColumnActive) DrawRectangleRec(middleColumnRec, GRAY);
|
||||
if (rightColumnActive) DrawRectangleRec(rightColumnRec, GRAY);
|
||||
|
||||
if (levelFinished)
|
||||
{
|
||||
DrawRectangleBordersRec((Rectangle){0, 0, GetScreenWidth(), GetScreenHeight()}, 0, 0, 60, Fade(LIGHTGRAY, 0.6f));
|
||||
DrawText("LEVEL 08", GetScreenWidth()/2 - MeasureText("LEVEL 08", 30)/2, 20, 30, GRAY);
|
||||
DrawText(FormatText("DONE! (Seconds: %03i)", levelTimeSec), GetScreenWidth()/2 - MeasureText("DONE! (Seconds: 000)", 30)/2, GetScreenHeight() - 40, 30, GRAY);
|
||||
}
|
||||
else DrawText("LEVEL 08", GetScreenWidth()/2 - MeasureText("LEVEL 08", 30)/2, 20, 30, LIGHTGRAY);
|
||||
}
|
||||
|
||||
// Level10 Screen Unload logic
|
||||
void UnloadLevel10Screen(void)
|
||||
{
|
||||
// TODO: Unload Level10 screen variables here!
|
||||
}
|
||||
|
||||
// Level10 Screen should finish?
|
||||
int FinishLevel10Screen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
227
games/just_do_GGJ2015/src/screens/screen_logo.c
Normal file
227
games/just_do_GGJ2015/src/screens/screen_logo.c
Normal file
@ -0,0 +1,227 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Logo Screen Functions Definitions (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "screens.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition (local to this module)
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Logo screen global variables
|
||||
static int framesCounter;
|
||||
static int finishScreen;
|
||||
|
||||
const char msgLogoA[64] = "A simple and easy-to-use library";
|
||||
const char msgLogoB[64] = "to learn videogames programming";
|
||||
|
||||
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;
|
||||
|
||||
int lettersCounter = 0;
|
||||
char msgBuffer[128] = { ' ' };
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Logo Screen Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Logo Screen Initialization logic
|
||||
void InitLogoScreen(void)
|
||||
{
|
||||
// Initialize LOGO screen variables here!
|
||||
framesCounter = 0;
|
||||
finishScreen = 0;
|
||||
|
||||
logoPositionX = GetScreenWidth()/2 - 128;
|
||||
logoPositionY = GetScreenHeight()/2 - 128;
|
||||
}
|
||||
|
||||
// Logo Screen Update logic
|
||||
void UpdateLogoScreen(void)
|
||||
{
|
||||
// Update LOGO screen
|
||||
framesCounter++; // Count frames
|
||||
|
||||
// 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;
|
||||
PlaySound(levelWin);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Wait for 2 seconds (60 frames) before jumping to TITLE screen
|
||||
if (msgLogoBDone)
|
||||
{
|
||||
framesCounter++;
|
||||
|
||||
if (framesCounter > 90) finishScreen = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Logo Screen Draw logic
|
||||
void DrawLogoScreen(void)
|
||||
{
|
||||
// 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(GetScreenWidth()/2 - 112, GetScreenHeight()/2 - 112 - 60, 224, 224, RAYWHITE);
|
||||
|
||||
DrawText(raylib, GetScreenWidth()/2 - 44, GetScreenHeight()/2 + 48 - 60, 50, BLACK);
|
||||
|
||||
if (!msgLogoADone) DrawText(msgBuffer, GetScreenWidth()/2 - MeasureText(msgLogoA, 30)/2, logoPositionY + 230, 30, GRAY);
|
||||
else
|
||||
{
|
||||
DrawText(msgLogoA, GetScreenWidth()/2 - MeasureText(msgLogoA, 30)/2, logoPositionY + 230, 30, GRAY);
|
||||
|
||||
if (!msgLogoBDone) DrawText(msgBuffer, GetScreenWidth()/2 - MeasureText(msgLogoB, 30)/2, logoPositionY + 280, 30, GRAY);
|
||||
else
|
||||
{
|
||||
DrawText(msgLogoB, GetScreenWidth()/2 - MeasureText(msgLogoA, 30)/2, logoPositionY + 280, 30, GRAY);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Logo Screen Unload logic
|
||||
void UnloadLogoScreen(void)
|
||||
{
|
||||
// TODO: Unload LOGO screen variables here!
|
||||
}
|
||||
|
||||
// Logo Screen should finish?
|
||||
int FinishLogoScreen(void)
|
||||
{
|
||||
return finishScreen;
|
||||
}
|
150
games/just_do_GGJ2015/src/screens/screens.h
Normal file
150
games/just_do_GGJ2015/src/screens/screens.h
Normal file
@ -0,0 +1,150 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib - Standard Game template
|
||||
*
|
||||
* Screens Functions Declarations (Init, Update, Draw, Unload)
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#ifndef SCREENS_H
|
||||
#define SCREENS_H
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
typedef enum GameScreen { LOGO, LEVEL00, LEVEL01, LEVEL02, LEVEL03, LEVEL04, LEVEL05, LEVEL06, LEVEL07, LEVEL08, LEVEL09 } GameScreen;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
GameScreen currentScreen;
|
||||
Sound levelWin;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Logo Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLogoScreen(void);
|
||||
void UpdateLogoScreen(void);
|
||||
void DrawLogoScreen(void);
|
||||
void UnloadLogoScreen(void);
|
||||
int FinishLogoScreen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level00 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel00Screen(void);
|
||||
void UpdateLevel00Screen(void);
|
||||
void DrawLevel00Screen(void);
|
||||
void UnloadLevel00Screen(void);
|
||||
int FinishLevel00Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level01 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel01Screen(void);
|
||||
void UpdateLevel01Screen(void);
|
||||
void DrawLevel01Screen(void);
|
||||
void UnloadLevel01Screen(void);
|
||||
int FinishLevel01Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level02 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel02Screen(void);
|
||||
void UpdateLevel02Screen(void);
|
||||
void DrawLevel02Screen(void);
|
||||
void UnloadLevel02Screen(void);
|
||||
int FinishLevel02Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level03 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel03Screen(void);
|
||||
void UpdateLevel03Screen(void);
|
||||
void DrawLevel03Screen(void);
|
||||
void UnloadLevel03Screen(void);
|
||||
int FinishLevel03Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level04 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel04Screen(void);
|
||||
void UpdateLevel04Screen(void);
|
||||
void DrawLevel04Screen(void);
|
||||
void UnloadLevel04Screen(void);
|
||||
int FinishLevel04Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level05 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel05Screen(void);
|
||||
void UpdateLevel05Screen(void);
|
||||
void DrawLevel05Screen(void);
|
||||
void UnloadLevel05Screen(void);
|
||||
int FinishLevel05Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level06 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel06Screen(void);
|
||||
void UpdateLevel06Screen(void);
|
||||
void DrawLevel06Screen(void);
|
||||
void UnloadLevel06Screen(void);
|
||||
int FinishLevel06Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level07 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel07Screen(void);
|
||||
void UpdateLevel07Screen(void);
|
||||
void DrawLevel07Screen(void);
|
||||
void UnloadLevel07Screen(void);
|
||||
int FinishLevel07Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level08 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel08Screen(void);
|
||||
void UpdateLevel08Screen(void);
|
||||
void DrawLevel08Screen(void);
|
||||
void UnloadLevel08Screen(void);
|
||||
int FinishLevel08Screen(void);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Level09 Screen Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
void InitLevel09Screen(void);
|
||||
void UpdateLevel09Screen(void);
|
||||
void DrawLevel09Screen(void);
|
||||
void UnloadLevel09Screen(void);
|
||||
int FinishLevel09Screen(void);
|
||||
|
||||
|
||||
void DrawRectangleBordersRec(Rectangle rec, int offsetX, int offsetY, int borderSize, Color col);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // SCREENS_H
|
23
src/audio.c
23
src/audio.c
@ -39,7 +39,8 @@
|
||||
#include "utils.h" // rRES data decompression utility function
|
||||
// NOTE: Includes Android fopen function map
|
||||
|
||||
#include "stb_vorbis.h" // OGG loading functions
|
||||
//#define STB_VORBIS_HEADER_ONLY
|
||||
#include "stb_vorbis.h" // OGG loading functions
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
@ -49,7 +50,7 @@
|
||||
#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
|
||||
#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
|
||||
@ -201,7 +202,7 @@ 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
|
||||
@ -283,7 +284,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId)
|
||||
|
||||
FILE *rresFile = fopen(rresName, "rb");
|
||||
|
||||
if (rresFile == NULL)
|
||||
if (rresFile == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
|
||||
}
|
||||
@ -378,7 +379,7 @@ 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
|
||||
@ -574,6 +575,7 @@ void PauseMusicStream(void)
|
||||
{
|
||||
TraceLog(INFO, "Pausing music stream");
|
||||
alSourcePause(currentMusic.source);
|
||||
musicEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -581,10 +583,14 @@ void PauseMusicStream(void)
|
||||
void ResumeMusicStream(void)
|
||||
{
|
||||
// Resume music playing... if music available!
|
||||
if (musicEnabled)
|
||||
ALenum state;
|
||||
alGetSourcei(currentMusic.source, AL_SOURCE_STATE, &state);
|
||||
|
||||
if (state == AL_PAUSED)
|
||||
{
|
||||
TraceLog(INFO, "Resume music stream");
|
||||
TraceLog(INFO, "Resuming music stream");
|
||||
alSourcePlay(currentMusic.source);
|
||||
musicEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -865,13 +871,12 @@ static Wave LoadOGG(char *fileName)
|
||||
|
||||
TraceLog(DEBUG, "[%s] Total samples calculated: %i", fileName, totalSamples);
|
||||
|
||||
//short *data
|
||||
wave.data = malloc(sizeof(short)*totalSamplesLength);
|
||||
|
||||
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);
|
||||
|
455
src/camera.c
Normal file
455
src/camera.c
Normal file
@ -0,0 +1,455 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.camera
|
||||
*
|
||||
* Camera Modes Setup and Control Functions
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include <math.h>
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
// CAMERA_GENERIC
|
||||
#define CAMERA_SCROLL_SENSITIVITY 1.5
|
||||
|
||||
// FREE_CAMERA
|
||||
#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01
|
||||
#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3
|
||||
#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120
|
||||
#define FREE_CAMERA_MIN_CLAMP 85
|
||||
#define FREE_CAMERA_MAX_CLAMP -85
|
||||
#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05
|
||||
#define FREE_CAMERA_PANNING_DIVIDER 5.1
|
||||
|
||||
// ORBITAL_CAMERA
|
||||
#define ORBITAL_CAMERA_SPEED 0.01
|
||||
|
||||
// FIRST_PERSON
|
||||
//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003
|
||||
#define FIRST_PERSON_FOCUS_DISTANCE 25
|
||||
#define FIRST_PERSON_MIN_CLAMP 85
|
||||
#define FIRST_PERSON_MAX_CLAMP -85
|
||||
|
||||
#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0
|
||||
#define FIRST_PERSON_STEP_DIVIDER 30.0
|
||||
#define FIRST_PERSON_WAVING_DIVIDER 200.0
|
||||
|
||||
#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85
|
||||
|
||||
// THIRD_PERSON
|
||||
//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003
|
||||
#define THIRD_PERSON_DISTANCE_CLAMP 1.2
|
||||
#define THIRD_PERSON_MIN_CLAMP 5
|
||||
#define THIRD_PERSON_MAX_CLAMP -85
|
||||
#define THIRD_PERSON_OFFSET (Vector3){ 0.4, 0, 0 }
|
||||
|
||||
// PLAYER (used by camera)
|
||||
#define PLAYER_WIDTH 0.4
|
||||
#define PLAYER_HEIGHT 0.9
|
||||
#define PLAYER_DEPTH 0.4
|
||||
#define PLAYER_MOVEMENT_DIVIDER 20.0
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
static Camera internalCamera = {{2,0,2},{0,0,0},{0,1,0}};
|
||||
static Vector2 cameraAngle = { 0, 0 };
|
||||
static float cameraTargetDistance = 5;
|
||||
static Vector3 resetingPosition = { 0, 0, 0 };
|
||||
static int resetingKey = 'Z';
|
||||
static Vector2 cameraMousePosition = { 0, 0 };
|
||||
static Vector2 cameraMouseVariation = { 0, 0 };
|
||||
static float mouseSensitivity = 0.003;
|
||||
static int cameraMovementController[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' };
|
||||
static int cameraMovementCounter = 0;
|
||||
static bool cameraUseGravity = true;
|
||||
static int pawnControllingKey = MOUSE_MIDDLE_BUTTON;
|
||||
static int fnControllingKey = KEY_LEFT_ALT;
|
||||
static int smoothZoomControllingKey = KEY_LEFT_CONTROL;
|
||||
|
||||
static int cameraMode = CAMERA_CUSTOM;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
static void ProcessCamera(Camera *camera, Vector3 *playerPosition);
|
||||
/*
|
||||
static void SetCameraControls(int front, int left, int back, right, up, down);
|
||||
static void SetMouseSensitivity(int sensitivity);
|
||||
static void SetResetPosition(Vector3 resetPosition);
|
||||
static void SetResetControl(int resetKey);
|
||||
static void SetPawnControl(int pawnControlKey);
|
||||
static void SetFnControl(int fnControlKey);
|
||||
static void SetSmoothZoomControl(int smoothZoomControlKey);
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Select camera mode (multiple camera modes available)
|
||||
void SetCameraMode(int mode)
|
||||
{
|
||||
if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE))
|
||||
{
|
||||
cameraMode = CAMERA_THIRD_PERSON;
|
||||
cameraTargetDistance = 5;
|
||||
cameraAngle.y = -40 * DEG2RAD;
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
}
|
||||
else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL))
|
||||
{
|
||||
cameraMode = CAMERA_THIRD_PERSON;
|
||||
cameraTargetDistance = 5;
|
||||
cameraAngle.y = -40 * DEG2RAD;
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
}
|
||||
else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE))
|
||||
{
|
||||
cameraTargetDistance = 10;
|
||||
cameraAngle.x = 45 * DEG2RAD;
|
||||
cameraAngle.y = -40 * DEG2RAD;
|
||||
internalCamera.target = (Vector3){ 0, 0, 0};
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
}
|
||||
else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL))
|
||||
{
|
||||
cameraTargetDistance = 10;
|
||||
cameraAngle.x = 225 * DEG2RAD;
|
||||
cameraAngle.y = -40 * DEG2RAD;
|
||||
internalCamera.target = (Vector3){ 3, 0, 3};
|
||||
ProcessCamera(&internalCamera, &internalCamera.position);
|
||||
}
|
||||
|
||||
cameraMode = mode;
|
||||
}
|
||||
|
||||
// Update camera with position
|
||||
Camera UpdateCamera(Vector3 *position)
|
||||
{
|
||||
// Calculate camera
|
||||
if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position);
|
||||
|
||||
return internalCamera;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Process desired camera mode and controls
|
||||
static void ProcessCamera(Camera *camera, Vector3 *playerPosition)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) || defined(PLATFORM_RPI)
|
||||
// Mouse movement detection
|
||||
if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL))
|
||||
{
|
||||
HideCursor();
|
||||
|
||||
if (GetMousePosition().x < GetScreenHeight() / 3) SetMousePosition((Vector2){ GetScreenWidth() - GetScreenHeight() / 3, GetMousePosition().y});
|
||||
else if (GetMousePosition().y < GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, GetScreenHeight() - GetScreenHeight() / 3});
|
||||
else if (GetMousePosition().x > GetScreenWidth() - GetScreenHeight() / 3) SetMousePosition((Vector2) { GetScreenHeight() / 3, GetMousePosition().y});
|
||||
else if (GetMousePosition().y > GetScreenHeight() - GetScreenHeight() / 3) SetMousePosition((Vector2){ GetMousePosition().x, GetScreenHeight() / 3});
|
||||
else
|
||||
{
|
||||
cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowCursor();
|
||||
|
||||
cameraMouseVariation.x = GetMousePosition().x - cameraMousePosition.x;
|
||||
cameraMouseVariation.y = GetMousePosition().y - cameraMousePosition.y;
|
||||
}
|
||||
|
||||
cameraMousePosition = GetMousePosition();
|
||||
|
||||
// Support for multiple automatic camera modes
|
||||
switch (cameraMode)
|
||||
{
|
||||
case CAMERA_FREE:
|
||||
{
|
||||
// Camera zoom
|
||||
if ((cameraTargetDistance < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP;
|
||||
}
|
||||
// Camera looking down
|
||||
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
}
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
|
||||
if (camera->target.y < 0) camera->target.y = -0.001;
|
||||
}
|
||||
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (GetMouseWheelMove() > 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
// Camera looking up
|
||||
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_DISTANCE_MAX_CLAMP) && (GetMouseWheelMove() < 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
}
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
|
||||
{
|
||||
camera->target.x += GetMouseWheelMove() * (camera->target.x - camera->position.x) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.y += GetMouseWheelMove() * (camera->target.y - camera->position.y) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
camera->target.z += GetMouseWheelMove() * (camera->target.z - camera->position.z) * CAMERA_SCROLL_SENSITIVITY / cameraTargetDistance;
|
||||
|
||||
if (camera->target.y > 0) camera->target.y = 0.001;
|
||||
}
|
||||
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (GetMouseWheelMove() > 0))
|
||||
{
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
if (cameraTargetDistance < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP;
|
||||
}
|
||||
|
||||
// Inputs
|
||||
if (IsKeyDown(fnControllingKey))
|
||||
{
|
||||
if (IsKeyDown(smoothZoomControllingKey))
|
||||
{
|
||||
// Camera smooth zoom
|
||||
if (IsMouseButtonDown(pawnControllingKey)) cameraTargetDistance += (cameraMouseVariation.y * FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY);
|
||||
}
|
||||
// Camera orientation calculation
|
||||
else if (IsMouseButtonDown(pawnControllingKey))
|
||||
{
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
cameraAngle.y += cameraMouseVariation.y * -FREE_CAMERA_MOUSE_SENSITIVITY;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP * DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP * DEG2RAD;
|
||||
}
|
||||
}
|
||||
// Paning
|
||||
else if (IsMouseButtonDown(pawnControllingKey))
|
||||
{
|
||||
camera->target.x += ((cameraMouseVariation.x * -FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.x) + (cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * sin(cameraAngle.x) * sin(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.y += ((cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
camera->target.z += ((cameraMouseVariation.x * FREE_CAMERA_MOUSE_SENSITIVITY) * sin(cameraAngle.x) + (cameraMouseVariation.y * FREE_CAMERA_MOUSE_SENSITIVITY) * cos(cameraAngle.x) * sin(cameraAngle.y)) * (cameraTargetDistance / FREE_CAMERA_PANNING_DIVIDER);
|
||||
}
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown(resetingKey)) camera->target = resetingPosition;
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
} break;
|
||||
case CAMERA_ORBITAL:
|
||||
{
|
||||
cameraAngle.x += ORBITAL_CAMERA_SPEED;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
// Focus to center
|
||||
if (IsKeyDown('Z')) camera->target = (Vector3) { 0, 0, 0 };
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
|
||||
} break;
|
||||
case CAMERA_FIRST_PERSON:
|
||||
case CAMERA_THIRD_PERSON:
|
||||
{
|
||||
bool isMoving = false;
|
||||
|
||||
// Keyboard inputs
|
||||
if (IsKeyDown(cameraMovementController[0]))
|
||||
{
|
||||
playerPosition->x -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y += sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[2]))
|
||||
{
|
||||
playerPosition->x += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
if (!cameraUseGravity) camera->position.y -= sin(cameraAngle.y) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
|
||||
if (IsKeyDown(cameraMovementController[1]))
|
||||
{
|
||||
playerPosition->x -= cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z += sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[3]))
|
||||
{
|
||||
playerPosition->x += cos(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
playerPosition->z -= sin(cameraAngle.x) / PLAYER_MOVEMENT_DIVIDER;
|
||||
|
||||
isMoving = true;
|
||||
}
|
||||
|
||||
if (IsKeyDown(cameraMovementController[4]))
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y += 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
}
|
||||
else if (IsKeyDown(cameraMovementController[5]))
|
||||
{
|
||||
if (!cameraUseGravity) playerPosition->y -= 1 / PLAYER_MOVEMENT_DIVIDER;
|
||||
}
|
||||
|
||||
if (cameraMode == CAMERA_THIRD_PERSON)
|
||||
{
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y * -mouseSensitivity;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
|
||||
// Camera zoom
|
||||
cameraTargetDistance -= (GetMouseWheelMove() * CAMERA_SCROLL_SENSITIVITY);
|
||||
|
||||
// Camera distance clamp
|
||||
if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x * cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x);
|
||||
camera->target.y = playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y;
|
||||
camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z * sin(cameraAngle.x) - THIRD_PERSON_OFFSET.x * sin(cameraAngle.x);
|
||||
|
||||
// Camera position update
|
||||
camera->position.x = sin(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.x;
|
||||
|
||||
if (cameraAngle.y <= 0) camera->position.y = sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sin(cameraAngle.y) * cameraTargetDistance * sin(cameraAngle.y) + camera->target.y;
|
||||
|
||||
camera->position.z = cos(cameraAngle.x) * cameraTargetDistance * cos(cameraAngle.y) + camera->target.z;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isMoving) cameraMovementCounter++;
|
||||
|
||||
// Camera orientation calculation
|
||||
// Get the mouse sensitivity
|
||||
cameraAngle.x += cameraMouseVariation.x * -mouseSensitivity;
|
||||
cameraAngle.y += cameraMouseVariation.y * -mouseSensitivity;
|
||||
|
||||
// Angle clamp
|
||||
if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP * DEG2RAD;
|
||||
else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP * DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP * DEG2RAD;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sin(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sin(cameraAngle.y) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cos(cameraAngle.x) * FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
camera->position.x = playerPosition->x;
|
||||
camera->position.y = (playerPosition->y + PLAYER_HEIGHT * FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMovementCounter / FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER) / FIRST_PERSON_STEP_DIVIDER;
|
||||
camera->position.z = playerPosition->z;
|
||||
|
||||
camera->up.x = sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
camera->up.z = -sin(cameraMovementCounter / (FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER * 2)) / FIRST_PERSON_WAVING_DIVIDER;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetCameraControls(int frontKey, int leftKey, int backKey, int rightKey, int upKey, int downKey)
|
||||
{
|
||||
cameraMovementController[0] = frontKey;
|
||||
cameraMovementController[1] = leftKey;
|
||||
cameraMovementController[2] = backKey;
|
||||
cameraMovementController[3] = rightKey;
|
||||
cameraMovementController[4] = upKey;
|
||||
cameraMovementController[5] = downKey;
|
||||
}
|
||||
|
||||
void SetMouseSensitivity(float sensitivity)
|
||||
{
|
||||
mouseSensitivity = (sensitivity / 10000.0);
|
||||
}
|
||||
|
||||
void SetResetPosition(Vector3 resetPosition)
|
||||
{
|
||||
resetingPosition = resetPosition;
|
||||
}
|
||||
|
||||
void SetResetControl(int resetKey)
|
||||
{
|
||||
resetingKey = resetKey;
|
||||
}
|
||||
|
||||
void SetPawnControl(int pawnControlKey)
|
||||
{
|
||||
pawnControllingKey = pawnControlKey;
|
||||
}
|
||||
|
||||
void SetFnControl(int fnControlKey)
|
||||
{
|
||||
fnControllingKey = fnControlKey;
|
||||
}
|
||||
|
||||
void SetSmoothZoomControl(int smoothZoomControlKey)
|
||||
{
|
||||
smoothZoomControllingKey = smoothZoomControlKey;
|
||||
}
|
||||
|
||||
void SetOrbitalTarget(Vector3 target)
|
||||
{
|
||||
internalCamera.target = target;
|
||||
}
|
554
src/core.c
554
src/core.c
@ -45,13 +45,18 @@
|
||||
#include <stdio.h> // Standard input / output lib
|
||||
#include <stdlib.h> // Declares malloc() and free() for memory management, rand(), atexit()
|
||||
#include <stdint.h> // Required for typedef unsigned long long int uint64_t, used by hi-res timer
|
||||
#include <time.h> // Useful to initialize random seed - Android/RPI hi-res timer
|
||||
#include <time.h> // Useful to initialize random seed - Android/RPI hi-res timer (NOTE: Linux only!)
|
||||
#include <math.h> // Math related functions, tan() used to set perspective
|
||||
#include <string.h> // String function definitions, memset()
|
||||
#include <errno.h> // Macros for reporting and retrieving error conditions through error codes
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
#include <GLFW/glfw3.h> // GLFW3 library: Windows, OpenGL context and Input management
|
||||
#ifdef __linux
|
||||
#define GLFW_EXPOSE_NATIVE_X11 // Linux specific definitions for getting
|
||||
#define GLFW_EXPOSE_NATIVE_GLX // native functions like glfwGetX11Window
|
||||
#include <GLFW/glfw3native.h> // which are required for hiding mouse
|
||||
#endif
|
||||
//#include <GL/gl.h> // OpenGL functions (GLFW3 already includes gl.h)
|
||||
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
|
||||
#endif
|
||||
@ -104,28 +109,13 @@
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
static GLFWwindow *window; // Native window (graphic device)
|
||||
static bool windowMinimized = false;
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
static struct android_app *app; // Android activity
|
||||
static struct android_poll_source *source; // Android events polling source
|
||||
static int ident, events;
|
||||
static bool windowReady = false; // Used to detect display initialization
|
||||
|
||||
// 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;
|
||||
const int32_t TAP_TIMEOUT = 180*1000000;
|
||||
const int32_t TOUCH_SLOP = 8;
|
||||
|
||||
#elif defined(PLATFORM_RPI)
|
||||
static EGL_DISPMANX_WINDOW_T nativeWindow; // Native window (graphic device)
|
||||
|
||||
@ -152,8 +142,7 @@ static int gamepadStream = -1; // Gamepad device file descripto
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
static EGLDisplay display; // Native display device (physical screen connection)
|
||||
static EGLSurface surface; // Surface to draw on, framebuffers (connected to context)
|
||||
static EGLContext context; // Graphic context, mode in which drawing can be done
|
||||
|
||||
static EGLContext context; // Graphic context, mode in which drawing can be done
|
||||
static uint64_t baseTime; // Base time measure for hi-res timer
|
||||
static bool windowShouldClose = false; // Flag to set window for closing
|
||||
#endif
|
||||
@ -191,11 +180,8 @@ static int currentMouseWheelY = 0; // Required to track mouse wheel var
|
||||
|
||||
static int exitKey = KEY_ESCAPE; // Default exit key (ESC)
|
||||
static int lastKeyPressed = -1;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static float touchX; // Touch position X
|
||||
static float touchY; // Touch position Y
|
||||
static bool cursorHidden;
|
||||
#endif
|
||||
|
||||
static double currentTime, previousTime; // Used to track timmings
|
||||
@ -206,6 +192,9 @@ static double targetTime = 0.0; // Desired time for one frame, if 0
|
||||
static char configFlags = 0;
|
||||
static bool showLogo = false;
|
||||
|
||||
// Shaders variables
|
||||
static bool enabledPostpro = false;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Other Modules Functions Declaration (required by core)
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -214,6 +203,17 @@ extern void UnloadDefaultFont(void); // [Module: text] Unloads defaul
|
||||
|
||||
extern void UpdateMusicStream(void); // [Module: audio] Updates buffers for music streaming
|
||||
|
||||
extern Vector2 GetRawPosition(void);
|
||||
extern void ResetGestures(void);
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
extern void InitAndroidGestures(struct android_app *app);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
extern void InitWebGestures(void); // [Module: gestures] Initializes emscripten gestures for web
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -227,6 +227,7 @@ static void SwapBuffers(void); // Copy back buffer to f
|
||||
static void PollInputEvents(void); // Register user events
|
||||
static void LogoAnimation(void); // Plays raylib logo appearing animation
|
||||
static void SetupFramebufferSize(int displayWidth, int displayHeight);
|
||||
|
||||
#if defined(PLATFORM_RPI)
|
||||
static void InitMouse(void); // Mouse initialization (including mouse thread)
|
||||
static void *MouseThread(void *arg); // Mouse reading thread
|
||||
@ -243,6 +244,7 @@ static void CharCallback(GLFWwindow *window, unsigned int key);
|
||||
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
|
||||
static void WindowIconifyCallback(GLFWwindow* window, int iconified); // GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
|
||||
@ -250,8 +252,7 @@ static void TakeScreenshot(void);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static int32_t InputCallback(struct android_app *app, AInputEvent *event); // Process Android activity input events
|
||||
static void CommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
|
||||
static void AndroidCommandCallback(struct android_app *app, int32_t cmd); // Process Android activity lifecycle commands
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -261,8 +262,8 @@ static void CommandCallback(struct android_app *app, int32_t cmd); //
|
||||
// Initialize Window and Graphics Context (OpenGL)
|
||||
void InitWindow(int width, int height, const char *title)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib...");
|
||||
|
||||
TraceLog(INFO, "Initializing raylib (v1.3.0)");
|
||||
|
||||
// Store window title (could be useful...)
|
||||
windowTitle = title;
|
||||
|
||||
@ -285,6 +286,11 @@ void InitWindow(int width, int height, const char *title)
|
||||
InitKeyboard(); // Keyboard init
|
||||
InitGamepad(); // Gamepad init
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
InitWebGestures(); // Init touch input events for web
|
||||
#endif
|
||||
|
||||
mousePosition.x = screenWidth/2;
|
||||
mousePosition.y = screenHeight/2;
|
||||
|
||||
@ -300,8 +306,8 @@ void InitWindow(int width, int height, const char *title)
|
||||
// Android activity initialization
|
||||
void InitWindow(int width, int height, struct android_app *state)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib...");
|
||||
|
||||
TraceLog(INFO, "Initializing raylib (v1.3.0)");
|
||||
|
||||
app_dummy();
|
||||
|
||||
screenWidth = width;
|
||||
@ -336,8 +342,9 @@ void InitWindow(int width, int height, struct android_app *state)
|
||||
//AConfiguration_getScreenLong(app->config);
|
||||
|
||||
//state->userData = &engine;
|
||||
app->onAppCmd = CommandCallback;
|
||||
app->onInputEvent = InputCallback;
|
||||
app->onAppCmd = AndroidCommandCallback;
|
||||
|
||||
InitAndroidGestures(app);
|
||||
|
||||
InitAssetManager(app->activity->assetManager);
|
||||
|
||||
@ -399,6 +406,9 @@ void CloseWindow(void)
|
||||
bool WindowShouldClose(void)
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// While window minimized, stop loop execution
|
||||
while (windowMinimized) glfwPollEvents();
|
||||
|
||||
return (glfwWindowShouldClose(window));
|
||||
#elif defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
return windowShouldClose;
|
||||
@ -429,7 +439,7 @@ void SetCustomCursor(const char *cursorImage)
|
||||
cursor = LoadTexture(cursorImage);
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// NOTE: emscripten not implemented
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
#endif
|
||||
customCursor = true;
|
||||
@ -469,22 +479,31 @@ void BeginDrawing(void)
|
||||
updateTime = currentTime - previousTime;
|
||||
previousTime = currentTime;
|
||||
|
||||
if (enabledPostpro) rlEnableFBO();
|
||||
|
||||
rlClearScreenBuffers();
|
||||
|
||||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
|
||||
rlMultMatrixf(GetMatrixVector(downscaleView)); // If downscale required, apply it here
|
||||
|
||||
// rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL 1.1
|
||||
//rlTranslatef(0.375, 0.375, 0); // HACK to have 2D pixel-perfect drawing on OpenGL 1.1
|
||||
// NOTE: Not required with OpenGL 3.3+
|
||||
}
|
||||
|
||||
// End canvas drawing and Swap Buffers (Double Buffering)
|
||||
void EndDrawing(void)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
if (enabledPostpro) rlglDrawPostpro(); // Draw postprocessing effect (shader)
|
||||
|
||||
SwapBuffers(); // Copy back buffer to front buffer
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
ResetGestures();
|
||||
#endif
|
||||
|
||||
PollInputEvents(); // Poll user events
|
||||
|
||||
UpdateMusicStream(); // NOTE: Function checks if music is enabled
|
||||
@ -510,7 +529,7 @@ void EndDrawing(void)
|
||||
// Initializes 3D mode for drawing (Camera setup)
|
||||
void Begin3dMode(Camera camera)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||
|
||||
@ -528,14 +547,14 @@ void Begin3dMode(Camera camera)
|
||||
rlLoadIdentity(); // Reset current matrix (MODELVIEW)
|
||||
|
||||
// Setup Camera view
|
||||
Matrix matLookAt = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
rlMultMatrixf(GetMatrixVector(matLookAt)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||
Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
rlMultMatrixf(GetMatrixVector(view)); // Multiply MODELVIEW matrix by view matrix (camera)
|
||||
}
|
||||
|
||||
// Ends 3D mode and returns to default 2D orthographic mode
|
||||
void End3dMode(void)
|
||||
{
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
rlglDraw(); // Draw Buffers (Only OpenGL 3+ and ES2)
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to projection matrix
|
||||
rlPopMatrix(); // Restore previous matrix (PROJECTION) from matrix stack
|
||||
@ -612,9 +631,8 @@ Color Fade(Color color, float alpha)
|
||||
return (Color){color.r, color.g, color.b, color.a*alpha};
|
||||
}
|
||||
|
||||
// Enable some window configurations (SetWindowFlags()?)
|
||||
// TODO: Review function name and usage
|
||||
void SetupFlags(char flags)
|
||||
// Enable some window/system configurations
|
||||
void SetConfigFlags(char flags)
|
||||
{
|
||||
configFlags = flags;
|
||||
|
||||
@ -628,6 +646,41 @@ void ShowLogo(void)
|
||||
showLogo = true;
|
||||
}
|
||||
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera)
|
||||
{
|
||||
Ray ray;
|
||||
|
||||
Matrix proj = MatrixIdentity();
|
||||
Matrix view = MatrixLookAt(camera.position, camera.target, camera.up);
|
||||
|
||||
float aspect = (GLfloat)GetScreenWidth()/(GLfloat)GetScreenHeight();
|
||||
double top = 0.1f*tanf(45.0f*PI / 360.0f);
|
||||
double right = top*aspect;
|
||||
|
||||
proj = MatrixFrustum(-right, right, -top, top, 0.01f, 1000.0f);
|
||||
MatrixTranspose(&proj);
|
||||
|
||||
float realy = (float)GetScreenHeight() - mousePosition.y;
|
||||
|
||||
//float z;
|
||||
// glReadPixels(mousePosition.x, mousePosition.y, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &z);
|
||||
//http://www.bfilipek.com/2012/06/select-mouse-opengl.html
|
||||
|
||||
Vector3 nearPoint = { mousePosition.x, realy, 0.0f };
|
||||
Vector3 farPoint = { mousePosition.x, realy, 1.0f };
|
||||
|
||||
//nearPoint = internalCamera.position;
|
||||
farPoint = rlglUnproject(farPoint, proj, view);
|
||||
|
||||
Vector3 direction = VectorSubtract(farPoint, nearPoint);
|
||||
VectorNormalize(&direction);
|
||||
|
||||
ray.position = nearPoint;
|
||||
ray.direction = direction;
|
||||
|
||||
return ray;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -733,7 +786,7 @@ void SetMousePosition(Vector2 position)
|
||||
{
|
||||
mousePosition = position;
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
// NOTE: emscripten not implemented
|
||||
// NOTE: emscripten not implemented
|
||||
glfwSetCursorPos(window, position.x, position.y);
|
||||
#endif
|
||||
}
|
||||
@ -741,17 +794,52 @@ void SetMousePosition(Vector2 position)
|
||||
// Returns mouse wheel movement Y
|
||||
int GetMouseWheelMove(void)
|
||||
{
|
||||
previousMouseWheelY = currentMouseWheelY;
|
||||
|
||||
currentMouseWheelY = 0;
|
||||
|
||||
return previousMouseWheelY;
|
||||
}
|
||||
|
||||
// Hide mouse cursor
|
||||
void HideCursor()
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#ifdef __linux
|
||||
XColor Col;
|
||||
const char Nil[] = {0};
|
||||
|
||||
Pixmap Pix = XCreateBitmapFromData(glfwGetX11Display(), glfwGetX11Window(window), Nil, 1, 1);
|
||||
Cursor Cur = XCreatePixmapCursor(glfwGetX11Display(), Pix, Pix, &Col, &Col, 0, 0);
|
||||
|
||||
XDefineCursor(glfwGetX11Display(), glfwGetX11Window(window), Cur);
|
||||
XFreeCursor(glfwGetX11Display(), Cur);
|
||||
#else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_HIDDEN);
|
||||
#endif
|
||||
#endif
|
||||
cursorHidden = true;
|
||||
}
|
||||
|
||||
// Show mouse cursor
|
||||
void ShowCursor()
|
||||
{
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#ifdef __linux
|
||||
XUndefineCursor(glfwGetX11Display(), glfwGetX11Window(window));
|
||||
#else
|
||||
glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL);
|
||||
#endif
|
||||
#endif
|
||||
cursorHidden = false;
|
||||
}
|
||||
|
||||
// Check if mouse cursor is hidden
|
||||
bool IsCursorHidden()
|
||||
{
|
||||
return cursorHidden;
|
||||
}
|
||||
#endif
|
||||
|
||||
// TODO: Enable gamepad usage on Rapsberry Pi
|
||||
// NOTE: emscripten not implemented
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
// Detect if a gamepad is available
|
||||
bool IsGamepadAvailable(int gamepad)
|
||||
{
|
||||
@ -848,66 +936,73 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
bool IsScreenTouched(void)
|
||||
{
|
||||
return touchTap;
|
||||
}
|
||||
|
||||
bool IsDoubleTap(void)
|
||||
{
|
||||
if (doubleTap) TraceLog(INFO, "DOUBLE TAP gesture detected");
|
||||
|
||||
return doubleTap;
|
||||
}
|
||||
|
||||
bool IsDragGesture(void)
|
||||
{
|
||||
return drag;
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
// Returns touch position X
|
||||
int GetTouchX(void)
|
||||
{
|
||||
return (int)touchX;
|
||||
return (int)GetRawPosition().x;
|
||||
}
|
||||
|
||||
// Returns touch position Y
|
||||
int GetTouchY(void)
|
||||
{
|
||||
return (int)touchY;
|
||||
return (int)GetRawPosition().y;
|
||||
}
|
||||
|
||||
// Returns touch position XY
|
||||
Vector2 GetTouchPosition(void)
|
||||
{
|
||||
Vector2 position = { touchX, touchY };
|
||||
Vector2 position = GetRawPosition();
|
||||
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
// TODO: Seems to work ok but... review!
|
||||
position.x = position.x*((float)screenWidth / (float)(displayWidth - renderOffsetX)) - renderOffsetX/2;
|
||||
position.y = position.y*((float)screenHeight / (float)(displayHeight - renderOffsetY)) - renderOffsetY/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
position.x = position.x*((float)renderWidth / (float)displayWidth) - renderOffsetX/2;
|
||||
position.y = position.y*((float)renderHeight / (float)displayHeight) - renderOffsetY/2;
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// Set postprocessing shader
|
||||
void SetPostproShader(Shader shader)
|
||||
{
|
||||
if (rlGetVersion() == OPENGL_11) TraceLog(WARNING, "Postprocessing shaders not supported on OpenGL 1.1");
|
||||
else
|
||||
{
|
||||
if (!enabledPostpro)
|
||||
{
|
||||
enabledPostpro = true;
|
||||
rlglInitPostpro();
|
||||
rlglSetPostproShader(shader);
|
||||
}
|
||||
else
|
||||
{
|
||||
rlglSetPostproShader(shader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set custom shader to be used in batch draw
|
||||
void SetCustomShader(Shader shader)
|
||||
{
|
||||
rlglSetCustomShader(shader);
|
||||
}
|
||||
|
||||
// Set default shader to be used in batch draw
|
||||
void SetDefaultShader(void)
|
||||
{
|
||||
rlglSetDefaultShader();
|
||||
|
||||
enabledPostpro = false;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -946,7 +1041,7 @@ static void InitDisplay(int width, int height)
|
||||
displayWidth = screenWidth;
|
||||
displayHeight = screenHeight;
|
||||
#endif
|
||||
|
||||
|
||||
glfwDefaultWindowHints(); // Set default windows hints
|
||||
|
||||
glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||
@ -956,13 +1051,18 @@ static void InitDisplay(int width, int height)
|
||||
//glfwWindowHint(GLFW_CLIENT_API, GLFW_OPENGL_API); // Default OpenGL API to use. Alternative: GLFW_OPENGL_ES_API
|
||||
//glfwWindowHint(GLFW_AUX_BUFFERS, 0); // Number of auxiliar buffers
|
||||
|
||||
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
|
||||
// NOTE: When asking for an OpenGL context version, most drivers provide highest supported version
|
||||
// with forward compatibility to older OpenGL versions.
|
||||
// For example, if using OpenGL 1.1, driver can provide a 3.3 context fordward compatible.
|
||||
|
||||
if (rlGetVersion() == OPENGL_33)
|
||||
{
|
||||
//glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
|
||||
if (configFlags & FLAG_MSAA_4X_HINT)
|
||||
{
|
||||
glfwWindowHint(GLFW_SAMPLES, 4); // Enables multisampling x4 (MSAA), default is 0
|
||||
TraceLog(INFO, "Enabled MSAA x4");
|
||||
}
|
||||
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // Choose OpenGL major version (just hint)
|
||||
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); // Choose OpenGL minor version (just hint)
|
||||
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // Profiles Hint: Only 3.2 and above!
|
||||
@ -1009,12 +1109,18 @@ static void InitDisplay(int width, int height)
|
||||
glfwSetMouseButtonCallback(window, MouseButtonCallback);
|
||||
glfwSetCharCallback(window, CharCallback);
|
||||
glfwSetScrollCallback(window, ScrollCallback);
|
||||
glfwSetWindowIconifyCallback(window, WindowIconifyCallback);
|
||||
|
||||
glfwMakeContextCurrent(window);
|
||||
|
||||
//glfwSwapInterval(0); // Disables GPU v-sync (if set), so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
|
||||
// If not set, swap interval uses GPU v-sync configuration
|
||||
// Framerate can be setup using SetTargetFPS()
|
||||
// Enables GPU v-sync, so frames are not limited to screen refresh rate (60Hz -> 60 FPS)
|
||||
// If not set, swap interval uses GPU v-sync configuration
|
||||
// Framerate can be setup using SetTargetFPS()
|
||||
if (configFlags & FLAG_VSYNC_HINT)
|
||||
{
|
||||
glfwSwapInterval(1);
|
||||
TraceLog(INFO, "Trying to enable VSYNC");
|
||||
}
|
||||
|
||||
//glfwGetFramebufferSize(window, &renderWidth, &renderHeight); // Get framebuffer size of current window
|
||||
|
||||
@ -1036,6 +1142,7 @@ static void InitDisplay(int width, int height)
|
||||
VC_RECT_T srcRect;
|
||||
#endif
|
||||
|
||||
// TODO: if (configFlags & FLAG_MSAA_4X_HINT) activate (EGL_SAMPLES, 4)
|
||||
const EGLint framebufferAttribs[] =
|
||||
{
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, // Type of context support -> Required on RPI?
|
||||
@ -1158,7 +1265,7 @@ static void InitDisplay(int width, int height)
|
||||
}
|
||||
|
||||
// Initialize OpenGL graphics
|
||||
void InitGraphics(void)
|
||||
static void InitGraphics(void)
|
||||
{
|
||||
rlglInit(); // Init rlgl
|
||||
|
||||
@ -1216,7 +1323,7 @@ static void MouseButtonCallback(GLFWwindow *window, int button, int action, int
|
||||
static void CharCallback(GLFWwindow *window, unsigned int key)
|
||||
{
|
||||
lastKeyPressed = key;
|
||||
|
||||
|
||||
//TraceLog(INFO, "Char Callback Key pressed: %i\n", key);
|
||||
}
|
||||
|
||||
@ -1242,212 +1349,30 @@ static void WindowSizeCallback(GLFWwindow *window, int width, int height)
|
||||
// Background must be also re-cleared
|
||||
ClearBackground(RAYWHITE);
|
||||
}
|
||||
|
||||
// GLFW3 WindowIconify Callback, runs when window is minimized/restored
|
||||
static void WindowIconifyCallback(GLFWwindow* window, int iconified)
|
||||
{
|
||||
if (iconified)
|
||||
{
|
||||
// The window was iconified
|
||||
PauseMusicStream();
|
||||
|
||||
windowMinimized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// The window was restored
|
||||
ResumeMusicStream();
|
||||
|
||||
windowMinimized = false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
// Android: Process activity input events
|
||||
static int32_t InputCallback(struct android_app *app, AInputEvent *event)
|
||||
{
|
||||
int type = AInputEvent_getType(event);
|
||||
//int32_t key = 0;
|
||||
|
||||
if (type == AINPUT_EVENT_TYPE_MOTION)
|
||||
{
|
||||
// Detect TOUCH position
|
||||
if ((screenWidth > displayWidth) || (screenHeight > displayHeight))
|
||||
{
|
||||
// TODO: Seems to work ok but... review!
|
||||
touchX = AMotionEvent_getX(event, 0) * ((float)screenWidth / (float)(displayWidth - renderOffsetX)) - renderOffsetX/2;
|
||||
touchY = AMotionEvent_getY(event, 0) * ((float)screenHeight / (float)(displayHeight - renderOffsetY)) - renderOffsetY/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
touchX = AMotionEvent_getX(event, 0) * ((float)renderWidth / (float)displayWidth) - renderOffsetX/2;
|
||||
touchY = AMotionEvent_getY(event, 0) * ((float)renderHeight / (float)displayHeight) - renderOffsetY/2;
|
||||
}
|
||||
|
||||
// Detect TAP event
|
||||
/*
|
||||
if (AMotionEvent_getPointerCount(event) > 1 )
|
||||
{
|
||||
// Only support single touch
|
||||
return false;
|
||||
}
|
||||
*/
|
||||
int32_t action = AMotionEvent_getAction(event);
|
||||
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
|
||||
switch (flags)
|
||||
{
|
||||
case AMOTION_EVENT_ACTION_DOWN:
|
||||
{
|
||||
touchId = AMotionEvent_getPointerId(event, 0);
|
||||
tapTouchX = AMotionEvent_getX(event, 0);
|
||||
tapTouchY = AMotionEvent_getY(event, 0);
|
||||
|
||||
} break;
|
||||
case AMOTION_EVENT_ACTION_UP:
|
||||
{
|
||||
int64_t eventTime = AMotionEvent_getEventTime(event);
|
||||
int64_t downTime = AMotionEvent_getDownTime(event);
|
||||
|
||||
if (eventTime - downTime <= TAP_TIMEOUT)
|
||||
{
|
||||
if (touchId == AMotionEvent_getPointerId(event, 0))
|
||||
{
|
||||
float x = AMotionEvent_getX(event, 0) - tapTouchX;
|
||||
float y = AMotionEvent_getY(event, 0) - tapTouchY;
|
||||
|
||||
float densityFactor = 1.0f;
|
||||
|
||||
if ( x*x + y*y < TOUCH_SLOP*TOUCH_SLOP * densityFactor)
|
||||
{
|
||||
// TAP Detected
|
||||
touchTap = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//float AMotionEvent_getX(event, size_t pointer_index);
|
||||
//int32_t AMotionEvent_getButtonState(event); // Pressed buttons
|
||||
//int32_t AMotionEvent_getPointerId(event, size_t pointer_index);
|
||||
//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)
|
||||
{
|
||||
//key = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Android: Process activity lifecycle commands
|
||||
static void CommandCallback(struct android_app *app, int32_t cmd)
|
||||
static void AndroidCommandCallback(struct android_app *app, int32_t cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
@ -1636,24 +1561,24 @@ 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
|
||||
|
||||
previousMouseWheelY = currentMouseWheelY;
|
||||
currentMouseWheelY = 0;
|
||||
|
||||
glfwPollEvents(); // Register keyboard/mouse events... and window events!
|
||||
#elif defined(PLATFORM_ANDROID)
|
||||
|
||||
// TODO: Check virtual keyboard (?)
|
||||
|
||||
// Reset touch events
|
||||
touchTap = false;
|
||||
doubleTap = false;
|
||||
drag = false;
|
||||
|
||||
// Poll Events (registered events)
|
||||
// TODO: Enable/disable activityMinimized to block activity if minimized
|
||||
//while ((ident = ALooper_pollAll(activityMinimized ? 0 : -1, NULL, &events,(void**)&source)) >= 0)
|
||||
while ((ident = ALooper_pollAll(0, NULL, &events,(void**)&source)) >= 0)
|
||||
{
|
||||
// Process this event
|
||||
@ -1664,8 +1589,8 @@ static void PollInputEvents(void)
|
||||
{
|
||||
// NOTE: Never close window, native activity is controlled by the system!
|
||||
//TraceLog(INFO, "Closing Window...");
|
||||
//windowShouldClose = true;
|
||||
|
||||
//windowShouldClose = true;
|
||||
|
||||
//ANativeActivity_finish(app->activity);
|
||||
}
|
||||
}
|
||||
@ -1952,13 +1877,13 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
|
||||
if (widthRatio <= heightRatio)
|
||||
{
|
||||
renderWidth = displayWidth;
|
||||
renderHeight = (int)((float)screenHeight*widthRatio);
|
||||
renderHeight = (int)round((float)screenHeight*widthRatio);
|
||||
renderOffsetX = 0;
|
||||
renderOffsetY = (displayHeight - renderHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderWidth = (int)((float)screenWidth*heightRatio);
|
||||
renderWidth = (int)round((float)screenWidth*heightRatio);
|
||||
renderHeight = displayHeight;
|
||||
renderOffsetX = (displayWidth - renderWidth);
|
||||
renderOffsetY = 0;
|
||||
@ -1988,13 +1913,13 @@ static void SetupFramebufferSize(int displayWidth, int displayHeight)
|
||||
if (displayRatio <= screenRatio)
|
||||
{
|
||||
renderWidth = screenWidth;
|
||||
renderHeight = (int)((float)screenWidth/displayRatio);
|
||||
renderHeight = (int)round((float)screenWidth/displayRatio);
|
||||
renderOffsetX = 0;
|
||||
renderOffsetY = (renderHeight - screenHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
renderWidth = (int)((float)screenHeight*displayRatio);
|
||||
renderWidth = (int)round((float)screenHeight*displayRatio);
|
||||
renderHeight = screenHeight;
|
||||
renderOffsetX = (renderWidth - screenWidth);
|
||||
renderOffsetY = 0;
|
||||
@ -2134,4 +2059,3 @@ static void LogoAnimation(void)
|
||||
|
||||
showLogo = false; // Prevent for repeating when reloading window (Android)
|
||||
}
|
||||
|
||||
|
645
src/gestures.c
Normal file
645
src/gestures.c
Normal file
@ -0,0 +1,645 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib.gestures
|
||||
*
|
||||
* Gestures Detection and Usage Functions Definitions
|
||||
*
|
||||
* Copyright (c) 2015 Marc Palau and Ramon Santamaria
|
||||
*
|
||||
* This software is provided "as-is", without any express or implied warranty. In no event
|
||||
* will the authors be held liable for any damages arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose, including commercial
|
||||
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
|
||||
*
|
||||
* 1. The origin of this software must not be misrepresented; you must not claim that you
|
||||
* wrote the original software. If you use this software in a product, an acknowledgment
|
||||
* in the product documentation would be appreciated but is not required.
|
||||
*
|
||||
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
|
||||
* as being the original software.
|
||||
*
|
||||
* 3. This notice may not be removed or altered from any source distribution.
|
||||
*
|
||||
**********************************************************************************************/
|
||||
|
||||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <stdlib.h> // malloc(), free()
|
||||
#include <stdio.h> // printf(), fprintf()
|
||||
#include <math.h> // Used for ...
|
||||
#include <stdint.h> // Defines int32_t, int64_t
|
||||
|
||||
#if defined(_WIN32)
|
||||
//#include <Windows.h>
|
||||
#elif defined(__linux)
|
||||
#include <time.h> // Used for clock functions
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include <jni.h> // Java native interface
|
||||
#include <android/sensor.h> // Android sensors functions
|
||||
#include <android/window.h> // Defines AWINDOW_FLAG_FULLSCREEN and others
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
#include <emscripten/emscripten.h>
|
||||
#include <emscripten/html5.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define FORCE_TO_SWIPE 20
|
||||
#define TAP_TIMEOUT 300
|
||||
|
||||
#define MAX_TOUCH_POINTS 4
|
||||
|
||||
typedef enum {
|
||||
TYPE_MOTIONLESS,
|
||||
TYPE_DRAG,
|
||||
TYPE_DUAL_INPUT
|
||||
} GestureType;
|
||||
|
||||
typedef enum {
|
||||
UP,
|
||||
DOWN,
|
||||
MOVE
|
||||
} ActionType;
|
||||
|
||||
typedef struct {
|
||||
ActionType action;
|
||||
int pointCount;
|
||||
int pointerId[MAX_TOUCH_POINTS];
|
||||
Vector2 position[MAX_TOUCH_POINTS];
|
||||
} GestureEvent;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
static GestureType gestureType = TYPE_MOTIONLESS;
|
||||
static double eventTime = 0;
|
||||
//static int32_t touchId; // Not used...
|
||||
|
||||
// Tap
|
||||
// Our initial press position on tap
|
||||
static Vector2 initialTapPosition = { 0, 0 };
|
||||
|
||||
// Double tap
|
||||
// If we are double tapping or not
|
||||
static bool doubleTapping = false;
|
||||
// If we recently made a tap
|
||||
static bool untap = false;
|
||||
|
||||
// Drag
|
||||
// Our initial press position on drag
|
||||
static Vector2 initialDragPosition = { 0, 0 };
|
||||
// Position that will compare itself with the mouse one
|
||||
static Vector2 endDragPosition = { 0, 0 };
|
||||
// Position of the last event detection
|
||||
static Vector2 lastDragPosition = { 0, 0 };
|
||||
// The total drag vector
|
||||
static Vector2 dragVector = { 0, 0 };
|
||||
// The distance traveled dragging
|
||||
static float magnitude = 0;
|
||||
// The angle direction of the drag
|
||||
static float angle = 0;
|
||||
// A magnitude to calculate how fast we did the drag ( pixels per frame )
|
||||
static float intensity = 0;
|
||||
// Time that have passed while dragging
|
||||
static int draggingTimeCounter = 0;
|
||||
|
||||
// Pinch
|
||||
// First initial pinch position
|
||||
static Vector2 firstInitialPinchPosition = { 0, 0 };
|
||||
// Second initial pinch position
|
||||
static Vector2 secondInitialPinchPosition = { 0, 0 };
|
||||
// First end pinch position
|
||||
static Vector2 firstEndPinchPosition = { 0, 0 };
|
||||
// Second end pinch position
|
||||
static Vector2 secondEndPinchPosition = { 0, 0 };
|
||||
// Delta Displacement
|
||||
static float pinchDelta = 0;
|
||||
|
||||
// Detected gesture
|
||||
static int currentGesture = GESTURE_NONE;
|
||||
|
||||
static Vector2 touchPosition;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Declaration
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void ProcessMotionEvent(GestureEvent event);
|
||||
extern void ResetGestures(void);
|
||||
extern Vector2 GetRawPosition(void);
|
||||
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude);
|
||||
static float OnPinch();
|
||||
static void SetDualInput(GestureEvent event);
|
||||
static float Distance(Vector2 v1, Vector2 v2);
|
||||
static float DotProduct(Vector2 v1, Vector2 v2);
|
||||
static double GetCurrentTime();
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event);
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Returns tap position XY
|
||||
extern Vector2 GetRawPosition(void)
|
||||
{
|
||||
return touchPosition;
|
||||
}
|
||||
|
||||
// Check if a gesture have been detected
|
||||
bool IsGestureDetected(void)
|
||||
{
|
||||
if (currentGesture == GESTURE_DRAG) TraceLog(INFO, "DRAG");
|
||||
else if (currentGesture == GESTURE_TAP) TraceLog(INFO, "TAP");
|
||||
else if (currentGesture == GESTURE_DOUBLETAP) TraceLog(INFO, "DOUBLE");
|
||||
else if (currentGesture == GESTURE_HOLD) TraceLog(INFO, "HOLD");
|
||||
else if (currentGesture == GESTURE_SWIPE_RIGHT) TraceLog(INFO, "RIGHT");
|
||||
else if (currentGesture == GESTURE_SWIPE_UP) TraceLog(INFO, "UP");
|
||||
else if (currentGesture == GESTURE_SWIPE_LEFT) TraceLog(INFO, "LEFT");
|
||||
else if (currentGesture == GESTURE_SWIPE_DOWN) TraceLog(INFO, "DOWN");
|
||||
else if (currentGesture == GESTURE_PINCH_IN) TraceLog(INFO, "PINCH IN");
|
||||
else if (currentGesture == GESTURE_PINCH_OUT) TraceLog(INFO, "PINCH OUT");
|
||||
|
||||
if (currentGesture != GESTURE_NONE) return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Check gesture type
|
||||
int GetGestureType(void)
|
||||
{
|
||||
return currentGesture;
|
||||
}
|
||||
|
||||
// Get drag intensity (pixels per frame)
|
||||
float GetDragIntensity(void)
|
||||
{
|
||||
return intensity;
|
||||
}
|
||||
|
||||
// Get drag angle
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
|
||||
float GetDragAngle(void)
|
||||
{
|
||||
return angle;
|
||||
}
|
||||
|
||||
// Get drag vector (between initial and final position)
|
||||
Vector2 GetDragVector(void)
|
||||
{
|
||||
return dragVector;
|
||||
}
|
||||
|
||||
// Hold time measured in frames
|
||||
int GetHoldDuration(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get magnitude between two pinch points
|
||||
float GetPinchDelta(void)
|
||||
{
|
||||
return pinchDelta;
|
||||
}
|
||||
|
||||
// Get angle beween two pinch points
|
||||
// NOTE: Angle in degrees, horizontal-right is 0, counterclock-wise
|
||||
float GetPinchAngle(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern void ResetGestures(void)
|
||||
{
|
||||
if (currentGesture == GESTURE_TAP) currentGesture = GESTURE_HOLD;
|
||||
else if (currentGesture != GESTURE_HOLD) currentGesture = GESTURE_NONE;
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
extern void InitWebGestures(void)
|
||||
{
|
||||
/*
|
||||
emscripten_set_touchstart_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchend_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchmove_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
emscripten_set_touchcancel_callback("#canvas", data, 0, Emscripten_HandleTouch);
|
||||
*/
|
||||
|
||||
//emscripten_set_touchstart_callback(0, NULL, 1, Emscripten_HandleTouch);
|
||||
|
||||
emscripten_set_touchstart_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchend_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchmove_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
emscripten_set_touchcancel_callback("#canvas", NULL, 1, EmscriptenInputCallback);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
extern void InitAndroidGestures(struct android_app *app)
|
||||
{
|
||||
app->onInputEvent = AndroidInputCallback;
|
||||
|
||||
// TODO: Receive frameBuffer data: displayWidth/displayHeight, renderWidth/renderHeight, screenWidth/screenHeight
|
||||
}
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void ProcessMotionEvent(GestureEvent event)
|
||||
{
|
||||
// Resets
|
||||
dragVector = (Vector2){ 0, 0 };
|
||||
pinchDelta = 0;
|
||||
|
||||
switch (gestureType)
|
||||
{
|
||||
case TYPE_MOTIONLESS: // Detect TAP, DOUBLE_TAP and HOLD events
|
||||
{
|
||||
if (event.action == DOWN)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
else
|
||||
{
|
||||
// Set the press position
|
||||
initialTapPosition = event.position[0];
|
||||
|
||||
// If too much time have passed, we reset the double tap
|
||||
if (GetCurrentTime() - eventTime > TAP_TIMEOUT) untap = false;
|
||||
|
||||
// If we are in time, we detect the double tap
|
||||
if (untap) doubleTapping = true;
|
||||
|
||||
// Update our event time
|
||||
eventTime = GetCurrentTime();
|
||||
|
||||
// Set hold
|
||||
if (doubleTapping) currentGesture = GESTURE_DOUBLETAP;
|
||||
else currentGesture = GESTURE_TAP;
|
||||
}
|
||||
}
|
||||
else if (event.action == UP)
|
||||
{
|
||||
currentGesture = GESTURE_NONE;
|
||||
|
||||
// Detect that we are tapping instead of holding
|
||||
if (GetCurrentTime() - eventTime < TAP_TIMEOUT)
|
||||
{
|
||||
if (doubleTapping) untap = false;
|
||||
else untap = true;
|
||||
}
|
||||
|
||||
// Tap finished
|
||||
doubleTapping = false;
|
||||
|
||||
// Update our event time
|
||||
eventTime = GetCurrentTime();
|
||||
}
|
||||
// Begin dragging
|
||||
else if (event.action == MOVE)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
else
|
||||
{
|
||||
// Set the drag starting position
|
||||
initialDragPosition = initialTapPosition;
|
||||
endDragPosition = initialDragPosition;
|
||||
|
||||
// Initialize drag
|
||||
draggingTimeCounter = 0;
|
||||
gestureType = TYPE_DRAG;
|
||||
currentGesture = GESTURE_NONE;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TYPE_DRAG: // Detect DRAG and SWIPE events
|
||||
{
|
||||
// end of the drag
|
||||
if (event.action == UP)
|
||||
{
|
||||
// Return Swipe if we have enough sensitivity
|
||||
if (intensity > FORCE_TO_SWIPE)
|
||||
{
|
||||
if (angle < 30 || angle > 330) currentGesture = GESTURE_SWIPE_RIGHT; // Right
|
||||
else if (angle > 60 && angle < 120) currentGesture = GESTURE_SWIPE_UP; // Up
|
||||
else if (angle > 150 && angle < 210) currentGesture = GESTURE_SWIPE_LEFT; // Left
|
||||
else if (angle > 240 && angle < 300) currentGesture = GESTURE_SWIPE_DOWN; // Down
|
||||
}
|
||||
|
||||
magnitude = 0;
|
||||
angle = 0;
|
||||
intensity = 0;
|
||||
|
||||
gestureType = TYPE_MOTIONLESS;
|
||||
}
|
||||
// Update while we are dragging
|
||||
else if (event.action == MOVE)
|
||||
{
|
||||
if (event.pointCount > 1) SetDualInput(event);
|
||||
else
|
||||
{
|
||||
lastDragPosition = endDragPosition;
|
||||
|
||||
endDragPosition = GetRawPosition();
|
||||
|
||||
//endDragPosition.x = AMotionEvent_getX(event, 0);
|
||||
//endDragPosition.y = AMotionEvent_getY(event, 0);
|
||||
|
||||
// Calculate attributes
|
||||
dragVector = (Vector2){ endDragPosition.x - lastDragPosition.x, endDragPosition.y - lastDragPosition.y };
|
||||
magnitude = sqrt(pow(endDragPosition.x - initialDragPosition.x, 2) + pow(endDragPosition.y - initialDragPosition.y, 2));
|
||||
angle = CalculateAngle(initialDragPosition, endDragPosition, magnitude);
|
||||
intensity = magnitude / (float)draggingTimeCounter;
|
||||
|
||||
currentGesture = GESTURE_DRAG;
|
||||
draggingTimeCounter++;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case TYPE_DUAL_INPUT:
|
||||
{
|
||||
if (event.action == UP)
|
||||
{
|
||||
if (event.pointCount == 1)
|
||||
{
|
||||
// Set the drag starting position
|
||||
initialTapPosition = event.position[0];
|
||||
}
|
||||
gestureType = TYPE_MOTIONLESS;
|
||||
}
|
||||
else if (event.action == MOVE)
|
||||
{
|
||||
// Adapt the ending position of the inputs
|
||||
firstEndPinchPosition = event.position[0];
|
||||
secondEndPinchPosition = event.position[1];
|
||||
|
||||
// If there is no more than two inputs
|
||||
if (event.pointCount == 2)
|
||||
{
|
||||
// Detect pinch delta
|
||||
pinchDelta = OnPinch();
|
||||
|
||||
// Pinch gesture resolution
|
||||
if (pinchDelta != 0)
|
||||
{
|
||||
if (pinchDelta > 0) currentGesture = GESTURE_PINCH_IN;
|
||||
else currentGesture = GESTURE_PINCH_OUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set the drag starting position
|
||||
initialTapPosition = event.position[0];
|
||||
|
||||
gestureType = TYPE_MOTIONLESS;
|
||||
}
|
||||
|
||||
// Readapt the initial position of the inputs
|
||||
firstInitialPinchPosition = firstEndPinchPosition;
|
||||
secondInitialPinchPosition = secondEndPinchPosition;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
//--------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
||||
static float CalculateAngle(Vector2 initialPosition, Vector2 actualPosition, float magnitude)
|
||||
{
|
||||
float angle;
|
||||
|
||||
// Calculate arcsinus of the movement ( Our sinus is (actualPosition.y - initialPosition.y) / magnitude)
|
||||
angle = asin((actualPosition.y - initialPosition.y) / magnitude);
|
||||
angle *= RAD2DEG;
|
||||
|
||||
// Calculate angle depending on the sector
|
||||
if (actualPosition.x - initialPosition.x >= 0)
|
||||
{
|
||||
// Sector 4
|
||||
if (actualPosition.y - initialPosition.y >= 0)
|
||||
{
|
||||
angle *= -1;
|
||||
angle += 360;
|
||||
}
|
||||
// Sector 1
|
||||
else
|
||||
{
|
||||
angle *= -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sector 3
|
||||
if (actualPosition.y - initialPosition.y >= 0)
|
||||
{
|
||||
angle += 180;
|
||||
}
|
||||
// Sector 2
|
||||
else
|
||||
{
|
||||
angle *= -1;
|
||||
angle = 180 - angle;
|
||||
}
|
||||
}
|
||||
|
||||
return angle;
|
||||
}
|
||||
|
||||
static float OnPinch()
|
||||
{
|
||||
// Calculate distances
|
||||
float initialDistance = Distance(firstInitialPinchPosition, secondInitialPinchPosition);
|
||||
float endDistance = Distance(firstEndPinchPosition, secondEndPinchPosition);
|
||||
|
||||
// Calculate Vectors
|
||||
Vector2 firstTouchVector = { firstEndPinchPosition.x - firstInitialPinchPosition.x, firstEndPinchPosition.y - firstInitialPinchPosition.y };
|
||||
Vector2 secondTouchVector = { secondEndPinchPosition.x - secondInitialPinchPosition.x, secondEndPinchPosition.y - secondInitialPinchPosition.y };
|
||||
|
||||
// Detect the pinch gesture
|
||||
// Calculate Distances
|
||||
if (DotProduct(firstTouchVector, secondTouchVector) < -0.5) return initialDistance - endDistance;
|
||||
else return 0;
|
||||
}
|
||||
|
||||
static void SetDualInput(GestureEvent event)
|
||||
{
|
||||
initialDragPosition = (Vector2){ 0, 0 };
|
||||
endDragPosition = (Vector2){ 0, 0 };
|
||||
lastDragPosition = (Vector2){ 0, 0 };
|
||||
|
||||
// Initialize positions
|
||||
firstInitialPinchPosition = event.position[0];
|
||||
secondInitialPinchPosition = event.position[1];
|
||||
|
||||
firstEndPinchPosition = firstInitialPinchPosition;
|
||||
secondEndPinchPosition = secondInitialPinchPosition;
|
||||
|
||||
// Resets
|
||||
magnitude = 0;
|
||||
angle = 0;
|
||||
intensity = 0;
|
||||
|
||||
gestureType = TYPE_DUAL_INPUT;
|
||||
}
|
||||
|
||||
static float Distance(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
float dx = v2.x - v1.x;
|
||||
float dy = v2.y - v1.y;
|
||||
|
||||
result = sqrt(dx*dx + dy*dy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static float DotProduct(Vector2 v1, Vector2 v2)
|
||||
{
|
||||
float result;
|
||||
|
||||
float v1Module = sqrt(v1.x*v1.x + v1.y*v1.y);
|
||||
float v2Module = sqrt(v2.x*v2.x + v2.y*v2.y);
|
||||
|
||||
Vector2 v1Normalized = { v1.x / v1Module, v1.y / v1Module };
|
||||
Vector2 v2Normalized = { v2.x / v2Module, v2.y / v2Module };
|
||||
|
||||
result = v1Normalized.x*v2Normalized.x + v1Normalized.y*v2Normalized.y;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static double GetCurrentTime()
|
||||
{
|
||||
double time = 0;
|
||||
#if defined(_WIN32)
|
||||
/*
|
||||
// NOTE: Requires Windows.h
|
||||
FILETIME tm;
|
||||
GetSystemTimePreciseAsFileTime(&tm);
|
||||
ULONGLONG nowTime = ((ULONGLONG)tm.dwHighDateTime << 32) | (ULONGLONG)tm.dwLowDateTime; // Time provided in 100-nanosecond intervals
|
||||
|
||||
time = ((double)nowTime/10000000.0); // time in seconds
|
||||
*/
|
||||
#endif
|
||||
|
||||
#if defined(__linux)
|
||||
// NOTE: Only for Linux-based systems
|
||||
struct timespec now;
|
||||
clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
uint64_t nowTime = (uint64_t)now.tv_sec*1000000000LLU + (uint64_t)now.tv_nsec; // Time provided in nanoseconds
|
||||
|
||||
time = ((double)nowTime/1000000.0); // time in miliseconds
|
||||
#endif
|
||||
|
||||
return time;
|
||||
}
|
||||
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
// Android: Get input events
|
||||
static int32_t AndroidInputCallback(struct android_app *app, AInputEvent *event)
|
||||
{
|
||||
int type = AInputEvent_getType(event);
|
||||
|
||||
if (type == AINPUT_EVENT_TYPE_MOTION)
|
||||
{
|
||||
touchPosition.x = AMotionEvent_getX(event, 0);
|
||||
touchPosition.y = AMotionEvent_getY(event, 0);
|
||||
}
|
||||
else if (type == AINPUT_EVENT_TYPE_KEY)
|
||||
{
|
||||
//int32_t key = AKeyEvent_getKeyCode(event);
|
||||
//int32_t AKeyEvent_getMetaState(event);
|
||||
}
|
||||
|
||||
int32_t action = AMotionEvent_getAction(event);
|
||||
unsigned int flags = action & AMOTION_EVENT_ACTION_MASK;
|
||||
|
||||
GestureEvent gestureEvent;
|
||||
|
||||
// Action
|
||||
if (flags == AMOTION_EVENT_ACTION_DOWN) gestureEvent.action = DOWN;
|
||||
else if (flags == AMOTION_EVENT_ACTION_UP) gestureEvent.action = UP;
|
||||
else if (flags == AMOTION_EVENT_ACTION_MOVE) gestureEvent.action = MOVE;
|
||||
|
||||
// Points
|
||||
gestureEvent.pointCount = AMotionEvent_getPointerCount(event);
|
||||
|
||||
// Position
|
||||
gestureEvent.position[0] = (Vector2){ AMotionEvent_getX(event, 0), AMotionEvent_getY(event, 0) };
|
||||
gestureEvent.position[1] = (Vector2){ AMotionEvent_getX(event, 1), AMotionEvent_getY(event, 1) };
|
||||
|
||||
ProcessMotionEvent(gestureEvent);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_WEB)
|
||||
// Web: Get input events
|
||||
static EM_BOOL EmscriptenInputCallback(int eventType, const EmscriptenTouchEvent *touchEvent, void *userData)
|
||||
{
|
||||
/*
|
||||
for (int i = 0; i < touchEvent->numTouches; i++)
|
||||
{
|
||||
long x, y, id;
|
||||
|
||||
if (!touchEvent->touches[i].isChanged) continue;
|
||||
|
||||
id = touchEvent->touches[i].identifier;
|
||||
x = touchEvent->touches[i].canvasX;
|
||||
y = touchEvent->touches[i].canvasY;
|
||||
}
|
||||
|
||||
printf("%s, numTouches: %d %s%s%s%s\n", emscripten_event_type_to_string(eventType), event->numTouches,
|
||||
event->ctrlKey ? " CTRL" : "", event->shiftKey ? " SHIFT" : "", event->altKey ? " ALT" : "", event->metaKey ? " META" : "");
|
||||
|
||||
for(int i = 0; i < event->numTouches; ++i)
|
||||
{
|
||||
const EmscriptenTouchPoint *t = &event->touches[i];
|
||||
|
||||
printf(" %ld: screen: (%ld,%ld), client: (%ld,%ld), page: (%ld,%ld), isChanged: %d, onTarget: %d, canvas: (%ld, %ld)\n",
|
||||
t->identifier, t->screenX, t->screenY, t->clientX, t->clientY, t->pageX, t->pageY, t->isChanged, t->onTarget, t->canvasX, t->canvasY);
|
||||
}
|
||||
*/
|
||||
GestureEvent gestureEvent;
|
||||
|
||||
// Action
|
||||
if (eventType == EMSCRIPTEN_EVENT_TOUCHSTART) gestureEvent.action = DOWN;
|
||||
else if (eventType == EMSCRIPTEN_EVENT_TOUCHEND) gestureEvent.action = UP;
|
||||
else if (eventType == EMSCRIPTEN_EVENT_TOUCHMOVE) gestureEvent.action = MOVE;
|
||||
|
||||
// Points
|
||||
gestureEvent.pointCount = touchEvent->numTouches;
|
||||
|
||||
// Position
|
||||
gestureEvent.position[0] = (Vector2){ touchEvent->touches[0].canvasX, touchEvent->touches[0].canvasY };
|
||||
gestureEvent.position[1] = (Vector2){ touchEvent->touches[1].canvasX, touchEvent->touches[1].canvasY };
|
||||
|
||||
touchPosition = gestureEvent.position[0];
|
||||
|
||||
ProcessMotionEvent(gestureEvent);
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
15
src/makefile
15
src/makefile
@ -93,7 +93,7 @@ else
|
||||
endif
|
||||
|
||||
# define all object files required
|
||||
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o stb_vorbis.o
|
||||
OBJS = core.o rlgl.o raymath.o shapes.o text.o textures.o models.o audio.o utils.o camera.o gestures.o
|
||||
|
||||
# typing 'make' will invoke the first target entry in the file,
|
||||
# in this case, the 'default' target entry is raylib
|
||||
@ -144,9 +144,13 @@ audio.o: audio.c
|
||||
utils.o: utils.c
|
||||
$(CC) -c utils.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile stb_vorbis library
|
||||
stb_vorbis.o: stb_vorbis.c
|
||||
$(CC) -c stb_vorbis.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
# compile camera module
|
||||
camera.o: camera.c
|
||||
$(CC) -c camera.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# compile gestures module
|
||||
gestures.o: gestures.c
|
||||
$(CC) -c gestures.c $(CFLAGS) $(INCLUDES) -D$(PLATFORM)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
@ -155,8 +159,7 @@ ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
rm -f *.o libraylib.a
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o libraylib.a
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o libraylib.a
|
||||
endif
|
||||
|
888
src/models.c
888
src/models.c
File diff suppressed because it is too large
Load Diff
195
src/raylib.h
195
src/raylib.h
@ -1,6 +1,6 @@
|
||||
/**********************************************************************************************
|
||||
*
|
||||
* raylib 1.2 (www.raylib.com)
|
||||
* raylib 1.3.0 (www.raylib.com)
|
||||
*
|
||||
* A simple and easy-to-use library to learn videogames programming
|
||||
*
|
||||
@ -27,7 +27,6 @@
|
||||
*
|
||||
* 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)
|
||||
@ -78,7 +77,7 @@
|
||||
// Some basic Defines
|
||||
//----------------------------------------------------------------------------------
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846
|
||||
#define PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define DEG2RAD (PI / 180.0f)
|
||||
@ -90,8 +89,9 @@
|
||||
#define FLAG_SHOW_MOUSE_CURSOR 4
|
||||
#define FLAG_CENTERED_MODE 8
|
||||
#define FLAG_MSAA_4X_HINT 16
|
||||
#define FLAG_VSYNC_HINT 32
|
||||
|
||||
// Keyboard Function Keys
|
||||
// Keyboard Function Keys
|
||||
#define KEY_SPACE 32
|
||||
#define KEY_ESCAPE 256
|
||||
#define KEY_ENTER 257
|
||||
@ -177,8 +177,10 @@
|
||||
// Types and Structures Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
#ifndef __cplusplus
|
||||
// Boolean type
|
||||
typedef enum { false, true } bool;
|
||||
#endif
|
||||
|
||||
// byte type
|
||||
typedef unsigned char byte;
|
||||
@ -196,6 +198,14 @@ typedef struct Vector3 {
|
||||
float z;
|
||||
} Vector3;
|
||||
|
||||
// Matrix type (OpenGL style 4x4 - right handed, column major)
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12;
|
||||
float m1, m5, m9, m13;
|
||||
float m2, m6, m10, m14;
|
||||
float m3, m7, m11, m15;
|
||||
} Matrix;
|
||||
|
||||
// Color type, RGBA (32bit)
|
||||
typedef struct Color {
|
||||
unsigned char r;
|
||||
@ -215,17 +225,21 @@ typedef struct Rectangle {
|
||||
// Image type, bpp always RGBA (32bit)
|
||||
// NOTE: Data stored in CPU memory (RAM)
|
||||
typedef struct Image {
|
||||
Color *pixels;
|
||||
int width;
|
||||
int height;
|
||||
void *data; // Image raw data
|
||||
int width; // Image base width
|
||||
int height; // Image base height
|
||||
int mipmaps; // Mipmap levels, 1 by default
|
||||
int format; // Data format (TextureFormat)
|
||||
} 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;
|
||||
unsigned int id; // OpenGL texture id
|
||||
int width; // Texture base width
|
||||
int height; // Texture base height
|
||||
int mipmaps; // Mipmap levels, 1 by default
|
||||
int format; // Data format (TextureFormat)
|
||||
} Texture2D;
|
||||
|
||||
// Character type (one font glyph)
|
||||
@ -251,25 +265,60 @@ typedef struct Camera {
|
||||
Vector3 up;
|
||||
} Camera;
|
||||
|
||||
// Camera modes
|
||||
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
|
||||
|
||||
// Vertex data definning a mesh
|
||||
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
|
||||
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;
|
||||
} VertexData;
|
||||
|
||||
// Shader type
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
unsigned int texDiffuseId; // Diffuse texture id
|
||||
unsigned int texNormalId; // Normal texture id
|
||||
unsigned int texSpecularId; // Specular texture id
|
||||
|
||||
// Variable attributes
|
||||
int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
int normalLoc; // Normal attribute location point (vertex shader)
|
||||
int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
// Uniforms
|
||||
int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
|
||||
int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
|
||||
int mapDiffuseLoc; // Diffuse map texture uniform location point (fragment shader)
|
||||
int mapNormalLoc; // Normal map texture uniform location point (fragment shader)
|
||||
int mapSpecularLoc; // Specular map texture uniform location point (fragment shader)
|
||||
} Shader;
|
||||
|
||||
// 3d Model type
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
Matrix transform;
|
||||
Texture2D texture; // Only for OpenGL 1.1, on newer versions this should be in the shader
|
||||
Shader shader;
|
||||
} Model;
|
||||
|
||||
// Ray type (useful for raycast)
|
||||
typedef struct Ray {
|
||||
Vector3 position;
|
||||
Vector3 direction;
|
||||
} Ray;
|
||||
|
||||
// Sound source type
|
||||
typedef struct Sound {
|
||||
unsigned int source;
|
||||
@ -285,6 +334,44 @@ typedef struct Wave {
|
||||
short channels;
|
||||
} Wave;
|
||||
|
||||
// Texture formats
|
||||
// NOTE: Support depends on OpenGL version and platform
|
||||
typedef enum {
|
||||
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
|
||||
UNCOMPRESSED_GRAY_ALPHA, // 16 bpp (2 channels)
|
||||
UNCOMPRESSED_R5G6B5, // 16 bpp
|
||||
UNCOMPRESSED_R8G8B8, // 24 bpp
|
||||
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
|
||||
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
|
||||
UNCOMPRESSED_R8G8B8A8, // 32 bpp
|
||||
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
|
||||
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
|
||||
COMPRESSED_DXT3_RGBA, // 8 bpp
|
||||
COMPRESSED_DXT5_RGBA, // 8 bpp
|
||||
COMPRESSED_ETC1_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
|
||||
COMPRESSED_PVRT_RGB, // 4 bpp
|
||||
COMPRESSED_PVRT_RGBA, // 4 bpp
|
||||
COMPRESSED_ASTC_4x4_RGBA, // 8 bpp
|
||||
COMPRESSED_ASTC_8x8_RGBA // 2 bpp
|
||||
} TextureFormat;
|
||||
|
||||
// Gestures type
|
||||
typedef enum {
|
||||
GESTURE_NONE = 0,
|
||||
GESTURE_TAP,
|
||||
GESTURE_DOUBLETAP,
|
||||
GESTURE_HOLD,
|
||||
GESTURE_DRAG,
|
||||
GESTURE_SWIPE_RIGHT,
|
||||
GESTURE_SWIPE_LEFT,
|
||||
GESTURE_SWIPE_UP,
|
||||
GESTURE_SWIPE_DOWN,
|
||||
GESTURE_PINCH_IN,
|
||||
GESTURE_PINCH_OUT
|
||||
} Gestures;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" { // Prevents name mangling of functions
|
||||
#endif
|
||||
@ -312,7 +399,6 @@ 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
|
||||
@ -331,9 +417,35 @@ int GetHexValue(Color color); // Returns hexadecim
|
||||
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 SetConfigFlags(char flags); // Enable some window configurations
|
||||
void ShowLogo(void); // Activates raylib logo at startup (can be done with flags)
|
||||
|
||||
void SetPostproShader(Shader shader); // Set fullscreen postproduction shader
|
||||
void SetCustomShader(Shader shader); // Set custom shader to be used in batch draw
|
||||
void SetDefaultShader(void); // Set default shader to be used in batch draw
|
||||
|
||||
Ray GetMouseRay(Vector2 mousePosition, Camera camera); // Gives the rayTrace from mouse position
|
||||
|
||||
// Camera modes setup and control functions (module: camera)
|
||||
void SetCameraMode(int mode); // Select camera mode (multiple camera modes available)
|
||||
Camera UpdateCamera(Vector3 *position); // Update camera with position
|
||||
|
||||
void SetCameraControls(int front, int left, int back, int right, int up, int down);
|
||||
void SetMouseSensitivity(float sensitivity);
|
||||
void SetResetPosition(Vector3 resetPosition);
|
||||
void SetResetControl(int resetKey);
|
||||
void SetPawnControl(int pawnControlKey);
|
||||
void SetFnControl(int fnControlKey);
|
||||
void SetSmoothZoomControl(int smoothZoomControlKey);
|
||||
void SetOrbitalTarget(Vector3 target);
|
||||
|
||||
int GetShaderLocation(Shader shader, const char *uniformName);
|
||||
void SetShaderValue(Shader shader, int uniformLoc, float *value, int size);
|
||||
|
||||
void SetShaderMapDiffuse(Shader *shader, Texture2D texture);
|
||||
void SetShaderMapNormal(Shader *shader, const char *uniformName, Texture2D texture);
|
||||
void SetShaderMapSpecular(Shader *shader, const char *uniformName, Texture2D texture);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Input Handling Functions (Module: core)
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -342,6 +454,7 @@ bool IsKeyPressed(int key); // Detect if a key has b
|
||||
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
|
||||
int GetKeyPressed(void); // Get latest key 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
|
||||
@ -352,9 +465,13 @@ int GetMouseY(void); // Returns mouse positio
|
||||
Vector2 GetMousePosition(void); // Returns mouse position XY
|
||||
void SetMousePosition(Vector2 position); // Set mouse position XY
|
||||
int GetMouseWheelMove(void); // Returns mouse wheel movement Y
|
||||
|
||||
void ShowCursor(void); // Shows cursor
|
||||
void HideCursor(void); // Hides cursor
|
||||
bool IsCursorHidden(void); // Returns true if cursor is not visible
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP)
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
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
|
||||
@ -363,11 +480,20 @@ bool IsGamepadButtonReleased(int gamepad, int button); // Detect if a gamepad b
|
||||
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
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_WEB)
|
||||
int GetTouchX(void); // Returns touch position X
|
||||
int GetTouchY(void); // Returns touch position Y
|
||||
Vector2 GetTouchPosition(void); // Returns touch position XY
|
||||
|
||||
// Gestures System (module: gestures)
|
||||
bool IsGestureDetected(void);
|
||||
int GetGestureType(void);
|
||||
float GetDragIntensity(void);
|
||||
float GetDragAngle(void);
|
||||
Vector2 GetDragVector(void);
|
||||
int GetHoldDuration(void); // Hold time in frames
|
||||
float GetPinchDelta(void);
|
||||
float GetPinchAngle(void);
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -405,13 +531,15 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
|
||||
//------------------------------------------------------------------------------------
|
||||
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)
|
||||
Image LoadImageFromData(Color *pixels, int width, int height, int format); // Load image from Color array data
|
||||
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
|
||||
Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load a texture from raw data 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)
|
||||
Color *GetPixelData(Image image); // Get pixel data from image as a Color struct array
|
||||
|
||||
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
|
||||
@ -448,31 +576,40 @@ 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 DrawPlane(Vector3 centerPos, Vector2 size, Color color); // Draw a plane XZ
|
||||
void DrawQuad(Vector3 v1, Vector3 v2, Vector3 v3, Vector3 v4, Color color); // Draw a quad
|
||||
void DrawRay(Ray ray, Color color); // Draw a ray line
|
||||
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 LoadModelEx(VertexData data); // Load a 3d model (from vertex data)
|
||||
//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 SetModelShader(Model *model, Shader shader); // Link a shader to a model (not available on OpenGL 1.1)
|
||||
|
||||
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 DrawModelEx(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, 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
|
||||
|
||||
Shader LoadShader(char *vsFileName, char *fsFileName); // Load a custom shader (vertex shader + fragment shader)
|
||||
void UnloadShader(Shader shader); // Unload a custom shader from memory
|
||||
|
||||
bool CheckCollisionSpheres(Vector3 centerA, float radiusA, Vector3 centerB, float radiusB);
|
||||
bool CheckCollisionBoxes(Vector3 minBBox1, Vector3 maxBBox1, Vector3 minBBox2, Vector3 maxBBox2);
|
||||
bool CheckCollisionBoxSphere(Vector3 minBBox, Vector3 maxBBox, Vector3 centerSphere, float radiusSphere);
|
||||
Vector3 ResolveCollisionCubicmap(Image cubicmap, Vector3 mapPosition, Vector3 *playerPosition, float radius); // Return the normal vector of the impacted surface
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Audio Loading and Playing Functions (Module: audio)
|
||||
//------------------------------------------------------------------------------------
|
||||
|
312
src/raymath.c
312
src/raymath.c
@ -346,8 +346,6 @@ void MatrixInvert(Matrix *mat)
|
||||
temp.m14 = (-a30*b03 + a31*b01 - a32*b00)*invDet;
|
||||
temp.m15 = (a20*b03 - a21*b01 + a22*b00)*invDet;
|
||||
|
||||
PrintMatrix(temp);
|
||||
|
||||
*mat = temp;
|
||||
}
|
||||
|
||||
@ -433,72 +431,78 @@ Matrix MatrixSubstract(Matrix left, Matrix right)
|
||||
}
|
||||
|
||||
// Returns translation matrix
|
||||
// TODO: Review this function
|
||||
Matrix MatrixTranslate(float x, float y, float z)
|
||||
{
|
||||
/*
|
||||
For OpenGL
|
||||
1, 0, 0, 0
|
||||
0, 1, 0, 0
|
||||
0, 0, 1, 0
|
||||
x, y, z, 1
|
||||
Is the correct Translation Matrix. Why? Opengl Uses column-major matrix ordering.
|
||||
Which is the Transpose of the Matrix you initially presented, which is in row-major ordering.
|
||||
Row major is used in most math text-books and also DirectX, so it is a common
|
||||
point of confusion for those new to OpenGL.
|
||||
|
||||
* matrix notation used in opengl documentation does not describe in-memory layout for OpenGL matrices
|
||||
|
||||
Translation matrix should be laid out in memory like this:
|
||||
{ 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, trabsX, transY, transZ, 1 }
|
||||
|
||||
|
||||
9.005 Are OpenGL matrices column-major or row-major?
|
||||
|
||||
For programming purposes, OpenGL matrices are 16-value arrays with base vectors laid out
|
||||
contiguously in memory. The translation components occupy the 13th, 14th, and 15th elements
|
||||
of the 16-element matrix, where indices are numbered from 1 to 16 as described in section
|
||||
2.11.2 of the OpenGL 2.1 Specification.
|
||||
|
||||
Column-major versus row-major is purely a notational convention. Note that post-multiplying
|
||||
with column-major matrices produces the same result as pre-multiplying with row-major matrices.
|
||||
The OpenGL Specification and the OpenGL Reference Manual both use column-major notation.
|
||||
You can use any notation, as long as it's clearly stated.
|
||||
|
||||
Sadly, the use of column-major format in the spec and blue book has resulted in endless confusion
|
||||
in the OpenGL programming community. Column-major notation suggests that matrices
|
||||
are not laid out in memory as a programmer would expect.
|
||||
*/
|
||||
|
||||
Matrix result = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, x, y, z, 1 };
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns rotation matrix
|
||||
// TODO: Review this function
|
||||
Matrix MatrixRotate(float angleX, float angleY, float angleZ)
|
||||
// Create rotation matrix from axis and angle
|
||||
// NOTE: Angle should be provided in radians
|
||||
Matrix MatrixRotate(float angle, Vector3 axis)
|
||||
{
|
||||
Matrix result;
|
||||
|
||||
Matrix rotX = MatrixRotateX(angleX);
|
||||
Matrix rotY = MatrixRotateY(angleY);
|
||||
Matrix rotZ = MatrixRotateZ(angleZ);
|
||||
Matrix mat = MatrixIdentity();
|
||||
|
||||
result = MatrixMultiply(MatrixMultiply(rotX, rotY), rotZ);
|
||||
float x = axis.x, y = axis.y, z = axis.z;
|
||||
|
||||
float length = sqrt(x*x + y*y + z*z);
|
||||
|
||||
if ((length != 1) && (length != 0))
|
||||
{
|
||||
length = 1/length;
|
||||
x *= length;
|
||||
y *= length;
|
||||
z *= length;
|
||||
}
|
||||
|
||||
float s = sinf(angle);
|
||||
float c = cosf(angle);
|
||||
float t = 1.0f - c;
|
||||
|
||||
// Cache some matrix values (speed optimization)
|
||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||
|
||||
// Construct the elements of the rotation matrix
|
||||
float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
|
||||
float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
|
||||
float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
|
||||
|
||||
// Perform rotation-specific matrix multiplication
|
||||
result.m0 = a00*b00 + a10*b01 + a20*b02;
|
||||
result.m1 = a01*b00 + a11*b01 + a21*b02;
|
||||
result.m2 = a02*b00 + a12*b01 + a22*b02;
|
||||
result.m3 = a03*b00 + a13*b01 + a23*b02;
|
||||
result.m4 = a00*b10 + a10*b11 + a20*b12;
|
||||
result.m5 = a01*b10 + a11*b11 + a21*b12;
|
||||
result.m6 = a02*b10 + a12*b11 + a22*b12;
|
||||
result.m7 = a03*b10 + a13*b11 + a23*b12;
|
||||
result.m8 = a00*b20 + a10*b21 + a20*b22;
|
||||
result.m9 = a01*b20 + a11*b21 + a21*b22;
|
||||
result.m10 = a02*b20 + a12*b21 + a22*b22;
|
||||
result.m11 = a03*b20 + a13*b21 + a23*b22;
|
||||
result.m12 = mat.m12;
|
||||
result.m13 = mat.m13;
|
||||
result.m14 = mat.m14;
|
||||
result.m15 = mat.m15;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
// Another implementation for MatrixRotate...
|
||||
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 c = cosf(angle); // cosine
|
||||
float s = sinf(angle); // 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;
|
||||
@ -532,124 +536,6 @@ Matrix MatrixRotate(float angle, float x, float y, float z)
|
||||
}
|
||||
*/
|
||||
|
||||
// Create rotation matrix from axis and angle
|
||||
// TODO: Test this function
|
||||
// NOTE: NO prototype defined!
|
||||
Matrix MatrixFromAxisAngle(Vector3 axis, float angle)
|
||||
{
|
||||
Matrix result;
|
||||
|
||||
Matrix mat = MatrixIdentity();
|
||||
|
||||
float x = axis.x, y = axis.y, z = axis.z;
|
||||
|
||||
float length = sqrt(x*x + y*y + z*z);
|
||||
|
||||
if ((length != 1) && (length != 0))
|
||||
{
|
||||
length = 1 / length;
|
||||
x *= length;
|
||||
y *= length;
|
||||
z *= length;
|
||||
}
|
||||
|
||||
float s = sin(angle);
|
||||
float c = cos(angle);
|
||||
float t = 1-c;
|
||||
|
||||
// Cache some matrix values (speed optimization)
|
||||
float a00 = mat.m0, a01 = mat.m1, a02 = mat.m2, a03 = mat.m3;
|
||||
float a10 = mat.m4, a11 = mat.m5, a12 = mat.m6, a13 = mat.m7;
|
||||
float a20 = mat.m8, a21 = mat.m9, a22 = mat.m10, a23 = mat.m11;
|
||||
|
||||
// Construct the elements of the rotation matrix
|
||||
float b00 = x*x*t + c, b01 = y*x*t + z*s, b02 = z*x*t - y*s;
|
||||
float b10 = x*y*t - z*s, b11 = y*y*t + c, b12 = z*y*t + x*s;
|
||||
float b20 = x*z*t + y*s, b21 = y*z*t - x*s, b22 = z*z*t + c;
|
||||
|
||||
// Perform rotation-specific matrix multiplication
|
||||
result.m0 = a00*b00 + a10*b01 + a20*b02;
|
||||
result.m1 = a01*b00 + a11*b01 + a21*b02;
|
||||
result.m2 = a02*b00 + a12*b01 + a22*b02;
|
||||
result.m3 = a03*b00 + a13*b01 + a23*b02;
|
||||
result.m4 = a00*b10 + a10*b11 + a20*b12;
|
||||
result.m5 = a01*b10 + a11*b11 + a21*b12;
|
||||
result.m6 = a02*b10 + a12*b11 + a22*b12;
|
||||
result.m7 = a03*b10 + a13*b11 + a23*b12;
|
||||
result.m8 = a00*b20 + a10*b21 + a20*b22;
|
||||
result.m9 = a01*b20 + a11*b21 + a21*b22;
|
||||
result.m10 = a02*b20 + a12*b21 + a22*b22;
|
||||
result.m11 = a03*b20 + a13*b21 + a23*b22;
|
||||
result.m12 = mat.m12;
|
||||
result.m13 = mat.m13;
|
||||
result.m14 = mat.m14;
|
||||
result.m15 = mat.m15;
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
// Create rotation matrix from axis and angle (version 2)
|
||||
// TODO: Test this function
|
||||
// NOTE: NO prototype defined!
|
||||
Matrix MatrixFromAxisAngle2(Vector3 axis, float angle)
|
||||
{
|
||||
Matrix result;
|
||||
|
||||
VectorNormalize(&axis);
|
||||
float axisX = axis.x, axisY = axis.y, axisZ = axis.y;
|
||||
|
||||
// Calculate angles
|
||||
float cosres = (float)cos(angle);
|
||||
float sinres = (float)sin(angle);
|
||||
float t = 1.0f - cosres;
|
||||
|
||||
// Do the conversion math once
|
||||
float tXX = t * axisX * axisX;
|
||||
float tXY = t * axisX * axisY;
|
||||
float tXZ = t * axisX * axisZ;
|
||||
float tYY = t * axisY * axisY;
|
||||
float tYZ = t * axisY * axisZ;
|
||||
float tZZ = t * axisZ * axisZ;
|
||||
|
||||
float sinX = sinres * axisX;
|
||||
float sinY = sinres * axisY;
|
||||
float sinZ = sinres * axisZ;
|
||||
|
||||
result.m0 = tXX + cosres;
|
||||
result.m1 = tXY + sinZ;
|
||||
result.m2 = tXZ - sinY;
|
||||
result.m3 = 0;
|
||||
result.m4 = tXY - sinZ;
|
||||
result.m5 = tYY + cosres;
|
||||
result.m6 = tYZ + sinX;
|
||||
result.m7 = 0;
|
||||
result.m8 = tXZ + sinY;
|
||||
result.m9 = tYZ - sinX;
|
||||
result.m10 = tZZ + cosres;
|
||||
result.m11 = 0;
|
||||
result.m12 = 0;
|
||||
result.m13 = 0;
|
||||
result.m14 = 0;
|
||||
result.m15 = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns rotation matrix for a given quaternion
|
||||
Matrix MatrixFromQuaternion(Quaternion q)
|
||||
{
|
||||
Matrix result = MatrixIdentity();
|
||||
|
||||
Vector3 axis;
|
||||
float angle;
|
||||
|
||||
QuaternionToAxisAngle(q, &axis, &angle);
|
||||
|
||||
result = MatrixFromAxisAngle2(axis, angle);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns x-rotation matrix (angle in radians)
|
||||
Matrix MatrixRotateX(float angle)
|
||||
{
|
||||
@ -671,8 +557,8 @@ Matrix MatrixRotateY(float angle)
|
||||
{
|
||||
Matrix result = MatrixIdentity();
|
||||
|
||||
float cosres = (float)cos(angle);
|
||||
float sinres = (float)sin(angle);
|
||||
float cosres = cosf(angle);
|
||||
float sinres = sinf(angle);
|
||||
|
||||
result.m0 = cosres;
|
||||
result.m2 = sinres;
|
||||
@ -706,22 +592,6 @@ Matrix MatrixScale(float x, float y, float z)
|
||||
return result;
|
||||
}
|
||||
|
||||
// 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();
|
||||
|
||||
Matrix mRotation = MatrixRotate(rotation.x, rotation.y, rotation.z);
|
||||
Matrix mScale = MatrixScale(scale.x, scale.y, scale.z);
|
||||
Matrix mTranslate = MatrixTranslate(translation.x, translation.y, translation.z);
|
||||
|
||||
result = MatrixMultiply(MatrixMultiply(mRotation, mScale), mTranslate);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns two matrix multiplication
|
||||
// NOTE: When multiplying matrices... the order matters!
|
||||
Matrix MatrixMultiply(Matrix left, Matrix right)
|
||||
@ -876,7 +746,7 @@ void PrintMatrix(Matrix m)
|
||||
// Module Functions Definition - Quaternion math
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Calculates the length of a quaternion
|
||||
// Computes the length of a quaternion
|
||||
float QuaternionLength(Quaternion quat)
|
||||
{
|
||||
return sqrt(quat.x*quat.x + quat.y*quat.y + quat.z*quat.z + quat.w*quat.w);
|
||||
@ -922,13 +792,13 @@ Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
||||
|
||||
float cosHalfTheta = q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w;
|
||||
|
||||
if (abs(cosHalfTheta) >= 1.0f) result = q1;
|
||||
if (fabs(cosHalfTheta) >= 1.0f) result = q1;
|
||||
else
|
||||
{
|
||||
float halfTheta = acos(cosHalfTheta);
|
||||
float sinHalfTheta = sqrt(1.0f - cosHalfTheta*cosHalfTheta);
|
||||
|
||||
if (abs(sinHalfTheta) < 0.001f)
|
||||
if (fabs(sinHalfTheta) < 0.001f)
|
||||
{
|
||||
result.x = (q1.x*0.5f + q2.x*0.5f);
|
||||
result.y = (q1.y*0.5f + q2.y*0.5f);
|
||||
@ -950,7 +820,7 @@ Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float amount)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns a quaternion from a given rotation matrix
|
||||
// Returns a quaternion for a given rotation matrix
|
||||
Quaternion QuaternionFromMatrix(Matrix matrix)
|
||||
{
|
||||
Quaternion result;
|
||||
@ -1006,29 +876,7 @@ Quaternion QuaternionFromMatrix(Matrix matrix)
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns rotation quaternion for an angle around an axis
|
||||
// NOTE: angle must be provided in radians
|
||||
Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle)
|
||||
{
|
||||
Quaternion result = { 0, 0, 0, 1 };
|
||||
|
||||
if (VectorLength(axis) != 0.0)
|
||||
|
||||
angle *= 0.5;
|
||||
|
||||
VectorNormalize(&axis);
|
||||
|
||||
result.x = axis.x * (float)sin(angle);
|
||||
result.y = axis.y * (float)sin(angle);
|
||||
result.z = axis.z * (float)sin(angle);
|
||||
result.w = (float)cos(angle);
|
||||
|
||||
QuaternionNormalize(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Calculates the matrix from the given quaternion
|
||||
// Returns a matrix for a given quaternion
|
||||
Matrix QuaternionToMatrix(Quaternion q)
|
||||
{
|
||||
Matrix result;
|
||||
@ -1067,14 +915,36 @@ Matrix QuaternionToMatrix(Quaternion q)
|
||||
result.m13 = 0;
|
||||
result.m14 = 0;
|
||||
result.m15 = 1;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns rotation quaternion for an angle and axis
|
||||
// NOTE: angle must be provided in radians
|
||||
Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis)
|
||||
{
|
||||
Quaternion result = { 0, 0, 0, 1 };
|
||||
|
||||
if (VectorLength(axis) != 0.0)
|
||||
|
||||
angle *= 0.5;
|
||||
|
||||
VectorNormalize(&axis);
|
||||
|
||||
result.x = axis.x * (float)sin(angle);
|
||||
result.y = axis.y * (float)sin(angle);
|
||||
result.z = axis.z * (float)sin(angle);
|
||||
result.w = (float)cos(angle);
|
||||
|
||||
QuaternionNormalize(&result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Returns the axis and the angle for a given quaternion
|
||||
void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
|
||||
// Returns the rotation angle and axis for a given quaternion
|
||||
void QuaternionToAxisAngle(Quaternion q, float *outAngle, Vector3 *outAxis)
|
||||
{
|
||||
if (abs(q.w) > 1.0f) QuaternionNormalize(&q);
|
||||
if (fabs(q.w) > 1.0f) QuaternionNormalize(&q);
|
||||
|
||||
Vector3 resAxis = { 0, 0, 0 };
|
||||
float resAngle = 0;
|
||||
@ -1097,4 +967,18 @@ void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle)
|
||||
|
||||
*outAxis = resAxis;
|
||||
*outAngle = resAngle;
|
||||
}
|
||||
|
||||
// Transform a quaternion given a transformation matrix
|
||||
void QuaternionTransform(Quaternion *q, Matrix mat)
|
||||
{
|
||||
float x = q->x;
|
||||
float y = q->y;
|
||||
float z = q->z;
|
||||
float w = q->w;
|
||||
|
||||
q->x = mat.m0*x + mat.m4*y + mat.m8*z + mat.m12*w;
|
||||
q->y = mat.m1*x + mat.m5*y + mat.m9*z + mat.m13*w;
|
||||
q->z = mat.m2*x + mat.m6*y + mat.m10*z + mat.m14*w;
|
||||
q->w = mat.m3*x + mat.m7*y + mat.m11*z + mat.m15*w;
|
||||
}
|
@ -53,15 +53,15 @@
|
||||
float y;
|
||||
float z;
|
||||
} Vector3;
|
||||
#endif
|
||||
|
||||
// Matrix type (OpenGL style 4x4 - right handed, column major)
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12;
|
||||
float m1, m5, m9, m13;
|
||||
float m2, m6, m10, m14;
|
||||
float m3, m7, m11, m15;
|
||||
} Matrix;
|
||||
// Matrix type (OpenGL style 4x4 - right handed, column major)
|
||||
typedef struct Matrix {
|
||||
float m0, m4, m8, m12;
|
||||
float m1, m5, m9, m13;
|
||||
float m2, m6, m10, m14;
|
||||
float m3, m7, m11, m15;
|
||||
} Matrix;
|
||||
#endif
|
||||
|
||||
// Quaternion type
|
||||
typedef struct Quaternion {
|
||||
@ -91,7 +91,7 @@ void VectorNormalize(Vector3 *v); // Normalize provided ve
|
||||
float VectorDistance(Vector3 v1, Vector3 v2); // Calculate distance between two points
|
||||
Vector3 VectorLerp(Vector3 v1, Vector3 v2, float amount); // Calculate linear interpolation between two vectors
|
||||
Vector3 VectorReflect(Vector3 vector, Vector3 normal); // Calculate reflected vector to normal
|
||||
void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 with a given Matrix
|
||||
void VectorTransform(Vector3 *v, Matrix mat); // Transforms a Vector3 by a given Matrix
|
||||
Vector3 VectorZero(void); // Return a Vector3 init to zero
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
@ -107,15 +107,11 @@ 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 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 MatrixRotate(float angle, Vector3 axis); // Returns rotation matrix for an angle around an specified axis (angle in radians)
|
||||
Matrix MatrixRotateX(float angle); // Returns x-rotation matrix (angle in radians)
|
||||
Matrix MatrixRotateY(float angle); // Returns y-rotation matrix (angle in radians)
|
||||
Matrix MatrixRotateZ(float angle); // Returns z-rotation matrix (angle in radians)
|
||||
Matrix MatrixScale(float x, float y, float z); // Returns scaling matrix
|
||||
Matrix MatrixTransform(Vector3 translation, Vector3 rotation, Vector3 scale); // Returns transformation matrix for a given translation, rotation and scale
|
||||
Matrix MatrixMultiply(Matrix left, Matrix right); // Returns two matrix multiplication
|
||||
Matrix MatrixFrustum(double left, double right, double bottom, double top, double near, double far); // Returns perspective projection matrix
|
||||
Matrix MatrixPerspective(double fovy, double aspect, double near, double far); // Returns perspective projection matrix
|
||||
@ -126,14 +122,15 @@ void PrintMatrix(Matrix m); // Print matrix utility
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration to work with Quaternions
|
||||
//------------------------------------------------------------------------------------
|
||||
float QuaternionLength(Quaternion quat); // Calculates the length of a quaternion
|
||||
float QuaternionLength(Quaternion quat); // Compute the length of a quaternion
|
||||
void QuaternionNormalize(Quaternion *q); // Normalize provided quaternion
|
||||
Quaternion QuaternionMultiply(Quaternion q1, Quaternion q2); // Calculate two quaternion multiplication
|
||||
Quaternion QuaternionSlerp(Quaternion q1, Quaternion q2, float slerp); // Calculates spherical linear interpolation between two quaternions
|
||||
Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion from a given rotation matrix
|
||||
Quaternion QuaternionFromAxisAngle(Vector3 axis, float angle); // Returns rotation quaternion for an angle around an axis
|
||||
Matrix QuaternionToMatrix(Quaternion q); // Calculates the matrix from the given quaternion
|
||||
void QuaternionToAxisAngle(Quaternion q, Vector3 *outAxis, float *outAngle); // Returns the axis and the angle for a given quaternion
|
||||
Quaternion QuaternionFromMatrix(Matrix matrix); // Returns a quaternion for a given rotation matrix
|
||||
Matrix QuaternionToMatrix(Quaternion q); // Returns a matrix for a given quaternion
|
||||
Quaternion QuaternionFromAxisAngle(float angle, Vector3 axis); // Returns rotation quaternion for an angle and axis
|
||||
void QuaternionToAxisAngle(Quaternion q, float *outAngle, Vector3 *outAxis); // Returns the rotation angle and axis for a given quaternion
|
||||
void QuaternionTransform(Quaternion *q, Matrix mat); // Transform a quaternion given a transformation matrix
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
1793
src/rlgl.c
1793
src/rlgl.c
File diff suppressed because it is too large
Load Diff
81
src/rlgl.h
81
src/rlgl.h
@ -32,7 +32,7 @@
|
||||
//#define RLGL_STANDALONE // NOTE: To use rlgl as standalone lib, just uncomment this line
|
||||
|
||||
#ifndef RLGL_STANDALONE
|
||||
#include "raylib.h" // Required for typedef: Model
|
||||
#include "raylib.h" // Required for typedef(s): Model, Shader, Texture2D
|
||||
#include "utils.h" // Required for function TraceLog()
|
||||
#endif
|
||||
|
||||
@ -89,21 +89,69 @@ typedef enum { RL_LINES, RL_TRIANGLES, RL_QUADS } DrawMode;
|
||||
typedef enum { OPENGL_11 = 1, OPENGL_33, OPENGL_ES_20 } GlVersion;
|
||||
|
||||
#ifdef RLGL_STANDALONE
|
||||
typedef struct {
|
||||
// Texture formats (support depends on OpenGL version)
|
||||
typedef enum {
|
||||
UNCOMPRESSED_GRAYSCALE = 1, // 8 bit per pixel (no alpha)
|
||||
UNCOMPRESSED_R5G6B5, // 16 bpp
|
||||
UNCOMPRESSED_R8G8B8, // 24 bpp
|
||||
UNCOMPRESSED_R5G5B5A1, // 16 bpp (1 bit alpha)
|
||||
UNCOMPRESSED_R4G4B4A4, // 16 bpp (4 bit alpha)
|
||||
UNCOMPRESSED_R8G8B8A8, // 32 bpp
|
||||
COMPRESSED_DXT1_RGB, // 4 bpp (no alpha)
|
||||
COMPRESSED_DXT1_RGBA, // 4 bpp (1 bit alpha)
|
||||
COMPRESSED_DXT3_RGBA, // 8 bpp
|
||||
COMPRESSED_DXT5_RGBA, // 8 bpp
|
||||
COMPRESSED_ETC1_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_RGB, // 4 bpp
|
||||
COMPRESSED_ETC2_EAC_RGBA, // 8 bpp
|
||||
COMPRESSED_PVRT_RGB, // 4 bpp
|
||||
COMPRESSED_PVRT_RGBA, // 4 bpp
|
||||
/*COMPRESSED_ASTC_RGBA_4x4*/ // 8 bpp
|
||||
} TextureFormat;
|
||||
|
||||
// VertexData type
|
||||
// NOTE: If using OpenGL 1.1, data loaded in CPU; if OpenGL 3.3+ data loaded in GPU (vaoId)
|
||||
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;
|
||||
} VertexData;
|
||||
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
unsigned int vaoId;
|
||||
unsigned int vboId[4];
|
||||
unsigned int textureId;
|
||||
//Matrix transform;
|
||||
} VertexData;
|
||||
|
||||
// Shader type
|
||||
typedef struct Shader {
|
||||
unsigned int id; // Shader program id
|
||||
|
||||
// Variable attributes
|
||||
unsigned int vertexLoc; // Vertex attribute location point (vertex shader)
|
||||
unsigned int texcoordLoc; // Texcoord attribute location point (vertex shader)
|
||||
unsigned int normalLoc; // Normal attribute location point (vertex shader)
|
||||
unsigned int colorLoc; // Color attibute location point (vertex shader)
|
||||
|
||||
// Uniforms
|
||||
unsigned int projectionLoc; // Projection matrix uniform location point (vertex shader)
|
||||
unsigned int modelviewLoc; // ModeView matrix uniform location point (vertex shader)
|
||||
unsigned int textureLoc; // Texture uniform location point (fragment shader)
|
||||
unsigned int tintColorLoc; // Color uniform location point (fragment shader)
|
||||
} Shader;
|
||||
|
||||
// 3d Model type
|
||||
typedef struct Model {
|
||||
VertexData mesh;
|
||||
Matrix transform;
|
||||
Texture2D texture;
|
||||
Shader shader;
|
||||
} Model;
|
||||
|
||||
// Texture2D type
|
||||
typedef struct Texture2D {
|
||||
unsigned int id; // Texture id
|
||||
int width;
|
||||
int height;
|
||||
} Texture2D;
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -145,11 +193,13 @@ void rlColor4f(float x, float y, float z, float w); // Define one vertex (color)
|
||||
void rlEnableTexture(unsigned int id); // Enable texture usage
|
||||
void rlDisableTexture(void); // Disable texture usage
|
||||
void rlDeleteTextures(unsigned int id); // Delete OpenGL texture from GPU
|
||||
void rlDeleteShader(unsigned int id); // Delete OpenGL shader program from GPU
|
||||
void rlDeleteVertexArrays(unsigned int id); // Unload vertex data (VAO) from GPU memory
|
||||
void rlDeleteBuffers(unsigned int id); // Unload vertex data (VBO) from GPU memory
|
||||
void rlClearColor(byte r, byte g, byte b, byte a); // Clear color buffer with color
|
||||
void rlClearScreenBuffers(void); // Clear used screen buffers (color and depth)
|
||||
int rlGetVersion(void); // Returns current OpenGL version
|
||||
void rlEnableFBO(void); // Enable rendering to postprocessing FBO
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Functions Declaration - rlgl functionality
|
||||
@ -159,11 +209,20 @@ void rlglClose(void); // De-init rlgl
|
||||
void rlglDraw(void); // Draw VAO/VBO
|
||||
void rlglInitGraphics(int offsetX, int offsetY, int width, int height); // Initialize Graphics (OpenGL stuff)
|
||||
|
||||
unsigned int rlglLoadTexture(unsigned char *data, int width, int height, bool genMipmaps); // Load in GPU OpenGL texture
|
||||
unsigned int rlglLoadCompressedTexture(unsigned char *data, int width, int height, int mipmapCount, int format);
|
||||
unsigned int rlglLoadTexture(void *data, int width, int height, int textureFormat, int mipmapCount, bool genMipmaps); // Load in GPU OpenGL texture
|
||||
Shader rlglLoadShader(char *vsFileName, char *fsFileName); // Load a shader (vertex shader + fragment shader) from files
|
||||
unsigned int rlglLoadShaderFromText(char *vShaderStr, char *fShaderStr); // Load a shader from text data
|
||||
void rlglInitPostpro(void); // Initialize postprocessing system
|
||||
void rlglDrawPostpro(void); // Draw with postprocessing shader
|
||||
void rlglSetPostproShader(Shader shader); // Set postprocessing shader
|
||||
void rlglSetModelShader(Model *model, Shader shader); // Set shader for a model
|
||||
void rlglSetCustomShader(Shader shader); // Set custom shader to be used on batch draw
|
||||
void rlglSetDefaultShader(void); // Set default shader to be used on batch draw
|
||||
|
||||
Model rlglLoadModel(VertexData mesh); // Upload vertex data into GPU and provided VAO/VBO ids
|
||||
void rlglDrawModel(Model model, Vector3 position, Vector3 rotation, Vector3 scale, Color color, bool wires);
|
||||
void rlglDrawModel(Model model, Vector3 position, float rotationAngle, Vector3 rotationAxis, Vector3 scale, Color color, bool wires);
|
||||
|
||||
Vector3 rlglUnproject(Vector3 source, Matrix proj, Matrix view); // Get world coordinates from screen coordinates
|
||||
|
||||
byte *rlglReadScreenPixels(int width, int height); // Read screen pixel data (color buffer)
|
||||
|
||||
|
46
src/shapes.c
46
src/shapes.c
@ -98,7 +98,7 @@ void DrawLineV(Vector2 startPos, Vector2 endPos, Color color)
|
||||
// Draw a color-filled circle
|
||||
void DrawCircle(int centerX, int centerY, float radius, Color color)
|
||||
{
|
||||
DrawPoly((Vector2){centerX, centerY}, 360, radius, 0, color);
|
||||
DrawPoly((Vector2){ centerX, centerY }, 36, radius, 0, color);
|
||||
}
|
||||
|
||||
// Draw a gradient-filled circle
|
||||
@ -106,14 +106,14 @@ void DrawCircle(int centerX, int centerY, float radius, Color color)
|
||||
void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Color color2)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i=0; i < 360; i += 2)
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(color1.r, color1.g, color1.b, color1.a);
|
||||
rlVertex2i(centerX, centerY);
|
||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
|
||||
rlColor4ub(color2.r, color2.g, color2.b, color2.a);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*(i+2)) * radius, centerY + cos(DEG2RAD*(i+2)) * radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -122,12 +122,12 @@ void DrawCircleGradient(int centerX, int centerY, float radius, Color color1, Co
|
||||
void DrawCircleV(Vector2 center, float radius, Color color)
|
||||
{
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i=0; i < 360; i += 2)
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlVertex2i(center.x, center.y);
|
||||
rlVertex2f(center.x + sin(DEG2RAD*i) * radius, center.y + cos(DEG2RAD*i) * radius);
|
||||
rlVertex2f(center.x + sin(DEG2RAD*(i+2)) * radius, center.y + cos(DEG2RAD*(i+2)) * radius);
|
||||
rlVertex2f(center.x + sin(DEG2RAD*i)*radius, center.y + cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(center.x + sin(DEG2RAD*(i + 10)) * radius, center.y + cos(DEG2RAD*(i + 10)) * radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -139,10 +139,10 @@ void DrawCircleLines(int centerX, int centerY, float radius, Color color)
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
// NOTE: Circle outline is drawn pixel by pixel every degree (0 to 360)
|
||||
for (int i=0; i < 360; i++)
|
||||
for (int i = 0; i < 360; i += 10)
|
||||
{
|
||||
rlVertex2f(centerX + sin(DEG2RAD*i) * radius, centerY + cos(DEG2RAD*i) * radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*(i+1)) * radius, centerY + cos(DEG2RAD*(i+1)) * radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*i)*radius, centerY + cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(centerX + sin(DEG2RAD*(i + 10)) * radius, centerY + cos(DEG2RAD*(i + 10))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -201,7 +201,7 @@ void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f);
|
||||
|
||||
rlTexCoord2f(0.0f, 0.0f);
|
||||
rlVertex2f(position.x, position.y);
|
||||
@ -275,13 +275,13 @@ void DrawPoly(Vector2 center, int sides, float radius, float rotation, Color col
|
||||
rlRotatef(rotation, 0, 0, 1);
|
||||
|
||||
rlBegin(RL_TRIANGLES);
|
||||
for (int i=0; i < 360; i += 360/sides)
|
||||
for (int i = 0; i < 360; i += 360/sides)
|
||||
{
|
||||
rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
rlVertex2i(0, 0);
|
||||
rlVertex2f(sin(DEG2RAD*i) * radius, cos(DEG2RAD*i) * radius);
|
||||
rlVertex2f(sin(DEG2RAD*(i+360/sides)) * radius, cos(DEG2RAD*(i+360/sides)) * radius);
|
||||
rlVertex2f(sin(DEG2RAD*i)*radius, cos(DEG2RAD*i)*radius);
|
||||
rlVertex2f(sin(DEG2RAD*(i + 360/sides))*radius, cos(DEG2RAD*(i + 360/sides))*radius);
|
||||
}
|
||||
rlEnd();
|
||||
rlPopMatrix();
|
||||
@ -299,8 +299,8 @@ void DrawPolyEx(Vector2 *points, int numPoints, Color color)
|
||||
for (int i = 0; i < numPoints - 2; i++)
|
||||
{
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i+1].x, points[i+1].y);
|
||||
rlVertex2f(points[i+2].x, points[i+2].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
rlVertex2f(points[i + 2].x, points[i + 2].y);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -318,7 +318,7 @@ void DrawPolyExLines(Vector2 *points, int numPoints, Color color)
|
||||
for (int i = 0; i < numPoints - 1; i++)
|
||||
{
|
||||
rlVertex2f(points[i].x, points[i].y);
|
||||
rlVertex2f(points[i+1].x, points[i+1].y);
|
||||
rlVertex2f(points[i + 1].x, points[i + 1].y);
|
||||
}
|
||||
rlEnd();
|
||||
}
|
||||
@ -367,10 +367,10 @@ bool CheckCollisionRecs(Rectangle rec1, Rectangle rec2)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
int dx = abs((rec1.x + rec1.width / 2) - (rec2.x + rec2.width / 2));
|
||||
int dy = abs((rec1.y + rec1.height / 2) - (rec2.y + rec2.height / 2));
|
||||
int dx = abs((rec1.x + rec1.width/2) - (rec2.x + rec2.width/2));
|
||||
int dy = abs((rec1.y + rec1.height/2) - (rec2.y + rec2.height/2));
|
||||
|
||||
if ((dx <= (rec1.width / 2 + rec2.width / 2)) && ((dy <= (rec1.height / 2 + rec2.height / 2)))) collision = true;
|
||||
if ((dx <= (rec1.width/2 + rec2.width/2)) && ((dy <= (rec1.height/2 + rec2.height/2)))) collision = true;
|
||||
|
||||
return collision;
|
||||
}
|
||||
@ -395,10 +395,10 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
||||
{
|
||||
bool collision = false;
|
||||
|
||||
float dx = abs((rec.x + rec.width / 2) - center.x);
|
||||
float dy = abs((rec.y + rec.height / 2) - center.y);
|
||||
float dx = fabs((rec.x + rec.width/2) - center.x);
|
||||
float dy = fabs((rec.y + rec.height/2) - center.y);
|
||||
|
||||
if ((dx <= (rec.width / 2 + radius)) && (dy <= (rec.height / 2 + radius))) collision = true;
|
||||
if ((dx <= (rec.width/2 + radius)) && (dy <= (rec.height/2 + radius))) collision = true;
|
||||
|
||||
return collision;
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
#version 150
|
||||
|
||||
uniform sampler2D texture0;
|
||||
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
out vec4 pixelColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Output pixel color
|
||||
pixelColor = texture(texture0, fragTexCoord) * fragColor;
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
#version 150
|
||||
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 modelviewMatrix;
|
||||
|
||||
in vec3 vertexPosition;
|
||||
in vec2 vertexTexCoord;
|
||||
in vec4 vertexColor;
|
||||
|
||||
out vec2 fragTexCoord;
|
||||
out vec4 fragColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Pass some variables to the fragment shader
|
||||
fragTexCoord = vertexTexCoord;
|
||||
fragColor = vertexColor;
|
||||
|
||||
// Apply all matrix transformations to vertex
|
||||
gl_Position = projectionMatrix * modelviewMatrix * vec4(vertexPosition, 1.0);
|
||||
}
|
206
src/stb_image.h
206
src/stb_image.h
@ -1,4 +1,4 @@
|
||||
/* stb_image - v2.00b - public domain image loader - http://nothings.org/stb_image.h
|
||||
/* stb_image - v2.05 - public domain image loader - http://nothings.org/stb_image.h
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
Do this:
|
||||
@ -143,6 +143,13 @@
|
||||
|
||||
|
||||
Latest revision history:
|
||||
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
||||
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
||||
2.03 (2015-04-12) additional corruption checking
|
||||
stbi_set_flip_vertically_on_load
|
||||
fix NEON support; fix mingw support
|
||||
2.02 (2015-01-19) fix incorrect assert, fix warning
|
||||
2.01 (2015-01-17) fix various warnings
|
||||
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
|
||||
2.00 (2014-12-25) optimize JPEG, including x86 SSE2 & ARM NEON SIMD
|
||||
progressive JPEG
|
||||
@ -154,8 +161,6 @@
|
||||
1.47 (2014-12-14) 1/2/4-bit PNG support (both grayscale and paletted)
|
||||
optimize PNG
|
||||
fix bug in interlaced PNG with user-specified channel count
|
||||
1.46 (2014-08-26) fix broken tRNS chunk in non-paletted PNG
|
||||
1.45 (2014-08-16) workaround MSVC-ARM internal compiler error by wrapping malloc
|
||||
|
||||
See end of file for full revision history.
|
||||
|
||||
@ -178,7 +183,7 @@
|
||||
James "moose2000" Brown (iPhone PNG) Roy Eltham
|
||||
Ben "Disch" Wenger (io callbacks) Luke Graham
|
||||
Omar Cornut (1/2/4-bit PNG) Thomas Ruf
|
||||
John Bartholomew
|
||||
Nicolas Guillemot (vertical flip) John Bartholomew
|
||||
Ken Hamada
|
||||
Optimizations & bugfixes Cort Stratton
|
||||
Fabian "ryg" Giesen Blazej Dariusz Roszkowski
|
||||
@ -191,6 +196,12 @@
|
||||
Ronny Chevalier
|
||||
Michal Cichon
|
||||
Tero Hanninen
|
||||
Sergio Gonzalez
|
||||
Cass Everitt
|
||||
Engin Manap
|
||||
Martins Mozeiko
|
||||
Joseph Thomson
|
||||
Phil Jordan
|
||||
|
||||
License:
|
||||
This software is in the public domain. Where that dedication is not
|
||||
@ -371,6 +382,7 @@ License:
|
||||
// and only if iPhone convert-to-rgb processing is on).
|
||||
//
|
||||
|
||||
|
||||
#define STBI_NO_HDR // RaySan: not required by raylib
|
||||
#define STBI_NO_SIMD // RaySan: issues when compiling with GCC 4.7.2
|
||||
|
||||
@ -489,6 +501,8 @@ STBIDEF void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultipl
|
||||
// or just pass them through "as-is"
|
||||
STBIDEF void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert);
|
||||
|
||||
// flip the image vertically, so the first pixel in the output array is the bottom left
|
||||
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip);
|
||||
|
||||
// ZLIB client - used by PNG, available for other purposes
|
||||
|
||||
@ -626,7 +640,38 @@ typedef unsigned char validate_uint32[sizeof(stbi__uint32)==4 ? 1 : -1];
|
||||
#define STBI_FREE(p) free(p)
|
||||
#endif
|
||||
|
||||
#if !defined(STBI_NO_SIMD) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386) || defined(_M_IX86))
|
||||
// x86/x64 detection
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#define STBI__X64_TARGET
|
||||
#elif defined(__i386) || defined(_M_IX86)
|
||||
#define STBI__X86_TARGET
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__) && (defined(STBI__X86_TARGET) || defined(STBI__X64_TARGET)) && !defined(__SSE2__) && !defined(STBI_NO_SIMD)
|
||||
// NOTE: not clear do we actually need this for the 64-bit path?
|
||||
// gcc doesn't support sse2 intrinsics unless you compile with -msse2,
|
||||
// (but compiling with -msse2 allows the compiler to use SSE2 everywhere;
|
||||
// this is just broken and gcc are jerks for not fixing it properly
|
||||
// http://www.virtualdub.org/blog/pivot/entry.php?id=363 )
|
||||
#define STBI_NO_SIMD
|
||||
#endif
|
||||
|
||||
#if defined(__MINGW32__) && defined(STBI__X86_TARGET) && !defined(STBI_MINGW_ENABLE_SSE2) && !defined(STBI_NO_SIMD)
|
||||
// Note that __MINGW32__ doesn't actually mean 32-bit, so we have to avoid STBI__X64_TARGET
|
||||
//
|
||||
// 32-bit MinGW wants ESP to be 16-byte aligned, but this is not in the
|
||||
// Windows ABI and VC++ as well as Windows DLLs don't maintain that invariant.
|
||||
// As a result, enabling SSE2 on 32-bit MinGW is dangerous when not
|
||||
// simultaneously enabling "-mstackrealign".
|
||||
//
|
||||
// See https://github.com/nothings/stb/issues/81 for more information.
|
||||
//
|
||||
// So default to no SSE2 on 32-bit MinGW. If you've read this far and added
|
||||
// -mstackrealign to your build settings, feel free to #define STBI_MINGW_ENABLE_SSE2.
|
||||
#define STBI_NO_SIMD
|
||||
#endif
|
||||
|
||||
#if !defined(STBI_NO_SIMD) && defined(STBI__X86_TARGET)
|
||||
#define STBI_SSE2
|
||||
#include <emmintrin.h>
|
||||
|
||||
@ -879,7 +924,14 @@ static float *stbi__ldr_to_hdr(stbi_uc *data, int x, int y, int comp);
|
||||
static stbi_uc *stbi__hdr_to_ldr(float *data, int x, int y, int comp);
|
||||
#endif
|
||||
|
||||
static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
static int stbi__vertically_flip_on_load = 0;
|
||||
|
||||
STBIDEF void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip)
|
||||
{
|
||||
stbi__vertically_flip_on_load = flag_true_if_should_flip;
|
||||
}
|
||||
|
||||
static unsigned char *stbi__load_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
#ifndef STBI_NO_JPEG
|
||||
if (stbi__jpeg_test(s)) return stbi__jpeg_load(s,x,y,comp,req_comp);
|
||||
@ -919,6 +971,53 @@ static unsigned char *stbi_load_main(stbi__context *s, int *x, int *y, int *comp
|
||||
return stbi__errpuc("unknown image type", "Image not of any known type, or corrupt");
|
||||
}
|
||||
|
||||
static unsigned char *stbi__load_flip(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
unsigned char *result = stbi__load_main(s, x, y, comp, req_comp);
|
||||
|
||||
if (stbi__vertically_flip_on_load && result != NULL) {
|
||||
int w = *x, h = *y;
|
||||
int depth = req_comp ? req_comp : *comp;
|
||||
int row,col,z;
|
||||
stbi_uc temp;
|
||||
|
||||
// @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
|
||||
for (row = 0; row < (h>>1); row++) {
|
||||
for (col = 0; col < w; col++) {
|
||||
for (z = 0; z < depth; z++) {
|
||||
temp = result[(row * w + col) * depth + z];
|
||||
result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
|
||||
result[((h - row - 1) * w + col) * depth + z] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void stbi__float_postprocess(float *result, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
if (stbi__vertically_flip_on_load && result != NULL) {
|
||||
int w = *x, h = *y;
|
||||
int depth = req_comp ? req_comp : *comp;
|
||||
int row,col,z;
|
||||
float temp;
|
||||
|
||||
// @OPTIMIZE: use a bigger temp buffer and memcpy multiple pixels at once
|
||||
for (row = 0; row < (h>>1); row++) {
|
||||
for (col = 0; col < w; col++) {
|
||||
for (z = 0; z < depth; z++) {
|
||||
temp = result[(row * w + col) * depth + z];
|
||||
result[(row * w + col) * depth + z] = result[((h - row - 1) * w + col) * depth + z];
|
||||
result[((h - row - 1) * w + col) * depth + z] = temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
|
||||
static FILE *stbi__fopen(char const *filename, char const *mode)
|
||||
@ -949,7 +1048,7 @@ STBIDEF stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req
|
||||
unsigned char *result;
|
||||
stbi__context s;
|
||||
stbi__start_file(&s,f);
|
||||
result = stbi_load_main(&s,x,y,comp,req_comp);
|
||||
result = stbi__load_flip(&s,x,y,comp,req_comp);
|
||||
if (result) {
|
||||
// need to 'unget' all the characters in the IO buffer
|
||||
fseek(f, - (int) (s.img_buffer_end - s.img_buffer), SEEK_CUR);
|
||||
@ -962,25 +1061,29 @@ STBIDEF stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, i
|
||||
{
|
||||
stbi__context s;
|
||||
stbi__start_mem(&s,buffer,len);
|
||||
return stbi_load_main(&s,x,y,comp,req_comp);
|
||||
return stbi__load_flip(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
STBIDEF stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi__context s;
|
||||
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
|
||||
return stbi_load_main(&s,x,y,comp,req_comp);
|
||||
return stbi__load_flip(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_LINEAR
|
||||
static float *stbi_loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
static float *stbi__loadf_main(stbi__context *s, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
unsigned char *data;
|
||||
#ifndef STBI_NO_HDR
|
||||
if (stbi__hdr_test(s))
|
||||
return stbi__hdr_load(s,x,y,comp,req_comp);
|
||||
if (stbi__hdr_test(s)) {
|
||||
float *hdr_data = stbi__hdr_load(s,x,y,comp,req_comp);
|
||||
if (hdr_data)
|
||||
stbi__float_postprocess(hdr_data,x,y,comp,req_comp);
|
||||
return hdr_data;
|
||||
}
|
||||
#endif
|
||||
data = stbi_load_main(s, x, y, comp, req_comp);
|
||||
data = stbi__load_flip(s, x, y, comp, req_comp);
|
||||
if (data)
|
||||
return stbi__ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp);
|
||||
return stbi__errpf("unknown image type", "Image not of any known type, or corrupt");
|
||||
@ -990,14 +1093,14 @@ STBIDEF float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, in
|
||||
{
|
||||
stbi__context s;
|
||||
stbi__start_mem(&s,buffer,len);
|
||||
return stbi_loadf_main(&s,x,y,comp,req_comp);
|
||||
return stbi__loadf_main(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
STBIDEF float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp)
|
||||
{
|
||||
stbi__context s;
|
||||
stbi__start_callbacks(&s, (stbi_io_callbacks *) clbk, user);
|
||||
return stbi_loadf_main(&s,x,y,comp,req_comp);
|
||||
return stbi__loadf_main(&s,x,y,comp,req_comp);
|
||||
}
|
||||
|
||||
#ifndef STBI_NO_STDIO
|
||||
@ -1015,7 +1118,7 @@ STBIDEF float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_
|
||||
{
|
||||
stbi__context s;
|
||||
stbi__start_file(&s,f);
|
||||
return stbi_loadf_main(&s,x,y,comp,req_comp);
|
||||
return stbi__loadf_main(&s,x,y,comp,req_comp);
|
||||
}
|
||||
#endif // !STBI_NO_STDIO
|
||||
|
||||
@ -1138,6 +1241,10 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
|
||||
|
||||
static void stbi__skip(stbi__context *s, int n)
|
||||
{
|
||||
if (n < 0) {
|
||||
s->img_buffer = s->img_buffer_end;
|
||||
return;
|
||||
}
|
||||
if (s->io.read) {
|
||||
int blen = (int) (s->img_buffer_end - s->img_buffer);
|
||||
if (blen < n) {
|
||||
@ -1546,6 +1653,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
|
||||
|
||||
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
|
||||
k = stbi_lrot(j->code_buffer, n);
|
||||
STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
|
||||
j->code_buffer = k & ~stbi__bmask[n];
|
||||
k &= stbi__bmask[n];
|
||||
j->code_bits -= n;
|
||||
@ -1730,15 +1838,12 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
short *p = &data[stbi__jpeg_dezigzag[k]];
|
||||
if (*p != 0)
|
||||
if (stbi__jpeg_get_bit(j))
|
||||
{
|
||||
if ((*p & bit)==0)
|
||||
{
|
||||
if ((*p & bit)==0) {
|
||||
if (*p > 0)
|
||||
*p += bit;
|
||||
else
|
||||
*p -= bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
k = j->spec_start;
|
||||
@ -1754,8 +1859,11 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
if (r)
|
||||
j->eob_run += stbi__jpeg_get_bits(j, r);
|
||||
r = 64; // force end of block
|
||||
} else
|
||||
r = 16; // r=15 is the code for 16 0s
|
||||
} else {
|
||||
// r=15 s=0 should write 16 0s, so we just do
|
||||
// a run of 15 0s and then write s (which is 0),
|
||||
// so we don't have to do anything special here
|
||||
}
|
||||
} else {
|
||||
if (s != 1) return stbi__err("bad huffman code", "Corrupt JPEG");
|
||||
// sign bit
|
||||
@ -1767,27 +1875,21 @@ static int stbi__jpeg_decode_block_prog_ac(stbi__jpeg *j, short data[64], stbi__
|
||||
|
||||
// advance by r
|
||||
while (k <= j->spec_end) {
|
||||
short *p = &data[stbi__jpeg_dezigzag[k]];
|
||||
short *p = &data[stbi__jpeg_dezigzag[k++]];
|
||||
if (*p != 0) {
|
||||
if (stbi__jpeg_get_bit(j))
|
||||
{
|
||||
if ((*p & bit)==0)
|
||||
{
|
||||
if ((*p & bit)==0) {
|
||||
if (*p > 0)
|
||||
*p += bit;
|
||||
else
|
||||
*p -= bit;
|
||||
}
|
||||
}
|
||||
++k;
|
||||
} else {
|
||||
if (r == 0) {
|
||||
if (s)
|
||||
data[stbi__jpeg_dezigzag[k++]] = s;
|
||||
*p = (short) s;
|
||||
break;
|
||||
}
|
||||
--r;
|
||||
++k;
|
||||
}
|
||||
}
|
||||
} while (k <= j->spec_end);
|
||||
@ -2207,7 +2309,7 @@ static void stbi__idct_simd(stbi_uc *out, int out_stride, short data[64])
|
||||
// pass 1
|
||||
dct_trn16(row0, row1); // a0b0a2b2a4b4a6b6
|
||||
dct_trn16(row2, row3);
|
||||
dct_trn16(row4, row5);
|
||||
dct_trn16(row4, row5);
|
||||
dct_trn16(row6, row7);
|
||||
|
||||
// pass 2
|
||||
@ -2434,7 +2536,6 @@ static int stbi__parse_entropy_coded_data(stbi__jpeg *z)
|
||||
for (x=0; x < z->img_comp[n].h; ++x) {
|
||||
int x2 = (i*z->img_comp[n].h + x);
|
||||
int y2 = (j*z->img_comp[n].v + y);
|
||||
//int ha = z->img_comp[n].ha; // RaySan: Unused, commented to avoid warning
|
||||
short *data = z->img_comp[n].coeff + 64 * (x2 + y2 * z->img_comp[n].coeff_w);
|
||||
if (!stbi__jpeg_decode_block_prog_dc(z, data, &z->huff_dc[z->img_comp[n].hd], n))
|
||||
return 0;
|
||||
@ -2701,6 +2802,10 @@ static int stbi__decode_jpeg_header(stbi__jpeg *z, int scan)
|
||||
static int stbi__decode_jpeg_image(stbi__jpeg *j)
|
||||
{
|
||||
int m;
|
||||
for (m = 0; m < 4; m++) {
|
||||
j->img_comp[m].raw_data = NULL;
|
||||
j->img_comp[m].raw_coeff = NULL;
|
||||
}
|
||||
j->restart_interval = 0;
|
||||
if (!stbi__decode_jpeg_header(j, STBI__SCAN_load)) return 0;
|
||||
m = stbi__get_marker(j);
|
||||
@ -3013,7 +3118,7 @@ static void stbi__YCbCr_to_RGB_simd(stbi_uc *out, stbi_uc const *y, stbi_uc cons
|
||||
__m128i cr_const1 = _mm_set1_epi16( - (short) ( 0.71414f*4096.0f+0.5f));
|
||||
__m128i cb_const0 = _mm_set1_epi16( - (short) ( 0.34414f*4096.0f+0.5f));
|
||||
__m128i cb_const1 = _mm_set1_epi16( (short) ( 1.77200f*4096.0f+0.5f));
|
||||
__m128i y_bias = _mm_set1_epi8((char) 128);
|
||||
__m128i y_bias = _mm_set1_epi8((char) (unsigned char) 128);
|
||||
__m128i xw = _mm_set1_epi16(255); // alpha channel
|
||||
|
||||
for (; i+7 < count; i += 8) {
|
||||
@ -3380,7 +3485,8 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
|
||||
++sizes[sizelist[i]];
|
||||
sizes[0] = 0;
|
||||
for (i=1; i < 16; ++i)
|
||||
STBI_ASSERT(sizes[i] <= (1 << i));
|
||||
if (sizes[i] > (1 << i))
|
||||
return stbi__err("bad sizes", "Corrupt PNG");
|
||||
code = 0;
|
||||
for (i=1; i < 16; ++i) {
|
||||
next_code[i] = code;
|
||||
@ -3388,7 +3494,7 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z, stbi_uc *sizelist, int num)
|
||||
z->firstsymbol[i] = (stbi__uint16) k;
|
||||
code = (code + sizes[i]);
|
||||
if (sizes[i])
|
||||
if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt JPEG");
|
||||
if (code-1 >= (1 << i)) return stbi__err("bad codelengths","Corrupt PNG");
|
||||
z->maxcode[i] = code << (16-i); // preshift for inner loop
|
||||
code <<= 1;
|
||||
k += sizes[i];
|
||||
@ -3557,9 +3663,9 @@ static int stbi__parse_huffman_block(stbi__zbuf *a)
|
||||
p = (stbi_uc *) (zout - dist);
|
||||
if (dist == 1) { // run of one byte; common in images.
|
||||
stbi_uc v = *p;
|
||||
do *zout++ = v; while (--len);
|
||||
if (len) { do *zout++ = v; while (--len); }
|
||||
} else {
|
||||
do *zout++ = *p++; while (--len);
|
||||
if (len) { do *zout++ = *p++; while (--len); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3587,7 +3693,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
|
||||
n = 0;
|
||||
while (n < hlit + hdist) {
|
||||
int c = stbi__zhuffman_decode(a, &z_codelength);
|
||||
STBI_ASSERT(c >= 0 && c < 19);
|
||||
if (c < 0 || c >= 19) return stbi__err("bad codelengths", "Corrupt PNG");
|
||||
if (c < 16)
|
||||
lencodes[n++] = (stbi_uc) c;
|
||||
else if (c == 16) {
|
||||
@ -4019,7 +4125,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
|
||||
cur[i*2+0] = cur[i];
|
||||
}
|
||||
} else {
|
||||
assert(img_n == 3);
|
||||
STBI_ASSERT(img_n == 3);
|
||||
for (i=x-1; i >= 0; --i) {
|
||||
cur[i*4+3] = 255;
|
||||
cur[i*4+2] = cur[i*3+2];
|
||||
@ -4284,6 +4390,7 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
|
||||
if (first) return stbi__err("first not IHDR", "Corrupt PNG");
|
||||
if (pal_img_n && !pal_len) return stbi__err("no PLTE","Corrupt PNG");
|
||||
if (scan == STBI__SCAN_header) { s->img_n = pal_img_n; return 1; }
|
||||
if ((int)(ioff + c.length) < (int)ioff) return 0;
|
||||
if (ioff + c.length > idata_limit) {
|
||||
stbi_uc *p;
|
||||
if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096;
|
||||
@ -4643,7 +4750,7 @@ static stbi_uc *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
}
|
||||
} else {
|
||||
for (i=0; i < (int) s->img_x; ++i) {
|
||||
stbi__uint32 v = (stbi__uint32) (bpp == 16 ? stbi__get16le(s) : stbi__get32le(s));
|
||||
stbi__uint32 v = (bpp == 16 ? (stbi__uint32) stbi__get16le(s) : stbi__get32le(s));
|
||||
int a;
|
||||
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mr, rshift, rcount));
|
||||
out[z++] = STBI__BYTECAST(stbi__shiftsigned(v & mg, gshift, gcount));
|
||||
@ -4800,7 +4907,7 @@ static stbi_uc *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int
|
||||
*y = tga_height;
|
||||
if (comp) *comp = tga_comp;
|
||||
|
||||
tga_data = (unsigned char*)stbi__malloc( tga_width * tga_height * tga_comp );
|
||||
tga_data = (unsigned char*)stbi__malloc( (size_t)tga_width * tga_height * tga_comp );
|
||||
if (!tga_data) return stbi__errpuc("outofmem", "Out of memory");
|
||||
|
||||
// skip to the data's starting position (offset usually = 0)
|
||||
@ -5461,6 +5568,7 @@ static stbi_uc *stbi__process_gif_raster(stbi__context *s, stbi__gif *g)
|
||||
stbi__gif_lzw *p;
|
||||
|
||||
lzw_cs = stbi__get8(s);
|
||||
if (lzw_cs > 12) return NULL;
|
||||
clear = 1 << lzw_cs;
|
||||
first = 1;
|
||||
codesize = lzw_cs + 1;
|
||||
@ -6130,7 +6238,7 @@ static int stbi__info_main(stbi__context *s, int *x, int *y, int *comp)
|
||||
#ifndef STBI_NO_PSD
|
||||
if (stbi__psd_info(s, x, y, comp)) return 1;
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef STBI_NO_PIC
|
||||
if (stbi__pic_info(s, x, y, comp)) return 1;
|
||||
#endif
|
||||
@ -6192,6 +6300,13 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
|
||||
/*
|
||||
revision history:
|
||||
2.05 (2015-04-19) fix bug in progressive JPEG handling, fix warning
|
||||
2.04 (2015-04-15) try to re-enable SIMD on MinGW 64-bit
|
||||
2.03 (2015-04-12) extra corruption checking (mmozeiko)
|
||||
stbi_set_flip_vertically_on_load (nguillemot)
|
||||
fix NEON support; fix mingw support
|
||||
2.02 (2015-01-19) fix incorrect assert, fix warning
|
||||
2.01 (2015-01-17) fix various warnings; suppress SIMD on gcc 32-bit without -msse2
|
||||
2.00b (2014-12-25) fix STBI_MALLOC in progressive JPEG
|
||||
2.00 (2014-12-25) optimize JPG, including x86 SSE2 & NEON SIMD (ryg)
|
||||
progressive JPEG (stb)
|
||||
@ -6276,7 +6391,7 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
1.21 fix use of 'stbi_uc' in header (reported by jon blow)
|
||||
1.20 added support for Softimage PIC, by Tom Seddon
|
||||
1.19 bug in interlaced PNG corruption check (found by ryg)
|
||||
1.18 2008-08-02
|
||||
1.18 (2008-08-02)
|
||||
fix a threading bug (local mutable static)
|
||||
1.17 support interlaced PNG
|
||||
1.16 major bugfix - stbi__convert_format converted one too many pixels
|
||||
@ -6321,5 +6436,6 @@ STBIDEF int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int
|
||||
0.52 png handles req_comp=3,4 directly; minor cleanup; jpeg comments
|
||||
0.51 obey req_comp requests, 1-component jpegs return as 1-component,
|
||||
on 'test' only check type, not whether we support this variant
|
||||
0.50 first released version
|
||||
0.50 (2006-11-19)
|
||||
first released version
|
||||
*/
|
||||
|
@ -1,16 +1,15 @@
|
||||
/* stb_image_write - v0.95 - public domain - http://nothings.org/stb/stb_image_write.h
|
||||
/* stb_image_write - v0.98 - public domain - http://nothings.org/stb/stb_image_write.h
|
||||
writes out PNG/BMP/TGA images to C stdio - Sean Barrett 2010
|
||||
no warranty implied; use at your own risk
|
||||
|
||||
|
||||
Before including,
|
||||
Before #including,
|
||||
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
in the file that you want to have the implementation.
|
||||
|
||||
Will probably not work correctly with strict-aliasing optimizations.
|
||||
in the file that you want to have the implementation.
|
||||
|
||||
Will probably not work correctly with strict-aliasing optimizations.
|
||||
|
||||
ABOUT:
|
||||
|
||||
@ -22,16 +21,24 @@ ABOUT:
|
||||
for source code compactness and simplicitly, not optimal image file size
|
||||
or run-time performance.
|
||||
|
||||
BUILDING:
|
||||
|
||||
You can #define STBIW_ASSERT(x) before the #include to avoid using assert.h.
|
||||
You can #define STBIW_MALLOC(), STBIW_REALLOC(), and STBIW_FREE() to replace
|
||||
malloc,realloc,free.
|
||||
You can define STBIW_MEMMOVE() to replace memmove()
|
||||
|
||||
USAGE:
|
||||
|
||||
There are three functions, one for each image file format:
|
||||
There are four functions, one for each image file format:
|
||||
|
||||
int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
int stbi_write_hdr(char const *filename, int w, int h, int comp, const void *data);
|
||||
|
||||
Each function returns 0 on failure and non-0 on success.
|
||||
|
||||
|
||||
The functions create an image file defined by the parameters. The image
|
||||
is a rectangle of pixels stored from left-to-right, top-to-bottom.
|
||||
Each pixel contains 'comp' channels of data stored interleaved with 8-bits
|
||||
@ -44,13 +51,30 @@ USAGE:
|
||||
PNG creates output files with the same number of components as the input.
|
||||
The BMP format expands Y to RGB in the file format and does not
|
||||
output alpha.
|
||||
|
||||
|
||||
PNG supports writing rectangles of data even when the bytes storing rows of
|
||||
data are not consecutive in memory (e.g. sub-rectangles of a larger image),
|
||||
by supplying the stride between the beginning of adjacent rows. The other
|
||||
formats do not. (Thus you cannot write a native-format BMP through the BMP
|
||||
writer, both because it is in BGR order and because it may have padding
|
||||
at the end of the line.)
|
||||
|
||||
HDR expects linear float data. Since the format is always 32-bit rgb(e)
|
||||
data, alpha (if provided) is discarded, and for monochrome data it is
|
||||
replicated across all three channels.
|
||||
|
||||
CREDITS:
|
||||
|
||||
PNG/BMP/TGA
|
||||
Sean Barrett
|
||||
HDR
|
||||
Baldur Karlsson
|
||||
TGA monochrome:
|
||||
Jean-Sebastien Guay
|
||||
misc enhancements:
|
||||
Tim Kelsey
|
||||
bugfixes:
|
||||
github:Chribba
|
||||
*/
|
||||
|
||||
#ifndef INCLUDE_STB_IMAGE_WRITE_H
|
||||
@ -60,9 +84,10 @@ USAGE:
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
|
||||
extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
|
||||
extern int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
@ -76,7 +101,30 @@ extern int stbi_write_tga(char const *filename, int w, int h, int comp, const vo
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#if defined(STBIW_MALLOC) && defined(STBIW_FREE) && defined(STBIW_REALLOC)
|
||||
// ok
|
||||
#elif !defined(STBIW_MALLOC) && !defined(STBIW_FREE) && !defined(STBIW_REALLOC)
|
||||
// ok
|
||||
#else
|
||||
#error "Must define all or none of STBIW_MALLOC, STBIW_FREE, and STBIW_REALLOC."
|
||||
#endif
|
||||
|
||||
#ifndef STBIW_MALLOC
|
||||
#define STBIW_MALLOC(sz) malloc(sz)
|
||||
#define STBIW_REALLOC(p,sz) realloc(p,sz)
|
||||
#define STBIW_FREE(p) free(p)
|
||||
#endif
|
||||
#ifndef STBIW_MEMMOVE
|
||||
#define STBIW_MEMMOVE(a,b,sz) memmove(a,b,sz)
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef STBIW_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBIW_ASSERT(x) assert(x)
|
||||
#endif
|
||||
|
||||
typedef unsigned int stbiw_uint32;
|
||||
typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1];
|
||||
@ -95,7 +143,7 @@ static void writefv(FILE *f, const char *fmt, va_list v)
|
||||
b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24);
|
||||
fwrite(b,4,1,f); break; }
|
||||
default:
|
||||
assert(0);
|
||||
STBIW_ASSERT(0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -108,7 +156,7 @@ static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c)
|
||||
fwrite(arr, 3, 1, f);
|
||||
}
|
||||
|
||||
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad)
|
||||
static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
|
||||
{
|
||||
unsigned char bg[3] = { 255, 0, 255}, px[3];
|
||||
stbiw_uint32 zero = 0;
|
||||
@ -117,7 +165,7 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
|
||||
if (y <= 0)
|
||||
return;
|
||||
|
||||
if (vdir < 0)
|
||||
if (vdir < 0)
|
||||
j_end = -1, j = y-1;
|
||||
else
|
||||
j_end = y, j = 0;
|
||||
@ -128,8 +176,12 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
|
||||
if (write_alpha < 0)
|
||||
fwrite(&d[comp-1], 1, 1, f);
|
||||
switch (comp) {
|
||||
case 1:
|
||||
case 2: fwrite(d, 1, 1, f);
|
||||
case 1: fwrite(d, 1, 1, f);
|
||||
break;
|
||||
case 2: if (expand_mono)
|
||||
write3(f, d[0],d[0],d[0]); // monochrome bmp
|
||||
else
|
||||
fwrite(d, 1, 1, f); // monochrome TGA
|
||||
break;
|
||||
case 4:
|
||||
if (!write_alpha) {
|
||||
@ -151,7 +203,7 @@ static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp,
|
||||
}
|
||||
}
|
||||
|
||||
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...)
|
||||
static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, int expand_mono, void *data, int alpha, int pad, const char *fmt, ...)
|
||||
{
|
||||
FILE *f;
|
||||
if (y < 0 || x < 0) return 0;
|
||||
@ -161,7 +213,7 @@ static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, in
|
||||
va_start(v, fmt);
|
||||
writefv(f, fmt, v);
|
||||
va_end(v);
|
||||
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad);
|
||||
write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad,expand_mono);
|
||||
fclose(f);
|
||||
}
|
||||
return f != NULL;
|
||||
@ -170,7 +222,7 @@ static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, in
|
||||
int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
|
||||
{
|
||||
int pad = (-x*3) & 3;
|
||||
return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad,
|
||||
return outfile(filename,-1,-1,x,y,comp,1,(void *) data,0,pad,
|
||||
"11 4 22 4" "4 44 22 444444",
|
||||
'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header
|
||||
40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header
|
||||
@ -181,10 +233,159 @@ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *dat
|
||||
int has_alpha = (comp == 2 || comp == 4);
|
||||
int colorbytes = has_alpha ? comp-1 : comp;
|
||||
int format = colorbytes < 2 ? 3 : 2; // 3 color channels (RGB/RGBA) = 2, 1 color channel (Y/YA) = 3
|
||||
return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0,
|
||||
return outfile(filename, -1,-1, x, y, comp, 0, (void *) data, has_alpha, 0,
|
||||
"111 221 2222 11", 0,0,format, 0,0,0, 0,0,x,y, (colorbytes+has_alpha)*8, has_alpha*8);
|
||||
}
|
||||
|
||||
// *************************************************************************************************
|
||||
// Radiance RGBE HDR writer
|
||||
// by Baldur Karlsson
|
||||
#define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
|
||||
|
||||
void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
|
||||
{
|
||||
int exponent;
|
||||
float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
|
||||
|
||||
if (maxcomp < 1e-32) {
|
||||
rgbe[0] = rgbe[1] = rgbe[2] = rgbe[3] = 0;
|
||||
} else {
|
||||
float normalize = (float) frexp(maxcomp, &exponent) * 256.0f/maxcomp;
|
||||
|
||||
rgbe[0] = (unsigned char)(linear[0] * normalize);
|
||||
rgbe[1] = (unsigned char)(linear[1] * normalize);
|
||||
rgbe[2] = (unsigned char)(linear[2] * normalize);
|
||||
rgbe[3] = (unsigned char)(exponent + 128);
|
||||
}
|
||||
}
|
||||
|
||||
void stbiw__write_run_data(FILE *f, int length, unsigned char databyte)
|
||||
{
|
||||
unsigned char lengthbyte = (unsigned char) (length+128);
|
||||
STBIW_ASSERT(length+128 <= 255);
|
||||
fwrite(&lengthbyte, 1, 1, f);
|
||||
fwrite(&databyte, 1, 1, f);
|
||||
}
|
||||
|
||||
void stbiw__write_dump_data(FILE *f, int length, unsigned char *data)
|
||||
{
|
||||
unsigned char lengthbyte = (unsigned char )(length & 0xff);
|
||||
STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
|
||||
fwrite(&lengthbyte, 1, 1, f);
|
||||
fwrite(data, length, 1, f);
|
||||
}
|
||||
|
||||
void stbiw__write_hdr_scanline(FILE *f, int width, int comp, unsigned char *scratch, const float *scanline)
|
||||
{
|
||||
unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
|
||||
unsigned char rgbe[4];
|
||||
float linear[3];
|
||||
int x;
|
||||
|
||||
scanlineheader[2] = (width&0xff00)>>8;
|
||||
scanlineheader[3] = (width&0x00ff);
|
||||
|
||||
/* skip RLE for images too small or large */
|
||||
if (width < 8 || width >= 32768) {
|
||||
for (x=0; x < width; x++) {
|
||||
switch (comp) {
|
||||
case 4: /* fallthrough */
|
||||
case 3: linear[2] = scanline[x*comp + 2];
|
||||
linear[1] = scanline[x*comp + 1];
|
||||
linear[0] = scanline[x*comp + 0];
|
||||
break;
|
||||
case 2: /* fallthrough */
|
||||
case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
|
||||
break;
|
||||
}
|
||||
stbiw__linear_to_rgbe(rgbe, linear);
|
||||
fwrite(rgbe, 4, 1, f);
|
||||
}
|
||||
} else {
|
||||
int c,r;
|
||||
/* encode into scratch buffer */
|
||||
for (x=0; x < width; x++) {
|
||||
switch(comp) {
|
||||
case 4: /* fallthrough */
|
||||
case 3: linear[2] = scanline[x*comp + 2];
|
||||
linear[1] = scanline[x*comp + 1];
|
||||
linear[0] = scanline[x*comp + 0];
|
||||
break;
|
||||
case 2: /* fallthrough */
|
||||
case 1: linear[0] = linear[1] = linear[2] = scanline[x*comp + 0];
|
||||
break;
|
||||
}
|
||||
stbiw__linear_to_rgbe(rgbe, linear);
|
||||
scratch[x + width*0] = rgbe[0];
|
||||
scratch[x + width*1] = rgbe[1];
|
||||
scratch[x + width*2] = rgbe[2];
|
||||
scratch[x + width*3] = rgbe[3];
|
||||
}
|
||||
|
||||
fwrite(scanlineheader, 4, 1, f);
|
||||
|
||||
/* RLE each component separately */
|
||||
for (c=0; c < 4; c++) {
|
||||
unsigned char *comp = &scratch[width*c];
|
||||
|
||||
x = 0;
|
||||
while (x < width) {
|
||||
// find first run
|
||||
r = x;
|
||||
while (r+2 < width) {
|
||||
if (comp[r] == comp[r+1] && comp[r] == comp[r+2])
|
||||
break;
|
||||
++r;
|
||||
}
|
||||
if (r+2 >= width)
|
||||
r = width;
|
||||
// dump up to first run
|
||||
while (x < r) {
|
||||
int len = r-x;
|
||||
if (len > 128) len = 128;
|
||||
stbiw__write_dump_data(f, len, &comp[x]);
|
||||
x += len;
|
||||
}
|
||||
// if there's a run, output it
|
||||
if (r+2 < width) { // same test as what we break out of in search loop, so only true if we break'd
|
||||
// find next byte after run
|
||||
while (r < width && comp[r] == comp[x])
|
||||
++r;
|
||||
// output run up to r
|
||||
while (x < r) {
|
||||
int len = r-x;
|
||||
if (len > 127) len = 127;
|
||||
stbiw__write_run_data(f, len, comp[x]);
|
||||
x += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
if (y <= 0 || x <= 0 || data == NULL) return 0;
|
||||
f = fopen(filename, "wb");
|
||||
if (f) {
|
||||
/* Each component is stored separately. Allocate scratch space for full output scanline. */
|
||||
unsigned char *scratch = (unsigned char *) STBIW_MALLOC(x*4);
|
||||
fprintf(f, "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n" );
|
||||
fprintf(f, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n" , y, x);
|
||||
for(i=0; i < y; i++)
|
||||
stbiw__write_hdr_scanline(f, x, comp, scratch, data + comp*i*x);
|
||||
STBIW_FREE(scratch);
|
||||
fclose(f);
|
||||
}
|
||||
return f != NULL;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// PNG
|
||||
|
||||
// stretchy buffer; stbiw__sbpush() == vector<>::push_back() -- stbiw__sbcount() == vector<>::size()
|
||||
#define stbiw__sbraw(a) ((int *) (a) - 2)
|
||||
#define stbiw__sbm(a) stbiw__sbraw(a)[0]
|
||||
@ -196,13 +397,13 @@ int stbi_write_tga(char const *filename, int x, int y, int comp, const void *dat
|
||||
|
||||
#define stbiw__sbpush(a, v) (stbiw__sbmaybegrow(a,1), (a)[stbiw__sbn(a)++] = (v))
|
||||
#define stbiw__sbcount(a) ((a) ? stbiw__sbn(a) : 0)
|
||||
#define stbiw__sbfree(a) ((a) ? free(stbiw__sbraw(a)),0 : 0)
|
||||
#define stbiw__sbfree(a) ((a) ? STBIW_FREE(stbiw__sbraw(a)),0 : 0)
|
||||
|
||||
static void *stbiw__sbgrowf(void **arr, int increment, int itemsize)
|
||||
{
|
||||
int m = *arr ? 2*stbiw__sbm(*arr)+increment : increment+1;
|
||||
void *p = realloc(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
|
||||
assert(p);
|
||||
void *p = STBIW_REALLOC(*arr ? stbiw__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2);
|
||||
STBIW_ASSERT(p);
|
||||
if (p) {
|
||||
if (!*arr) ((int *) p)[1] = 0;
|
||||
*arr = (void *) ((int *) p + 2);
|
||||
@ -287,7 +488,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
||||
|
||||
i=0;
|
||||
while (i < data_len-3) {
|
||||
// hash next 3 bytes of data to be compressed
|
||||
// hash next 3 bytes of data to be compressed
|
||||
int h = stbiw__zhash(data+i)&(stbiw__ZHASH-1), best=3;
|
||||
unsigned char *bestloc = 0;
|
||||
unsigned char **hlist = hash_table[h];
|
||||
@ -300,7 +501,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
||||
}
|
||||
// when hash table entry is too long, delete half the entries
|
||||
if (hash_table[h] && stbiw__sbn(hash_table[h]) == 2*quality) {
|
||||
memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
|
||||
STBIW_MEMMOVE(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality);
|
||||
stbiw__sbn(hash_table[h]) = quality;
|
||||
}
|
||||
stbiw__sbpush(hash_table[h],data+i);
|
||||
@ -323,7 +524,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
||||
|
||||
if (bestloc) {
|
||||
int d = (int) (data+i - bestloc); // distance back
|
||||
assert(d <= 32767 && best <= 258);
|
||||
STBIW_ASSERT(d <= 32767 && best <= 258);
|
||||
for (j=0; best > lengthc[j+1]-1; ++j);
|
||||
stbiw__zlib_huff(j+257);
|
||||
if (lengtheb[j]) stbiw__zlib_add(best - lengthc[j], lengtheb[j]);
|
||||
@ -364,7 +565,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
|
||||
}
|
||||
*out_len = stbiw__sbn(out);
|
||||
// make returned pointer freeable
|
||||
memmove(stbiw__sbraw(out), out, *out_len);
|
||||
STBIW_MEMMOVE(stbiw__sbraw(out), out, *out_len);
|
||||
return (unsigned char *) stbiw__sbraw(out);
|
||||
}
|
||||
|
||||
@ -411,8 +612,8 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
|
||||
if (stride_bytes == 0)
|
||||
stride_bytes = x * n;
|
||||
|
||||
filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0;
|
||||
line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; }
|
||||
filt = (unsigned char *) STBIW_MALLOC((x*n+1) * y); if (!filt) return 0;
|
||||
line_buffer = (signed char *) STBIW_MALLOC(x * n); if (!line_buffer) { STBIW_FREE(filt); return 0; }
|
||||
for (j=0; j < y; ++j) {
|
||||
static int mapping[] = { 0,1,2,3,4 };
|
||||
static int firstmap[] = { 0,1,0,5,6 };
|
||||
@ -451,20 +652,20 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
|
||||
}
|
||||
// when we get here, best contains the filter type, and line_buffer contains the data
|
||||
filt[j*(x*n+1)] = (unsigned char) best;
|
||||
memcpy(filt+j*(x*n+1)+1, line_buffer, x*n);
|
||||
STBIW_MEMMOVE(filt+j*(x*n+1)+1, line_buffer, x*n);
|
||||
}
|
||||
free(line_buffer);
|
||||
STBIW_FREE(line_buffer);
|
||||
zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory
|
||||
free(filt);
|
||||
STBIW_FREE(filt);
|
||||
if (!zlib) return 0;
|
||||
|
||||
// each tag requires 12 bytes of overhead
|
||||
out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12);
|
||||
out = (unsigned char *) STBIW_MALLOC(8 + 12+13 + 12+zlen + 12);
|
||||
if (!out) return 0;
|
||||
*out_len = 8 + 12+13 + 12+zlen + 12;
|
||||
|
||||
o=out;
|
||||
memcpy(o,sig,8); o+= 8;
|
||||
STBIW_MEMMOVE(o,sig,8); o+= 8;
|
||||
stbiw__wp32(o, 13); // header length
|
||||
stbiw__wptag(o, "IHDR");
|
||||
stbiw__wp32(o, x);
|
||||
@ -478,14 +679,16 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
|
||||
|
||||
stbiw__wp32(o, zlen);
|
||||
stbiw__wptag(o, "IDAT");
|
||||
memcpy(o, zlib, zlen); o += zlen; free(zlib);
|
||||
STBIW_MEMMOVE(o, zlib, zlen);
|
||||
o += zlen;
|
||||
STBIW_FREE(zlib);
|
||||
stbiw__wpcrc(&o, zlen);
|
||||
|
||||
stbiw__wp32(o,0);
|
||||
stbiw__wptag(o, "IEND");
|
||||
stbiw__wpcrc(&o,0);
|
||||
|
||||
assert(o == out + *out_len);
|
||||
STBIW_ASSERT(o == out + *out_len);
|
||||
|
||||
return out;
|
||||
}
|
||||
@ -497,16 +700,22 @@ int stbi_write_png(char const *filename, int x, int y, int comp, const void *dat
|
||||
unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
|
||||
if (!png) return 0;
|
||||
f = fopen(filename, "wb");
|
||||
if (!f) { free(png); return 0; }
|
||||
if (!f) { STBIW_FREE(png); return 0; }
|
||||
fwrite(png, 1, len, f);
|
||||
fclose(f);
|
||||
free(png);
|
||||
STBIW_FREE(png);
|
||||
return 1;
|
||||
}
|
||||
#endif // STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
|
||||
/* Revision history
|
||||
|
||||
0.98 (2015-04-08)
|
||||
added STBIW_MALLOC, STBIW_ASSERT etc
|
||||
0.97 (2015-01-18)
|
||||
fixed HDR asserts, rewrote HDR rle logic
|
||||
0.96 (2015-01-17)
|
||||
add HDR output
|
||||
fix monochrome BMP
|
||||
0.95 (2014-08-17)
|
||||
add monochrome TGA output
|
||||
0.94 (2014-05-31)
|
||||
|
560
src/stb_rect_pack.h
Normal file
560
src/stb_rect_pack.h
Normal file
@ -0,0 +1,560 @@
|
||||
// stb_rect_pack.h - v0.06 - public domain - rectangle packing
|
||||
// Sean Barrett 2014
|
||||
//
|
||||
// Useful for e.g. packing rectangular textures into an atlas.
|
||||
// Does not do rotation.
|
||||
//
|
||||
// Not necessarily the awesomest packing method, but better than
|
||||
// the totally naive one in stb_truetype (which is primarily what
|
||||
// this is meant to replace).
|
||||
//
|
||||
// Has only had a few tests run, may have issues.
|
||||
//
|
||||
// More docs to come.
|
||||
//
|
||||
// No memory allocations; uses qsort() and assert() from stdlib.
|
||||
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
|
||||
//
|
||||
// This library currently uses the Skyline Bottom-Left algorithm.
|
||||
//
|
||||
// Please note: better rectangle packers are welcome! Please
|
||||
// implement them to the same API, but with a different init
|
||||
// function.
|
||||
//
|
||||
// Credits
|
||||
//
|
||||
// Library
|
||||
// Sean Barrett
|
||||
// Minor features
|
||||
// Martins Mozeiko
|
||||
// Bugfixes / warning fixes
|
||||
// [your name could be here]
|
||||
//
|
||||
// Version history:
|
||||
//
|
||||
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
|
||||
// 0.05: added STBRP_ASSERT to allow replacing assert
|
||||
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
|
||||
// 0.01: initial release
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// INCLUDE SECTION
|
||||
//
|
||||
|
||||
#ifndef STB_INCLUDE_STB_RECT_PACK_H
|
||||
#define STB_INCLUDE_STB_RECT_PACK_H
|
||||
|
||||
#define STB_RECT_PACK_VERSION 1
|
||||
|
||||
#ifdef STBRP_STATIC
|
||||
#define STBRP_DEF static
|
||||
#else
|
||||
#define STBRP_DEF extern
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct stbrp_context stbrp_context;
|
||||
typedef struct stbrp_node stbrp_node;
|
||||
typedef struct stbrp_rect stbrp_rect;
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
typedef int stbrp_coord;
|
||||
#else
|
||||
typedef unsigned short stbrp_coord;
|
||||
#endif
|
||||
|
||||
STBRP_DEF void stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects);
|
||||
// Assign packed locations to rectangles. The rectangles are of type
|
||||
// 'stbrp_rect' defined below, stored in the array 'rects', and there
|
||||
// are 'num_rects' many of them.
|
||||
//
|
||||
// Rectangles which are successfully packed have the 'was_packed' flag
|
||||
// set to a non-zero value and 'x' and 'y' store the minimum location
|
||||
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
|
||||
// if you imagine y increasing downwards). Rectangles which do not fit
|
||||
// have the 'was_packed' flag set to 0.
|
||||
//
|
||||
// You should not try to access the 'rects' array from another thread
|
||||
// while this function is running, as the function temporarily reorders
|
||||
// the array while it executes.
|
||||
//
|
||||
// To pack into another rectangle, you need to call stbrp_init_target
|
||||
// again. To continue packing into the same rectangle, you can call
|
||||
// this function again. Calling this multiple times with multiple rect
|
||||
// arrays will probably produce worse packing results than calling it
|
||||
// a single time with the full rectangle array, but the option is
|
||||
// available.
|
||||
|
||||
struct stbrp_rect
|
||||
{
|
||||
// reserved for your use:
|
||||
int id;
|
||||
|
||||
// input:
|
||||
stbrp_coord w, h;
|
||||
|
||||
// output:
|
||||
stbrp_coord x, y;
|
||||
int was_packed; // non-zero if valid packing
|
||||
|
||||
}; // 16 bytes, nominally
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes);
|
||||
// Initialize a rectangle packer to:
|
||||
// pack a rectangle that is 'width' by 'height' in dimensions
|
||||
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
|
||||
//
|
||||
// You must call this function every time you start packing into a new target.
|
||||
//
|
||||
// There is no "shutdown" function. The 'nodes' memory must stay valid for
|
||||
// the following stbrp_pack_rects() call (or calls), but can be freed after
|
||||
// the call (or calls) finish.
|
||||
//
|
||||
// Note: to guarantee best results, either:
|
||||
// 1. make sure 'num_nodes' >= 'width'
|
||||
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
|
||||
//
|
||||
// If you don't do either of the above things, widths will be quantized to multiples
|
||||
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
|
||||
//
|
||||
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
|
||||
// may run out of temporary storage and be unable to pack some rectangles.
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem);
|
||||
// Optionally call this function after init but before doing any packing to
|
||||
// change the handling of the out-of-temp-memory scenario, described above.
|
||||
// If you call init again, this will be reset to the default (false).
|
||||
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic);
|
||||
// Optionally select which packing heuristic the library should use. Different
|
||||
// heuristics will produce better/worse results for different data sets.
|
||||
// If you call init again, this will be reset to the default.
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP_HEURISTIC_Skyline_default=0,
|
||||
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
|
||||
STBRP_HEURISTIC_Skyline_BF_sortHeight,
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// the details of the following structures don't matter to you, but they must
|
||||
// be visible so you can handle the memory allocations for them
|
||||
|
||||
struct stbrp_node
|
||||
{
|
||||
stbrp_coord x,y;
|
||||
stbrp_node *next;
|
||||
};
|
||||
|
||||
struct stbrp_context
|
||||
{
|
||||
int width;
|
||||
int height;
|
||||
int align;
|
||||
int init_mode;
|
||||
int heuristic;
|
||||
int num_nodes;
|
||||
stbrp_node *active_head;
|
||||
stbrp_node *free_head;
|
||||
stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2'
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// IMPLEMENTATION SECTION
|
||||
//
|
||||
|
||||
#ifdef STB_RECT_PACK_IMPLEMENTATION
|
||||
#ifndef STBRP_SORT
|
||||
#include <stdlib.h>
|
||||
#define STBRP_SORT qsort
|
||||
#endif
|
||||
|
||||
#ifndef STBRP_ASSERT
|
||||
#include <assert.h>
|
||||
#define STBRP_ASSERT assert
|
||||
#endif
|
||||
|
||||
enum
|
||||
{
|
||||
STBRP__INIT_skyline = 1,
|
||||
};
|
||||
|
||||
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
|
||||
{
|
||||
switch (context->init_mode) {
|
||||
case STBRP__INIT_skyline:
|
||||
STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
|
||||
context->heuristic = heuristic;
|
||||
break;
|
||||
default:
|
||||
STBRP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
|
||||
{
|
||||
if (allow_out_of_mem)
|
||||
// if it's ok to run out of memory, then don't bother aligning them;
|
||||
// this gives better packing, but may fail due to OOM (even though
|
||||
// the rectangles easily fit). @TODO a smarter approach would be to only
|
||||
// quantize once we've hit OOM, then we could get rid of this parameter.
|
||||
context->align = 1;
|
||||
else {
|
||||
// if it's not ok to run out of memory, then quantize the widths
|
||||
// so that num_nodes is always enough nodes.
|
||||
//
|
||||
// I.e. num_nodes * align >= width
|
||||
// align >= width / num_nodes
|
||||
// align = ceil(width/num_nodes)
|
||||
|
||||
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
|
||||
{
|
||||
int i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(width <= 0xffff && height <= 0xffff);
|
||||
#endif
|
||||
|
||||
for (i=0; i < num_nodes-1; ++i)
|
||||
nodes[i].next = &nodes[i+1];
|
||||
nodes[i].next = NULL;
|
||||
context->init_mode = STBRP__INIT_skyline;
|
||||
context->heuristic = STBRP_HEURISTIC_Skyline_default;
|
||||
context->free_head = &nodes[0];
|
||||
context->active_head = &context->extra[0];
|
||||
context->width = width;
|
||||
context->height = height;
|
||||
context->num_nodes = num_nodes;
|
||||
stbrp_setup_allow_out_of_mem(context, 0);
|
||||
|
||||
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
|
||||
context->extra[0].x = 0;
|
||||
context->extra[0].y = 0;
|
||||
context->extra[0].next = &context->extra[1];
|
||||
context->extra[1].x = (stbrp_coord) width;
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
context->extra[1].y = (1<<30);
|
||||
#else
|
||||
context->extra[1].y = 65535;
|
||||
#endif
|
||||
context->extra[1].next = NULL;
|
||||
}
|
||||
|
||||
// find minimum y position if it starts at x1
|
||||
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
|
||||
{
|
||||
stbrp_node *node = first;
|
||||
int x1 = x0 + width;
|
||||
int min_y, visited_width, waste_area;
|
||||
STBRP_ASSERT(first->x <= x0);
|
||||
|
||||
#if 0
|
||||
// skip in case we're past the node
|
||||
while (node->next->x <= x0)
|
||||
++node;
|
||||
#else
|
||||
STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency
|
||||
#endif
|
||||
|
||||
STBRP_ASSERT(node->x <= x0);
|
||||
|
||||
min_y = 0;
|
||||
waste_area = 0;
|
||||
visited_width = 0;
|
||||
while (node->x < x1) {
|
||||
if (node->y > min_y) {
|
||||
// raise min_y higher.
|
||||
// we've accounted for all waste up to min_y,
|
||||
// but we'll now add more waste for everything we've visted
|
||||
waste_area += visited_width * (node->y - min_y);
|
||||
min_y = node->y;
|
||||
// the first time through, visited_width might be reduced
|
||||
if (node->x < x0)
|
||||
visited_width += node->next->x - x0;
|
||||
else
|
||||
visited_width += node->next->x - node->x;
|
||||
} else {
|
||||
// add waste area
|
||||
int under_width = node->next->x - node->x;
|
||||
if (under_width + visited_width > width)
|
||||
under_width = width - visited_width;
|
||||
waste_area += under_width * (min_y - node->y);
|
||||
visited_width += under_width;
|
||||
}
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
*pwaste = waste_area;
|
||||
return min_y;
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x,y;
|
||||
stbrp_node **prev_link;
|
||||
} stbrp__findresult;
|
||||
|
||||
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
|
||||
{
|
||||
int best_waste = (1<<30), best_x, best_y = (1 << 30);
|
||||
stbrp__findresult fr;
|
||||
stbrp_node **prev, *node, *tail, **best = NULL;
|
||||
|
||||
// align to multiple of c->align
|
||||
width = (width + c->align - 1);
|
||||
width -= width % c->align;
|
||||
STBRP_ASSERT(width % c->align == 0);
|
||||
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
while (node->x + width <= c->width) {
|
||||
int y,waste;
|
||||
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
|
||||
// bottom left
|
||||
if (y < best_y) {
|
||||
best_y = y;
|
||||
best = prev;
|
||||
}
|
||||
} else {
|
||||
// best-fit
|
||||
if (y + height <= c->height) {
|
||||
// can only use it if it first vertically
|
||||
if (y < best_y || (y == best_y && waste < best_waste)) {
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
|
||||
best_x = (best == NULL) ? 0 : (*best)->x;
|
||||
|
||||
// if doing best-fit (BF), we also have to try aligning right edge to each node position
|
||||
//
|
||||
// e.g, if fitting
|
||||
//
|
||||
// ____________________
|
||||
// |____________________|
|
||||
//
|
||||
// into
|
||||
//
|
||||
// | |
|
||||
// | ____________|
|
||||
// |____________|
|
||||
//
|
||||
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
|
||||
//
|
||||
// This makes BF take about 2x the time
|
||||
|
||||
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
|
||||
tail = c->active_head;
|
||||
node = c->active_head;
|
||||
prev = &c->active_head;
|
||||
// find first node that's admissible
|
||||
while (tail->x < width)
|
||||
tail = tail->next;
|
||||
while (tail) {
|
||||
int xpos = tail->x - width;
|
||||
int y,waste;
|
||||
STBRP_ASSERT(xpos >= 0);
|
||||
// find the left position that matches this
|
||||
while (node->next->x <= xpos) {
|
||||
prev = &node->next;
|
||||
node = node->next;
|
||||
}
|
||||
STBRP_ASSERT(node->next->x > xpos && node->x <= xpos);
|
||||
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
|
||||
if (y + height < c->height) {
|
||||
if (y <= best_y) {
|
||||
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
|
||||
best_x = xpos;
|
||||
STBRP_ASSERT(y <= best_y);
|
||||
best_y = y;
|
||||
best_waste = waste;
|
||||
best = prev;
|
||||
}
|
||||
}
|
||||
}
|
||||
tail = tail->next;
|
||||
}
|
||||
}
|
||||
|
||||
fr.prev_link = best;
|
||||
fr.x = best_x;
|
||||
fr.y = best_y;
|
||||
return fr;
|
||||
}
|
||||
|
||||
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
|
||||
{
|
||||
// find best position according to heuristic
|
||||
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
|
||||
stbrp_node *node, *cur;
|
||||
|
||||
// bail if:
|
||||
// 1. it failed
|
||||
// 2. the best node doesn't fit (we don't always check this)
|
||||
// 3. we're out of memory
|
||||
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
|
||||
res.prev_link = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
// on success, create new node
|
||||
node = context->free_head;
|
||||
node->x = (stbrp_coord) res.x;
|
||||
node->y = (stbrp_coord) (res.y + height);
|
||||
|
||||
context->free_head = node->next;
|
||||
|
||||
// insert the new node into the right starting point, and
|
||||
// let 'cur' point to the remaining nodes needing to be
|
||||
// stiched back in
|
||||
|
||||
cur = *res.prev_link;
|
||||
if (cur->x < res.x) {
|
||||
// preserve the existing one, so start testing with the next one
|
||||
stbrp_node *next = cur->next;
|
||||
cur->next = node;
|
||||
cur = next;
|
||||
} else {
|
||||
*res.prev_link = node;
|
||||
}
|
||||
|
||||
// from here, traverse cur and free the nodes, until we get to one
|
||||
// that shouldn't be freed
|
||||
while (cur->next && cur->next->x <= res.x + width) {
|
||||
stbrp_node *next = cur->next;
|
||||
// move the current node to the free list
|
||||
cur->next = context->free_head;
|
||||
context->free_head = cur;
|
||||
cur = next;
|
||||
}
|
||||
|
||||
// stitch the list back in
|
||||
node->next = cur;
|
||||
|
||||
if (cur->x < res.x + width)
|
||||
cur->x = (stbrp_coord) (res.x + width);
|
||||
|
||||
#ifdef _DEBUG
|
||||
cur = context->active_head;
|
||||
while (cur->x < context->width) {
|
||||
STBRP_ASSERT(cur->x < cur->next->x);
|
||||
cur = cur->next;
|
||||
}
|
||||
STBRP_ASSERT(cur->next == NULL);
|
||||
|
||||
{
|
||||
stbrp_node *L1 = NULL, *L2 = NULL;
|
||||
int count=0;
|
||||
cur = context->active_head;
|
||||
while (cur) {
|
||||
L1 = cur;
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
cur = context->free_head;
|
||||
while (cur) {
|
||||
L2 = cur;
|
||||
cur = cur->next;
|
||||
++count;
|
||||
}
|
||||
STBRP_ASSERT(count == context->num_nodes+2);
|
||||
}
|
||||
#endif
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int rect_height_compare(const void *a, const void *b)
|
||||
{
|
||||
stbrp_rect *p = (stbrp_rect *) a;
|
||||
stbrp_rect *q = (stbrp_rect *) b;
|
||||
if (p->h > q->h)
|
||||
return -1;
|
||||
if (p->h < q->h)
|
||||
return 1;
|
||||
return (p->w > q->w) ? -1 : (p->w < q->w);
|
||||
}
|
||||
|
||||
static int rect_width_compare(const void *a, const void *b)
|
||||
{
|
||||
stbrp_rect *p = (stbrp_rect *) a;
|
||||
stbrp_rect *q = (stbrp_rect *) b;
|
||||
if (p->w > q->w)
|
||||
return -1;
|
||||
if (p->w < q->w)
|
||||
return 1;
|
||||
return (p->h > q->h) ? -1 : (p->h < q->h);
|
||||
}
|
||||
|
||||
static int rect_original_order(const void *a, const void *b)
|
||||
{
|
||||
stbrp_rect *p = (stbrp_rect *) a;
|
||||
stbrp_rect *q = (stbrp_rect *) b;
|
||||
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
|
||||
}
|
||||
|
||||
#ifdef STBRP_LARGE_RECTS
|
||||
#define STBRP__MAXVAL 0xffffffff
|
||||
#else
|
||||
#define STBRP__MAXVAL 0xffff
|
||||
#endif
|
||||
|
||||
STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
|
||||
{
|
||||
int i;
|
||||
|
||||
// we use the 'was_packed' field internally to allow sorting/unsorting
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
rects[i].was_packed = i;
|
||||
#ifndef STBRP_LARGE_RECTS
|
||||
STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff);
|
||||
#endif
|
||||
}
|
||||
|
||||
// sort according to heuristic
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
|
||||
|
||||
for (i=0; i < num_rects; ++i) {
|
||||
stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
|
||||
if (fr.prev_link) {
|
||||
rects[i].x = (stbrp_coord) fr.x;
|
||||
rects[i].y = (stbrp_coord) fr.y;
|
||||
} else {
|
||||
rects[i].x = rects[i].y = STBRP__MAXVAL;
|
||||
}
|
||||
}
|
||||
|
||||
// unsort
|
||||
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
|
||||
|
||||
// set was_packed flags
|
||||
for (i=0; i < num_rects; ++i)
|
||||
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
|
||||
}
|
||||
#endif
|
2632
src/stb_truetype.h
Normal file
2632
src/stb_truetype.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,3 @@
|
||||
|
||||
#include "stb_vorbis.h"
|
||||
|
||||
#ifndef STB_VORBIS_HEADER_ONLY
|
||||
@ -180,7 +179,7 @@
|
||||
#define NULL 0
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#if !defined(_MSC_VER) && !(defined(__MINGW32__) && defined(__forceinline))
|
||||
#if __GNUC__
|
||||
#define __forceinline inline
|
||||
#else
|
||||
@ -3562,7 +3561,7 @@ static int start_decoder(vorb *f)
|
||||
g->sorted_order[j] = (uint8) p[j].y;
|
||||
// precompute the neighbors
|
||||
for (j=2; j < g->values; ++j) {
|
||||
int low = 0,hi = 0;
|
||||
int low,hi;
|
||||
neighbors(g->Xlist, j, &low,&hi);
|
||||
g->neighbors[j][0] = low;
|
||||
g->neighbors[j][1] = hi;
|
||||
@ -5024,6 +5023,7 @@ int stb_vorbis_get_samples_float(stb_vorbis *f, int channels, float **buffer, in
|
||||
#endif // STB_VORBIS_NO_PULLDATA_API
|
||||
|
||||
/* Version history
|
||||
1.05 - 2015/04/19 - don't define __forceinline if it's redundant
|
||||
1.04 - 2014/08/27 - fix missing const-correct case in API
|
||||
1.03 - 2014/08/07 - Warning fixes
|
||||
1.02 - 2014/07/09 - Declare qsort compare function _cdecl on windows
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Ogg Vorbis audio decoder - v1.04 - public domain
|
||||
// Ogg Vorbis audio decoder - v1.05 - public domain
|
||||
// http://nothings.org/stb_vorbis/
|
||||
//
|
||||
// Written by Sean Barrett in 2007, last updated in 2014
|
||||
@ -24,12 +24,13 @@
|
||||
// Casey Muratori John Bolton Gargaj
|
||||
// Laurent Gomila Marc LeBlanc Ronny Chevalier
|
||||
// Bernhard Wodo Evan Balster "alxprd"@github
|
||||
// Tom Beaumont Ingo Leitgeb
|
||||
// Tom Beaumont Ingo Leitgeb Nicolas Guillemot
|
||||
// (If you reported a bug but do not appear in this list, it is because
|
||||
// someone else reported the bug before you. There were too many of you to
|
||||
// list them all because I was lax about updating for a long time, sorry.)
|
||||
//
|
||||
// Partial history:
|
||||
// 1.05 - 2015/04/19 - don't define __forceinline if it's redundant
|
||||
// 1.04 - 2014/08/27 - fix missing const-correct case in API
|
||||
// 1.03 - 2014/08/07 - warning fixes
|
||||
// 1.02 - 2014/07/09 - declare qsort comparison as explicitly _cdecl in Windows
|
||||
@ -58,6 +59,12 @@
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
// NOTE: Added to work with raylib on Android
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
#include "utils.h" // Android fopen function map
|
||||
#endif
|
||||
|
||||
// RaySan: Added for Linux
|
||||
#ifdef __linux
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
263
src/text.c
263
src/text.c
@ -30,15 +30,20 @@
|
||||
#include <stdarg.h> // Used for functions with variable number of parameters (FormatText())
|
||||
#include <stdio.h> // Standard input / output lib
|
||||
|
||||
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
|
||||
#include "utils.h" // Required for function GetExtendion()
|
||||
#include "utils.h" // Required for function GetExtension()
|
||||
|
||||
// Following libs are used on LoadTTF()
|
||||
#define STB_TRUETYPE_IMPLEMENTATION
|
||||
#define STB_RECT_PACK_IMPLEMENTATION
|
||||
#include "stb_rect_pack.h"
|
||||
#include "stb_truetype.h"
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Defines and Macros
|
||||
//----------------------------------------------------------------------------------
|
||||
#define FONT_FIRST_CHAR 32
|
||||
#define MAX_FONTCHARS 128
|
||||
#define MAX_FORMATTEXT_LENGTH 50
|
||||
#define MAX_FORMATTEXT_LENGTH 64
|
||||
|
||||
#define BIT_CHECK(a,b) ((a) & (1<<(b)))
|
||||
|
||||
@ -64,6 +69,7 @@ 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 SpriteFont LoadRBMF(const char *fileName); // Load a rBMF font file (raylib BitMap Font)
|
||||
static SpriteFont LoadTTF(const char *fileName, int fontSize); // Generate a sprite font image from TTF data (font size required)
|
||||
|
||||
extern void LoadDefaultFont(void);
|
||||
extern void UnloadDefaultFont(void);
|
||||
@ -73,16 +79,15 @@ extern void UnloadDefaultFont(void);
|
||||
//----------------------------------------------------------------------------------
|
||||
extern void LoadDefaultFont(void)
|
||||
{
|
||||
defaultFont.numChars = 96; // We know our default font has 94 chars
|
||||
// NOTE: Using UTF8 encoding table for Unicode U+0000..U+00FF Basic Latin + Latin-1 Supplement
|
||||
// http://www.utf8-chartable.de/unicode-utf8-table.pl
|
||||
|
||||
Image image;
|
||||
image.width = 128; // We know our default font image is 128 pixels width
|
||||
image.height = 64; // We know our default font image is 64 pixels height
|
||||
defaultFont.numChars = 224; // Number of chars included in our default font
|
||||
|
||||
// Default font is directly defined here (data generated from a sprite font image)
|
||||
// This way, we reconstruct SpriteFont without creating large global variables
|
||||
// This data is automatically allocated to Stack and automatically deallocated at the end of this function
|
||||
int defaultFontData[256] = {
|
||||
int defaultFontData[512] = {
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200020, 0x0001b000, 0x00000000, 0x00000000, 0x8ef92520, 0x00020a00, 0x7dbe8000, 0x1f7df45f,
|
||||
0x4a2bf2a0, 0x0852091e, 0x41224000, 0x10041450, 0x2e292020, 0x08220812, 0x41222000, 0x10041450, 0x10f92020, 0x3efa084c, 0x7d22103c, 0x107df7de,
|
||||
0xe8a12020, 0x08220832, 0x05220800, 0x10450410, 0xa4a3f000, 0x08520832, 0x05220400, 0x10450410, 0xe2f92020, 0x0002085e, 0x7d3e0281, 0x107df41f,
|
||||
@ -98,42 +103,78 @@ extern void LoadDefaultFont(void)
|
||||
0x04000404, 0x4100203c, 0x00000000, 0x00000800, 0xf7df7df0, 0x514bef85, 0xbefbefbe, 0x04513bef, 0x14414500, 0x494a2885, 0xa28a28aa, 0x04510820,
|
||||
0xf44145f0, 0x474a289d, 0xa28a28aa, 0x04510be0, 0x14414510, 0x494a2884, 0xa28a28aa, 0x02910a00, 0xf7df7df0, 0xd14a2f85, 0xbefbe8aa, 0x011f7be0,
|
||||
0x00000000, 0x00400804, 0x20080000, 0x00000000, 0x00000000, 0x00600f84, 0x20080000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x00000000,
|
||||
0x24fa28a2, 0x00000901, 0x00000000, 0x00000000, 0x2242252a, 0x00000952, 0x00000000, 0x00000000, 0x2422222a, 0x00000929, 0x00000000, 0x00000000,
|
||||
0x2412252a, 0x00000901, 0x00000000, 0x00000000, 0x24fbe8be, 0x00000901, 0x00000000, 0x00000000, 0xac020000, 0x00000f01, 0x00000000, 0x00000000,
|
||||
0x0003e000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0xac000000, 0x00000f01, 0x00000000, 0x00000000, 0x24000000, 0x00000901, 0x00000000, 0x06000000, 0x24000000, 0x00000901, 0x00000000, 0x09108000,
|
||||
0x24fa28a2, 0x00000901, 0x00000000, 0x013e0000, 0x2242252a, 0x00000952, 0x00000000, 0x038a8000, 0x2422222a, 0x00000929, 0x00000000, 0x010a8000,
|
||||
0x2412252a, 0x00000901, 0x00000000, 0x010a8000, 0x24fbe8be, 0x00000901, 0x00000000, 0x0ebe8000, 0xac020000, 0x00000f01, 0x00000000, 0x00048000,
|
||||
0x0003e000, 0x00000000, 0x00000000, 0x00008000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000038, 0x8443b80e, 0x00203a03,
|
||||
0x02bea080, 0xf0000020, 0xc452208a, 0x04202b02, 0xf8029122, 0x07f0003b, 0xe44b388e, 0x02203a02, 0x081e8a1c, 0x0411e92a, 0xf4420be0, 0x01248202,
|
||||
0xe8140414, 0x05d104ba, 0xe7c3b880, 0x00893a0a, 0x283c0e1c, 0x04500902, 0xc4400080, 0x00448002, 0xe8208422, 0x04500002, 0x80400000, 0x05200002,
|
||||
0x083e8e00, 0x04100002, 0x804003e0, 0x07000042, 0xf8008400, 0x07f00003, 0x80400000, 0x04000022, 0x00000000, 0x00000000, 0x80400000, 0x04000002,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00800702, 0x1848a0c2, 0x84010000, 0x02920921, 0x01042642, 0x00005121, 0x42023f7f, 0x00291002,
|
||||
0xefc01422, 0x7efdfbf7, 0xefdfa109, 0x03bbbbf7, 0x28440f12, 0x42850a14, 0x20408109, 0x01111010, 0x28440408, 0x42850a14, 0x2040817f, 0x01111010,
|
||||
0xefc78204, 0x7efdfbf7, 0xe7cf8109, 0x011111f3, 0x2850a932, 0x42850a14, 0x2040a109, 0x01111010, 0x2850b840, 0x42850a14, 0xefdfbf79, 0x03bbbbf7,
|
||||
0x001fa020, 0x00000000, 0x00001000, 0x00000000, 0x00002070, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x08022800, 0x00012283, 0x02430802, 0x01010001, 0x8404147c, 0x20000144, 0x80048404, 0x00823f08, 0xdfbf4284, 0x7e03f7ef, 0x142850a1, 0x0000210a,
|
||||
0x50a14684, 0x528a1428, 0x142850a1, 0x03efa17a, 0x50a14a9e, 0x52521428, 0x142850a1, 0x02081f4a, 0x50a15284, 0x4a221428, 0xf42850a1, 0x03efa14b,
|
||||
0x50a16284, 0x4a521428, 0x042850a1, 0x0228a17a, 0xdfbf427c, 0x7e8bf7ef, 0xf7efdfbf, 0x03efbd0b, 0x00000000, 0x04000000, 0x00000000, 0x00000008,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00200508, 0x00840400, 0x11458122, 0x00014210,
|
||||
0x00514294, 0x51420800, 0x20a22a94, 0x0050a508, 0x00200000, 0x00000000, 0x00050000, 0x08000000, 0xfefbefbe, 0xfbefbefb, 0xfbeb9114, 0x00fbefbe,
|
||||
0x20820820, 0x8a28a20a, 0x8a289114, 0x3e8a28a2, 0xfefbefbe, 0xfbefbe0b, 0x8a289114, 0x008a28a2, 0x228a28a2, 0x08208208, 0x8a289114, 0x088a28a2,
|
||||
0xfefbefbe, 0xfbefbefb, 0xfa2f9114, 0x00fbefbe, 0x00000000, 0x00000040, 0x00000000, 0x00000000, 0x00000000, 0x00000020, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00210100, 0x00000004, 0x00000000, 0x00000000, 0x14508200, 0x00001402, 0x00000000, 0x00000000,
|
||||
0x00000010, 0x00000020, 0x00000000, 0x00000000, 0xa28a28be, 0x00002228, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000,
|
||||
0xa28a28aa, 0x000022a8, 0x00000000, 0x00000000, 0xa28a28aa, 0x000022e8, 0x00000000, 0x00000000, 0xbefbefbe, 0x00003e2f, 0x00000000, 0x00000000,
|
||||
0x00000004, 0x00002028, 0x00000000, 0x00000000, 0x80000000, 0x00003e0f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
|
||||
0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
|
||||
int charsHeight = 10;
|
||||
int charsDivisor = 1; // Every char is separated from the consecutive by a 1 pixel divisor, horizontally and vertically
|
||||
|
||||
int charsWidth[96] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6,
|
||||
7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
|
||||
2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4 };
|
||||
int charsWidth[224] = { 3, 1, 4, 6, 5, 7, 6, 2, 3, 3, 5, 5, 2, 4, 1, 7, 5, 2, 5, 5, 5, 5, 5, 5, 5, 5, 1, 1, 3, 4, 3, 6,
|
||||
7, 6, 6, 6, 6, 6, 6, 6, 6, 3, 5, 6, 5, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 6, 6, 6, 2, 7, 2, 3, 5,
|
||||
2, 5, 5, 5, 5, 5, 4, 5, 5, 1, 2, 5, 2, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 3, 1, 3, 4, 4,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 5, 5, 5, 7, 1, 5, 3, 7, 3, 5, 4, 1, 7, 4, 3, 5, 3, 3, 2, 5, 6, 1, 2, 2, 3, 5, 6, 6, 6, 6,
|
||||
6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 3, 3, 3, 3, 7, 6, 6, 6, 6, 6, 6, 5, 6, 6, 6, 6, 6, 6, 4, 6,
|
||||
5, 5, 5, 5, 5, 5, 9, 5, 5, 5, 5, 5, 2, 2, 3, 3, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5 };
|
||||
|
||||
// Re-construct image from defaultFontData and generate OpenGL texture
|
||||
//----------------------------------------------------------------------
|
||||
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
|
||||
int imWidth = 128;
|
||||
int imHeight = 128;
|
||||
|
||||
Color *imagePixels = (Color *)malloc(imWidth*imHeight*sizeof(Color));
|
||||
|
||||
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
|
||||
for (int i = 0; i < imWidth*imHeight; i++) imagePixels[i] = BLANK; // Initialize array
|
||||
|
||||
int counter = 0; // Font data elements counter
|
||||
|
||||
// Fill imgData with defaultFontData (convert from bit to pixel!)
|
||||
for (int i = 0; i < image.width * image.height; i += 32)
|
||||
for (int i = 0; i < imWidth*imHeight; i += 32)
|
||||
{
|
||||
for (int j = 31; j >= 0; j--)
|
||||
{
|
||||
if (BIT_CHECK(defaultFontData[counter], j)) image.pixels[i+j] = WHITE;
|
||||
if (BIT_CHECK(defaultFontData[counter], j)) imagePixels[i+j] = WHITE;
|
||||
}
|
||||
|
||||
counter++;
|
||||
|
||||
if (counter > 256) counter = 0; // Security check...
|
||||
if (counter > 512) counter = 0; // Security check...
|
||||
}
|
||||
|
||||
//FILE *myimage = fopen("default_font.raw", "wb");
|
||||
//fwrite(image.pixels, 1, 128*128*4, myimage);
|
||||
//fclose(myimage);
|
||||
|
||||
Image image = LoadImageFromData(imagePixels, imWidth, imHeight, UNCOMPRESSED_GRAY_ALPHA);
|
||||
|
||||
free(imagePixels);
|
||||
|
||||
defaultFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
UnloadImage(image);
|
||||
|
||||
@ -172,7 +213,7 @@ extern void LoadDefaultFont(void)
|
||||
|
||||
extern void UnloadDefaultFont(void)
|
||||
{
|
||||
rlDeleteTextures(defaultFont.texture.id);
|
||||
UnloadTexture(defaultFont.texture);
|
||||
free(defaultFont.charSet);
|
||||
}
|
||||
|
||||
@ -189,18 +230,21 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
|
||||
// Check file extension
|
||||
if (strcmp(GetExtension(fileName),"rbmf") == 0) spriteFont = LoadRBMF(fileName);
|
||||
else if (strcmp(GetExtension(fileName),"ttf") == 0) spriteFont = LoadTTF(fileName, 20);
|
||||
else
|
||||
{
|
||||
Image image = LoadImage(fileName);
|
||||
|
||||
// At this point we have a pixel array with all the data...
|
||||
// At this point we have a data array...
|
||||
|
||||
Color *imagePixels = GetPixelData(image);
|
||||
|
||||
#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);
|
||||
int numChars = ParseImageData(imagePixels, image.width, image.height, &spriteFont.charSet);
|
||||
|
||||
TraceLog(INFO, "[%s] SpriteFont data parsed correctly", fileName);
|
||||
TraceLog(INFO, "[%s] SpriteFont num chars detected: %i", fileName, numChars);
|
||||
@ -208,7 +252,8 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
spriteFont.numChars = numChars;
|
||||
|
||||
spriteFont.texture = LoadTextureFromImage(image, false); // Convert loaded image to OpenGL texture
|
||||
|
||||
|
||||
free(imagePixels);
|
||||
UnloadImage(image);
|
||||
}
|
||||
|
||||
@ -218,7 +263,7 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
||||
// Unload SpriteFont from GPU memory
|
||||
void UnloadSpriteFont(SpriteFont spriteFont)
|
||||
{
|
||||
rlDeleteTextures(spriteFont.texture.id);
|
||||
UnloadTexture(spriteFont.texture);
|
||||
free(spriteFont.charSet);
|
||||
}
|
||||
|
||||
@ -244,41 +289,37 @@ void DrawText(const char *text, int posX, int posY, int fontSize, Color color)
|
||||
void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, int fontSize, int spacing, Color tint)
|
||||
{
|
||||
int length = strlen(text);
|
||||
int positionX = (int)position.x;
|
||||
int offsetX = 0;
|
||||
float scaleFactor;
|
||||
unsigned char letter;
|
||||
|
||||
Character c;
|
||||
|
||||
if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
||||
else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
||||
//if (fontSize <= spriteFont.charSet[0].h) scaleFactor = 1.0f;
|
||||
//else scaleFactor = (float)fontSize / spriteFont.charSet[0].h;
|
||||
|
||||
scaleFactor = (float)fontSize/spriteFont.charSet[0].h;
|
||||
|
||||
rlEnableTexture(spriteFont.texture.id);
|
||||
|
||||
rlBegin(RL_QUADS);
|
||||
for(int i = 0; i < length; i++)
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if ((unsigned char)text[i] == 0xc2)
|
||||
{
|
||||
c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
|
||||
|
||||
rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||
rlNormal3f(0.0f, 0.0f, 1.0f); // Normal Pointing Towards Viewer
|
||||
|
||||
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
|
||||
rlVertex2f(positionX, position.y);
|
||||
|
||||
rlTexCoord2f((float)c.x / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
|
||||
rlVertex2f(positionX, position.y + (c.h) * scaleFactor);
|
||||
|
||||
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)(c.y + c.h) / spriteFont.texture.height);
|
||||
rlVertex2f(positionX + (c.w) * scaleFactor, position.y + (c.h) * scaleFactor);
|
||||
|
||||
rlTexCoord2f((float)(c.x + c.w) / spriteFont.texture.width, (float)c.y / spriteFont.texture.height);
|
||||
rlVertex2f(positionX + (c.w) * scaleFactor, position.y);
|
||||
|
||||
positionX += ((spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR].w) * scaleFactor + spacing);
|
||||
letter = (unsigned char)text[i + 1];
|
||||
c = spriteFont.charSet[letter - FONT_FIRST_CHAR];
|
||||
i++;
|
||||
}
|
||||
rlEnd();
|
||||
else if ((unsigned char)text[i] == 0xc3)
|
||||
{
|
||||
letter = (unsigned char)text[i + 1];
|
||||
c = spriteFont.charSet[letter - FONT_FIRST_CHAR + 64];
|
||||
i++;
|
||||
}
|
||||
else c = spriteFont.charSet[(int)text[i] - FONT_FIRST_CHAR];
|
||||
|
||||
rlDisableTexture();
|
||||
DrawTexturePro(spriteFont.texture, (Rectangle){ c.x, c.y, c.w, c.h }, (Rectangle){ position.x + offsetX, position.y, c.w*scaleFactor, c.h*scaleFactor} , (Vector2){ 0, 0 }, 0.0f, tint);
|
||||
|
||||
offsetX += (c.w*scaleFactor + spacing);
|
||||
}
|
||||
}
|
||||
|
||||
// Formatting of text with variables to 'embed'
|
||||
@ -465,7 +506,6 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
} rbmfInfoHeader;
|
||||
|
||||
SpriteFont spriteFont;
|
||||
Image image;
|
||||
|
||||
rbmfInfoHeader rbmfHeader;
|
||||
unsigned int *rbmfFileData = NULL;
|
||||
@ -487,9 +527,6 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
|
||||
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));
|
||||
@ -502,22 +539,26 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
|
||||
// Re-construct image from rbmfFileData
|
||||
//-----------------------------------------
|
||||
image.pixels = (Color *)malloc(image.width * image.height * sizeof(Color));
|
||||
Color *imagePixels = (Color *)malloc(rbmfHeader.imgWidth*rbmfHeader.imgHeight*sizeof(Color));
|
||||
|
||||
for (int i = 0; i < image.width * image.height; i++) image.pixels[i] = BLANK; // Initialize array
|
||||
for (int i = 0; i < rbmfHeader.imgWidth*rbmfHeader.imgHeight; i++) imagePixels[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)
|
||||
for (int i = 0; i < rbmfHeader.imgWidth*rbmfHeader.imgHeight; i += 32)
|
||||
{
|
||||
for (int j = 31; j >= 0; j--)
|
||||
{
|
||||
if (BIT_CHECK(rbmfFileData[counter], j)) image.pixels[i+j] = WHITE;
|
||||
if (BIT_CHECK(rbmfFileData[counter], j)) imagePixels[i+j] = WHITE;
|
||||
}
|
||||
|
||||
counter++;
|
||||
}
|
||||
|
||||
Image image = LoadImageFromData(imagePixels, rbmfHeader.imgWidth, rbmfHeader.imgHeight, UNCOMPRESSED_GRAY_ALPHA);
|
||||
|
||||
free(imagePixels);
|
||||
|
||||
TraceLog(INFO, "[%s] Image reconstructed correctly, now converting it to texture", fileName);
|
||||
|
||||
@ -557,7 +598,7 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
|
||||
TraceLog(INFO, "[%s] rBMF file loaded correctly as SpriteFont", fileName);
|
||||
}
|
||||
|
||||
|
||||
fclose(rbmfFile);
|
||||
|
||||
free(rbmfFileData); // Now we can free loaded data from RAM memory
|
||||
@ -567,11 +608,105 @@ static SpriteFont LoadRBMF(const char *fileName)
|
||||
}
|
||||
|
||||
// Generate a sprite font from TTF data (font size required)
|
||||
static SpriteFont GenerateFromTTF(const char *fileName, int fontSize)
|
||||
static SpriteFont LoadTTF(const char *fileName, int fontSize)
|
||||
{
|
||||
SpriteFont font;
|
||||
|
||||
// TODO: Load TTF and generate bitmap font and chars data
|
||||
Image image;
|
||||
image.width = 512;
|
||||
image.height = 512;
|
||||
//image.pixels = (Color *)malloc(image.width*image.height*sizeof(Color));
|
||||
|
||||
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
|
||||
|
||||
// TODO: Load TTF and generate bitmap font and chars data -> REVIEW!
|
||||
|
||||
stbtt_packedchar chardata[128]; // Num characters: 128 (?) -> REVIEW!
|
||||
|
||||
unsigned char *tempBitmap = (unsigned char *)malloc(image.width*image.height*sizeof(unsigned char)); // One channel bitmap returned!
|
||||
|
||||
// REFERENCE
|
||||
/*
|
||||
typedef struct
|
||||
{
|
||||
unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap
|
||||
float xoff,yoff,xadvance;
|
||||
float xoff2,yoff2;
|
||||
} stbtt_packedchar;
|
||||
*/
|
||||
|
||||
stbtt_pack_context pc;
|
||||
|
||||
FILE *ttfFile = fopen(fileName, "rb");
|
||||
|
||||
fread(ttfBuffer, 1, 1<<25, ttfFile);
|
||||
|
||||
stbtt_PackBegin(&pc, tempBitmap, image.width, image.height, 0, 1, NULL);
|
||||
|
||||
//stbtt_PackSetOversampling(&pc, 1, 1);
|
||||
//stbtt_PackFontRange(&pc, ttfBuffer, 0, fontSize, 32, 95, chardata[0]+32);
|
||||
stbtt_PackSetOversampling(&pc, 2, 2); // Better results
|
||||
stbtt_PackFontRange(&pc, ttfBuffer, 0, fontSize, 32, 95, chardata + 32);
|
||||
//stbtt_PackSetOversampling(&pc, 3, 1);
|
||||
//stbtt_PackFontRange(&pc, ttfBuffer, 0, fontSize, 32, 95, chardata[2]+32);
|
||||
|
||||
stbtt_PackEnd(&pc);
|
||||
|
||||
free(ttfBuffer);
|
||||
|
||||
// Now we have image data in tempBitmap and chardata filled...
|
||||
/*
|
||||
for (int i = 0; i < 512*512; i++)
|
||||
{
|
||||
image.pixels[i].r = tempBitmap[i];
|
||||
image.pixels[i].g = tempBitmap[i];
|
||||
image.pixels[i].b = tempBitmap[i];
|
||||
image.pixels[i].a = 255;
|
||||
}
|
||||
*/
|
||||
free(tempBitmap);
|
||||
|
||||
// REFERENCE EXAMPLE
|
||||
/*
|
||||
//To draw, provide *text, posX, posY
|
||||
//stbtt_aligned_quad letter;
|
||||
//stbtt_GetPackedQuad(chardata[0], BITMAP_W, BITMAP_H, *text++, &posX, &posY, &letter, font ? 0 : integer_align);
|
||||
|
||||
void print(float x, float y, int fontNum, char *text)
|
||||
{
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glBindTexture(GL_TEXTURE_2D, font_tex);
|
||||
glBegin(GL_QUADS);
|
||||
while (*text) {
|
||||
stbtt_aligned_quad q;
|
||||
stbtt_GetPackedQuad(chardata[fontNum], BITMAP_W, BITMAP_H, *text++, &x, &y, &q, fontNum ? 0 : integer_align);
|
||||
drawBoxTC(q.x0,q.y0,q.x1,q.y1, q.s0,q.t0,q.s1,q.t1);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
print(100,160, 0, "This is a test");
|
||||
*/
|
||||
font.numChars = 95;
|
||||
font.charSet = (Character *)malloc(font.numChars*sizeof(Character));
|
||||
font.texture = LoadTextureFromImage(image, false);
|
||||
|
||||
//stbtt_aligned_quad letter;
|
||||
//int x = 0, y = 0;
|
||||
|
||||
for (int i = 0; i < font.numChars; i++)
|
||||
{
|
||||
font.charSet[i].value = i + 32;
|
||||
|
||||
//stbtt_GetPackedQuad(chardata[0], 512, 512, i, &x, &y, &letter, 0);
|
||||
|
||||
font.charSet[i].x = chardata[i + 32].x0;
|
||||
font.charSet[i].y = chardata[i + 32].y0;
|
||||
font.charSet[i].w = chardata[i + 32].x1 - chardata[i + 32].x0;
|
||||
font.charSet[i].h = chardata[i + 32].y1 - chardata[i + 32].y0;
|
||||
}
|
||||
|
||||
UnloadImage(image);
|
||||
|
||||
return font;
|
||||
}
|
1066
src/textures.c
1066
src/textures.c
File diff suppressed because it is too large
Load Diff
16
src/utils.c
16
src/utils.c
@ -79,7 +79,7 @@ unsigned char *DecompressData(const unsigned char *data, unsigned long compSize,
|
||||
pUncomp = (mz_uint8 *)malloc((size_t)uncompSize);
|
||||
|
||||
// Check correct memory allocation
|
||||
if (!pUncomp)
|
||||
if (pUncomp == NULL)
|
||||
{
|
||||
TraceLog(WARNING, "Out of memory while decompressing data");
|
||||
}
|
||||
@ -235,18 +235,18 @@ void TraceLog(int msgType, const char *text, ...)
|
||||
}
|
||||
|
||||
// Initialize asset manager from android app
|
||||
void InitAssetManager(AAssetManager *manager)
|
||||
void InitAssetManager(AAssetManager *manager)
|
||||
{
|
||||
assetManager = manager;
|
||||
}
|
||||
|
||||
// Replacement for fopen
|
||||
FILE *android_fopen(const char *fileName, const char *mode)
|
||||
FILE *android_fopen(const char *fileName, const char *mode)
|
||||
{
|
||||
if (mode[0] == 'w') return NULL;
|
||||
|
||||
AAsset *asset = AAssetManager_open(assetManager, fileName, 0);
|
||||
|
||||
|
||||
if(!asset) return NULL;
|
||||
|
||||
return funopen(asset, android_read, android_write, android_seek, android_close);
|
||||
@ -292,24 +292,24 @@ int GetNextPOT(int num)
|
||||
// Module specific Functions Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
#if defined(PLATFORM_ANDROID)
|
||||
static int android_read(void *cookie, char *buf, int size)
|
||||
static int android_read(void *cookie, char *buf, int size)
|
||||
{
|
||||
return AAsset_read((AAsset *)cookie, buf, size);
|
||||
}
|
||||
|
||||
static int android_write(void *cookie, const char *buf, int size)
|
||||
static int android_write(void *cookie, const char *buf, int size)
|
||||
{
|
||||
TraceLog(ERROR, "Can't provide write access to the APK");
|
||||
|
||||
return EACCES;
|
||||
}
|
||||
|
||||
static fpos_t android_seek(void *cookie, fpos_t offset, int whence)
|
||||
static fpos_t android_seek(void *cookie, fpos_t offset, int whence)
|
||||
{
|
||||
return AAsset_seek((AAsset *)cookie, offset, whence);
|
||||
}
|
||||
|
||||
static int android_close(void *cookie)
|
||||
static int android_close(void *cookie)
|
||||
{
|
||||
AAsset_close((AAsset *)cookie);
|
||||
return 0;
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# raylib - Advance Game
|
||||
#
|
||||
# makefile to compile advance game
|
||||
# makefile to compile advance game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,49 +23,133 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
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
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -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./screens -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I./screens -I../../src
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
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)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
screens/screen_logo.o \
|
||||
@ -80,7 +164,7 @@ default: advance_game
|
||||
|
||||
# compile template - advance_game
|
||||
advance_game: advance_game.c $(SCREENS)
|
||||
$(CC) -o $@ $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screen LOGO
|
||||
screens/screen_logo.o: screens/screen_logo.c
|
||||
@ -104,11 +188,24 @@ screens/screen_ending.o: screens/screen_ending.c
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
rm -f screens/*.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
del screens/*.o *.exe
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,7 +2,7 @@
|
||||
#
|
||||
# raylib - Basic Game
|
||||
#
|
||||
# makefile to compile basic game
|
||||
# makefile to compile basic game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,18 +23,60 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
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
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -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
|
||||
@ -42,45 +84,100 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
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)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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 basic_game
|
||||
default: basic_game
|
||||
|
||||
# compile template - basic_game
|
||||
basic_game: basic_game.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# raylib - Basic Test
|
||||
#
|
||||
# makefile to compile basic test
|
||||
# makefile to compile basic test for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,18 +23,60 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
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
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -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
|
||||
@ -42,45 +84,100 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
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)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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 basic_test
|
||||
default: basic_test
|
||||
|
||||
# compile template - basic_test
|
||||
basic_test: basic_test.c
|
||||
$(CC) -o $@ $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#
|
||||
# raylib - Simple Game
|
||||
#
|
||||
# makefile to compile simple game
|
||||
# makefile to compile simple game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,12 +23,44 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler flags:
|
||||
# -O2 defines optimization level
|
||||
@ -39,6 +71,12 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
else
|
||||
CFLAGS = -O2 -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
|
||||
@ -46,37 +84,79 @@ ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
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)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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 simple_game
|
||||
default: simple_game
|
||||
|
||||
# compile template - simple_game
|
||||
simple_game: simple_game.c screens.o
|
||||
$(CC) -o $@ $< screens.o $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< screens.o $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screens
|
||||
screens.o: screens.c
|
||||
@ -84,11 +164,24 @@ screens.o: screens.c
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
Binary file not shown.
@ -2,7 +2,7 @@
|
||||
#
|
||||
# raylib - Standard Game
|
||||
#
|
||||
# makefile to compile standard game
|
||||
# makefile to compile standard game for desktop platforms, Raspberry Pi and HTML5 (emscripten)
|
||||
#
|
||||
# Copyright (c) 2014 Ramon Santamaria (Ray San - raysan@raysanweb.com)
|
||||
#
|
||||
@ -23,49 +23,133 @@
|
||||
#
|
||||
#**************************************************************************************************
|
||||
|
||||
# define raylib platform if not defined (by default, compile for RPI)
|
||||
# Other possible platform: PLATFORM_DESKTOP
|
||||
PLATFORM ?= PLATFORM_RPI
|
||||
# define raylib platform to compile for
|
||||
# possible platforms: PLATFORM_DESKTOP PLATFORM_RPI PLATFORM_WEB
|
||||
# WARNING: To compile to HTML5, code must be redesigned to use emscripten.h and emscripten_set_main_loop()
|
||||
PLATFORM ?= PLATFORM_DESKTOP
|
||||
|
||||
# determine PLATFORM_OS in case PLATFORM_DESKTOP selected
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
# No uname.exe on MinGW!, but OS=Windows_NT on Windows! ifeq ($(UNAME),Msys) -> Windows
|
||||
ifeq ($(OS),Windows_NT)
|
||||
PLATFORM_OS=WINDOWS
|
||||
LIBPATH=win32
|
||||
else
|
||||
UNAMEOS:=$(shell uname)
|
||||
ifeq ($(UNAMEOS),Linux)
|
||||
PLATFORM_OS=LINUX
|
||||
LIBPATH=linux
|
||||
else
|
||||
ifeq ($(UNAMEOS),Darwin)
|
||||
PLATFORM_OS=OSX
|
||||
LIBPATH=osx
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# define compiler: gcc for C program, define as g++ for C++
|
||||
CC = gcc
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
# define emscripten compiler
|
||||
CC = emcc
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# define llvm compiler for mac
|
||||
CC = clang
|
||||
else
|
||||
# define default gcc compiler
|
||||
CC = gcc
|
||||
endif
|
||||
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
|
||||
CFLAGS = -O2 -Wall -std=c99
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
CFLAGS = -O2 -Wall -std=gnu99 -fgnu89-inline
|
||||
else
|
||||
CFLAGS = -O2 -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./screens -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
INCLUDES = -I. -I../../src -I/opt/vc/include -I/opt/vc/include/interface/vcos/pthreads
|
||||
else
|
||||
INCLUDES = -I. -I./screens -I../../src
|
||||
INCLUDES = -I. -I../../src
|
||||
# external libraries headers
|
||||
# GLFW3
|
||||
INCLUDES += -I../../external/glfw3/include
|
||||
# GLEW
|
||||
INCLUDES += -I../../external/glew/include
|
||||
# OpenAL Soft
|
||||
INCLUDES += -I../../external/openal_soft/include
|
||||
endif
|
||||
|
||||
# define library paths containing required libs
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
LFLAGS = -L. -L../../src -L/opt/vc/lib
|
||||
else
|
||||
LFLAGS = -L. -L../../src
|
||||
# external libraries to link with
|
||||
# GLFW3
|
||||
LFLAGS += -L../../external/glfw3/lib/$(LIBPATH)
|
||||
ifneq ($(PLATFORM_OS),OSX)
|
||||
# OpenAL Soft
|
||||
LFLAGS += -L../../external/openal_soft/lib/$(LIBPATH)
|
||||
# GLEW
|
||||
LFLAGS += -L../../external/glew/lib/$(LIBPATH)
|
||||
endif
|
||||
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_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
# libraries for Debian GNU/Linux desktop compiling
|
||||
# requires the following packages:
|
||||
# libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw3 -lGLEW -lGL -lopenal -lX11 -lXrandr -lXinerama -lXi -lXxf86vm -lXcursor -lm -pthread
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
# libraries for OS X 10.9 desktop compiling
|
||||
# requires the following packages:
|
||||
# libglfw3-dev libopenal-dev libglew-dev libegl1-mesa-dev
|
||||
LIBS = -lraylib -lglfw -framework OpenGL -framework OpenAl -framework Cocoa
|
||||
else
|
||||
# libraries for Windows desktop compiling
|
||||
# NOTE: GLFW3 and OpenAL Soft libraries should be installed
|
||||
LIBS = -lraylib -lglfw3 -lglew32 -lopengl32 -lopenal32 -lgdi32
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
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)
|
||||
ifeq ($(PLATFORM_OS),WINDOWS)
|
||||
# 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
|
||||
|
||||
# define all screen object files required
|
||||
SCREENS = \
|
||||
screens/screen_logo.o \
|
||||
@ -80,7 +164,7 @@ default: standard_game
|
||||
|
||||
# compile template - standard_game
|
||||
standard_game: standard_game.c $(SCREENS)
|
||||
$(CC) -o $@ $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
$(CC) -o $@$(EXT) $< $(SCREENS) $(CFLAGS) $(INCLUDES) $(LFLAGS) $(LIBS) -D$(PLATFORM) $(WINFLAGS)
|
||||
|
||||
# compile screen LOGO
|
||||
screens/screen_logo.o: screens/screen_logo.c
|
||||
@ -104,11 +188,24 @@ screens/screen_ending.o: screens/screen_ending.c
|
||||
|
||||
# clean everything
|
||||
clean:
|
||||
ifeq ($(PLATFORM),PLATFORM_DESKTOP)
|
||||
ifeq ($(PLATFORM_OS),OSX)
|
||||
find . -type f -perm +ugo+x -delete
|
||||
rm -f *.o
|
||||
else
|
||||
ifeq ($(PLATFORM_OS),LINUX)
|
||||
find -type f -executable | xargs file -i | grep -E 'x-object|x-archive|x-sharedlib|x-executable' | rev | cut -d ':' -f 2- | rev | xargs rm -f
|
||||
else
|
||||
del *.o *.exe
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_RPI)
|
||||
rm -f screens/*.o
|
||||
# find . -executable -delete
|
||||
else
|
||||
del screens/*.o *.exe
|
||||
find . -type f -executable -delete
|
||||
rm -f *.o
|
||||
endif
|
||||
ifeq ($(PLATFORM),PLATFORM_WEB)
|
||||
del *.o *.html *.js
|
||||
endif
|
||||
@echo Cleaning done
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user