REDESIGN: LoadStorageValue()/SaveStorageValue()
Using new file I/O ABI
This commit is contained in:
parent
2294947660
commit
23bde477e5
4 changed files with 68 additions and 50 deletions
|
@ -12,7 +12,10 @@
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
// NOTE: Storage positions must start with 0, directly related to file memory layout
|
// NOTE: Storage positions must start with 0, directly related to file memory layout
|
||||||
typedef enum { STORAGE_SCORE = 0, STORAGE_HISCORE } StorageData;
|
typedef enum {
|
||||||
|
STORAGE_POSITION_SCORE = 0,
|
||||||
|
STORAGE_POSITION_HISCORE = 1
|
||||||
|
} StorageData;
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
|
@ -43,14 +46,14 @@ int main(void)
|
||||||
|
|
||||||
if (IsKeyPressed(KEY_ENTER))
|
if (IsKeyPressed(KEY_ENTER))
|
||||||
{
|
{
|
||||||
SaveStorageValue(STORAGE_SCORE, score);
|
SaveStorageValue(STORAGE_POSITION_SCORE, score);
|
||||||
SaveStorageValue(STORAGE_HISCORE, hiscore);
|
SaveStorageValue(STORAGE_POSITION_HISCORE, hiscore);
|
||||||
}
|
}
|
||||||
else if (IsKeyPressed(KEY_SPACE))
|
else if (IsKeyPressed(KEY_SPACE))
|
||||||
{
|
{
|
||||||
// NOTE: If requested position could not be found, value 0 is returned
|
// NOTE: If requested position could not be found, value 0 is returned
|
||||||
score = LoadStorageValue(STORAGE_SCORE);
|
score = LoadStorageValue(STORAGE_POSITION_SCORE);
|
||||||
hiscore = LoadStorageValue(STORAGE_HISCORE);
|
hiscore = LoadStorageValue(STORAGE_POSITION_HISCORE);
|
||||||
}
|
}
|
||||||
|
|
||||||
framesCounter++;
|
framesCounter++;
|
||||||
|
|
|
@ -60,6 +60,8 @@
|
||||||
//#define SUPPORT_HIGH_DPI 1
|
//#define SUPPORT_HIGH_DPI 1
|
||||||
// Support CompressData() and DecompressData() functions
|
// Support CompressData() and DecompressData() functions
|
||||||
#define SUPPORT_COMPRESSION_API 1
|
#define SUPPORT_COMPRESSION_API 1
|
||||||
|
#define SUPPORT_DATA_STORAGE 1
|
||||||
|
// Support saving binary data automatically to a generated storage.data file. This file is managed internally.
|
||||||
|
|
||||||
//------------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------------
|
||||||
// Module: rlgl - Configuration Flags
|
// Module: rlgl - Configuration Flags
|
||||||
|
|
96
src/core.c
96
src/core.c
|
@ -82,6 +82,9 @@
|
||||||
* provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module
|
* provided by stb_image and stb_image_write libraries, so, those libraries must be enabled on textures module
|
||||||
* for linkage
|
* for linkage
|
||||||
*
|
*
|
||||||
|
* #define SUPPORT_DATA_STORAGE
|
||||||
|
* Support saving binary data automatically to a generated storage.data file. This file is managed internally.
|
||||||
|
*
|
||||||
* DEPENDENCIES:
|
* DEPENDENCIES:
|
||||||
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly)
|
* rglfw - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX. FreeBSD, OpenBSD, NetBSD, DragonFly)
|
||||||
* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
|
* raymath - 3D math functionality (Vector2, Vector3, Matrix, Quaternion)
|
||||||
|
@ -152,7 +155,6 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
#include <stdlib.h> // Required for: srand(), rand(), atexit()
|
||||||
#include <stdio.h> // Required for: FILE, fopen(), fseek(), fread(), fwrite(), fclose() [Used in SaveStorageValue()/LoadStorageValue()]
|
|
||||||
#include <string.h> // Required for: strrchr(), strcmp(), strlen()
|
#include <string.h> // Required for: strrchr(), strcmp(), strlen()
|
||||||
#include <time.h> // Required for: time() [Used in InitTimer()]
|
#include <time.h> // Required for: time() [Used in InitTimer()]
|
||||||
#include <math.h> // Required for: tan() [Used in BeginMode3D()]
|
#include <math.h> // Required for: tan() [Used in BeginMode3D()]
|
||||||
|
@ -283,12 +285,14 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_GAMEPADS 4 // Max number of gamepads supported
|
#define MAX_GAMEPADS 4 // Max number of gamepads supported
|
||||||
#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
|
|
||||||
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
|
#define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad)
|
||||||
|
#define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad)
|
||||||
|
|
||||||
#define MAX_CHARS_QUEUE 16 // Max number of characters in the input queue
|
#define MAX_CHARS_QUEUE 16 // Max number of characters in the input queue
|
||||||
|
|
||||||
#define STORAGE_FILENAME "storage.data"
|
#if defined(SUPPORT_DATA_STORAGE)
|
||||||
|
#define STORAGE_DATA_FILE "storage.data"
|
||||||
|
#endif
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------
|
||||||
// Types and Structures Definition
|
// Types and Structures Definition
|
||||||
|
@ -2182,40 +2186,50 @@ unsigned char *DecompressData(unsigned char *compData, int compDataLength, int *
|
||||||
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
|
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
|
||||||
void SaveStorageValue(int position, int value)
|
void SaveStorageValue(int position, int value)
|
||||||
{
|
{
|
||||||
FILE *storageFile = NULL;
|
#if defined(SUPPORT_DATA_STORAGE)
|
||||||
|
|
||||||
char path[512] = { 0 };
|
char path[512] = { 0 };
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
strcpy(path, CORE.Android.internalDataPath);
|
strcpy(path, CORE.Android.internalDataPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, STORAGE_FILENAME);
|
strcat(path, STORAGE_DATA_FILE);
|
||||||
#else
|
#else
|
||||||
strcpy(path, STORAGE_FILENAME);
|
strcpy(path, STORAGE_DATA_FILE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try open existing file to append data
|
int dataSize = 0;
|
||||||
storageFile = fopen(path, "rb+");
|
unsigned char *fileData = LoadFileData(path, &dataSize);
|
||||||
|
|
||||||
// If file doesn't exist, create a new storage data file
|
if (fileData != NULL)
|
||||||
if (!storageFile) storageFile = fopen(path, "wb");
|
|
||||||
|
|
||||||
if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be created");
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Get file size
|
if (dataSize <= (position*sizeof(int)))
|
||||||
fseek(storageFile, 0, SEEK_END);
|
{
|
||||||
int fileSize = ftell(storageFile); // Size in bytes
|
// Increase data size up to position and store value
|
||||||
fseek(storageFile, 0, SEEK_SET);
|
dataSize = (position + 1)*sizeof(int);
|
||||||
|
fileData = (unsigned char *)RL_REALLOC(fileData, dataSize);
|
||||||
if (fileSize < (position*sizeof(int))) TRACELOG(LOG_WARNING, "Storage position could not be found");
|
int *dataPtr = (int *)fileData;
|
||||||
|
dataPtr[position] = value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fseek(storageFile, (position*sizeof(int)), SEEK_SET);
|
// Replace value on selected position
|
||||||
fwrite(&value, 1, sizeof(int), storageFile);
|
int *dataPtr = (int *)fileData;
|
||||||
|
dataPtr[position] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(storageFile);
|
SaveFileData(path, fileData, dataSize);
|
||||||
|
RL_FREE(fileData);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dataSize = (position + 1)*sizeof(int);
|
||||||
|
fileData = (unsigned char *)RL_MALLOC(dataSize);
|
||||||
|
int *dataPtr = (int *)fileData;
|
||||||
|
dataPtr[position] = value;
|
||||||
|
|
||||||
|
SaveFileData(path, fileData, dataSize);
|
||||||
|
RL_FREE(fileData);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load integer value from storage file (from defined position)
|
// Load integer value from storage file (from defined position)
|
||||||
|
@ -2223,37 +2237,31 @@ void SaveStorageValue(int position, int value)
|
||||||
int LoadStorageValue(int position)
|
int LoadStorageValue(int position)
|
||||||
{
|
{
|
||||||
int value = 0;
|
int value = 0;
|
||||||
|
#if defined(SUPPORT_DATA_STORAGE)
|
||||||
char path[512] = { 0 };
|
char path[512] = { 0 };
|
||||||
#if defined(PLATFORM_ANDROID)
|
#if defined(PLATFORM_ANDROID)
|
||||||
strcpy(path, CORE.Android.internalDataPath);
|
strcpy(path, CORE.Android.internalDataPath);
|
||||||
strcat(path, "/");
|
strcat(path, "/");
|
||||||
strcat(path, STORAGE_FILENAME);
|
strcat(path, STORAGE_DATA_FILE);
|
||||||
#else
|
#else
|
||||||
strcpy(path, STORAGE_FILENAME);
|
strcpy(path, STORAGE_DATA_FILE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Try open existing file to append data
|
int dataSize = 0;
|
||||||
FILE *storageFile = fopen(path, "rb");
|
unsigned char *fileData = LoadFileData(path, &dataSize);
|
||||||
|
|
||||||
if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be found");
|
if (fileData != NULL)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Get file size
|
if (dataSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found");
|
||||||
fseek(storageFile, 0, SEEK_END);
|
|
||||||
int fileSize = ftell(storageFile); // Size in bytes
|
|
||||||
fseek(storageFile, 0, SEEK_SET); // Reset file pointer
|
|
||||||
|
|
||||||
if (fileSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found");
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
fseek(storageFile, (position*4), SEEK_SET);
|
int *dataPtr = (int *)fileData;
|
||||||
fread(&value, 4, 1, storageFile); // Read 1 element of 4 bytes size
|
value = dataPtr[position];
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(storageFile);
|
RL_FREE(fileData);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -173,6 +173,8 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead)
|
||||||
|
|
||||||
if (file != NULL)
|
if (file != NULL)
|
||||||
{
|
{
|
||||||
|
// WARNING: On binary streams SEEK_END could not be found,
|
||||||
|
// using fseek() and ftell() could not work in some (rare) cases
|
||||||
fseek(file, 0, SEEK_END);
|
fseek(file, 0, SEEK_END);
|
||||||
int size = ftell(file);
|
int size = ftell(file);
|
||||||
fseek(file, 0, SEEK_SET);
|
fseek(file, 0, SEEK_SET);
|
||||||
|
@ -180,10 +182,13 @@ unsigned char *LoadFileData(const char *fileName, int *bytesRead)
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
{
|
{
|
||||||
data = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*size);
|
data = (unsigned char *)RL_MALLOC(sizeof(unsigned char)*size);
|
||||||
|
|
||||||
|
// NOTE: fread() returns number of read elements instead of bytes, so we read [1 byte, size elements]
|
||||||
int count = fread(data, sizeof(unsigned char), size, file);
|
int count = fread(data, sizeof(unsigned char), size, file);
|
||||||
*bytesRead = count;
|
*bytesRead = count;
|
||||||
|
|
||||||
if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially read", fileName);
|
if (count != size) TRACELOG(LOG_WARNING, "[%s] File partially loaded", fileName);
|
||||||
|
else TRACELOG(LOG_INFO, "[%s] File loaded successfully", fileName);
|
||||||
}
|
}
|
||||||
else TRACELOG(LOG_WARNING, "[%s] File could not be read", fileName);
|
else TRACELOG(LOG_WARNING, "[%s] File could not be read", fileName);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue