From 92001ba9d0cb35307c39ca62aa83244b4df6df59 Mon Sep 17 00:00:00 2001 From: KikooDX Date: Mon, 22 Mar 2021 13:12:21 +0100 Subject: [PATCH] Save KBLE file. --- src/main.c | 113 +++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 101 insertions(+), 12 deletions(-) diff --git a/src/main.c b/src/main.c index 34c5c59..fdd2df3 100644 --- a/src/main.c +++ b/src/main.c @@ -5,6 +5,7 @@ #include #include #include +#include #include #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; }