This commit is contained in:
Saggi Mizrahi 2016-12-22 01:28:53 +00:00 committed by GitHub
commit ac05e039b1
28 changed files with 226 additions and 552 deletions

14
.gitignore vendored
View File

@ -51,6 +51,17 @@ ipch/
*.exe *.exe
!tools/rREM/rrem.exe !tools/rREM/rrem.exe
# Ignore all examples files
examples/*
# Unignore all examples dirs
!examples/*/
# Unignore all examples files with extension
!examples/*.c
!examples/*.lua
!examples/*.png
# Unignore examples Makefile
!examples/Makefile
# Ignore files build by xcode # Ignore files build by xcode
*.mode*v* *.mode*v*
*.pbxuser *.pbxuser
@ -68,9 +79,6 @@ DerivedData/
src/libraylib.a src/libraylib.a
src/libraylib.bc src/libraylib.bc
# oculus example
!examples/oculus_glfw_sample/
# external libraries DLLs # external libraries DLLs
!src/external/glfw3/lib/win32/glfw3.dll !src/external/glfw3/lib/win32/glfw3.dll
!src/external/openal_soft/lib/win32/OpenAL32.dll !src/external/openal_soft/lib/win32/OpenAL32.dll

View File

@ -11,7 +11,7 @@ NOTE:
It includes some interesting new features and is a stepping stone towards raylib future. It includes some interesting new features and is a stepping stone towards raylib future.
HUGE changes: HUGE changes:
[rlua] LUA BINDING: Complete raylib LUA binding, ALL raylib functions ported to LUA plus the +60 code examples. [rlua] Lua BINDING: Complete raylib Lua binding, ALL raylib functions ported to Lua plus the +60 code examples.
[audio] COMPLETE REDESIGN: Improved music support and also raw audio data processing and playing, +20 new functions added. [audio] COMPLETE REDESIGN: Improved music support and also raw audio data processing and playing, +20 new functions added.
[physac] COMPLETE REWRITE: Improved performance, functionality and simplified usage, moved to own repository and added multiple examples! [physac] COMPLETE REWRITE: Improved performance, functionality and simplified usage, moved to own repository and added multiple examples!

View File

@ -158,7 +158,7 @@ notes on raylib 1.6
On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features: On November 2016, only 4 months after raylib 1.5, arrives raylib 1.6. This new version represents another big review of the library and includes some interesting additions. This version conmmemorates raylib 3rd anniversary (raylib 1.0 was published on November 2013) and it is a stepping stone for raylib future. raylib roadmap has been reviewed and redefined to focus on its primary objective: create a simple and easy-to-use library to learn videogames programming. Some of the new features:
Complete raylib LUA binding. All raylib functions plus the +60 code examples have been ported to LUA, now LUA users can enjoy coding videogames in LUA while using all the internal power of raylib. This addition also open the doors to LUA scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to LUA scripts while keep using raylib functionality. Complete raylib Lua binding. All raylib functions plus the +60 code examples have been ported to Lua, now Lua users can enjoy coding videogames in Lua while using all the internal power of raylib. This addition also open the doors to Lua scripting support for a future raylib-based engine, being able to move game logic (Init, Update, Draw, De-Init) to Lua scripts while keep using raylib functionality.
Completely redesigned audio module. Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. FLAC file format support has also been added. In the same line, OpenAL Soft backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more! Completely redesigned audio module. Based on the new direction taken in raylib 1.5, it has been further improved and more functionality added (+20 new functions) to allow raw audio processing and streaming. FLAC file format support has also been added. In the same line, OpenAL Soft backend is now provided as a static library in Windows to allow static linking and get ride of OpenAL32.dll. Now raylib Windows games are completey self-contained, no external libraries required any more!
@ -273,6 +273,9 @@ contributing (in some way or another) to make raylib project better. Huge thanks
- [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game. - [Emanuele Petriglia](https://github.com/LelixSuper) for working on multiple GNU/Linux improvements and developing [TicTacToe](https://github.com/LelixSuper/TicTacToe) raylib game.
- [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system. - [Joshua Reisenauer](https://github.com/kd7tck) for adding audio modules support (XM, MOD) and reviewing audio system.
- Marcelo Paez (paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo! - Marcelo Paez (paezao) for his help on OSX to solve High DPI display issue. Thanks Marcelo!
- [Ghassan Al-Mashareqa](https://github.com/ghassanpl) for his amazing contribution with raylib Lua module, I just work over his code to implement [rlua](https://github.com/raysan5/raylib/blob/master/src/rlua.h)
- [Teodor Stoenescu](https://github.com/teodor-stoenescu) for his improvements on OBJ object loading.
Please, if I forget someone in this list, excuse me and write me an email to remind me to add you!
[raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San" [raysan5]: mailto:raysan5@gmail.com "Ramon Santamaria - Ray San"

View File

@ -17,7 +17,7 @@ raylib 1.x
raylib 1.6 raylib 1.6
[DONE] LUA scripting support (raylib lua wrapper) [DONE] Lua scripting support (raylib Lua wrapper)
[DONE] Redesigned audio module [DONE] Redesigned audio module
raylib 1.5 raylib 1.5

View File

@ -112,7 +112,7 @@ int main()
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
BeginDrawing(); BeginDrawing();
ClearBackground(WHITE); ClearBackground(RAYWHITE);
for (int i = MAX_CIRCLES - 1; i >= 0; i--) for (int i = MAX_CIRCLES - 1; i >= 0; i--)
{ {

View File

@ -24,10 +24,52 @@
********************************************************************************************/ ********************************************************************************************/
#include <stdio.h> #include <stdio.h>
#if defined(_WIN32)
#include <conio.h> // Windows only, no stardard library #include <conio.h> // Windows only, no stardard library
#endif
#include "audio.h" #include "audio.h"
#if defined(__linux)
#include <stdio.h>
#include <termios.h>
#include <unistd.h>
#include <fcntl.h>
static int kbhit(void)
{
struct termios oldt, newt;
int ch;
int oldf;
tcgetattr(STDIN_FILENO, &oldt);
newt = oldt;
newt.c_lflag &= ~(ICANON | ECHO);
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
ch = getchar();
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
fcntl(STDIN_FILENO, F_SETFL, oldf);
if(ch != EOF)
{
ungetc(ch, stdin);
return 1;
}
return 0;
}
static char getch()
{
return getchar();
}
#endif
#define KEY_ESCAPE 27 #define KEY_ESCAPE 27
int main() int main()
@ -78,4 +120,4 @@ int main()
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
return 0; return 0;
} }

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "..\src\physac.h" #include "../src/physac.h"
int main() int main()
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "..\src\physac.h" #include "../src/physac.h"
int main() int main()
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "..\src\physac.h" #include "../src/physac.h"
#define VELOCITY 0.5f #define VELOCITY 0.5f

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "..\src\physac.h" #include "../src/physac.h"
int main() int main()
{ {

View File

@ -12,7 +12,7 @@
#include "raylib.h" #include "raylib.h"
#define PHYSAC_IMPLEMENTATION #define PHYSAC_IMPLEMENTATION
#include "..\src\physac.h" #include "../src/physac.h"
int main() int main()
{ {

View File

@ -144,7 +144,7 @@ int main(void)
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateOculusTracking(); UpdateOculusTracking(&camera);
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

View File

@ -1,29 +0,0 @@
========================================================================
STATIC LIBRARY : raylib Project Overview
========================================================================
AppWizard has created this raylib library project for you.
No source files were created as part of your project.
raylib.vcxproj
This is the main project file for VC++ projects generated using an Application Wizard.
It contains information about the version of Visual C++ that generated the file, and
information about the platforms, configurations, and project features selected with the
Application Wizard.
raylib.vcxproj.filters
This is the filters file for VC++ projects generated using an Application Wizard.
It contains information about the association between the files in your project
and the filters. This association is used in the IDE to show grouping of files with
similar extensions under a specific node (for e.g. ".cpp" files are associated with the
"Source Files" filter).
/////////////////////////////////////////////////////////////////////////////
Other notes:
AppWizard uses "TODO:" comments to indicate parts of the source code you
should add to or customize.
/////////////////////////////////////////////////////////////////////////////

View File

@ -52,8 +52,7 @@
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end() #include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
#else #else
#include "raylib.h" #include "raylib.h"
#include "utils.h" // Required for: DecompressData() #include "utils.h" // Required for: fopen() Android mapping, TraceLog()
// NOTE: Includes Android fopen() function map
#endif #endif
#include "AL/al.h" // OpenAL basic header #include "AL/al.h" // OpenAL basic header
@ -324,117 +323,6 @@ Sound LoadSoundFromWave(Wave wave)
return sound; return sound;
} }
// Load sound to memory from rRES file (raylib Resource)
// TODO: Maybe rresName could be directly a char array with all the data?
Sound LoadSoundFromRES(const char *rresName, int resId)
{
Sound sound = { 0 };
#if defined(AUDIO_STANDALONE)
TraceLog(WARNING, "Sound loading from rRES resource file not supported on standalone mode");
#else
bool found = false;
char id[4]; // rRES file identifier
unsigned char version; // rRES file version and subversion
char useless; // rRES header reserved data
short numRes;
ResInfoHeader infoHeader;
FILE *rresFile = fopen(rresName, "rb");
if (rresFile == NULL) TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
else
{
// Read rres file (basic file check - id)
fread(&id[0], sizeof(char), 1, rresFile);
fread(&id[1], sizeof(char), 1, rresFile);
fread(&id[2], sizeof(char), 1, rresFile);
fread(&id[3], sizeof(char), 1, rresFile);
fread(&version, sizeof(char), 1, rresFile);
fread(&useless, sizeof(char), 1, rresFile);
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
}
else
{
// Read number of resources embedded
fread(&numRes, sizeof(short), 1, rresFile);
for (int i = 0; i < numRes; i++)
{
fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile);
if (infoHeader.id == resId)
{
found = true;
// Check data is of valid SOUND type
if (infoHeader.type == 1) // SOUND data type
{
// TODO: Check data compression type
// NOTE: We suppose compression type 2 (DEFLATE - default)
// Reading SOUND parameters
Wave wave;
short sampleRate, bps;
char channels, reserved;
fread(&sampleRate, sizeof(short), 1, rresFile); // Sample rate (frequency)
fread(&bps, sizeof(short), 1, rresFile); // Bits per sample
fread(&channels, 1, 1, rresFile); // Channels (1 - mono, 2 - stereo)
fread(&reserved, 1, 1, rresFile); // <reserved>
wave.sampleRate = sampleRate;
wave.sampleSize = bps;
wave.channels = (short)channels;
unsigned char *data = malloc(infoHeader.size);
fread(data, infoHeader.size, 1, rresFile);
wave.data = DecompressData(data, infoHeader.size, infoHeader.srcSize);
free(data);
sound = LoadSoundFromWave(wave);
// Sound is loaded, we can unload wave data
UnloadWave(wave);
}
else TraceLog(WARNING, "[%s] Required resource do not seem to be a valid SOUND resource", rresName);
}
else
{
// Depending on type, skip the right amount of parameters
switch (infoHeader.type)
{
case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters
case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters
case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review)
case 3: break; // TEXT: No parameters
case 4: break; // RAW: No parameters
default: break;
}
// Jump DATA to read next infoHeader
fseek(rresFile, infoHeader.size, SEEK_CUR);
}
}
}
fclose(rresFile);
}
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
#endif
return sound;
}
// Unload Wave data // Unload Wave data
void UnloadWave(Wave wave) void UnloadWave(Wave wave)
{ {
@ -454,7 +342,7 @@ void UnloadSound(Sound sound)
// Update sound buffer with new data // Update sound buffer with new data
// NOTE: data must match sound.format // NOTE: data must match sound.format
void UpdateSound(Sound sound, void *data, int numSamples) void UpdateSound(Sound sound, const void *data, int numSamples)
{ {
ALint sampleRate, sampleSize, channels; ALint sampleRate, sampleSize, channels;
alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate);
@ -604,7 +492,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
// Copy a wave to a new wave // Copy a wave to a new wave
Wave WaveCopy(Wave wave) Wave WaveCopy(Wave wave)
{ {
Wave newWave; Wave newWave = { 0 };
if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char)); if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char));
else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short)); else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short));
@ -822,8 +710,8 @@ void UpdateMusicStream(Music music)
if (processed > 0) if (processed > 0)
{ {
bool active = true; bool active = true;
short pcm[AUDIO_BUFFER_SIZE]; short pcm[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack)
float pcmf[AUDIO_BUFFER_SIZE]; float pcmf[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack)
int numBuffersToProcess = processed; int numBuffersToProcess = processed;
int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, int numSamples = 0; // Total size of data steamed in L+R samples for xm floats,
@ -952,7 +840,7 @@ float GetMusicTimePlayed(Music music)
float secondsPlayed = 0.0f; float secondsPlayed = 0.0f;
unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; unsigned int samplesPlayed = music->totalSamples - music->samplesLeft;
secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); secondsPlayed = (float)(samplesPlayed/(music->stream.sampleRate*music->stream.channels));
return secondsPlayed; return secondsPlayed;
} }
@ -1004,17 +892,17 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
{ {
if (stream.sampleSize == 8) if (stream.sampleSize == 8)
{ {
unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack)
alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate); alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate);
} }
else if (stream.sampleSize == 16) else if (stream.sampleSize == 16)
{ {
short pcm[AUDIO_BUFFER_SIZE] = { 0 }; short pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack)
alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate); alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate);
} }
else if (stream.sampleSize == 32) else if (stream.sampleSize == 32)
{ {
float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; // TODO: Dynamic allocation (uses more than 16KB of stack)
alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate); alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate);
} }
} }
@ -1195,11 +1083,13 @@ static Wave LoadWAV(const char *fileName)
// Read in the sound data into the soundData variable // Read in the sound data into the soundData variable
fread(wave.data, waveData.subChunkSize, 1, wavFile); fread(wave.data, waveData.subChunkSize, 1, wavFile);
// Now we set the variables that we need later // Store wave parameters
wave.sampleCount = waveData.subChunkSize;
wave.sampleRate = waveFormat.sampleRate; wave.sampleRate = waveFormat.sampleRate;
wave.sampleSize = waveFormat.bitsPerSample; wave.sampleSize = waveFormat.bitsPerSample;
wave.channels = waveFormat.numChannels; wave.channels = waveFormat.numChannels;
// NOTE: subChunkSize comes in bytes, we need to translate it to number of samples
wave.sampleCount = waveData.subChunkSize/(waveFormat.bitsPerSample/8);
TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels); TraceLog(INFO, "[%s] WAV file loaded successfully (SampleRate: %i, SampleSize: %i, Channels: %i)", fileName, wave.sampleRate, wave.sampleSize, wave.channels);
} }

