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 OUTPUTFLAG = -o
endif 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) ifneq ($(UNAME_S),Windows)
COMMON_OBJECTS += libsdlpp.a COMMON_OBJECTS += libsdlpp.a
endif endif
@ -69,6 +69,8 @@ tool_box.${OBJEXT}: tool_box.cpp ../sdlpp/sdlpp.hpp sprites.hpp tool_box.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< $(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
editor_visitor.${OBJEXT}: editor_visitor.cpp ../sdlpp/sdlpp.hpp sprites.hpp editor_visitor.hpp editor_visitor.${OBJEXT}: editor_visitor.cpp ../sdlpp/sdlpp.hpp sprites.hpp editor_visitor.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< $(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 mario.${OBJEXT}: mario.cpp ../sdlpp/sdlpp.hpp mario.hpp global_vars.hpp objectids.hpp sprites.hpp ../sdlpp/sdlpp_rectrenderer.hpp
$(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $< $(CXX) $(CXXFLAGS) -c ${OUTPUTFLAG}$@ $<
libsdlpp.a: ../sdlpp libsdlpp.a: ../sdlpp

View File

@ -154,7 +154,7 @@ const std::vector< uint64_t > possibleBlocks = {
}; };
const std::vector< uint64_t > possibleMods = { const std::vector< uint64_t > possibleMods = {
DESTRUCTIBLE_ID, DESTRUCTIBLE_MODIFIER_ID,
}; };
const std::vector< uint64_t > possibleCharacters = { 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_PEDESTAL_ID, &CANNON_PEDESTAL_SRC },
{ CANNON_ID, &CANNON_SRC }, { CANNON_ID, &CANNON_SRC },
{ MARIO_ID, &MARIO_STANDING_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 = { 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_PEDESTAL_ID, HAS_COLLISION },
{ CANNON_ID, HAS_COLLISION }, { CANNON_ID, HAS_COLLISION },
{ MARIO_ID, 0 }, { MARIO_ID, 0 },
{ DESTRUCTIBLE_ID, 0 }, { DESTRUCTIBLE_MODIFIER_ID, 0 },
}; };
bool blockCanBeDestroyed(uint64_t id) { bool blockCanBeDestroyed(uint64_t id) {

View File

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

View File

@ -207,7 +207,7 @@ int main() {
leftStop->setColiderColor( "#FF00FF" ); leftStop->setColiderColor( "#FF00FF" );
scene->addObject( leftStop ); 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 ); 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); 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,92 +7,144 @@
#include "objectids.hpp" #include "objectids.hpp"
#include "global_vars.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, void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > mario, std::shared_ptr< SDLPP::RenderObject > mario,
const std::string &file, const std::string &file ) {
std::shared_ptr< SDLPP::Renderer > &renderer ) {
std::vector< mapColumnType > tmp = {}; std::vector< mapColumnType > tmp = {};
loadMap(scene, mario, file, renderer, tmp, false); loadMap( scene, mario, file, tmp, false );
scene->moveZTop(mario); 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 // editor loader
void loadMap( std::shared_ptr< SDLPP::Scene > &scene, void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > &mario, std::shared_ptr< SDLPP::RenderObject > &mario,
const std::string &file, const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer, std::vector< mapColumnType > &objects, bool editor,
std::vector< mapColumnType > &objects, bool editor, size_t editor_width ) { size_t editor_width ) {
auto renderer = scene->getRendererShared();
std::ifstream map_file; std::ifstream map_file;
map_file.open( file, std::ios::in | std::ios::binary ); map_file.open( file, std::ios::in | std::ios::binary );
uint16_t cols; uint16_t cols;
map_file.read( ( char * )&cols, sizeof( uint16_t ) / sizeof( char ) ); map_file.read( ( char * )&cols, sizeof( uint16_t ) / sizeof( char ) );
if(editor) { if ( editor ) {
objects.resize( cols ); objects.resize( cols );
} }
mapColumnType *col = nullptr; mapColumnType *col = nullptr;
for ( uint16_t i = 0; i < cols; i++ ) { for ( uint16_t i = 0; i < cols; i++ ) {
if(editor) { if ( editor ) {
col = &objects[i]; col = &objects[i];
} }
for ( int j = 0; j < 16; j++ ) { for ( int j = 0; j < 16; j++ ) {
uint16_t input_number; auto block = parseBlock( map_file );
uint8_t additional_data = 0; if ( editor ) {
uint8_t character_type = 0, character = 0, modifier_type = 0, col->at( j ) = block;
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;
}
}
if(editor) {
col->at(j) = { type, id, character_type, character,
modifier_type, modifier_data };
} }
bool destructible = false; bool destructible = false;
if(!editor && modifier_type == DESTRUCTIBLE_ID) { if ( !editor &&
block.getModifierId() == DESTRUCTIBLE_MODIFIER_ID ) {
destructible = true; destructible = true;
} }
// TODO add modifiers to createTerrainBlock // TODO add modifiers to createTerrainBlock
auto obj = if(block.getTerrainId() != 0) {
createTerrainBlock( id, static_cast< LandType::Value >( type ), auto obj = createTerrainBlock(
renderer, i, j, destructible, editor ); block.getTerrainId(), block.getTerrainType(),
if(obj != nullptr) { renderer, i, j, destructible, editor );
if(editor) { if ( obj != nullptr ) {
obj->getCollisions()[0]->setId( EDITOR_TERRAIN_ID ); if ( editor ) {
obj->getCollisions()[0]->setId( EDITOR_TERRAIN_ID );
}
scene->addObject( obj );
} }
scene->addObject( obj );
} }
if ( character ) { if ( block.hasCharacter() ) {
if ( character == MARIO_ID ) { if ( block.getCharacterId() == MARIO_ID ) {
if(editor) { if ( editor ) {
scene->addObject( createMario( scene->addObject( createMario(
static_cast< LandType::Value >( character_type ), block.getCharacterType(),
renderer, i, j ) ); renderer, i, j ) );
mario = scene->getObject(scene->getObjects().size() - 1); mario =
scene->getObject( scene->getObjects().size() - 1 );
} else { } else {
mario->setPos( i * BLOCK_SIZE, mario->setPos( i * BLOCK_SIZE,
1 - ( 16 - j ) * BLOCK_SIZE ); 1 - ( 16 - j ) * BLOCK_SIZE );
} }
} }
} }
if ( editor && modifier_type ) { if ( editor && block.hasModifier() ) {
// TODO createModifierBlock with data
auto mod = createTerrainBlock( auto mod = createTerrainBlock(
modifier_type, LandType::OVERWORLD, renderer, i, j, block.getModifierId(), LandType::OVERWORLD, renderer, i, j,
g_translucent_terrain_texture, false, editor ); g_translucent_terrain_texture, false, editor );
mod->getCollisions()[0]->setId( EDITOR_TERRAIN_ID ); mod->getCollisions()[0]->setId( EDITOR_TERRAIN_ID );
dynamic_cast< MarioBlock * >( mod.get() )->setTerrain( false ); 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 ) { void saveMap( const std::string &file, std::vector< mapColumnType > &objects ) {
std::ofstream output_file; std::ofstream output_file;
output_file.open( file, std::ios::out | std::ios::binary ); 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 ) ); output_file.write( ( char * )&cols, sizeof( uint16_t ) / sizeof( char ) );
for ( auto &col : objects ) { for ( auto &col : objects ) {
for ( int i = 0; i < 16; i++ ) { for ( int i = 0; i < 16; i++ ) {
auto &obj = col[i]; auto &block = col[i];
uint16_t wide_type = std::get< MapObject::TERRAIN_TYPE >( obj ); auto wide_terrain = combineTerrain(block.getTerrainId(), block.getTerrainType());
wide_type = wide_type << 12; // if block has additional data it needs to indicate it
uint16_t write_num = if ( block.hasCharacter() || block.hasModifier() ) {
( 0x0FFF & std::get< MapObject::TERRAIN_ID >( obj ) ) | wide_terrain |= WIDE_TERRAIN_HAS_ADDITIONAL;
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;
} }
output_file.write( ( char * )&write_num, write16Bits(output_file, wide_terrain);
sizeof( uint16_t ) / sizeof( char ) );
uint8_t additional_data = 0; uint8_t additional_data = 0;
if ( std::get< MapObject::CHARACTER_ID >( obj ) ) { if ( block.hasCharacter() ) {
additional_data |= std::get< MapObject::CHARACTER_TYPE >( obj ) additional_data = combineAdditionalData(block.getCharacterId(), block.getCharacterType());
<< 4; } else if ( block.hasModifier() ) {
additional_data |= std::get< MapObject::CHARACTER_ID >( obj ); // TODO seriously change order of id/data!!!
} else if ( std::get< MapObject::MODIFIER_TYPE >( obj ) ) { additional_data = combineAdditionalData(block.getModifierData(), block.getModifierId());
additional_data |= std::get< MapObject::MODIFIER_TYPE >( obj ) additional_data |= ADDITIONAL_IS_MOD;
<< 4;
additional_data |= 0x80;
additional_data |= std::get< MapObject::MODIFIER_DATA >( obj );
} }
if ( additional_data ) { if ( additional_data ) {
output_file.write( ( char * )&additional_data, write8Bits(output_file, additional_data);
sizeof( uint8_t ) / sizeof( char ) );
} }
} }
} }

View File

@ -3,30 +3,16 @@
#include "../sdlpp/sdlpp_scene.hpp" #include "../sdlpp/sdlpp_scene.hpp"
#include "../sdlpp/sdlpp_rectrenderer.hpp" #include "../sdlpp/sdlpp_rectrenderer.hpp"
#include "mapobject.hpp"
struct MapObject { typedef std::array< MapObject, 16 > mapColumnType;
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;
void loadMap( std::shared_ptr< SDLPP::Scene > &scene, void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > mario, std::shared_ptr< SDLPP::RenderObject > mario,
const std::string &file, const std::string &file );
std::shared_ptr< SDLPP::Renderer > &renderer );
void loadMap( std::shared_ptr< SDLPP::Scene > &scene, void loadMap( std::shared_ptr< SDLPP::Scene > &scene,
std::shared_ptr< SDLPP::RenderObject > &mario, std::shared_ptr< SDLPP::RenderObject > &mario,
const std::string &file, const std::string &file,
std::shared_ptr< SDLPP::Renderer > &renderer,
std::vector< mapColumnType > &objects, bool editor = false, size_t editor_width = 0 ); std::vector< mapColumnType > &objects, bool editor = false, size_t editor_width = 0 );
void saveMap( const std::string &file, std::vector< mapColumnType > &objects ); 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 #define CANNON_ID 0x703A
// modifiers // modifiers
#define DESTRUCTIBLE_ID 0x01 #define DESTRUCTIBLE_MODIFIER_ID 0x01
// character IDs // character IDs
#define MARIO_ID 0x0F #define MARIO_ID 0x0F