#include "../sdlpp/sdlpp.hpp" #include "gui/gui.hpp" #include "sprites.hpp" #include #ifdef _WIN32 #include "../sdlpp/SDL2/SDL2_framerate.h" #include #include #include #else #include #endif // UNIX #include #include #include #include "global_vars.hpp" #include "objectids.hpp" #include "blocks.hpp" #include "maploader.hpp" #include "../sdlpp/sdlpp_mouse.hpp" #include "edit_box.hpp" #include "editor_visitor.hpp" #include "tool_box.hpp" #include "blocks/coineditorblock.hpp" #define MAP_WIDTH 24 #define MAP_HEIGHT 16 #define QUIT_FLAG 0x00000001 #define UPDATE_FLAG 0x00000002 #define MAP_LEFT_ENABLED_FLAG 0x00000004 #define MAP_RIGHT_ENABLED_FLAG 0x00000008 #define TOOL_LEFT_ENABLED_FLAG 0x00000010 #define TOOL_RIGHT_ENABLED_FLAG 0x00000020 #define MOD_LEFT_ENABLED_FLAG 0x00000040 #define MOD_RIGHT_ENABLED_FLAG 0x00000080 #define CHARACTER_LEFT_ENABLED_FLAG 0x00000100 #define CHARACTER_RIGHT_ENABLED_FLAG 0x00000200 #define TOOLS_WIDTH 4 #define CHARACTER_WIDTH 3 #define MOD_WIDTH 2 #define OVERWORLD_WIDTH 2 struct ToolType { enum Value { BLOCK, MOD, CHARACTER, WORLD, }; }; struct MouseInfo { uint64_t cur_flags{}; uint64_t prev_flags{}; SDLPP::Vec2D edit_box; SDLPP::Vec2D tool_box; ToolType::Value tool_type{}; uint64_t cur_button_index{}; }; struct MapInfo { int cur_page; int max_page; }; struct ToolInfo { ToolType::Value type; uint64_t index; SDL_Rect texture_src; int cur_page_tools; int max_page_tools; int cur_page_mods; int max_page_mods; int cur_page_characters; int max_page_characters; }; struct GlobalVars { MouseInfo mouse{}; MapInfo map{}; ToolInfo tool{}; uint64_t flags{}; std::vector objects; std::vector> tools; std::vector> mods; std::vector> characters; std::vector> tool_boxes; std::vector> mod_boxes; std::vector> character_boxes; std::vector> buttons; enum LandType::Value current_world_type{}; std::shared_ptr coin_tool; std::shared_ptr generic_tool; std::shared_ptr current_tool; std::shared_ptr translucent_terrain_texture; std::shared_ptr translucent_mario_texture; std::shared_ptr translucent_mod_texture; std::shared_ptr translucent_enemies_texture; std::shared_ptr mario; SDLPP::Vec2D mario_pos; }; GlobalVars global_vars; std::mutex destruction_mutex; std::mutex render_mutex; void updateTool() { auto tool_index = global_vars.tool.index; uint64_t tool_id = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: tool_id = possibleBlocks[tool_index]; break; case ToolType::MOD: tool_id = possibleMods[tool_index]; break; case ToolType::CHARACTER: tool_id = possibleCharacters[tool_index]; default: break; } auto tool_role = getBlockRole(tool_id); std::shared_ptr target_texture = nullptr; SDL_Rect target_src; switch (tool_role) { case BlockRole::TERRAIN: target_texture = global_vars.translucent_terrain_texture; target_src = global_vars.tools[global_vars.tool.index]->getTextureSourceRect(); break; case BlockRole::MARIO: target_texture = global_vars.translucent_mario_texture; target_src = global_vars.characters[global_vars.tool.index] ->getTextureSourceRect(); break; case BlockRole::MODIFIER: target_texture = global_vars.translucent_mod_texture; target_src = global_vars.mods[global_vars.tool.index]->getTextureSourceRect(); break; case BlockRole::CHARACTER: target_texture = global_vars.translucent_enemies_texture; target_src = global_vars.characters[global_vars.tool.index] ->getTextureSourceRect(); break; } global_vars.current_tool->setHidden(true); if (tool_id == COIN_MODIFIER_ID) { global_vars.coin_tool->setPos(global_vars.current_tool->getPos()); global_vars.current_tool = global_vars.coin_tool; } else { global_vars.generic_tool->setPos(global_vars.current_tool->getPos()); global_vars.current_tool = global_vars.generic_tool; global_vars.current_tool->setTexture(target_texture, target_src); global_vars.current_tool->setId(tool_id); global_vars.current_tool->getCollisions()[0]->setId(tool_id); } global_vars.current_tool->setHidden(false); } void removeMario() { if (!global_vars.mario) { return; } global_vars .objects[global_vars.mario_pos.getX()][global_vars.mario_pos.getY()] .unsetCharacter(); global_vars.mario->destroy(); } void setToolColor(const std::string &color) { std::vector> *store = nullptr; int multiplier = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: multiplier = TOOLS_WIDTH; store = &global_vars.tool_boxes; break; case ToolType::MOD: multiplier = MOD_WIDTH; store = &global_vars.mod_boxes; break; case ToolType::CHARACTER: multiplier = CHARACTER_WIDTH; store = &global_vars.character_boxes; default: break; } if (store == nullptr) { return; } auto index = global_vars.tool.index % (2 * multiplier); store->at(index)->setColor(color); } void setToolColor() { setToolColor("#FFFF8888"); } void unsetToolColor() { setToolColor("#FFFFFF00"); } void updateToolSelection(int prev_index, ToolType::Value type) { unsetToolColor(); size_t cur_page = 0; size_t multiplier = 0; std::vector> *tool_vec = nullptr; switch (type) { case ToolType::BLOCK: cur_page = global_vars.tool.cur_page_tools; multiplier = 2 * TOOLS_WIDTH; tool_vec = &global_vars.tools; break; case ToolType::MOD: cur_page = global_vars.tool.cur_page_mods; multiplier = 2 * MOD_WIDTH; tool_vec = &global_vars.mods; break; case ToolType::CHARACTER: cur_page = global_vars.tool.cur_page_characters; multiplier = 2 * CHARACTER_WIDTH; tool_vec = &global_vars.characters; default: break; } if (tool_vec == nullptr) { return; } auto cur = cur_page * multiplier; size_t prev = prev_index * multiplier; for (size_t i = prev; i < (tool_vec->size() < prev + multiplier ? tool_vec->size() : prev + multiplier); i++) { tool_vec->at(i)->setHidden(true); } for (size_t i = cur; i < (tool_vec->size() < cur + multiplier ? tool_vec->size() : cur + multiplier); i++) { tool_vec->at(i)->setHidden(false); } if (global_vars.tool.index / multiplier == cur_page) { setToolColor(); } } void moveToolsLeft(ToolType::Value type) { switch (type) { case ToolType::BLOCK: global_vars.tool.cur_page_tools--; updateToolSelection(global_vars.tool.cur_page_tools + 1, type); break; case ToolType::MOD: global_vars.tool.cur_page_mods--; updateToolSelection(global_vars.tool.cur_page_mods + 1, type); break; case ToolType::CHARACTER: global_vars.tool.cur_page_characters--; updateToolSelection(global_vars.tool.cur_page_characters + 1, type); default: break; } } void moveToolsRight(ToolType::Value type) { switch (type) { case ToolType::BLOCK: global_vars.tool.cur_page_tools++; updateToolSelection(global_vars.tool.cur_page_tools - 1, type); break; case ToolType::MOD: global_vars.tool.cur_page_mods++; updateToolSelection(global_vars.tool.cur_page_mods - 1, type); break; case ToolType::CHARACTER: global_vars.tool.cur_page_characters++; updateToolSelection(global_vars.tool.cur_page_characters - 1, type); default: break; } } void updateToolIndex(uint64_t new_index, ToolType::Value new_type) { int multiplier = 0; int *page = nullptr; switch (new_type) { case ToolType::BLOCK: multiplier = 2 * TOOLS_WIDTH; page = &global_vars.tool.cur_page_tools; break; case ToolType::MOD: multiplier = 2 * MOD_WIDTH; page = &global_vars.tool.cur_page_mods; break; case ToolType::CHARACTER: multiplier = 2 * CHARACTER_WIDTH; page = &global_vars.tool.cur_page_characters; default: break; } unsetToolColor(); global_vars.tool.type = new_type; global_vars.tool.index = new_index; setToolColor(); updateTool(); if (new_index / multiplier != static_cast(*page)) { auto prev = *page; *page = new_index / multiplier; updateToolSelection(prev, global_vars.tool.type); } } void updateToolIndex(uint64_t new_index) { updateToolIndex(new_index, global_vars.tool.type); } void selectLowerTool() { int multiplier = 0; size_t max_index = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: multiplier = 2 * TOOLS_WIDTH; max_index = global_vars.tools.size() - 1; break; case ToolType::MOD: multiplier = 2 * MOD_WIDTH; max_index = global_vars.mods.size() - 1; break; case ToolType::CHARACTER: multiplier = 2 * CHARACTER_WIDTH; max_index = global_vars.characters.size() - 1; default: break; } if (global_vars.tool.index % multiplier >= static_cast(multiplier / 2) || global_vars.tool.index + multiplier / 2 > max_index) { return; } updateToolIndex(global_vars.tool.index + multiplier / 2); } void selectUpperTool() { int multiplier = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: multiplier = 2 * TOOLS_WIDTH; break; case ToolType::MOD: multiplier = 2 * MOD_WIDTH; break; case ToolType::CHARACTER: multiplier = 2 * CHARACTER_WIDTH; default: break; } if (global_vars.tool.index % multiplier < static_cast(multiplier / 2)) { return; } updateToolIndex(global_vars.tool.index - multiplier / 2); } void selectPrevTool() { int multiplier = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: multiplier = TOOLS_WIDTH; break; case ToolType::MOD: multiplier = MOD_WIDTH; break; case ToolType::CHARACTER: multiplier = CHARACTER_WIDTH; default: break; } int subtraction = 1; if (global_vars.tool.index % multiplier == 0) { subtraction = multiplier + 1; } if (global_vars.tool.index == 0 || global_vars.tool.index - subtraction > static_cast(-multiplier)) { return; } updateToolIndex(global_vars.tool.index - subtraction); } void selectNextTool() { size_t max_index = 0; int multiplier = 0; switch (global_vars.tool.type) { case ToolType::BLOCK: max_index = global_vars.tools.size() - 1; multiplier = TOOLS_WIDTH; break; case ToolType::MOD: max_index = global_vars.mods.size() - 1; multiplier = MOD_WIDTH; break; case ToolType::CHARACTER: max_index = global_vars.characters.size() - 1; multiplier = CHARACTER_WIDTH; default: break; } int addition = 1; if (global_vars.tool.index % multiplier == static_cast(multiplier - 1)) { addition = multiplier + 1; } if (global_vars.tool.index == max_index) { return; } if (global_vars.tool.index + addition > max_index) { addition = 1; } updateToolIndex(global_vars.tool.index + addition); } void setFlag(uint64_t flag) { global_vars.flags |= flag; } void unsetFlag(uint64_t flag) { global_vars.flags &= ~flag; } bool getFlag(uint64_t flag) { return global_vars.flags & flag; } void updateWorld() { for (auto &block : global_vars.tools) { block->setType(global_vars.current_world_type); } for (auto &block : global_vars.characters) { block->setType(global_vars.current_world_type); } if (getBlockRole(global_vars.current_tool->getId()) != BlockRole::MODIFIER) { global_vars.current_tool->setType(global_vars.current_world_type); } } // TODO add mouse wheel control for modifiers void handleKeyUp(SDL_Keycode key, SDLPP::Scene &scene) { switch (key) { case SDLK_ESCAPE: setFlag(QUIT_FLAG); break; case SDLK_a: selectPrevTool(); break; case SDLK_d: selectNextTool(); break; case SDLK_w: selectUpperTool(); break; case SDLK_s: selectLowerTool(); break; case SDLK_1: global_vars.current_world_type = possibleLands[0]; updateWorld(); break; case SDLK_2: global_vars.current_world_type = possibleLands[1]; updateWorld(); break; case SDLK_3: global_vars.current_world_type = possibleLands[2]; updateWorld(); break; case SDLK_4: global_vars.current_world_type = possibleLands[3]; updateWorld(); break; case SDLK_r: scene.getRenderer().setRenderColiders( !scene.getRenderer().getRenderColiders()); default: break; } } void getMousePositionFlags(SDLPP::Scene &scene) { auto mouse = scene.getObjects({ EDITOR_MOUSE_ID })[0]; // move mouse colider to mouse position mouse->setPos(SDLPP::Mouse::getMousePositionDouble( scene.getRenderer(), SDLPP::OBJ_CENTER, SDLPP::OBJ_CENTER)); MouseVisitor visitor; scene.visitCollisions(*mouse, visitor); if(visitor.getCurButton() != global_vars.mouse.cur_button_index) { if(global_vars.mouse.cur_button_index != (uint64_t)-1) { global_vars.buttons[global_vars.mouse.cur_button_index]->unsetHighlight(render_mutex); } if(visitor.getCurButton() != (uint64_t)-1) { global_vars.buttons[visitor.getCurButton()]->setHighlight(render_mutex); } } global_vars.mouse.cur_button_index = visitor.getCurButton(); global_vars.mouse.cur_flags = visitor.getFlags(); // + 1 because the left map arrow is on position 0 global_vars.mouse.edit_box = visitor.getEditBoxIndexes() + SDLPP::Vec2D(1, 0); global_vars.mouse.tool_box = visitor.getToolBoxIndexes(); global_vars.mouse.tool_type = static_cast(visitor.getToolType()); // if we found an edit box, move tool icon to that box if (visitor.foundEditBox()) { const auto &box = global_vars.mouse.edit_box; global_vars.current_tool->setPos(box.getX() * BLOCK_SIZE, 1 - MAP_HEIGHT * BLOCK_SIZE + box.getY() * BLOCK_SIZE); } } struct moveStruct { std::shared_ptr scene; std::shared_ptr