2048 game saving state

This commit is contained in:
nakst 2021-09-09 16:40:51 +01:00
parent 72c8bbe4f7
commit e9592f46c0
6 changed files with 51 additions and 12 deletions

View File

@ -16,7 +16,7 @@
#define TILE_BOUNDS(x, y) ES_RECT_4PD(mainArea.l + TILE_GAP * (x + 1) + TILE_SIZE * x, mainArea.t + TILE_GAP * (y + 1) + TILE_SIZE * y, TILE_SIZE, TILE_SIZE)
#define SETTINGS_FILE "|Settings:/Default.ini"
#define SETTINGS_FILE "|Settings:/Default.dat"
struct AnimatingTile {
float sourceOpacity, targetOpacity;
@ -44,7 +44,6 @@ size_t animatingTileCount;
float animationTimeMs;
uint8_t grid[TILE_COUNT][TILE_COUNT];
uintptr_t currentTileCount;
int32_t score, highScore;
EsInstance *instance;
@ -54,7 +53,9 @@ EsTextDisplay *scoreDisplay, *highScoreDisplay;
void SaveConfiguration() {
EsBuffer buffer = {};
buffer.canGrow = true;
EsBufferFormat(&buffer, "high_score=%d\n", highScore);
EsBufferWriteInt32Endian(&buffer, highScore);
EsBufferWriteInt32Endian(&buffer, score);
EsBufferWrite(&buffer, grid, sizeof(grid));
EsFileWriteAll(EsLiteral(SETTINGS_FILE), buffer.out, buffer.position);
EsHeapFree(buffer.out);
}
@ -141,7 +142,17 @@ bool MoveTiles(intptr_t dx, intptr_t dy, bool speculative) {
}
void SpawnTile() {
if (currentTileCount == TILE_COUNT * TILE_COUNT) {
bool full = true;
for (uintptr_t i = 0; i < TILE_COUNT; i++) {
for (uintptr_t j = 0; j < TILE_COUNT; j++) {
if (!grid[i][j]) {
full = false;
}
}
}
if (full) {
// The grid is full.
return;
}
@ -188,9 +199,10 @@ void Update(intptr_t dx, intptr_t dy) {
if (!MoveTiles(dx, dy, false)) {
return;
}
SpawnTile();
}
SpawnTile();
EsElementStartAnimating(gameArea);
if (score > highScore) {
@ -324,9 +336,11 @@ int InfoPanelMessage(EsElement *element, EsMessage *message) {
void NewGameCommand(EsInstance *, EsElement *, EsCommand *) {
SaveConfiguration();
EsElementStartTransition(gameArea, ES_TRANSITION_SLIDE_UP);
EsMemoryZero(grid, sizeof(grid));
score = 0;
Update(0, 0);
SpawnTile();
EsElementFocus(gameArea);
}
@ -370,13 +384,14 @@ void ProcessApplicationMessage(EsMessage *message) {
void _start() {
_init();
EsINIState state = { (char *) EsFileReadAll(EsLiteral(SETTINGS_FILE), &state.bytes) };
while (EsINIParse(&state)) {
if (0 == EsStringCompareRaw(state.key, state.keyBytes, EsLiteral("high_score"))) {
highScore = EsIntegerParse(state.value, state.valueBytes);
}
}
EsBuffer buffer = {};
uint8_t *settings = (uint8_t *) EsFileReadAll(EsLiteral(SETTINGS_FILE), &buffer.bytes);
buffer.in = settings;
highScore = EsBufferReadInt32Endian(&buffer, 0);
score = EsBufferReadInt32Endian(&buffer, 0);
EsBufferReadInto(&buffer, grid, sizeof(grid));
EsHeapFree(settings);
if (!settings) SpawnTile();
while (true) {
ProcessApplicationMessage(EsMessageReceive());

View File

@ -1,6 +1,7 @@
[general]
name=2048
icon=icon_applications_other
use_single_instance=1
[build]
source=apps/2048.cpp

View File

@ -1655,6 +1655,7 @@ void ConfigurationLoadApplications() {
application->iconID = EsIconIDFromString(icon);
EsHeapFree(icon);
application->useSingleProcess = EsSystemConfigurationGroupReadInteger(group, EsLiteral("use_single_process"), true);
application->useSingleInstance = EsSystemConfigurationGroupReadInteger(group, EsLiteral("use_single_instance"), true);
application->hidden = EsSystemConfigurationGroupReadInteger(group, EsLiteral("hidden"), false);
application->id = EsIntegerParse(group->section, group->sectionBytes);

View File

@ -1978,7 +1978,9 @@ function void EsArenaInitialise(EsArena *arena, size_t blockSize, size_t itemSiz
function const void *EsBufferRead(struct EsBuffer *buffer, size_t readBytes);
function bool EsBufferReadInto(struct EsBuffer *buffer, void *destination, size_t readBytes);
function const void *EsBufferReadMany(struct EsBuffer *buffer, size_t a, size_t b);
function int32_t EsBufferReadInt32Endian(EsBuffer *buffer, int32_t errorValue);
function void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writeBytes);
function bool EsBufferWriteInt32Endian(EsBuffer *buffer, int32_t value); // Changes byte order if big endian.
function void EsBufferFormat(EsBuffer *buffer, EsCString format, ...); // Appends.
function void EsBufferFormatV(EsBuffer *buffer, EsCString format, va_list arguments); // Appends.
function void EsBufferFlushToFileStore(EsBuffer *buffer);

View File

@ -2677,4 +2677,22 @@ void *EsBufferWrite(EsBuffer *buffer, const void *source, size_t writeBytes) {
}
}
bool EsBufferWriteInt32Endian(EsBuffer *buffer, int32_t value) {
#ifdef __BIG_ENDIAN__
value = ByteSwap32(value);
#endif
EsBufferWrite(buffer, &value, sizeof(int32_t));
return buffer->error;
}
int32_t EsBufferReadInt32Endian(EsBuffer *buffer, int32_t errorValue) {
int32_t *pointer = (int32_t *) EsBufferRead(buffer, sizeof(int32_t));
if (!pointer) return errorValue;
#ifdef __BIG_ENDIAN__
return ByteSwap32(*pointer);
#else
return *pointer;
#endif
}
#endif

View File

@ -442,3 +442,5 @@ EsRectangleLinearInterpolate=440
EsDrawRoundedRectangle=441
EsDrawTextSimple=442
EsColorInterpolate=443
EsBufferReadInt32Endian=444
EsBufferWriteInt32Endian=445