feat(gui): add toolbar widget

feat(gui): add grid_select, toggle, panel, status_bar, image widgets
fix(bsp): fill in exterior cells
This commit is contained in:
asrael 2026-02-27 06:50:49 -06:00
parent 5a565844dd
commit 8d491612ab
63 changed files with 3150 additions and 1686 deletions

View file

@ -1,24 +1,16 @@
#include "pxl8_save.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#ifdef _WIN32
#include <direct.h>
#include <shlobj.h>
#define PATH_SEP '\\'
#else
#include <unistd.h>
#include <pwd.h>
#define PATH_SEP '/'
#endif
#include "pxl8_io.h"
#include "pxl8_log.h"
#include "pxl8_macros.h"
#include "pxl8_mem.h"
#define PATH_SEP '/'
typedef struct {
u32 magic;
u32 version;
@ -49,23 +41,6 @@ static void pxl8_save_get_slot_path(pxl8_save* save, u8 slot, char* path, usize
}
}
static pxl8_result pxl8_save_ensure_directory(const char* path) {
struct stat st;
if (stat(path, &st) == 0) {
return S_ISDIR(st.st_mode) ? PXL8_OK : PXL8_ERROR_SYSTEM_FAILURE;
}
#ifdef _WIN32
if (_mkdir(path) != 0 && errno != EEXIST) {
#else
if (mkdir(path, 0755) != 0 && errno != EEXIST) {
#endif
return PXL8_ERROR_SYSTEM_FAILURE;
}
return PXL8_OK;
}
pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
if (!game_name) return NULL;
@ -75,40 +50,17 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
save->magic = magic;
save->version = version;
char base_dir[PXL8_SAVE_MAX_PATH];
#ifdef _WIN32
if (SUCCEEDED(SHGetFolderPathA(NULL, CSIDL_APPDATA, NULL, 0, base_dir))) {
snprintf(save->directory, sizeof(save->directory),
"%s%cpxl8%c%s", base_dir, PATH_SEP, PATH_SEP, game_name);
} else {
pxl8_free(save);
return NULL;
}
#else
const char* home = getenv("HOME");
if (!home) {
struct passwd* pw = getpwuid(getuid());
if (pw) home = pw->pw_dir;
}
if (!home) {
char* pref_path = pxl8_io_get_pref_path("pxl8", game_name);
if (!pref_path) {
pxl8_free(save);
return NULL;
}
pxl8_strncpy(save->directory, pref_path, sizeof(save->directory));
pxl8_free(pref_path);
snprintf(base_dir, sizeof(base_dir), "%s/.local/share", home);
pxl8_save_ensure_directory(base_dir);
snprintf(base_dir, sizeof(base_dir), "%s/.local/share/pxl8", home);
pxl8_save_ensure_directory(base_dir);
snprintf(save->directory, sizeof(save->directory),
"%s/.local/share/pxl8/%s", home, game_name);
#endif
if (pxl8_save_ensure_directory(save->directory) != PXL8_OK) {
pxl8_free(save);
return NULL;
usize dir_len = strlen(save->directory);
if (dir_len > 0 && save->directory[dir_len - 1] == '/') {
save->directory[dir_len - 1] = '\0';
}
pxl8_info("Save system initialized: %s", save->directory);
@ -116,9 +68,7 @@ pxl8_save* pxl8_save_create(const char* game_name, u32 magic, u32 version) {
}
void pxl8_save_destroy(pxl8_save* save) {
if (save) {
pxl8_free(save);
}
pxl8_free(save);
}
pxl8_result pxl8_save_write(pxl8_save* save, u8 slot, const u8* data, u32 size) {
@ -234,9 +184,7 @@ pxl8_result pxl8_save_read(pxl8_save* save, u8 slot, u8** data_out, u32* size_ou
}
void pxl8_save_free(u8* data) {
if (data) {
pxl8_free(data);
}
pxl8_free(data);
}
bool pxl8_save_exists(pxl8_save* save, u8 slot) {
@ -248,8 +196,7 @@ bool pxl8_save_exists(pxl8_save* save, u8 slot) {
char path[PXL8_SAVE_MAX_PATH];
pxl8_save_get_slot_path(save, slot, path, sizeof(path));
struct stat st;
return stat(path, &st) == 0;
return pxl8_io_file_exists(path);
}
pxl8_result pxl8_save_delete(pxl8_save* save, u8 slot) {