Save KBLE file.

This commit is contained in:
KikooDX 2021-03-22 13:12:21 +01:00
parent ed3eb67086
commit 92001ba9d0
1 changed files with 101 additions and 12 deletions

View File

@ -5,6 +5,7 @@
#include <gint/keyboard.h>
#include <gint/bfile.h>
#include <gint/gint.h>
#include <gint/std/stdlib.h>
#include <stdint.h>
#define LEVEL_WIDTH 16
@ -17,6 +18,7 @@ typedef unsigned int tile_t;
static uint16_t *filepath = u"\\\\fls0\\sample.kble";
static const int kble_format_version = 0;
static const int kble_header_len = 6;
tile_t level[LEVEL_SIZE];
int level_id = 0;
@ -24,7 +26,8 @@ int fatal_error = 0;
char *fatal_error_msg = "no error, happy kikoo :D";
int debug_value = 0;
static void load_level(void);
static void level_load(void);
static void level_save(void);
static int read_byte(int file);
static tile_t read_merge_bytes(int file, int size);
@ -33,17 +36,25 @@ int main(void) {
dtext(1, 1, C_BLACK, "loading level (well trying to)...");
dupdate();
gint_switch(load_level);
gint_switch(level_load);
dclear(C_BLACK);
dtext(1, 1, C_WHITE, fatal_error_msg);
dprint(1, 20, C_WHITE, "%d", debug_value);
dupdate();
getkey();
gint_switch(level_save);
dclear(C_WHITE);
dtext(1, 1, C_BLACK, fatal_error_msg);
dprint(1, 20, C_BLACK, "%d", debug_value);
dupdate();
getkey();
return 1;
}
static void load_level(void) {
static void level_load(void) {
int file;
int tile_size;
int width;
@ -80,15 +91,14 @@ static void load_level(void) {
/* using those informations, see if the file size make sense */
file_size = BFile_Size(file);
assert(file_size >= 0, "can't read file size");
/* KBLE header len is 6 bytes */
assert(file_size == 6 + LEVEL_SIZE * tile_size,
assert(file_size == kble_header_len + LEVEL_SIZE * tile_size,
"file size doesn't make sense");
/* read file content */
for (i = 0; i < LEVEL_SIZE; i += 1) {
tile = read_merge_bytes(file, tile_size);
assert(tile != (tile_t)-1, "can't read tile");
level[i] = tile;
tile = read_merge_bytes(file, tile_size);
assert(tile != (tile_t)-1, "can't read tile");
level[i] = tile;
}
/* close file */
@ -96,6 +106,85 @@ static void load_level(void) {
assert(file >= 0, "closure failed miserably");
}
/* Save level to memory. Allocate memory to write everything at once. */
static void level_save(void) {
int file;
unsigned int tile_size;
unsigned int max_tile_size = 1;
int i;
tile_t tile;
int data_size;
char *data = NULL;
/* find appropriate tile size */
for (i = 0; i < LEVEL_SIZE; i += 1) {
tile = level[i];
tile_size = 1;
while (tile >>= 8)
tile_size += 1;
if (tile_size > max_tile_size)
max_tile_size = tile_size;
}
assert(max_tile_size <= sizeof(tile_t),
"computed tile size is crazy");
/* total amount of data to write in bytes */
data_size = kble_header_len + LEVEL_SIZE * tile_size;
/* allocate memory */
data = malloc(data_size);
/* kble format version */
data[0] = kble_format_version;
/* tile size in bytes */
data[1] = max_tile_size;
/* width and height (comptime) */
data[2] = LEVEL_WIDTH / 256;
data[3] = LEVEL_WIDTH % 256;
data[4] = LEVEL_HEIGHT / 256;
data[5] = LEVEL_HEIGHT % 256;
/* level content */
assert(max_tile_size == 1,
"this editor only support tiles from 0 to 255");
for (i = 0; i < LEVEL_SIZE; i += 1) {
data[i + kble_header_len] = level[i];
}
/* open file in write mode */
file = BFile_Open(filepath, BFile_WriteOnly);
assert(file >= 0, "can't open file in write mode");
/* recreate file with correct size if needed */
if (BFile_Size(file) != data_size) {
int data_size_copy = data_size;
/* close file */
file = BFile_Close(file);
assert(file >= 0, "closure failed miserably (w)");
/* remove file */
file = BFile_Remove(filepath);
assert(file >= 0, "file removal failed somehow");
/* create file */
file = BFile_Create(filepath, BFile_File, &data_size_copy);
assert(file >= 0, "file creation failed :(");
assert(data_size == data_size_copy,
"casio messed up my data_size variable");
/* open file */
file = BFile_Open(filepath, BFile_WriteOnly);
assert(file >= 0, "can't open file in write mode");
}
/* write data */
BFile_Write(file, data, data_size);
/* close file */
file = BFile_Close(file);
assert(file >= 0, "closure failed miserably (w)");
/* free memory */
free(data);
}
/* Read a single byte. Negative value is BFile error code. */
static int read_byte(int file) {
char byte;
@ -115,11 +204,11 @@ static tile_t read_merge_bytes(int file, int size) {
int i = 0;
byte_ptr += sizeof(tile_t) - size;
for (i = 0; i < size; i += 1) {
byte = read_byte(file);
if (byte < 0)
return -1;
byte = read_byte(file);
if (byte < 0)
return -1;
*byte_ptr = byte;
byte_ptr += 1;
byte_ptr += 1;
}
return merged;
}