Merge aaea2eb9a6 into 17f09cb034
This commit is contained in:
commit
ac05e039b1
14
.gitignore
vendored
14
.gitignore
vendored
|
|
@ -51,6 +51,17 @@ ipch/
|
|||
*.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
|
||||
*.mode*v*
|
||||
*.pbxuser
|
||||
|
|
@ -68,9 +79,6 @@ DerivedData/
|
|||
src/libraylib.a
|
||||
src/libraylib.bc
|
||||
|
||||
# oculus example
|
||||
!examples/oculus_glfw_sample/
|
||||
|
||||
# external libraries DLLs
|
||||
!src/external/glfw3/lib/win32/glfw3.dll
|
||||
!src/external/openal_soft/lib/win32/OpenAL32.dll
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ NOTE:
|
|||
It includes some interesting new features and is a stepping stone towards raylib future.
|
||||
|
||||
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.
|
||||
[physac] COMPLETE REWRITE: Improved performance, functionality and simplified usage, moved to own repository and added multiple examples!
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
||||
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!
|
||||
|
||||
|
|
@ -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.
|
||||
- [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!
|
||||
- [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"
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ raylib 1.x
|
|||
|
||||
raylib 1.6
|
||||
|
||||
[DONE] LUA scripting support (raylib lua wrapper)
|
||||
[DONE] Lua scripting support (raylib Lua wrapper)
|
||||
[DONE] Redesigned audio module
|
||||
|
||||
raylib 1.5
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ int main()
|
|||
//----------------------------------------------------------------------------------
|
||||
BeginDrawing();
|
||||
|
||||
ClearBackground(WHITE);
|
||||
ClearBackground(RAYWHITE);
|
||||
|
||||
for (int i = MAX_CIRCLES - 1; i >= 0; i--)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -24,10 +24,52 @@
|
|||
********************************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#if defined(_WIN32)
|
||||
#include <conio.h> // Windows only, no stardard library
|
||||
|
||||
#endif
|
||||
#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
|
||||
|
||||
int main()
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#include "..\src\physac.h"
|
||||
#include "../src/physac.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#include "..\src\physac.h"
|
||||
#include "../src/physac.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#include "..\src\physac.h"
|
||||
#include "../src/physac.h"
|
||||
|
||||
#define VELOCITY 0.5f
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#include "..\src\physac.h"
|
||||
#include "../src/physac.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include "raylib.h"
|
||||
|
||||
#define PHYSAC_IMPLEMENTATION
|
||||
#include "..\src\physac.h"
|
||||
#include "../src/physac.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -144,7 +144,7 @@ int main(void)
|
|||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
UpdateOculusTracking();
|
||||
UpdateOculusTracking(&camera);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
136
src/audio.c
136
src/audio.c
|
|
@ -52,8 +52,7 @@
|
|||
#include <stdarg.h> // Required for: va_list, va_start(), vfprintf(), va_end()
|
||||
#else
|
||||
#include "raylib.h"
|
||||
#include "utils.h" // Required for: DecompressData()
|
||||
// NOTE: Includes Android fopen() function map
|
||||
#include "utils.h" // Required for: fopen() Android mapping, TraceLog()
|
||||
#endif
|
||||
|
||||
#include "AL/al.h" // OpenAL basic header
|
||||
|
|
@ -324,117 +323,6 @@ Sound LoadSoundFromWave(Wave wave)
|
|||
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
|
||||
void UnloadWave(Wave wave)
|
||||
{
|
||||
|
|
@ -454,7 +342,7 @@ void UnloadSound(Sound sound)
|
|||
|
||||
// Update sound buffer with new data
|
||||
// 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;
|
||||
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
|
||||
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));
|
||||
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)
|
||||
{
|
||||
bool active = true;
|
||||
short pcm[AUDIO_BUFFER_SIZE];
|
||||
float pcmf[AUDIO_BUFFER_SIZE];
|
||||
short pcm[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack)
|
||||
float pcmf[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack)
|
||||
int numBuffersToProcess = processed;
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1004,17 +892,17 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
|||
{
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1195,12 +1083,14 @@ static Wave LoadWAV(const char *fileName)
|
|||
// Read in the sound data into the soundData variable
|
||||
fread(wave.data, waveData.subChunkSize, 1, wavFile);
|
||||
|
||||
// Now we set the variables that we need later
|
||||
wave.sampleCount = waveData.subChunkSize;
|
||||
// Store wave parameters
|
||||
wave.sampleRate = waveFormat.sampleRate;
|
||||
wave.sampleSize = waveFormat.bitsPerSample;
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 LoadSoundFromWave(Wave wave); // Load sound to memory from wave data
|
||||
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
|
||||
void 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 UnloadSound(Sound sound); // Unload sound
|
||||
void PlaySound(Sound sound); // Play a sound
|
||||
|
|
|
|||
70
src/camera.h
70
src/camera.h
|
|
@ -223,15 +223,15 @@ void SetCameraMode(Camera camera, int mode)
|
|||
float dy = v2.y - v1.y;
|
||||
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 };
|
||||
distance.x = sqrt(dx*dx + dz*dz);
|
||||
distance.y = sqrt(dx*dx + dy*dy);
|
||||
distance.x = sqrtf(dx*dx + dz*dz);
|
||||
distance.y = sqrtf(dx*dx + dy*dy);
|
||||
|
||||
// Camera angle calculation
|
||||
cameraAngle.x = asin(fabs(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.x = asinf(fabsf(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
|
||||
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
|
||||
//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();
|
||||
|
||||
if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
|
||||
else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
|
||||
else if (mousePosition.x > (screenWidth - screenHeight/3)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
|
||||
else if (mousePosition.y > (screenHeight - screenHeight/3)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 });
|
||||
if (mousePosition.x < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y });
|
||||
else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 });
|
||||
else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y });
|
||||
else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 });
|
||||
else
|
||||
{
|
||||
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;
|
||||
}
|
||||
// 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))
|
||||
{
|
||||
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;
|
||||
}
|
||||
// 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))
|
||||
{
|
||||
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
|
||||
|
|
@ -385,9 +387,9 @@ void UpdateCamera(Camera *camera)
|
|||
else
|
||||
{
|
||||
// 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.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(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.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)*cosf(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_THIRD_PERSON:
|
||||
{
|
||||
camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
sin(cameraAngle.x)*direction[MOVE_FRONT] -
|
||||
cos(cameraAngle.x)*direction[MOVE_LEFT] +
|
||||
cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
sinf(cameraAngle.x)*direction[MOVE_FRONT] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_LEFT] +
|
||||
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] -
|
||||
sin(cameraAngle.y)*direction[MOVE_BACK] +
|
||||
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
|
||||
sinf(cameraAngle.y)*direction[MOVE_BACK] +
|
||||
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
cos(cameraAngle.x)*direction[MOVE_FRONT] +
|
||||
sin(cameraAngle.x)*direction[MOVE_LEFT] -
|
||||
sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
|
||||
cosf(cameraAngle.x)*direction[MOVE_FRONT] +
|
||||
sinf(cameraAngle.x)*direction[MOVE_LEFT] -
|
||||
sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
|
||||
|
||||
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;
|
||||
|
||||
// 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.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
|
||||
{
|
||||
|
|
@ -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;
|
||||
|
||||
// Camera is always looking at player
|
||||
camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cos(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 + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
|
||||
|
||||
if (isMoving) swingCounter++;
|
||||
|
||||
// Camera position update
|
||||
// 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.z = -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 = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
|
|
@ -473,10 +475,10 @@ void UpdateCamera(Camera *camera)
|
|||
(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...
|
||||
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
|
||||
if (cameraAngle.y <= 0.0f) 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;
|
||||
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
|
||||
if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
|
||||
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
45
src/core.c
45
src/core.c
|
|
@ -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 "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_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
|
||||
#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
|
||||
#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 SetupViewport(void);
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
|
|
@ -744,8 +746,7 @@ void EndTextureMode(void)
|
|||
rlDisableRenderTexture(); // Disable render target
|
||||
|
||||
// Set viewport to default framebuffer size (screen size)
|
||||
// TODO: consider possible viewport offsets
|
||||
rlViewport(0, 0, GetScreenWidth(), GetScreenHeight());
|
||||
SetupViewport();
|
||||
|
||||
rlMatrixMode(RL_PROJECTION); // Switch to PROJECTION matrix
|
||||
rlLoadIdentity(); // Reset current matrix (PROJECTION)
|
||||
|
|
@ -1089,7 +1090,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera)
|
|||
QuaternionTransform(&worldPos, matProj);
|
||||
|
||||
// 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
|
||||
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
|
||||
rlglInit(screenWidth, screenHeight);
|
||||
|
||||
#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
|
||||
// Setup default viewport
|
||||
SetupViewport();
|
||||
|
||||
// Initialize internal projection and modelview matrices
|
||||
// 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
|
||||
}
|
||||
|
||||
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
|
||||
// NOTE: Global variables renderWidth/renderHeight and renderOffsetX/renderOffsetY can be modified
|
||||
static void SetupFramebufferSize(int displayWidth, int displayHeight)
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ static int tapCounter = 0; // TAP counter (one tap implies
|
|||
|
||||
// Hold gesture variables
|
||||
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
|
||||
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
|
||||
|
||||
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)
|
||||
|
|
@ -474,7 +474,7 @@ static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition)
|
|||
{
|
||||
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;
|
||||
|
||||
|
|
@ -489,7 +489,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2)
|
|||
float dx = v2.x - v1.x;
|
||||
float dy = v2.y - v1.y;
|
||||
|
||||
result = sqrt(dx*dx + dy*dy);
|
||||
result = (float)sqrt(dx*dx + dy*dy);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
87
src/models.c
87
src/models.c
|
|
@ -648,89 +648,6 @@ Model LoadModelEx(Mesh data, bool dynamic)
|
|||
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
|
||||
// NOTE: model map size is defined in generic units
|
||||
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[4] = (box.min.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[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(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] = (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]);
|
||||
|
||||
|
|
|
|||
|
|
@ -239,9 +239,10 @@ PHYSACDEF void ClosePhysics(void);
|
|||
// Functions required to query time on Windows
|
||||
int __stdcall QueryPerformanceCounter(unsigned long long int *lpPerformanceCount);
|
||||
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 <time.h> // Required for: clock_gettime()
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -266,7 +267,7 @@ PHYSACDEF void ClosePhysics(void);
|
|||
static unsigned int usedMemory = 0; // Total allocated dynamic memory
|
||||
static bool physicsThreadEnabled = false; // Physics thread enabled state
|
||||
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
|
||||
#endif
|
||||
static double startTime = 0; // Start time in milliseconds
|
||||
|
|
@ -1942,7 +1943,7 @@ static double GetCurrentTime(void)
|
|||
{
|
||||
double time = 0;
|
||||
|
||||
#if defined(PLATFORM_DESKTOP) || defined(PLATFORM_WEB)
|
||||
#if defined(_WIN32)
|
||||
unsigned long long int clockFrequency, currentTime;
|
||||
|
||||
QueryPerformanceFrequency(&clockFrequency);
|
||||
|
|
@ -1951,7 +1952,7 @@ static double GetCurrentTime(void)
|
|||
time = (double)((double)currentTime/clockFrequency)*1000;
|
||||
#endif
|
||||
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI)
|
||||
#if defined(PLATFORM_ANDROID) || defined(PLATFORM_RPI) || defined(__linux) || defined(PLATFORM_WEB)
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
uint64_t temp = (uint64_t)ts.tv_sec*1000000000LLU + (uint64_t)ts.tv_nsec;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Multiple platforms support: Windows, Linux, Mac, Android, Raspberry Pi, HTML5 and Oculus Rift CV1
|
||||
* Custom color palette for fancy visuals on raywhite background
|
||||
* Minimal external dependencies (GLFW3, OpenGL, OpenAL)
|
||||
* Complete binding for LUA [rlua]
|
||||
* Complete binding for Lua [rlua]
|
||||
*
|
||||
* External libs:
|
||||
* GLFW3 (www.glfw.org) for window/context management and input [core]
|
||||
|
|
@ -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 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 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 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 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)
|
||||
|
|
@ -857,7 +855,6 @@ RLAPI void DrawLight(Light light);
|
|||
//------------------------------------------------------------------------------------
|
||||
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 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 LoadCubicmap(Image cubicmap); // Load a map image as a 3d model (cubes based)
|
||||
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 Sound LoadSound(const char *fileName); // Load sound to memory
|
||||
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 void UpdateSound(Sound sound, void *data, int numSamples); // Update sound buffer with new data
|
||||
RLAPI void UnloadWave(Wave wave); // Unload wave data
|
||||
RLAPI void UnloadSound(Sound sound); // Unload sound
|
||||
RLAPI void PlaySound(Sound sound); // Play a sound
|
||||
|
|
|
|||
|
|
@ -222,16 +222,16 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v)
|
|||
{
|
||||
Vector3 result;
|
||||
|
||||
float min = fabs(v.x);
|
||||
float min = fabsf(v.x);
|
||||
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};
|
||||
}
|
||||
|
||||
if(fabs(v.z) < min)
|
||||
if(fabsf(v.z) < min)
|
||||
{
|
||||
cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f};
|
||||
}
|
||||
|
|
@ -256,7 +256,7 @@ RMDEF float VectorLength(const Vector3 v)
|
|||
{
|
||||
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;
|
||||
}
|
||||
|
|
@ -284,7 +284,7 @@ RMDEF void VectorNormalize(Vector3 *v)
|
|||
|
||||
length = VectorLength(*v);
|
||||
|
||||
if (length == 0) length = 1.0f;
|
||||
if (length == 0.0f) length = 1.0f;
|
||||
|
||||
ilength = 1.0f/length;
|
||||
|
||||
|
|
@ -302,7 +302,7 @@ RMDEF float VectorDistance(Vector3 v1, Vector3 v2)
|
|||
float dy = v2.y - v1.y;
|
||||
float dz = v2.z - v1.z;
|
||||
|
||||
result = sqrt(dx*dx + dy*dy + dz*dz);
|
||||
result = sqrtf(dx*dx + dy*dy + dz*dz);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
@ -590,7 +590,7 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle)
|
|||
|
||||
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))
|
||||
{
|
||||
|
|
|
|||
14
src/rlgl.c
14
src/rlgl.c
|
|
@ -318,6 +318,7 @@ static bool texCompETC1Supported = false; // ETC1 texture compression support
|
|||
static bool texCompETC2Supported = false; // ETC2/EAC texture compression support
|
||||
static bool texCompPVRTSupported = false; // PVR texture compression support
|
||||
static bool texCompASTCSupported = false; // ASTC texture compression support
|
||||
#endif
|
||||
|
||||
// Extension supported flag: Anisotropic filtering
|
||||
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
|
||||
static bool texClampMirrorSupported = false; // Clamp mirror wrap mode supported
|
||||
#endif
|
||||
|
||||
#if defined(RLGL_OCULUS_SUPPORT)
|
||||
// OVR device variables
|
||||
|
|
@ -902,6 +902,10 @@ void rlDisableTexture(void)
|
|||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -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_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)
|
||||
{
|
||||
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");
|
||||
} break;
|
||||
|
|
@ -1733,7 +1737,7 @@ void rlglGenerateMipmaps(Texture2D *texture)
|
|||
{
|
||||
#if defined(GRAPHICS_API_OPENGL_11)
|
||||
// Compute required mipmaps
|
||||
void *data = rlglReadTexturePixels(texture);
|
||||
void *data = rlglReadTexturePixels(*texture);
|
||||
|
||||
// NOTE: data size is reallocated to fit mipmaps 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 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
|
||||
}
|
||||
else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id);
|
||||
|
|
|
|||
|
|
@ -133,6 +133,7 @@ RLUADEF void CloseLuaDevice(void); // De-initialize Lua system
|
|||
#define LuaPush_AudioStream(L, aud) LuaPushOpaqueType(L, aud)
|
||||
|
||||
#define LuaGetArgument_string luaL_checkstring
|
||||
#define LuaGetArgument_ptr (void *)luaL_checkinteger
|
||||
#define LuaGetArgument_int (int)luaL_checkinteger
|
||||
#define LuaGetArgument_unsigned (unsigned)luaL_checkinteger
|
||||
#define LuaGetArgument_char (char)luaL_checkinteger
|
||||
|
|
@ -1198,7 +1199,7 @@ int lua_GetGamepadName(lua_State* L)
|
|||
// TODO: Return gamepad name id
|
||||
|
||||
int arg1 = LuaGetArgument_int(L, 1);
|
||||
char * result = GetGamepadName(arg1);
|
||||
const char * result = GetGamepadName(arg1);
|
||||
//lua_pushboolean(L, result);
|
||||
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);
|
||||
|
||||
int arg1 = 0;
|
||||
float * arg1 = 0;
|
||||
int arg2 = LuaGetArgument_int(L, 2);
|
||||
int arg3 = LuaGetArgument_int(L, 3);
|
||||
int arg4 = LuaGetArgument_int(L, 4);
|
||||
|
|
@ -2904,7 +2905,7 @@ int lua_UpdateSound(lua_State* L)
|
|||
|
||||
Sound arg1 = LuaGetArgument_Sound(L, 1);
|
||||
const char * arg2 = LuaGetArgument_string(L, 2);
|
||||
int * arg3 = LuaGetArgument_int(L, 3);
|
||||
int arg3 = LuaGetArgument_int(L, 3);
|
||||
UpdateSound(arg1, arg2, arg3);
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
15
src/shapes.c
15
src/shapes.c
|
|
@ -453,16 +453,17 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec)
|
|||
int recCenterX = rec.x + rec.width/2;
|
||||
int recCenterY = rec.y + rec.height/2;
|
||||
|
||||
float dx = fabs(center.x - recCenterX);
|
||||
float dy = fabs(center.y - recCenterY);
|
||||
float dx = fabsf(center.x - recCenterX);
|
||||
float dy = fabsf(center.y - recCenterY);
|
||||
|
||||
if (dx > (rec.width/2 + radius)) { return false; }
|
||||
if (dy > (rec.height/2 + radius)) { return false; }
|
||||
if (dx > ((float)rec.width/2.0f + radius)) { return false; }
|
||||
if (dy > ((float)rec.height/2.0f + radius)) { return false; }
|
||||
|
||||
if (dx <= (rec.width/2)) { return true; }
|
||||
if (dy <= (rec.height/2)) { return true; }
|
||||
if (dx <= ((float)rec.width/2.0f)) { 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));
|
||||
}
|
||||
|
|
|
|||
29
src/text.c
29
src/text.c
|
|
@ -367,7 +367,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||
if ((unsigned char)text[i] == '\n')
|
||||
{
|
||||
// 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;
|
||||
}
|
||||
else
|
||||
|
|
@ -394,8 +394,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||
spriteFont.charRecs[index].width*scaleFactor,
|
||||
spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint);
|
||||
|
||||
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (spriteFont.charRecs[index].width*scaleFactor + spacing);
|
||||
else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing);
|
||||
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing);
|
||||
else textOffsetX += (int)(spriteFont.charAdvanceX[index]*scaleFactor + spacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -463,11 +463,11 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
|
|||
int tempLen = 0; // Used to count longer text line num chars
|
||||
int lenCounter = 0;
|
||||
|
||||
int textWidth = 0;
|
||||
int tempTextWidth = 0; // Used to count longer text line width
|
||||
float textWidth = 0;
|
||||
float tempTextWidth = 0; // Used to count longer text line width
|
||||
|
||||
int textHeight = spriteFont.size;
|
||||
float scaleFactor = fontSize/spriteFont.size;
|
||||
float textHeight = (float)spriteFont.size;
|
||||
float scaleFactor = fontSize/(float)spriteFont.size;
|
||||
|
||||
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;
|
||||
lenCounter = 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;
|
||||
|
|
@ -494,8 +494,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
|
|||
if (tempTextWidth < textWidth) tempTextWidth = textWidth;
|
||||
|
||||
Vector2 vec;
|
||||
vec.x = (float)tempTextWidth*scaleFactor + (tempLen - 1)*spacing; // Adds chars spacing to measure
|
||||
vec.y = (float)textHeight*scaleFactor;
|
||||
vec.x = tempTextWidth*scaleFactor + (float)((tempLen - 1)*spacing); // Adds chars spacing to measure
|
||||
vec.y = textHeight*scaleFactor;
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
|
@ -504,10 +504,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
|
|||
// NOTE: Uses default font
|
||||
void DrawFPS(int posX, int posY)
|
||||
{
|
||||
char buffer[20];
|
||||
|
||||
// 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 int counter = 0;
|
||||
|
|
@ -520,12 +518,11 @@ void DrawFPS(int posX, int posY)
|
|||
else
|
||||
{
|
||||
fps = GetFPS();
|
||||
refreshRate = fps;
|
||||
refreshRate = (int)fps;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
sprintf(buffer, "%2.0f FPS", fps);
|
||||
DrawText(buffer, posX, posY, 20, LIME);
|
||||
DrawText(FormatText("%2.0f FPS", fps), posX, posY, 20, LIME);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
|
|||
153
src/textures.c
153
src/textures.c
|
|
@ -37,11 +37,10 @@
|
|||
#include <string.h> // Required for: strcmp(), strrchr(), strncmp()
|
||||
|
||||
#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()
|
||||
|
||||
#include "utils.h" // rRES data decompression utility function
|
||||
// NOTE: Includes Android fopen function map
|
||||
#include "utils.h" // Required for: fopen() Android mapping, TraceLog()
|
||||
|
||||
// Support only desired texture formats, by default: JPEG, PNG, BMP, TGA
|
||||
//#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);
|
||||
|
||||
// TODO: Check if data have been read
|
||||
// TODO: Check if data has been read
|
||||
|
||||
image.width = width;
|
||||
image.height = height;
|
||||
|
|
@ -229,118 +228,6 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
|
|||
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
|
||||
Texture2D LoadTexture(const char *fileName)
|
||||
{
|
||||
|
|
@ -377,18 +264,6 @@ Texture2D LoadTextureEx(void *data, int width, int height, int textureFormat)
|
|||
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
|
||||
// NOTE: image is not unloaded, it must be done manually
|
||||
Texture2D LoadTextureFromImage(Image image)
|
||||
|
|
@ -1100,18 +975,18 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
|
|||
Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color));
|
||||
|
||||
// EDIT: added +1 to account for an early rounding problem
|
||||
int x_ratio = (int)((image->width<<16)/newWidth) + 1;
|
||||
int y_ratio = (int)((image->height<<16)/newHeight) + 1;
|
||||
int xRatio = (int)((image->width << 16)/newWidth) + 1;
|
||||
int yRatio = (int)((image->height << 16)/newHeight) + 1;
|
||||
|
||||
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);
|
||||
y2 = ((i*y_ratio) >> 16);
|
||||
x2 = ((x*xRatio) >> 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);
|
||||
|
||||
rlPushMatrix();
|
||||
rlTranslatef(destRec.x, destRec.y, 0);
|
||||
rlTranslatef((float)destRec.x, (float)destRec.y, 0);
|
||||
rlRotatef(rotation, 0, 0, 1);
|
||||
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
|
||||
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
|
||||
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
|
||||
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();
|
||||
rlPopMatrix();
|
||||
|
||||
|
|
|
|||
42
src/utils.c
42
src/utils.c
|
|
@ -49,9 +49,6 @@
|
|||
#include "external/stb_image_write.h" // Required for: stbi_write_png()
|
||||
#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
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -75,45 +72,6 @@ static int android_close(void *cookie);
|
|||
// 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)
|
||||
// Creates a bitmap (BMP) file from an array of pixel data
|
||||
// NOTE: This function is not explicitly available to raylib users
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user