Map conversion should work

This commit is contained in:
Ulysse Cura 2025-08-22 19:11:46 +02:00
parent c56b462203
commit f080e38244
17 changed files with 263 additions and 94 deletions

57
.vscode/settings.json vendored
View File

@ -18,6 +18,61 @@
"stdexcept": "cpp", "stdexcept": "cpp",
"iostream": "cpp", "iostream": "cpp",
"ios": "cpp", "ios": "cpp",
"vector2d.hpp": "c" "vector2d.hpp": "c",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"any": "cpp",
"array": "cpp",
"atomic": "cpp",
"bit": "cpp",
"bitset": "cpp",
"codecvt": "cpp",
"compare": "cpp",
"concepts": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"deque": "cpp",
"forward_list": "cpp",
"list": "cpp",
"map": "cpp",
"set": "cpp",
"unordered_map": "cpp",
"vector": "cpp",
"exception": "cpp",
"algorithm": "cpp",
"functional": "cpp",
"memory": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"ratio": "cpp",
"tuple": "cpp",
"type_traits": "cpp",
"utility": "cpp",
"initializer_list": "cpp",
"limits": "cpp",
"mutex": "cpp",
"new": "cpp",
"numbers": "cpp",
"ranges": "cpp",
"semaphore": "cpp",
"span": "cpp",
"stop_token": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
} }
} }

6
.vscode/tasks.json vendored
View File

@ -6,9 +6,9 @@
"detail": "Build project", "detail": "Build project",
"type": "shell", "type": "shell",
"command": "make", "command": "make",
"args": [ //"args": [
"-j$(nproc)" // "-j$(nproc)"
], //],
"group": "build", "group": "build",
"presentation": { "presentation": {
"echo": true, "echo": true,

View File

@ -4,14 +4,20 @@ BUILD_DIR = build
# Source files # Source files
SOURCES := \ SOURCES := \
src/main.cpp \ src/main.cpp \
src/game_data/game_data.cpp src/game_data/game_data.cpp \
src/game_data/maps.cpp \
src/game_data/textures.cpp
# Assets files # Assets files
ASSETS := \ ASSETS := \
assets/tileset/tileset.png \
assets/player-sheets/player_idle_sheet.png \ assets/player-sheets/player_idle_sheet.png \
assets/player-sheets/player_walk_sheet.png \ assets/player-sheets/player_walk_sheet.png \
assets/player-sheets/player_run_sheet.png \ assets/player-sheets/player_run_sheet.png \
assets/tileset/tileset.png \ assets/props-sheets/barred_door_sheet.png \
assets/props-sheets/lever_sheet.png \
assets/props-sheets/small_chest_sheet.png \
assets/props-sheets/big_chest_sheet.png \
assets/maps/example.json assets/maps/example.json
# Output target name # Output target name
@ -19,7 +25,7 @@ OUTPUT := 2D_Engine_Casio_Tool
# Compiler and flags # Compiler and flags
CXX = ccache g++ CXX = ccache g++
CXXFLAGS = -Wall -Wextra -std=c++17 -g -no-pie CXXFLAGS = -Wall -Wextra -std=c++17 -O2 -no-pie
INCLUDE_DIRS = 3rd_party INCLUDE_DIRS = 3rd_party
LDFLAGS = -no-pie LDFLAGS = -no-pie
@ -65,7 +71,6 @@ $(BUILD_DIR)/%.o: %.cpp
$(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1)))) $(eval CURRENT_FILE := $(shell echo $$(($(CURRENT_FILE)+1))))
$(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_FILES))))) $(eval PERCENTAGE := $(shell echo $$(($(CURRENT_FILE)*100/$(TOTAL_FILES)))))
@echo "[$(PERCENTAGE)%] $(GREEN)Building CXX object $@$(RESET)" @echo "[$(PERCENTAGE)%] $(GREEN)Building CXX object $@$(RESET)"
$(Q)mkdir -p $(dir $@)
$(Q)$(CXX) $(CXXFLAGS) $(INCLUDE_DIRS:%=-I%) -MMD -MP -c $< -o $@ $(Q)$(CXX) $(CXXFLAGS) $(INCLUDE_DIRS:%=-I%) -MMD -MP -c $< -o $@
# Convert .*.o from .* (png files for example) # Convert .*.o from .* (png files for example)

View File