View File

@ -115,7 +115,7 @@ Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, in
Sound LoadSound(const char *fileName); // Load sound to memory Sound LoadSound(const char *fileName); // Load sound to memory
Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data void UpdateSound(Sound sound, const void *data, int numSamples); // Update sound buffer with new data
void UnloadWave(Wave wave); // Unload wave data void UnloadWave(Wave wave); // Unload wave data
void UnloadSound(Sound sound); // Unload sound void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound void PlaySound(Sound sound); // Play a sound

View File

@ -223,15 +223,15 @@ void SetCameraMode(Camera camera, int mode)
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
Vector2 distance = { 0.0f, 0.0f }; Vector2 distance = { 0.0f, 0.0f };
distance.x = sqrt(dx*dx + dz*dz); distance.x = sqrtf(dx*dx + dz*dz);
distance.y = sqrt(dx*dx + dy*dy); distance.y = sqrtf(dx*dx + dy*dy);
// Camera angle calculation // Camera angle calculation
cameraAngle.x = asin(fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) cameraAngle.x = asinf(fabsf(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
cameraAngle.y = -asin(fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) cameraAngle.y = -asinf(fabsf(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
// NOTE: Just testing what cameraAngle means // NOTE: Just testing what cameraAngle means
//cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW) //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
@ -285,10 +285,10 @@ void UpdateCamera(Camera *camera)
{ {
HideCursor(); HideCursor();
if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y }); if (mousePosition.x < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 }); else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
else if (mousePosition.x > (screenWidth - screenHeight/3)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y }); else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
else if (mousePosition.y > (screenHeight - screenHeight/3)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 }); else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 });
else else
{ {
mousePositionDelta.x = mousePosition.x - previousMousePosition.x; mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
@ -321,6 +321,7 @@ void UpdateCamera(Camera *camera)
if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
} }
// Camera looking down // Camera looking down
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
@ -341,6 +342,7 @@ void UpdateCamera(Camera *camera)
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
} }
// Camera looking up // Camera looking up
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
@ -385,9 +387,9 @@ void UpdateCamera(Camera *camera)
else else
{ {
// Camera panning // Camera panning
camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
} }
} }
@ -404,19 +406,19 @@ void UpdateCamera(Camera *camera)
case CAMERA_FIRST_PERSON: case CAMERA_FIRST_PERSON:
case CAMERA_THIRD_PERSON: case CAMERA_THIRD_PERSON:
{ {
camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] - camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
sin(cameraAngle.x)*direction[MOVE_FRONT] - sinf(cameraAngle.x)*direction[MOVE_FRONT] -
cos(cameraAngle.x)*direction[MOVE_LEFT] + cosf(cameraAngle.x)*direction[MOVE_LEFT] +
cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] - camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
sin(cameraAngle.y)*direction[MOVE_BACK] + sinf(cameraAngle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] - camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
cos(cameraAngle.x)*direction[MOVE_FRONT] + cosf(cameraAngle.x)*direction[MOVE_FRONT] +
sin(cameraAngle.x)*direction[MOVE_LEFT] - sinf(cameraAngle.x)*direction[MOVE_LEFT] -
sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
bool isMoving = false; // Required for swinging bool isMoving = false; // Required for swinging
@ -439,9 +441,9 @@ void UpdateCamera(Camera *camera)
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
// Camera is always looking at player // Camera is always looking at player
camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cosf(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x);
camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y; camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y;
camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sinf(cameraAngle.x);
} }
else // CAMERA_FIRST_PERSON else // CAMERA_FIRST_PERSON
{ {
@ -450,18 +452,18 @@ void UpdateCamera(Camera *camera)
else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD; else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
// Camera is always looking at player // Camera is always looking at player
camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
if (isMoving) swingCounter++; if (isMoving) swingCounter++;
// Camera position update // Camera position update
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position' // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
camera->position.y = playerEyesPosition - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
} }
} break; } break;
default: break; default: break;
@ -473,10 +475,10 @@ void UpdateCamera(Camera *camera)
(cameraMode == CAMERA_THIRD_PERSON)) (cameraMode == CAMERA_THIRD_PERSON))
{ {
// TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target... // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
} }
} }

View File

@ -42,13 +42,14 @@
* *
**********************************************************************************************/ **********************************************************************************************/
#include "raylib.h" // raylib main header #include "raylib.h"
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3+ or ES2
#include "utils.h" // Includes Android fopen map, InitAssetManager(), TraceLog() #include "utils.h" // Required for: fopen() Android mapping, TraceLog()
#define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation) #define RAYMATH_IMPLEMENTATION // Use raymath as a header-only library (includes implementation)
#define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint) #define RAYMATH_EXTERN_INLINE // Compile raymath functions as static inline (remember, it's a compiler hint)
#include "raymath.h" // Required for Vector3 and Matrix functions #include "raymath.h" // Required for: Vector3 and Matrix functions
#define GESTURES_IMPLEMENTATION #define GESTURES_IMPLEMENTATION
#include "gestures.h" // Gestures detection functionality #include "gestures.h" // Gestures detection functionality
@ -264,6 +265,7 @@ static void SwapBuffers(void); // Copy back buffer to f
static void LogoAnimation(void); // Plays raylib logo appearing animation static void LogoAnimation(void); // Plays raylib logo appearing animation
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable static void TakeScreenshot(void); // Takes a screenshot and saves it in the same folder as executable
static void SetupViewport(void);
#endif #endif
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
@ -744,8 +746,7 @@ void EndTextureMode(void)
rlDisableRenderTexture(); // Disable render target rlDisableRenderTexture(); // Disable render target
// Set viewport to default framebuffer size (screen size) // Set viewport to default framebuffer size (screen size)
// TODO: consider possible viewport offsets SetupViewport();
rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
rlLoadIdentity(); // Reset current matrix (PROJECTION) rlLoadIdentity(); // Reset current matrix (PROJECTION)
@ -779,7 +780,7 @@ float GetFrameTime(void)
// As we are operate quite a lot with frameTime, // As we are operate quite a lot with frameTime,
// it could be no stable, so we round it before passing it around // it could be no stable, so we round it before passing it around
// NOTE: There are still problems with high framerates (>500fps) // NOTE: There are still problems with high framerates (>500fps)
double roundedFrameTime = round(frameTime*10000)/10000.0; double roundedFrameTime = round(frameTime*10000)/10000.0;
return (float)roundedFrameTime; // Time in seconds to run a frame return (float)roundedFrameTime; // Time in seconds to run a frame
} }
@ -1089,7 +1090,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
QuaternionTransform(&worldPos, matProj); QuaternionTransform(&worldPos, matProj);
// Calculate normalized device coordinates (inverted y) // Calculate normalized device coordinates (inverted y)
Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.z }; Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w };
// Calculate 2d screen position vector // Calculate 2d screen position vector
Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() }; Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() };
@ -1776,19 +1777,8 @@ static void InitGraphicsDevice(int width, int height)
// NOTE: screenWidth and screenHeight not used, just stored as globals // NOTE: screenWidth and screenHeight not used, just stored as globals
rlglInit(screenWidth, screenHeight); rlglInit(screenWidth, screenHeight);
#ifdef __APPLE__ // Setup default viewport
// Get framebuffer size of current window SetupViewport();
// NOTE: Required to handle HighDPI display correctly on OSX because framebuffer
// is automatically reasized to adapt to new DPI.
// When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback()
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY);
#else
// Initialize screen viewport (area of the screen that you will actually draw to)
// NOTE: Viewport must be recalculated if screen is resized
rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY);
#endif
// Initialize internal projection and modelview matrices // Initialize internal projection and modelview matrices
// NOTE: Default to orthographic projection mode with top-left corner at (0,0) // NOTE: Default to orthographic projection mode with top-left corner at (0,0)
@ -1805,6 +1795,23 @@ static void InitGraphicsDevice(int width, int height)
#endif #endif
} }
static void SetupViewport(void)
{
#ifdef __APPLE__
// Get framebuffer size of current window
// NOTE: Required to handle HighDPI display correctly on OSX because framebuffer
// is automatically reasized to adapt to new DPI.
// When OS does that, it can be detected using GLFW3 callback: glfwSetFramebufferSizeCallback()
int fbWidth, fbHeight;
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
rlViewport(renderOffsetX/2, renderOffsetY/2, fbWidth - renderOffsetX, fbHeight - renderOffsetY);
#else
// Initialize screen viewport (area of the screen that you will actually draw to)
// NOTE: Viewport must be recalculated if screen is resized
rlViewport(renderOffsetX/2, renderOffsetY/2, renderWidth - renderOffsetX, renderHeight - renderOffsetY);
#endif
}
// Compute framebuffer size relative to screen size and display size // Compute framebuffer size relative to screen size and display size
// NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified // NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified
static void SetupFramebufferSize(int displayWidth, int displayHeight) static void SetupFramebufferSize(int displayWidth, int displayHeight)

