Skip to content

Commit

Permalink
Add .MAZ importing code! Factor common file definitions out of `expor…
Browse files Browse the repository at this point in the history
…t.h` and into `mazformat.h`.
  • Loading branch information
nok-ko committed Apr 17, 2022
1 parent 775a691 commit b68879c
Show file tree
Hide file tree
Showing 6 changed files with 209 additions and 30 deletions.
16 changes: 14 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,19 +1,31 @@
cmake_minimum_required(VERSION 3.21)
project(ray_maze C)


# Dependencies
set(CMAKE_C_STANDARD 11) # Requires C11 standard
add_subdirectory(raylib)

include_directories(include)
#add_library(raygui raygui.c)

# All warnings/errors for the code we wrote:
if (MSVC)
# warning level 4 and all warnings as errors
add_compile_options(/W4 /WX)
else()
# lots of warnings and all warnings as errors
add_compile_options(-Wall -Wextra -pedantic -Wmissing-braces)
endif()

add_library(stack stack.c)
add_library(queue queue.c)
add_library(maze_gen maze.c)
add_library(export export.c)
add_library(import import.c)
add_executable(ray_maze main.c)

target_link_libraries(ray_maze raylib maze_gen stack queue export)
target_link_libraries(ray_maze raylib maze_gen stack queue export import)


# Checks if OSX and links appropriate frameworks (only required on MacOS)
if (APPLE)
Expand Down
30 changes: 4 additions & 26 deletions export.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//
// Serialization/exporting code for converting mazes to "MAZ"-format files.
// Created by Nokko on 2022-04-16.
//

Expand All @@ -7,39 +7,17 @@

#include <stdint.h>
#include "maze.h"
#include "mazformat.h"


// More or less raw data, use a struct packed_chunk at higher levels.
struct maze_dump {
int width;
int height;
size_t size;
unsigned char *dump;
};

struct packed_chunk {
uint32_t width;
uint32_t height;
size_t len;
uint8_t packing_method;
uint8_t *data;
};

// .MAZ Format File Header
static const char MAZ_HEADER[8] = "\xe4\xe5maze<3";

// Packing Method constants.
// Need to be static to prevent linkage issues.
static const uint8_t PM_Packed = 0;
static const uint8_t PM_Unpacked = 1;
static const uint8_t PM_RESERVED = 63;

// Raw data dumps without width+height info.
struct maze_dump *dump_unpacked(struct maze *m);

struct maze_dump *dump_packed(struct maze *m);

// Write a `.rawmaz` dump to disk.
// Essentially useless, here for debug reasons.
// Just use PM_Unpacked if you want this.
void write_dump(struct maze_dump *d, const char *filename);

// Write a `.maz` file to disk, with the specified filename and packing method.
Expand Down
105 changes: 105 additions & 0 deletions import.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
//
// Created by Nokko on 2022-04-16.
//

#include <stdio.h> // For file operations
#include <string.h> // strcmp()
#include <stdint.h>
#include <stdbool.h>
#include "import.h"

// Read in a `.rawmaz` maze dump. No error handling here.
struct maze *read_dump(const char *filename) {

return NULL;
}

// Unpack maze data from a .MAZ file and produce a maze.
struct maze *unpack_maz(struct packed_chunk *chunk) {
struct maze *m = malloc(sizeof(struct maze));
m->data = malloc(sizeof(int) * chunk->width * chunk->height);
m->width = (int) chunk->width;
m->height = (int) chunk->height;
size_t mdata_len = chunk->width * chunk->height;

bool packed = (chunk->packing_method == PM_Packed);
int nibble_mask = 15; // 00001111, low nibble
if (packed) {
nibble_mask ^= 255; // 11110000, high nibble
}

// Every loop, write 1 or 2 maze cells, consume 1 byte of data.
uint8_t *d = chunk->data;
for (int *mp = m->data; mp < m->data + mdata_len; mp++, d++) {
*mp = (nibble_mask & *d); // First nibble
if (packed) {
*mp >>= 4;
mp++;
}

if (packed && mp < m->data + mdata_len) {
*mp = (nibble_mask ^ 255 & *d); // Second nibble (if packed), no shift
}
}

free(chunk->data);
return m;
}

// Alloc enough memory to read in the data from a .MAZ file,
// read it, write the length out, close the file.
void read_data(FILE *f, struct packed_chunk *chunk) {
// Figure out the length:
switch (chunk->packing_method) {
case PM_Packed:
// Same ol' ceil division trick.
chunk->len = (chunk->width * chunk->height + 1) / 2;
break;
case PM_Unpacked:
chunk->len = (chunk->width * chunk->height);
break;
default:
break;
}
uint8_t *data = malloc(chunk->len * sizeof(uint8_t));
fread(data, sizeof(uint8_t), chunk->len, f);
chunk->data = data;
fclose(f);
}

