housekeeping and todos

This commit is contained in:
scawful
2024-01-26 23:18:26 -05:00
parent 28f6056b2f
commit df1cdb22f5
6 changed files with 158 additions and 24 deletions

View File

@@ -55,6 +55,44 @@ absl::Status OverworldEditor::Update() {
map_blockset_loaded_ = false;
}
// TODO: Setup pan tool with middle mouse button
// if (ImGui::IsMouseDragging(ImGuiMouseButton_Middle)) {
// previous_mode = current_mode;
// current_mode = EditingMode::PAN;
// ow_map_canvas_.set_draggable(true);
// middle_mouse_dragging_ = true;
// }
// if (ImGui::IsMouseReleased(ImGuiMouseButton_Middle) &&
// current_mode == EditingMode::PAN && middle_mouse_dragging_) {
// current_mode = previous_mode;
// ow_map_canvas_.set_draggable(false);
// middle_mouse_dragging_ = false;
// }
if (overworld_canvas_fullscreen_) {
static bool use_work_area = true;
static ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration |
ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoSavedSettings;
// We demonstrate using the full viewport area or the work area (without
// menu-bars, task-bars etc.) Based on your use case you may want one or the
// other.
const ImGuiViewport *viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(use_work_area ? viewport->WorkPos : viewport->Pos);
ImGui::SetNextWindowSize(use_work_area ? viewport->WorkSize
: viewport->Size);
if (ImGui::Begin("Example: Fullscreen window",
&overworld_canvas_fullscreen_, flags)) {
// Draws the toolset for editing the Overworld.
RETURN_IF_ERROR(DrawToolset())
DrawOverworldCanvas();
}
ImGui::End();
return absl::OkStatus();
}
TAB_BAR("##OWEditorTabBar")
TAB_ITEM("Map Editor")
status_ = UpdateOverworldEdit();
@@ -187,7 +225,7 @@ absl::Status OverworldEditor::DrawToolset() {
static bool show_gfx_group = false;
static bool show_properties = false;
if (BeginTable("OWToolset", 20, kToolsetTableFlags, ImVec2(0, 0))) {
if (BeginTable("OWToolset", 22, kToolsetTableFlags, ImVec2(0, 0))) {
for (const auto &name : kToolsetColumnNames)
ImGui::TableSetupColumn(name.data());
@@ -213,8 +251,22 @@ absl::Status OverworldEditor::DrawToolset() {
ow_map_canvas_.ZoomIn();
}
NEXT_COLUMN()
if (ImGui::Button(ICON_MD_OPEN_IN_FULL)) {
overworld_canvas_fullscreen_ = !overworld_canvas_fullscreen_;
}
HOVER_HINT("Fullscreen Canvas")
TEXT_COLUMN(ICON_MD_MORE_VERT) // Separator
NEXT_COLUMN()
if (ImGui::Selectable(ICON_MD_PAN_TOOL_ALT,
current_mode == EditingMode::PAN)) {
current_mode = EditingMode::PAN;
ow_map_canvas_.set_draggable(true);
}
HOVER_HINT("Pan (Right click and drag)")
NEXT_COLUMN()
if (ImGui::Selectable(ICON_MD_DRAW,
current_mode == EditingMode::DRAW_TILE)) {
@@ -946,7 +998,11 @@ void OverworldEditor::DrawOverworldCanvas() {
gui::BeginChildBothScrollbars(7);
ow_map_canvas_.DrawBackground();
gui::EndNoPadding();
ow_map_canvas_.DrawContextMenu();
if (current_mode == EditingMode::PAN) {
ow_map_canvas_.DrawContextMenu();
} else {
ow_map_canvas_.set_draggable(false);
}
if (overworld_.is_loaded()) {
DrawOverworldMaps();
DrawOverworldEntrances(ow_map_canvas_.zero_point(),
@@ -1134,6 +1190,8 @@ absl::Status OverworldEditor::LoadSpriteGraphics() {
absl::Status OverworldEditor::DrawExperimentalModal() {
ImGui::Begin("Experimental", &show_experimental);
DrawDebugWindow();
gui::TextWithSeparators("PROTOTYPE OVERWORLD TILEMAP LOADER");
Text("Please provide two files:");
Text("One based on MAPn.DAT, which represents the overworld tilemap");
@@ -1178,6 +1236,36 @@ absl::Status OverworldEditor::DrawExperimentalModal() {
return absl::OkStatus();
}
void OverworldEditor::DrawDebugWindow() {
ImGui::Text("Current Map: %d", current_map_);
ImGui::Text("Current Tile16: %d", current_tile16_);
int relative_x = (int)ow_map_canvas_.drawn_tile_position().x % 512;
int relative_y = (int)ow_map_canvas_.drawn_tile_position().y % 512;
ImGui::Text("Current Tile16 Drawn Position (Relative): %d, %d", relative_x,
relative_y);
// Print the size of the overworld map_tiles per world
ImGui::Text("Light World Map Tiles: %d",
overworld_.mutable_map_tiles()->light_world.size());
ImGui::Text("Dark World Map Tiles: %d",
overworld_.mutable_map_tiles()->dark_world.size());
ImGui::Text("Special World Map Tiles: %d",
overworld_.mutable_map_tiles()->special_world.size());
static bool view_lw_map_tiles = false;
static MemoryEditor mem_edit;
// Let's create buttons which let me view containers in the memory editor
if (ImGui::Button("View Light World Map Tiles")) {
view_lw_map_tiles = !view_lw_map_tiles;
}
if (view_lw_map_tiles) {
mem_edit.DrawContents(
overworld_.mutable_map_tiles()->light_world[current_map_].data(),
overworld_.mutable_map_tiles()->light_world[current_map_].size());
}
}
} // namespace editor
} // namespace app
} // namespace yaze

View File

@@ -36,10 +36,10 @@ static constexpr uint kTile8DisplayHeight = 64;
static constexpr float kInputFieldSize = 30.f;
static constexpr absl::string_view kToolsetColumnNames[] = {
"#undoTool", "#redoTool", "#drawTool", "#separator2",
"#zoomOutTool", "#zoomInTool", "#separator", "#history",
"#entranceTool", "#exitTool", "#itemTool", "#spriteTool",
"#transportTool", "#musicTool", "#separator3", "#tilemapTool",
"#undoTool", "#redoTool", "#separator2", "#zoomOutTool",
"#zoomInTool", "#separator", "#drawTool", "#history",
"#entranceTool", "#exitTool", "#itemTool", "#spriteTool",
"#transportTool", "#musicTool", "#separator3", "#tilemapTool",
"propertiesTool"};
constexpr ImGuiTableFlags kOWMapFlags = ImGuiTableFlags_Borders;
@@ -126,6 +126,8 @@ class OverworldEditor : public Editor,
absl::Status LoadSpriteGraphics();
absl::Status DrawExperimentalModal();
void DrawDebugWindow();
auto gfx_group_editor() const { return gfx_group_editor_; }
enum class EditingMode {
@@ -135,10 +137,12 @@ class OverworldEditor : public Editor,
ITEMS,
SPRITES,
TRANSPORTS,
MUSIC
MUSIC,
PAN
};
EditingMode current_mode = EditingMode::DRAW_TILE;
EditingMode previous_mode = EditingMode::DRAW_TILE;
int current_world_ = 0;
int current_map_ = 0;
@@ -171,6 +175,8 @@ class OverworldEditor : public Editor,
bool is_dragging_entrance_ = false;
bool show_tile16_editor_ = false;
bool show_gfx_group_editor_ = false;
bool overworld_canvas_fullscreen_ = false;
bool middle_mouse_dragging_ = false;
bool IsMouseHoveringOverEntrance(const zelda3::OverworldEntrance &entrance,
ImVec2 canvas_p, ImVec2 scrolling);

View File

@@ -78,7 +78,7 @@ void Canvas::DrawBackground(ImVec2 canvas_size, bool can_drag) {
ImVec2(canvas_sz_.x * global_scale_, canvas_sz_.y * global_scale_);
ImGui::InvisibleButton("canvas", scaled_sz, kMouseFlags);
if (can_drag) {
if (draggable_ && ImGui::IsItemHovered()) {
const bool is_active = ImGui::IsItemActive(); // Held
const ImVec2 origin(canvas_p0_.x + scrolling_.x,
canvas_p0_.y + scrolling_.y); // Lock scrolled origin
@@ -87,8 +87,9 @@ void Canvas::DrawBackground(ImVec2 canvas_size, bool can_drag) {
// Pan (we use a zero mouse threshold when there's no context menu)
if (const float mouse_threshold_for_pan =
enable_context_menu_ ? -1.0f : 0.0f;
is_active && ImGui::IsMouseDragging(ImGuiMouseButton_Right,
mouse_threshold_for_pan)) {
is_active &&
ImGui::IsMouseDragging(ImGuiMouseButton_Right,
mouse_threshold_for_pan)) {
scrolling_.x += io.MouseDelta.x;
scrolling_.y += io.MouseDelta.y;
}
@@ -110,12 +111,12 @@ void Canvas::DrawContextMenu() {
// Contents of the Context Menu
if (ImGui::BeginPopup("context")) {
ImGui::MenuItem("Show Grid", nullptr, &enable_grid_);
ImGui::Selectable("Show Labels", &enable_hex_tile_labels_);
if (ImGui::MenuItem("Reset Position", nullptr, false)) {
scrolling_.x = 0;
scrolling_.y = 0;
}
ImGui::MenuItem("Show Grid", nullptr, &enable_grid_);
ImGui::Selectable("Show Labels", &enable_hex_tile_labels_);
if (ImGui::BeginMenu("Canvas Properties")) {
ImGui::Text("Canvas Size: %.0f x %.0f", canvas_sz_.x, canvas_sz_.y);
ImGui::Text("Global Scale: %.1f", global_scale_);
@@ -193,9 +194,7 @@ bool Canvas::DrawTilePainter(const Bitmap &bitmap, int size, float scale) {
if (ImGui::IsMouseClicked(ImGuiMouseButton_Left)) {
// Draw the currently selected tile on the overworld here
// Save the coordinates of the selected tile.
drawn_tile_pos_ = io.MousePos;
SDL_Log("Drawn tile position: %.0f, %.0f", drawn_tile_pos_.x,
drawn_tile_pos_.y);
drawn_tile_pos_ = painter_pos;
return true;
}

View File

@@ -142,15 +142,17 @@ class Canvas {
int num_rows = height() / custom_step_;
int tile_id = (x / custom_step_) + (y / custom_step_) * num_columns;
if (tile_id >= num_columns * num_rows) {
tile_id = -1; // Invalid tile ID
tile_id = -1; // Invalid tile ID
}
return tile_id;
}
auto set_current_labels(int i) { current_labels_ = i; }
auto set_highlight_tile_id(int i) { highlight_tile_id = i; }
auto set_draggable(bool value) { draggable_ = value; }
private:
bool draggable_ = false;
bool enable_grid_ = true;
bool enable_hex_tile_labels_ = false;
bool enable_custom_labels_ = false;

View File

@@ -45,7 +45,9 @@ bool InputScalarLeft(const char* label, ImGuiDataType data_type, void* p_data,
value_changed = DataTypeApplyFromText(buf, data_type, p_data, format);
} else {
const float button_size = GetFrameHeight();
ImGui::AlignTextToFramePadding();
ImGui::Text("%s", label);
ImGui::SameLine();
BeginGroup(); // The only purpose of the group here is to allow the caller
// to query item data e.g. IsItemActive()
PushID(label);
@@ -57,9 +59,7 @@ bool InputScalarLeft(const char* label, ImGuiDataType data_type, void* p_data,
ImVec2{style.ItemSpacing.x, style.ItemSpacing.y});
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding,
ImVec2{style.FramePadding.x, style.FramePadding.y});
ImGui::AlignTextToFramePadding();
ImGui::Text("%s", label);
ImGui::SameLine();
ImGui::SetNextItemWidth(input_width);
if (InputText("", buf, IM_ARRAYSIZE(buf),
flags)) // PushId(label) + "" gives us the expected ID

View File

@@ -133,7 +133,8 @@ constexpr uint32_t gfx_groups_pointer = 0x6237;
struct WriteAction {
int address;
std::variant<int, uint8_t, uint16_t, std::vector<uint8_t>, gfx::SNESColor>
std::variant<int, uint8_t, uint16_t, std::vector<uint8_t>, gfx::SNESColor,
std::vector<gfx::SNESColor>>
value;
};
@@ -147,9 +148,22 @@ class ROM : public core::ExperimentFlags {
return status;
}
template <typename T, typename... Args>
absl::Status RunTransactionV2(int address, T& var, Args&&... args) {
absl::Status status = WriteHelperV2<T>(var, address);
if (!status.ok()) {
return status;
}
if constexpr (sizeof...(args) > 0) {
status = WriteHelperV2(std::forward<Args>(args)...);
}
return status;
}
absl::Status WriteHelper(const WriteAction& action) {
if (std::holds_alternative<uint8_t>(action.value) ||
std::holds_alternative<int>(action.value)) {
if (std::holds_alternative<uint8_t>(action.value)) {
return Write(action.address, std::get<uint8_t>(action.value));
} else if (std::holds_alternative<uint16_t>(action.value)) {
return WriteShort(action.address, std::get<uint16_t>(action.value));
@@ -158,8 +172,33 @@ class ROM : public core::ExperimentFlags {
std::get<std::vector<uint8_t>>(action.value));
} else if (std::holds_alternative<gfx::SNESColor>(action.value)) {
return WriteColor(action.address, std::get<gfx::SNESColor>(action.value));
} else if (std::holds_alternative<std::vector<gfx::SNESColor>>(
action.value)) {
return absl::UnimplementedError(
"WriteHelper: std::vector<gfx::SNESColor>");
}
return absl::InvalidArgumentError("Invalid write argument type");
auto error_message = absl::StrFormat("Invalid write argument type: %s",
typeid(action.value).name());
return absl::InvalidArgumentError(error_message);
}
template <typename T>
absl::Status WriteHelperV2(int address, T& var) {
if constexpr (std::is_same_v<T, uint8_t>) {
return Write(address, var);
} else if constexpr (std::is_same_v<T, uint16_t>) {
return WriteShort(address, var);
} else if constexpr (std::is_same_v<T, std::vector<uint8_t>>) {
return WriteVector(address, var);
} else if constexpr (std::is_same_v<T, gfx::SNESColor>) {
return WriteColor(address, var);
} else if constexpr (std::is_same_v<T, std::vector<gfx::SNESColor>>) {
return absl::UnimplementedError(
"WriteHelperV2: std::vector<gfx::SNESColor>");
}
auto error_message =
absl::StrFormat("Invalid write argument type: %s", typeid(T).name());
return absl::InvalidArgumentError(error_message);
}
template <typename T, typename... Args>