View File

@ -179,7 +179,7 @@ static int tapCounter = 0; // TAP counter (one tap implies
// Hold gesture variables // Hold gesture variables
static bool resetHold = false; // HOLD reset to get first touch point again static bool resetHold = false; // HOLD reset to get first touch point again
static float timeHold = 0.0f; // HOLD duration in milliseconds static double timeHold = 0.0f; // HOLD duration in milliseconds
// Drag gesture variables // Drag gesture variables
static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position)
@ -423,11 +423,11 @@ float GetGestureHoldDuration(void)
{ {
// NOTE: time is calculated on current gesture HOLD // NOTE: time is calculated on current gesture HOLD
float time = 0.0f; double time = 0.0;
if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold;
return time; return (float)time;
} }
// Get drag vector (between initial touch point to current) // Get drag vector (between initial touch point to current)
@ -474,7 +474,7 @@ static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition)
{ {
float angle; float angle;
angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); angle = atan2f(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI);
if (angle < 0) angle += 360.0f; if (angle < 0) angle += 360.0f;
@ -489,7 +489,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2)
float dx = v2.x - v1.x; float dx = v2.x - v1.x;
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
result = sqrt(dx*dx + dy*dy); result = (float)sqrt(dx*dx + dy*dy);
return result; return result;
} }

View File

@ -648,89 +648,6 @@ Model LoadModelEx(Mesh data, bool dynamic)
return model; return model;
} }
// Load a 3d model from rRES file (raylib Resource)
Model LoadModelFromRES(const char *rresName, int resId)
{
Model model = { 0 };
bool found = false;
char id[4]; // rRES file identifier
unsigned char version; // rRES file version and subversion
char useless; // rRES header reserved data
short numRes;
ResInfoHeader infoHeader;
FILE *rresFile = fopen(rresName, "rb");
if (rresFile == NULL)
{
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
}
else
{
// Read rres file (basic file check - id)
fread(&id[0], sizeof(char), 1, rresFile);
fread(&id[1], sizeof(char), 1, rresFile);
fread(&id[2], sizeof(char), 1, rresFile);
fread(&id[3], sizeof(char), 1, rresFile);
fread(&version, sizeof(char), 1, rresFile);
fread(&useless, sizeof(char), 1, rresFile);
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
}
else
{
// Read number of resources embedded
fread(&numRes, sizeof(short), 1, rresFile);
for (int i = 0; i < numRes; i++)
{
fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile);
if (infoHeader.id == resId)
{
found = true;
// Check data is of valid MODEL type
if (infoHeader.type == 8)
{
// TODO: Load model data
}
else
{
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid MODEL resource", rresName);
}
}
else
{
// Depending on type, skip the right amount of parameters
switch (infoHeader.type)
{
case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters
case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters
case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review)
case 3: break; // TEXT: No parameters
case 4: break; // RAW: No parameters
default: break;
}
// Jump DATA to read next infoHeader
fseek(rresFile, infoHeader.size, SEEK_CUR);
}
}
}
fclose(rresFile);
}
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
return model;
}
// Load a heightmap image as a 3d model // Load a heightmap image as a 3d model
// NOTE: model map size is defined in generic units // NOTE: model map size is defined in generic units
Model LoadHeightmap(Image heightmap, Vector3 size) Model LoadHeightmap(Image heightmap, Vector3 size)
@ -1517,8 +1434,8 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box)
t[3] = (box.max.y - ray.position.y)/ray.direction.y; t[3] = (box.max.y - ray.position.y)/ray.direction.y;
t[4] = (box.min.z - ray.position.z)/ray.direction.z; t[4] = (box.min.z - ray.position.z)/ray.direction.z;
t[5] = (box.max.z - ray.position.z)/ray.direction.z; t[5] = (box.max.z - ray.position.z)/ray.direction.z;
t[6] = fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
t[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
collision = !(t[7] < 0 || t[6] > t[7]); collision = !(t[7] < 0 || t[6] > t[7]);

View File

@ -239,9 +239,10 @@ PHYSACDEF void ClosePhysics(void);
// Functions required to query time on Windows // Functions required to query time on Windows
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount); int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency); int __stdcall QueryPerformanceFrequency(unsigned long long int *lpFrequency);
#elif defined(__linux) #elif defined(__linux) || defined(PLATFORM_WEB)
#include <sys/time.h> // Required for: timespec #include <sys/time.h> // Required for: timespec
#include <time.h> // Required for: clock_gettime() #include <time.h> // Required for: clock_gettime()
#include <stdint.h>
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -266,7 +267,7 @@ PHYSACDEF void ClosePhysics(void);
static unsigned int usedMemory = 0; // Total allocated dynamic memory static unsigned int usedMemory = 0; // Total allocated dynamic memory
static bool physicsThreadEnabled = false; // Physics thread enabled state static bool physicsThreadEnabled = false; // Physics thread enabled state
static double currentTime = 0; // Current time in milliseconds static double currentTime = 0; // Current time in milliseconds
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB)
static double baseTime = 0; // Android and RPI platforms base time static double baseTime = 0; // Android and RPI platforms base time
#endif #endif
static double startTime = 0; // Start time in milliseconds static double startTime = 0; // Start time in milliseconds
@ -1942,7 +1943,7 @@ static double GetCurrentTime(void)
{ {
double time = 0; double time = 0;
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB) #if defined(_WIN32)
unsigned long long int clockFrequency, currentTime; unsigned long long int clockFrequency, currentTime;
QueryPerformanceFrequency(&clockFrequency); QueryPerformanceFrequency(&clockFrequency);
@ -1951,7 +1952,7 @@ static double GetCurrentTime(void)
time = (double)((double)currentTime/clockFrequency)*1000; time = (double)((double)currentTime/clockFrequency)*1000;
#endif #endif
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) #if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB)
struct timespec ts; struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); clock_gettime(CLOCK_MONOTONIC, &ts);
uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec; uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;

