Преглед на файлове

REDESIGN: LoadStorageValue()/SaveStorageValue()

Using new file I/O ABI
pull/1113/head
Ray преди 5 години
родител
ревизия
23bde477e5
променени са 4 файла, в които са добавени 68 реда и са изтрити 50 реда
  1. +8
    -5
      examples/core/core_storage_values.c
  2. +2
    -0
      src/config.h
  3. +52
    -44
      src/core.c
  4. +6
    -1
      src/utils.c

+ 8
- 5
examples/core/core_storage_values.c Целия файл

@ -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_HISCORE, hiscore);
SaveStorageValue(STORAGE_POSITION_SCORE, score);
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);
hiscore = LoadStorageValue(STORAGE_HISCORE);
score = LoadStorageValue(STORAGE_POSITION_SCORE);
hiscore = LoadStorageValue(STORAGE_POSITION_HISCORE);
} }
framesCounter++; framesCounter++;

+ 2
- 0
src/config.h Целия файл

@ -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

+ 52
- 44
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
storageFile = fopen(path, "rb+");
// If file doesn't exist, create a new storage data file
if (!storageFile) storageFile = fopen(path, "wb");
if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be created");
else
int dataSize = 0;
unsigned char *fileData = LoadFileData(path, &dataSize);
if (fileData != NULL)
{ {
// Get file size
fseek(storageFile, 0, SEEK_END);
int fileSize = ftell(storageFile); // Size in bytes
fseek(storageFile, 0, SEEK_SET);
if (fileSize < (position*sizeof(int))) TRACELOG(LOG_WARNING, "Storage position could not be found");
if (dataSize <= (position*sizeof(int)))
{
// Increase data size up to position and store value
dataSize = (position + 1)*sizeof(int);
fileData = (unsigned char *)RL_REALLOC(fileData, dataSize);
int *dataPtr = (int *)fileData;
dataPtr[position] = value;
}
else else
{ {
fseek(storageFile, (position*sizeof(int)), SEEK_SET);
fwrite(&value, 1, sizeof(int), storageFile);
// Replace value on selected position
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
FILE *storageFile = fopen(path, "rb");
if (!storageFile) TRACELOG(LOG_WARNING, "Storage data file could not be found");
else
int dataSize = 0;
unsigned char *fileData = LoadFileData(path, &dataSize);
if (fileData != NULL)
{ {
// Get file size
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");
if (dataSize < (position*4)) TRACELOG(LOG_WARNING, "Storage position could not be found");
else else
{ {
n">fseek(storageFile, (position*4), SEEK_SET);
fread(&value, 4, 1, storageFile); // Read 1 element of 4 bytes size
int *dataPtr = (int *)fileData;
value = dataPtr[position];
} }
fclose(storageFile);
RL_FREE(fileData);
} }
#endif
return value; return value;
} }

+ 6
- 1
src/utils.c Целия файл

@ -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);

Зареждане…
Отказ
Запис