@ -1,5 +1,5 @@
{ {
"MapWidth": 2, "MapWidth": 3,
"MapHeight": 2, "MapHeight": 2,
"BackgroundLayer1": [ "BackgroundLayer1": [
@ -33,40 +33,28 @@
}, },
{ {
"Type": "SpriteComponent", "Type": "SpriteComponent",
"TextureName": "dungeon_door_sheet" "TextureName": "barred_door_sheet"
}, },
{ {
"Type": "AnimationSystem", "Type": "AnimationSystem",
"NbFrames": 15, "NbFrames": 8,
"ActualFrame": 8, "ActualFrame": 0,
"FrameDelayMs": 100, "FrameDelayMs": 100,
"Play": false, "Play": false,
"Loop": false, "Loop": false,
"Reverse": false "Reverse": false
},
{
"Type": "DoorSystem",
"States": [
{
"Channel": 0,
"State": true
}
]
} }
] ]
}, },
{ {
"ID": 542, "ID": 2034,
"StoreInteraction": true,
"Components": [ "Components": [
{ {
"Type": "TransformComponent", "Type": "TransformComponent",
"Bounds": { "x": 256,
"x": 256, "y": 192,
"y": 384, "w": 48,
"w": 48, "h": 32,
"h": 32
},
"Speed": 0 "Speed": 0
}, },
{ {
@ -81,10 +69,6 @@
"Play": false, "Play": false,
"Loop": false, "Loop": false,
"Reverse": false "Reverse": false
},
{
"Type": "LeverSystem",
"Channel": 0
} }
] ]
} }

View File

@ -1,5 +1,5 @@
import fxconv import fxconv
from fxconv import u16, u32, ref from fxconv import u16, u32, ref, string
import json import json
def convert(input, output, params, target): def convert(input, output, params, target):
@ -13,41 +13,59 @@ def convert_map(input, output, params, target):
with open(input, "r") as fp: with open(input, "r") as fp:
map = json.load(fp) map = json.load(fp)
w = map["MapWidth"] TRANSFORM_COMPONENT = 0
h = map["MapHeight"] SPRITE_COMPONENT = 1
ANIMATION_SYSTEM = 2
background_layer1 = bytes(map["BackgroundLayer1"])
background_layer2 = bytes(map["BackgroundLayer2"])
background_layer3 = bytes(map["BackgroundLayer3"])
foreground = bytes(map["Foreground"])
entities = fxconv.Structure() entities = fxconv.Structure()
for entity in map["Entities"]: for entity in map["Entities"]:
e = fxconv.Structure() e = fxconv.Structure()
e += u16(entity["ID"]) e += u16(entity["ID"])
e += u32(entity["Components"].size()) e += u32(len(entity["Components"]))
for component in entity["Components"]: for component in entity["Components"]:
c = fxconv.Structure() c = fxconv.Structure()
c_data = fxconv.Structure()
match component["Type"]: match component["Type"]:
case "TransformComponent": case "TransformComponent":
c += u32(component["x"]) c += u32(TRANSFORM_COMPONENT)
c += u32(component["y"]) c_data += u32(component["x"])
c += u32(component["w"]) c_data += u32(component["y"])
c += u32(component["h"]) c_data += u32(component["w"])
c += u32(component["Speed"]) c_data += u32(component["h"])
c_data += u32(component["Speed"])
case "SpriteComponent":
c += u32(SPRITE_COMPONENT)
c_data += string(component["TextureName"])
case "AnimationSystem":
c += u32(SPRITE_COMPONENT)
c_data += u32(component["NbFrames"])
c_data += u32(component["ActualFrame"])
c_data += u32(component["FrameDelayMs"])
c_data += u32(component["Play"])
c_data += u32(component["Loop"])
c_data += u32(component["Reverse"])
case _: case _:
raise fxconv.FxconvError(f"unknown component type {component["Type"]}") raise fxconv.FxconvError(f"unknown component type {component['Type']}")
c += ref(c_data)
e += ref(c) e += ref(c)
entities += e
o = fxconv.ObjectData() o = fxconv.ObjectData()
o += u32(w) + u32(h) o += string(params["name"])
o += ref(background_layer1) o += u32(map["MapWidth"]) + u32(map["MapHeight"])
o += ref(background_layer2) o += bytes(map["BackgroundLayer1"])
o += ref(background_layer3) o += bytes(map["BackgroundLayer2"])
o += ref(foreground) o += bytes(map["BackgroundLayer3"])
o += u32(map["Entities"].size()) o += bytes(map["Foreground"])
o += u32(len(map["Entities"]))
o += ref(entities) o += ref(entities)
fxconv.elf(o, output, params["name"], **target) fxconv.elf(o, output, params["name"], **target)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

View File

@ -0,0 +1,3 @@
*.png:
type: bopti-image
name_regex: (.*)\.png img_\1

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 670 B

View File

@ -1,11 +1,22 @@
#include <iostream> #include <iosfwd>
#include "game_data.hpp" #include "game_data.hpp"
void load_game_data(game_data_t *game_data) game_data_t game_data {};
static inline void verify_integrity(void)
{ {
verify_textures_integrity();
verify_maps_integrity();
} }
void write_game_data_as_bin_into_file(game_data_t *game_data, std::ofstream *bin_output_file) void write_game_data_as_bin_into_file(void)
{ {
std::ofstream bin_output_file {"GameData.bin", std::ios::binary};
if(!bin_output_file)
{
throw std::runtime_error("Couldn't create output file");
}
verify_integrity();
} }

View File

@ -7,15 +7,13 @@
#include "maps.hpp" #include "maps.hpp"
typedef struct game_data_t { typedef struct game_data_t {
uint32_t nb_textures; const uint32_t nb_textures = NB_TEXTURES;
texture_t *textures; const texture_t *textures = textures;
uint32_t nb_maps; const uint32_t nb_maps = NB_MAPS;
map_t *maps; const map_t **maps = maps;
} game_data_t; } game_data_t;
void load_game_data(game_data_t *game_data); void write_game_data_as_bin_into_file(void);
void write_game_data_as_bin_into_file(game_data_t *game_data, std::ofstream *bin_output_file);
#endif // GAME_DATA_HPP #endif // GAME_DATA_HPP

84
src/game_data/maps.cpp Normal file
View File

@ -0,0 +1,84 @@
#include <iostream>
#include "maps.hpp"
static inline void verify_layers_integrity(void)
{
for(uint32_t map_index = 0; map_index < NB_MAPS; map_index++)
{
std::cout << "Map " << map_index + 1 << std::endl;
}
}
static inline void verify_entities_integrity(void)
{
}
void verify_maps_integrity(void)
{
std::cout << "Nb Maps : " << NB_MAPS << std::endl;
for(uint32_t map_index = 0; map_index < NB_MAPS; map_index++)
{
const uint32_t NB_ENTITIES = maps[map_index]->nb_entities;
const entity_t *ENTITIES = maps[map_index]->entities;
std::cout << "Map " << map_index + 1 << std::endl;
std::cout << " - MapName : " << maps[map_index]->map_name << std::endl;
std::cout << " - MapWidth : " << maps[map_index]->map_width << std::endl;
std::cout << " - MapHeight : " << maps[map_index]->map_width << std::endl;
std::cout << " - Nb Entities : " << NB_ENTITIES << std::endl;
for(uint32_t entity_index = 0; entity_index < NB_ENTITIES; entity_index++)
{
const uint32_t NB_COMPONENTS = ENTITIES->nb_component;
const component_t *COMPONENTS = ENTITIES->components;
std::cout << " - Nb Components : " << NB_COMPONENTS << std::endl;
for(uint32_t component_index = 0; component_index < NB_COMPONENTS; component_index++)
{
const component_t *COMPONENT = &COMPONENTS[component_index];
std::cout << " Component " << component_index << std::endl;
switch(COMPONENT->component_type)
{
case TRANSFORM_COMPONENT:
{
const transform_component_data_t *component_data = COMPONENT->component_data.transform_component_data;
std::cout << " - TransformComponent :" << std::endl;
std::cout << " - x : " << component_data->x << std::endl;
std::cout << " - y : " << component_data->y << std::endl;
std::cout << " - w : " << component_data->w << std::endl;
std::cout << " - h : " << component_data->h << std::endl;
std::cout << " - Speed : " << component_data->speed << std::endl;
break;
}
case SPRITE_COMPONENT:
{
const sprite_component_data_t *component_data = COMPONENT->component_data.sprite_component_data;
std::cout << " - SpriteComponent :" << std::endl;
std::cout << " - TextureName : " << component_data->texture_name << std::endl;
break;
}
case ANIMATION_SYSTEM:
{
const animation_system_data_t *system_data = COMPONENT->component_data.animation_system_data;
std::cout << " - AnimationSystem :" << std::endl;
std::cout << " - NbFrames : " << system_data->nb_frames;
std::cout << " - FrameNb : " << system_data->actual_frame_nb;
std::cout << " - FrameDelay : " << system_data->frame_delay_ms;
std::cout << " - Play : " << system_data->play;
std::cout << " - Loop : " << system_data->loop;
std::cout << " - Reverse : " << system_data->reverse;
break;
}
}
}
}
}
}

View File

@ -4,19 +4,19 @@
#include "ecs/ecs.hpp" #include "ecs/ecs.hpp"
typedef struct map_t { typedef struct map_t {
const char *name; const char *map_name;
uint32_t map_width; const uint32_t map_width;
uint32_t map_height; const uint32_t map_height;
uint16_t *map_background_layer1; const uint16_t *map_background_layer1;
uint16_t *map_background_layer2; const uint16_t *map_background_layer2;
uint16_t *map_background_layer3; const uint16_t *map_background_layer3;
uint16_t *map_foreground; const uint16_t *map_foreground;
uint32_t nb_entities; const uint32_t nb_entities;
entity_t *entities; const entity_t *entities;
} map_t; } __attribute__((packed, aligned(4))) map_t;
extern map_t map_example; extern map_t map_example;
@ -24,6 +24,9 @@ static map_t *maps[] = {
&map_example &map_example
}; };
#define NB_MAPS sizeof(maps) / sizeof(map_t) #define NB_MAPS 1
// Throw an exception if maps integrity is not complete
void verify_maps_integrity(void);
#endif // MAP_HPP #endif // MAP_HPP

View File

@ -0,0 +1,6 @@
#include "textures.hpp"
void verify_textures_integrity(void)
{
return;
}

View File

@ -5,21 +5,32 @@
typedef struct texture_t { typedef struct texture_t {
const char *name; const char *name;
bopti_image_t *image; const bopti_image_t *image;
} texture_t; } __attribute__((packed, aligned(4))) texture_t;
extern bopti_image_t img_tileset; extern bopti_image_t img_tileset;
extern bopti_image_t img_player_idle_sheet; extern bopti_image_t img_player_idle_sheet;
extern bopti_image_t img_player_walk_sheet; extern bopti_image_t img_player_walk_sheet;
extern bopti_image_t img_player_run_sheet; extern bopti_image_t img_player_run_sheet;
extern bopti_image_t img_barred_door_sheet;
extern bopti_image_t img_lever_sheet;
extern bopti_image_t img_small_chest_sheet;
extern bopti_image_t img_big_chest_sheet;
static texture_t textures[] = { static texture_t textures[] = {
{"tileset", &img_tileset}, {"tileset", &img_tileset},
{"player_idle_sheet", &img_player_idle_sheet}, {"player_idle_sheet", &img_player_idle_sheet},
{"player_walk_sheet", &img_player_walk_sheet}, {"player_walk_sheet", &img_player_walk_sheet},
{"player_run_sheet", &img_player_run_sheet} {"player_run_sheet", &img_player_run_sheet},
{"barred_door_sheet", &img_barred_door_sheet},
{"lever_sheet", &img_lever_sheet},
{"small_chest_sheet", &img_small_chest_sheet},
{"big_chest_sheet", &img_big_chest_sheet}
}; };
#define NB_TEXTURES sizeof(textures) / sizeof(texture_t) #define NB_TEXTURES 8
// Throw an exception if textures integrity is not complete
void verify_textures_integrity(void);
#endif // TEXTURE_HPP #endif // TEXTURE_HPP

View File

@ -1,30 +1,21 @@
#include <iostream> #include <iostream>
#include <stdexcept>
#include "game_data/game_data.hpp" #include "game_data/game_data.hpp"
void error(std::string error); void error(std::string error);
int main(int argc, char *argv[]) int main(void)
{ {
if(argc != 3) try
{ {
error("You need to give an input and output file"); write_game_data_as_bin_into_file();
return EXIT_FAILURE;
} }
catch(std::exception const &exception)
std::ofstream bin_output_file {argv[2], std::ios::binary};
if(!bin_output_file)
{ {
error("Couldn't create output file"); error(static_cast<std::string>(exception.what()));
return EXIT_FAILURE;
} }
game_data_t game_data;
load_game_data(&game_data);
write_game_data_as_bin_into_file(&game_data, &bin_output_file);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }