storage values
There is no browser build of this example yet.
Is it the same as C?
- Desktop:verified The Zig version renders a final frame that is byte-identical to the C example.
- Browser:not checked yet The browser comparison does not cover this example yet.
//! raylib [core] example - storage values
//!
//! Zig-API translation of examples/core/core_storage_values.c (raylib 6.2).
//! Example licensed under an unmodified zlib/libpng license.
//! Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
const std = @import("std");
const rl = @import("raylib");
const storage_data_file = "storage.data"; // Storage file
/// NOTE: Storage positions must start with 0, directly related to file memory layout
const StorageData = enum(u32) {
score = 0,
hiscore = 1,
};
pub fn main(init: std.process.Init) void {
const gpa = init.gpa;
// Initialization
const screen_width = 800;
const screen_height = 450;
rl.initWindow(screen_width, screen_height, "raylib [core] example - storage values");
defer rl.closeWindow(); // Close window and OpenGL context
var score: i32 = 0;
var hiscore: i32 = 0;
var frames_counter: i32 = 0;
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
// Main game loop
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
// Update
if (rl.isKeyPressed(.r)) {
score = rl.getRandomValue(1000, 2000);
hiscore = rl.getRandomValue(2000, 4000);
}
if (rl.isKeyPressed(.enter)) {
saveStorageValue(gpa, .score, score) catch |err| logSaveError(err);
saveStorageValue(gpa, .hiscore, hiscore) catch |err| logSaveError(err);
} else if (rl.isKeyPressed(.space)) {
// NOTE: If requested position could not be found, value 0 is returned
score = loadStorageValue(.score);
hiscore = loadStorageValue(.hiscore);
}
frames_counter += 1;
// Draw
rl.beginDrawing();
defer rl.endDrawing();
rl.clearBackground(.ray_white);
rl.drawText(rl.textFormat("SCORE: {d}", .{score}), 280, 130, 40, .maroon);
rl.drawText(rl.textFormat("HI-SCORE: {d}", .{hiscore}), 210, 200, 50, .black);
rl.drawText(rl.textFormat("frames: {d}", .{frames_counter}), 10, 10, 20, .lime);
rl.drawText("Press R to generate random numbers", 220, 40, 20, .light_gray);
rl.drawText("Press ENTER to SAVE values", 250, 310, 20, .light_gray);
rl.drawText("Press SPACE to LOAD values", 252, 350, 20, .light_gray);
}
}
fn logSaveError(err: anyerror) void {
rl.traceLog(.warning, "FILEIO: [{s}] Failed to save storage value: {s}", .{ storage_data_file, @errorName(err) });
}
/// Save integer value to storage file (to defined position)
/// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
fn saveStorageValue(gpa: std.mem.Allocator, position: StorageData, value: i32) !void {
const offset = @backingInt(position) * @sizeOf(i32);
// Start from the current file contents (if any), grown up to the requested position
const old_data: []const u8 = rl.loadFileData(storage_data_file) catch blk: {
rl.traceLog(.info, "FILEIO: [{s}] File created successfully", .{storage_data_file});
break :blk &.{};
};
defer if (old_data.len > 0) rl.unloadFileData(@constCast(old_data));
const data = try gpa.alloc(u8, @max(old_data.len, offset + @sizeOf(i32)));
defer gpa.free(data);
@memset(data, 0);
@memcpy(data[0..old_data.len], old_data);
// Replace value on selected position
std.mem.writeInt(i32, data[offset..][0..@sizeOf(i32)], value, .native);
if (!rl.saveFileData(storage_data_file, data)) return error.SaveFailed;
rl.traceLog(.info, "FILEIO: [{s}] Saved storage value: {d}", .{ storage_data_file, value });
}
/// Load integer value from storage file (from defined position)
/// NOTE: If requested position could not be found, value 0 is returned
fn loadStorageValue(position: StorageData) i32 {
const offset = @backingInt(position) * @sizeOf(i32);
const data = rl.loadFileData(storage_data_file) catch return 0;
defer rl.unloadFileData(data);
const value: i32 = if (data.len < offset + @sizeOf(i32)) blk: {
rl.traceLog(.warning, "FILEIO: [{s}] Failed to find storage position: {d}", .{ storage_data_file, @backingInt(position) });
break :blk 0;
} else std.mem.readInt(i32, data[offset..][0..@sizeOf(i32)], .native);
rl.traceLog(.info, "FILEIO: [{s}] Loaded storage value: {d}", .{ storage_data_file, value });
return value;
}/*******************************************************************************************
*
* raylib [core] example - storage values
*
* Example complexity rating: [★★☆☆] 2/4
*
* Example originally created with raylib 1.4, last time updated with raylib 4.2
*
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
* BSD-like license that allows static linking with closed source software
*
* Copyright (c) 2015-2025 Ramon Santamaria (@raysan5)
*
********************************************************************************************/
#include "raylib.h"
#include <stdlib.h> // Required for: calloc(), free()
#define STORAGE_DATA_FILE "storage.data" // Storage file
// NOTE: Storage positions must start with 0, directly related to file memory layout
typedef enum {
STORAGE_POSITION_SCORE = 0,
STORAGE_POSITION_HISCORE = 1
} StorageData;
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
static bool SaveStorageValue(unsigned int position, int value);
static int LoadStorageValue(unsigned int position);
//------------------------------------------------------------------------------------
// Program main entry point
//------------------------------------------------------------------------------------
int main(void)
{
// Initialization
//--------------------------------------------------------------------------------------
const int screenWidth = 800;
const int screenHeight = 450;
InitWindow(screenWidth, screenHeight, "raylib [core] example - storage values");
int score = 0;
int hiscore = 0;
int framesCounter = 0;
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//--------------------------------------------------------------------------------------
// Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
{
// Update
//----------------------------------------------------------------------------------
if (IsKeyPressed(KEY_R))
{
score = GetRandomValue(1000, 2000);
hiscore = GetRandomValue(2000, 4000);
}
if (IsKeyPressed(KEY_ENTER))
{
SaveStorageValue(STORAGE_POSITION_SCORE, score);
SaveStorageValue(STORAGE_POSITION_HISCORE, hiscore);
}
else if (IsKeyPressed(KEY_SPACE))
{
// NOTE: If requested position could not be found, value 0 is returned
score = LoadStorageValue(STORAGE_POSITION_SCORE);
hiscore = LoadStorageValue(STORAGE_POSITION_HISCORE);
}
framesCounter++;
//----------------------------------------------------------------------------------
// Draw
//----------------------------------------------------------------------------------
BeginDrawing();
ClearBackground(RAYWHITE);
DrawText(TextFormat("SCORE: %i", score), 280, 130, 40, MAROON);
DrawText(TextFormat("HI-SCORE: %i", hiscore), 210, 200, 50, BLACK);
DrawText(TextFormat("frames: %i", framesCounter), 10, 10, 20, LIME);
DrawText("Press R to generate random numbers", 220, 40, 20, LIGHTGRAY);
DrawText("Press ENTER to SAVE values", 250, 310, 20, LIGHTGRAY);
DrawText("Press SPACE to LOAD values", 252, 350, 20, LIGHTGRAY);
EndDrawing();
//----------------------------------------------------------------------------------
}
// De-Initialization
//--------------------------------------------------------------------------------------
CloseWindow(); // Close window and OpenGL context
//--------------------------------------------------------------------------------------
return 0;
}
//------------------------------------------------------------------------------------
// Module Functions Declaration
//------------------------------------------------------------------------------------
// Save integer value to storage file (to defined position)
// NOTE: Storage positions is directly related to file memory layout (4 bytes each integer)
bool SaveStorageValue(unsigned int position, int value)
{
bool success = false;
int dataSize = 0;
unsigned int newDataSize = 0;
unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize);
unsigned char *newFileData = NULL;
if (fileData != NULL)
{
if (dataSize <= (position*sizeof(int)))
{
// Increase data size up to position and store value
newDataSize = (position + 1)*sizeof(int);
newFileData = (unsigned char *)RL_REALLOC(fileData, newDataSize);
if (newFileData != NULL)
{
// RL_REALLOC succeded
int *dataPtr = (int *)newFileData;
dataPtr[position] = value;
}
else
{
// RL_REALLOC failed
TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to realloc data (%u), position in bytes (%u) bigger than actual file size", STORAGE_DATA_FILE, dataSize, position*sizeof(int));
// We store the old size of the file
newFileData = fileData;
newDataSize = dataSize;
}
}
else
{
// Store the old size of the file
newFileData = fileData;
newDataSize = dataSize;
// Replace value on selected position
int *dataPtr = (int *)newFileData;
dataPtr[position] = value;
}
success = SaveFileData(STORAGE_DATA_FILE, newFileData, newDataSize);
RL_FREE(newFileData);
TraceLog(LOG_INFO, "FILEIO: [%s] Saved storage value: %i", STORAGE_DATA_FILE, value);
}
else
{
TraceLog(LOG_INFO, "FILEIO: [%s] File created successfully", STORAGE_DATA_FILE);
dataSize = (position + 1)*sizeof(int);
fileData = (unsigned char *)RL_MALLOC(dataSize);
int *dataPtr = (int *)fileData;
dataPtr[position] = value;
success = SaveFileData(STORAGE_DATA_FILE, fileData, dataSize);
UnloadFileData(fileData);
TraceLog(LOG_INFO, "FILEIO: [%s] Saved storage value: %i", STORAGE_DATA_FILE, value);
}
return success;
}
// Load integer value from storage file (from defined position)
// NOTE: If requested position could not be found, value 0 is returned
int LoadStorageValue(unsigned int position)
{
int value = 0;
int dataSize = 0;
unsigned char *fileData = LoadFileData(STORAGE_DATA_FILE, &dataSize);
if (fileData != NULL)
{
if (dataSize < ((int)(position*4))) TraceLog(LOG_WARNING, "FILEIO: [%s] Failed to find storage position: %i", STORAGE_DATA_FILE, position);
else
{
int *dataPtr = (int *)fileData;
value = dataPtr[position];
}
UnloadFileData(fileData);
TraceLog(LOG_INFO, "FILEIO: [%s] Loaded storage value: %i", STORAGE_DATA_FILE, value);
}
return value;
}From raylib 6.2. The original on GitHub.