View File

@ -19,7 +19,7 @@
* Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1 * Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1
* Custom color palette for fancy visuals on raywhite background * Custom color palette for fancy visuals on raywhite background
* Minimal external dependencies (GLFW3, OpenGL, OpenAL) * Minimal external dependencies (GLFW3, OpenGL, OpenAL)
* Complete binding for LUA [rlua] * Complete binding for Lua [rlua]
* *
* External libs: * External libs:
* GLFW3 (www.glfw.org) for window/context management and input [core] * GLFW3 (www.glfw.org) for window/context management and input [core]
@ -549,7 +549,7 @@ typedef enum {
// Texture parameters: filter mode // Texture parameters: filter mode
// NOTE 1: Filtering considers mipmaps if available in the texture // NOTE 1: Filtering considers mipmaps if available in the texture
// NOTE 2: Filter is accordingly set for minification and magnification // NOTE 2: Filter is accordingly set for minification and magnification
typedef enum { typedef enum {
FILTER_POINT = 0, // No filter, just pixel aproximation FILTER_POINT = 0, // No filter, just pixel aproximation
FILTER_BILINEAR, // Linear filtering FILTER_BILINEAR, // Linear filtering
FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps) FILTER_TRILINEAR, // Trilinear filtering (linear with mipmaps)
@ -581,12 +581,12 @@ typedef enum {
} Gestures; } Gestures;
// Camera system modes // Camera system modes
typedef enum { typedef enum {
CAMERA_CUSTOM = 0, CAMERA_CUSTOM = 0,
CAMERA_FREE, CAMERA_FREE,
CAMERA_ORBITAL, CAMERA_ORBITAL,
CAMERA_FIRST_PERSON, CAMERA_FIRST_PERSON,
CAMERA_THIRD_PERSON CAMERA_THIRD_PERSON
} CameraMode; } CameraMode;
// Head Mounted Display devices // Head Mounted Display devices
@ -770,10 +770,8 @@ RLAPI bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Ve
RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM) RLAPI Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit) RLAPI Image LoadImageEx(Color *pixels, int width, int height); // Load image data from Color array data (RGBA - 32bit)
RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file RLAPI Image LoadImageRaw(const char *fileName, int width, int height, int format, int headerSize); // Load image data from RAW file
RLAPI Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory RLAPI Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory RLAPI Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat); // Load a texture from raw data into GPU memory
RLAPI Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data RLAPI Texture2D LoadTextureFromImage(Image image); // Load a texture from image data
RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering RLAPI RenderTexture2D LoadRenderTexture(int width, int height); // Load a texture to be used for rendering
RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM) RLAPI void UnloadImage(Image image); // Unload image from CPU memory (RAM)
@ -857,7 +855,6 @@ RLAPI void DrawLight(Light light);
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ) RLAPI Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data) RLAPI Model LoadModelEx(Mesh data, bool dynamic); // Load a 3d model (from mesh data)
RLAPI Model LoadModelFromRES(const char *rresName, int resId); // Load a 3d model from rRES file (raylib Resource)
RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model RLAPI Model LoadHeightmap(Image heightmap, Vector3 size); // Load a heightmap image as a 3d model
RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based) RLAPI Model LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
RLAPI void UnloadModel(Model model); // Unload 3d model from memory RLAPI void UnloadModel(Model model); // Unload 3d model from memory
@ -933,8 +930,8 @@ RLAPI Wave LoadWave(const char *fileName); // Load wa
RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit) RLAPI Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // Load wave data from float array data (32bit)
RLAPI Sound LoadSound(const char *fileName); // Load sound to memory RLAPI Sound LoadSound(const char *fileName); // Load sound to memory
RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data RLAPI Sound LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
RLAPI void UpdateSound(Sound sound, const void *data, int numSamples);// Update sound buffer with new data
RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource) RLAPI Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
RLAPI void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
RLAPI void UnloadWave(Wave wave); // Unload wave data RLAPI void UnloadWave(Wave wave); // Unload wave data
RLAPI void UnloadSound(Sound sound); // Unload sound RLAPI void UnloadSound(Sound sound); // Unload sound
RLAPI void PlaySound(Sound sound); // Play a sound RLAPI void PlaySound(Sound sound); // Play a sound

View File

@ -222,16 +222,16 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v)
{ {
Vector3 result; Vector3 result;
float min = fabs(v.x); float min = fabsf(v.x);
Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f};
if (fabs(v.y) < min) if (fabsf(v.y) < min)
{ {
min = fabs(v.y); min = fabsf(v.y);
cardinalAxis = (Vector3){0.0f, 1.0f, 0.0f}; cardinalAxis = (Vector3){0.0f, 1.0f, 0.0f};
} }
if(fabs(v.z) < min) if(fabsf(v.z) < min)
{ {
cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f}; cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f};
} }
@ -256,7 +256,7 @@ RMDEF float VectorLength(const Vector3 v)
{ {
float length; float length;
length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z); length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z);
return length; return length;
} }
@ -284,7 +284,7 @@ RMDEF void VectorNormalize(Vector3 *v)
length = VectorLength(*v); length = VectorLength(*v);
if (length == 0) length = 1.0f; if (length == 0.0f) length = 1.0f;
ilength = 1.0f/length; ilength = 1.0f/length;
@ -302,7 +302,7 @@ RMDEF float VectorDistance(Vector3 v1, Vector3 v2)
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
result = sqrt(dx*dx + dy*dy + dz*dz); result = sqrtf(dx*dx + dy*dy + dz*dz);
return result; return result;
} }
@ -590,7 +590,7 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
float x = axis.x, y = axis.y, z = axis.z; float x = axis.x, y = axis.y, z = axis.z;
float length = sqrt(x*x + y*y + z*z); float length = sqrtf(x*x + y*y + z*z);
if ((length != 1.0f) && (length != 0.0f)) if ((length != 1.0f) && (length != 0.0f))
{ {

View File

@ -318,6 +318,7 @@ static bool texCompETC1Supported = false; // ETC1 texture compression support
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
static bool texCompPVRTSupported = false; // PVR texture compression support static bool texCompPVRTSupported = false; // PVR texture compression support
static bool texCompASTCSupported = false; // ASTC texture compression support static bool texCompASTCSupported = false; // ASTC texture compression support
#endif
// Extension supported flag: Anisotropic filtering // Extension supported flag: Anisotropic filtering
static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support static bool texAnisotropicFilterSupported = false; // Anisotropic texture filtering support
@ -325,7 +326,6 @@ static float maxAnisotropicLevel = 0.0f; // Maximum anisotropy level supp
// Extension supported flag: Clamp mirror wrap mode // Extension supported flag: Clamp mirror wrap mode
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
#endif
#if defined(RLGL_OCULUS_SUPPORT) #if defined(RLGL_OCULUS_SUPPORT)
// OVR device variables // OVR device variables
@ -902,6 +902,10 @@ void rlDisableTexture(void)
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
glDisable(GL_TEXTURE_2D); glDisable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, 0); glBindTexture(GL_TEXTURE_2D, 0);
#else
// NOTE: If quads batch limit is reached,
// we force a draw call and next batch starts
if (quads.vCounter/4 >= MAX_QUADS_BATCH) rlglDraw();
#endif #endif
} }
@ -922,11 +926,11 @@ void rlTextureParameters(unsigned int id, int param, int value)
case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break;
case RL_TEXTURE_ANISOTROPIC_FILTER: case RL_TEXTURE_ANISOTROPIC_FILTER:
{ {
if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
else if (maxAnisotropicLevel > 0.0f) else if (maxAnisotropicLevel > 0.0f)
{ {
TraceLog(WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, maxAnisotropicLevel); TraceLog(WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, maxAnisotropicLevel);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value);
} }
else TraceLog(WARNING, "Anisotropic filtering not supported"); else TraceLog(WARNING, "Anisotropic filtering not supported");
} break; } break;
@ -1733,7 +1737,7 @@ void rlglGenerateMipmaps(Texture2D *texture)
{ {
#if defined(GRAPHICS_API_OPENGL_11) #if defined(GRAPHICS_API_OPENGL_11)
// Compute required mipmaps // Compute required mipmaps
void *data = rlglReadTexturePixels(texture); void *data = rlglReadTexturePixels(*texture);
// NOTE: data size is reallocated to fit mipmaps data // NOTE: data size is reallocated to fit mipmaps data
// NOTE: CPU mipmap generation only supports RGBA 32bit data // NOTE: CPU mipmap generation only supports RGBA 32bit data
@ -1776,7 +1780,7 @@ void rlglGenerateMipmaps(Texture2D *texture)
#define MIN(a,b) (((a)<(b))?(a):(b)) #define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b))
texture->mipmaps = 1 + floor(log2(MAX(texture->width, texture->height))); texture->mipmaps = 1 + (int)floor(log(MAX(texture->width, texture->height))/log(2));
#endif #endif
} }
else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id); else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id);

View File

@ -133,6 +133,7 @@ RLUADEF void CloseLuaDevice(void); // De-initialize Lua system
#define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud) #define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud)
#define LuaGetArgument_string luaL_checkstring #define LuaGetArgument_string luaL_checkstring
#define LuaGetArgument_ptr (void *)luaL_checkinteger
#define LuaGetArgument_int (int)luaL_checkinteger #define LuaGetArgument_int (int)luaL_checkinteger
#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger #define LuaGetArgument_unsigned (unsigned)luaL_checkinteger
#define LuaGetArgument_char (char)luaL_checkinteger #define LuaGetArgument_char (char)luaL_checkinteger
@ -1198,7 +1199,7 @@ int lua_GetGamepadName(lua_State* L)
// TODO: Return gamepad name id // TODO: Return gamepad name id
int arg1 = LuaGetArgument_int(L, 1); int arg1 = LuaGetArgument_int(L, 1);
char * result = GetGamepadName(arg1); const char * result = GetGamepadName(arg1);
//lua_pushboolean(L, result); //lua_pushboolean(L, result);
return 1; return 1;
} }
@ -2863,7 +2864,7 @@ int lua_LoadWaveEx(lua_State* L)
{ {
// TODO: Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels); // TODO: Wave LoadWaveEx(float *data, int sampleCount, int sampleRate, int sampleSize, int channels);
int arg1 = 0; float * arg1 = 0;
int arg2 = LuaGetArgument_int(L, 2); int arg2 = LuaGetArgument_int(L, 2);
int arg3 = LuaGetArgument_int(L, 3); int arg3 = LuaGetArgument_int(L, 3);
int arg4 = LuaGetArgument_int(L, 4); int arg4 = LuaGetArgument_int(L, 4);
@ -2904,7 +2905,7 @@ int lua_UpdateSound(lua_State* L)
Sound arg1 = LuaGetArgument_Sound(L, 1); Sound arg1 = LuaGetArgument_Sound(L, 1);
const char * arg2 = LuaGetArgument_string(L, 2); const char * arg2 = LuaGetArgument_string(L, 2);
int * arg3 = LuaGetArgument_int(L, 3); int arg3 = LuaGetArgument_int(L, 3);
UpdateSound(arg1, arg2, arg3); UpdateSound(arg1, arg2, arg3);
return 0; return 0;
} }

View File

@ -453,16 +453,17 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
int recCenterX = rec.x + rec.width/2; int recCenterX = rec.x + rec.width/2;
int recCenterY = rec.y + rec.height/2; int recCenterY = rec.y + rec.height/2;
float dx = fabs(center.x - recCenterX); float dx = fabsf(center.x - recCenterX);
float dy = fabs(center.y - recCenterY); float dy = fabsf(center.y - recCenterY);
if (dx > (rec.width/2 + radius)) { return false; } if (dx > ((float)rec.width/2.0f + radius)) { return false; }
if (dy > (rec.height/2 + radius)) { return false; } if (dy > ((float)rec.height/2.0f + radius)) { return false; }
if (dx <= (rec.width/2)) { return true; } if (dx <= ((float)rec.width/2.0f)) { return true; }
if (dy <= (rec.height/2)) { return true; } if (dy <= ((float)rec.height/2.0f)) { return true; }
float cornerDistanceSq = (dx - rec.width/2)*(dx - rec.width/2) + (dy - rec.height/2)*(dy - rec.height/2); float cornerDistanceSq = (dx - (float)rec.width/2.0f)*(dx - (float)rec.width/2.0f) +
(dy - (float)rec.height/2.0f)*(dy - (float)rec.height/2.0f);
return (cornerDistanceSq <= (radius*radius)); return (cornerDistanceSq <= (radius*radius));
} }

