#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< SDLPP::Scene > &scene, std::shared_ptr< SDLPP::RectangleRender > mario, const std::string &file, std::shared_ptr< SDLPP::Renderer > &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< LandType::Value >( 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< SDLPP::Scene > &scene, const std::string &file, std::shared_ptr< SDLPP::Renderer > &renderer, std::vector< mapColumnType > &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< LandType::Value >( 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< LandType::Value >( 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< mapColumnType > &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(); }