Update C sources
This commit is contained in:
parent
aba5226027
commit
e257f040ea
8 changed files with 415 additions and 415 deletions
|
@ -236,9 +236,9 @@ Wave LoadWave(const char *fileName)
|
|||
else if (strcmp(GetExtension(fileName),"rres") == 0)
|
||||
{
|
||||
RRESData rres = LoadResource(fileName);
|
||||
|
||||
|
||||
// NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels
|
||||
|
||||
|
||||
if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4);
|
||||
else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName);
|
||||
|
||||
|
@ -253,18 +253,18 @@ Wave LoadWave(const char *fileName)
|
|||
Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int channels)
|
||||
{
|
||||
Wave wave;
|
||||
|
||||
|
||||
wave.data = data;
|
||||
wave.sampleCount = sampleCount;
|
||||
wave.sampleRate = sampleRate;
|
||||
wave.sampleSize = sampleSize;
|
||||
wave.channels = channels;
|
||||
|
||||
|
||||
// NOTE: Copy wave data to work with, user is responsible of input data to free
|
||||
Wave cwave = WaveCopy(wave);
|
||||
|
||||
|
||||
WaveFormat(&cwave, sampleRate, sampleSize, channels);
|
||||
|
||||
|
||||
return cwave;
|
||||
}
|
||||
|
||||
|
@ -273,9 +273,9 @@ Wave LoadWaveEx(void *data, int sampleCount, int sampleRate, int sampleSize, int
|
|||
Sound LoadSound(const char *fileName)
|
||||
{
|
||||
Wave wave = LoadWave(fileName);
|
||||
|
||||
|
||||
Sound sound = LoadSoundFromWave(wave);
|
||||
|
||||
|
||||
UnloadWave(wave); // Sound is loaded, we can unload wave
|
||||
|
||||
return sound;
|
||||
|
@ -359,7 +359,7 @@ void UnloadWave(Wave wave)
|
|||
void UnloadSound(Sound sound)
|
||||
{
|
||||
alSourceStop(sound.source);
|
||||
|
||||
|
||||
alDeleteSources(1, &sound.source);
|
||||
alDeleteBuffers(1, &sound.buffer);
|
||||
|
||||
|
@ -374,13 +374,13 @@ void UpdateSound(Sound sound, const void *data, int numSamples)
|
|||
alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate);
|
||||
alGetBufferi(sound.buffer, AL_BITS, &sampleSize); // It could also be retrieved from sound.format
|
||||
alGetBufferi(sound.buffer, AL_CHANNELS, &channels); // It could also be retrieved from sound.format
|
||||
|
||||
|
||||
TraceLog(DEBUG, "UpdateSound() : AL_FREQUENCY: %i", sampleRate);
|
||||
TraceLog(DEBUG, "UpdateSound() : AL_BITS: %i", sampleSize);
|
||||
TraceLog(DEBUG, "UpdateSound() : AL_CHANNELS: %i", channels);
|
||||
|
||||
unsigned int dataSize = numSamples*channels*sampleSize/8; // Size of data in bytes
|
||||
|
||||
|
||||
alSourceStop(sound.source); // Stop sound
|
||||
alSourcei(sound.source, AL_BUFFER, 0); // Unbind buffer from sound to update
|
||||
//alDeleteBuffers(1, &sound.buffer); // Delete current buffer data
|
||||
|
@ -468,18 +468,18 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
|
|||
if (wave->sampleRate != sampleRate)
|
||||
{
|
||||
// TODO: Resample wave data (upsampling or downsampling)
|
||||
// NOTE 1: To downsample, you have to drop samples or average them.
|
||||
// NOTE 1: To downsample, you have to drop samples or average them.
|
||||
// NOTE 2: To upsample, you have to interpolate new samples.
|
||||
|
||||
|
||||
wave->sampleRate = sampleRate;
|
||||
}
|
||||
|
||||
|
||||
// Format sample size
|
||||
// NOTE: Only supported 8 bit <--> 16 bit <--> 32 bit
|
||||
if (wave->sampleSize != sampleSize)
|
||||
{
|
||||
void *data = malloc(wave->sampleCount*wave->channels*sampleSize/8);
|
||||
|
||||
|
||||
for (int i = 0; i < wave->sampleCount; i++)
|
||||
{
|
||||
for (int j = 0; j < wave->channels; j++)
|
||||
|
@ -489,30 +489,30 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
|
|||
if (wave->sampleSize == 16) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float)(((short *)wave->data)[wave->channels*i + j])/32767.0f)*256);
|
||||
else if (wave->sampleSize == 32) ((unsigned char *)data)[wave->channels*i + j] = (unsigned char)(((float *)wave->data)[wave->channels*i + j]*127.0f + 127);
|
||||
}
|
||||
else if (sampleSize == 16)
|
||||
else if (sampleSize == 16)
|
||||
{
|
||||
if (wave->sampleSize == 8) ((short *)data)[wave->channels*i + j] = (short)(((float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f)*32767);
|
||||
else if (wave->sampleSize == 32) ((short *)data)[wave->channels*i + j] = (short)((((float *)wave->data)[wave->channels*i + j])*32767);
|
||||
}
|
||||
else if (sampleSize == 32)
|
||||
else if (sampleSize == 32)
|
||||
{
|
||||
if (wave->sampleSize == 8) ((float *)data)[wave->channels*i + j] = (float)(((unsigned char *)wave->data)[wave->channels*i + j] - 127)/256.0f;
|
||||
else if (wave->sampleSize == 16) ((float *)data)[wave->channels*i + j] = (float)(((short *)wave->data)[wave->channels*i + j])/32767.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
wave->sampleSize = sampleSize;
|
||||
free(wave->data);
|
||||
wave->data = data;
|
||||
}
|
||||
|
||||
|
||||
// Format channels (interlaced mode)
|
||||
// NOTE: Only supported mono <--> stereo
|
||||
if (wave->channels != channels)
|
||||
{
|
||||
void *data = malloc(wave->sampleCount*channels*wave->sampleSize/8);
|
||||
|
||||
|
||||
if ((wave->channels == 1) && (channels == 2)) // mono ---> stereo (duplicate mono information)
|
||||
{
|
||||
for (int i = 0; i < wave->sampleCount; i++)
|
||||
|
@ -534,7 +534,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels)
|
|||
else if (wave->sampleSize == 32) ((float *)data)[i] = (((float *)wave->data)[j] + ((float *)wave->data)[j + 1])/2.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: Add/remove additional interlaced channels
|
||||
|
||||
wave->channels = channels;
|
||||
|
@ -568,15 +568,15 @@ Wave WaveCopy(Wave wave)
|
|||
// NOTE: Security check in case of out-of-range
|
||||
void WaveCrop(Wave *wave, int initSample, int finalSample)
|
||||
{
|
||||
if ((initSample >= 0) && (initSample < finalSample) &&
|
||||
if ((initSample >= 0) && (initSample < finalSample) &&
|
||||
(finalSample > 0) && (finalSample < wave->sampleCount))
|
||||
{
|
||||
int sampleCount = finalSample - initSample;
|
||||
|
||||
|
||||
void *data = malloc(sampleCount*wave->channels*wave->sampleSize/8);
|
||||
|
||||
|
||||
memcpy(data, wave->data + (initSample*wave->channels*wave->sampleSize/8), sampleCount*wave->channels*wave->sampleSize/8);
|
||||
|
||||
|
||||
free(wave->data);
|
||||
wave->data = data;
|
||||
}
|
||||
|
@ -588,7 +588,7 @@ void WaveCrop(Wave *wave, int initSample, int finalSample)
|
|||
float *GetWaveData(Wave wave)
|
||||
{
|
||||
float *samples = (float *)malloc(wave.sampleCount*wave.channels*sizeof(float));
|
||||
|
||||
|
||||
for (int i = 0; i < wave.sampleCount; i++)
|
||||
{
|
||||
for (int j = 0; j < wave.channels; j++)
|
||||
|
@ -598,7 +598,7 @@ float *GetWaveData(Wave wave)
|
|||
else if (wave.sampleSize == 32) samples[wave.channels*i + j] = ((float *)wave.data)[wave.channels*i + j];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
|
@ -637,7 +637,7 @@ Music LoadMusicStream(const char *fileName)
|
|||
else if (strcmp(GetExtension(fileName), "flac") == 0)
|
||||
{
|
||||
music->ctxFlac = drflac_open_file(fileName);
|
||||
|
||||
|
||||
if (music->ctxFlac == NULL) TraceLog(WARNING, "[%s] FLAC audio file could not be opened", fileName);
|
||||
else
|
||||
{
|
||||
|
@ -646,7 +646,7 @@ Music LoadMusicStream(const char *fileName)
|
|||
music->samplesLeft = music->totalSamples;
|
||||
music->ctxType = MUSIC_AUDIO_FLAC;
|
||||
music->loop = true; // We loop by default
|
||||
|
||||
|
||||
TraceLog(DEBUG, "[%s] FLAC total samples: %i", fileName, music->totalSamples);
|
||||
TraceLog(DEBUG, "[%s] FLAC sample rate: %i", fileName, music->ctxFlac->sampleRate);
|
||||
TraceLog(DEBUG, "[%s] FLAC bits per sample: %i", fileName, music->ctxFlac->bitsPerSample);
|
||||
|
@ -733,7 +733,7 @@ void ResumeMusicStream(Music music)
|
|||
void StopMusicStream(Music music)
|
||||
{
|
||||
alSourceStop(music->stream.source);
|
||||
|
||||
|
||||
switch (music->ctxType)
|
||||
{
|
||||
case MUSIC_AUDIO_OGG: stb_vorbis_seek_start(music->ctxOgg); break;
|
||||
|
@ -741,7 +741,7 @@ void StopMusicStream(Music music)
|
|||
case MUSIC_MODULE_MOD: jar_mod_seek_start(&music->ctxMod); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
music->samplesLeft = music->totalSamples;
|
||||
}
|
||||
|
||||
|
@ -750,14 +750,14 @@ void UpdateMusicStream(Music music)
|
|||
{
|
||||
ALenum state;
|
||||
ALint processed = 0;
|
||||
|
||||
|
||||
alGetSourcei(music->stream.source, AL_SOURCE_STATE, &state); // Get music stream state
|
||||
alGetSourcei(music->stream.source, AL_BUFFERS_PROCESSED, &processed); // Get processed buffers
|
||||
|
||||
if (processed > 0)
|
||||
{
|
||||
bool active = true;
|
||||
|
||||
|
||||
// NOTE: Using dynamic allocation because it could require more than 16KB
|
||||
void *pcm = calloc(AUDIO_BUFFER_SIZE*music->stream.channels*music->stream.sampleSize/8, 1);
|
||||
|
||||
|
@ -769,7 +769,7 @@ void UpdateMusicStream(Music music)
|
|||
{
|
||||
if (music->samplesLeft >= AUDIO_BUFFER_SIZE) numSamples = AUDIO_BUFFER_SIZE;
|
||||
else numSamples = music->samplesLeft;
|
||||
|
||||
|
||||
// TODO: Really don't like ctxType thingy...
|
||||
switch (music->ctxType)
|
||||
{
|
||||
|
@ -789,7 +789,7 @@ void UpdateMusicStream(Music music)
|
|||
case MUSIC_MODULE_MOD: jar_mod_fillbuffer(&music->ctxMod, pcm, numSamples, 0); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
||||
UpdateAudioStream(music->stream, pcm, numSamples);
|
||||
music->samplesLeft -= numSamples;
|
||||
|
||||
|
@ -799,12 +799,12 @@ void UpdateMusicStream(Music music)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// This error is registered when UpdateAudioStream() fails
|
||||
if (alGetError() == AL_INVALID_VALUE) TraceLog(WARNING, "OpenAL: Error buffering data...");
|
||||
|
||||
// Reset audio stream for looping
|
||||
if (!active)
|
||||
if (!active)
|
||||
{
|
||||
StopMusicStream(music); // Stop music (and reset)
|
||||
if (music->loop) PlayMusicStream(music); // Play again
|
||||
|
@ -815,7 +815,7 @@ void UpdateMusicStream(Music music)
|
|||
// just make sure to play again on window restore
|
||||
if (state != AL_PLAYING) PlayMusicStream(music);
|
||||
}
|
||||
|
||||
|
||||
free(pcm);
|
||||
}
|
||||
}
|
||||
|
@ -871,7 +871,7 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
|||
|
||||
stream.sampleRate = sampleRate;
|
||||
stream.sampleSize = sampleSize;
|
||||
|
||||
|
||||
// Only mono and stereo channels are supported, more channels require AL_EXT_MCFORMATS extension
|
||||
if ((channels > 0) && (channels < 3)) stream.channels = channels;
|
||||
else
|
||||
|
@ -915,12 +915,12 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un
|
|||
// Initialize buffer with zeros by default
|
||||
// NOTE: Using dynamic allocation because it requires more than 16KB
|
||||
void *pcm = calloc(AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, 1);
|
||||
|
||||
|
||||
for (int i = 0; i < MAX_STREAM_BUFFERS; i++)
|
||||
{
|
||||
alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*stream.sampleSize/8*stream.channels, stream.sampleRate);
|
||||
}
|
||||
|
||||
|
||||
free(pcm);
|
||||
|
||||
alSourceQueueBuffers(stream.source, MAX_STREAM_BUFFERS, stream.buffers);
|
||||
|
@ -1100,7 +1100,7 @@ static Wave LoadWAV(const char *fileName)
|
|||
wave.sampleRate = wavFormat.sampleRate;
|
||||
wave.sampleSize = wavFormat.bitsPerSample;
|
||||
wave.channels = wavFormat.numChannels;
|
||||
|
||||
|
||||
// NOTE: Only support 8 bit, 16 bit and 32 bit sample sizes
|
||||
if ((wave.sampleSize != 8) && (wave.sampleSize != 16) && (wave.sampleSize != 32))
|
||||
{
|
||||
|
@ -1109,16 +1109,16 @@ static Wave LoadWAV(const char *fileName)
|
|||
}
|
||||
|
||||
// NOTE: Only support up to 2 channels (mono, stereo)
|
||||
if (wave.channels > 2)
|
||||
if (wave.channels > 2)
|
||||
{
|
||||
WaveFormat(&wave, wave.sampleRate, wave.sampleSize, 2);
|
||||
TraceLog(WARNING, "[%s] WAV channels number (%i) not supported, converted to 2 channels", fileName, wave.channels);
|
||||
}
|
||||
|
||||
|
||||
// NOTE: subChunkSize comes in bytes, we need to translate it to number of samples
|
||||
wave.sampleCount = (wavData.subChunkSize/(wave.sampleSize/8))/wave.channels;
|
||||
|
||||
TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
|
||||
TraceLog(INFO, "[%s] WAV file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1150,7 +1150,7 @@ static Wave LoadOGG(const char *fileName)
|
|||
wave.sampleSize = 16; // 16 bit per sample (short)
|
||||
wave.channels = info.channels;
|
||||
wave.sampleCount = (int)stb_vorbis_stream_length_in_samples(oggFile);
|
||||
|
||||
|
||||
float totalSeconds = stb_vorbis_stream_length_in_seconds(oggFile);
|
||||
if (totalSeconds > 10) TraceLog(WARNING, "[%s] Ogg audio lenght is larger than 10 seconds (%f), that's a big file in memory, consider music streaming", fileName, totalSeconds);
|
||||
|
||||
|
@ -1178,16 +1178,16 @@ static Wave LoadFLAC(const char *fileName)
|
|||
// Decode an entire FLAC file in one go
|
||||
uint64_t totalSampleCount;
|
||||
wave.data = drflac_open_and_decode_file_s16(fileName, &wave.channels, &wave.sampleRate, &totalSampleCount);
|
||||
|
||||
|
||||
wave.sampleCount = (int)totalSampleCount/wave.channels;
|
||||
wave.sampleSize = 16;
|
||||
|
||||
|
||||
// NOTE: Only support up to 2 channels (mono, stereo)
|
||||
if (wave.channels > 2) TraceLog(WARNING, "[%s] FLAC channels number (%i) not supported", fileName, wave.channels);
|
||||
|
||||
if (wave.data == NULL) TraceLog(WARNING, "[%s] FLAC data could not be loaded", fileName);
|
||||
else TraceLog(INFO, "[%s] FLAC file loaded successfully (%i Hz, %i bit, %s)", fileName, wave.sampleRate, wave.sampleSize, (wave.channels == 1) ? "Mono" : "Stereo");
|
||||
|
||||
|
||||
return wave;
|
||||
}
|
||||
|
||||
|
|
104
raylib/core.c
104
raylib/core.c
|
@ -9,7 +9,7 @@
|
|||
* External libs:
|
||||
* GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX)
|
||||
* raymath - 3D math functionality (Vector3, Matrix, Quaternion)
|
||||
* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person)
|
||||
* camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person)
|
||||
* gestures - Gestures system for touch-ready devices (or simulated from mouse inputs)
|
||||
*
|
||||
* Module Configuration Flags:
|
||||
|
@ -103,7 +103,7 @@
|
|||
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
|
||||
#include <linux/input.h> // Linux: Keycodes constants definition (KEY_A, ...)
|
||||
#include <linux/joystick.h> // Linux: Joystick support library
|
||||
|
||||
|
||||
#include "bcm_host.h" // Raspberry Pi VideoCore IV access functions
|
||||
|
||||
#include "EGL/egl.h" // Khronos EGL library - Native platform display device control functions
|
||||
|
@ -330,7 +330,7 @@ static void *GamepadThread(void *arg); // Mouse reading thread
|
|||
// Initialize Window and Graphics Context (OpenGL)
|
||||
void InitWindow(int width, int height, const char *title)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib (v1.6.0)");
|
||||
TraceLog(INFO, "Initializing raylib (v1.7.0)");
|
||||
|
||||
// Store window title (could be useful...)
|
||||
windowTitle = title;
|
||||
|
@ -387,7 +387,7 @@ void InitWindow(int width, int height, const char *title)
|
|||
// Android activity initialization
|
||||
void InitWindow(int width, int height, void *state)
|
||||
{
|
||||
TraceLog(INFO, "Initializing raylib (v1.6.0)");
|
||||
TraceLog(INFO, "Initializing raylib (v1.7.0)");
|
||||
|
||||
app_dummy();
|
||||
|
||||
|
@ -488,9 +488,9 @@ void CloseWindow(void)
|
|||
// Wait for mouse and gamepad threads to finish before closing
|
||||
// NOTE: Those threads should already have finished at this point
|
||||
// because they are controlled by windowShouldClose variable
|
||||
|
||||
|
||||
windowShouldClose = true; // Added to force threads to exit when the close window is called
|
||||
|
||||
|
||||
pthread_join(mouseThreadId, NULL);
|
||||
pthread_join(touchThreadId, NULL);
|
||||
pthread_join(gamepadThreadId, NULL);
|
||||
|
@ -649,14 +649,14 @@ void EndDrawing(void)
|
|||
frameTime = updateTime + drawTime;
|
||||
|
||||
// Wait for some milliseconds...
|
||||
if (frameTime < targetTime)
|
||||
if (frameTime < targetTime)
|
||||
{
|
||||
Wait((int)((targetTime - frameTime)*1000));
|
||||
|
||||
|
||||
currentTime = GetTime();
|
||||
double extraTime = currentTime - previousTime;
|
||||
previousTime = currentTime;
|
||||
|
||||
|
||||
frameTime = updateTime + drawTime + extraTime;
|
||||
}
|
||||
}
|
||||
|
@ -1147,7 +1147,7 @@ bool IsKeyDown(int key)
|
|||
bool IsKeyReleased(int key)
|
||||
{
|
||||
bool released = false;
|
||||
|
||||
|
||||
if ((currentKeyState[key] != previousKeyState[key]) && (currentKeyState[key] == 0)) released = true;
|
||||
else released = false;
|
||||
|
||||
|
@ -1182,7 +1182,7 @@ void SetExitKey(int key)
|
|||
bool IsGamepadAvailable(int gamepad)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad]) result = true;
|
||||
#endif
|
||||
|
@ -1196,7 +1196,7 @@ bool IsGamepadName(int gamepad, const char *name)
|
|||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
const char *gamepadName = NULL;
|
||||
const char *gamepadName = NULL;
|
||||
|
||||
if (gamepadReady[gamepad]) gamepadName = GetGamepadName(gamepad);
|
||||
if ((name != NULL) && (gamepadName != NULL)) result = (strcmp(name, gamepadName) == 0);
|
||||
|
@ -1235,7 +1235,7 @@ int GetGamepadAxisCount(int gamepad)
|
|||
float GetGamepadAxisMovement(int gamepad, int axis)
|
||||
{
|
||||
float value = 0;
|
||||
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (axis < MAX_GAMEPAD_AXIS)) value = gamepadAxisState[gamepad][axis];
|
||||
#endif
|
||||
|
@ -1249,8 +1249,8 @@ bool IsGamepadButtonPressed(int gamepad, int button)
|
|||
bool pressed = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||
(currentGamepadState[gamepad][button] == 1)) pressed = true;
|
||||
#endif
|
||||
|
||||
|
@ -1274,10 +1274,10 @@ bool IsGamepadButtonDown(int gamepad, int button)
|
|||
bool IsGamepadButtonReleased(int gamepad, int button)
|
||||
{
|
||||
bool released = false;
|
||||
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(currentGamepadState[gamepad][button] != previousGamepadState[gamepad][button]) &&
|
||||
(currentGamepadState[gamepad][button] == 0)) released = true;
|
||||
#endif
|
||||
|
||||
|
@ -1290,7 +1290,7 @@ bool IsGamepadButtonUp(int gamepad, int button)
|
|||
bool result = false;
|
||||
|
||||
#if !defined(PLATFORM_ANDROID)
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
if ((gamepad < MAX_GAMEPADS) && gamepadReady[gamepad] && (button < MAX_GAMEPAD_BUTTONS) &&
|
||||
(currentGamepadState[gamepad][button] == 0)) result = true;
|
||||
#endif
|
||||
|
||||
|
@ -1503,7 +1503,7 @@ static void InitGraphicsDevice(int width, int height)
|
|||
glfwWindowHint(GLFW_RESIZABLE, GL_TRUE); // Resizable window
|
||||
}
|
||||
else glfwWindowHint(GLFW_RESIZABLE, GL_FALSE); // Avoid window being resizable
|
||||
|
||||
|
||||
//glfwWindowHint(GLFW_DECORATED, GL_TRUE); // Border and buttons on Window
|
||||
//glfwWindowHint(GLFW_RED_BITS, 8); // Framebuffer red color component bits
|
||||
//glfwWindowHint(GLFW_DEPTH_BITS, 16); // Depthbuffer bits (24 by default)
|
||||
|
@ -1941,7 +1941,7 @@ static double GetTime(void)
|
|||
// Wait for some milliseconds (stop program execution)
|
||||
static void Wait(int ms)
|
||||
{
|
||||
#if defined _WIN32
|
||||
#if defined _WIN32
|
||||
Sleep(ms);
|
||||
#elif defined __linux || defined(PLATFORM_WEB)
|
||||
struct timespec req = { 0 };
|
||||
|
@ -1949,7 +1949,7 @@ static void Wait(int ms)
|
|||
ms -= (sec*1000);
|
||||
req.tv_sec=sec;
|
||||
req.tv_nsec=ms*1000000L;
|
||||
|
||||
|
||||
// NOTE: Use nanosleep() on Unix platforms... usleep() it's deprecated.
|
||||
while (nanosleep(&req,&req) == -1) continue;
|
||||
//#elif defined __APPLE__
|
||||
|
@ -1999,10 +1999,10 @@ static void PollInputEvents(void)
|
|||
// NOTE: Gestures update must be called every frame to reset gestures correctly
|
||||
// because ProcessGestureEvent() is just called on an event, not every frame
|
||||
UpdateGestures();
|
||||
|
||||
|
||||
// Reset last key pressed registered
|
||||
lastKeyPressed = -1;
|
||||
|
||||
|
||||
#if !defined(PLATFORM_RPI)
|
||||
// Reset last gamepad button/axis registered state
|
||||
lastGamepadButtonPressed = -1;
|
||||
|
@ -2018,7 +2018,7 @@ static void PollInputEvents(void)
|
|||
|
||||
mousePosition.x = (float)mouseX;
|
||||
mousePosition.y = (float)mouseY;
|
||||
|
||||
|
||||
// Keyboard input polling (automatically managed by GLFW3 through callback)
|
||||
|
||||
// Register previous keys states
|
||||
|
@ -2039,7 +2039,7 @@ static void PollInputEvents(void)
|
|||
if (glfwJoystickPresent(i)) gamepadReady[i] = true;
|
||||
else gamepadReady[i] = false;
|
||||
}
|
||||
|
||||
|
||||
// Register gamepads buttons events
|
||||
for (int i = 0; i < MAX_GAMEPADS; i++)
|
||||
{
|
||||
|
@ -2047,14 +2047,14 @@ static void PollInputEvents(void)
|
|||
{
|
||||
// Register previous gamepad states
|
||||
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
|
||||
|
||||
|
||||
// Get current gamepad state
|
||||
// NOTE: There is no callback available, so we get it manually
|
||||
const unsigned char *buttons;
|
||||
int buttonsCount;
|
||||
|
||||
buttons = glfwGetJoystickButtons(i, &buttonsCount);
|
||||
|
||||
|
||||
for (int k = 0; (buttons != NULL) && (k < buttonsCount) && (buttonsCount < MAX_GAMEPAD_BUTTONS); k++)
|
||||
{
|
||||
if (buttons[k] == GLFW_PRESS)
|
||||
|
@ -2064,18 +2064,18 @@ static void PollInputEvents(void)
|
|||
}
|
||||
else currentGamepadState[i][k] = 0;
|
||||
}
|
||||
|
||||
|
||||
// Get current axis state
|
||||
const float *axes;
|
||||
int axisCount = 0;
|
||||
|
||||
axes = glfwGetJoystickAxes(i, &axisCount);
|
||||
|
||||
|
||||
for (int k = 0; (axes != NULL) && (k < axisCount) && (k < MAX_GAMEPAD_AXIS); k++)
|
||||
{
|
||||
gamepadAxisState[i][k] = axes[k];
|
||||
}
|
||||
|
||||
|
||||
gamepadAxisCount = axisCount;
|
||||
}
|
||||
}
|
||||
|
@ -2088,16 +2088,16 @@ static void PollInputEvents(void)
|
|||
#if defined(PLATFORM_WEB)
|
||||
// Get number of gamepads connected
|
||||
int numGamepads = emscripten_get_num_gamepads();
|
||||
|
||||
|
||||
for (int i = 0; (i < numGamepads) && (i < MAX_GAMEPADS); i++)
|
||||
{
|
||||
// Register previous gamepad button states
|
||||
for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++) previousGamepadState[i][k] = currentGamepadState[i][k];
|
||||
|
||||
|
||||
EmscriptenGamepadEvent gamepadState;
|
||||
|
||||
|
||||
int result = emscripten_get_gamepad_status(i, &gamepadState);
|
||||
|
||||
|
||||
if (result == EMSCRIPTEN_RESULT_SUCCESS)
|
||||
{
|
||||
// Register buttons data for every connected gamepad
|
||||
|
@ -2109,16 +2109,16 @@ static void PollInputEvents(void)
|
|||
lastGamepadButtonPressed = j;
|
||||
}
|
||||
else currentGamepadState[i][j] = 0;
|
||||
|
||||
|
||||
//printf("Gamepad %d, button %d: Digital: %d, Analog: %g\n", gamepadState.index, j, gamepadState.digitalButton[j], gamepadState.analogButton[j]);
|
||||
}
|
||||
|
||||
|
||||
// Register axis data for every connected gamepad
|
||||
for (int j = 0; (j < gamepadState.numAxes) && (j < MAX_GAMEPAD_AXIS); j++)
|
||||
{
|
||||
gamepadAxisState[i][j] = gamepadState.axis[j];
|
||||
}
|
||||
|
||||
|
||||
gamepadAxisCount = gamepadState.numAxes;
|
||||
}
|
||||
}
|
||||
|
@ -2665,16 +2665,16 @@ static EM_BOOL EmscriptenGamepadCallback(int eventType, const EmscriptenGamepadE
|
|||
{
|
||||
/*
|
||||
printf("%s: timeStamp: %g, connected: %d, index: %ld, numAxes: %d, numButtons: %d, id: \"%s\", mapping: \"%s\"\n",
|
||||
eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state",
|
||||
eventType != 0 ? emscripten_event_type_to_string(eventType) : "Gamepad state",
|
||||
gamepadEvent->timestamp, gamepadEvent->connected, gamepadEvent->index, gamepadEvent->numAxes, gamepadEvent->numButtons, gamepadEvent->id, gamepadEvent->mapping);
|
||||
|
||||
|
||||
for(int i = 0; i < gamepadEvent->numAxes; ++i) printf("Axis %d: %g\n", i, gamepadEvent->axis[i]);
|
||||
for(int i = 0; i < gamepadEvent->numButtons; ++i) printf("Button %d: Digital: %d, Analog: %g\n", i, gamepadEvent->digitalButton[i], gamepadEvent->analogButton[i]);
|
||||
*/
|
||||
|
||||
|
||||
if ((gamepadEvent->connected) && (gamepadEvent->index < MAX_GAMEPADS)) gamepadReady[gamepadEvent->index] = true;
|
||||
else gamepadReady[gamepadEvent->index] = false;
|
||||
|
||||
|
||||
// TODO: Test gamepadEvent->index
|
||||
|
||||
return 0;
|
||||
|
@ -2935,7 +2935,7 @@ static void InitTouch(void)
|
|||
}
|
||||
|
||||
// Touch reading thread.
|
||||
// This reads from a Virtual Input Event /dev/input/event4 which is
|
||||
// This reads from a Virtual Input Event /dev/input/event4 which is
|
||||
// created by the ts_uinput daemon. This takes, filters and scales
|
||||
// raw input from the Touchscreen (which appears in /dev/input/event3)
|
||||
// based on the Calibration data referenced by tslib.
|
||||
|
@ -2949,7 +2949,7 @@ static void *TouchThread(void *arg)
|
|||
if (read(touchStream, &ev, sizeof(ev)) == (int)sizeof(ev))
|
||||
{
|
||||
// if pressure > 0 then simulate left mouse button click
|
||||
if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1)
|
||||
if (ev.type == EV_ABS && ev.code == 24 && ev.value == 0 && currentMouseState[0] == 1)
|
||||
{
|
||||
currentMouseState[0] = 0;
|
||||
gestureEvent.touchAction = TOUCH_UP;
|
||||
|
@ -2963,10 +2963,10 @@ static void *TouchThread(void *arg)
|
|||
gestureEvent.position[1].x /= (float)GetScreenWidth();
|
||||
gestureEvent.position[1].y /= (float)GetScreenHeight();
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
}
|
||||
if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0)
|
||||
}
|
||||
if (ev.type == EV_ABS && ev.code == 24 && ev.value > 0 && currentMouseState[0] == 0)
|
||||
{
|
||||
currentMouseState[0] = 1;
|
||||
currentMouseState[0] = 1;
|
||||
gestureEvent.touchAction = TOUCH_DOWN;
|
||||
gestureEvent.pointCount = 1;
|
||||
gestureEvent.pointerId[0] = 0;
|
||||
|
@ -2978,9 +2978,9 @@ static void *TouchThread(void *arg)
|
|||
gestureEvent.position[1].x /= (float)GetScreenWidth();
|
||||
gestureEvent.position[1].y /= (float)GetScreenHeight();
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
}
|
||||
}
|
||||
// x & y values supplied by event4 have been scaled & de-jittered using tslib calibration data
|
||||
if (ev.type == EV_ABS && ev.code == 0)
|
||||
if (ev.type == EV_ABS && ev.code == 0)
|
||||
{
|
||||
mousePosition.x = ev.value;
|
||||
if (mousePosition.x < 0) mousePosition.x = 0;
|
||||
|
@ -2997,7 +2997,7 @@ static void *TouchThread(void *arg)
|
|||
gestureEvent.position[1].y /= (float)GetScreenHeight();
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
}
|
||||
if (ev.type == EV_ABS && ev.code == 1)
|
||||
if (ev.type == EV_ABS && ev.code == 1)
|
||||
{
|
||||
mousePosition.y = ev.value;
|
||||
if (mousePosition.y < 0) mousePosition.y = 0;
|
||||
|
@ -3014,7 +3014,7 @@ static void *TouchThread(void *arg)
|
|||
gestureEvent.position[1].y /= (float)GetScreenHeight();
|
||||
ProcessGestureEvent(gestureEvent);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
|
@ -3084,7 +3084,7 @@ static void *GamepadThread(void *arg)
|
|||
{
|
||||
// 1 - button pressed, 0 - button released
|
||||
currentGamepadState[i][gamepadEvent.number] = (int)gamepadEvent.value;
|
||||
|
||||
|
||||
if ((int)gamepadEvent.value == 1) lastGamepadButtonPressed = gamepadEvent.number;
|
||||
else lastGamepadButtonPressed = -1;
|
||||
}
|
||||
|
|
|
@ -65,17 +65,17 @@
|
|||
// Gestures type
|
||||
// NOTE: It could be used as flags to enable only some gestures
|
||||
typedef enum {
|
||||
GESTURE_NONE = 1,
|
||||
GESTURE_TAP = 2,
|
||||
GESTURE_DOUBLETAP = 4,
|
||||
GESTURE_HOLD = 8,
|
||||
GESTURE_DRAG = 16,
|
||||
GESTURE_SWIPE_RIGHT = 32,
|
||||
GESTURE_SWIPE_LEFT = 64,
|
||||
GESTURE_SWIPE_UP = 128,
|
||||
GESTURE_SWIPE_DOWN = 256,
|
||||
GESTURE_PINCH_IN = 512,
|
||||
GESTURE_PINCH_OUT = 1024
|
||||
GESTURE_NONE = 0,
|
||||
GESTURE_TAP = 1,
|
||||
GESTURE_DOUBLETAP = 2,
|
||||
GESTURE_HOLD = 4,
|
||||
GESTURE_DRAG = 8,
|
||||
GESTURE_SWIPE_RIGHT = 16,
|
||||
GESTURE_SWIPE_LEFT = 32,
|
||||
GESTURE_SWIPE_UP = 64,
|
||||
GESTURE_SWIPE_DOWN = 128,
|
||||
GESTURE_PINCH_IN = 256,
|
||||
GESTURE_PINCH_OUT = 512
|
||||
} Gestures;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ func GetDroppedFiles(count *int32) []string {
|
|||
ccount := (*C.int)(unsafe.Pointer(count))
|
||||
ret := C.GetDroppedFiles(ccount)
|
||||
|
||||
tmpslice := (*[1 << 30]*C.char)(unsafe.Pointer(ret))[:*count:*count]
|
||||
tmpslice := (*[1 << 24]*C.char)(unsafe.Pointer(ret))[:*count:*count]
|
||||
gostrings := make([]string, *count)
|
||||
for i, s := range tmpslice {
|
||||
gostrings[i] = C.GoString(s)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/**********************************************************************************************
|
||||
*
|
||||
* raylib 1.6.0 (www.raylib.com)
|
||||
* raylib 1.7.0 (www.raylib.com)
|
||||
*
|
||||
* A simple and easy-to-use library to learn videogames programming
|
||||
*
|
||||
|
|
490
raylib/rlgl.c
490
raylib/rlgl.c
File diff suppressed because it is too large
Load diff
|
@ -286,17 +286,17 @@ SpriteFont LoadSpriteFont(const char *fileName)
|
|||
SpriteFont LoadSpriteFontTTF(const char *fileName, int fontSize, int numChars, int *fontChars)
|
||||
{
|
||||
SpriteFont spriteFont = { 0 };
|
||||
|
||||
if (strcmp(GetExtension(fileName),"ttf") == 0)
|
||||
|
||||
if (strcmp(GetExtension(fileName),"ttf") == 0)
|
||||
{
|
||||
if ((fontChars == NULL) || (numChars == 0))
|
||||
{
|
||||
int totalChars = 95; // Default charset [32..126]
|
||||
|
||||
|
||||
int *defaultFontChars = (int *)malloc(totalChars*sizeof(int));
|
||||
|
||||
|
||||
for (int i = 0; i < totalChars; i++) defaultFontChars[i] = i + 32; // Default first character: SPACE[32]
|
||||
|
||||
|
||||
spriteFont = LoadTTF(fileName, fontSize, totalChars, defaultFontChars);
|
||||
}
|
||||
else spriteFont = LoadTTF(fileName, fontSize, numChars, fontChars);
|
||||
|
@ -353,10 +353,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||
int textOffsetX = 0; // Offset between characters
|
||||
int textOffsetY = 0; // Required for line break!
|
||||
float scaleFactor;
|
||||
|
||||
|
||||
unsigned char letter; // Current character
|
||||
int index; // Index position in sprite font
|
||||
|
||||
|
||||
scaleFactor = fontSize/spriteFont.size;
|
||||
|
||||
// NOTE: Some ugly hacks are made to support Latin-1 Extended characters directly
|
||||
|
@ -388,10 +388,10 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float
|
|||
}
|
||||
else index = GetCharIndex(spriteFont, (int)text[i]);
|
||||
|
||||
DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index],
|
||||
DrawTexturePro(spriteFont.texture, spriteFont.charRecs[index],
|
||||
(Rectangle){ position.x + textOffsetX + spriteFont.charOffsets[index].x*scaleFactor,
|
||||
position.y + textOffsetY + spriteFont.charOffsets[index].y*scaleFactor,
|
||||
spriteFont.charRecs[index].width*scaleFactor,
|
||||
spriteFont.charRecs[index].width*scaleFactor,
|
||||
spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint);
|
||||
|
||||
if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing);
|
||||
|
@ -476,7 +476,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i
|
|||
if (text[i] != '\n')
|
||||
{
|
||||
int index = GetCharIndex(spriteFont, (int)text[i]);
|
||||
|
||||
|
||||
if (spriteFont.charAdvanceX[index] != 0) textWidth += spriteFont.charAdvanceX[index];
|
||||
else textWidth += (spriteFont.charRecs[index].width + spriteFont.charOffsets[index].x);
|
||||
}
|
||||
|
@ -517,7 +517,7 @@ static int GetCharIndex(SpriteFont font, int letter)
|
|||
#define UNORDERED_CHARSET
|
||||
#if defined(UNORDERED_CHARSET)
|
||||
int index = 0;
|
||||
|
||||
|
||||
for (int i = 0; i < font.numChars; i++)
|
||||
{
|
||||
if (font.charValues[i] == letter)
|
||||
|
@ -526,7 +526,7 @@ static int GetCharIndex(SpriteFont font, int letter)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return index;
|
||||
#else
|
||||
return (letter - 32);
|
||||
|
@ -607,14 +607,14 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
|||
}
|
||||
|
||||
TraceLog(DEBUG, "SpriteFont data parsed correctly from image");
|
||||
|
||||
// NOTE: We need to remove key color borders from image to avoid weird
|
||||
|
||||
// NOTE: We need to remove key color borders from image to avoid weird
|
||||
// artifacts on texture scaling when using FILTER_BILINEAR or FILTER_TRILINEAR
|
||||
for (int i = 0; i < image.height*image.width; i++) if (COLOR_EQUAL(pixels[i], key)) pixels[i] = BLANK;
|
||||
|
||||
// Create a new image with the processed color data (key color replaced by BLANK)
|
||||
Image fontClear = LoadImageEx(pixels, image.width, image.height);
|
||||
|
||||
|
||||
free(pixels); // Free pixels array memory
|
||||
|
||||
// Create spritefont with all data parsed from image
|
||||
|
@ -622,7 +622,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
|||
|
||||
spriteFont.texture = LoadTextureFromImage(fontClear); // Convert processed image to OpenGL texture
|
||||
spriteFont.numChars = index;
|
||||
|
||||
|
||||
UnloadImage(fontClear); // Unload processed image once converted to texture
|
||||
|
||||
// We got tempCharValues and tempCharsRecs populated with chars data
|
||||
|
@ -643,7 +643,7 @@ static SpriteFont LoadImageFont(Image image, Color key, int firstChar)
|
|||
}
|
||||
|
||||
spriteFont.size = spriteFont.charRecs[0].height;
|
||||
|
||||
|
||||
TraceLog(INFO, "Image file loaded correctly as SpriteFont");
|
||||
|
||||
return spriteFont;
|
||||
|
@ -853,13 +853,13 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||
strncat(texPath, texFileName, strlen(texFileName));
|
||||
|
||||
TraceLog(DEBUG, "[%s] Font texture loading path: %s", fileName, texPath);
|
||||
|
||||
|
||||
Image imFont = LoadImage(texPath);
|
||||
|
||||
if (imFont.format == UNCOMPRESSED_GRAYSCALE)
|
||||
|
||||
if (imFont.format == UNCOMPRESSED_GRAYSCALE)
|
||||
{
|
||||
Image imCopy = ImageCopy(imFont);
|
||||
|
||||
|
||||
for (int i = 0; i < imCopy.width*imCopy.height; i++) ((unsigned char *)imCopy.data)[i] = 0xff; // WHITE pixel
|
||||
|
||||
ImageAlphaMask(&imCopy, imFont);
|
||||
|
@ -867,7 +867,7 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||
UnloadImage(imCopy);
|
||||
}
|
||||
else font.texture = LoadTextureFromImage(imFont);
|
||||
|
||||
|
||||
font.size = fontSize;
|
||||
font.numChars = numChars;
|
||||
font.charValues = (int *)malloc(numChars*sizeof(int));
|
||||
|
@ -876,7 +876,7 @@ static SpriteFont LoadBMFont(const char *fileName)
|
|||
font.charAdvanceX = (int *)malloc(numChars*sizeof(int));
|
||||
|
||||
UnloadImage(imFont);
|
||||
|
||||
|
||||
free(texPath);
|
||||
|
||||
int charId, charX, charY, charWidth, charHeight, charOffsetX, charOffsetY, charAdvanceX;
|
||||
|
@ -913,11 +913,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
|
|||
// NOTE: Font texture size is predicted (being as much conservative as possible)
|
||||
// Predictive method consist of supposing same number of chars by line-column (sqrtf)
|
||||
// and a maximum character width of 3/4 of fontSize... it worked ok with all my tests...
|
||||
|
||||
|
||||
// Calculate next power-of-two value
|
||||
float guessSize = ceilf((float)fontSize*3/4)*ceilf(sqrtf((float)numChars));
|
||||
int textureSize = (int)powf(2, ceilf(logf((float)guessSize)/logf(2))); // Calculate next POT
|
||||
|
||||
|
||||
TraceLog(INFO, "TTF spritefont loading: Predicted texture size: %ix%i", textureSize, textureSize);
|
||||
|
||||
unsigned char *ttfBuffer = (unsigned char *)malloc(1 << 25);
|
||||
|
@ -935,7 +935,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
|
|||
}
|
||||
|
||||
fread(ttfBuffer, 1, 1 << 25, ttfFile);
|
||||
|
||||
|
||||
if (fontChars[0] != 32) TraceLog(WARNING, "TTF spritefont loading: first character is not SPACE(32) character");
|
||||
|
||||
// NOTE: Using stb_truetype crappy packing method, no guarante the font fits the image...
|
||||
|
@ -945,7 +945,7 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
|
|||
|
||||
//if (result > 0) TraceLog(INFO, "TTF spritefont loading: first unused row of generated bitmap: %i", result);
|
||||
if (result < 0) TraceLog(WARNING, "TTF spritefont loading: Not all the characters fit in the font");
|
||||
|
||||
|
||||
free(ttfBuffer);
|
||||
|
||||
// Convert image data from grayscale to to UNCOMPRESSED_GRAY_ALPHA
|
||||
|
@ -966,11 +966,11 @@ static SpriteFont LoadTTF(const char *fileName, int fontSize, int numChars, int
|
|||
image.mipmaps = 1;
|
||||
image.format = UNCOMPRESSED_GRAY_ALPHA;
|
||||
image.data = dataGrayAlpha;
|
||||
|
||||
|
||||
font.texture = LoadTextureFromImage(image);
|
||||
|
||||
|
||||
//SavePNG("generated_ttf_image.png", (unsigned char *)image.data, image.width, image.height, 2);
|
||||
|
||||
|
||||
UnloadImage(image); // Unloads dataGrayAlpha
|
||||
|
||||
font.size = fontSize;
|
||||
|
|
|
@ -144,9 +144,9 @@ Image LoadImage(const char *fileName)
|
|||
else if (strcmp(GetExtension(fileName),"rres") == 0)
|
||||
{
|
||||
RRESData rres = LoadResource(fileName);
|
||||
|
||||
|
||||
// NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps
|
||||
|
||||
|
||||
if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3);
|
||||
else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName);
|
||||
|
||||
|
@ -197,9 +197,9 @@ Image LoadImagePro(void *data, int width, int height, int format)
|
|||
srcImage.height = height;
|
||||
srcImage.mipmaps = 1;
|
||||
srcImage.format = format;
|
||||
|
||||
|
||||
Image dstImage = ImageCopy(srcImage);
|
||||
|
||||
|
||||
return dstImage;
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ Image LoadImageRaw(const char *fileName, int width, int height, int format, int
|
|||
if (bytes < size)
|
||||
{
|
||||
TraceLog(WARNING, "[%s] RAW image data can not be read, wrong requested format or size", fileName);
|
||||
|
||||
|
||||
if (image.data != NULL) free(image.data);
|
||||
}
|
||||
else
|
||||
|
@ -615,12 +615,12 @@ void ImageAlphaMask(Image *image, Image alphaMask)
|
|||
// Force mask to be Grayscale
|
||||
Image mask = ImageCopy(alphaMask);
|
||||
if (mask.format != UNCOMPRESSED_GRAYSCALE) ImageFormat(&mask, UNCOMPRESSED_GRAYSCALE);
|
||||
|
||||
|
||||
// In case image is only grayscale, we just add alpha channel
|
||||
if (image->format == UNCOMPRESSED_GRAYSCALE)
|
||||
{
|
||||
ImageFormat(image, UNCOMPRESSED_GRAY_ALPHA);
|
||||
|
||||
|
||||
// Apply alpha mask to alpha channel
|
||||
for (int i = 0, k = 1; (i < mask.width*mask.height) || (i < image->width*image->height); i++, k += 2)
|
||||
{
|
||||
|
@ -955,7 +955,7 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight)
|
|||
void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
||||
{
|
||||
bool cropRequired = false;
|
||||
|
||||
|
||||
// Security checks to avoid size and rectangle issues (out of bounds)
|
||||
// Check that srcRec is inside src image
|
||||
if (srcRec.x < 0) srcRec.x = 0;
|
||||
|
@ -973,15 +973,15 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
|||
TraceLog(WARNING, "Source rectangle height out of bounds, rescaled height: %i", srcRec.height);
|
||||
cropRequired = true;
|
||||
}
|
||||
|
||||
|
||||
Image srcCopy = ImageCopy(src); // Make a copy of source image to work with it
|
||||
ImageCrop(&srcCopy, srcRec); // Crop source image to desired source rectangle
|
||||
|
||||
|
||||
// Check that dstRec is inside dst image
|
||||
// TODO: Allow negative position within destination with cropping
|
||||
if (dstRec.x < 0) dstRec.x = 0;
|
||||
if (dstRec.y < 0) dstRec.y = 0;
|
||||
|
||||
|
||||
// Scale source image in case destination rec size is different than source rec size
|
||||
if ((dstRec.width != srcRec.width) || (dstRec.height != srcRec.height))
|
||||
{
|
||||
|
@ -1001,20 +1001,20 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
|||
TraceLog(WARNING, "Destination rectangle height out of bounds, rescaled height: %i", dstRec.height);
|
||||
cropRequired = true;
|
||||
}
|
||||
|
||||
|
||||
if (cropRequired)
|
||||
{
|
||||
// Crop destination rectangle if out of bounds
|
||||
Rectangle crop = { 0, 0, dstRec.width, dstRec.height };
|
||||
ImageCrop(&srcCopy, crop);
|
||||
}
|
||||
|
||||
|
||||
// Get image data as Color pixels array to work with it
|
||||
Color *dstPixels = GetImageData(*dst);
|
||||
Color *srcPixels = GetImageData(srcCopy);
|
||||
|
||||
UnloadImage(srcCopy); // Source copy not required any more...
|
||||
|
||||
|
||||
Color srcCol, dstCol;
|
||||
|
||||
// Blit pixels, copy source image into destination
|
||||
|
@ -1026,13 +1026,13 @@ void ImageDraw(Image *dst, Image src, Rectangle srcRec, Rectangle dstRec)
|
|||
// Alpha blending implementation
|
||||
dstCol = dstPixels[j*dst->width + i];
|
||||
srcCol = srcPixels[(j - dstRec.y)*dstRec.width + (i - dstRec.x)];
|
||||
|
||||
|
||||
dstCol.r = ((srcCol.a*(srcCol.r - dstCol.r)) >> 8) + dstCol.r;
|
||||
dstCol.g = ((srcCol.a*(srcCol.g - dstCol.g)) >> 8) + dstCol.g;
|
||||
dstCol.b = ((srcCol.a*(srcCol.b - dstCol.b)) >> 8) + dstCol.b;
|
||||
|
||||
|
||||
dstPixels[j*dst->width + i] = dstCol;
|
||||
|
||||
|
||||
// TODO: Support other blending options
|
||||
}
|
||||
}
|
||||
|
@ -1369,7 +1369,7 @@ void SetTextureFilter(Texture2D texture, int filterMode)
|
|||
{
|
||||
// RL_FILTER_MIP_NEAREST - tex filter: POINT, mipmaps filter: POINT (sharp switching between mipmaps)
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_NEAREST);
|
||||
|
||||
|
||||
// RL_FILTER_NEAREST - tex filter: POINT (no filter), no mipmaps
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_NEAREST);
|
||||
}
|
||||
|
@ -1387,7 +1387,7 @@ void SetTextureFilter(Texture2D texture, int filterMode)
|
|||
// RL_FILTER_LINEAR_MIP_NEAREST - tex filter: BILINEAR, mipmaps filter: POINT (sharp switching between mipmaps)
|
||||
// Alternative: RL_FILTER_NEAREST_MIP_LINEAR - tex filter: POINT, mipmaps filter: BILINEAR (smooth transition between mipmaps)
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR_MIP_NEAREST);
|
||||
|
||||
|
||||
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||
}
|
||||
|
@ -1404,14 +1404,14 @@ void SetTextureFilter(Texture2D texture, int filterMode)
|
|||
{
|
||||
// RL_FILTER_MIP_LINEAR - tex filter: BILINEAR, mipmaps filter: BILINEAR (smooth transition between mipmaps)
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_MIP_LINEAR);
|
||||
|
||||
|
||||
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
TraceLog(WARNING, "[TEX ID %i] No mipmaps available for TRILINEAR texture filtering", texture.id);
|
||||
|
||||
|
||||
// RL_FILTER_LINEAR - tex filter: BILINEAR, no mipmaps
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MIN_FILTER, RL_FILTER_LINEAR);
|
||||
rlTextureParameters(texture.id, RL_TEXTURE_MAG_FILTER, RL_FILTER_LINEAR);
|
||||
|
@ -2007,19 +2007,19 @@ static Image LoadPVR(const char *fileName)
|
|||
image.mipmaps = pvrHeader.numMipmaps;
|
||||
|
||||
// Check data format
|
||||
if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8))
|
||||
if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 0)) && (pvrHeader.channelDepth[0] == 8))
|
||||
image.format = UNCOMPRESSED_GRAYSCALE;
|
||||
else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8)))
|
||||
else if (((pvrHeader.channels[0] == 'l') && (pvrHeader.channels[1] == 'a')) && ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8)))
|
||||
image.format = UNCOMPRESSED_GRAY_ALPHA;
|
||||
else if ((pvrHeader.channels[0] == 'r') && (pvrHeader.channels[1] == 'g') && (pvrHeader.channels[2] == 'b'))
|
||||
{
|
||||
if (pvrHeader.channels[3] == 'a')
|
||||
{
|
||||
if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1))
|
||||
if ((pvrHeader.channelDepth[0] == 5) && (pvrHeader.channelDepth[1] == 5) && (pvrHeader.channelDepth[2] == 5) && (pvrHeader.channelDepth[3] == 1))
|
||||
image.format = UNCOMPRESSED_R5G5B5A1;
|
||||
else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4))
|
||||
else if ((pvrHeader.channelDepth[0] == 4) && (pvrHeader.channelDepth[1] == 4) && (pvrHeader.channelDepth[2] == 4) && (pvrHeader.channelDepth[3] == 4))
|
||||
image.format = UNCOMPRESSED_R4G4B4A4;
|
||||
else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8))
|
||||
else if ((pvrHeader.channelDepth[0] == 8) && (pvrHeader.channelDepth[1] == 8) && (pvrHeader.channelDepth[2] == 8) && (pvrHeader.channelDepth[3] == 8))
|
||||
image.format = UNCOMPRESSED_R8G8B8A8;
|
||||
}
|
||||
else if (pvrHeader.channels[3] == 0)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue