Mario editor: more terrain, can place Mario

This commit is contained in:
zv0n 2021-05-07 23:17:05 +02:00
parent 85807ca962
commit c849895c72
8 changed files with 253 additions and 39 deletions

View File

@ -6,8 +6,10 @@
MarioBlock::MarioBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> renderer, std::shared_ptr<SDLPP::Texture> texture, SDL_Rect src) : RectangleRender( x * BLOCK_SIZE, 1 - (16-y) * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE, renderer, texture, src ) {}
void MarioBlock::visit( SDLPP::Visitor &visitor ) {
// TODO if character don't
if(!_tool && !_character && visitor.getVisitorType() == TOOL_VISITOR_TYPE) {
if(!_tool && _terrain && visitor.getVisitorType() == TOOL_VISITOR_TYPE) {
destroy();
}
if(!_tool && !_terrain && visitor.getVisitorType() == MODIFIER_VISITOR_TYPE) {
destroy();
}
visitor.visit(*this);
@ -15,36 +17,71 @@ void MarioBlock::visit( SDLPP::Visitor &visitor ) {
void MarioBlock::setTool(bool tool) {
_tool = tool;
}
void MarioBlock::setCharacter(bool character) {
_character = character;
void MarioBlock::setTerrain(bool terrain) {
_terrain = terrain;
}
const std::vector< uint64_t > possibleBlocks = { FLOOR_ID,
HILL_INCLINE_ID,
HILL_DECLINE_ID,
HILL_DOTS_RIGHT_ID,
STEP_ID,
HILL_TOP_ID,
HILL_DOTS_LEFT_ID,
HILL_FILL_ID,
HILL_TOP_ID,
BUSH_LEFT_ID,
BUSH_MIDDLE_ID,
BUSH_RIGHT_ID,
CLOUD_LEFT_BOTTOM_ID,
CLOUD_MIDDLE_BOTTOM_ID,
CLOUD_RIGHT_BOTTOM_ID,
HILL_INCLINE_ID,
HILL_DOTS_RIGHT_ID,
HILL_DECLINE_ID,
CLOUD_LEFT_TOP_ID,
CLOUD_MIDDLE_TOP_ID,
CLOUD_RIGHT_TOP_ID,
PIPE_LEFT_BOTTOM_ID,
VINE_TOP_ID,
CLOUD_LEFT_BOTTOM_ID,
CLOUD_MIDDLE_BOTTOM_ID,
CLOUD_RIGHT_BOTTOM_ID,
VINE_BOTTOM_ID,
BRICK_TOP_ID,
BRICK_ID,
FLAG_ID,
WATER_TOP_ID,
BUSH_LEFT_ID,
BUSH_MIDDLE_ID,
BUSH_RIGHT_ID,
WATER_FILL_ID,
PIPE_LEFT_TOP_ID,
PIPE_RIGHT_BOTTOM_ID,
PIPE_RIGHT_TOP_ID,
CASTLE_TOWER_ID,
CASTLE_TOWER_FILLED_ID,
PIPE_LEFT_BOTTOM_ID,
PIPE_RIGHT_BOTTOM_ID,
CASTLE_LEFT_ID,
CASTLE_RIGHT_ID,
CASTLE_BLACK_ID,
POLE_TOP_ID,
CASTLE_ENTRY_ID,
CASTLE_TOWER_ID,
CASTLE_TOWER_FILLED_ID };
SIDEWAY_PIPE_END_TOP_ID,
SIDEWAY_PIPE_MIDDLE_TOP_ID,
POLE_BOTTOM_ID,
CASTLE_BLACK_ID,
SIDEWAY_PIPE_END_BOTTOM_ID,
SIDEWAY_PIPE_MIDDLE_BOTTOM_ID,
SIDEWAY_PIPE_CONNECTOR_TOP_ID,
TREE_PLATFORM_TOP_LEFT_ID,
TREE_PLATFORM_TOP_MIDDLE_ID,
TREE_PLATFORM_TOP_RIGHT_ID,
SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID,
MUSHROOM_PLATFORM_TOP_LEFT_ID,
MUSHROOM_PLATFORM_TOP_MIDDLE_ID,
MUSHROOM_PLATFORM_TOP_RIGHT_ID,
TREE_PLATFORM_BARK_ID,
MUSHROOM_PLATFORM_BARK_TOP_ID,
TREE_LEAVES_TOP_ID,
TREE_LEAVES_SMALL_ID,
CANNON_TOWER_ID,
MUSHROOM_PLATFORM_BARK_BOTTOM_ID,
TREE_LEAVES_BOTTOM_ID,
TREE_BARK_ID,
CANNON_PEDESTAL_ID,
CANNON_ID,
MARIO_ID,
};
const std::unordered_map<uint64_t, const SDL_Rect*> block_mapping = {
{FLOOR_ID, &FLOOR_SRC}, {HILL_INCLINE_ID, &HILL_INCLINE_SRC},
@ -59,7 +96,32 @@ const std::unordered_map<uint64_t, const SDL_Rect*> block_mapping = {
{PIPE_RIGHT_TOP_ID, &PIPE_RIGHT_TOP_SRC}, {CASTLE_LEFT_ID, &CASTLE_LEFT_SRC},
{CASTLE_RIGHT_ID, &CASTLE_RIGHT_SRC}, {CASTLE_BLACK_ID, &CASTLE_BLACK_SRC},
{CASTLE_ENTRY_ID, &CASTLE_ENTRY_SRC}, {CASTLE_TOWER_ID, &CASTLE_TOWER_SRC},
{CASTLE_TOWER_FILLED_ID, &CASTLE_TOWER_FILLED_SRC}
{CASTLE_TOWER_FILLED_ID, &CASTLE_TOWER_FILLED_SRC}, {VINE_TOP_ID, &VINE_TOP_SRC},
{VINE_BOTTOM_ID, &VINE_BOTTOM_SRC}, {POLE_TOP_ID, &POLE_TOP_SRC},
{POLE_BOTTOM_ID, &POLE_BOTTOM_SRC}, {FLAG_ID, &FLAG_SRC},
{STEP_ID, &STEP_SRC}, {BRICK_ID, &BRICK_SRC}, {BRICK_TOP_ID, &BRICK_TOP_SRC},
{SIDEWAY_PIPE_END_TOP_ID, &SIDEWAY_PIPE_END_TOP_SRC},
{SIDEWAY_PIPE_END_BOTTOM_ID, &SIDEWAY_PIPE_END_BOTTOM_SRC},
{SIDEWAY_PIPE_MIDDLE_TOP_ID, &SIDEWAY_PIPE_MIDDLE_TOP_SRC},
{SIDEWAY_PIPE_MIDDLE_BOTTOM_ID, &SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC},
{SIDEWAY_PIPE_CONNECTOR_TOP_ID, &SIDEWAY_PIPE_CONNECTOR_TOP_SRC},
{SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID, &SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC},
{TREE_PLATFORM_TOP_LEFT_ID, &TREE_PLATFORM_TOP_LEFT_SRC},
{TREE_PLATFORM_TOP_MIDDLE_ID, &TREE_PLATFORM_TOP_MIDDLE_SRC},
{TREE_PLATFORM_TOP_RIGHT_ID, &TREE_PLATFORM_TOP_RIGHT_SRC},
{TREE_PLATFORM_BARK_ID, &TREE_PLATFORM_BARK_SRC},
{WATER_TOP_ID, &WATER_TOP_SRC}, {WATER_FILL_ID, &WATER_FILL_SRC},
{MUSHROOM_PLATFORM_TOP_LEFT_ID, &MUSHROOM_PLATFORM_TOP_LEFT_SRC},
{MUSHROOM_PLATFORM_TOP_MIDDLE_ID, &MUSHROOM_PLATFORM_TOP_MIDDLE_SRC},
{MUSHROOM_PLATFORM_TOP_RIGHT_ID, &MUSHROOM_PLATFORM_TOP_RIGHT_SRC},
{MUSHROOM_PLATFORM_BARK_TOP_ID, &MUSHROOM_PLATFORM_BARK_TOP_SRC},
{MUSHROOM_PLATFORM_BARK_BOTTOM_ID, &MUSHROOM_PLATFORM_BARK_BOTTOM_SRC},
{TREE_BARK_ID, &TREE_BARK_SRC}, {TREE_LEAVES_SMALL_ID, &TREE_LEAVES_SMALL_SRC},
{TREE_LEAVES_TOP_ID, &TREE_LEAVES_TOP_SRC},
{TREE_LEAVES_BOTTOM_ID, &TREE_LEAVES_BOTTOM_SRC},
{CANNON_TOWER_ID, &CANNON_TOWER_SRC},
{CANNON_PEDESTAL_ID, &CANNON_PEDESTAL_SRC},
{CANNON_ID, &CANNON_SRC}, {MARIO_ID, &MARIO_STANDING_SRC}
};
std::shared_ptr< SDLPP::RectangleRender >
@ -125,6 +187,6 @@ createTerrainBlock( uint64_t block_id, BlockType type,
std::shared_ptr<SDLPP::RectangleRender> createMario( BlockType type, std::shared_ptr<SDLPP::Renderer> &renderer, int x, int y ) {
//TODO add type additions
auto mario = createBlock( renderer, x, y, g_mario_texture, MARIO_STANDING_SRC, MARIO_ID, true );
dynamic_cast<MarioBlock&>(*mario).setCharacter();
dynamic_cast<MarioBlock&>(*mario).setTerrain(false);
return mario;
}

View File

@ -9,10 +9,10 @@ public:
MarioBlock(int x, int y, std::shared_ptr<SDLPP::Renderer> renderer, std::shared_ptr<SDLPP::Texture> texture, SDL_Rect src);
void visit( SDLPP::Visitor &visitor ) override;
void setTool(bool tool = true);
void setCharacter(bool character = true);
void setTerrain(bool terrain = true);
private:
bool _tool = false;
bool _character = false;
bool _terrain = true;
};
extern const std::vector<uint64_t> possibleBlocks;

View File

@ -41,6 +41,10 @@ int current_tool_index = 0;
int max_tool_index = 0;
std::shared_ptr<SDLPP::Texture> g_placeholder_texture = nullptr;
std::shared_ptr<SDLPP::Texture> g_placeholder_mario = nullptr;
std::shared_ptr<SDLPP::RenderObject> g_mario = nullptr;
SDLPP::Vec2D<int> g_mario_pos = {0,0};
void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) {
switch ( key ) {
@ -65,11 +69,21 @@ void handleKeyDown( SDL_Keycode key, SDLPP::Scene &scene ) {
}
void updateTool() {
if(possibleBlocks[current_block] == MARIO_ID) {
current_tool->setTexture(g_placeholder_mario, getSourceRectByID(possibleBlocks[current_block], OVERWORLD));
} else {
current_tool->setTexture(g_placeholder_texture, getSourceRectByID(possibleBlocks[current_block], OVERWORLD));
}
current_tool->setId(possibleBlocks[current_block]);
current_tool->getCollisions()[0]->setId(possibleBlocks[current_block]);
}
void removeMario() {
auto prev = objects[g_mario_pos.getX()][g_mario_pos.getY()];
objects[g_mario_pos.getX()][g_mario_pos.getY()] = {std::get<0>(prev), std::get<1>(prev), 0, 0, 0, 0};
g_mario->destroy();
}
void updateToolSelection(int prev_index) {
auto prev = prev_index * 8;
auto cur = current_tool_index * 8;
@ -155,20 +169,42 @@ void pollEvents( SDLPP::Scene &scene ) {
std::lock_guard<std::mutex> lock(destruction_mutex);
ToolVisitor visitor;
if(current_tool->getId() < 0x7000) {
visitor.setVisitorType(MODIFIER_VISITOR_TYPE);
} else {
visitor.setVisitorType(TOOL_VISITOR_TYPE);
}
// TODO
scene.visitCollisions(*current_tool, visitor);
if(visitor.removeBlock() && !visitor.addBlock()) {
// TODO check if modifier
auto prev = objects[current_start_index + current_box.getX()][current_box.getY()];
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, 0, std::get<2>(prev), std::get<3>(prev), 0, 0};
if(visitor.getVisitorType() == TOOL_VISITOR_TYPE) {
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, 0, std::get<2>(prev), std::get<3>(prev), std::get<4>(prev), std::get<5>(prev)};
} else {
objects[current_start_index + current_box.getX()][current_box.getY()] = {std::get<0>(prev), std::get<1>(prev), 0, 0, 0, 0};
}
} else if(visitor.addBlock()) {
// TODO check if modifier
auto prev = objects[current_start_index + current_box.getX()][current_box.getY()];
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, current_tool->getId(), std::get<2>(prev), std::get<3>(prev), 0, 0};
auto obj = createTerrainBlock(current_tool->getId(), OVERWORLD, renderer, 1 + current_box.getX(), current_box.getY(), true);
int z_index = 1;
std::shared_ptr<SDLPP::RenderObject> obj = nullptr;
if(visitor.getVisitorType() == TOOL_VISITOR_TYPE) {
objects[current_start_index + current_box.getX()][current_box.getY()] = {OVERWORLD, current_tool->getId(), std::get<2>(prev), std::get<3>(prev), std::get<4>(prev), std::get<5>(prev)};
obj = createTerrainBlock(current_tool->getId(), OVERWORLD, renderer, 1 + current_box.getX(), current_box.getY(), true);
obj->getCollisions()[0]->setId(EDITOR_TERRAIN_ID);
} else {
// TODO check if modifier or character
objects[current_start_index + current_box.getX()][current_box.getY()] = {std::get<0>(prev), std::get<1>(prev), OVERWORLD, MARIO_ID, 0, 0};
obj = createMario(OVERWORLD, renderer, 1 + current_box.getX(), current_box.getY());
if(g_mario) {
removeMario();
}
g_mario = obj;
g_mario_pos = {current_start_index + current_box.getX(), current_box.getY()};
obj->getCollisions()[0]->setId(EDITOR_CHARACTER_ID);
z_index = scene.getObjects().size() - 1;
}
scene.addObject(obj);
scene.setZIndex(obj, 1);
scene.setZIndex(obj, z_index);
}
}
if(current_tool_box.getX() != -1) {
@ -307,13 +343,18 @@ int main() {
}
int tool_index = 0;
for(auto &block : possibleBlocks) {
if(block == MARIO_ID ) {
tools.push_back(createMario(OVERWORLD, renderer, 0, 0));
} else {
tools.push_back(createTerrainBlock(block, OVERWORLD, renderer, false));
}
tools.back()->setHidden(true);
tools.back()->setPermanent();
auto x = tool_index % 4;
auto y = tool_index / 4;
// TODO add 14 and 1 as constants somewhere
// TODO investigate
tools.back()->setPos(13*BLOCK_SIZE + x*BLOCK_SIZE, BLOCK_SIZE + y*BLOCK_SIZE);
// TODO investigate when not permanent requires `-1` on x position
tools.back()->setPos(14*BLOCK_SIZE + x*BLOCK_SIZE, BLOCK_SIZE + y*BLOCK_SIZE);
// std::cout << "TOOL POS: " << tools.back()->getPos().getX() << ", " << tools.back()->getPos().getY() << std::endl;
scene->addObject(tools.back());
tool_index = (tool_index + 1) % 8;
@ -363,9 +404,12 @@ int main() {
g_placeholder_texture = std::make_shared< SDLPP::Texture >(
renderer, "sprites/terrain.png", MARIO_OVERWORLD_COLORKEY );
g_placeholder_texture->setAlpha(100);
g_placeholder_mario = std::make_shared< SDLPP::Texture >(
renderer, "sprites/mario.png", MARIO_OVERWORLD_COLORKEY );
g_placeholder_mario->setAlpha(100);
current_tool = createTerrainBlock(possibleBlocks[current_block], OVERWORLD, renderer, g_placeholder_texture, false);
current_tool->addCollision(SDLPP::RectColider(0.1, 0.1, 0.8, 0.8));
current_tool->setTextureAlpha(100);
dynamic_cast<MarioBlock&>(*current_tool).setTool();
scene->addObject(current_tool);
scene->moveZTop(current_tool);

View File

@ -62,7 +62,12 @@ void ToolVisitor::visit( const SDLPP::RenderObject &obj ) {
switch ( id ) {
case EDITOR_TERRAIN_ID:
remove_block = true;
if(obj.getId() == source_id) {
if(obj.getId() == source_id && getVisitorType() == TOOL_VISITOR_TYPE) {
add_block = false;
}
case EDITOR_CHARACTER_ID:
remove_block = true;
if(obj.getId() == source_id && getVisitorType() == MODIFIER_VISITOR_TYPE) {
add_block = false;
}
default:

View File

@ -194,6 +194,7 @@ int main() {
auto scene = std::make_shared< SDLPP::Scene >( renderer );
auto bg = std::make_shared< SDLPP::RectangleRender >(
0, 0, 10, 10, renderer, MARIO_OVERWORLD_COLORKEY, true );
bg->setPermanent();
bg->setStatic();
bg->setId( 1 );
scene->addObject( bg );

View File

@ -1,6 +1,7 @@
#ifndef OBJECTIDS_H
#define OBJECTIDS_H
// terrain
#define BLOCK_PREFIX 0x7000
#define FLOOR_ID 0x7001
#define HILL_INCLINE_ID 0x7002
@ -28,6 +29,41 @@
#define CASTLE_ENTRY_ID 0x7018
#define CASTLE_TOWER_ID 0x7019
#define CASTLE_TOWER_FILLED_ID 0x701A
#define VINE_TOP_ID 0x701B
#define VINE_BOTTOM_ID 0x701C
#define POLE_TOP_ID 0x701D
#define POLE_BOTTOM_ID 0x701E
#define FLAG_ID 0x701F
#define STEP_ID 0x7020
#define BRICK_ID 0x7021
#define BRICK_TOP_ID 0x7022
#define SIDEWAY_PIPE_END_TOP_ID 0x7023
#define SIDEWAY_PIPE_END_BOTTOM_ID 0x7024
#define SIDEWAY_PIPE_MIDDLE_TOP_ID 0x7025
#define SIDEWAY_PIPE_MIDDLE_BOTTOM_ID 0x7026
#define SIDEWAY_PIPE_CONNECTOR_TOP_ID 0x7027
#define SIDEWAY_PIPE_CONNECTOR_BOTTOM_ID 0x7028
#define TREE_PLATFORM_TOP_LEFT_ID 0x7029
#define TREE_PLATFORM_TOP_MIDDLE_ID 0x702A
#define TREE_PLATFORM_TOP_RIGHT_ID 0x702B
#define TREE_PLATFORM_BARK_ID 0x702C
#define WATER_TOP_ID 0x702D
#define WATER_FILL_ID 0x702E
#define MUSHROOM_PLATFORM_TOP_LEFT_ID 0x702F
#define MUSHROOM_PLATFORM_TOP_MIDDLE_ID 0x7030
#define MUSHROOM_PLATFORM_TOP_RIGHT_ID 0x7031
#define MUSHROOM_PLATFORM_BARK_TOP_ID 0x7032
#define MUSHROOM_PLATFORM_BARK_BOTTOM_ID 0x7033
#define TREE_BARK_ID 0x7034
#define TREE_LEAVES_SMALL_ID 0x7035
#define TREE_LEAVES_TOP_ID 0x7036
#define TREE_LEAVES_BOTTOM_ID 0x7037
#define CANNON_TOWER_ID 0x7038
#define CANNON_PEDESTAL_ID 0x7039
#define CANNON_ID 0x703A
// modifiers
// character IDs
#define MARIO_ID 0x0F
@ -47,9 +83,11 @@
#define EDITOR_TOOL_ID 0xF006
#define EDITOR_LEFT_TOOL_ID 0xF007
#define EDITOR_RIGHT_TOOL_ID 0xF008
#define EDITOR_CHARACTER_ID 0xF009
#define TOOL_VISITOR_TYPE 0xE001
#define MOUSE_VISITOR_TYPE 0xE002
#define MARIO_VISITOR_TYPE 0xE003
#define MODIFIER_VISITOR_TYPE 0xE002
#define MOUSE_VISITOR_TYPE 0xE003
#define MARIO_VISITOR_TYPE 0xE004
#endif

View File

@ -46,6 +46,38 @@ const SDL_Rect CASTLE_BLACK_SRC = {86, 131, 16, 16};
const SDL_Rect CASTLE_ENTRY_SRC = {86, 114, 16, 16};
const SDL_Rect CASTLE_TOWER_SRC = {69, 114, 16, 16};
const SDL_Rect CASTLE_TOWER_FILLED_SRC = {103, 114, 16, 16};
const SDL_Rect VINE_TOP_SRC = {69, 29, 16, 16};
const SDL_Rect VINE_BOTTOM_SRC = {69, 46, 16, 16};
const SDL_Rect POLE_TOP_SRC = {86, 29, 16, 16};
const SDL_Rect POLE_BOTTOM_SRC = {86, 46, 16, 16};
const SDL_Rect FLAG_SRC = {137, 46, 16, 16};
const SDL_Rect STEP_SRC = {86, 63, 16, 16};
const SDL_Rect BRICK_SRC = {35, 97, 16, 16};
const SDL_Rect BRICK_TOP_SRC = {18, 97, 16, 16};
const SDL_Rect SIDEWAY_PIPE_END_TOP_SRC = {69, 80, 16, 16};
const SDL_Rect SIDEWAY_PIPE_END_BOTTOM_SRC = {69, 97, 16, 16};
const SDL_Rect SIDEWAY_PIPE_MIDDLE_TOP_SRC = {86, 80, 16, 16};
const SDL_Rect SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC = {86, 97, 16, 16};
const SDL_Rect SIDEWAY_PIPE_CONNECTOR_TOP_SRC = {103, 80, 16, 16};
const SDL_Rect SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC = {103, 97, 16, 16};
const SDL_Rect TREE_PLATFORM_TOP_LEFT_SRC = {137, 12, 16, 16};
const SDL_Rect TREE_PLATFORM_TOP_MIDDLE_SRC = {154, 12, 16, 16};
const SDL_Rect TREE_PLATFORM_TOP_RIGHT_SRC = {171, 12, 16, 16};
const SDL_Rect TREE_PLATFORM_BARK_SRC = {154, 46, 16, 16};
const SDL_Rect WATER_TOP_SRC = {171, 29, 16, 16};
const SDL_Rect WATER_FILL_SRC = {171, 46, 16, 16};
const SDL_Rect MUSHROOM_PLATFORM_TOP_LEFT_SRC = {188, 12, 16, 16};
const SDL_Rect MUSHROOM_PLATFORM_TOP_MIDDLE_SRC = {205, 12, 16, 16};
const SDL_Rect MUSHROOM_PLATFORM_TOP_RIGHT_SRC = {222, 12, 16, 16};
const SDL_Rect MUSHROOM_PLATFORM_BARK_TOP_SRC = {205, 29, 16, 16};
const SDL_Rect MUSHROOM_PLATFORM_BARK_BOTTOM_SRC = {205, 46, 16, 16};
const SDL_Rect TREE_BARK_SRC = {222, 46, 16, 16};
const SDL_Rect TREE_LEAVES_SMALL_SRC = {222, 29, 16, 16};
const SDL_Rect TREE_LEAVES_TOP_SRC = {239, 12, 16, 16};
const SDL_Rect TREE_LEAVES_BOTTOM_SRC = {239, 29, 16, 16};
const SDL_Rect CANNON_TOWER_SRC = {256, 46, 16, 16};
const SDL_Rect CANNON_PEDESTAL_SRC = {256, 29, 16, 16};
const SDL_Rect CANNON_SRC = {256, 12, 16, 16};
const SDLPP::Vec2D<uint64_t> OVERWORLD_SHIFT = {0, 0};
const SDLPP::Vec2D<uint64_t> UNDERWORLD_SHIFT = {274, 0};

View File

@ -50,6 +50,38 @@ extern const SDL_Rect CASTLE_BLACK_SRC;
extern const SDL_Rect CASTLE_ENTRY_SRC;
extern const SDL_Rect CASTLE_TOWER_SRC;
extern const SDL_Rect CASTLE_TOWER_FILLED_SRC;
extern const SDL_Rect VINE_TOP_SRC;
extern const SDL_Rect VINE_BOTTOM_SRC;
extern const SDL_Rect POLE_TOP_SRC;
extern const SDL_Rect POLE_BOTTOM_SRC;
extern const SDL_Rect FLAG_SRC;
extern const SDL_Rect STEP_SRC;
extern const SDL_Rect BRICK_SRC;
extern const SDL_Rect BRICK_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_END_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_END_BOTTOM_SRC;
extern const SDL_Rect SIDEWAY_PIPE_MIDDLE_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_MIDDLE_BOTTOM_SRC;
extern const SDL_Rect SIDEWAY_PIPE_CONNECTOR_TOP_SRC;
extern const SDL_Rect SIDEWAY_PIPE_CONNECTOR_BOTTOM_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_LEFT_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_MIDDLE_SRC;
extern const SDL_Rect TREE_PLATFORM_TOP_RIGHT_SRC;
extern const SDL_Rect TREE_PLATFORM_BARK_SRC;
extern const SDL_Rect WATER_TOP_SRC;
extern const SDL_Rect WATER_FILL_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_LEFT_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_MIDDLE_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_TOP_RIGHT_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_BARK_TOP_SRC;
extern const SDL_Rect MUSHROOM_PLATFORM_BARK_BOTTOM_SRC;
extern const SDL_Rect TREE_BARK_SRC;
extern const SDL_Rect TREE_LEAVES_SMALL_SRC;
extern const SDL_Rect TREE_LEAVES_TOP_SRC;
extern const SDL_Rect TREE_LEAVES_BOTTOM_SRC;
extern const SDL_Rect CANNON_TOWER_SRC;
extern const SDL_Rect CANNON_PEDESTAL_SRC;
extern const SDL_Rect CANNON_SRC;
extern const SDLPP::Vec2D<uint64_t> OVERWORLD_SHIFT;
extern const SDLPP::Vec2D<uint64_t> UNDERWORLD_SHIFT;