Updated raylib to version 1.0.4

Lots of changes added, check CHANGELOG for detailed description
This commit is contained in:
raysan5 2014-01-23 12:36:18 +01:00
parent 762befb967
commit 2cf5fa7765
15 changed files with 1283 additions and 114 deletions

View File

@ -1,11 +1,32 @@
changelog
---------
Current Release: raylib 1.0.3 (December 2013)
Current Release: raylib 1.0.4 (January 2014)
NOTE: Only versions marked as 'Release' are available on release folder, updates are only available as source.
NOTE: Current Release includes all previous updates.
-----------------------------------------------
Release: raylib 1.0.4 (23 January 2014)
-----------------------------------------------
[tool] Published a first alpha version of rREM tool (raylib Resource Embedder)
[core] GetRandomValue() - Bug corrected, now works right
[core] Fade() - Added, fades a color to an alpha percentadge
[core] WriteBitmap() - Moved to new module: utils.c, not used anymore
[core] TakeScreenshot() - Now uses WritePNG() (utils.c)
[utils] New module created with utility functions
[utils] WritePNG() - Write a PNG file (used by TakeScreenshot() on core)
[utils] DecompressData() - Added, used for rRES resource data decompresion
[textures] LoadImageFromRES() - Added, load an image from a rRES resource file
[textures] LoadTextureFromRES() - Added, load a texture from a rRES resource file
[audio] LoadSoundFromRES() - Added, load a sound from a rRES resource file
[audio] IsPlaying() - Added, check if a sound is currently playing
[audio] SetVolume() - Added, set the volume for a sound
[audio] SetPitch() - Added, set the pitch for a sound
[examples] ex06a_color_select completed
[examples] ex06b_logo_anim completed
[examples] ex06c_font select completed
-----------------------------------------------
Release: raylib 1.0.3 (19 December 2013)
-----------------------------------------------

View File

@ -3,7 +3,7 @@
about
-----
raylib is a simple and easy-to-use library to learn C videogames programming.
raylib is a simple and easy-to-use library to learn videogames programming.
raylib is highly inspired by Borland BGI graphics lib (more specifically WinBGI) and by XNA framework.
Allegro and SDL have also been analyzed for reference.
@ -80,7 +80,8 @@ raylib could be build with the following command lines (Using GCC compiler):
gcc -c models.c -std=c99 -Wall
gcc -c vector3.c -std=c99 -Wall
gcc -c audio.c -std=c99 -Wall
ar rcs raylib.a core.o shapes.o textures.o stb_image.o text.o models.o vector3.o audio.o
gcc -c utils.c -std=c99 -Wall
ar rcs raylib.a core.o shapes.o textures.o stb_image.o text.o models.o vector3.o utils.o audio.o
To compile examples, make sure raylib.h is placed in include path and libraries raylib (libraylib.a) and glfw3 (libglfw3.a)
are placed in the libraries path. It's also recommended to link with file icon.o for fancy raylib icon usage.

View File

@ -9,7 +9,7 @@ Around the source code there are some TODO points with pending revisions/bugs an
raylib v1.x
- Review Billboard Drawing functions
- Review Heightmap Loading and Drawing functions
- Review Heightmap Loading and Drawing functions - Load Heightmap directly as a Model
- Lighting support (only 3d mode) - CreateLight()
- [DONE] Simple Collision Detection functions
- Default scene Camera controls (zoom, pan, rotate)

View File

@ -1,8 +1,8 @@
/*********************************************************************************************
*
* raylib 1.0.3 (www.raylib.com)
* raylib 1.0.4 (www.raylib.com)
*
* A simple and easy-to-use library to learn C videogames programming
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
@ -16,13 +16,14 @@
* GLFW3 (www.glfw.org) for window/context management and input
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
* Some design decisions:
* 32bit Colors - All defined color are always RGBA
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
*
*
* -- LICENSE (raylib v1.0, November 2013) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
@ -236,29 +237,31 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
void InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
void CloseWindow(); // Close Window and Terminate Context
bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(); // Fullscreen toggle (by default F11)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, // Initialize Window and Graphics Context (OpenGL),...
bool resizable, const char *cursorImage); // ...define if windows-resizable and custom cursor
void CloseWindow(); // Close Window and Terminate Context
bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(); // Fullscreen toggle (by default F11)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(); // Returns current FPS
float GetFrameTime(); // Returns time in seconds for one frame
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(); // Returns current FPS
float GetFrameTime(); // Returns time in seconds for one frame
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
@ -317,15 +320,18 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
//Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps); // Load an image as texture (and convert to POT with mipmaps) (raylib 1.x)
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
float rotation, Color tint);
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
@ -334,7 +340,8 @@ SpriteFont GetDefaultFont();
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
int MeasureText(const char *text, int fontSize); // Measure string width for default font
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
@ -362,6 +369,7 @@ void DrawGizmo(Vector3 position, bool orbits);
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
@ -380,11 +388,15 @@ void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vect
void InitAudioDevice(); // Initialize audio device and context
void CloseAudioDevice(); // Close the audio device and context
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
void PlaySoundEx(Sound sound, float timePosition, bool loop); // Play a sound with extended parameters
void PauseSound(Sound sound); // Pause a sound
void StopSound(Sound sound); // Stop playing a sound
bool IsPlaying(Sound sound); // Check if a sound is currently playing
void SetVolume(Sound sound, float volume); // Set volume for a sound (1.0 is base level)
void SetPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
#ifdef __cplusplus
}

Binary file not shown.

View File

@ -35,6 +35,8 @@
#include <stdlib.h> // To use exit() function
#include <stdio.h> // Used for .WAV loading
#include "utils.h" // rRES data decompression utility function
//#include "stb_vorbis.h" // TODO: OGG loading functions
//----------------------------------------------------------------------------------
@ -52,8 +54,7 @@ typedef struct Wave {
unsigned int sampleRate;
unsigned int dataSize;
short bitsPerSample;
short channels;
short format;
short channels;
} Wave;
//----------------------------------------------------------------------------------
@ -179,6 +180,159 @@ Sound LoadSound(char *fileName)
return sound;
}
// Load sound to memory from rRES file (raylib Resource)
Sound LoadSoundFromRES(const char *rresName, int resId)
{
// NOTE: rresName could be directly a char array with all the data!!! --> TODO
Sound sound;
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) printf("Error opening raylib Resource file\n");
// 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'))
{
printf("This is not a valid raylib Resource file!\n");
exit(1);
}
// 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>
printf("Sample rate: %i\n", (int)sampleRate);
printf("Bits per sample: %i\n", (int)bps);
printf("Channels: %i\n", (int)channels);
wave.sampleRate = sampleRate;
wave.dataSize = infoHeader.srcSize;
wave.bitsPerSample = 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);
// Convert wave to Sound (OpenAL)
ALenum format;
// The OpenAL format is worked out by looking at the number of channels and the bits per sample
if (wave.channels == 1)
{
if (wave.bitsPerSample == 8 ) format = AL_FORMAT_MONO8;
else if (wave.bitsPerSample == 16) format = AL_FORMAT_MONO16;
}
else if (wave.channels == 2)
{
if (wave.bitsPerSample == 8 ) format = AL_FORMAT_STEREO8;
else if (wave.bitsPerSample == 16) format = AL_FORMAT_STEREO16;
}
// Create an audio source
ALuint source;
alGenSources(1, &source); // Generate pointer to audio source
alSourcef(source, AL_PITCH, 1);
alSourcef(source, AL_GAIN, 1);
alSource3f(source, AL_POSITION, 0, 0, 0);
alSource3f(source, AL_VELOCITY, 0, 0, 0);
alSourcei(source, AL_LOOPING, AL_FALSE);
// Convert loaded data to OpenAL buffer
//----------------------------------------
ALuint buffer;
alGenBuffers(1, &buffer); // Generate pointer to buffer
// Upload sound data to buffer
alBufferData(buffer, format, (void*)wave.data, wave.dataSize, wave.sampleRate);
// Attach sound buffer to source
alSourcei(source, AL_BUFFER, buffer);
// Unallocate WAV data
UnloadWAV(wave);
printf("Audio file loaded...!\n");
sound.source = source;
sound.buffer = buffer;
}
else
{
printf("Required resource do not seem to be a valid IMAGE resource\n");
exit(2);
}
}
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) printf("Required resource id could not be found in the raylib Resource file!\n");
return sound;
}
// Unload sound
void UnloadSound(Sound sound)
{
@ -197,10 +351,18 @@ void PlaySound(Sound sound)
// NOTE: Only work when the entire file is in a single buffer
//int byteOffset;
//alGetSourcei(sound.source, AL_BYTE_OFFSET, &byteOffset);
//
//int sampleRate;
//alGetBufferi(sound.buffer, AL_FREQUENCY, &sampleRate); // AL_CHANNELS, AL_BITS (bps)
//float seconds = (float)byteOffset / sampleRate; // Number of seconds since the beginning of the sound
//or
//float result;
//alGetSourcef(sound.source, AL_SEC_OFFSET, &result); // AL_SAMPLE_OFFSET
}
// Play a sound with extended options
// TODO: This function should be reviewed...
void PlaySoundEx(Sound sound, float timePosition, bool loop)
{
// TODO: Review
@ -227,6 +389,30 @@ void StopSound(Sound sound)
alSourceStop(sound.source);
}
// Check if a sound is playing
bool IsPlaying(Sound sound)
{
bool playing = false;
ALint state;
alGetSourcei(sound.source, AL_SOURCE_STATE, &state);
if (state == AL_PLAYING) playing = true;
return playing;
}
// Set volume for a sound
void SetVolume(Sound sound, float volume)
{
alSourcef(sound.source, AL_GAIN, volume);
}
// Set pitch for a sound
void SetPitch(Sound sound, float pitch)
{
alSourcef(sound.source, AL_PITCH, pitch);
}
// Load WAV file into Wave structure
static Wave LoadWAV(char *fileName)
{

View File

@ -35,6 +35,7 @@
#include <time.h> // Useful to initialize random seed
#include <math.h> // Math related functions, tan() on SetPerspective
#include "vector3.h" // Basic Vector3 functions
#include "utils.h" // WritePNG() function
//#define GLFW_DLL // Using GLFW DLL on Windows -> No, we use static version!
@ -81,7 +82,6 @@ static char currentGamepadState[32] = {0}; // Required to check if gamepad btn
//----------------------------------------------------------------------------------
extern void LoadDefaultFont(); // [Module: text] Loads default font on InitWindow()
extern void UnloadDefaultFont(); // [Module: text] Unloads default font from GPU memory
extern void WriteBitmap(const char *fileName, const pixel *imgDataPixel, int width, int height); // [Module: textures] Writes a bitmap (BMP) file
//----------------------------------------------------------------------------------
// Module specific Functions Declaration
@ -354,6 +354,15 @@ int GetRandomValue(int min, int max)
return (rand()%(abs(max-min)+1) + min);
}
// Fades color by a percentadge
Color Fade(Color color, float alpha)
{
if (alpha < 0.0) alpha = 0.0;
else if (alpha > 1.0) alpha = 1.0;
return (Color){color.r, color.g, color.b, color.a*alpha};
}
//----------------------------------------------------------------------------------
// Module Functions Definition - Input (Keyboard, Mouse, Gamepad) Functions
//----------------------------------------------------------------------------------
@ -737,21 +746,36 @@ static void TakeScreenshot()
char buffer[20]; // Buffer to store file name
int fbWidth, fbHeight;
Color *imgDataPixel; // Pixel image data array
unsigned char *imgData; // Pixel image data array
glfwGetFramebufferSize(window, &fbWidth, &fbHeight); // Get framebuffer size of current window
imgDataPixel = (Color *)malloc(fbWidth * fbHeight * sizeof(Color));
imgData = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
// NOTE: glReadPixels returns image flipped vertically -> (0,0) is the bottom left corner of the framebuffer
glReadPixels(0, 0, fbWidth, fbHeight, GL_RGBA, GL_UNSIGNED_BYTE, imgDataPixel);
glReadPixels(0, 0, fbWidth, fbHeight, GL_RGBA, GL_UNSIGNED_BYTE, imgData);
sprintf(buffer, "screenshot%03i.bmp", shotNum);
// TODO: Flip image vertically!
unsigned char *imgDataFlip = (unsigned char *)malloc(fbWidth * fbHeight * sizeof(unsigned char) * 4);
for (int y = fbHeight-1; y >= 0; y--)
{
for (int x = 0; x < (fbWidth*4); x++)
{
imgDataFlip[x + (fbHeight - y - 1)*fbWidth*4] = imgData[x + (y*fbWidth*4)];
}
}
free(imgData);
sprintf(buffer, "screenshot%03i.png", shotNum);
// NOTE: BMP directly stores data flipped vertically
WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
//WriteBitmap(buffer, imgDataPixel, fbWidth, fbHeight); // Writes pixel data array into a bitmap (BMP) file
WritePNG(buffer, imgDataFlip, fbWidth, fbHeight);
free(imgDataPixel);
free(imgDataFlip);
shotNum++;
}

View File

@ -1,8 +1,8 @@
/*********************************************************************************************
*
* raylib 1.0.3 (www.raylib.com)
* raylib 1.0.4 (www.raylib.com)
*
* A simple and easy-to-use library to learn C videogames programming
* A simple and easy-to-use library to learn videogames programming
*
* Features:
* Library written in plain C code (C99)
@ -16,13 +16,14 @@
* GLFW3 (www.glfw.org) for window/context management and input
* stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA, PSD, GIF, HDR, PIC)
* OpenAL Soft for audio device/context management
* tinfl for data decompression (DEFLATE algorithm)
*
* Some design decisions:
* 32bit Colors - All defined color are always RGBA
* 32bit Textures - All loaded images are converted automatically to RGBA textures
* SpriteFonts - All loaded sprite-font images are converted to RGBA and POT textures
* One custom default font is loaded automatically when InitWindow()
*
*
* -- LICENSE (raylib v1.0, November 2013) --
*
* raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified,
@ -236,29 +237,31 @@ extern "C" { // Prevents name mangling of functions
//------------------------------------------------------------------------------------
// Window and Graphics Device Functions (Module: core)
//------------------------------------------------------------------------------------
void InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, bool resizable, const char *cursorImage);
void CloseWindow(); // Close Window and Terminate Context
bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(); // Fullscreen toggle (by default F11)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void InitWindow(int width, int height, const char *title); // Initialize Window and Graphics Context (OpenGL)
void InitWindowEx(int width, int height, const char* title, // Initialize Window and Graphics Context (OpenGL),...
bool resizable, const char *cursorImage); // ...define if windows-resizable and custom cursor
void CloseWindow(); // Close Window and Terminate Context
bool WindowShouldClose(); // Detect if KEY_ESCAPE pressed or Close icon pressed
void ToggleFullscreen(); // Fullscreen toggle (by default F11)
void SetCustomCursor(const char *cursorImage); // Set a custom cursor icon/image
void SetExitKey(int key); // Set a custom key to exit program (default is ESC)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
void ClearBackground(Color color); // Sets Background Color
void BeginDrawing(); // Setup drawing canvas to start drawing
void EndDrawing(); // End canvas drawing and Swap Buffers (Double Buffering)
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
void Begin3dMode(Camera cam); // Initializes 3D mode for drawing (Camera setup)
void End3dMode(); // Ends 3D mode and returns to default 2D orthographic mode
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(); // Returns current FPS
float GetFrameTime(); // Returns time in seconds for one frame
void SetTargetFPS(int fps); // Set target FPS (maximum)
float GetFPS(); // Returns current FPS
float GetFrameTime(); // Returns time in seconds for one frame
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
Color GetColor(int hexValue); // Returns a Color struct from hexadecimal value
int GetHexValue(Color color); // Returns hexadecimal value for a Color
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
int GetRandomValue(int min, int max); // Returns a random value between min and max (both included)
Color Fade(Color color, float alpha); // Color fade-in or fade-out, alpha goes from 0.0 to 1.0
//------------------------------------------------------------------------------------
// Input Handling Functions (Module: core)
@ -317,15 +320,18 @@ bool CheckCollisionPointTriangle(Vector2 point, Vector2 p1, Vector2 p2, Vector2
// Texture Loading and Drawing Functions (Module: textures)
//------------------------------------------------------------------------------------
Image LoadImage(const char *fileName); // Load an image into CPU memory (RAM)
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
Image LoadImageFromRES(const char *rresName, int resId); // Load an image from rRES file (raylib Resource)
Texture2D LoadTexture(const char *fileName); // Load an image as texture into GPU memory
//Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps); // Load an image as texture (and convert to POT with mipmaps) (raylib 1.x)
Texture2D LoadTextureFromRES(const char *rresName, int resId); // Load an image as texture from rRES file (raylib Resource)
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
void UnloadImage(Image image); // Unload image from CPU memory (RAM)
void UnloadTexture(Texture2D texture); // Unload texture from GPU memory
void DrawTexture(Texture2D texture, int posX, int posY, Color tint); // Draw a Texture2D
void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); // Draw a Texture2D with extended parameters
void DrawTextureRec(Texture2D texture, Rectangle sourceRec, Vector2 position, Color tint); // Draw a part of a texture defined by a rectangle
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, float rotation, Color tint); // Draw a part of a texture defined by a rectangle with 'pro' parameters
Texture2D CreateTexture2D(Image image); // Create a Texture2D from Image data
void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, Vector2 origin, // Draw a part of a texture defined by a rectangle with 'pro' parameters
float rotation, Color tint);
//------------------------------------------------------------------------------------
// Font Loading and Text Drawing Functions (Module: text)
@ -334,7 +340,8 @@ SpriteFont GetDefaultFont();
SpriteFont LoadSpriteFont(const char *fileName); // Load a SpriteFont image into GPU memory
void UnloadSpriteFont(SpriteFont spriteFont); // Unload SpriteFont from GPU memory
void DrawText(const char *text, int posX, int posY, int fontSize, Color color); // Draw text (using default font)
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, int fontSize, int spacing, Color tint); // Draw text using SpriteFont
void DrawTextEx(SpriteFont spriteFont, const char* text, Vector2 position, // Draw text using SpriteFont and additional parameters
int fontSize, int spacing, Color tint);
int MeasureText(const char *text, int fontSize); // Measure string width for default font
Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, int fontSize, int spacing); // Measure string size for SpriteFont
int GetFontBaseSize(SpriteFont spriteFont); // Returns the base size for a SpriteFont (chars height)
@ -362,6 +369,7 @@ void DrawGizmo(Vector3 position, bool orbits);
// Model 3d Loading and Drawing Functions (Module: models)
//------------------------------------------------------------------------------------
Model LoadModel(const char *fileName); // Load a 3d model (.OBJ)
//Model LoadModelFromRES(const char *rresName, int resId); // TODO: Load a 3d model from rRES file (raylib Resource)
void UnloadModel(Model model); // Unload 3d model from memory
void DrawModel(Model model, Vector3 position, float scale, Color color); // Draw a model
void DrawModelEx(Model model, Texture2D texture, Vector3 position, float scale, Color tint); // Draw a textured model
@ -380,11 +388,15 @@ void DrawHeightmapEx(Image heightmap, Texture2D texture, Vector3 centerPos, Vect
void InitAudioDevice(); // Initialize audio device and context
void CloseAudioDevice(); // Close the audio device and context
Sound LoadSound(char *fileName); // Load sound to memory
Sound LoadSoundFromRES(const char *rresName, int resId); // Load sound to memory from rRES file (raylib Resource)
void UnloadSound(Sound sound); // Unload sound
void PlaySound(Sound sound); // Play a sound
void PlaySoundEx(Sound sound, float timePosition, bool loop); // Play a sound with extended parameters
void PauseSound(Sound sound); // Pause a sound
void StopSound(Sound sound); // Stop playing a sound
bool IsPlaying(Sound sound); // Check if a sound is currently playing
void SetVolume(Sound sound, float volume); // Set volume for a sound (1.0 is base level)
void SetPitch(Sound sound, float pitch); // Set pitch for a sound (1.0 is base level)
#ifdef __cplusplus
}

View File

@ -32,6 +32,8 @@
#include <stdlib.h> // Declares malloc() and free() for memory management
#include "stb_image.h" // Used to read image data (multiple formats support)
#include "utils.h" // rRES data decompression utility function
//----------------------------------------------------------------------------------
// Defines and Macros
//----------------------------------------------------------------------------------
@ -95,10 +97,121 @@ Image LoadImage(const char *fileName)
return image;
}
// Unload image from CPU memory (RAM)
void UnloadImage(Image image)
// Load an image from rRES file (raylib Resource)
Image LoadImageFromRES(const char *rresName, int resId)
{
free(image.pixels);
// NOTE: rresName could be directly a char array with all the data!!! ---> TODO!
Image image;
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) printf("Error opening raylib Resource file\n");
// 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'))
{
printf("This is not a valid raylib Resource file!\n");
exit(1);
}
// 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)
printf("Image width: %i\n", (int)imgWidth);
printf("Image height: %i\n", (int)imgHeight);
image.width = (int)imgWidth;
image.height = (int)imgHeight;
unsigned char *data = malloc(infoHeader.size);
fread(data, infoHeader.size, 1, rresFile);
unsigned char *imgData = DecompressData(data, infoHeader.size, infoHeader.srcSize);
image.pixels = (Color *)malloc(sizeof(Color)*imgWidth*imgHeight);
int pix = 0;
for (int i = 0; i < (imgWidth*imgHeight*4); i += 4)
{
image.pixels[pix].r = imgData[i];
image.pixels[pix].g = imgData[i+1];
image.pixels[pix].b = imgData[i+2];
image.pixels[pix].a = imgData[i+3];
pix++;
}
free(imgData);
free(data);
}
else
{
printf("Required resource do not seem to be a valid IMAGE resource\n");
exit(2);
}
}
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) printf("Required resource id could not be found in the raylib Resource file!\n");
return image;
}
// Load an image as texture into GPU memory
@ -140,6 +253,17 @@ Texture2D LoadTexture(const char *fileName)
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 = CreateTexture2D(image);
return texture;
}
// Load an image as texture (and convert to POT with mipmaps)
Texture2D LoadTextureEx(const char *fileName, bool createPOT, bool mipmaps)
{
@ -187,6 +311,12 @@ Texture2D CreateTexture2D(Image image)
return texture;
}
// Unload image from CPU memory (RAM)
void UnloadImage(Image image)
{
free(image.pixels);
}
// Unload texture from GPU memory
void UnloadTexture(Texture2D texture)
{
@ -299,47 +429,4 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V
glPopMatrix();
glDisable(GL_TEXTURE_2D); // Disable textures usage
}
// Creates a bitmap (BMP) file from an array of pixel data
// NOTE: This function is only used by module [core], not explicitly available to raylib users
extern void WriteBitmap(const char *fileName, const Color *imgDataPixel, int width, int height)
{
int filesize = 54 + 3*width*height;
unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
bmpFileHeader[2] = (unsigned char)(filesize);
bmpFileHeader[3] = (unsigned char)(filesize>>8);
bmpFileHeader[4] = (unsigned char)(filesize>>16);
bmpFileHeader[5] = (unsigned char)(filesize>>24);
bmpInfoHeader[4] = (unsigned char)(width);
bmpInfoHeader[5] = (unsigned char)(width>>8);
bmpInfoHeader[6] = (unsigned char)(width>>16);
bmpInfoHeader[7] = (unsigned char)(width>>24);
bmpInfoHeader[8] = (unsigned char)(height);
bmpInfoHeader[9] = (unsigned char)(height>>8);
bmpInfoHeader[10] = (unsigned char)(height>>16);
bmpInfoHeader[11] = (unsigned char)(height>>24);
FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
// NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
// Write pixel data to file
for (int y = 0; y < height ; y++)
{
for (int x = 0; x < width; x++)
{
fputc(imgDataPixel[x + y*width].b, bmpFile);
fputc(imgDataPixel[x + y*width].g, bmpFile);
fputc(imgDataPixel[x + y*width].r, bmpFile);
}
}
fclose(bmpFile); // Close bitmap file
}

592
src/tinfl.c Normal file
View File

@ -0,0 +1,592 @@
/* tinfl.c v1.11 - public domain inflate with zlib header parsing/adler32 checking (inflate-only subset of miniz.c)
See "unlicense" statement at the end of this file.
Rich Geldreich <richgel99@gmail.com>, last updated May 20, 2011
Implements RFC 1950: http://www.ietf.org/rfc/rfc1950.txt and RFC 1951: http://www.ietf.org/rfc/rfc1951.txt
The entire decompressor coroutine is implemented in tinfl_decompress(). The other functions are optional high-level helpers.
*/
#ifndef TINFL_HEADER_INCLUDED
#define TINFL_HEADER_INCLUDED
#include <stdlib.h>
typedef unsigned char mz_uint8;
typedef signed short mz_int16;
typedef unsigned short mz_uint16;
typedef unsigned int mz_uint32;
typedef unsigned int mz_uint;
typedef unsigned long long mz_uint64;
#if defined(_M_IX86) || defined(_M_X64)
// Set MINIZ_USE_UNALIGNED_LOADS_AND_STORES to 1 if integer loads and stores to unaligned addresses are acceptable on the target platform (slightly faster).
#define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 1
// Set MINIZ_LITTLE_ENDIAN to 1 if the processor is little endian.
#define MINIZ_LITTLE_ENDIAN 1
#endif
#if defined(_WIN64) || defined(__MINGW64__) || defined(_LP64) || defined(__LP64__)
// Set MINIZ_HAS_64BIT_REGISTERS to 1 if the processor has 64-bit general purpose registers (enables 64-bit bitbuffer in inflator)
#define MINIZ_HAS_64BIT_REGISTERS 1
#endif
// Works around MSVC's spammy "warning C4127: conditional expression is constant" message.
#ifdef _MSC_VER
#define MZ_MACRO_END while (0, 0)
#else
#define MZ_MACRO_END while (0)
#endif
// Decompression flags used by tinfl_decompress().
// TINFL_FLAG_PARSE_ZLIB_HEADER: If set, the input has a valid zlib header and ends with an adler32 checksum (it's a valid zlib stream). Otherwise, the input is a raw deflate stream.
// TINFL_FLAG_HAS_MORE_INPUT: If set, there are more input bytes available beyond the end of the supplied input buffer. If clear, the input buffer contains all remaining input.
// TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF: If set, the output buffer is large enough to hold the entire decompressed stream. If clear, the output buffer is at least the size of the dictionary (typically 32KB).
// TINFL_FLAG_COMPUTE_ADLER32: Force adler-32 checksum computation of the decompressed bytes.
enum
{
TINFL_FLAG_PARSE_ZLIB_HEADER = 1,
TINFL_FLAG_HAS_MORE_INPUT = 2,
TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF = 4,
TINFL_FLAG_COMPUTE_ADLER32 = 8
};
// High level decompression functions:
// tinfl_decompress_mem_to_heap() decompresses a block in memory to a heap block allocated via malloc().
// On entry:
// pSrc_buf, src_buf_len: Pointer and size of the Deflate or zlib source data to decompress.
// On return:
// Function returns a pointer to the decompressed data, or NULL on failure.
// *pOut_len will be set to the decompressed data's size, which could be larger than src_buf_len on uncompressible data.
// The caller must free() the returned block when it's no longer needed.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags);
// tinfl_decompress_mem_to_mem() decompresses a block in memory to another block in memory.
// Returns TINFL_DECOMPRESS_MEM_TO_MEM_FAILED on failure, or the number of bytes written on success.
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags);
// tinfl_decompress_mem_to_callback() decompresses a block in memory to an internal 32KB buffer, and a user provided callback function will be called to flush the buffer.
// Returns 1 on success or 0 on failure.
typedef int (*tinfl_put_buf_func_ptr)(const void* pBuf, int len, void *pUser);
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags);
struct tinfl_decompressor_tag; typedef struct tinfl_decompressor_tag tinfl_decompressor;
// Max size of LZ dictionary.
#define TINFL_LZ_DICT_SIZE 32768
// Return status.
typedef enum
{
TINFL_STATUS_BAD_PARAM = -3,
TINFL_STATUS_ADLER32_MISMATCH = -2,
TINFL_STATUS_FAILED = -1,
TINFL_STATUS_DONE = 0,
TINFL_STATUS_NEEDS_MORE_INPUT = 1,
TINFL_STATUS_HAS_MORE_OUTPUT = 2
} tinfl_status;
// Initializes the decompressor to its initial state.
#define tinfl_init(r) do { (r)->m_state = 0; } MZ_MACRO_END
#define tinfl_get_adler32(r) (r)->m_check_adler32
// Main low-level decompressor coroutine function. This is the only function actually needed for decompression. All the other functions are just high-level helpers for improved usability.
// This is a universal API, i.e. it can be used as a building block to build any desired higher level decompression API. In the limit case, it can be called once per every byte input or output.
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags);
// Internal/private bits follow.
enum
{
TINFL_MAX_HUFF_TABLES = 3, TINFL_MAX_HUFF_SYMBOLS_0 = 288, TINFL_MAX_HUFF_SYMBOLS_1 = 32, TINFL_MAX_HUFF_SYMBOLS_2 = 19,
TINFL_FAST_LOOKUP_BITS = 10, TINFL_FAST_LOOKUP_SIZE = 1 << TINFL_FAST_LOOKUP_BITS
};
typedef struct
{
mz_uint8 m_code_size[TINFL_MAX_HUFF_SYMBOLS_0];
mz_int16 m_look_up[TINFL_FAST_LOOKUP_SIZE], m_tree[TINFL_MAX_HUFF_SYMBOLS_0 * 2];
} tinfl_huff_table;
#if MINIZ_HAS_64BIT_REGISTERS
#define TINFL_USE_64BIT_BITBUF 1
#endif
#if TINFL_USE_64BIT_BITBUF
typedef mz_uint64 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (64)
#else
typedef mz_uint32 tinfl_bit_buf_t;
#define TINFL_BITBUF_SIZE (32)
#endif
struct tinfl_decompressor_tag
{
mz_uint32 m_state, m_num_bits, m_zhdr0, m_zhdr1, m_z_adler32, m_final, m_type, m_check_adler32, m_dist, m_counter, m_num_extra, m_table_sizes[TINFL_MAX_HUFF_TABLES];
tinfl_bit_buf_t m_bit_buf;
size_t m_dist_from_out_buf_start;
tinfl_huff_table m_tables[TINFL_MAX_HUFF_TABLES];
mz_uint8 m_raw_header[4], m_len_codes[TINFL_MAX_HUFF_SYMBOLS_0 + TINFL_MAX_HUFF_SYMBOLS_1 + 137];
};
#endif // #ifdef TINFL_HEADER_INCLUDED
// ------------------- End of Header: Implementation follows. (If you only want the header, define MINIZ_HEADER_FILE_ONLY.)
#ifndef TINFL_HEADER_FILE_ONLY
#include <string.h>
// MZ_MALLOC, etc. are only used by the optional high-level helper functions.
#ifdef MINIZ_NO_MALLOC
#define MZ_MALLOC(x) NULL
#define MZ_FREE(x) x, ((void)0)
#define MZ_REALLOC(p, x) NULL
#else
#define MZ_MALLOC(x) malloc(x)
#define MZ_FREE(x) free(x)
#define MZ_REALLOC(p, x) realloc(p, x)
#endif
#define MZ_MAX(a,b) (((a)>(b))?(a):(b))
#define MZ_MIN(a,b) (((a)<(b))?(a):(b))
#define MZ_CLEAR_OBJ(obj) memset(&(obj), 0, sizeof(obj))
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES && MINIZ_LITTLE_ENDIAN
#define MZ_READ_LE16(p) *((const mz_uint16 *)(p))
#define MZ_READ_LE32(p) *((const mz_uint32 *)(p))
#else
#define MZ_READ_LE16(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U))
#define MZ_READ_LE32(p) ((mz_uint32)(((const mz_uint8 *)(p))[0]) | ((mz_uint32)(((const mz_uint8 *)(p))[1]) << 8U) | ((mz_uint32)(((const mz_uint8 *)(p))[2]) << 16U) | ((mz_uint32)(((const mz_uint8 *)(p))[3]) << 24U))
#endif
#define TINFL_MEMCPY(d, s, l) memcpy(d, s, l)
#define TINFL_MEMSET(p, c, l) memset(p, c, l)
#define TINFL_CR_BEGIN switch(r->m_state) { case 0:
#define TINFL_CR_RETURN(state_index, result) do { status = result; r->m_state = state_index; goto common_exit; case state_index:; } MZ_MACRO_END
#define TINFL_CR_RETURN_FOREVER(state_index, result) do { for ( ; ; ) { TINFL_CR_RETURN(state_index, result); } } MZ_MACRO_END
#define TINFL_CR_FINISH }
// TODO: If the caller has indicated that there's no more input, and we attempt to read beyond the input buf, then something is wrong with the input because the inflator never
// reads ahead more than it needs to. Currently TINFL_GET_BYTE() pads the end of the stream with 0's in this scenario.
#define TINFL_GET_BYTE(state_index, c) do { \
if (pIn_buf_cur >= pIn_buf_end) { \
for ( ; ; ) { \
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT) { \
TINFL_CR_RETURN(state_index, TINFL_STATUS_NEEDS_MORE_INPUT); \
if (pIn_buf_cur < pIn_buf_end) { \
c = *pIn_buf_cur++; \
break; \
} \
} else { \
c = 0; \
break; \
} \
} \
} else c = *pIn_buf_cur++; } MZ_MACRO_END
#define TINFL_NEED_BITS(state_index, n) do { mz_uint c; TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; } while (num_bits < (mz_uint)(n))
#define TINFL_SKIP_BITS(state_index, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
#define TINFL_GET_BITS(state_index, b, n) do { if (num_bits < (mz_uint)(n)) { TINFL_NEED_BITS(state_index, n); } b = bit_buf & ((1 << (n)) - 1); bit_buf >>= (n); num_bits -= (n); } MZ_MACRO_END
// TINFL_HUFF_BITBUF_FILL() is only used rarely, when the number of bytes remaining in the input buffer falls below 2.
// It reads just enough bytes from the input stream that are needed to decode the next Huffman code (and absolutely no more). It works by trying to fully decode a
// Huffman code by using whatever bits are currently present in the bit buffer. If this fails, it reads another byte, and tries again until it succeeds or until the
// bit buffer contains >=15 bits (deflate's max. Huffman code size).
#define TINFL_HUFF_BITBUF_FILL(state_index, pHuff) \
do { \
temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]; \
if (temp >= 0) { \
code_len = temp >> 9; \
if ((code_len) && (num_bits >= code_len)) \
break; \
} else if (num_bits > TINFL_FAST_LOOKUP_BITS) { \
code_len = TINFL_FAST_LOOKUP_BITS; \
do { \
temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; \
} while ((temp < 0) && (num_bits >= (code_len + 1))); if (temp >= 0) break; \
} TINFL_GET_BYTE(state_index, c); bit_buf |= (((tinfl_bit_buf_t)c) << num_bits); num_bits += 8; \
} while (num_bits < 15);
// TINFL_HUFF_DECODE() decodes the next Huffman coded symbol. It's more complex than you would initially expect because the zlib API expects the decompressor to never read
// beyond the final byte of the deflate stream. (In other words, when this macro wants to read another byte from the input, it REALLY needs another byte in order to fully
// decode the next Huffman code.) Handling this properly is particularly important on raw deflate (non-zlib) streams, which aren't followed by a byte aligned adler-32.
// The slow path is only executed at the very end of the input buffer.
#define TINFL_HUFF_DECODE(state_index, sym, pHuff) do { \
int temp; mz_uint code_len, c; \
if (num_bits < 15) { \
if ((pIn_buf_end - pIn_buf_cur) < 2) { \
TINFL_HUFF_BITBUF_FILL(state_index, pHuff); \
} else { \
bit_buf |= (((tinfl_bit_buf_t)pIn_buf_cur[0]) << num_bits) | (((tinfl_bit_buf_t)pIn_buf_cur[1]) << (num_bits + 8)); pIn_buf_cur += 2; num_bits += 16; \
} \
} \
if ((temp = (pHuff)->m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0) \
code_len = temp >> 9, temp &= 511; \
else { \
code_len = TINFL_FAST_LOOKUP_BITS; do { temp = (pHuff)->m_tree[~temp + ((bit_buf >> code_len++) & 1)]; } while (temp < 0); \
} sym = temp; bit_buf >>= code_len; num_bits -= code_len; } MZ_MACRO_END
tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_next, size_t *pIn_buf_size, mz_uint8 *pOut_buf_start, mz_uint8 *pOut_buf_next, size_t *pOut_buf_size, const mz_uint32 decomp_flags)
{
static const int s_length_base[31] = { 3,4,5,6,7,8,9,10,11,13, 15,17,19,23,27,31,35,43,51,59, 67,83,99,115,131,163,195,227,258,0,0 };
static const int s_length_extra[31]= { 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 };
static const int s_dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, 257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0};
static const int s_dist_extra[32] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
static const mz_uint8 s_length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 };
static const int s_min_table_sizes[3] = { 257, 1, 4 };
tinfl_status status = TINFL_STATUS_FAILED; mz_uint32 num_bits, dist, counter, num_extra; tinfl_bit_buf_t bit_buf;
const mz_uint8 *pIn_buf_cur = pIn_buf_next, *const pIn_buf_end = pIn_buf_next + *pIn_buf_size;
mz_uint8 *pOut_buf_cur = pOut_buf_next, *const pOut_buf_end = pOut_buf_next + *pOut_buf_size;
size_t out_buf_size_mask = (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF) ? (size_t)-1 : ((pOut_buf_next - pOut_buf_start) + *pOut_buf_size) - 1, dist_from_out_buf_start;
// Ensure the output buffer's size is a power of 2, unless the output buffer is large enough to hold the entire output file (in which case it doesn't matter).
if (((out_buf_size_mask + 1) & out_buf_size_mask) || (pOut_buf_next < pOut_buf_start)) { *pIn_buf_size = *pOut_buf_size = 0; return TINFL_STATUS_BAD_PARAM; }
num_bits = r->m_num_bits; bit_buf = r->m_bit_buf; dist = r->m_dist; counter = r->m_counter; num_extra = r->m_num_extra; dist_from_out_buf_start = r->m_dist_from_out_buf_start;
TINFL_CR_BEGIN
bit_buf = num_bits = dist = counter = num_extra = r->m_zhdr0 = r->m_zhdr1 = 0; r->m_z_adler32 = r->m_check_adler32 = 1;
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_GET_BYTE(1, r->m_zhdr0); TINFL_GET_BYTE(2, r->m_zhdr1);
counter = (((r->m_zhdr0 * 256 + r->m_zhdr1) % 31 != 0) || (r->m_zhdr1 & 32) || ((r->m_zhdr0 & 15) != 8));
if (!(decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)) counter |= (((1U << (8U + (r->m_zhdr0 >> 4))) > 32768U) || ((out_buf_size_mask + 1) < (size_t)(1U << (8U + (r->m_zhdr0 >> 4)))));
if (counter) { TINFL_CR_RETURN_FOREVER(36, TINFL_STATUS_FAILED); }
}
do
{
TINFL_GET_BITS(3, r->m_final, 3); r->m_type = r->m_final >> 1;
if (r->m_type == 0)
{
TINFL_SKIP_BITS(5, num_bits & 7);
for (counter = 0; counter < 4; ++counter) { if (num_bits) TINFL_GET_BITS(6, r->m_raw_header[counter], 8); else TINFL_GET_BYTE(7, r->m_raw_header[counter]); }
if ((counter = (r->m_raw_header[0] | (r->m_raw_header[1] << 8))) != (mz_uint)(0xFFFF ^ (r->m_raw_header[2] | (r->m_raw_header[3] << 8)))) { TINFL_CR_RETURN_FOREVER(39, TINFL_STATUS_FAILED); }
while ((counter) && (num_bits))
{
TINFL_GET_BITS(51, dist, 8);
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(52, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)dist;
counter--;
}
while (counter)
{
size_t n; while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(9, TINFL_STATUS_HAS_MORE_OUTPUT); }
while (pIn_buf_cur >= pIn_buf_end)
{
if (decomp_flags & TINFL_FLAG_HAS_MORE_INPUT)
{
TINFL_CR_RETURN(38, TINFL_STATUS_NEEDS_MORE_INPUT);
}
else
{
TINFL_CR_RETURN_FOREVER(40, TINFL_STATUS_FAILED);
}
}
n = MZ_MIN(MZ_MIN((size_t)(pOut_buf_end - pOut_buf_cur), (size_t)(pIn_buf_end - pIn_buf_cur)), counter);
TINFL_MEMCPY(pOut_buf_cur, pIn_buf_cur, n); pIn_buf_cur += n; pOut_buf_cur += n; counter -= (mz_uint)n;
}
}
else if (r->m_type == 3)
{
TINFL_CR_RETURN_FOREVER(10, TINFL_STATUS_FAILED);
}
else
{
if (r->m_type == 1)
{
mz_uint8 *p = r->m_tables[0].m_code_size; mz_uint i;
r->m_table_sizes[0] = 288; r->m_table_sizes[1] = 32; TINFL_MEMSET(r->m_tables[1].m_code_size, 5, 32);
for ( i = 0; i <= 143; ++i) *p++ = 8; for ( ; i <= 255; ++i) *p++ = 9; for ( ; i <= 279; ++i) *p++ = 7; for ( ; i <= 287; ++i) *p++ = 8;
}
else
{
for (counter = 0; counter < 3; counter++) { TINFL_GET_BITS(11, r->m_table_sizes[counter], "\05\05\04"[counter]); r->m_table_sizes[counter] += s_min_table_sizes[counter]; }
MZ_CLEAR_OBJ(r->m_tables[2].m_code_size); for (counter = 0; counter < r->m_table_sizes[2]; counter++) { mz_uint s; TINFL_GET_BITS(14, s, 3); r->m_tables[2].m_code_size[s_length_dezigzag[counter]] = (mz_uint8)s; }
r->m_table_sizes[2] = 19;
}
for ( ; (int)r->m_type >= 0; r->m_type--)
{
int tree_next, tree_cur; tinfl_huff_table *pTable;
mz_uint i, j, used_syms, total, sym_index, next_code[17], total_syms[16]; pTable = &r->m_tables[r->m_type]; MZ_CLEAR_OBJ(total_syms); MZ_CLEAR_OBJ(pTable->m_look_up); MZ_CLEAR_OBJ(pTable->m_tree);
for (i = 0; i < r->m_table_sizes[r->m_type]; ++i) total_syms[pTable->m_code_size[i]]++;
used_syms = 0, total = 0; next_code[0] = next_code[1] = 0;
for (i = 1; i <= 15; ++i) { used_syms += total_syms[i]; next_code[i + 1] = (total = ((total + total_syms[i]) << 1)); }
if ((65536 != total) && (used_syms > 1))
{
TINFL_CR_RETURN_FOREVER(35, TINFL_STATUS_FAILED);
}
for (tree_next = -1, sym_index = 0; sym_index < r->m_table_sizes[r->m_type]; ++sym_index)
{
mz_uint rev_code = 0, l, cur_code, code_size = pTable->m_code_size[sym_index]; if (!code_size) continue;
cur_code = next_code[code_size]++; for (l = code_size; l > 0; l--, cur_code >>= 1) rev_code = (rev_code << 1) | (cur_code & 1);
if (code_size <= TINFL_FAST_LOOKUP_BITS) { mz_int16 k = (mz_int16)((code_size << 9) | sym_index); while (rev_code < TINFL_FAST_LOOKUP_SIZE) { pTable->m_look_up[rev_code] = k; rev_code += (1 << code_size); } continue; }
if (0 == (tree_cur = pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)])) { pTable->m_look_up[rev_code & (TINFL_FAST_LOOKUP_SIZE - 1)] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; }
rev_code >>= (TINFL_FAST_LOOKUP_BITS - 1);
for (j = code_size; j > (TINFL_FAST_LOOKUP_BITS + 1); j--)
{
tree_cur -= ((rev_code >>= 1) & 1);
if (!pTable->m_tree[-tree_cur - 1]) { pTable->m_tree[-tree_cur - 1] = (mz_int16)tree_next; tree_cur = tree_next; tree_next -= 2; } else tree_cur = pTable->m_tree[-tree_cur - 1];
}
tree_cur -= ((rev_code >>= 1) & 1); pTable->m_tree[-tree_cur - 1] = (mz_int16)sym_index;
}
if (r->m_type == 2)
{
for (counter = 0; counter < (r->m_table_sizes[0] + r->m_table_sizes[1]); )
{
mz_uint s; TINFL_HUFF_DECODE(16, dist, &r->m_tables[2]); if (dist < 16) { r->m_len_codes[counter++] = (mz_uint8)dist; continue; }
if ((dist == 16) && (!counter))
{
TINFL_CR_RETURN_FOREVER(17, TINFL_STATUS_FAILED);
}
num_extra = "\02\03\07"[dist - 16]; TINFL_GET_BITS(18, s, num_extra); s += "\03\03\013"[dist - 16];
TINFL_MEMSET(r->m_len_codes + counter, (dist == 16) ? r->m_len_codes[counter - 1] : 0, s); counter += s;
}
if ((r->m_table_sizes[0] + r->m_table_sizes[1]) != counter)
{
TINFL_CR_RETURN_FOREVER(21, TINFL_STATUS_FAILED);
}
TINFL_MEMCPY(r->m_tables[0].m_code_size, r->m_len_codes, r->m_table_sizes[0]); TINFL_MEMCPY(r->m_tables[1].m_code_size, r->m_len_codes + r->m_table_sizes[0], r->m_table_sizes[1]);
}
}
for ( ; ; )
{
mz_uint8 *pSrc;
for ( ; ; )
{
if (((pIn_buf_end - pIn_buf_cur) < 4) || ((pOut_buf_end - pOut_buf_cur) < 2))
{
TINFL_HUFF_DECODE(23, counter, &r->m_tables[0]);
if (counter >= 256)
break;
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(24, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = (mz_uint8)counter;
}
else
{
int sym2; mz_uint code_len;
#if TINFL_USE_64BIT_BITBUF
if (num_bits < 30) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE32(pIn_buf_cur)) << num_bits); pIn_buf_cur += 4; num_bits += 32; }
#else
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
counter = sym2; bit_buf >>= code_len; num_bits -= code_len;
if (counter & 256)
break;
#if !TINFL_USE_64BIT_BITBUF
if (num_bits < 15) { bit_buf |= (((tinfl_bit_buf_t)MZ_READ_LE16(pIn_buf_cur)) << num_bits); pIn_buf_cur += 2; num_bits += 16; }
#endif
if ((sym2 = r->m_tables[0].m_look_up[bit_buf & (TINFL_FAST_LOOKUP_SIZE - 1)]) >= 0)
code_len = sym2 >> 9;
else
{
code_len = TINFL_FAST_LOOKUP_BITS; do { sym2 = r->m_tables[0].m_tree[~sym2 + ((bit_buf >> code_len++) & 1)]; } while (sym2 < 0);
}
bit_buf >>= code_len; num_bits -= code_len;
pOut_buf_cur[0] = (mz_uint8)counter;
if (sym2 & 256)
{
pOut_buf_cur++;
counter = sym2;
break;
}
pOut_buf_cur[1] = (mz_uint8)sym2;
pOut_buf_cur += 2;
}
}
if ((counter &= 511) == 256) break;
num_extra = s_length_extra[counter - 257]; counter = s_length_base[counter - 257];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(25, extra_bits, num_extra); counter += extra_bits; }
TINFL_HUFF_DECODE(26, dist, &r->m_tables[1]);
num_extra = s_dist_extra[dist]; dist = s_dist_base[dist];
if (num_extra) { mz_uint extra_bits; TINFL_GET_BITS(27, extra_bits, num_extra); dist += extra_bits; }
dist_from_out_buf_start = pOut_buf_cur - pOut_buf_start;
if ((dist > dist_from_out_buf_start) && (decomp_flags & TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF))
{
TINFL_CR_RETURN_FOREVER(37, TINFL_STATUS_FAILED);
}
pSrc = pOut_buf_start + ((dist_from_out_buf_start - dist) & out_buf_size_mask);
if ((MZ_MAX(pOut_buf_cur, pSrc) + counter) > pOut_buf_end)
{
while (counter--)
{
while (pOut_buf_cur >= pOut_buf_end) { TINFL_CR_RETURN(53, TINFL_STATUS_HAS_MORE_OUTPUT); }
*pOut_buf_cur++ = pOut_buf_start[(dist_from_out_buf_start++ - dist) & out_buf_size_mask];
}
continue;
}
#if MINIZ_USE_UNALIGNED_LOADS_AND_STORES
else if ((counter >= 9) && (counter <= dist))
{
const mz_uint8 *pSrc_end = pSrc + (counter & ~7);
do
{
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
pOut_buf_cur += 8;
} while ((pSrc += 8) < pSrc_end);
if ((counter &= 7) < 3)
{
if (counter)
{
pOut_buf_cur[0] = pSrc[0];
if (counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
continue;
}
}
#endif
do
{
pOut_buf_cur[0] = pSrc[0];
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur[2] = pSrc[2];
pOut_buf_cur += 3; pSrc += 3;
} while ((int)(counter -= 3) > 2);
if ((int)counter > 0)
{
pOut_buf_cur[0] = pSrc[0];
if ((int)counter > 1)
pOut_buf_cur[1] = pSrc[1];
pOut_buf_cur += counter;
}
}
}
} while (!(r->m_final & 1));
if (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER)
{
TINFL_SKIP_BITS(32, num_bits & 7); for (counter = 0; counter < 4; ++counter) { mz_uint s; if (num_bits) TINFL_GET_BITS(41, s, 8); else TINFL_GET_BYTE(42, s); r->m_z_adler32 = (r->m_z_adler32 << 8) | s; }
}
TINFL_CR_RETURN_FOREVER(34, TINFL_STATUS_DONE);
TINFL_CR_FINISH
common_exit:
r->m_num_bits = num_bits; r->m_bit_buf = bit_buf; r->m_dist = dist; r->m_counter = counter; r->m_num_extra = num_extra; r->m_dist_from_out_buf_start = dist_from_out_buf_start;
*pIn_buf_size = pIn_buf_cur - pIn_buf_next; *pOut_buf_size = pOut_buf_cur - pOut_buf_next;
if ((decomp_flags & (TINFL_FLAG_PARSE_ZLIB_HEADER | TINFL_FLAG_COMPUTE_ADLER32)) && (status >= 0))
{
const mz_uint8 *ptr = pOut_buf_next; size_t buf_len = *pOut_buf_size;
mz_uint32 i, s1 = r->m_check_adler32 & 0xffff, s2 = r->m_check_adler32 >> 16; size_t block_len = buf_len % 5552;
while (buf_len)
{
for (i = 0; i + 7 < block_len; i += 8, ptr += 8)
{
s1 += ptr[0], s2 += s1; s1 += ptr[1], s2 += s1; s1 += ptr[2], s2 += s1; s1 += ptr[3], s2 += s1;
s1 += ptr[4], s2 += s1; s1 += ptr[5], s2 += s1; s1 += ptr[6], s2 += s1; s1 += ptr[7], s2 += s1;
}
for ( ; i < block_len; ++i) s1 += *ptr++, s2 += s1;
s1 %= 65521U, s2 %= 65521U; buf_len -= block_len; block_len = 5552;
}
r->m_check_adler32 = (s2 << 16) + s1; if ((status == TINFL_STATUS_DONE) && (decomp_flags & TINFL_FLAG_PARSE_ZLIB_HEADER) && (r->m_check_adler32 != r->m_z_adler32)) status = TINFL_STATUS_ADLER32_MISMATCH;
}
return status;
}
// Higher level helper functions.
void *tinfl_decompress_mem_to_heap(const void *pSrc_buf, size_t src_buf_len, size_t *pOut_len, int flags)
{
tinfl_decompressor decomp; void *pBuf = NULL, *pNew_buf; size_t src_buf_ofs = 0, out_buf_capacity = 0;
*pOut_len = 0;
tinfl_init(&decomp);
for ( ; ; )
{
size_t src_buf_size = src_buf_len - src_buf_ofs, dst_buf_size = out_buf_capacity - *pOut_len, new_out_buf_capacity;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf + src_buf_ofs, &src_buf_size, (mz_uint8*)pBuf, pBuf ? (mz_uint8*)pBuf + *pOut_len : NULL, &dst_buf_size,
(flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
if ((status < 0) || (status == TINFL_STATUS_NEEDS_MORE_INPUT))
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
src_buf_ofs += src_buf_size;
*pOut_len += dst_buf_size;
if (status == TINFL_STATUS_DONE) break;
new_out_buf_capacity = out_buf_capacity * 2; if (new_out_buf_capacity < 128) new_out_buf_capacity = 128;
pNew_buf = MZ_REALLOC(pBuf, new_out_buf_capacity);
if (!pNew_buf)
{
MZ_FREE(pBuf); *pOut_len = 0; return NULL;
}
pBuf = pNew_buf; out_buf_capacity = new_out_buf_capacity;
}
return pBuf;
}
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len, const void *pSrc_buf, size_t src_buf_len, int flags)
{
tinfl_decompressor decomp; tinfl_status status; tinfl_init(&decomp);
status = tinfl_decompress(&decomp, (const mz_uint8*)pSrc_buf, &src_buf_len, (mz_uint8*)pOut_buf, (mz_uint8*)pOut_buf, &out_buf_len, (flags & ~TINFL_FLAG_HAS_MORE_INPUT) | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF);
return (status != TINFL_STATUS_DONE) ? TINFL_DECOMPRESS_MEM_TO_MEM_FAILED : out_buf_len;
}
int tinfl_decompress_mem_to_callback(const void *pIn_buf, size_t *pIn_buf_size, tinfl_put_buf_func_ptr pPut_buf_func, void *pPut_buf_user, int flags)
{
int result = 0;
tinfl_decompressor decomp;
mz_uint8 *pDict = (mz_uint8*)MZ_MALLOC(TINFL_LZ_DICT_SIZE); size_t in_buf_ofs = 0, dict_ofs = 0;
if (!pDict)
return TINFL_STATUS_FAILED;
tinfl_init(&decomp);
for ( ; ; )
{
size_t in_buf_size = *pIn_buf_size - in_buf_ofs, dst_buf_size = TINFL_LZ_DICT_SIZE - dict_ofs;
tinfl_status status = tinfl_decompress(&decomp, (const mz_uint8*)pIn_buf + in_buf_ofs, &in_buf_size, pDict, pDict + dict_ofs, &dst_buf_size,
(flags & ~(TINFL_FLAG_HAS_MORE_INPUT | TINFL_FLAG_USING_NON_WRAPPING_OUTPUT_BUF)));
in_buf_ofs += in_buf_size;
if ((dst_buf_size) && (!(*pPut_buf_func)(pDict + dict_ofs, (int)dst_buf_size, pPut_buf_user)))
break;
if (status != TINFL_STATUS_HAS_MORE_OUTPUT)
{
result = (status == TINFL_STATUS_DONE);
break;
}
dict_ofs = (dict_ofs + dst_buf_size) & (TINFL_LZ_DICT_SIZE - 1);
}
MZ_FREE(pDict);
*pIn_buf_size = in_buf_ofs;
return result;
}
#endif // #ifndef TINFL_HEADER_FILE_ONLY
/*
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <http://unlicense.org/>
*/

