Mario: add MapObject and use that instead of tuples

This commit is contained in:
zv0n 2021-06-07 23:48:28 +02:00
parent 76f55fd98c
commit a54d079fd2
9 changed files with 329 additions and 169 deletions

View File

@ -18,7 +18,7 @@ LDFLAGS ?= -lSDL2 -lSDL2_image -lSDL2_gfx -lSDL2_ttf -pthread
OUTPUTFLAG = -o
endif
COMMON_OBJECTS = global_vars.${OBJEXT} sprites.${OBJEXT} maploader.${OBJEXT}
COMMON_OBJECTS = global_vars.${OBJEXT} sprites.${OBJEXT} maploader.${OBJEXT} mapobject.${OBJEXT}
ifneq ($(UNAME_S),Windows)
COMMON_OBJECTS += libsdlpp.a
endif
@ -69,6 +69,8 @@ tool_box.${OBJEXT}: tool_box.cpp ../sdlpp/sdlpp.hpp sprites.hpp tool_box.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
editor_visitor.${OBJEXT}: editor_visitor.cpp ../sdlpp/sdlpp.hpp sprites.hpp editor_visitor.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
mapobject.${OBJEXT}: mapobject.cpp ../sdlpp/sdlpp.hpp objectids.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
mario.${OBJEXT}: mario.cpp ../sdlpp/sdlpp.hpp mario.hpp global_vars.hpp objectids.hpp sprites.hpp ../sdlpp/sdlpp_rectrenderer.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
libsdlpp.a: ../sdlpp

View File

@ -154,7 +154,7 @@ const std::vector< uint64_t > possibleBlocks = {
};
const std::vector< uint64_t > possibleMods = {
DESTRUCTIBLE_ID,
DESTRUCTIBLE_MODIFIER_ID,
};
const std::vector< uint64_t > possibleCharacters = {
@ -228,7 +228,7 @@ const std::unordered_map< uint64_t, const SDL_Rect * > block_mapping = {
{ CANNON_PEDESTAL_ID, &CANNON_PEDESTAL_SRC },
{ CANNON_ID, &CANNON_SRC },
{ MARIO_ID, &MARIO_STANDING_SRC },
{ DESTRUCTIBLE_ID, &DESTRUCTIBLE_SRC },
{ DESTRUCTIBLE_MODIFIER_ID, &DESTRUCTIBLE_SRC },
};
const std::unordered_map< uint64_t, uint64_t > block_flags = {
@ -291,7 +291,7 @@ const std::unordered_map< uint64_t, uint64_t > block_flags = {
{ CANNON_PEDESTAL_ID, HAS_COLLISION },
{ CANNON_ID, HAS_COLLISION },
{ MARIO_ID, 0 },
{ DESTRUCTIBLE_ID, 0 },
{ DESTRUCTIBLE_MODIFIER_ID, 0 },
};
bool blockCanBeDestroyed(uint64_t id) {

View File

@ -136,13 +136,9 @@ void updateTool() {
void removeMario() {
if ( !global_vars.mario )
return;
auto prev = global_vars.objects[global_vars.mario_pos.getX()]
[global_vars.mario_pos.getY()];
// remove character/modifiers
global_vars
.objects[global_vars.mario_pos.getX()][global_vars.mario_pos.getY()] = {
std::get< 0 >( prev ), std::get< 1 >( prev ), 0, 0, 0, 0
};
.objects[global_vars.mario_pos.getX()][global_vars.mario_pos.getY()]
.unsetCharacter();
global_vars.mario->destroy();
}
@ -549,7 +545,7 @@ SDLPP::Vec2D< int > getSelectedObjectIndexes() {
SDLPP::Vec2D< int >( global_vars.map.cur_page - 1, 0 );
}
mapObjectType &getSelectedObject() {
MapObject &getSelectedObject() {
auto pos = getSelectedObjectIndexes();
return global_vars.objects[pos.getX()][pos.getY()];
}
@ -570,48 +566,36 @@ void placeTool( SDLPP::Scene &scene ) {
}
scene.visitCollisions( *global_vars.current_tool, visitor );
if ( visitor.removeBlock() && !visitor.addBlock() ) {
auto &obj = getSelectedObject();
if ( visitor.removeBlock() && !visitor.addBlock() ) {
switch ( visitor.getVisitorType() ) {
case VisitorType::Terrain:
std::get< MapObject::TERRAIN_TYPE >( obj ) =
global_vars.current_world_type;
std::get< MapObject::TERRAIN_ID >( obj ) = 0;
obj.unsetTerrain();
break;
case VisitorType::Modifier:
std::get< MapObject::CHARACTER_TYPE >( obj ) = 0;
std::get< MapObject::CHARACTER_ID >( obj ) = 0;
std::get< MapObject::MODIFIER_TYPE >( obj ) = 0;
std::get< MapObject::MODIFIER_DATA >( obj ) = 0;
obj.unsetModifier();
break;
default:
break;
}
} else if ( visitor.addBlock() ) {
auto &obj = getSelectedObject();
auto renderer = scene.getRendererShared();
int z_index = 1;
std::shared_ptr< SDLPP::RenderObject > new_obj = nullptr;
switch ( visitor.getVisitorType() ) {
case VisitorType::Terrain:
std::get< MapObject::TERRAIN_TYPE >( obj ) =
global_vars.current_world_type;
std::get< MapObject::TERRAIN_ID >( obj ) =
global_vars.current_tool->getId();
new_obj =
createTerrainBlock( global_vars.current_tool->getId(),
global_vars.current_world_type, renderer,
obj.setTerrain( global_vars.current_tool->getId(),
global_vars.current_world_type );
new_obj = createTerrainBlock(
obj.getTerrainId(),
obj.getTerrainType(), renderer,
global_vars.mouse.edit_box.getX(),
global_vars.mouse.edit_box.getY(), false, true );
new_obj->getCollisions()[0]->setId( EDITOR_TERRAIN_ID );
break;
case VisitorType::Modifier:
if ( tool_type == BlockRole::MARIO ) {
std::get< MapObject::CHARACTER_TYPE >( obj ) =
global_vars.current_world_type;
std::get< MapObject::CHARACTER_ID >( obj ) = MARIO_ID;
std::get< MapObject::MODIFIER_TYPE >( obj ) = 0;
std::get< MapObject::MODIFIER_DATA >( obj ) = 0;
obj.setCharacter(MARIO_ID, global_vars.current_world_type);
new_obj = createMario( global_vars.current_world_type, renderer,
global_vars.mouse.edit_box.getX(),
global_vars.mouse.edit_box.getY() );
@ -624,12 +608,10 @@ void placeTool( SDLPP::Scene &scene ) {
// TODO BlockRole::Character
} else {
// TODO data
std::get< MapObject::MODIFIER_TYPE >( obj ) =
global_vars.current_tool->getId();
std::get< MapObject::MODIFIER_DATA >( obj ) = 0;
obj.setModifier(global_vars.current_tool->getId(), 0);
new_obj = createTerrainBlock(
global_vars.current_tool->getId(),
global_vars.current_world_type, renderer,
obj.getModifierId(),
LandType::OVERWORLD, renderer,
global_vars.mouse.edit_box.getX(),
global_vars.mouse.edit_box.getY(),
global_vars.translucent_terrain_texture, false, true );
@ -705,7 +687,8 @@ void pollEvents( SDLPP::Scene &scene ) {
global_vars.current_world_type = possibleLands[index];
updateWorld();
} else if ( index < max_index ) {
updateToolIndex( cur_page * multiplier + index, global_vars.mouse.tool_type );
updateToolIndex( cur_page * multiplier + index,
global_vars.mouse.tool_type );
}
}
break;
@ -820,8 +803,9 @@ void populateToolGrid(
// fall through
case ToolType::BLOCK:
case ToolType::MOD:
tool_store.push_back( createTerrainBlock(
block, global_vars.current_world_type, renderer, false, true ) );
tool_store.push_back(
createTerrainBlock( block, global_vars.current_world_type,
renderer, false, true ) );
default:
break;
}
@ -952,7 +936,7 @@ int main() {
global_vars.current_world_type = LandType::OVERWORLD;
// TODO file name
loadMap( scene, global_vars.mario, "test_binary.bin", renderer,
loadMap( scene, global_vars.mario, "test_binary.bin",
global_vars.objects, true, MAP_WIDTH );
auto font = std::make_shared< SDLPP::Font >( "testfont.ttf", 36 );
@ -962,9 +946,9 @@ int main() {
// create grids and arrow controls
// map
auto arrows = createArrowControls(
0, ( MAP_WIDTH + 1 ) * BLOCK_SIZE,
1 - MAP_HEIGHT * BLOCK_SIZE, MAP_HEIGHT * BLOCK_SIZE,
EDITOR_LEFT_MAP_ID, EDITOR_RIGHT_MAP_ID, scene, font_config );
0, ( MAP_WIDTH + 1 ) * BLOCK_SIZE, 1 - MAP_HEIGHT * BLOCK_SIZE,
MAP_HEIGHT * BLOCK_SIZE, EDITOR_LEFT_MAP_ID, EDITOR_RIGHT_MAP_ID, scene,
font_config );
auto left_map_arrow = arrows.first;
auto right_map_arrow = arrows.second;
createGrid( BLOCK_SIZE, 1 - MAP_HEIGHT * BLOCK_SIZE, MAP_WIDTH, MAP_HEIGHT,
@ -973,53 +957,61 @@ int main() {
for ( int i = 0; i < MAP_WIDTH; i++ ) {
for ( int j = 0; j < MAP_HEIGHT; j++ ) {
scene->addObject( std::make_shared< EditBox >(
i, j, BLOCK_SIZE, 1 - MAP_HEIGHT * BLOCK_SIZE, MAP_WIDTH, MAP_HEIGHT, renderer ) );
i, j, BLOCK_SIZE, 1 - MAP_HEIGHT * BLOCK_SIZE, MAP_WIDTH,
MAP_HEIGHT, renderer ) );
}
}
// tools
populateToolGrid( TOOLS_WIDTH, 2, ( MAP_WIDTH - TOOLS_WIDTH ) * BLOCK_SIZE,
1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, ToolType::BLOCK, possibleBlocks,
global_vars.tools, global_vars.tool_boxes, scene,
"TERRAIN", font_config );
arrows = createArrowControls( ( MAP_WIDTH - TOOLS_WIDTH - 1 ) * BLOCK_SIZE,
MAP_WIDTH * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE,
2 * BLOCK_SIZE, EDITOR_LEFT_TOOL_ID,
EDITOR_RIGHT_TOOL_ID, scene, font_config );
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, ToolType::BLOCK,
possibleBlocks, global_vars.tools, global_vars.tool_boxes,
scene, "TERRAIN", font_config );
arrows = createArrowControls(
( MAP_WIDTH - TOOLS_WIDTH - 1 ) * BLOCK_SIZE, MAP_WIDTH * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, 2 * BLOCK_SIZE,
EDITOR_LEFT_TOOL_ID, EDITOR_RIGHT_TOOL_ID, scene, font_config );
auto left_tool_arrow = arrows.first;
auto right_tool_arrow = arrows.second;
createGrid( ( MAP_WIDTH - TOOLS_WIDTH ) * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE,
TOOLS_WIDTH, 2, scene );
createGrid( ( MAP_WIDTH - TOOLS_WIDTH ) * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, TOOLS_WIDTH, 2, scene );
// mods
populateToolGrid( MOD_WIDTH, 2, 5 * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, ToolType::MOD,
populateToolGrid( MOD_WIDTH, 2, 5 * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, ToolType::MOD,
possibleMods, global_vars.mods, global_vars.mod_boxes,
scene, "MODS", font_config );
arrows =
createArrowControls( 4 * BLOCK_SIZE, ( MOD_WIDTH + 5 ) * BLOCK_SIZE,
arrows = createArrowControls(
4 * BLOCK_SIZE, ( MOD_WIDTH + 5 ) * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, 2 * BLOCK_SIZE, EDITOR_LEFT_MOD_ID,
EDITOR_RIGHT_MOD_ID, scene, font_config );
auto left_mod_arrow = arrows.first;
auto right_mod_arrow = arrows.second;
createGrid( 5 * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, MOD_WIDTH, 2, scene );
createGrid( 5 * BLOCK_SIZE, 1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, MOD_WIDTH,
2, scene );
// characters
populateToolGrid( CHARACTER_WIDTH, 2, ( MOD_WIDTH + 8 ) * BLOCK_SIZE,
1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, ToolType::CHARACTER, possibleCharacters,
global_vars.characters, global_vars.character_boxes,
scene, "CHARACTERS", font_config );
arrows = createArrowControls(
( MOD_WIDTH + 7 ) * BLOCK_SIZE,
( MOD_WIDTH + 8 + CHARACTER_WIDTH ) * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE,
2 * BLOCK_SIZE, EDITOR_LEFT_CHARACTER_ID, EDITOR_RIGHT_CHARACTER_ID,
scene, font_config );
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, ToolType::CHARACTER,
possibleCharacters, global_vars.characters,
global_vars.character_boxes, scene, "CHARACTERS",
font_config );
arrows =
createArrowControls( ( MOD_WIDTH + 7 ) * BLOCK_SIZE,
( MOD_WIDTH + 8 + CHARACTER_WIDTH ) * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE,
2 * BLOCK_SIZE, EDITOR_LEFT_CHARACTER_ID,
EDITOR_RIGHT_CHARACTER_ID, scene, font_config );
auto left_char_arrow = arrows.first;
auto right_char_arrow = arrows.second;
createGrid( ( MOD_WIDTH + 8 ) * BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, CHARACTER_WIDTH, 2,
createGrid( ( MOD_WIDTH + 8 ) * BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, CHARACTER_WIDTH, 2,
scene );
// world type
populateWorldType( OVERWORLD_WIDTH, 2, BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, scene, "WORLD",
populateWorldType( OVERWORLD_WIDTH, 2, BLOCK_SIZE,
1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE, scene, "WORLD",
font_config );
createGrid( BLOCK_SIZE, 1 - (MAP_HEIGHT + 3) * BLOCK_SIZE, OVERWORLD_WIDTH, 2, scene );
createGrid( BLOCK_SIZE, 1 - ( MAP_HEIGHT + 3 ) * BLOCK_SIZE,
OVERWORLD_WIDTH, 2, scene );
global_vars.map.max_page = global_vars.objects.size() - MAP_WIDTH;

View File

@ -207,7 +207,7 @@ int main() {
leftStop->setColiderColor( "#FF00FF" );
scene->addObject( leftStop );
loadMap( scene, mario, "test_binary2.bin", renderer );
loadMap( scene, mario, "test_binary2.bin" );
auto font = std::make_shared< SDLPP::Font >( "testfont.ttf", 36 );
fps = std::make_shared<SDLPP::TextRenderer>(0.2, 0, 0.78, 0.1, renderer, font, "0fps", "#FFFFFF", "#000000", 0.1, SDLPP_TEXT_RIGHT);

View File

@ -7,21 +7,91 @@
#include "objectids.hpp"
#include "global_vars.hpp"
#define TERRAIN_TYPE_HAS_ADDITIONAL 0x8
#define WIDE_TERRAIN_HAS_ADDITIONAL 0x8000
#define ADDITIONAL_IS_MOD 0x80
void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > mario,
const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer ) {
const std::string &file ) {
std::vector< mapColumnType > tmp = {};
loadMap(scene, mario, file, renderer, tmp, false);
loadMap( scene, mario, file, tmp, false );
scene->moveZTop( mario );
}
uint8_t read8Bits( std::ifstream &file ) {
uint8_t data;
file.read( ( char * )&data, sizeof( uint8_t ) / sizeof( char ) );
return data;
}
void write8Bits( std::ofstream &file, uint8_t data ) {
file.write( ( char * )&data, sizeof( uint8_t ) / sizeof( char ) );
}
uint16_t read16Bits( std::ifstream &file ) {
uint16_t data;
file.read( ( char * )&data, sizeof( uint16_t ) / sizeof( char ) );
return data;
}
void write16Bits( std::ofstream &file, uint16_t data ) {
file.write( ( char * )&data, sizeof( uint16_t ) / sizeof( char ) );
}
std::pair< uint16_t, uint8_t > separateWideTerrain( uint16_t wide_terrain ) {
uint8_t terrain_type = ( wide_terrain & 0xF000 ) >> 12;
uint16_t terrain_id = ( wide_terrain & 0x0FFF ) | BLOCK_PREFIX;
return { terrain_id, terrain_type };
}
std::pair< uint8_t, uint8_t > separateAdditionalData( uint8_t data ) {
auto id = data & 0x0F;
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;
}
MapObject parseBlock( std::ifstream &map_file ) {
uint8_t character_type = 0, character_id = 0, modifier_id = 0,
modifier_data = 0;
uint16_t wide_terrain = read16Bits( map_file );
auto terrain = separateWideTerrain( wide_terrain );
uint16_t terrain_id = terrain.first;
uint8_t terrain_type = terrain.second;
if ( terrain_type & TERRAIN_TYPE_HAS_ADDITIONAL ) {
uint8_t additional_data = read8Bits( map_file );
terrain_type &= ~TERRAIN_TYPE_HAS_ADDITIONAL;
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;
modifier_data = modifier.first;
} else {
// character
auto character = separateAdditionalData( additional_data );
character_id = character.first;
character_type = character.second;
}
}
return MapObject( terrain_id, terrain_type, character_id, character_type,
modifier_id, modifier_data );
}
// editor loader
void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > &mario,
const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer,
std::vector< mapColumnType > &objects, bool editor, size_t editor_width ) {
std::vector< mapColumnType > &objects, bool editor,
size_t editor_width ) {
auto renderer = scene->getRendererShared();
std::ifstream map_file;
map_file.open( file, std::ios::in | std::ios::binary );
uint16_t cols;
@ -36,40 +106,19 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
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;
}
}
auto block = parseBlock( map_file );
if ( editor ) {
col->at(j) = { type, id, character_type, character,
modifier_type, modifier_data };
col->at( j ) = block;
}
bool destructible = false;
if(!editor && modifier_type == DESTRUCTIBLE_ID) {
if ( !editor &&
block.getModifierId() == DESTRUCTIBLE_MODIFIER_ID ) {
destructible = true;
}
// TODO add modifiers to createTerrainBlock
auto obj =
createTerrainBlock( id, static_cast< LandType::Value >( type ),
if(block.getTerrainId() != 0) {
auto obj = createTerrainBlock(
block.getTerrainId(), block.getTerrainType(),
renderer, i, j, destructible, editor );
if ( obj != nullptr ) {
if ( editor ) {
@ -77,22 +126,25 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
}
scene->addObject( obj );
}
if ( character ) {
if ( character == MARIO_ID ) {
}
if ( block.hasCharacter() ) {
if ( block.getCharacterId() == MARIO_ID ) {
if ( editor ) {
scene->addObject( createMario(
static_cast< LandType::Value >( character_type ),
block.getCharacterType(),
renderer, i, j ) );
mario = scene->getObject(scene->getObjects().size() - 1);
mario =
scene->getObject( scene->getObjects().size() - 1 );
} else {
mario->setPos( i * BLOCK_SIZE,
1 - ( 16 - j ) * BLOCK_SIZE );
}
}
}
if ( editor && modifier_type ) {
if ( editor && block.hasModifier() ) {
// TODO createModifierBlock with data
auto mod = createTerrainBlock(
modifier_type, LandType::OVERWORLD, renderer, i, j,
block.getModifierId(), LandType::OVERWORLD, renderer, i, j,
g_translucent_terrain_texture, false, editor );
mod->getCollisions()[0]->setId( EDITOR_TERRAIN_ID );
dynamic_cast< MarioBlock * >( mod.get() )->setTerrain( false );
@ -105,8 +157,6 @@ void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
}
}
// 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 );
@ -114,33 +164,23 @@ void saveMap( const std::string &file, std::vector< mapColumnType > &objects ) {
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< MapObject::TERRAIN_TYPE >( obj );
wide_type = wide_type << 12;
uint16_t write_num =
( 0x0FFF & std::get< MapObject::TERRAIN_ID >( obj ) ) |
wide_type;
// character type can be 0 (overworld), modifier data can be 0
if ( std::get< MapObject::CHARACTER_ID >( obj ) ||
std::get< MapObject::MODIFIER_TYPE >( obj ) ) {
write_num |= 0x8000;
auto &block = col[i];
auto wide_terrain = combineTerrain(block.getTerrainId(), block.getTerrainType());
// if block has additional data it needs to indicate it
if ( block.hasCharacter() || block.hasModifier() ) {
wide_terrain |= WIDE_TERRAIN_HAS_ADDITIONAL;
}
output_file.write( ( char * )&write_num,
sizeof( uint16_t ) / sizeof( char ) );
write16Bits(output_file, wide_terrain);
uint8_t additional_data = 0;
if ( std::get< MapObject::CHARACTER_ID >( obj ) ) {
additional_data |= std::get< MapObject::CHARACTER_TYPE >( obj )
<< 4;
additional_data |= std::get< MapObject::CHARACTER_ID >( obj );
} else if ( std::get< MapObject::MODIFIER_TYPE >( obj ) ) {
additional_data |= std::get< MapObject::MODIFIER_TYPE >( obj )
<< 4;
additional_data |= 0x80;
additional_data |= std::get< MapObject::MODIFIER_DATA >( obj );
if ( block.hasCharacter() ) {
additional_data = combineAdditionalData(block.getCharacterId(), block.getCharacterType());
} else if ( block.hasModifier() ) {
// TODO seriously change order of id/data!!!
additional_data = combineAdditionalData(block.getModifierData(), block.getModifierId());
additional_data |= ADDITIONAL_IS_MOD;
}
if ( additional_data ) {
output_file.write( ( char * )&additional_data,
sizeof( uint8_t ) / sizeof( char ) );
write8Bits(output_file, additional_data);
}
}
}

View File

@ -3,30 +3,16 @@
#include "../sdlpp/sdlpp_scene.hpp"
#include "../sdlpp/sdlpp_rectrenderer.hpp"
#include "mapobject.hpp"
struct MapObject {
enum Index {
TERRAIN_TYPE = 0,
TERRAIN_ID = 1,
CHARACTER_TYPE = 2,
CHARACTER_ID = 3,
MODIFIER_TYPE = 4,
MODIFIER_DATA = 5,
};
};
typedef std::tuple< uint8_t, uint16_t, uint8_t, uint8_t, uint8_t, uint8_t >
mapObjectType;
typedef std::array< mapObjectType, 16 > mapColumnType;
typedef std::array< MapObject, 16 > mapColumnType;
void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > mario,
const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer );
const std::string &file );
void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > &mario,
const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer,
std::vector< mapColumnType > &objects, bool editor = false, size_t editor_width = 0 );
void saveMap( const std::string &file, std::vector< mapColumnType > &objects );

98
mario/mapobject.cpp Normal file
View File

@ -0,0 +1,98 @@
#include "mapobject.hpp"
MapObject::MapObject( uint16_t terrain_id, LandType::Value terrain_type,
uint8_t character_id, LandType::Value character_type,
uint8_t modifier_id, uint8_t modifier_data ) {
setTerrain(terrain_id, terrain_type);
if(character_id != 0)
setCharacter(character_id, character_type);
if(modifier_id != 0)
setModifier(modifier_id, modifier_data);
}
MapObject::MapObject( uint16_t terrain_id, uint8_t terrain_type,
uint8_t character_id, uint8_t character_type,
uint8_t modifier_id, uint8_t modifier_data )
: MapObject( terrain_id, static_cast< LandType::Value >( terrain_type ),
character_id,
static_cast< LandType::Value >( character_type ),
modifier_id, modifier_data ) {}
void MapObject::setTerrain( uint16_t id, LandType::Value land_type ) {
terrain_id = id;
terrain_type = land_type;
}
void MapObject::setTerrain( uint16_t id, uint8_t land_type ) {
setTerrain( id, static_cast< LandType::Value >( land_type ) );
}
void MapObject::setCharacter( uint8_t id, LandType::Value land_type ) {
character_id = id;
character_type = land_type;
if(hasModifier()) {
modifier_id = 0;
modifier_data = 0;
}
}
void MapObject::setCharacter( uint8_t id, uint8_t land_type ) {
setCharacter( id, static_cast< LandType::Value >( land_type ) );
}
void MapObject::setModifier( uint8_t id, uint8_t data ) {
modifier_id = id;
modifier_data = data;
if(hasCharacter()) {
character_id = 0;
character_type = LandType::OVERWORLD;
}
}
void MapObject::unsetTerrain() {
setTerrain(0, 0);
}
void MapObject::unsetModifier() {
if ( hasModifier() ) {
setModifier( 0, 0 );
}
}
void MapObject::unsetCharacter() {
if ( hasCharacter() ) {
setCharacter( 0, 0 );
}
}
bool MapObject::hasCharacter() {
return character_id != 0;
}
bool MapObject::hasModifier() {
return modifier_id != 0;
}
uint16_t MapObject::getTerrainId() {
return terrain_id;
}
uint8_t MapObject::getCharacterId() {
return character_id;
}
uint8_t MapObject::getModifierId() {
return modifier_id;
}
LandType::Value MapObject::getTerrainType() {
return terrain_type;
}
LandType::Value MapObject::getCharacterType() {
return character_type;
}
uint8_t MapObject::getModifierData() {
return modifier_data;
}

42
mario/mapobject.hpp Normal file
View File

@ -0,0 +1,42 @@
#ifndef MAP_OBJECT_H
#define MAP_OBJECT_H
#include "blocks.hpp"
class MapObject {
public:
MapObject() = default;
MapObject( uint16_t terrain_id, uint8_t terrain_type, uint8_t character_id,
uint8_t character_type, uint8_t modifier_id,
uint8_t modifier_data );
MapObject( uint16_t terrain_id, LandType::Value terrain_type,
uint8_t character_id, LandType::Value character_type,
uint8_t modifier_id, uint8_t modifier_data );
void setTerrain( uint16_t id, LandType::Value land_type );
void setTerrain( uint16_t id, uint8_t land_type );
void setCharacter( uint8_t id, LandType::Value land_type );
void setCharacter( uint8_t id, uint8_t land_type );
void setModifier( uint8_t id, uint8_t data );
void unsetTerrain();
void unsetModifier();
void unsetCharacter();
bool hasCharacter();
bool hasModifier();
uint16_t getTerrainId();
uint8_t getCharacterId();
uint8_t getModifierId();
LandType::Value getTerrainType();
LandType::Value getCharacterType();
uint8_t getModifierData();
private:
LandType::Value terrain_type = LandType::OVERWORLD;
uint16_t terrain_id = 0;
LandType::Value character_type = LandType::OVERWORLD;
uint8_t character_id = 0;
uint8_t modifier_id = 0;
uint8_t modifier_data = 0;
};
#endif

View File

@ -63,7 +63,7 @@
#define CANNON_ID 0x703A
// modifiers
#define DESTRUCTIBLE_ID 0x01
#define DESTRUCTIBLE_MODIFIER_ID 0x01
// character IDs
#define MARIO_ID 0x0F