Compare commits

...

8 Commits

Author SHA1 Message Date
Ulysse Cura aec1749384 Updated TODO.md. 2026-08-21 22:58:07 +02:00
Ulysse Cura 419a247584 Changed way asset builder works. 2026-08-21 22:57:55 +02:00
Ulysse Cura 53e5e82976 Fixed hitbox layer export in tiled extension. 2026-08-21 22:56:17 +02:00
Ulysse Cura 1951d0bbca Documented changing map format and tiled export tool updated. 2026-08-20 01:08:02 +02:00
Ulysse Cura 66a0cf3df8 Working map diplaying. 2026-08-20 01:06:55 +02:00
Ulysse Cura 447592a0d8 Adding camera and tilemap display. 2026-08-19 14:14:01 +02:00
Ulysse Cura 75a9ceb635 Fixed animation system frame skipping. 2026-08-19 14:13:21 +02:00
Ulysse Cura 8159bb4d2f More ideas ! 2026-08-19 14:13:02 +02:00
27 changed files with 953 additions and 980 deletions

View File

@ -9,5 +9,13 @@ Ordre des salles en bazard.
Deux routes, une ou l'on reprend control, une autre ou l'on perd control.
Ce control s'exprimerai par l'environnement par exemple.
Dans l'idée de se faire contrôler c'est toujours sympa quand le perso fait quelque chose, par exemple dire "j'adore la peluche chat!" et ses parents disent "t'es plus un bébé", et l'enfant ne prend plus de peluches.
Parfois des opinions plus graves comme l'homophobie, racisme, grossophobie, etc...
Dans l'idée de se faire contrôler c'est toujours sympa quand le perso fait quelque chose,
par exemple dire "j'adore la peluche chat!" et ses parents disent "t'es plus un bébé", et l'enfant ne prend plus de peluches.
Parfois des opinions plus graves comme l'homophobie, racisme, grossophobie, etc...
## Esprit / Realitée
Changer entre réalité et esprit, voir la construction d'un esprit critique,
l'enfant absorbe tout au début, questionne rien, et avance en se posant des questions, en cherchant des réponses, en faisant ses propres opinions, etc...
Que se soit un peu énigmes peut être, des choses à résoudre dans son esprit pour qu'il puisse s'en sortir dans la vraie vie, provoquant des scénarios différents, des réactions différentes face à ce qu'il peut vivre.
Ce qu'il vit ne changerait pas mais uniquement ce qu'il en retient en quelque sorte.

@ -1 +1 @@
Subproject commit 519ae78ada36b922c64de8d37571db8d0ba0c944
Subproject commit 2a0803d4c4e15048fced7d3c402b76fc782e0d85

22
TODO.md
View File

@ -8,10 +8,6 @@
- [ ] Add compression into asset builder and asset manager
- [ ] Optimize asset builder file analize
- [ ] Create camera
- [ ] Make functionnal hitboxes between entities and map
- [ ] Make triggers
@ -19,18 +15,26 @@
- [ ] Make physics component use acceleration
- [ ] Make camera use acceleration
- [ ] Make camera center on map
###### Bugs
### In progress
- [ ] Create tilemap management and display
### Done
- [x] Create camera
- [x] Optimize asset builder file analize
- [x] Create tilemap management and display
- [x] Find tilemap building format
- [x] Add building support for tilemaps in asset builder
- [x] Add loading support in asset manager
- [ ] Display tilemaps
- [ ] Work on optimizations !
### Done
- [x] Display tilemaps
- [NO] Work on optimizations !
- [x] Work on entities draw order

View File

@ -6,24 +6,41 @@ ASSETS := \
props_sheets/barred_door_sheet.png \
props_sheets/wooden_door_sheet.png \
tileset/tileset.png \
maps/dungeon_entry.map \
maps/dungeon_room_1.map
ASSETS := $(addprefix $(ASSETS_DIR)/,$(ASSETS))
ASSETS_OBJECTS = $(ASSETS:%=$(BUILD_DIR)/%.o)
ASSET_BUILDER_DIR = $(ASSETS_DIR)/asset_builder/src
ASSET_BUILDER_OUTPUT = $(BUILD_DIR)/$(ASSETS_DIR)/asset_builder/asset_builder
build_assets: setup_asset build_asset_builder asset_end
include $(ASSET_BUILDER_DIR)/Makefile
build_assets: setup_asset build_asset_builder count_assets_build asset_end
# Current file nb to process
CURRENT_ASSET_FILE := 0
# Count nb of files to build
count_assets_build:
$(eval export TOTAL_ASSETS_FILES := $(shell echo $$(($$(make -n $(ASSETS_OBJECTS) 2>/dev/null | grep -c "Building") + 1))))
setup_asset:
@echo "Building $(notdir $(ASSET_OUTPUT))"
$(Q)mkdir -p $(dir $(ASSETS_OBJECTS))
$(ASSET_OUTPUT): $(ASSET_BUILDER_OUTPUT) $(ASSETS)
$(ASSET_OUTPUT): $(ASSETS_OBJECTS) $(ASSET_BUILDER_OUTPUT)
@echo -e "[100%] $(YELLOW)Building $(notdir $(ASSET_OUTPUT))$(RESET)"
$(Q)$(ASSET_BUILDER_OUTPUT) $@ $(ASSETS)
$(Q)$(ASSET_BUILDER_OUTPUT) $@ $(ASSETS_OBJECTS)
# Build .o files
$(BUILD_DIR)/$(ASSETS_DIR)/%.o: $(ASSETS_DIR)/% $(ASSET_BUILDER_OUTPUT)
$(eval CURRENT_ASSET_FILE := $(shell echo $$(($(CURRENT_ASSET_FILE)+1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_ASSET_FILE)*100/$(TOTAL_ASSETS_FILES)))))
@echo -e "[$(PERCENTAGE)%] $(GREEN)Building ASSET object $@$(RESET)"
$(Q)$(ASSET_BUILDER_OUTPUT) $@ -c $<
asset_end: $(ASSET_OUTPUT)
@echo "Built target $(notdir $(ASSET_OUTPUT))"

View File

@ -7,7 +7,63 @@ The supported file formats are :
The different files format are deduced from the extensions only.
The code has some optimisation problems but here is the main idea :
--------
To build objects files, they are analised and written in an output file wich content depend on asset type.
Their structure will be :
| Description | Length |
| :---------------- | :-----------------------|
| Asset size | unsigned int (32 bits) |
| Asset data | depends on asset type |
#### Image (.png)
Convert png's RGBA8888 to custom RGB565 with #0001 in RGB565 as the transparent color.
If png's alpha is null then the color of the pixel will be replaced with this.
##### Image asset data structure
| Description | Length |
| :---------------- | :------------------------------------------ |
| Image width | unsigned short (16 bits) |
| Image height | unsigned short (16 bits) |
| Image data | depend on image size, pixel short (16 bits) |
#### Maps (.map)
Convert from json to custom format.
##### Maps asset data structure
| Description | Length |
| :-------------------------- | :---------------------------------------------------- |
| Map width | unsigned short (16 bits) |
| Map height | unsigned short (16 bits) |
| Map background layers nb | unsigned char (8 bits) |
| Map background layers data | depends map size and layer count, tile short (16 bits)|
| Map foreground layer data | depend on map size, tile short (16 bits) |
| Tileset asset name | const char [] (variable length, ends with '\00') |
| Map hitboxes data | depend on map size, tile unsigned char (8 bits) |
| Entities number | unsigned short (16 bits) |
| ... | |
| Entity ID | unsigned int (32 bits) |
| Entity components number | unsigned short (16 bits) |
| ... | |
| Component type | unsigned short (16 bits) |
| ... | |
| Component attributes | depend on attribute type |
| int | unsigned int (32 bits) |
| float | float (32 bits) |
| bool | _Bool (8 bits) |
| str | const char [] (variable length, ends with '\00') |
| ... | |
| ... | |
--------
To build asset file :
First calculate header wich consists of :
@ -19,51 +75,4 @@ First calculate header wich consists of :
| Asset start index | unsigned int (32 bits) |
| ... | |
This calculation needs to analse the content of inputs files to calculate the start offsets in the file.
Then write the content of each file in the same order as they were analysed for header calculations.
For the moment each input file is openend and analized 2 times.
## Image (.png)
Convert png's RGBA8888 to custom RGB565 with #0001 in RGB565 as the transparent color.
If png's alpha is null then the color of the pixel will be replaced with this.
### Image asset data structure
| Description | Length |
| :---------------- | :------------------------------------------ |
| Image width | unsigned int (32 bits) |
| Image height | unsigned int (32 bits) |
| Image data | depend on image size, pixel short (16 bits) |
## Maps (.map)
Convert from json to custom format.
### Maps asset data structure
| Description | Length |
| :-------------------------- | :------------------------------------------------ |
| Map width | unsigned int (32 bits) |
| Map height | unsigned int (32 bits) |
| Map background layer 1 data | depend on map size, tile short (16 bits) |
| Map background layer 2 data | depend on map size, tile short (16 bits) |
| Map background layer 3 data | depend on map size, tile short (16 bits) |
| Map foreground layer data | depend on map size, tile short (16 bits) |
| Map hitboxes data | depend on map size, tile unsigned char (8 bits) |
| Entities number | unsigned int (32 bits) |
| ... | |
| Entity ID | unsigned int (32 bits) |
| Entity components number | unsigned int (32 bits) |
| ... | |
| Component type | int (32 bits) |
| ... | |
| Component attributes | depend on attribute type |
| int | int (32 bits) |
| float | float (32 bits) |
| bool | bool (8 bits) |
| str | const char [] (variable length, ends with '\00') |
| ... | |
| ... | |
And then write content of each input files.

View File

@ -1,8 +1,9 @@
# Source files
ASSET_BUILDER_SOURCES := \
asset_file.c \
object.c \
image.c \
map.c \
utils.c \
main.c
# Compiler and flags

View File

@ -1,92 +0,0 @@
#include "asset_file.h"
#include <string.h>
#include <stdlib.h>
#include "image.h"
#include "map.h"
#include "errors.h"
int parse_file_for_header(const char *input_file_name, asset_header_def_t *asset_header_def)
{
const char *file_name_dot = strrchr(input_file_name, '.');
if(!file_name_dot)
{
error_printf("File does not have an extension.");
return EXIT_FAILURE;
}
const char *file_name_ext = file_name_dot + 1;
if(!strcmp(file_name_ext, "png"))
{
if(parse_png_for_header(input_file_name, asset_header_def)) return_failure_int;
}
else if(!strcmp(file_name_ext, "map"))
{
if(parse_map_for_header(input_file_name, asset_header_def)) return_failure_int;
}
else
{
error_printf("Extension unsupported : %s", file_name_dot);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
int write_header_to_file(asset_file_header_t *asset_file_header, FILE *output_file)
{
if(fwrite(&asset_file_header->assets_number, sizeof(asset_file_header->assets_number), 1, output_file) != 1)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
for(uint32_t i = 0; i < asset_file_header->assets_number; i++)
{
size_t name_length = strlen(asset_file_header->assets_header_def[i].name) + 1;
if(fwrite(asset_file_header->assets_header_def[i].name, sizeof(unsigned char), name_length, output_file) != name_length)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
if(fwrite(&asset_file_header->assets_header_def[i].start, sizeof(asset_file_header->assets_header_def[i].start), 1, output_file) != 1)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}
int parse_file_for_content_and_write(const char *input_file_name, FILE *output_file)
{
const char *file_name_dot = strrchr(input_file_name, '.');
if(!file_name_dot)
{
error_printf("File does not have an extension.");
return EXIT_FAILURE;
}
const char *file_name_ext = file_name_dot + 1;
if(!strcmp(file_name_ext, "png"))
{
if(parse_png_for_content_and_write(input_file_name, output_file)) return_failure_int;
}
else if(!strcmp(file_name_ext, "map"))
{
if(parse_map_for_content_and_write(input_file_name, output_file)) return_failure_int;
}
else
{
error_printf("Extension unsupported : %s", file_name_dot);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -1,25 +0,0 @@
#ifndef ASSET_FILE_H
#define ASSET_FILE_H
#include <stdint.h>
#include <stdio.h>
typedef struct asset_header_def_t {
char *name;
uint32_t start, end;
} asset_header_def_t;
typedef struct asset_file_header_t {
uint32_t assets_number;
asset_header_def_t *assets_header_def;
size_t header_size;
} asset_file_header_t;
int parse_file_for_header(const char *input_file_name, asset_header_def_t *asset_header_def);
int write_header_to_file(asset_file_header_t *asset_file_header, FILE *output_file);
int parse_file_for_content_and_write(const char *input_file_name, FILE *output_file);
#endif // ASSET_FILE_H

View File

@ -15,8 +15,23 @@
fprintf(stderr, "\033[32mINFO\033[m: " __VA_ARGS__); \
fputc('\n', stderr); \
} while (0)
#define return_failure_int \
do { \
fprintf(stderr, "\tin %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return EXIT_FAILURE; \
} while (0);
#define return_failure_ptr \
do { \
fprintf(stderr, "\tin %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return NULL; \
} while (0);
#else
#define debug_printf(...)
#define return_failure_int return EXIT_FAILURE;
#define return_failure_ptr return NULL;
#endif
#define warning_printf(...) \
@ -32,16 +47,4 @@
fputc('\n', stderr); \
} while (0)
#define return_failure_int \
do { \
fprintf(stderr, " in %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return EXIT_FAILURE; \
} while (0);
#define return_failure_ptr \
do { \
fprintf(stderr, " in %s:%d:%s()\n", __FILE__, __LINE__, __func__); \
return NULL; \
} while (0);
#endif // ERRORS_H

View File

@ -1,9 +1,9 @@
#ifndef IMAGE_H
#define IMAGE_H
#include "asset_file.h"
#include <stdio.h>
#include <stdint.h>
int parse_png_for_header(const char *input_file_name, asset_header_def_t *asset_header_def);
int parse_png_for_content_and_write(const char *input_file_name, FILE *output_file);
int build_image(const char *input_file_name, FILE *output_file, uint32_t *asset_size);
#endif // IMAGE_H

View File

@ -1,9 +1,9 @@
#ifndef MAP_H
#define MAP_H
#include "asset_file.h"
#include <stdio.h>
#include <stdint.h>
int parse_map_for_header(const char *input_file_name, asset_header_def_t *asset_header_def);
int parse_map_for_content_and_write(const char *input_file_name, FILE *output_file);
int build_map(const char *input_file_name, FILE *output_file, uint32_t *asset_size);
#endif // MAP_H

View File

@ -0,0 +1,8 @@
#ifndef OBJECT_H
#define OBJECT_H
#include <stdio.h>
int build_object(const char *input_file_path, FILE *output_file);
#endif // OBJECT_H

View File

@ -0,0 +1,10 @@
#ifndef UTILS_H
#define UTILS_H
#include <stdio.h>
int file_read(void *ptr, size_t size, size_t nb, FILE *file);
int file_write(const void *ptr, size_t size, size_t nb, FILE *file);
#endif // UTILS_H

View File

@ -2,96 +2,10 @@
#include <png.h>
#include <stdlib.h>
#include "asset_file.h"
#include "utils.h"
#include "errors.h"
int parse_png_for_header(const char *file_name, asset_header_def_t *asset_header_def)
{
FILE *input_file = fopen(file_name, "rb");
if(!input_file)
{
error_printf("Failed to open input file.");
return EXIT_FAILURE;
}
// Check png autenticity.
unsigned char sig[8];
if(fread(sig, sizeof(unsigned char), 8, input_file) != 8)
{
fclose(input_file);
error_printf("Failed to read input file.");
return EXIT_FAILURE;
}
if(!png_check_sig(sig, 8))
{
fclose(input_file);
error_printf("Png file is not valid.");
return EXIT_FAILURE;
}
// PNG structs.
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
{
fclose(input_file);
error_printf("Failed to allocate png ptr.");
return EXIT_FAILURE;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(input_file);
error_printf("Failed to allocate png info.");
return EXIT_FAILURE;
}
// Fill structs and load data.
png_init_io(png_ptr, input_file);
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
uint32_t width = png_get_image_width(png_ptr, info_ptr);
uint32_t height = png_get_image_height(png_ptr, info_ptr);
uint8_t bit_depth = png_get_bit_depth(png_ptr, info_ptr);
uint8_t color_type = png_get_color_type(png_ptr, info_ptr);
// Verify png attributes.
if(bit_depth != 8)
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
error_printf("Png bit depth not supported.");
return EXIT_FAILURE;
}
switch(color_type)
{
case PNG_COLOR_TYPE_RGB:
case PNG_COLOR_TYPE_RGB_ALPHA:
break;
default:
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
error_printf("Png color type not supported.");
return EXIT_FAILURE;
}
// Fill asset def.
asset_header_def->start = 0;
asset_header_def->end = sizeof(width) + sizeof(height) + height * width * sizeof(uint16_t);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return EXIT_SUCCESS;
}
int parse_png_for_content_and_write(const char *input_file_name, FILE *output_file)
int build_image(const char *input_file_name, FILE *output_file, uint32_t *asset_size)
{
FILE *input_file = fopen(input_file_name, "rb");
@ -102,18 +16,13 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
}
// Check png autenticity.
unsigned char sig[8];
if(fread(sig, sizeof(unsigned char), 8, input_file) != 8)
{
fclose(input_file);
error_printf("Failed to read input file.");
return EXIT_FAILURE;
}
png_byte sig[8];
if(file_read(sig, sizeof(png_byte), sizeof(sig), input_file)) return_failure_int;
if(!png_check_sig(sig, 8))
{
fclose(input_file);
error_printf("Png file is not valid.");
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return EXIT_FAILURE;
}
@ -121,17 +30,19 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if(!png_ptr)
{
fclose(input_file);
error_printf("Failed to allocate png ptr.");
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return EXIT_FAILURE;
}
png_infop info_ptr = png_create_info_struct(png_ptr);
if(!info_ptr)
{
png_destroy_read_struct(&png_ptr, NULL, NULL);
fclose(input_file);
error_printf("Failed to allocate png info.");
png_destroy_read_struct(&png_ptr, NULL, NULL);
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return EXIT_FAILURE;
}
@ -140,27 +51,31 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
png_set_sig_bytes(png_ptr, 8);
png_read_info(png_ptr, info_ptr);
uint32_t width = png_get_image_width(png_ptr, info_ptr);
uint32_t height = png_get_image_height(png_ptr, info_ptr);
uint16_t width = png_get_image_width(png_ptr, info_ptr);
uint16_t height = png_get_image_height(png_ptr, info_ptr);
size_t row_length = png_get_rowbytes(png_ptr, info_ptr);
// Write image size.
if(fwrite(&width, sizeof(width), 1, output_file) != 1)
if(file_write(&width, sizeof(width), 1, output_file))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return_failure_int;
}
if(fwrite(&height, sizeof(height), 1, output_file) != 1)
*asset_size += sizeof(width);
if(file_write(&height, sizeof(height), 1, output_file))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return_failure_int;
}
*asset_size += sizeof(height);
// Prepare storage.
png_byte src_pixels[height * row_length];
png_bytep src_row_ptrs[height];
@ -170,46 +85,43 @@ int parse_png_for_content_and_write(const char *input_file_name, FILE *output_fi
// Read pixels.
png_read_image(png_ptr, src_row_ptrs);
uint16_t dst_pixels[width * height * sizeof(uint16_t)];
uint16_t dst_pixels[width * height];
for(uint32_t i = 0; i < height; i++)
for(uint16_t i = 0; i < height; i++)
{
for(uint32_t j = 0; j < width; j += 1)
for(uint16_t j = 0; j < width; j += 1)
{
uint8_t r, g, b;
if(src_pixels[i * row_length + j * 4 + 3])
{
r = src_pixels[i * row_length + j * 4] >> 3;
g = src_pixels[i * row_length + j * 4 + 1] >> 2;
b = src_pixels[i * row_length + j * 4 + 2] >> 3;
uint8_t r = src_pixels[i * row_length + j * 4] >> 3;
uint8_t g = src_pixels[i * row_length + j * 4 + 1] >> 2;
uint8_t b = src_pixels[i * row_length + j * 4 + 2] >> 3;
dst_pixels[i * width + j] = ((r) << 11) | ((g) << 5) | b;
}
else
{
r = 0x00;
g = 0x00;
b = 0x01;
dst_pixels[i * width + j] = 0x0001;
}
uint16_t pixel = ((r) << 11) | ((g) << 5) | b;
dst_pixels[i * width + j] = pixel;
// printf("\033[48;2;%d;%d;%dm ", r << 3, g << 2, b << 3);
}
// puts("\033[m");
}
if(fwrite(&dst_pixels, sizeof(uint16_t), width * height, output_file) != width * height)
if(file_write(&dst_pixels, sizeof(*dst_pixels), width * height, output_file))
{
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
error_printf("Failed to write to output file : %d", errno);
if(fclose(input_file))
error_printf("Failed to close input file : %d", errno);
return_failure_int;
}
*asset_size += sizeof(dst_pixels);
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
if(fclose(input_file))
{
error_printf("Failed to close input file : %d", errno);
return EXIT_FAILURE;
}
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
fclose(input_file);
return EXIT_SUCCESS;
}

View File

@ -1,101 +1,212 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "asset_file.h"
#include <stdint.h>
#include "object.h"
#include "utils.h"
#include "errors.h"
typedef enum build_function_t {
BUILD_OBJECT,
BUILD_ASSET_FILE
} build_function_t;
void print_usage(void)
{
puts("\033[33musage\033[m:");
puts("\tasset_builder output_object_file -c input_file");
puts("\tasset_builder output_asset_file input_object_file [input_object_file2 ...]");
}
int main(int argc, char *argv[])
{
int exit_status = EXIT_FAILURE;
FILE *output_asset_file = NULL;
// Verify arguments minimum number.
// Parse args
if(argc < 3)
{
puts("\033[33musage\033[m: asset_builder output_file input_file [input_file_2 ...]");
goto end;
print_usage();
return EXIT_FAILURE;
}
// Header size and content.
asset_file_header_t asset_file_header;
asset_file_header.assets_number = argc - 2;
asset_file_header.header_size = sizeof(asset_file_header.assets_number) + sizeof(uint32_t) * asset_file_header.assets_number;
asset_file_header.assets_header_def = calloc(asset_file_header.assets_number, sizeof(asset_header_def_t));
if(!asset_file_header.assets_header_def)
const build_function_t build_function = strcmp(argv[2], "-c") ? BUILD_ASSET_FILE : BUILD_OBJECT;
const char *output_file_path = argv[1];
FILE *output_file = fopen(output_file_path, "wb");
if(!output_file)
{
error_printf("Failed to allocate memory.");
goto end;
error_printf("Failed to open output file : %d", errno);
return EXIT_FAILURE;
}
// Set assets name.
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
if(build_function == BUILD_OBJECT)
{
const char *file_name = argv[i + 2];
const char *file_name_last_slash = strrchr(file_name, '/');
const char *file_base_name = file_name_last_slash ? file_name_last_slash + 1 : file_name;
const char *file_name_dot = strrchr(file_name, '.');
const char *file_name_ext = file_name_dot ? file_name_dot + 1 : file_name;
size_t asset_name_length = strlen(file_base_name) - strlen(file_name_ext);
asset_file_header.assets_header_def[i].name = malloc(asset_name_length);
asset_file_header.assets_header_def[i].name[asset_name_length - 1] = '\0';
strncpy(asset_file_header.assets_header_def[i].name, file_base_name, asset_name_length - 1);
// Update header size.
asset_file_header.header_size += asset_name_length;
}
// Parse input files to create header structure and fill output file.
output_asset_file = fopen(argv[1], "wb");
if(!output_asset_file)
{
error_printf("could not create output file.");
goto end;
}
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
if(parse_file_for_header(argv[i + 2], &asset_file_header.assets_header_def[i])) return_failure_int;
// Calculate absolute position of assets in the file.
if(i) asset_file_header.assets_header_def[i].start = asset_file_header.assets_header_def[i - 1].end;
else asset_file_header.assets_header_def[0].start = asset_file_header.header_size;
asset_file_header.assets_header_def[i].end += asset_file_header.assets_header_def[i].start;
}
if(write_header_to_file(&asset_file_header, output_asset_file))
{
error_printf("Failed to write to output file : %d", errno);
goto end;
}
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
{
if(parse_file_for_content_and_write(argv[i + 2], output_asset_file)) return_failure_int;
}
exit_status = EXIT_SUCCESS;
end:
if(asset_file_header.assets_header_def)
{
for(uint32_t i = 0; i < asset_file_header.assets_number; i++)
if(argc != 4)
{
if(asset_file_header.assets_header_def[i].name)
print_usage();
return EXIT_FAILURE;
}
const char *input_file_path = argv[3];
if(build_object(input_file_path, output_file))
{
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
}
else if(build_function == BUILD_ASSET_FILE)
{
uint32_t header_size = 0;
const int nb_input_object_files = argc - 2;
if(file_write(&nb_input_object_files, sizeof(nb_input_object_files), 1, output_file))
{
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
header_size += sizeof(nb_input_object_files);
FILE *input_object_files[nb_input_object_files];
uint32_t input_object_files_sizes[nb_input_object_files];
uint32_t input_object_files_offsets[nb_input_object_files];
for(int i = 0; i < nb_input_object_files; i++)
{
const char *input_object_file_path = argv[i + 2];
input_object_files[i] = fopen(input_object_file_path, "rb");
if(!input_object_files[i])
{
free(asset_file_header.assets_header_def[i].name);
error_printf("Failed to open input object file : %d", errno);
for(; i >= 0; i--)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return EXIT_FAILURE;
}
if(file_read(&input_object_files_sizes[i], sizeof(*input_object_files_sizes), 1, input_object_files[i]))
{
for(; i >= 0; i--)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int
}
const char *input_object_file_slash = strrchr(input_object_file_path, '/');
const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path;
const char *input_object_file_ext = strchr(input_object_file_path, '.');
uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1;
header_size += input_object_file_base_name_length * sizeof(*input_object_file_name);
header_size += sizeof(*input_object_files_offsets);
}
input_object_files_offsets[0] = header_size;
for(int i = 0; i < nb_input_object_files; i++)
{
if(i) input_object_files_offsets[i] = input_object_files_offsets[i - 1] + input_object_files_sizes[i - 1];
char *input_object_file_path = argv[i + 2];
const char *input_object_file_slash = strrchr(input_object_file_path, '/');
const char *input_object_file_name = input_object_file_slash ? input_object_file_slash + 1 : input_object_file_path;
char *input_object_file_ext = strchr(input_object_file_path, '.');
input_object_file_ext[0] = '\00';
uint32_t input_object_file_base_name_length = strlen(input_object_file_name) - strlen(input_object_file_ext) + 1;
if(file_write(input_object_file_name, sizeof(*input_object_file_name), input_object_file_base_name_length, output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
if(file_write(&input_object_files_offsets[i], sizeof(*input_object_files_offsets), 1, output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
}
free(asset_file_header.assets_header_def);
for(int i = 0; i < nb_input_object_files; i++)
{
char buffer[input_object_files_sizes[i]];
if(file_read(buffer, sizeof(*buffer), input_object_files_sizes[i], input_object_files[i]))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
if(file_write(buffer, sizeof(*buffer), input_object_files_sizes[i], output_file))
{
for(i = 0; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return_failure_int;
}
}
for(int i = 0; i < nb_input_object_files; i++)
{
if(fclose(input_object_files[i]))
{
error_printf("Failed to close input object file : %d", errno);
for(i++; i < nb_input_object_files; i++)
if(fclose(input_object_files[i]))
error_printf("Failed to close input object file : %d", errno);
if(fclose(output_file))
error_printf("Failed to close output file : %d", errno);
return EXIT_FAILURE;
}
}
}
if(output_asset_file)
fclose(output_asset_file);
if(fclose(output_file))
{
error_printf("Failed to close output file : %d", errno);
return EXIT_FAILURE;
}
return exit_status;
return EXIT_SUCCESS;
}

View File

@ -4,171 +4,42 @@
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include "asset_file.h"
#include "utils.h"
#include "errors.h"
int parse_map_for_header(const char *input_file_name, asset_header_def_t *asset_header_def)
static int json_get_object_of_type(const json_object *obj, const char *key, json_type type, json_object **result)
{
json_object *root = json_object_from_file(input_file_name);
if (!root)
if(!json_object_object_get_ex(obj, key, result))
{
error_printf("Failed to load input file.");
error_printf("Object doesn't contain key \"%s\".", key);
return EXIT_FAILURE;
}
if(json_object_object_length(root) != 8)
if(!json_object_is_type(*result, type))
{
json_object_put(root);
error_printf("Map file doesn't contain 8 elements at its root.");
error_printf("Key \"%s\" is not of type %s.", key, json_type_to_name(type));
return EXIT_FAILURE;
}
json_object *tmp_obj;
return EXIT_SUCCESS;
}
if(!json_object_object_get_ex(root, "MapWidth", &tmp_obj))
static inline int json_get_idx_of_type(const json_object *obj, size_t idx, json_type type, json_object **result)
{
*result = json_object_array_get_idx(obj, idx);
if(!*result)
{
json_object_put(root);
error_printf("Map file doesn't contain key \"MapWidth\".");
error_printf("Array index out of range : %lu.", idx);
return EXIT_FAILURE;
}
if(!json_object_is_type(tmp_obj, json_type_int))
if(!json_object_is_type(*result, type))
{
error_printf("Map key \"MapWidth\" is not of type int.");
error_printf("Result is not of type %s.", json_type_to_name(type));
return EXIT_FAILURE;
}
int map_width = json_object_get_int(tmp_obj);
if(!json_object_object_get_ex(root, "MapHeight", &tmp_obj))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"MapHeight\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(tmp_obj, json_type_int))
{
error_printf("Map key \"MapHeight\" is not of type int.");
return EXIT_FAILURE;
}
int map_height = json_object_get_int(tmp_obj);
json_object *entities;
if(!json_object_object_get_ex(root, "Entities", &entities))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"Entities\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(entities, json_type_array))
{
json_object_put(root);
error_printf("Map object \"Entities\" is not an array.");
return EXIT_FAILURE;
}
uint32_t entities_nb = json_object_array_length(entities);
asset_header_def->start = 0;
asset_header_def->end = sizeof(map_width) + sizeof(map_height)
+ map_width * map_height * sizeof(uint16_t) * 4
+ map_width * map_height * sizeof(uint8_t)
+ sizeof(entities_nb);
for(uint32_t i = 0; i < entities_nb; i++)
{
json_object *entity = json_object_array_get_idx(entities, i);
if(!json_object_is_type(entity, json_type_object))
{
error_printf("Map entity is not of type object.");
return EXIT_FAILURE;
}
asset_header_def->end += sizeof(uint32_t);
json_object *components;
if(!json_object_object_get_ex(entity, "Components", &components))
{
error_printf("Entity doesn't have key \"Components\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(components, json_type_array))
{
error_printf("Component is not of type array.");
return EXIT_FAILURE;
}
uint32_t components_nb = json_object_array_length(components);
asset_header_def->end += sizeof(components_nb);
for(uint32_t j = 0; j < components_nb; j++)
{
json_object *component = json_object_array_get_idx(components, j);
if(!json_object_is_type(component, json_type_object))
{
error_printf("Entity component is not of type object.");
return EXIT_FAILURE;
}
asset_header_def->end += sizeof(uint32_t);
json_object *attributes;
if(!json_object_object_get_ex(component, "Attributes", &attributes))
{
error_printf("Component doesn't have key \"Attributes\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(attributes, json_type_array))
{
error_printf("Attributes is not of type array.");
return EXIT_FAILURE;
}
uint32_t attributes_nb = json_object_array_length(attributes);
for(uint32_t k = 0; k < attributes_nb; k++)
{
json_object *attribute = json_object_array_get_idx(attributes, k);
switch(json_object_get_type(attribute))
{
case json_type_int:
asset_header_def->end += sizeof(uint32_t);
break;
case json_type_double:
asset_header_def->end += sizeof(float);
break;
case json_type_boolean:
asset_header_def->end += sizeof(bool);
break;
case json_type_string:
asset_header_def->end += json_object_get_string_len(attribute) + 1;
break;
default:
error_printf("Attribute type is not supported : %s", json_type_to_name(json_object_get_type(attribute)));
return EXIT_FAILURE;
}
}
}
}
json_object_put(root);
return EXIT_SUCCESS;
}
@ -177,7 +48,7 @@ typedef enum component_type_t {
#include "components.def"
} component_type_t;
int parse_map_for_content_and_write(const char *input_file_name, FILE *output_file)
int build_map(const char *input_file_name, FILE *output_file, uint32_t *asset_size)
{
json_object *root = json_object_from_file(input_file_name);
if (!root)
@ -188,283 +59,233 @@ int parse_map_for_content_and_write(const char *input_file_name, FILE *output_fi
json_object *tmp_obj;
if(!json_object_object_get_ex(root, "MapWidth", &tmp_obj))
if(json_get_object_of_type(root, "MapWidth", json_type_int, &tmp_obj))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"MapWidth\".");
return EXIT_FAILURE;
return_failure_int;
}
int map_width = json_object_get_int(tmp_obj);
uint16_t map_width = json_object_get_int(tmp_obj);
if(fwrite(&map_width, sizeof(map_width), 1, output_file) != 1)
if(json_get_object_of_type(root, "MapHeight", json_type_int, &tmp_obj))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
if(!json_object_object_get_ex(root, "MapHeight", &tmp_obj))
uint16_t map_height = json_object_get_int(tmp_obj);
if(file_write(&map_width, sizeof(map_width), 1, output_file))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"MapHeight\".");
return EXIT_FAILURE;
return_failure_int;
}
int map_height = json_object_get_int(tmp_obj);
*asset_size += sizeof(map_width);
if(fwrite(&map_height, sizeof(map_height), 1, output_file) != 1)
if(file_write(&map_height, sizeof(map_height), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
// Background Layer 1
if(!json_object_object_get_ex(root, "BackgroundLayer1", &tmp_obj))
*asset_size += sizeof(map_height);
// BackgroundLayers
json_object *backgroundlayers;
if(json_get_object_of_type(root, "BackgroundLayers", json_type_array, &backgroundlayers))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"BackgroundLayer1\".");
return EXIT_FAILURE;
return_failure_int;
}
if(!json_object_is_type(tmp_obj, json_type_array))
uint8_t layer_count = json_object_array_length(backgroundlayers);
if(file_write(&layer_count, sizeof(layer_count), 1, output_file))
{
json_object_put(root);
error_printf("Map background layer 1 is not of type array.");
return EXIT_FAILURE;
return_failure_int;
}
uint16_t layer_data[map_width * map_height];
*asset_size += sizeof(layer_count);
for(size_t i = 0; i < (size_t)map_width * (size_t)map_height; i++)
{
json_object *tile = json_object_array_get_idx(tmp_obj, i);
layer_data[i] = json_object_get_int(tile);
}
uint16_t layer_data[(size_t)map_width * (size_t)map_height];
if(fwrite(&layer_data, sizeof(uint16_t), map_width * map_height, output_file) != (size_t)map_width * (size_t)map_height)
for(uint8_t i = 0; i < layer_count; i++)
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
json_object *backgroundlayer;
if(json_get_idx_of_type(backgroundlayers, i, json_type_array, &backgroundlayer))
{
json_object_put(root);
return_failure_int;
}
// Background Layer 2
if(!json_object_object_get_ex(root, "BackgroundLayer2", &tmp_obj))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"BackgroundLayer2\".");
return EXIT_FAILURE;
}
for(size_t j = 0; j < (size_t)map_width * (size_t)map_height; j++)
{
if(json_get_idx_of_type(backgroundlayer, j, json_type_int, &tmp_obj))
{
json_object_put(root);
return_failure_int;
}
layer_data[j] = json_object_get_int(tmp_obj);
}
if(!json_object_is_type(tmp_obj, json_type_array))
{
json_object_put(root);
error_printf("Map background layer 1 is not of type array.");
return EXIT_FAILURE;
}
if(file_write(&layer_data, sizeof(*layer_data), (size_t)map_width * (size_t)map_height, output_file))
{
json_object_put(root);
return_failure_int;
}
for(size_t i = 0; i < (size_t)map_width * (size_t)map_height; i++)
{
json_object *tile = json_object_array_get_idx(tmp_obj, i);
layer_data[i] = json_object_get_int(tile);
}
if(fwrite(&layer_data, sizeof(uint16_t), map_width * map_height, output_file) != (size_t)map_width * (size_t)map_height)
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
// Background Layer 3
if(!json_object_object_get_ex(root, "BackgroundLayer3", &tmp_obj))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"BackgroundLayer3\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(tmp_obj, json_type_array))
{
json_object_put(root);
error_printf("Map background layer 1 is not of type array.");
return EXIT_FAILURE;
}
for(size_t i = 0; i < (size_t)map_width * (size_t)map_height; i++)
{
json_object *tile = json_object_array_get_idx(tmp_obj, i);
layer_data[i] = json_object_get_int(tile);
}
if(fwrite(&layer_data, sizeof(uint16_t), map_width * map_height, output_file) != (size_t)map_width * (size_t)map_height)
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
*asset_size += sizeof(layer_data);
}
// Foreground
if(!json_object_object_get_ex(root, "Foreground", &tmp_obj))
json_object *foregroundlayer;
if(json_get_object_of_type(root, "ForegroundLayer", json_type_array, &foregroundlayer))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"Foreground\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(tmp_obj, json_type_array))
{
json_object_put(root);
error_printf("Map background layer 1 is not of type array.");
return EXIT_FAILURE;
return_failure_int;
}
for(size_t i = 0; i < (size_t)map_width * (size_t)map_height; i++)
{
json_object *tile = json_object_array_get_idx(tmp_obj, i);
layer_data[i] = json_object_get_int(tile);
if(json_get_idx_of_type(foregroundlayer, i, json_type_int, &tmp_obj))
{
json_object_put(root);
return_failure_int;
}
layer_data[i] = json_object_get_int(tmp_obj);
}
if(fwrite(&layer_data, sizeof(uint16_t), map_width * map_height, output_file) != (size_t)map_width * (size_t)map_height)
if(file_write(&layer_data, sizeof(*layer_data), (size_t)map_width * (size_t)map_height, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(layer_data);
// Hitboxes
if(!json_object_object_get_ex(root, "Hitboxes", &tmp_obj))
json_object *hitboxes;
if(json_get_object_of_type(root, "Hitboxes", json_type_array, &hitboxes))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"Hitboxes\".");
return EXIT_FAILURE;
return_failure_int;
}
if(!json_object_is_type(tmp_obj, json_type_array))
{
json_object_put(root);
error_printf("Map background layer 1 is not of type array.");
return EXIT_FAILURE;
}
uint8_t hitboxes_layer[map_width * map_height];
uint8_t hitboxes_layer_data[(size_t)map_width * (size_t)map_height];
for(size_t i = 0; i < (size_t)map_width * (size_t)map_height; i++)
{
json_object *tile = json_object_array_get_idx(tmp_obj, i);
hitboxes_layer[i] = json_object_get_int(tile);
if(json_get_idx_of_type(hitboxes, i, json_type_int, &tmp_obj))
{
json_object_put(root);
return_failure_int;
}
hitboxes_layer_data[i] = json_object_get_int(tmp_obj);
}
if(fwrite(&hitboxes_layer, sizeof(uint8_t), map_width * map_height, output_file) != (size_t)map_width * (size_t)map_height)
if(file_write(&hitboxes_layer_data, sizeof(*hitboxes_layer_data), (size_t)map_width * (size_t)map_height, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(hitboxes_layer_data);
// Entities
json_object *entities;
if(!json_object_object_get_ex(root, "Entities", &entities))
if(json_get_object_of_type(root, "Entities", json_type_array, &entities))
{
json_object_put(root);
error_printf("Map file doesn't contain key \"Entities\".");
return EXIT_FAILURE;
return_failure_int;
}
uint32_t entities_nb = json_object_array_length(entities);
uint16_t entities_nb = json_object_array_length(entities);
if(fwrite(&entities_nb, sizeof(entities_nb), 1, output_file) != 1)
if(file_write(&entities_nb, sizeof(entities_nb), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(entities_nb);
for(uint32_t i = 0; i < entities_nb; i++)
{
json_object *entity = json_object_array_get_idx(entities, i);
if(!json_object_object_get_ex(entity, "ID", &tmp_obj))
if(json_get_object_of_type(entity, "ID", json_type_int, &tmp_obj))
{
json_object_put(root);
error_printf("Entity doesn't have key \"ID\".");
return EXIT_FAILURE;
}
if(!json_object_is_type(tmp_obj, json_type_int))
{
json_object_put(root);
error_printf("Entity ID is not of type int.");
return EXIT_FAILURE;
return_failure_int;
}
uint32_t entity_id = json_object_get_int(tmp_obj);
if(fwrite(&entity_id, sizeof(entity_id), 1, output_file) != 1)
if(file_write(&entity_id, sizeof(entity_id), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(entity_id);
json_object *components;
if(!json_object_object_get_ex(entity, "Components", &components))
if(json_get_object_of_type(entity, "Components", json_type_array, &components))
{
json_object_put(root);
error_printf("Entity doesn't have key \"Components\".");
return EXIT_FAILURE;
return_failure_int;
}
uint32_t components_nb = json_object_array_length(components);
uint16_t components_nb = json_object_array_length(components);
if(fwrite(&components_nb, sizeof(components_nb), 1, output_file) != 1)
if(file_write(&components_nb, sizeof(components_nb), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(components_nb);
for(uint32_t j = 0; j < components_nb; j++)
{
json_object *component = json_object_array_get_idx(components, j);
json_object *component;
if(json_get_idx_of_type(components, j, json_type_object, &component))
{
json_object_put(root);
return_failure_int;
}
json_object *attributes;
if(!json_object_object_get_ex(component, "Type", &tmp_obj))
if(json_get_object_of_type(component, "Type", json_type_string, &tmp_obj))
{
json_object_put(root);
error_printf("Component doesn't have key \"Type\".");
return EXIT_FAILURE;
return_failure_int;
}
if(!json_object_is_type(tmp_obj, json_type_string))
{
json_object_put(root);
error_printf("Component type is not of type string.");
return EXIT_FAILURE;
}
uint16_t component_type;
component_type_t component_type;
#define COMPONENT(NAME, ...) \
if(!strcmp(#NAME, json_object_get_string(tmp_obj))) \
component_type = NAME;
#include "components.def"
if(fwrite(&component_type, sizeof(uint32_t), 1, output_file) != 1)
if(file_write(&component_type, sizeof(component_type), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
if(!json_object_object_get_ex(component, "Attributes", &attributes))
*asset_size += sizeof(component_type);
if(json_get_object_of_type(component, "Attributes", json_type_array, &attributes))
{
json_object_put(root);
error_printf("Component doesn't have key \"Attributes\".");
return EXIT_FAILURE;
return_failure_int;
}
uint32_t attributes_nb = json_object_array_length(attributes);
@ -477,53 +298,54 @@ int parse_map_for_content_and_write(const char *input_file_name, FILE *output_fi
{
case json_type_int:
{
int value = json_object_get_int(attribute);
if(fwrite(&value, sizeof(value), 1, output_file) != 1)
uint32_t value = json_object_get_int(attribute);
if(file_write(&value, sizeof(value), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
*asset_size += sizeof(value);
break;
}
case json_type_double:
{
float value = json_object_get_double(attribute);
if(fwrite(&value, sizeof(value), 1, output_file) != 1)
if(file_write(&value, sizeof(value), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(value);
break;
}
case json_type_boolean:
{
bool value = json_object_get_boolean(attribute);
if(fwrite(&value, sizeof(value), 1, output_file) != 1)
if(file_write(&value, sizeof(value), 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += sizeof(value);
break;
}
case json_type_string:
{
const char *str = json_object_get_string(attribute);
if(fwrite(str, sizeof(char), strlen(str) + 1, output_file) != strlen(str) + 1)
if(file_write(str, sizeof(*str), strlen(str) + 1, output_file))
{
json_object_put(root);
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
return_failure_int;
}
*asset_size += (strlen(str) + 1) * sizeof(*str);
break;
}
default:
error_printf("Component attribute of type %s is not handled.", json_type_to_name(json_object_get_type(attribute)));
return EXIT_FAILURE;
}
}

View File

@ -0,0 +1,50 @@
#include "object.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "utils.h"
#include "image.h"
#include "map.h"
#include "errors.h"
int build_object(const char *input_file_path, FILE *output_file)
{
// Reserve space to write asset_size
uint32_t asset_size = 0;
if(file_write(&asset_size, sizeof(asset_size), 1, output_file)) return_failure_int;
const char *input_file_dot = strrchr(input_file_path, '.');
if(!input_file_dot)
{
error_printf("Input file \"%s\" doesn't have an extension.", input_file_path);
return EXIT_FAILURE;
}
const char *input_file_ext = input_file_dot + 1;
if(!strcmp(input_file_ext, "png"))
{
if(build_image(input_file_path, output_file, &asset_size)) return_failure_int;
}
else if(!strcmp(input_file_ext, "map"))
{
if(build_map(input_file_path, output_file, &asset_size)) return_failure_int;
}
else
{
error_printf("Extension \"%s\" not supported.", input_file_ext);
return EXIT_FAILURE;
}
if(fseek(output_file, 0, SEEK_SET))
{
error_printf("Failed to seek in output file : %d", errno);
return EXIT_FAILURE;
}
if(file_write(&asset_size, sizeof(asset_size), 1, output_file)) return_failure_int;
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,27 @@
#include "utils.h"
#include <stdio.h>
#include <stdlib.h>
#include "errors.h"
inline int file_read(void *ptr, size_t size, size_t nb, FILE *file)
{
if(fread(ptr, size, nb, file) != nb)
{
error_printf("Failed to read output file : %d", errno);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
inline int file_write(const void *ptr, size_t size, size_t nb, FILE *file)
{
if(fwrite(ptr, size, nb, file) != nb)
{
error_printf("Failed to write to output file : %d", errno);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}

View File

@ -2,85 +2,87 @@
"MapWidth": 32,
"MapHeight": 24,
"BackgroundLayer1": [
734, 733, 734, 734, 734, 732, 732, 733, 738, 707, 986, 987, 988, 648, 649, 650, 651, 652, 733, 732, 2069, 2070, 2071, 2072, 733, 734, 734, 734, 733, 1774, 1775, 1776,
986, 987, 988, 734, 733, 734, 1432, 734, 733, 734, 1035, 1036, 1037, 697, 698, 699, 700, 701, 734, 2163, 2118, 2119, 2120, 2121, 732, 546, 733, 732, 943, 944, 945, 733,
1035, 1036, 1037, 615, 1717, 732, 1481, 733, 732, 1083, 1084, 1085, 1086, 746, 747, 748, 749, 750, 733, 2166, 2167, 2168, 2169, 2170, 594, 595, 596, 991, 992, 993, 994, 995,
732, 1085, 1086, 664, 733, 734, 1530, 1531, 732, 733, 733, 734, 734, 795, 796, 797, 798, 733, 1378, 2215, 2216, 2217, 2218, 2219, 643, 644, 645, 1040, 1041, 1042, 1043, 1044,
733, 733, 733, 732, 714, 1578, 1579, 1580, 732, 733, 734, 733, 734, 734, 734, 846, 733, 734, 1427, 1428, 2265, 2266, 2267, 1497, 692, 693, 694, 1089, 1090, 1091, 1092, 1093,
732, 734, 732, 733, 732, 1627, 1628, 1629, 733, 733, 733, 734, 734, 732, 732, 1287, 734, 734, 1476, 1477, 2314, 2315, 734, 1546, 732, 742, 743, 1138, 1139, 1140, 1141, 1142,
733, 732, 732, 732, 734, 1676, 1677, 1678, 734, 732, 733, 734, 733, 85, 35, 85, 85, 36, 36, 733, 1283, 733, 733, 733, 732, 733, 734, 1187, 1188, 1189, 1190, 1191,
1923, 732, 733, 733, 732, 1725, 1726, 1727, 1728, 734, 33, 231, 230, 231, 230, 230, 230, 231, 230, 230, 34, 732, 733, 1644, 733, 733, 734, 734, 732, 734, 733, 733,
1972, 732, 908, 734, 732, 1774, 1775, 1776, 732, 33, 130, 131, 180, 180, 229, 720, 721, 229, 131, 131, 129, 230, 34, 732, 734, 733, 734, 733, 733, 734, 732, 734,
2021, 2022, 733, 733, 959, 732, 1823, 546, 33, 130, 228, 180, 229, 229, 229, 769, 770, 180, 229, 180, 227, 229, 129, 34, 734, 732, 1721, 733, 734, 734, 732, 733,
2070, 2071, 732, 733, 1008, 732, 594, 595, 596, 228, 280, 278, 278, 278, 278, 818, 819, 278, 278, 278, 276, 180, 227, 229, 733, 734, 1770, 1771, 733, 733, 734, 732,
2119, 2120, 733, 733, 734, 733, 643, 644, 645, 280, 279, 732, 733, 732, 732, 734, 732, 732, 732, 733, 277, 278, 276, 180, 734, 734, 1819, 1820, 733, 734, 734, 732,
2168, 2169, 734, 732, 733, 734, 692, 693, 694, 279, 733, 733, 734, 734, 734, 734, 734, 733, 733, 734, 733, 733, 277, 734, 732, 733, 733, 1869, 885, 733, 734, 732,
2217, 2218, 2219, 734, 733, 732, 733, 742, 734, 734, 732, 733, 732, 734, 733, 733, 732, 733, 734, 732, 732, 734, 732, 732, 732, 732, 732, 733, 934, 733, 734, 733,
2266, 2267, 733, 943, 944, 945, 732, 733, 734, 734, 732, 733, 732, 732, 734, 734, 733, 732, 734, 733, 732, 733, 732, 732, 734, 733, 546, 982, 983, 732, 1432, 733,
733, 733, 991, 992, 993, 994, 995, 733, 733, 85, 734, 734, 734, 732, 732, 732, 732, 732, 734, 733, 734, 734, 733, 733, 732, 594, 595, 596, 732, 734, 1481, 732,
734, 734, 1040, 1041, 1042, 1043, 1044, 732, 733, 732, 733, 734, 733, 734, 734, 734, 732, 734, 734, 734, 734, 733, 732, 732, 733, 643, 644, 645, 733, 733, 1530, 1531,
733, 733, 1089, 1090, 1091, 1092, 1093, 733, 733, 733, 733, 733, 732, 734, 35, 35, 36, 734, 734, 733, 732, 733, 734, 732, 734, 692, 693, 694, 734, 732, 1579, 1580,
734, 732, 1138, 1139, 1140, 1141, 1142, 732, 733, 734, 733, 732, 732, 734, 85, 36, 85, 732, 734, 734, 732, 733, 732, 733, 885, 741, 742, 733, 732, 1627, 1628, 1629,
732, 732, 1187, 1188, 1189, 1190, 734, 733, 733, 732, 733, 732, 733, 35, 35, 85, 35, 732, 732, 732, 733, 734, 734, 734, 934, 733, 732, 732, 732, 1676, 1677, 1678,
733, 734, 733, 734, 1238, 1721, 734, 732, 732, 734, 732, 732, 732, 36, 85, 85, 36, 732, 734, 734, 733, 732, 734, 733, 983, 732, 732, 732, 732, 1725, 1726, 1727,
733, 732, 733, 733, 1287, 1770, 1771, 733, 733, 733, 734, 732, 734, 85, 85, 35, 85, 732, 734, 732, 733, 732, 734, 733, 733, 732, 732, 734, 733, 1774, 1775, 1776,
734, 732, 734, 734, 734, 1819, 1820, 734, 733, 732, 732, 732, 734, 35, 35, 36, 35, 36, 732, 732, 734, 733, 732, 734, 734, 734, 732, 732, 734, 734, 733, 732,
732, 733, 733, 733, 733, 732, 732, 733, 732, 734, 733, 732, 734, 732, 85, 35, 36, 35, 734, 733, 733, 732, 734, 733, 734, 732, 733, 734, 732, 733, 733, 734
"BackgroundLayers": [
[
734, 733, 734, 734, 734, 732, 732, 733, 738, 707, 986, 987, 988, 648, 649, 650, 651, 652, 733, 732, 2069, 2070, 2071, 2072, 733, 734, 734, 734, 733, 1774, 1775, 1776,
986, 987, 988, 734, 733, 734, 1432, 734, 733, 734, 1035, 1036, 1037, 697, 698, 699, 700, 701, 734, 2163, 2118, 2119, 2120, 2121, 732, 546, 733, 732, 943, 944, 945, 733,
1035, 1036, 1037, 615, 1717, 732, 1481, 733, 732, 1083, 1084, 1085, 1086, 746, 747, 748, 749, 750, 733, 2166, 2167, 2168, 2169, 2170, 594, 595, 596, 991, 992, 993, 994, 995,
732, 1085, 1086, 664, 733, 734, 1530, 1531, 732, 733, 733, 734, 734, 795, 796, 797, 798, 733, 1378, 2215, 2216, 2217, 2218, 2219, 643, 644, 645, 1040, 1041, 1042, 1043, 1044,
733, 733, 733, 732, 714, 1578, 1579, 1580, 732, 733, 734, 733, 734, 734, 734, 846, 733, 734, 1427, 1428, 2265, 2266, 2267, 1497, 692, 693, 694, 1089, 1090, 1091, 1092, 1093,
732, 734, 732, 733, 732, 1627, 1628, 1629, 733, 733, 733, 734, 734, 732, 732, 1287, 734, 734, 1476, 1477, 2314, 2315, 734, 1546, 732, 742, 743, 1138, 1139, 1140, 1141, 1142,
733, 732, 732, 732, 734, 1676, 1677, 1678, 734, 732, 733, 734, 733, 85, 35, 85, 85, 36, 36, 733, 1283, 733, 733, 733, 732, 733, 734, 1187, 1188, 1189, 1190, 1191,
1923, 732, 733, 733, 732, 1725, 1726, 1727, 1728, 734, 33, 231, 230, 231, 230, 230, 230, 231, 230, 230, 34, 732, 733, 1644, 733, 733, 734, 734, 732, 734, 733, 733,
1972, 732, 908, 734, 732, 1774, 1775, 1776, 732, 33, 130, 131, 180, 180, 229, 720, 721, 229, 131, 131, 129, 230, 34, 732, 734, 733, 734, 733, 733, 734, 732, 734,
2021, 2022, 733, 733, 959, 732, 1823, 546, 33, 130, 228, 180, 229, 229, 229, 769, 770, 180, 229, 180, 227, 229, 129, 34, 734, 732, 1721, 733, 734, 734, 732, 733,
2070, 2071, 732, 733, 1008, 732, 594, 595, 596, 228, 280, 278, 278, 278, 278, 818, 819, 278, 278, 278, 276, 180, 227, 229, 733, 734, 1770, 1771, 733, 733, 734, 732,
2119, 2120, 733, 733, 734, 733, 643, 644, 645, 280, 279, 732, 733, 732, 732, 734, 732, 732, 732, 733, 277, 278, 276, 180, 734, 734, 1819, 1820, 733, 734, 734, 732,
2168, 2169, 734, 732, 733, 734, 692, 693, 694, 279, 733, 733, 734, 734, 734, 734, 734, 733, 733, 734, 733, 733, 277, 734, 732, 733, 733, 1869, 885, 733, 734, 732,
2217, 2218, 2219, 734, 733, 732, 733, 742, 734, 734, 732, 733, 732, 734, 733, 733, 732, 733, 734, 732, 732, 734, 732, 732, 732, 732, 732, 733, 934, 733, 734, 733,
2266, 2267, 733, 943, 944, 945, 732, 733, 734, 734, 732, 733, 732, 732, 734, 734, 733, 732, 734, 733, 732, 733, 732, 732, 734, 733, 546, 982, 983, 732, 1432, 733,
733, 733, 991, 992, 993, 994, 995, 733, 733, 85, 734, 734, 734, 732, 732, 732, 732, 732, 734, 733, 734, 734, 733, 733, 732, 594, 595, 596, 732, 734, 1481, 732,
734, 734, 1040, 1041, 1042, 1043, 1044, 732, 733, 732, 733, 734, 733, 734, 734, 734, 732, 734, 734, 734, 734, 733, 732, 732, 733, 643, 644, 645, 733, 733, 1530, 1531,
733, 733, 1089, 1090, 1091, 1092, 1093, 733, 733, 733, 733, 733, 732, 734, 35, 35, 36, 734, 734, 733, 732, 733, 734, 732, 734, 692, 693, 694, 734, 732, 1579, 1580,
734, 732, 1138, 1139, 1140, 1141, 1142, 732, 733, 734, 733, 732, 732, 734, 85, 36, 85, 732, 734, 734, 732, 733, 732, 733, 885, 741, 742, 733, 732, 1627, 1628, 1629,
732, 732, 1187, 1188, 1189, 1190, 734, 733, 733, 732, 733, 732, 733, 35, 35, 85, 35, 732, 732, 732, 733, 734, 734, 734, 934, 733, 732, 732, 732, 1676, 1677, 1678,
733, 734, 733, 734, 1238, 1721, 734, 732, 732, 734, 732, 732, 732, 36, 85, 85, 36, 732, 734, 734, 733, 732, 734, 733, 983, 732, 732, 732, 732, 1725, 1726, 1727,
733, 732, 733, 733, 1287, 1770, 1771, 733, 733, 733, 734, 732, 734, 85, 85, 35, 85, 732, 734, 732, 733, 732, 734, 733, 733, 732, 732, 734, 733, 1774, 1775, 1776,
734, 732, 734, 734, 734, 1819, 1820, 734, 733, 732, 732, 732, 734, 35, 35, 36, 35, 36, 732, 732, 734, 733, 732, 734, 734, 734, 732, 732, 734, 734, 733, 732,
732, 733, 733, 733, 733, 732, 732, 733, 732, 734, 733, 732, 734, 732, 85, 35, 36, 35, 734, 733, 733, 732, 734, 733, 734, 732, 733, 734, 732, 733, 733, 734
],
[
937, 938, 939, 940, 1127, 1128, 1621, 737, 706, 0, 708, 0, 647, 0, 2412, 0, 0, 2414, 2113, 2114, 1298, 1299, 1300, 1301, 496, 497, 1052, 1053, 1773, 895, 896, 0,
0, 0, 565, 989, 1176, 1177, 0, 786, 787, 1034, 757, 758, 696, 0, 0, 0, 2412, 0, 702, 2117, 1347, 1348, 1349, 544, 545, 1352, 1101, 1102, 0, 0, 0, 1825,
0, 613, 614, 0, 616, 1718, 618, 1482, 1081, 805, 806, 807, 745, 2411, 0, 0, 0, 2413, 751, 1330, 1396, 1397, 1398, 593, 1400, 1401, 990, 0, 0, 0, 0, 0,
1084, 662, 663, 0, 1766, 1767, 0, 0, 1479, 854, 855, 1134, 792, 0, 0, 0, 2413, 799, 0, 1379, 1380, 1446, 1447, 642, 1449, 1450, 1039, 0, 0, 0, 0, 0,
1133, 1134, 712, 713, 0, 715, 716, 0, 1528, 903, 1182, 1183, 1184, 1047, 1048, 0, 2373, 2352, 0, 0, 1429, 1495, 1496, 0, 1498, 1499, 1088, 0, 0, 0, 0, 0,
1182, 1183, 1184, 762, 763, 764, 765, 0, 951, 1382, 953, 954, 0, 1285, 1286, 0, 1288, 0, 0, 1233, 1478, 1235, 2230, 0, 741, 1548, 1137, 0, 0, 0, 0, 0,
539, 809, 810, 811, 1675, 813, 814, 0, 1679, 1001, 520, 2454, 1912, 307, 359, 359, 359, 359, 308, 1526, 1592, 2278, 2279, 1595, 790, 791, 1186, 1575, 0, 0, 0, 0,
0, 858, 859, 860, 1724, 862, 863, 0, 0, 1442, 307, 359, 359, 355, 0, 0, 0, 0, 354, 359, 308, 1642, 543, 784, 1182, 1183, 1184, 1236, 1479, 1238, 1239, 1240,
0, 907, 0, 909, 1773, 911, 912, 497, 709, 307, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 359, 308, 1693, 834, 1382, 1672, 1285, 1528, 1287, 1288, 0,
0, 956, 957, 958, 0, 1823, 961, 0, 307, 355, 0, 1491, 1492, 1493, 0, 0, 0, 0, 450, 451, 2059, 0, 354, 308, 883, 1720, 0, 1334, 1335, 1336, 1337, 1149,
0, 914, 1006, 1007, 0, 1009, 0, 0, 0, 0, 0, 1540, 1541, 1542, 0, 0, 0, 0, 499, 500, 1961, 2009, 0, 132, 508, 1769, 0, 0, 2276, 1196, 1197, 1198,
962, 963, 1055, 1622, 1057, 1058, 0, 0, 0, 0, 1230, 0, 0, 1618, 0, 0, 0, 2352, 0, 0, 0, 490, 0, 132, 557, 1818, 0, 835, 1821, 1245, 1246, 1247,
1011, 1012, 2170, 1643, 1644, 1645, 0, 0, 0, 0, 2401, 1681, 1682, 0, 0, 0, 0, 0, 1622, 793, 0, 539, 0, 132, 606, 1867, 1868, 933, 0, 1294, 1295, 1296,
0, 1061, 893, 1692, 1693, 740, 1381, 0, 84, 793, 0, 0, 506, 0, 0, 0, 0, 0, 0, 0, 0, 2504, 31, 83, 850, 656, 497, 933, 0, 1343, 1344, 1345,
0, 941, 2268, 0, 0, 0, 1430, 791, 82, 181, 32, 1573, 0, 2450, 505, 0, 0, 0, 1000, 0, 0, 31, 83, 2114, 2115, 545, 0, 547, 0, 984, 0, 1394,
2315, 2316, 0, 1161, 0, 0, 0, 1183, 1184, 356, 82, 32, 0, 0, 0, 0, 0, 0, 0, 31, 181, 83, 0, 2163, 2164, 0, 0, 0, 1032, 1033, 0, 1443,
1207, 1039, 1209, 1210, 0, 0, 0, 2278, 705, 2363, 2362, 82, 181, 182, 182, 181, 181, 181, 181, 83, 2512, 793, 2211, 2179, 2180, 0, 0, 0, 1081, 1529, 0, 0,
1589, 1590, 1258, 1259, 1260, 1574, 1575, 0, 0, 0, 793, 2366, 2471, 2472, 307, 359, 308, 2422, 2423, 0, 705, 2509, 1182, 1183, 2229, 837, 0, 0, 695, 1578, 0, 0,
1638, 1639, 1307, 1308, 1309, 1623, 1624, 0, 0, 0, 0, 2401, 0, 0, 310, 0, 358, 2471, 2472, 0, 0, 2513, 0, 2277, 0, 886, 0, 743, 744, 0, 0, 0,
1687, 1688, 1356, 1357, 1671, 1672, 1191, 0, 0, 471, 0, 0, 0, 307, 355, 0, 358, 0, 0, 0, 0, 849, 0, 0, 0, 790, 791, 792, 1675, 0, 0, 0,
1231, 1232, 1236, 1237, 1720, 1408, 2181, 2182, 0, 2463, 0, 0, 0, 310, 0, 305, 357, 0, 1181, 0, 0, 0, 0, 490, 0, 1182, 1183, 707, 1724, 0, 0, 0,
1280, 1281, 1454, 1286, 1769, 0, 0, 2231, 2461, 0, 1279, 754, 0, 310, 0, 354, 308, 0, 0, 0, 0, 2412, 2415, 539, 1032, 1033, 932, 756, 1773, 0, 0, 0,
1329, 1330, 1334, 1335, 1336, 0, 0, 2280, 1181, 0, 2462, 0, 0, 356, 306, 0, 354, 308, 0, 0, 2597, 2413, 892, 0, 1081, 980, 981, 805, 806, 1823, 1824, 1825,
1378, 1379, 1552, 1553, 2324, 2325, 2326, 2327, 0, 0, 843, 0, 0, 1000, 356, 306, 0, 358, 0, 793, 0, 0, 2414, 1080, 0, 1029, 1030, 854, 855, 856, 0, 0
],
[
0, 0, 0, 0, 1619, 1620, 1383, 1384, 0, 0, 0, 0, 2415, 0, 0, 0, 0, 0, 653, 2068, 0, 0, 0, 0, 1302, 1303, 498, 893, 894, 0, 0, 0,
0, 0, 0, 566, 1668, 1669, 0, 1433, 755, 756, 0, 0, 0, 0, 0, 0, 0, 0, 1280, 2117, 0, 0, 0, 1350, 1351, 0, 547, 942, 0, 0, 0, 946,
0, 0, 0, 0, 0, 1480, 0, 0, 804, 0, 0, 0, 0, 0, 0, 0, 0, 1328, 1329, 0, 0, 0, 0, 1399, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 665, 1529, 0, 0, 853, 0, 0, 856, 1193, 0, 0, 0, 0, 1377, 0, 0, 1445, 0, 0, 1448, 0, 0, 0, 0, 0, 0, 0, 0,
0, 711, 0, 0, 0, 0, 0, 0, 902, 2323, 2324, 2325, 2326, 2327, 845, 0, 847, 848, 0, 0, 1494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
490, 760, 761, 0, 0, 0, 0, 0, 1630, 952, 2373, 2374, 2375, 2376, 0, 0, 0, 1475, 0, 0, 1234, 1544, 2316, 0, 1547, 0, 0, 0, 0, 0, 0, 0,
1874, 1875, 0, 0, 812, 0, 0, 0, 0, 1680, 1002, 1003, 0, 1334, 1335, 1336, 1337, 1524, 1525, 1282, 1592, 1284, 494, 735, 1596, 0, 1574, 0, 0, 0, 0, 0,
0, 1924, 0, 0, 861, 0, 0, 0, 0, 661, 1443, 1863, 0, 0, 0, 0, 0, 0, 0, 1331, 1332, 1333, 1643, 0, 785, 0, 1623, 1624, 1237, 0, 1050, 1051,
0, 1973, 1974, 0, 910, 0, 496, 0, 1777, 710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1131, 1692, 833, 0, 1671, 0, 2177, 1286, 1098, 1099, 1100,
0, 0, 2023, 867, 0, 960, 545, 0, 547, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 882, 459, 460, 0, 2226, 2227, 1147, 1148, 0,
0, 0, 2072, 916, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2412, 0, 0, 0, 358, 1919, 509, 0, 0, 1772, 0, 0, 0,
0, 0, 2121, 1594, 966, 642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, 1968, 558, 0, 0, 836, 837, 0, 0,
0, 0, 1013, 1014, 1015, 691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, 2017, 607, 0, 0, 0, 886, 0, 0,
0, 0, 1062, 894, 895, 736, 741, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 357, 2066, 496, 0, 498, 0, 935, 1383, 1384,
1109, 1110, 942, 1112, 1113, 1114, 790, 0, 356, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 357, 0, 544, 0, 0, 0, 548, 1431, 0, 1433,
1158, 990, 1160, 0, 1162, 1163, 1164, 2228, 0, 2366, 309, 306, 0, 0, 0, 0, 0, 0, 0, 305, 309, 357, 0, 0, 593, 0, 0, 0, 597, 1480, 0, 1482,
0, 1208, 0, 0, 1211, 1212, 0, 0, 0, 0, 0, 356, 309, 309, 309, 309, 309, 309, 309, 357, 0, 0, 0, 2212, 642, 0, 0, 0, 646, 0, 0, 0,
1256, 1088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2404, 2405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2228, 691, 0, 0, 0, 1577, 0, 0, 0,
0, 1137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2601, 2602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1626, 0, 0, 0,
0, 1186, 0, 0, 1358, 1359, 1673, 0, 0, 0, 0, 0, 0, 0, 2503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 935, 657, 658, 659, 0, 0, 0,
0, 1404, 1405, 1406, 1407, 0, 1240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 984, 706, 0, 708, 0, 0, 0,
1452, 1453, 0, 1455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2504, 0, 0, 0, 0, 0, 0, 0, 0, 931, 755, 0, 757, 758, 0, 0,
1501, 1502, 1503, 1504, 1818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 804, 0, 0, 807, 0, 0,
0, 0, 1380, 0, 494, 1868, 1869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 853, 0, 0, 0, 0, 0
]
],
"BackgroundLayer2": [
937, 938, 939, 940, 1127, 1128, 1621, 737, 706, 0, 708, 0, 647, 0, 2412, 0, 0, 2414, 2113, 2114, 1298, 1299, 1300, 1301, 496, 497, 1052, 1053, 1773, 895, 896, 0,
0, 0, 565, 989, 1176, 1177, 0, 786, 787, 1034, 757, 758, 696, 0, 0, 0, 2412, 0, 702, 2117, 1347, 1348, 1349, 544, 545, 1352, 1101, 1102, 0, 0, 0, 1825,
0, 613, 614, 0, 616, 1718, 618, 1482, 1081, 805, 806, 807, 745, 2411, 0, 0, 0, 2413, 751, 1330, 1396, 1397, 1398, 593, 1400, 1401, 990, 0, 0, 0, 0, 0,
1084, 662, 663, 0, 1766, 1767, 0, 0, 1479, 854, 855, 1134, 792, 0, 0, 0, 2413, 799, 0, 1379, 1380, 1446, 1447, 642, 1449, 1450, 1039, 0, 0, 0, 0, 0,
1133, 1134, 712, 713, 0, 715, 716, 0, 1528, 903, 1182, 1183, 1184, 1047, 1048, 0, 2373, 2352, 0, 0, 1429, 1495, 1496, 0, 1498, 1499, 1088, 0, 0, 0, 0, 0,
1182, 1183, 1184, 762, 763, 764, 765, 0, 951, 1382, 953, 954, 0, 1285, 1286, 0, 1288, 0, 0, 1233, 1478, 1235, 2230, 0, 741, 1548, 1137, 0, 0, 0, 0, 0,
539, 809, 810, 811, 1675, 813, 814, 0, 1679, 1001, 520, 2454, 1912, 307, 359, 359, 359, 359, 308, 1526, 1592, 2278, 2279, 1595, 790, 791, 1186, 1575, 0, 0, 0, 0,
0, 858, 859, 860, 1724, 862, 863, 0, 0, 1442, 307, 359, 359, 355, 0, 0, 0, 0, 354, 359, 308, 1642, 543, 784, 1182, 1183, 1184, 1236, 1479, 1238, 1239, 1240,
0, 907, 0, 909, 1773, 911, 912, 497, 709, 307, 355, 0, 0, 0, 0, 0, 0, 0, 0, 0, 354, 359, 308, 1693, 834, 1382, 1672, 1285, 1528, 1287, 1288, 0,
0, 956, 957, 958, 0, 1823, 961, 0, 307, 355, 0, 1491, 1492, 1493, 0, 0, 0, 0, 450, 451, 2059, 0, 354, 308, 883, 1720, 0, 1334, 1335, 1336, 1337, 1149,
0, 914, 1006, 1007, 0, 1009, 0, 0, 0, 0, 0, 1540, 1541, 1542, 0, 0, 0, 0, 499, 500, 1961, 2009, 0, 132, 508, 1769, 0, 0, 2276, 1196, 1197, 1198,
962, 963, 1055, 1622, 1057, 1058, 0, 0, 0, 0, 1230, 0, 0, 1618, 0, 0, 0, 2352, 0, 0, 0, 490, 0, 132, 557, 1818, 0, 835, 1821, 1245, 1246, 1247,
1011, 1012, 2170, 1643, 1644, 1645, 0, 0, 0, 0, 2401, 1681, 1682, 0, 0, 0, 0, 0, 1622, 793, 0, 539, 0, 132, 606, 1867, 1868, 933, 0, 1294, 1295, 1296,
0, 1061, 893, 1692, 1693, 740, 1381, 0, 84, 793, 0, 0, 506, 0, 0, 0, 0, 0, 0, 0, 0, 2504, 31, 83, 850, 656, 497, 933, 0, 1343, 1344, 1345,
0, 941, 2268, 0, 0, 0, 1430, 791, 82, 181, 32, 1573, 0, 2450, 505, 0, 0, 0, 1000, 0, 0, 31, 83, 2114, 2115, 545, 0, 547, 0, 984, 0, 1394,
2315, 2316, 0, 1161, 0, 0, 0, 1183, 1184, 356, 82, 32, 0, 0, 0, 0, 0, 0, 0, 31, 181, 83, 0, 2163, 2164, 0, 0, 0, 1032, 1033, 0, 1443,
1207, 1039, 1209, 1210, 0, 0, 0, 2278, 705, 2363, 2362, 82, 181, 182, 182, 181, 181, 181, 181, 83, 2512, 793, 2211, 2179, 2180, 0, 0, 0, 1081, 1529, 0, 0,
1589, 1590, 1258, 1259, 1260, 1574, 1575, 0, 0, 0, 793, 2366, 2471, 2472, 307, 359, 308, 2422, 2423, 0, 705, 2509, 1182, 1183, 2229, 837, 0, 0, 695, 1578, 0, 0,
1638, 1639, 1307, 1308, 1309, 1623, 1624, 0, 0, 0, 0, 2401, 0, 0, 310, 0, 358, 2471, 2472, 0, 0, 2513, 0, 2277, 0, 886, 0, 743, 744, 0, 0, 0,
1687, 1688, 1356, 1357, 1671, 1672, 1191, 0, 0, 471, 0, 0, 0, 307, 355, 0, 358, 0, 0, 0, 0, 849, 0, 0, 0, 790, 791, 792, 1675, 0, 0, 0,
1231, 1232, 1236, 1237, 1720, 1408, 2181, 2182, 0, 2463, 0, 0, 0, 310, 0, 305, 357, 0, 1181, 0, 0, 0, 0, 490, 0, 1182, 1183, 707, 1724, 0, 0, 0,
1280, 1281, 1454, 1286, 1769, 0, 0, 2231, 2461, 0, 1279, 754, 0, 310, 0, 354, 308, 0, 0, 0, 0, 2412, 2415, 539, 1032, 1033, 932, 756, 1773, 0, 0, 0,
1329, 1330, 1334, 1335, 1336, 0, 0, 2280, 1181, 0, 2462, 0, 0, 356, 306, 0, 354, 308, 0, 0, 2597, 2413, 892, 0, 1081, 980, 981, 805, 806, 1823, 1824, 1825,
1378, 1379, 1552, 1553, 2324, 2325, 2326, 2327, 0, 0, 843, 0, 0, 1000, 356, 306, 0, 358, 0, 793, 0, 0, 2414, 1080, 0, 1029, 1030, 854, 855, 856, 0, 0
],
"BackgroundLayer3": [
0, 0, 0, 0, 1619, 1620, 1383, 1384, 0, 0, 0, 0, 2415, 0, 0, 0, 0, 0, 653, 2068, 0, 0, 0, 0, 1302, 1303, 498, 893, 894, 0, 0, 0,
0, 0, 0, 566, 1668, 1669, 0, 1433, 755, 756, 0, 0, 0, 0, 0, 0, 0, 0, 1280, 2117, 0, 0, 0, 1350, 1351, 0, 547, 942, 0, 0, 0, 946,
0, 0, 0, 0, 0, 1480, 0, 0, 804, 0, 0, 0, 0, 0, 0, 0, 0, 1328, 1329, 0, 0, 0, 0, 1399, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 665, 1529, 0, 0, 853, 0, 0, 856, 1193, 0, 0, 0, 0, 1377, 0, 0, 1445, 0, 0, 1448, 0, 0, 0, 0, 0, 0, 0, 0,
0, 711, 0, 0, 0, 0, 0, 0, 902, 2323, 2324, 2325, 2326, 2327, 845, 0, 847, 848, 0, 0, 1494, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
490, 760, 761, 0, 0, 0, 0, 0, 1630, 952, 2373, 2374, 2375, 2376, 0, 0, 0, 1475, 0, 0, 1234, 1544, 2316, 0, 1547, 0, 0, 0, 0, 0, 0, 0,
1874, 1875, 0, 0, 812, 0, 0, 0, 0, 1680, 1002, 1003, 0, 1334, 1335, 1336, 1337, 1524, 1525, 1282, 1592, 1284, 494, 735, 1596, 0, 1574, 0, 0, 0, 0, 0,
0, 1924, 0, 0, 861, 0, 0, 0, 0, 661, 1443, 1863, 0, 0, 0, 0, 0, 0, 0, 1331, 1332, 1333, 1643, 0, 785, 0, 1623, 1624, 1237, 0, 1050, 1051,
0, 1973, 1974, 0, 910, 0, 496, 0, 1777, 710, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1131, 1692, 833, 0, 1671, 0, 2177, 1286, 1098, 1099, 1100,
0, 0, 2023, 867, 0, 960, 545, 0, 547, 548, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 882, 459, 460, 0, 2226, 2227, 1147, 1148, 0,
0, 0, 2072, 916, 0, 593, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2412, 0, 0, 0, 358, 1919, 509, 0, 0, 1772, 0, 0, 0,
0, 0, 2121, 1594, 966, 642, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, 1968, 558, 0, 0, 836, 837, 0, 0,
0, 0, 1013, 1014, 1015, 691, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 358, 2017, 607, 0, 0, 0, 886, 0, 0,
0, 0, 1062, 894, 895, 736, 741, 0, 310, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 357, 2066, 496, 0, 498, 0, 935, 1383, 1384,
1109, 1110, 942, 1112, 1113, 1114, 790, 0, 356, 306, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 305, 357, 0, 544, 0, 0, 0, 548, 1431, 0, 1433,
1158, 990, 1160, 0, 1162, 1163, 1164, 2228, 0, 2366, 309, 306, 0, 0, 0, 0, 0, 0, 0, 305, 309, 357, 0, 0, 593, 0, 0, 0, 597, 1480, 0, 1482,
0, 1208, 0, 0, 1211, 1212, 0, 0, 0, 0, 0, 356, 309, 309, 309, 309, 309, 309, 309, 357, 0, 0, 0, 2212, 642, 0, 0, 0, 646, 0, 0, 0,
1256, 1088, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2404, 2405, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2228, 691, 0, 0, 0, 1577, 0, 0, 0,
0, 1137, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2601, 2602, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1626, 0, 0, 0,
0, 1186, 0, 0, 1358, 1359, 1673, 0, 0, 0, 0, 0, 0, 0, 2503, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 935, 657, 658, 659, 0, 0, 0,
0, 1404, 1405, 1406, 1407, 0, 1240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 984, 706, 0, 708, 0, 0, 0,
1452, 1453, 0, 1455, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2504, 0, 0, 0, 0, 0, 0, 0, 0, 931, 755, 0, 757, 758, 0, 0,
1501, 1502, 1503, 1504, 1818, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 804, 0, 0, 807, 0, 0,
0, 0, 1380, 0, 494, 1868, 1869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 853, 0, 0, 0, 0, 0
],
"Foreground": [
"ForegroundLayer": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1231, 1232, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 567, 1431, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1281, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 617, 0, 0, 1483, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,

View File

@ -30,5 +30,4 @@
eJwL52JgCB/Fo3gUj+IhhiOhmB52RWDBxMhRy25S5anpBnL9Rg03kGsGLfw/EHaTmg5oZTeutECrND+KR/Eopj0GAGrPIzU=
</data>
</layer>
<objectgroup id="13" name="Entities"/>
</map>

View File

@ -2,63 +2,47 @@
"MapWidth": 14,
"MapHeight": 16,
"BackgroundLayer1": [
13, 157, 157, 157, 157, 157, 245, 247, 157, 157, 157, 157, 157, 14,
108, 1, 2, 2, 2, 2, 245, 247, 2, 2, 2, 2, 3, 156,
108, 50, 51, 51, 51, 51, 245, 247, 51, 51, 51, 51, 52, 156,
108, 196, 197, 197, 197, 197, 151, 150, 197, 197, 197, 197, 198, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 294, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 296, 156,
62, 107, 107, 107, 107, 107, 69, 70, 107, 107, 107, 107, 107, 63
"BackgroundLayers": [
[
13, 157, 157, 157, 157, 157, 245, 247, 157, 157, 157, 157, 157, 14,
108, 1, 2, 2, 2, 2, 245, 247, 2, 2, 2, 2, 3, 156,
108, 50, 51, 51, 51, 51, 245, 247, 51, 51, 51, 51, 52, 156,
108, 196, 197, 197, 197, 197, 151, 150, 197, 197, 197, 197, 198, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 245, 246, 246, 246, 246, 246, 246, 246, 246, 246, 246, 247, 156,
108, 294, 295, 295, 295, 295, 295, 295, 295, 295, 295, 295, 296, 156,
62, 107, 107, 107, 107, 107, 0, 0, 107, 107, 107, 107, 107, 63
],
[
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 71, 72, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 120, 121, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
]
],
"BackgroundLayer2": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 120, 121, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
],
"BackgroundLayer3": [
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
],
"Foreground": [
"ForegroundLayer": [
0, 0, 0, 0, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 71, 72, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
@ -72,7 +56,7 @@
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 20, 21, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0
],
"Hitboxes": [
0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0,

View File

@ -1,11 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.10" tiledversion="1.12.1" orientation="orthogonal" renderorder="right-down" width="14" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="9" nextobjectid="13">
<map version="1.10" tiledversion="1.12.1" orientation="orthogonal" renderorder="right-down" width="14" height="16" tilewidth="16" tileheight="16" infinite="0" nextlayerid="10" nextobjectid="13">
<editorsettings>
<export target="dungeon_room_1.json" format="custom"/>
<export target="dungeon_room_1.map" format="custom"/>
</editorsettings>
<tileset firstgid="1" source="../tileset/tileset.tsx"/>
<tileset firstgid="2647" source="hiitboxes.tsx"/>
<layer id="1" name="BackgroundLayer1" width="14" height="16">
<layer id="1" name="Background1" width="14" height="16">
<data encoding="csv">
14,158,158,158,158,158,246,248,158,158,158,158,158,15,
109,2,3,3,3,3,246,248,3,3,3,3,4,157,
@ -22,13 +22,13 @@
109,246,247,247,247,247,247,247,247,247,247,247,248,157,
109,246,247,247,247,247,247,247,247,247,247,247,248,157,
109,295,296,296,296,296,296,296,296,296,296,296,297,157,
63,108,108,108,108,108,70,71,108,108,108,108,108,64
63,108,108,108,108,108,1,1,108,108,108,108,108,64
</data>
</layer>
<layer id="2" name="BackgroundLayer2" width="14" height="16">
<layer id="9" name="Background2" width="14" height="16">
<data encoding="csv">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,72,73,1,1,1,1,1,1,
1,1,1,1,1,1,121,122,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@ -43,32 +43,12 @@
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1
</data>
</layer>
<layer id="3" name="BackgroundLayer3" width="14" height="16">
<data encoding="csv">
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1
</data>
</layer>
<layer id="4" name="Foreground" width="14" height="16">
<data encoding="csv">
1,1,1,1,1,1,23,24,1,1,1,1,1,1,
1,1,1,1,1,1,72,73,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@ -82,7 +62,7 @@
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,21,22,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1
1,1,1,1,1,1,70,71,1,1,1,1,1,1
</data>
</layer>
<layer id="7" name="Hitboxes" width="14" height="16">

View File

@ -5,37 +5,30 @@ function stringifyFloat(floatNumber)
return String(floatNumber);
}
function writeTileLayer(tileLayer, file)
function writeLayerContent(output_file, layer)
{
file.writeLine(" \"" + tileLayer.name + "\": [");
for(let cell_y = 0; cell_y < tileLayer.height; ++cell_y)
for(let cell_y = 0; cell_y < layer.height; ++cell_y)
{
file.write(" ");
output_file.write(" ");
for(let cell_x = 0; cell_x < tileLayer.width; ++cell_x)
for(let cell_x = 0; cell_x < layer.width; ++cell_x)
{
file.write(" " + tileLayer.cellAt(cell_x, cell_y).tileId)
if(cell_x < tileLayer.width - 1 || cell_y < tileLayer.height - 1)
file.write(",");
output_file.file.write(" " + layer.cellAt(cell_x, cell_y).tileId)
if(cell_x < layer.width - 1 || cell_y < layer.height - 1)
output_file.file.write(",");
}
file.writeLine("");
output_file.file.writeLine("");
}
file.writeLine(" ],");
}
function writeEntities(objectLayer, file)
function writeEntities(output_file, entitieslayer)
{
file.writeLine(" \"Entities\": [");
let entities = [];
for(let i = 0; i < objectLayer.objectCount; i++)
for(let i = 0; i < entitieslayer.objectCount; i++)
{
let entity = objectLayer.objectAt(i);
let entity = entitieslayer.objectAt(i);
if(entity.name)
{
@ -54,46 +47,51 @@ function writeEntities(objectLayer, file)
{
let entity = entities[i];
file.writeLine(" {");
file.writeLine(" \"ID\":" + entity.name + ",");
file.writeLine(" \"Components\": [");
output_file.writeLine("{");
output_file.indent_add(2);
output_file.writeLine("\"ID\":" + entity.name + ",");
output_file.writeLine("\"Components\": [");
let components = entity.properties()["components"];
let nb_components = Object.keys(components).length;
output_file.indent_add(2);
for(let j = 0; j < nb_components; j++)
{
let component = components[j];
let component_type = component[0];
file.writeLine(" {");
output_file.writeLine("{");
file.write(" \"Type\": \"" + component_type + "\"");
output_file.indent_add(2);
output_file.write("\"Type\": \"" + component_type + "\"");
if(component.length > 1)
{
file.writeLine(",");
file.writeLine(" \"Attributes\": [");
output_file.file.writeLine(",");
output_file.writeLine("\"Attributes\": [");
}
// Write atributes, speciale cases need speciale treatment.
if(component_type == "TRANSFORM_COMPONENT")
{
file.writeLine(",");
file.writeLine(" \"Attributes\": [");
file.writeLine(" " + stringifyFloat(entity.x) + ",");
file.writeLine(" " + stringifyFloat(entity.y) + ",");
file.writeLine(" " + stringifyFloat(entity.width) + ",");
file.writeLine(" " + stringifyFloat(entity.height));
file.writeLine(" ]");
output_file.file.writeLine(",");
output_file.writeLine("\"Attributes\": [");
output_file.writeLine(" " + stringifyFloat(entity.x) + ",");
output_file.writeLine(" " + stringifyFloat(entity.y) + ",");
output_file.writeLine(" " + stringifyFloat(entity.width) + ",");
output_file.writeLine(" " + stringifyFloat(entity.height));
output_file.writeLine("]");
}
else if(component_type == "HITBOX_COMPONENT")
{
let hitbox;
for(let k = 0; k < objectLayer.objectCount; k++)
for(let k = 0; k < entitieslayer.objectCount; k++)
{
hitbox = objectLayer.objectAt(k);
hitbox = entitieslayer.objectAt(k);
if(hitbox.id === component[1].id)
break;
}
@ -103,18 +101,18 @@ function writeEntities(objectLayer, file)
let width = hitbox.width / entity.width;
let height = hitbox.height / entity.height;
file.writeLine(" " + stringifyFloat(x) + ",");
file.writeLine(" " + stringifyFloat(y) + ",");
file.writeLine(" " + stringifyFloat(width) + ",");
file.writeLine(" " + stringifyFloat(height));
output_file.writeLine(" " + stringifyFloat(x) + ",");
output_file.writeLine(" " + stringifyFloat(y) + ",");
output_file.writeLine(" " + stringifyFloat(width) + ",");
output_file.writeLine(" " + stringifyFloat(height));
}
else if(component_type == "INTERACT_COMPONENT")
{
let interact_box;
for(let k = 0; k < objectLayer.objectCount; k++)
for(let k = 0; k < entitieslayer.objectCount; k++)
{
interact_box = objectLayer.objectAt(k);
interact_box = entitieslayer.objectAt(k);
if(interact_box.id === component[1].id)
break;
}
@ -124,37 +122,37 @@ function writeEntities(objectLayer, file)
let width = interact_box.width / entity.width;
let height = interact_box.height / entity.height;
file.writeLine(" " + stringifyFloat(x) + ",");
file.writeLine(" " + stringifyFloat(y) + ",");
file.writeLine(" " + stringifyFloat(width) + ",");
file.writeLine(" " + stringifyFloat(height) + ",");
output_file.writeLine(" " + stringifyFloat(x) + ",");
output_file.writeLine(" " + stringifyFloat(y) + ",");
output_file.writeLine(" " + stringifyFloat(width) + ",");
output_file.writeLine(" " + stringifyFloat(height) + ",");
file.writeLine(" " + component[2] + ",");
file.writeLine(" " + component[3] + ",");
file.writeLine(" " + component[4]);
output_file.writeLine(" " + component[2] + ",");
output_file.writeLine(" " + component[3] + ",");
output_file.writeLine(" " + component[4]);
}
else if(component_type == "SPRITE_COMPONENT")
{
file.writeLine(" \"" + component[1] + "\"");
output_file.writeLine(" \"" + component[1] + "\"");
}
else if(component_type == "ANIMATION_SYSTEM")
{
file.writeLine(" " + component[1] + ",");
file.writeLine(" " + component[2] + ",");
file.writeLine(" " + stringifyFloat(component[3]) + ",");
file.writeLine(" " + component[4] + ",");
file.writeLine(" " + component[5] + ",");
file.writeLine(" " + component[6]);
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2] + ",");
output_file.writeLine(" " + stringifyFloat(component[3]) + ",");
output_file.writeLine(" " + component[4] + ",");
output_file.writeLine(" " + component[5] + ",");
output_file.writeLine(" " + component[6]);
}
else if(component_type == "LEVER_COMPONENT")
{
file.writeLine(" " + component[1] + ",");
file.writeLine(" " + component[2]);
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2]);
}
else if(component_type == "DOOR_COMPONENT")
{
file.writeLine(" " + component[1] + ",");
file.writeLine(" " + component[2]);
output_file.writeLine(" " + component[1] + ",");
output_file.writeLine(" " + component[2]);
}
else
{
@ -162,23 +160,27 @@ function writeEntities(objectLayer, file)
}
if(component.length > 1)
file.writeLine(" ]");
output_file.writeLine("]");
output_file.indent_remove(2);
if(j == nb_components - 1)
file.writeLine(" }");
output_file.writeLine("}");
else
file.writeLine(" },");
output_file.writeLine("},");
}
file.writeLine(" ]");
output_file.indent_remove(2);
output_file.writeLine("]");
output_file.indent_remove(2);
if(i == entities.length - 1)
file.writeLine(" }");
output_file.writeLine("}");
else
file.writeLine(" },");
output_file.writeLine("},");
}
file.writeLine(" ]");
}
var customMapFormat = {
@ -187,12 +189,44 @@ var customMapFormat = {
write: function(map, fileName)
{
let file = new TextFile(fileName, TextFile.WriteOnly);
let output_file = {
file: new TextFile(fileName, TextFile.WriteOnly),
indent: "",
indent_add: function(nb)
{
this.indent += " ".repeat(nb);
},
indent_remove: function(nb)
{
this.indent = this.indent.substring(0, this.indent.length - nb);
},
file.writeLine("{");
file.writeLine(" \"MapWidth\": " + map.width + ",");
file.writeLine(" \"MapHeight\": " + map.height + ",");
file.writeLine("");
write: function(content)
{
this.file.write(this.indent);
this.file.write(content);
},
writeLine: function(content)
{
this.file.write(this.indent);
this.file.writeLine(content);
},
commit: function()
{
this.file.commit();
}
};
output_file.file.writeLine("{");
output_file.indent_add(2);
output_file.writeLine("\"MapWidth\": " + map.width + ",");
output_file.writeLine("\"MapHeight\": " + map.height + ",");
output_file.file.writeLine("");
let backgroundlayers = [];
let foregroundlayer = null;
let hitboxeslayer = null;
let entitieslayer = null;
for(let i = 0; i < map.layerCount; i++)
{
@ -200,17 +234,100 @@ var customMapFormat = {
if(layer.isTileLayer)
{
writeTileLayer(layer, file);
if(layer.name.startsWith("Background"))
{
backgroundlayers.push(layer);
}
else if(layer.name.startsWith("Foreground"))
{
foregroundlayer = layer;
}
else if(layer.name == "Hitboxes")
{
if(hitboxeslayer)
throw new Error("There cannot be multiple hitboxes layers.");
hitboxeslayer = layer;
}
else
{
throw new Error("Invalid layer name for a tile layer : " + layer.name);
}
}
else if(layer.isObjectLayer)
{
writeEntities(layer, file);
if(layer.name == "Entities")
{
if(entitieslayer)
throw new Error("There cannot be multiple entity layers.");
entitieslayer = layer;
}
else
{
throw new Error("Invalid layer name for an object layer : " + layer.name);
}
}
}
file.write("}");
file.commit();
},
if(backgroundlayers.length == 0)
{
throw new Error("At least one background layer is needed.");
}
if(foregroundlayer == null)
{
throw new Error("A foreground layer is needed.");
}
if(hitboxeslayer == null)
{
throw new Error("An hitboxes layer is needed.");
}
backgroundlayers.sort((a, b) => {
if(Number(a.name[a.name.length - 1]) > Number(b.name[b.name.length - 1]))
return 1;
return -1;
});
output_file.writeLine("\"BackgroundLayers\": [");
output_file.indent_add(2);
for(let i = 0; i < backgroundlayers.length; i++)
{
const layer = backgroundlayers[i];
output_file.writeLine("[");
writeLayerContent(output_file, layer);
if(i == backgroundlayers.length - 1)
output_file.writeLine("]");
else
output_file.writeLine("],");
};
output_file.indent_remove(2);
output_file.writeLine("],");
output_file.writeLine("\"ForegroundLayer\": [");
writeLayerContent(output_file, foregroundlayer);
output_file.writeLine("],");
output_file.writeLine("\"Hitboxes\": [");
writeLayerContent(output_file, hitboxeslayer);
output_file.writeLine("],");
output_file.writeLine("\"Entities\": [");
output_file.indent_add(2);
if(entitieslayer)
writeEntities(output_file, entitieslayer);
output_file.indent_remove(2);
output_file.writeLine("]");
output_file.indent_remove(2);
output_file.write("}");
output_file.commit();
}
}
tiled.registerMapFormat("custom", customMapFormat)

View File

@ -34,9 +34,9 @@ int animation_system_update(component_t *system)
{
system_data->frame_timer_ms += game.delta_time_ms;
if(system_data->frame_timer_ms >= system_data->frame_delay_ms)
while(system_data->frame_timer_ms >= system_data->frame_delay_ms)
{
system_data->frame_timer_ms = 0.0f;
system_data->frame_timer_ms -= system_data->frame_delay_ms;
if(system_data->reverse)
{

View File

@ -11,7 +11,7 @@ typedef struct sprite_component_data_t {
texture_t *texture;
rect_t src_rect;
frect_t dst_rect;
rect_t dst_rect;
bool flip;
} sprite_component_data_t;

View File

@ -34,7 +34,7 @@ inline int sprite_component_update(component_t *component)
sprite_component_data_t *component_data = component->data;
transform_component_data_t *transform_component_data = component_data->transform_component->data;
component_data->dst_rect = transform_component_data->bounds;
frect_to_rect(&transform_component_data->bounds, &component_data->dst_rect);
component->entity->draw_priority = transform_component_data->bounds.y + transform_component_data->bounds.h;
return EXIT_SUCCESS;

View File

@ -2,6 +2,7 @@
#include <stdlib.h>
#include "display.h"
#include "camera.h"
#include "asset_manager.h"
#include "event_bus.h"
#include "ecs.h"
@ -15,16 +16,22 @@ int game_init(void)
game.is_running = false;
if(display_init()) return_failure_int;
camera_init();
event_bus_init();
entity_manager_init();
if(asset_manager_init()) return_failure_int;
if(!asset_manager_load_asset("tileset", ASSET_TEXTURE)) return_failure_int;
asset_t *map_asset = asset_manager_load_asset("dungeon_room_1", ASSET_MAP);
asset_t *map_asset = asset_manager_load_asset("dungeon_entry", ASSET_MAP);
if(!map_asset) return_failure_int;
if(map_load_entities(map_asset->data)) return_failure_int;
game.map = map_asset->data;
asset_t *tileset_asset = asset_manager_load_asset("tileset", ASSET_TEXTURE);
if(!tileset_asset) return_failure_int;
game.map->tileset = tileset_asset->data;
if(map_load_entities(game.map)) return_failure_int;
/* ======== Player ======== */
{
@ -38,11 +45,17 @@ int game_init(void)
transform_component_data_t *transform_component_data = transform_component->data;
transform_component_data->bounds = (frect_t) {
.x = 10.0f,
.y = 10.0f,
.x = 100.0f,
.y = 100.0f,
.w = 32.0f,
.h = 32.0f
};
game.camera.tracking_pos = (fvector2d_t *)&transform_component_data->bounds;
game.camera.tracking_center_offset = (fvector2d_t) {
.x = transform_component_data->bounds.w / 2,
.y = transform_component_data->bounds.h / 2
};
}
{
@ -128,6 +141,8 @@ int game_update(void)
return_failure_int;
}
camera_update();
return EXIT_SUCCESS;
}
@ -138,6 +153,11 @@ int game_render(void)
game.is_running = false;
return_failure_int;
}
if(map_display_background())
{
game.is_running = false;
return_failure_int;
}
if(entity_manager_draw())
{
@ -145,6 +165,12 @@ int game_render(void)
return_failure_int;
}
if(map_display_foreground())
{
game.is_running = false;
return_failure_int;
}
if(display_update())
{
game.is_running = false;