127
src/utils.c Normal file
View File

@ -0,0 +1,127 @@
/*********************************************************************************************
*
* raylib.utils
*
* Utils Functions Definitions
*
* Uses external lib:
* tinfl - zlib DEFLATE algorithm decompression lib
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#include "utils.h"
#include <stdlib.h> // malloc(), free()
#include <stdio.h> // printf()
//#include <string.h> // String management functions: strlen(), strrchr(), strcmp()
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.h" // Create PNG file
#include "tinfl.c"
// 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)
{
printf("Out of memory!\n");
return NULL;
}
// Decompress data
tempUncompSize = tinfl_decompress_mem_to_mem(pUncomp, (size_t)uncompSize, data, compSize, 1);
if (tempUncompSize == -1)
{
printf("Decompression failed!\n");
free(pUncomp);
return NULL;
}
if (uncompSize != (int)tempUncompSize)
{
printf("WARNING! Expected uncompressed size do not match! Data may be corrupted!\n");
printf(" -- Expected uncompressed size: %i\n", uncompSize);
printf(" -- Returned uncompressed size: %i\n", tempUncompSize);
}
printf("Decompressed from %u bytes to %u bytes\n", (mz_uint32)compSize, (mz_uint32)tempUncompSize);
return pUncomp;
}
// Creates a bitmap (BMP) file from an array of pixel data
// NOTE: This function is not explicitly available to raylib users
void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int height)
{
int filesize = 54 + 3*width*height;
unsigned char bmpFileHeader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0}; // Standard BMP file header
unsigned char bmpInfoHeader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0}; // Standard BMP info header
bmpFileHeader[2] = (unsigned char)(filesize);
bmpFileHeader[3] = (unsigned char)(filesize>>8);
bmpFileHeader[4] = (unsigned char)(filesize>>16);
bmpFileHeader[5] = (unsigned char)(filesize>>24);
bmpInfoHeader[4] = (unsigned char)(width);
bmpInfoHeader[5] = (unsigned char)(width>>8);
bmpInfoHeader[6] = (unsigned char)(width>>16);
bmpInfoHeader[7] = (unsigned char)(width>>24);
bmpInfoHeader[8] = (unsigned char)(height);
bmpInfoHeader[9] = (unsigned char)(height>>8);
bmpInfoHeader[10] = (unsigned char)(height>>16);
bmpInfoHeader[11] = (unsigned char)(height>>24);
FILE *bmpFile = fopen(fileName, "wb"); // Define a pointer to bitmap file and open it in write-binary mode
// NOTE: fwrite parameters are: data pointer, size in bytes of each element to be written, number of elements, file-to-write pointer
fwrite(bmpFileHeader, sizeof(unsigned char), 14, bmpFile); // Write BMP file header data
fwrite(bmpInfoHeader, sizeof(unsigned char), 40, bmpFile); // Write BMP info header data
// Write pixel data to file
for (int y = 0; y < height ; y++)
{
for (int x = 0; x < width; x++)
{
fputc(imgData[(x*4)+2 + (y*width*4)], bmpFile);
fputc(imgData[(x*4)+1 + (y*width*4)], bmpFile);
fputc(imgData[(x*4) + (y*width*4)], bmpFile);
}
}
fclose(bmpFile); // Close bitmap file
}
// Creates a PNG image file from an array of pixel data
// NOTE: Uses stb_image_write
void WritePNG(const char *fileName, unsigned char *imgData, int width, int height)
{
stbi_write_png(fileName, width, height, 4, imgData, width*4); // It WORKS!!!
}

71
src/utils.h Normal file
View File

@ -0,0 +1,71 @@
/*********************************************************************************************
*
* raylib.utils
*
* Some utility functions: rRES files data decompression
*
* Uses external lib:
* tinfl - zlib DEFLATE algorithm decompression lib
*
* Copyright (c) 2013 Ramon Santamaria (Ray San - raysan@raysanweb.com)
*
* This software is provided "as-is", without any express or implied warranty. In no event
* will the authors be held liable for any damages arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose, including commercial
* applications, and to alter it and redistribute it freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not claim that you
* wrote the original software. If you use this software in a product, an acknowledgment
* in the product documentation would be appreciated but is not required.
*
* 2. Altered source versions must be plainly marked as such, and must not be misrepresented
* as being the original software.
*
* 3. This notice may not be removed or altered from any source distribution.
*
**********************************************************************************************/
#ifndef UTILS_H
#define UTILS_H
//----------------------------------------------------------------------------------
// Some basic Defines
//----------------------------------------------------------------------------------
//...
//----------------------------------------------------------------------------------
// Types and Structures Definition
//----------------------------------------------------------------------------------
typedef enum { IMAGE, SOUND, MODEL, TEXT, RAW } DataType;
// One resource info header, every resource includes this header (8 byte)
typedef struct {
unsigned short id; // Resource unique identifier (2 byte)
unsigned char type; // Resource type (1 byte)
unsigned char comp; // Data Compression and Coding (1 byte)
unsigned int size; // Data size in .rres file (compressed or not, only DATA) (4 byte)
unsigned int srcSize; // Source data size (uncompressed, only DATA)
} ResInfoHeader;
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions
#endif
//----------------------------------------------------------------------------------
// Global Variables Definition
//----------------------------------------------------------------------------------
// Nop...
//----------------------------------------------------------------------------------
// Module Functions Declaration
//----------------------------------------------------------------------------------
unsigned char *DecompressData(const unsigned char *data, unsigned long compSize, int uncompSize);
void WriteBitmap(const char *fileName, unsigned char *imgData, int width, int height);
void WritePNG(const char *fileName, unsigned char *imgData, int width, int height);
#ifdef __cplusplus
}
#endif
#endif // UTILS_H

View File

@ -26,7 +26,7 @@
#ifndef VECTOR3_H
#define VECTOR3_H
#include "raylib.h" // Defines Vector3 structure
#include "raylib.h" // Defines Vector3 structure
#ifdef __cplusplus
extern "C" { // Prevents name mangling of functions

36
tools/README.txt Normal file
View File

@ -0,0 +1,36 @@
/**********************************************************************************************
*
* rREM - raylib Resource Embedder 1.0.0 (alpha)
*
* Tool to embed resources (images, text, sounds, models...) into a rRES file.
*
* Copyright 2014 Ramon Santamaria. All rights reserved.
*
***********************************************************************************************/
rrem creates a .rres resource with embedded files and a .h header to access embedded data
Usage example:
1) Create 'resources.rres' and 'resources.h' including 3 files:
rrem image01.png image02.jpg sound03.wav
2) In your raylib program, just add at top:
#include "resources.h"
3) When a resource is required, just load it using:
Texture2D mytex = LoadTextureFromRES("resources.rres", RES_image01);
Sound mysound = LoadSoundFromRES("resources.rres", RES_sound03);
Note that you can check resources id names in resources.h file
Have fun! :)

BIN
tools/rrem.exe Normal file

Binary file not shown.