#include "maploader.hpp" #include "../sdlpp/sdlpp_rectrenderer.hpp" #include #include #include "sprites.hpp" #include "blocks.hpp" #include "objectids.hpp" // TODO move to one function void loadMap(std::shared_ptr &scene, std::shared_ptr mario, const std::string &file, std::shared_ptr &renderer) { std::ifstream map_file; map_file.open(file, std::ios::in | std::ios::binary); uint16_t cols; map_file.read((char*)&cols, sizeof(uint16_t)/sizeof(char)); for(uint16_t i = 0; i < cols; i++) { for(int j = 0; j < 16; j++) { uint16_t input_number; uint8_t additional_data = 0; uint8_t character_type = 0, character = 0, modifier_type = 0, modifier_data = 0; map_file.read((char *)&input_number, sizeof(uint16_t)/sizeof(char)); uint8_t type = (input_number & 0xF000)>>12; uint16_t id = (input_number & 0x0FFF) | BLOCK_PREFIX; if(type & 0x8) { map_file.read((char *)&additional_data, sizeof(uint8_t)/sizeof(char)); type &= ~0x8; if(additional_data & 0x80) { //modifier additional_data &= ~0x80; modifier_type = (additional_data & 0xF0)>>4; modifier_data = additional_data & 0x0F; } else { // character character_type = (additional_data & 0xF0)>>4; character = additional_data & 0x0F; } } bool collision = false; if(id == FLOOR_ID) { collision = true; } // TODO add modifiers to createTerrainBlock auto obj = createTerrainBlock(id, static_cast(type), renderer, i, j, collision); if(obj != nullptr) scene->addObject(obj); if(character) { if(character == MARIO_ID) { mario->setPos(i * BLOCK_SIZE, 1 - (16-j) * BLOCK_SIZE); } } } } scene->moveZTop(mario); } // editor loader void loadMap(std::shared_ptr &scene, const std::string &file, std::shared_ptr &renderer, std::vector &objects) { std::ifstream map_file; map_file.open(file, std::ios::in | std::ios::binary); uint16_t cols; map_file.read((char*)&cols, sizeof(uint16_t)/sizeof(char)); objects.resize(cols); for(uint16_t i = 0; i < cols; i++) { auto &col = objects[i]; for(int j = 0; j < 16; j++) { uint16_t input_number; uint8_t additional_data = 0; uint8_t character_type = 0, character = 0, modifier_type = 0, modifier_data = 0; map_file.read((char *)&input_number, sizeof(uint16_t)/sizeof(char)); uint8_t type = (input_number & 0xF000)>>12; uint16_t id = (input_number & 0x0FFF) | BLOCK_PREFIX; if(type & 0x8) { map_file.read((char *)&additional_data, sizeof(uint8_t)/sizeof(char)); type &= ~0x8; if(additional_data & 0x80) { //modifier additional_data &= ~0x80; modifier_type = (additional_data & 0xF0)>>4; modifier_data = additional_data & 0x0F; } else { // character character_type = (additional_data & 0xF0)>>4; character = additional_data & 0x0F; } } col[j] = {type, id, character_type, character, modifier_type, modifier_data}; // TODO add modifiers to createTerrainBlock auto obj = createTerrainBlock(id, static_cast(type), renderer, i, j, true); obj->getCollisions()[0]->setId(EDITOR_TERRAIN_ID); scene->addObject(obj); if(character) { if(character == MARIO_ID) { scene->addObject(createMario(static_cast(character_type), renderer, i, j)); } } } } if(objects.size() < 18) { objects.resize(18); } } // tuple - world object type, object, world character type, character, modifier type, modifier data 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(); output_file.write((char*)&cols, sizeof(uint16_t)/sizeof(char)); for(auto &col : objects) { for(int i = 0; i < 16; i++) { auto &obj = col[i]; uint16_t wide_type = std::get<0>(obj); wide_type = wide_type<<12; uint16_t write_num = (0x0FFF & std::get<1>(obj)) | wide_type; // 3 becuase character type can be 0 (overworld), 4 because modifier data can be 0 (breakable) if(std::get<3>(obj) || std::get<4>(obj)) { write_num |= 0x8000; } output_file.write((char*)&write_num, sizeof(uint16_t)/sizeof(char)); uint8_t additional_data = 0; if(std::get<3>(obj)) { additional_data |= std::get<2>(obj)<<4; additional_data |= std::get<3>(obj); } else if(std::get<4>(obj)) { additional_data |= std::get<4>(obj)<<4; additional_data |= 0x80; additional_data |= std::get<5>(obj); } if(additional_data) { output_file.write((char*)&additional_data, sizeof(uint8_t)/sizeof(char)); } } } output_file.close(); }