diff --git a/mario/maploader.cpp b/mario/maploader.cpp index 5b0c56d..697e1f0 100644 --- a/mario/maploader.cpp +++ b/mario/maploader.cpp @@ -10,6 +10,13 @@ #define TERRAIN_TYPE_HAS_ADDITIONAL 0x8 #define WIDE_TERRAIN_HAS_ADDITIONAL 0x8000 #define ADDITIONAL_IS_MOD 0x80 +#define FILE_VERSION 0x01 + +void loadMapV01(std::shared_ptr &scene, + std::shared_ptr &mario, + std::ifstream &map_file, std::vector &objects, + bool editor, size_t editor_width, + std::shared_ptr &renderer); void loadMap(std::shared_ptr &scene, std::shared_ptr mario, @@ -48,12 +55,14 @@ std::pair separateAdditionalData(uint8_t data) { auto type = (data & 0xF0) >> 4; return { id, type }; } + uint16_t combineTerrain(uint16_t id, uint8_t type) { uint16_t wide_terrain = type; wide_terrain = wide_terrain << 12; wide_terrain |= 0x0FFF & id; return wide_terrain; } + uint8_t combineAdditionalData(uint8_t id, uint8_t type) { return type << 4 | id; } @@ -73,9 +82,8 @@ MapObject parseBlock(std::ifstream &map_file) { if (additional_data & ADDITIONAL_IS_MOD) { additional_data &= ~ADDITIONAL_IS_MOD; auto modifier = separateAdditionalData(additional_data); - // TODO swap modifier id and data - modifier_id = modifier.second | 0x6000; - modifier_data = modifier.first; + modifier_id = modifier.first | 0x6000; + modifier_data = modifier.second; } else { // character auto character = separateAdditionalData(additional_data); @@ -88,6 +96,7 @@ MapObject parseBlock(std::ifstream &map_file) { } // editor loader +// TODO catch exception in calling functions void loadMap(std::shared_ptr &scene, std::shared_ptr &mario, const std::string &file, std::vector &objects, @@ -95,6 +104,26 @@ void loadMap(std::shared_ptr &scene, auto renderer = scene->getRendererShared(); std::ifstream map_file; map_file.open(file, std::ios::in | std::ios::binary); + if(!map_file.is_open()) { + objects.resize(editor_width); + return; + } + uint16_t version; + map_file.read((char *)&version, sizeof(uint16_t) / sizeof(char)); + switch(version) { + case 0x01: + loadMapV01(scene, mario, map_file, objects, editor, editor_width, renderer); + break; + default: + throw "Invalid file version"; + } +} + +void loadMapV01(std::shared_ptr &scene, + std::shared_ptr &mario, + std::ifstream &map_file, std::vector &objects, + bool editor, size_t editor_width, + std::shared_ptr &renderer) { uint16_t cols; map_file.read((char *)&cols, sizeof(uint16_t) / sizeof(char)); if (editor) { @@ -187,12 +216,19 @@ void loadMap(std::shared_ptr &scene, if (editor && objects.size() < editor_width) { objects.resize(editor_width); } + } +// TODO catch exception in calling func void saveMap(const std::string &file, std::vector &objects) { std::ofstream output_file; output_file.open(file, std::ios::out | std::ios::binary); - uint16_t cols = objects.size(); + if(!output_file.is_open()) { + throw "Could not open file '" + file + "'"; + } + const uint16_t version = FILE_VERSION; + output_file.write((char *)&version, sizeof(uint16_t) / sizeof(char)); + const uint16_t cols = objects.size(); output_file.write((char *)&cols, sizeof(uint16_t) / sizeof(char)); for (auto &col : objects) { for (int i = 0; i < 16; i++) { @@ -209,11 +245,10 @@ void saveMap(const std::string &file, std::vector &objects) { additional_data = combineAdditionalData( block.getCharacterId(), block.getCharacterType()); } else if (block.hasModifier()) { - // TODO seriously change order of id/data!!! // we have IDs like 0x600X but only X is useful data, the 0x6 at // the beginning is to differentiate mods from characters additional_data = combineAdditionalData( - block.getModifierData(), block.getModifierId() & 0x000F); + block.getModifierId() & 0x000F, block.getModifierData()); additional_data |= ADDITIONAL_IS_MOD; } if (additional_data) {