View File

@ -367,7 +367,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
if ((unsigned char)text[i] == '\n') if ((unsigned char)text[i] == '\n')
{ {
// NOTE: Fixed line spacing of 1.5 lines // NOTE: Fixed line spacing of 1.5 lines
textOffsetY += ((spriteFont.size + spriteFont.size/2)*scaleFactor); textOffsetY += (int)((spriteFont.size + spriteFont.size/2)*scaleFactor);
textOffsetX = 0; textOffsetX = 0;
} }
else else
@ -394,8 +394,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].width*scaleFactor,
spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint);
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (spriteFont.charRecs[index].width*scaleFactor + spacing); if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing);
else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing); else textOffsetX += (int)(spriteFont.charAdvanceX[index]*scaleFactor + spacing);
} }
} }
} }
@ -460,14 +460,14 @@ int MeasureText(const char *text, int fontSize)
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing)
{ {
int len = strlen(text); int len = strlen(text);
int tempLen = 0; // Used to count longer text line num chars int tempLen = 0; // Used to count longer text line num chars
int lenCounter = 0; int lenCounter = 0;
int textWidth = 0; float textWidth = 0;
int tempTextWidth = 0; // Used to count longer text line width float tempTextWidth = 0; // Used to count longer text line width
int textHeight = spriteFont.size; float textHeight = (float)spriteFont.size;
float scaleFactor = fontSize/spriteFont.size; float scaleFactor = fontSize/(float)spriteFont.size;
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)
{ {
@ -485,7 +485,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
if (tempTextWidth < textWidth) tempTextWidth = textWidth; if (tempTextWidth < textWidth) tempTextWidth = textWidth;
lenCounter = 0; lenCounter = 0;
textWidth = 0; textWidth = 0;
textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines textHeight += ((float)spriteFont.size*1.5f); // NOTE: Fixed line spacing of 1.5 lines
} }
if (tempLen < lenCounter) tempLen = lenCounter; if (tempLen < lenCounter) tempLen = lenCounter;
@ -494,8 +494,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
if (tempTextWidth < textWidth) tempTextWidth = textWidth; if (tempTextWidth < textWidth) tempTextWidth = textWidth;
Vector2 vec; Vector2 vec;
vec.x = (float)tempTextWidth*scaleFactor + (tempLen - 1)*spacing; // Adds chars spacing to measure vec.x = tempTextWidth*scaleFactor + (float)((tempLen - 1)*spacing); // Adds chars spacing to measure
vec.y = (float)textHeight*scaleFactor; vec.y = textHeight*scaleFactor;
return vec; return vec;
} }
@ -504,10 +504,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
// NOTE: Uses default font // NOTE: Uses default font
void DrawFPS(int posX, int posY) void DrawFPS(int posX, int posY)
{ {
char buffer[20];
// NOTE: We are rendering fps every second for better viewing on high framerates // NOTE: We are rendering fps every second for better viewing on high framerates
// TODO: Not working properly on ANDROID and RPI // TODO: Not working properly on ANDROID and RPI (for high framerates)
static float fps = 0.0f; static float fps = 0.0f;
static int counter = 0; static int counter = 0;
@ -520,12 +518,11 @@ void DrawFPS(int posX, int posY)
else else
{ {
fps = GetFPS(); fps = GetFPS();
refreshRate = fps; refreshRate = (int)fps;
counter = 0; counter = 0;
} }
sprintf(buffer, "%2.0f FPS", fps); DrawText(FormatText("%2.0f FPS", fps), posX, posY, 20, LIME);
DrawText(buffer, posX, posY, 20, LIME);
} }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------

View File

@ -37,11 +37,10 @@
#include <string.h> // Required for: strcmp(), strrchr(), strncmp() #include <string.h> // Required for: strcmp(), strrchr(), strncmp()
#include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2 #include "rlgl.h" // raylib OpenGL abstraction layer to OpenGL 1.1, 3.3 or ES2
// Required: rlglLoadTexture() rlDeleteTextures(), // Required for: rlglLoadTexture() rlDeleteTextures(),
// rlglGenerateMipmaps(), some funcs for DrawTexturePro() // rlglGenerateMipmaps(), some funcs for DrawTexturePro()
#include "utils.h" // rRES data decompression utility function #include "utils.h" // Required for: fopen() Android mapping, TraceLog()
// NOTE: Includes Android fopen function map
// Support only desired texture formats, by default: JPEG, PNG, BMP, TGA // Support only desired texture formats, by default: JPEG, PNG, BMP, TGA
//#define STBI_NO_JPEG // Image format .jpg and .jpeg //#define STBI_NO_JPEG // Image format .jpg and .jpeg
@ -216,7 +215,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
fread(image.data, size, 1, rawFile); fread(image.data, size, 1, rawFile);
// TODO: Check if data have been read // TODO: Check if data has been read
image.width = width; image.width = width;
image.height = height; image.height = height;
@ -229,118 +228,6 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
return image; return image;
} }
// Load an image from rRES file (raylib Resource)
// TODO: Review function to support multiple color modes
Image LoadImageFromRES(const char *rresName, int resId)
{
Image image = { 0 };
bool found = false;
char id[4]; // rRES file identifier
unsigned char version; // rRES file version and subversion
char useless; // rRES header reserved data
short numRes;
ResInfoHeader infoHeader;
FILE *rresFile = fopen(rresName, "rb");
if (rresFile == NULL)
{
TraceLog(WARNING, "[%s] rRES raylib resource file could not be opened", rresName);
}
else
{
// Read rres file (basic file check - id)
fread(&id[0], sizeof(char), 1, rresFile);
fread(&id[1], sizeof(char), 1, rresFile);
fread(&id[2], sizeof(char), 1, rresFile);
fread(&id[3], sizeof(char), 1, rresFile);
fread(&version, sizeof(char), 1, rresFile);
fread(&useless, sizeof(char), 1, rresFile);
if ((id[0] != 'r') && (id[1] != 'R') && (id[2] != 'E') &&(id[3] != 'S'))
{
TraceLog(WARNING, "[%s] This is not a valid raylib resource file", rresName);
}
else
{
// Read number of resources embedded
fread(&numRes, sizeof(short), 1, rresFile);
for (int i = 0; i < numRes; i++)
{
fread(&infoHeader, sizeof(ResInfoHeader), 1, rresFile);
if (infoHeader.id == resId)
{
found = true;
// Check data is of valid IMAGE type
if (infoHeader.type == 0) // IMAGE data type
{
// TODO: Check data compression type
// NOTE: We suppose compression type 2 (DEFLATE - default)
short imgWidth, imgHeight;
char colorFormat, mipmaps;
fread(&imgWidth, sizeof(short), 1, rresFile); // Image width
fread(&imgHeight, sizeof(short), 1, rresFile); // Image height
fread(&colorFormat, 1, 1, rresFile); // Image data color format (default: RGBA 32 bit)
fread(&mipmaps, 1, 1, rresFile); // Mipmap images included (default: 0)
image.width = (int)imgWidth;
image.height = (int)imgHeight;
unsigned char *compData = malloc(infoHeader.size);
fread(compData, infoHeader.size, 1, rresFile);
unsigned char *imgData = DecompressData(compData, infoHeader.size, infoHeader.srcSize);
// TODO: Review color mode
//image.data = (unsigned char *)malloc(sizeof(unsigned char)*imgWidth*imgHeight*4);
image.data = imgData;
//free(imgData);
free(compData);
TraceLog(INFO, "[%s] Image loaded successfully from resource, size: %ix%i", rresName, image.width, image.height);
}
else
{
TraceLog(WARNING, "[%s] Required resource do not seem to be a valid IMAGE resource", rresName);
}
}
else
{
// Depending on type, skip the right amount of parameters
switch (infoHeader.type)
{
case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters
case 1: fseek(rresFile, 6, SEEK_CUR); break; // SOUND: Jump 6 bytes of parameters
case 2: fseek(rresFile, 5, SEEK_CUR); break; // MODEL: Jump 5 bytes of parameters (TODO: Review)
case 3: break; // TEXT: No parameters
case 4: break; // RAW: No parameters
default: break;
}
// Jump DATA to read next infoHeader
fseek(rresFile, infoHeader.size, SEEK_CUR);
}
}
}
fclose(rresFile);
}
if (!found) TraceLog(WARNING, "[%s] Required resource id [%i] could not be found in the raylib resource file", rresName, resId);
return image;
}
// Load an image as texture into GPU memory // Load an image as texture into GPU memory
Texture2D LoadTexture(const char *fileName) Texture2D LoadTexture(const char *fileName)
{ {
@ -377,18 +264,6 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat)
return texture; return texture;
} }
// Load an image as texture from rRES file (raylib Resource)
Texture2D LoadTextureFromRES(const char *rresName, int resId)
{
Texture2D texture;
Image image = LoadImageFromRES(rresName, resId);
texture = LoadTextureFromImage(image);
UnloadImage(image);
return texture;
}
// Load a texture from image data // Load a texture from image data
// NOTE: image is not unloaded, it must be done manually // NOTE: image is not unloaded, it must be done manually
Texture2D LoadTextureFromImage(Image image) Texture2D LoadTextureFromImage(Image image)
@ -1100,18 +975,18 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color)); Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color));
// EDIT: added +1 to account for an early rounding problem // EDIT: added +1 to account for an early rounding problem
int x_ratio = (int)((image->width<<16)/newWidth) + 1; int xRatio = (int)((image->width << 16)/newWidth) + 1;
int y_ratio = (int)((image->height<<16)/newHeight) + 1; int yRatio = (int)((image->height << 16)/newHeight) + 1;
int x2, y2; int x2, y2;
for (int i = 0; i < newHeight; i++) for (int y = 0; y < newHeight; y++)
{ {
for (int j = 0; j < newWidth; j++) for (int x = 0; x < newWidth; x++)
{ {
x2 = ((j*x_ratio) >> 16); x2 = ((x*xRatio) >> 16);
y2 = ((i*y_ratio) >> 16); y2 = ((y*yRatio) >> 16);
output[(i*newWidth) + j] = pixels[(y2*image->width) + x2] ; output[(y*newWidth) + x] = pixels[(y2*image->width) + x2] ;
} }
} }
@ -1584,7 +1459,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
rlEnableTexture(texture.id); rlEnableTexture(texture.id);
rlPushMatrix(); rlPushMatrix();
rlTranslatef(destRec.x, destRec.y, 0); rlTranslatef((float)destRec.x, (float)destRec.y, 0);
rlRotatef(rotation, 0, 0, 1); rlRotatef(rotation, 0, 0, 1);
rlTranslatef(-origin.x, -origin.y, 0); rlTranslatef(-origin.x, -origin.y, 0);
@ -1598,15 +1473,15 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
// Bottom-right corner for texture and quad // Bottom-right corner for texture and quad
rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex2f(0.0f, destRec.height); rlVertex2f(0.0f, (float)destRec.height);
// Top-right corner for texture and quad // Top-right corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height);
rlVertex2f(destRec.width, destRec.height); rlVertex2f((float)destRec.width, (float)destRec.height);
// Top-left corner for texture and quad // Top-left corner for texture and quad
rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height); rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height);
rlVertex2f(destRec.width, 0.0f); rlVertex2f((float)destRec.width, 0.0f);
rlEnd(); rlEnd();
rlPopMatrix(); rlPopMatrix();

View File

@ -49,9 +49,6 @@
#include "external/stb_image_write.h" // Required for: stbi_write_png() #include "external/stb_image_write.h" // Required for: stbi_write_png()
#endif #endif
#include "external/tinfl.c" // Required for: tinfl_decompress_mem_to_mem()
// NOTE: DEFLATE algorythm data decompression
#define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing #define DO_NOT_TRACE_DEBUG_MSGS // Avoid DEBUG messages tracing
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
@ -75,45 +72,6 @@ static int android_close(void *cookie);
// Module Functions Definition - Utilities // Module Functions Definition - Utilities
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Data decompression function
// NOTE: Allocated data MUST be freed!
unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize)
{
int tempUncompSize;
unsigned char *pUncomp;
// Allocate buffer to hold decompressed data
pUncomp = (mz_uint8 *)malloc((size_t)uncompSize);
// Check correct memory allocation
if (pUncomp == NULL)
{
TraceLog(WARNING, "Out of memory while decompressing data");
}
else
{
// Decompress data
tempUncompSize = tinfl_decompress_mem_to_mem(pUncomp, (size_t)uncompSize, data, compSize, 1);
if (tempUncompSize == -1)
{
TraceLog(WARNING, "Data decompression failed");
free(pUncomp);
}
if (uncompSize != (int)tempUncompSize)
{
TraceLog(WARNING, "Expected uncompressed size do not match, data may be corrupted");
TraceLog(WARNING, " -- Expected uncompressed size: %i", uncompSize);
TraceLog(WARNING, " -- Returned uncompressed size: %i", tempUncompSize);
}
TraceLog(INFO, "Data decompressed successfully from %u bytes to %u bytes", (mz_uint32)compSize, (mz_uint32)tempUncompSize);
}
return pUncomp;
}
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI) #if defined(PLATFORM_DESKTOP) || defined(PLATFORM_RPI)
// Creates a bitmap (BMP) file from an array of pixel data // Creates a bitmap (BMP) file from an array of pixel data
// NOTE: This function is not explicitly available to raylib users // NOTE: This function is not explicitly available to raylib users