// Read in a `.maz`-format file.
// Errors are not handled - returns a NULL ptr on error.
struct maze *read_maz(const char *filename) {
// Alloc buffer for header
uint8_t *header = malloc(33);

// Open file
FILE *f = fopen(filename, "r");
if (f == NULL) {
free(header);
return NULL;
}

// Read header
fread(header, sizeof(uint8_t), 33, f);

// Make sure this is a .MAZ file
bool header_matches = (strncmp((char *) header, MAZ_HEADER, 8) == 0);
if (!header_matches) {
free(header);
return NULL;
}

// Read Dimensions Section
struct packed_chunk chunk = {
.width = *(uint32_t *) (header + 24),
.height = *(uint32_t *) (header + 28),
.packing_method = *(uint8_t *) (header + 32)
};
free(header);

read_data(f, &chunk);

return unpack_maz(&chunk);
}

18 changes: 18 additions & 0 deletions import.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
//
// Created by Nokko on 2022-04-16.
//

#ifndef RAY_MAZE_IMPORT_H
#define RAY_MAZE_IMPORT_H

#include "mazformat.h"
#include "maze.h"

// Read in a `.maz`-format file.
// Errors are not handled - returns a NULL ptr on error.
struct maze *read_maz(const char *filename);

// Read in a `.rawmaz` maze dump. No error handling here, either.
struct maze *read_dump(const char *filename);

#endif //RAY_MAZE_IMPORT_H
32 changes: 30 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "queue.h"
#include "stack.h"
#include "export.h"
#include "import.h"

#define VERSION "0.1.3"

Expand Down Expand Up @@ -192,6 +193,10 @@ int main(void) {
bool showColours = true;
bool showMaze = true;

char *filename_buf = malloc(sizeof(char) * 50);
strcpy(filename_buf, "realmaze.maz");
bool editing_filename = false;

while (!WindowShouldClose()) {
BeginDrawing();
ClearBackground(BLACK);
Expand Down Expand Up @@ -275,9 +280,9 @@ int main(void) {

// Gradient Colour Pickers:
if (shouldGenerate) GuiDisable();
gradientStartColor = GuiColorPicker((Rectangle){(x += 32), y - 80, 64, 64},
gradientStartColor = GuiColorPicker((Rectangle){(x += 32), y - 140, 64, 64},
"Gradient Start", gradientStartColor);
gradientEndColor = GuiColorPicker((Rectangle){(x += 96), y - 80, 64, 64},
gradientEndColor = GuiColorPicker((Rectangle){(x += 96), y - 140, 64, 64},
"Gradient End", gradientEndColor);
if (shouldGenerate) GuiEnable();

Expand All @@ -295,6 +300,28 @@ int main(void) {
write_maz(&m, PM_Packed, "realmaze.maz");
}

Rectangle textbox_bounds = (Rectangle){x += 192, y, 160, 24};

bool lmb_just_released = IsMouseButtonReleased(MOUSE_BUTTON_LEFT);
if (lmb_just_released && CheckCollisionPointRec(mousePos, textbox_bounds)) {
editing_filename = true;
} else if (lmb_just_released) {
editing_filename = false;
}

GuiTextBox(textbox_bounds, filename_buf, 50,editing_filename);

if (GuiButton((Rectangle) {x, y += 40, 160, 32}, "Read .MAZ File")) {
struct maze *mptr = read_maz(filename_buf);
int *old_data = m.data;
m.data = mptr->data;
free(old_data);
free(mptr);
GuiDisable();
}





// Carve through history…
Expand Down Expand Up @@ -372,5 +399,6 @@ int main(void) {
free_stack(stack);
free(color_data);
free(history_queue.values);
free(filename_buf);
return 0;
}
38 changes: 38 additions & 0 deletions mazformat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Constants for working with .MAZ-format files.
// Shared by import.h/export.h
// Created by Nokko on 2022-04-16.

#ifndef RAY_MAZE_MAZFORMAT_H
#define RAY_MAZE_MAZFORMAT_H

#include <stdint.h> // For int types
#include <stdlib.h> // For size_t


// More or less raw data, use a struct packed_chunk at higher levels.
struct maze_dump {
int width;
int height;
size_t size;
unsigned char *dump;
};

struct packed_chunk {
uint32_t width;
uint32_t height;
size_t len;
uint8_t packing_method;
uint8_t *data;
};

// Constants! Need to be static to prevent linkage issues.

// .MAZ Format File Header
static const char MAZ_HEADER[8] = "\xe4\xe5maze<3";

// Packing Methods.
static const uint8_t PM_Packed = 0;
static const uint8_t PM_Unpacked = 1;
static const uint8_t PM_RESERVED = 63;

#endif //RAY_MAZE_MAZFORMAT_H

0 comments on commit b68879c

Please sign in to comment.