Refactor ROM handling and remove SharedRom singleton for improved architecture
- Eliminated the SharedRom class to enhance modularity and reduce global state management. - Updated various classes to directly manage ROM instances, improving clarity and encapsulation. - Added new functions for loading messages and colors from ROM, enhancing functionality. - Refactored Canvas and Editor classes to utilize direct ROM references, streamlining interactions. - Improved documentation and comments for better code understanding and maintainability.
This commit is contained in:
@@ -9,7 +9,6 @@ The goal of yaze is to build a cross platform editor for the Legend of Zelda: A
|
|||||||
- **yaze**: Desktop application for Windows/macOS/Linux
|
- **yaze**: Desktop application for Windows/macOS/Linux
|
||||||
- **z3ed**: Command Line Interface
|
- **z3ed**: Command Line Interface
|
||||||
- **yaze_c**: C Library
|
- **yaze_c**: C Library
|
||||||
- **yaze_py**: Python Module
|
|
||||||
- **yaze_test**: Unit test executable
|
- **yaze_test**: Unit test executable
|
||||||
- **yaze_ios**: iOS application
|
- **yaze_ios**: iOS application
|
||||||
|
|
||||||
@@ -23,7 +22,6 @@ The goal of yaze is to build a cross platform editor for the Legend of Zelda: A
|
|||||||
- **app**: Contains the GUI editor `yaze`
|
- **app**: Contains the GUI editor `yaze`
|
||||||
- **app/emu**: Contains a standalone Snes emulator application `yaze_emu`
|
- **app/emu**: Contains a standalone Snes emulator application `yaze_emu`
|
||||||
- **cli**: Contains the command line interface `z3ed`
|
- **cli**: Contains the command line interface `z3ed`
|
||||||
- **cli/python**: Contains the Python module `yaze_py`
|
|
||||||
- **ios**: Contains the iOS application `yaze_ios`
|
- **ios**: Contains the iOS application `yaze_ios`
|
||||||
- **lib**: Contains the dependencies as git submodules
|
- **lib**: Contains the dependencies as git submodules
|
||||||
- **test**: Contains testing interface `yaze_test`
|
- **test**: Contains testing interface `yaze_test`
|
||||||
@@ -37,11 +35,10 @@ See [build-instructions.md](docs/build-instructions.md) for more information.
|
|||||||
- **ImGui**: GUI library
|
- **ImGui**: GUI library
|
||||||
- **Abseil**: C++ library
|
- **Abseil**: C++ library
|
||||||
- **libpng**: Image library
|
- **libpng**: Image library
|
||||||
- **Boost**: Python library
|
|
||||||
|
|
||||||
## Flow of Control
|
## Flow of Control
|
||||||
|
|
||||||
- app/yaze.cc
|
- app/main.cc
|
||||||
- Initializes `absl::FailureSignalHandler` for stack tracing.
|
- Initializes `absl::FailureSignalHandler` for stack tracing.
|
||||||
- Runs the `core::Controller` loop.
|
- Runs the `core::Controller` loop.
|
||||||
- app/core/controller.cc
|
- app/core/controller.cc
|
||||||
@@ -75,8 +72,6 @@ See [build-instructions.md](docs/build-instructions.md) for more information.
|
|||||||
|
|
||||||
The Rom class provides methods to manipulate and access data from a ROM.
|
The Rom class provides methods to manipulate and access data from a ROM.
|
||||||
|
|
||||||
Currently implemented as a singleton with SharedRom which is not great but has helped with development velocity. Potential room for improvement is to refactor the editors to take the ROM as a parameter.
|
|
||||||
|
|
||||||
## Bitmap
|
## Bitmap
|
||||||
|
|
||||||
- app/gfx/bitmap.cc
|
- app/gfx/bitmap.cc
|
||||||
|
|||||||
49
incl/yaze.h
49
incl/yaze.h
@@ -35,8 +35,6 @@ struct yaze_project {
|
|||||||
const char* name;
|
const char* name;
|
||||||
const char* filepath;
|
const char* filepath;
|
||||||
const char* rom_filename;
|
const char* rom_filename;
|
||||||
const char* code_folder;
|
|
||||||
const char* labels_filename;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
yaze_project yaze_load_project(const char* filename);
|
yaze_project yaze_load_project(const char* filename);
|
||||||
@@ -93,14 +91,61 @@ typedef struct snes_tile32 {
|
|||||||
uint16_t t3;
|
uint16_t t3;
|
||||||
} snes_tile32;
|
} snes_tile32;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get a color from a palette set.
|
||||||
|
*
|
||||||
|
* @details This function gets a color from a palette set and returns it as a
|
||||||
|
* snes_color object.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to get the color from.
|
||||||
|
* @param palette_set The palette set to get the color from.
|
||||||
|
* @param palette The palette to get the color from.
|
||||||
|
* @param color The color to get from the palette.
|
||||||
|
* @return The color from the palette set.
|
||||||
|
*/
|
||||||
snes_color yaze_get_color_from_paletteset(const zelda3_rom* rom,
|
snes_color yaze_get_color_from_paletteset(const zelda3_rom* rom,
|
||||||
int palette_set, int palette,
|
int palette_set, int palette,
|
||||||
int color);
|
int color);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load the overworld from the ROM.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load the overworld from.
|
||||||
|
* @return The status of the operation. If the operation is successful, the
|
||||||
|
* overworld object will be populated with the overworld from the ROM.
|
||||||
|
*/
|
||||||
zelda3_overworld* yaze_load_overworld(const zelda3_rom* rom);
|
zelda3_overworld* yaze_load_overworld(const zelda3_rom* rom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load all rooms from the ROM.
|
||||||
|
*
|
||||||
|
* @details This function loads all rooms from the ROM and returns them as an
|
||||||
|
* array of rooms.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load rooms from.
|
||||||
|
* @return The status of the operation. If the operation is successful, the
|
||||||
|
* rooms array will be populated with the rooms from the ROM.
|
||||||
|
*/
|
||||||
zelda3_dungeon_room* yaze_load_all_rooms(const zelda3_rom* rom);
|
zelda3_dungeon_room* yaze_load_all_rooms(const zelda3_rom* rom);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Load all messages from the ROM.
|
||||||
|
*
|
||||||
|
* @details This function loads all messages from the ROM and returns them as an
|
||||||
|
* array of messages.
|
||||||
|
*
|
||||||
|
* @param rom The ROM to load messages from.
|
||||||
|
* @param messages Pointer to an array of messages.
|
||||||
|
* @return The status of the operation. If the operation is successful, the
|
||||||
|
* messages array will be populated with the messages from the ROM.
|
||||||
|
*/
|
||||||
|
yaze_status yaze_load_messages(zelda3_rom* rom, zelda3_message** messages);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Function pointer to initialize the extension.
|
||||||
|
*
|
||||||
|
* @param context The editor context.
|
||||||
|
*/
|
||||||
typedef void (*yaze_initialize_func)(yaze_editor_context* context);
|
typedef void (*yaze_initialize_func)(yaze_editor_context* context);
|
||||||
typedef void (*yaze_cleanup_func)(void);
|
typedef void (*yaze_cleanup_func)(void);
|
||||||
|
|
||||||
|
|||||||
15
incl/zelda.h
15
incl/zelda.h
@@ -86,7 +86,7 @@ const static zelda3_version_pointers zelda3_jp_pointers = {
|
|||||||
|
|
||||||
typedef struct zelda3_rom {
|
typedef struct zelda3_rom {
|
||||||
const char* filename;
|
const char* filename;
|
||||||
const uint8_t* data;
|
uint8_t* data;
|
||||||
size_t size;
|
size_t size;
|
||||||
void* impl; // yaze::Rom*
|
void* impl; // yaze::Rom*
|
||||||
} zelda3_rom;
|
} zelda3_rom;
|
||||||
@@ -95,6 +95,19 @@ zelda3_rom* yaze_load_rom(const char* filename);
|
|||||||
void yaze_unload_rom(zelda3_rom* rom);
|
void yaze_unload_rom(zelda3_rom* rom);
|
||||||
void yaze_save_rom(zelda3_rom* rom, const char* filename);
|
void yaze_save_rom(zelda3_rom* rom, const char* filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Primitive of a message.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct zelda3_message {
|
||||||
|
uint8_t id;
|
||||||
|
uint8_t address;
|
||||||
|
uint8_t *raw_string;
|
||||||
|
uint8_t *contents_parsed;
|
||||||
|
uint8_t *data;
|
||||||
|
uint8_t *data_parsed;
|
||||||
|
} zelda3_message;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Primitive of an overworld map.
|
* @brief Primitive of an overworld map.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -206,15 +206,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (void)openFileAction:(id)sender {
|
- (void)openFileAction:(id)sender {
|
||||||
if (!yaze::SharedRom::shared_rom_
|
// TODO: Re-implmenent this without the SharedRom singleton
|
||||||
->LoadFromFile(yaze::core::FileDialogWrapper::ShowOpenFileDialog())
|
// if (!yaze::SharedRom::shared_rom_
|
||||||
.ok()) {
|
// ->LoadFromFile(yaze::core::FileDialogWrapper::ShowOpenFileDialog())
|
||||||
NSAlert *alert = [[NSAlert alloc] init];
|
// .ok()) {
|
||||||
[alert setMessageText:@"Error"];
|
// NSAlert *alert = [[NSAlert alloc] init];
|
||||||
[alert setInformativeText:@"Failed to load file."];
|
// [alert setMessageText:@"Error"];
|
||||||
[alert addButtonWithTitle:@"OK"];
|
// [alert setInformativeText:@"Failed to load file."];
|
||||||
[alert runModal];
|
// [alert addButtonWithTitle:@"OK"];
|
||||||
}
|
// [alert runModal];
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)cutAction:(id)sender {
|
- (void)cutAction:(id)sender {
|
||||||
@@ -238,12 +239,12 @@ extern "C" void yaze_initialize_cococa() {
|
|||||||
|
|
||||||
extern "C" int yaze_run_cocoa_app_delegate(const char *filename) {
|
extern "C" int yaze_run_cocoa_app_delegate(const char *filename) {
|
||||||
yaze_initialize_cococa();
|
yaze_initialize_cococa();
|
||||||
yaze::core::Controller controller;
|
auto controller = std::make_unique<yaze::core::Controller>();
|
||||||
EXIT_IF_ERROR(controller.OnEntry(filename));
|
EXIT_IF_ERROR(controller->OnEntry(filename));
|
||||||
while (controller.IsActive()) {
|
while (controller->IsActive()) {
|
||||||
@autoreleasepool {
|
@autoreleasepool {
|
||||||
controller.OnInput();
|
controller->OnInput();
|
||||||
if (auto status = controller.OnLoad(); !status.ok()) {
|
if (auto status = controller->OnLoad(); !status.ok()) {
|
||||||
NSAlert *alert = [[NSAlert alloc] init];
|
NSAlert *alert = [[NSAlert alloc] init];
|
||||||
[alert setMessageText:@"Error"];
|
[alert setMessageText:@"Error"];
|
||||||
[alert setInformativeText:[NSString stringWithUTF8String:status.message().data()]];
|
[alert setInformativeText:[NSString stringWithUTF8String:status.message().data()]];
|
||||||
@@ -251,10 +252,10 @@ extern "C" int yaze_run_cocoa_app_delegate(const char *filename) {
|
|||||||
[alert runModal];
|
[alert runModal];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
controller.DoRender();
|
controller->DoRender();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
controller.OnExit();
|
controller->OnExit();
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace editor {
|
|||||||
* @class GfxGroupEditor
|
* @class GfxGroupEditor
|
||||||
* @brief Manage graphics group configurations in a Rom.
|
* @brief Manage graphics group configurations in a Rom.
|
||||||
*/
|
*/
|
||||||
class GfxGroupEditor : public SharedRom {
|
class GfxGroupEditor {
|
||||||
public:
|
public:
|
||||||
absl::Status Update();
|
absl::Status Update();
|
||||||
|
|
||||||
@@ -27,6 +27,8 @@ class GfxGroupEditor : public SharedRom {
|
|||||||
void SetSelectedSpriteset(uint8_t spriteset) {
|
void SetSelectedSpriteset(uint8_t spriteset) {
|
||||||
selected_spriteset_ = spriteset;
|
selected_spriteset_ = spriteset;
|
||||||
}
|
}
|
||||||
|
void set_rom(Rom* rom) { rom_ = rom; }
|
||||||
|
Rom* rom() const { return rom_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t selected_blockset_ = 0;
|
uint8_t selected_blockset_ = 0;
|
||||||
@@ -39,6 +41,7 @@ class GfxGroupEditor : public SharedRom {
|
|||||||
gui::Canvas spriteset_canvas_;
|
gui::Canvas spriteset_canvas_;
|
||||||
|
|
||||||
gfx::SnesPalette palette_;
|
gfx::SnesPalette palette_;
|
||||||
|
Rom* rom_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace editor
|
} // namespace editor
|
||||||
|
|||||||
@@ -586,7 +586,9 @@ absl::Status OverworldEditor::CheckForCurrentMap() {
|
|||||||
}
|
}
|
||||||
const int current_highlighted_map = current_map_;
|
const int current_highlighted_map = current_map_;
|
||||||
|
|
||||||
current_parent_ = overworld_.overworld_map(current_map_)->parent();
|
if (!current_map_lock_) {
|
||||||
|
current_parent_ = overworld_.overworld_map(current_map_)->parent();
|
||||||
|
}
|
||||||
|
|
||||||
if (overworld_.overworld_map(current_map_)->is_large_map() ||
|
if (overworld_.overworld_map(current_map_)->is_large_map() ||
|
||||||
overworld_.overworld_map(current_map_)->large_index() != 0) {
|
overworld_.overworld_map(current_map_)->large_index() != 0) {
|
||||||
@@ -613,6 +615,11 @@ absl::Status OverworldEditor::CheckForCurrentMap() {
|
|||||||
maps_bmp_[current_map_].set_modified(false);
|
maps_bmp_[current_map_].set_modified(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If double clicked, toggle the current map
|
||||||
|
if (ImGui::IsMouseDoubleClicked(ImGuiMouseButton_Right)) {
|
||||||
|
current_map_lock_ = !current_map_lock_;
|
||||||
|
}
|
||||||
|
|
||||||
return absl::OkStatus();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ constexpr ImVec2 kBlocksetCanvasSize(0x100 + 1, 0x4000 + 1);
|
|||||||
constexpr ImVec2 kGraphicsBinCanvasSize(0x100 + 1, kNumSheetsToLoad * 0x40 + 1);
|
constexpr ImVec2 kGraphicsBinCanvasSize(0x100 + 1, kNumSheetsToLoad * 0x40 + 1);
|
||||||
|
|
||||||
constexpr ImGuiTableFlags kOWMapFlags =
|
constexpr ImGuiTableFlags kOWMapFlags =
|
||||||
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable;
|
ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable |
|
||||||
|
ImGuiTableFlags_RowBg | ImGuiTableFlags_SizingStretchProp;
|
||||||
constexpr ImGuiTableFlags kToolsetTableFlags = ImGuiTableFlags_SizingFixedFit;
|
constexpr ImGuiTableFlags kToolsetTableFlags = ImGuiTableFlags_SizingFixedFit;
|
||||||
constexpr ImGuiTableFlags kOWEditFlags =
|
constexpr ImGuiTableFlags kOWEditFlags =
|
||||||
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
|
ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable |
|
||||||
@@ -75,6 +76,7 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
|||||||
public:
|
public:
|
||||||
explicit OverworldEditor(Rom* rom) : rom_(rom) {
|
explicit OverworldEditor(Rom* rom) : rom_(rom) {
|
||||||
type_ = EditorType::kOverworld;
|
type_ = EditorType::kOverworld;
|
||||||
|
gfx_group_editor_.set_rom(rom);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize() override;
|
void Initialize() override;
|
||||||
@@ -212,12 +214,13 @@ class OverworldEditor : public Editor, public gfx::GfxContext {
|
|||||||
bool overworld_canvas_fullscreen_ = false;
|
bool overworld_canvas_fullscreen_ = false;
|
||||||
bool middle_mouse_dragging_ = false;
|
bool middle_mouse_dragging_ = false;
|
||||||
bool is_dragging_entity_ = false;
|
bool is_dragging_entity_ = false;
|
||||||
|
bool current_map_lock_ = false;
|
||||||
|
|
||||||
gfx::Tilemap tile16_blockset_;
|
gfx::Tilemap tile16_blockset_;
|
||||||
|
|
||||||
Rom* rom_;
|
Rom* rom_;
|
||||||
|
|
||||||
Tile16Editor tile16_editor_{&tile16_blockset_};
|
Tile16Editor tile16_editor_{rom_, &tile16_blockset_};
|
||||||
GfxGroupEditor gfx_group_editor_;
|
GfxGroupEditor gfx_group_editor_;
|
||||||
PaletteEditor palette_editor_;
|
PaletteEditor palette_editor_;
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ absl::Status Tile16Editor::DrawToCurrentTile16(ImVec2 click_position) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
absl::Status Tile16Editor::UpdateTile16Edit() {
|
absl::Status Tile16Editor::UpdateTile16Edit() {
|
||||||
auto ow_main_pal_group = rom()->palette_group().overworld_main;
|
static const auto ow_main_pal_group = rom()->palette_group().overworld_main;
|
||||||
|
|
||||||
// Create a more organized layout with tabs
|
// Create a more organized layout with tabs
|
||||||
if (BeginTabBar("Tile16EditorTabs")) {
|
if (BeginTabBar("Tile16EditorTabs")) {
|
||||||
|
|||||||
@@ -22,9 +22,10 @@ namespace editor {
|
|||||||
/**
|
/**
|
||||||
* @brief Popup window to edit Tile16 data
|
* @brief Popup window to edit Tile16 data
|
||||||
*/
|
*/
|
||||||
class Tile16Editor : public gfx::GfxContext, public SharedRom {
|
class Tile16Editor : public gfx::GfxContext {
|
||||||
public:
|
public:
|
||||||
Tile16Editor(gfx::Tilemap *tile16_blockset) : tile16_blockset_(tile16_blockset) {}
|
Tile16Editor(Rom *rom, gfx::Tilemap *tile16_blockset)
|
||||||
|
: rom_(rom), tile16_blockset_(tile16_blockset) {}
|
||||||
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp,
|
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp,
|
||||||
const gfx::Bitmap ¤t_gfx_bmp,
|
const gfx::Bitmap ¤t_gfx_bmp,
|
||||||
std::array<uint8_t, 0x200> &all_tiles_types);
|
std::array<uint8_t, 0x200> &all_tiles_types);
|
||||||
@@ -52,7 +53,11 @@ class Tile16Editor : public gfx::GfxContext, public SharedRom {
|
|||||||
absl::Status LoadTile16FromScratchSpace(int slot);
|
absl::Status LoadTile16FromScratchSpace(int slot);
|
||||||
absl::Status ClearScratchSpace(int slot);
|
absl::Status ClearScratchSpace(int slot);
|
||||||
|
|
||||||
|
void set_rom(Rom *rom) { rom_ = rom; }
|
||||||
|
Rom *rom() const { return rom_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Rom *rom_ = nullptr;
|
||||||
bool map_blockset_loaded_ = false;
|
bool map_blockset_loaded_ = false;
|
||||||
bool transfer_started_ = false;
|
bool transfer_started_ = false;
|
||||||
bool transfer_blockset_loaded_ = false;
|
bool transfer_blockset_loaded_ = false;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "app/core/platform/file_dialog.h"
|
#include "app/core/platform/file_dialog.h"
|
||||||
#include "app/core/platform/renderer.h"
|
#include "app/core/window.h"
|
||||||
#include "app/emu/cpu/internal/opcodes.h"
|
#include "app/emu/cpu/internal/opcodes.h"
|
||||||
#include "app/gui/icons.h"
|
#include "app/gui/icons.h"
|
||||||
#include "app/gui/input.h"
|
#include "app/gui/input.h"
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ struct BackgroundLayer {
|
|||||||
bool enabled; // Whether the background layer is enabled
|
bool enabled; // Whether the background layer is enabled
|
||||||
};
|
};
|
||||||
|
|
||||||
class Ppu : public SharedRom {
|
class Ppu {
|
||||||
public:
|
public:
|
||||||
// Initializes the PPU with the necessary resources and dependencies
|
// Initializes the PPU with the necessary resources and dependencies
|
||||||
Ppu(Memory& memory) : memory_(memory) {}
|
Ppu(Memory& memory) : memory_(memory) {}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "app/core/platform/renderer.h"
|
#include "app/core/window.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
#include "app/gfx/snes_tile.h"
|
#include "app/gfx/snes_tile.h"
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,11 @@
|
|||||||
#include "app/core/window.h"
|
#include "app/core/window.h"
|
||||||
#include "app/gfx/bitmap.h"
|
#include "app/gfx/bitmap.h"
|
||||||
#include "app/gui/color.h"
|
#include "app/gui/color.h"
|
||||||
#include "app/gui/input.h"
|
|
||||||
#include "app/gui/style.h"
|
#include "app/gui/style.h"
|
||||||
#include "app/rom.h"
|
|
||||||
#include "imgui/imgui.h"
|
#include "imgui/imgui.h"
|
||||||
#include "imgui_memory_editor.h"
|
#include "imgui_memory_editor.h"
|
||||||
|
|
||||||
namespace yaze {
|
namespace yaze::gui {
|
||||||
namespace gui {
|
|
||||||
|
|
||||||
using core::Renderer;
|
using core::Renderer;
|
||||||
|
|
||||||
@@ -43,8 +40,8 @@ constexpr ImGuiButtonFlags kMouseFlags =
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
ImVec2 AlignPosToGrid(ImVec2 pos, float scale) {
|
ImVec2 AlignPosToGrid(ImVec2 pos, float scale) {
|
||||||
return ImVec2(std::floor((double)pos.x / scale) * scale,
|
return ImVec2(std::floor(pos.x / scale) * scale,
|
||||||
std::floor((double)pos.y / scale) * scale);
|
std::floor(pos.y / scale) * scale);
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -62,15 +59,14 @@ void Canvas::UpdateColorPainter(gfx::Bitmap &bitmap, const ImVec4 &color,
|
|||||||
DrawOverlay();
|
DrawOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::UpdateInfoGrid(ImVec2 bg_size, int tile_size, float scale,
|
void Canvas::UpdateInfoGrid(ImVec2 bg_size, float grid_size, int label_id) {
|
||||||
float grid_size, int label_id) {
|
|
||||||
enable_custom_labels_ = true;
|
enable_custom_labels_ = true;
|
||||||
DrawBackground(bg_size);
|
DrawBackground(bg_size);
|
||||||
DrawInfoGrid(grid_size, 8, label_id);
|
DrawInfoGrid(grid_size, 8, label_id);
|
||||||
DrawOverlay();
|
DrawOverlay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Canvas::DrawBackground(ImVec2 canvas_size, bool can_drag) {
|
void Canvas::DrawBackground(ImVec2 canvas_size) {
|
||||||
draw_list_ = GetWindowDrawList();
|
draw_list_ = GetWindowDrawList();
|
||||||
canvas_p0_ = GetCursorScreenPos();
|
canvas_p0_ = GetCursorScreenPos();
|
||||||
if (!custom_canvas_size_) canvas_sz_ = GetContentRegionAvail();
|
if (!custom_canvas_size_) canvas_sz_ = GetContentRegionAvail();
|
||||||
@@ -145,59 +141,59 @@ void Canvas::DrawContextMenu() {
|
|||||||
Text("Pitch: %d", bitmap_->surface()->pitch);
|
Text("Pitch: %d", bitmap_->surface()->pitch);
|
||||||
Text("BitsPerPixel: %d", bitmap_->surface()->format->BitsPerPixel);
|
Text("BitsPerPixel: %d", bitmap_->surface()->format->BitsPerPixel);
|
||||||
Text("BytesPerPixel: %d", bitmap_->surface()->format->BytesPerPixel);
|
Text("BytesPerPixel: %d", bitmap_->surface()->format->BytesPerPixel);
|
||||||
EndMenu();
|
MenuItem("Data", nullptr, &show_bitmap_data);
|
||||||
}
|
if (BeginMenu("Format")) {
|
||||||
if (BeginMenu("Bitmap Format")) {
|
if (MenuItem("Indexed")) {
|
||||||
if (MenuItem("Indexed")) {
|
bitmap_->Reformat(gfx::BitmapFormat::kIndexed);
|
||||||
bitmap_->Reformat(gfx::BitmapFormat::kIndexed);
|
Renderer::Get().UpdateBitmap(bitmap_);
|
||||||
Renderer::Get().UpdateBitmap(bitmap_);
|
|
||||||
}
|
|
||||||
if (MenuItem("4BPP")) {
|
|
||||||
bitmap_->Reformat(gfx::BitmapFormat::k4bpp);
|
|
||||||
Renderer::Get().UpdateBitmap(bitmap_);
|
|
||||||
}
|
|
||||||
if (MenuItem("8BPP")) {
|
|
||||||
bitmap_->Reformat(gfx::BitmapFormat::k8bpp);
|
|
||||||
Renderer::Get().UpdateBitmap(bitmap_);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndMenu();
|
|
||||||
}
|
|
||||||
if (BeginMenu("View Palette")) {
|
|
||||||
DisplayEditablePalette(*bitmap_->mutable_palette(), "Palette", true, 8);
|
|
||||||
EndMenu();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BeginMenu("Bitmap Palette")) {
|
|
||||||
if (rom()->is_loaded()) {
|
|
||||||
gui::TextWithSeparators("ROM Palette");
|
|
||||||
ImGui::SetNextItemWidth(100.f);
|
|
||||||
ImGui::Combo("Palette Group", (int *)&edit_palette_group_name_index_,
|
|
||||||
gfx::kPaletteGroupAddressesKeys,
|
|
||||||
IM_ARRAYSIZE(gfx::kPaletteGroupAddressesKeys));
|
|
||||||
ImGui::SetNextItemWidth(100.f);
|
|
||||||
gui::InputHexWord("Palette Group Index", &edit_palette_index_);
|
|
||||||
|
|
||||||
auto palette_group = rom()->mutable_palette_group()->get_group(
|
|
||||||
gfx::kPaletteGroupAddressesKeys[edit_palette_group_name_index_]);
|
|
||||||
auto palette = palette_group->mutable_palette(edit_palette_index_);
|
|
||||||
|
|
||||||
if (ImGui::BeginChild("Palette", ImVec2(0, 300), true)) {
|
|
||||||
gui::SelectablePalettePipeline(edit_palette_sub_index_,
|
|
||||||
refresh_graphics_, *palette);
|
|
||||||
|
|
||||||
if (refresh_graphics_) {
|
|
||||||
bitmap_->SetPaletteWithTransparent(*palette,
|
|
||||||
edit_palette_sub_index_);
|
|
||||||
Renderer::Get().UpdateBitmap(bitmap_);
|
|
||||||
refresh_graphics_ = false;
|
|
||||||
}
|
|
||||||
ImGui::EndChild();
|
|
||||||
}
|
}
|
||||||
|
if (MenuItem("4BPP")) {
|
||||||
|
bitmap_->Reformat(gfx::BitmapFormat::k4bpp);
|
||||||
|
Renderer::Get().UpdateBitmap(bitmap_);
|
||||||
|
}
|
||||||
|
if (MenuItem("8BPP")) {
|
||||||
|
bitmap_->Reformat(gfx::BitmapFormat::k8bpp);
|
||||||
|
Renderer::Get().UpdateBitmap(bitmap_);
|
||||||
|
}
|
||||||
|
|
||||||
|
EndMenu();
|
||||||
|
}
|
||||||
|
if (BeginMenu("Change Palette")) {
|
||||||
|
Text("Work in progress");
|
||||||
|
// TODO: Get ROM data for change palette
|
||||||
|
// gui::TextWithSeparators("ROM Palette");
|
||||||
|
// ImGui::SetNextItemWidth(100.f);
|
||||||
|
// ImGui::Combo("Palette Group", (int *)&edit_palette_group_name_index_,
|
||||||
|
// gfx::kPaletteGroupAddressesKeys,
|
||||||
|
// IM_ARRAYSIZE(gfx::kPaletteGroupAddressesKeys));
|
||||||
|
// ImGui::SetNextItemWidth(100.f);
|
||||||
|
// gui::InputHexWord("Palette Group Index", &edit_palette_index_);
|
||||||
|
|
||||||
|
// auto palette_group = rom()->mutable_palette_group()->get_group(
|
||||||
|
// gfx::kPaletteGroupAddressesKeys[edit_palette_group_name_index_]);
|
||||||
|
// auto palette = palette_group->mutable_palette(edit_palette_index_);
|
||||||
|
|
||||||
|
// if (ImGui::BeginChild("Palette", ImVec2(0, 300), true)) {
|
||||||
|
// gui::SelectablePalettePipeline(edit_palette_sub_index_,
|
||||||
|
// refresh_graphics_, *palette);
|
||||||
|
|
||||||
|
// if (refresh_graphics_) {
|
||||||
|
// bitmap_->SetPaletteWithTransparent(*palette,
|
||||||
|
// edit_palette_sub_index_);
|
||||||
|
// Renderer::Get().UpdateBitmap(bitmap_);
|
||||||
|
// refresh_graphics_ = false;
|
||||||
|
// }
|
||||||
|
// ImGui::EndChild();
|
||||||
|
// }
|
||||||
|
EndMenu();
|
||||||
|
}
|
||||||
|
if (BeginMenu("View Palette")) {
|
||||||
|
DisplayEditablePalette(*bitmap_->mutable_palette(), "Palette", true,
|
||||||
|
8);
|
||||||
|
EndMenu();
|
||||||
}
|
}
|
||||||
EndMenu();
|
EndMenu();
|
||||||
}
|
}
|
||||||
MenuItem("Bitmap Data", nullptr, &show_bitmap_data);
|
|
||||||
}
|
}
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
if (BeginMenu("Grid Tile Size")) {
|
if (BeginMenu("Grid Tile Size")) {
|
||||||
@@ -255,12 +251,8 @@ bool Canvas::DrawTilePainter(const Bitmap &bitmap, int size, float scale) {
|
|||||||
origin.y + paint_pos.y + scaled_size));
|
origin.y + paint_pos.y + scaled_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsMouseClicked(ImGuiMouseButton_Left)) {
|
if (IsMouseClicked(ImGuiMouseButton_Left) &&
|
||||||
// Draw the currently selected tile on the overworld here
|
ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
||||||
// Save the coordinates of the selected tile.
|
|
||||||
drawn_tile_pos_ = paint_pos;
|
|
||||||
return true;
|
|
||||||
} else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
|
||||||
// Draw the currently selected tile on the overworld here
|
// Draw the currently selected tile on the overworld here
|
||||||
// Save the coordinates of the selected tile.
|
// Save the coordinates of the selected tile.
|
||||||
drawn_tile_pos_ = paint_pos;
|
drawn_tile_pos_ = paint_pos;
|
||||||
@@ -308,10 +300,8 @@ bool Canvas::DrawTilemapPainter(gfx::Tilemap &tilemap, int current_tile) {
|
|||||||
ImVec2(origin.x + paint_pos.x + scaled_size,
|
ImVec2(origin.x + paint_pos.x + scaled_size,
|
||||||
origin.y + paint_pos.y + scaled_size));
|
origin.y + paint_pos.y + scaled_size));
|
||||||
|
|
||||||
if (IsMouseClicked(ImGuiMouseButton_Left)) {
|
if (IsMouseClicked(ImGuiMouseButton_Left) ||
|
||||||
drawn_tile_pos_ = paint_pos;
|
ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
||||||
return true;
|
|
||||||
} else if (ImGui::IsMouseDragging(ImGuiMouseButton_Left)) {
|
|
||||||
drawn_tile_pos_ = paint_pos;
|
drawn_tile_pos_ = paint_pos;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -407,9 +397,7 @@ bool Canvas::DrawTileSelector(int size, int size_y) {
|
|||||||
if (!points_.empty()) {
|
if (!points_.empty()) {
|
||||||
points_.clear();
|
points_.clear();
|
||||||
}
|
}
|
||||||
ImVec2 painter_pos;
|
ImVec2 painter_pos = AlignPosToGrid(mouse_pos, size);
|
||||||
painter_pos.x = std::floor((double)mouse_pos.x / size) * size;
|
|
||||||
painter_pos.y = std::floor((double)mouse_pos.y / size) * size;
|
|
||||||
|
|
||||||
points_.push_back(painter_pos);
|
points_.push_back(painter_pos);
|
||||||
points_.push_back(ImVec2(painter_pos.x + size, painter_pos.y + size_y));
|
points_.push_back(ImVec2(painter_pos.x + size, painter_pos.y + size_y));
|
||||||
@@ -464,50 +452,48 @@ void Canvas::DrawSelectRect(int current_map, int tile_size, float scale) {
|
|||||||
dragging = true;
|
dragging = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragging) {
|
if (dragging && !ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
|
||||||
// Release dragging mode
|
// Release dragging mode
|
||||||
if (!ImGui::IsMouseDown(ImGuiMouseButton_Right)) {
|
dragging = false;
|
||||||
dragging = false;
|
|
||||||
|
|
||||||
// Calculate the bounds of the rectangle in terms of 16x16 tile indices
|
// Calculate the bounds of the rectangle in terms of 16x16 tile indices
|
||||||
constexpr int tile16_size = 16;
|
constexpr int tile16_size = 16;
|
||||||
int start_x = std::floor(drag_start_pos.x / scaled_size) * tile16_size;
|
int start_x = std::floor(drag_start_pos.x / scaled_size) * tile16_size;
|
||||||
int start_y = std::floor(drag_start_pos.y / scaled_size) * tile16_size;
|
int start_y = std::floor(drag_start_pos.y / scaled_size) * tile16_size;
|
||||||
int end_x = std::floor(drag_end_pos.x / scaled_size) * tile16_size;
|
int end_x = std::floor(drag_end_pos.x / scaled_size) * tile16_size;
|
||||||
int end_y = std::floor(drag_end_pos.y / scaled_size) * tile16_size;
|
int end_y = std::floor(drag_end_pos.y / scaled_size) * tile16_size;
|
||||||
|
|
||||||
// Swap the start and end positions if they are in the wrong order
|
// Swap the start and end positions if they are in the wrong order
|
||||||
if (start_x > end_x) std::swap(start_x, end_x);
|
if (start_x > end_x) std::swap(start_x, end_x);
|
||||||
if (start_y > end_y) std::swap(start_y, end_y);
|
if (start_y > end_y) std::swap(start_y, end_y);
|
||||||
|
|
||||||
selected_tiles_.clear();
|
selected_tiles_.clear();
|
||||||
// Number of tiles per local map (since each tile is 16x16)
|
// Number of tiles per local map (since each tile is 16x16)
|
||||||
constexpr int tiles_per_local_map = small_map_size / 16;
|
constexpr int tiles_per_local_map = small_map_size / 16;
|
||||||
|
|
||||||
// Loop through the tiles in the rectangle and store their positions
|
// Loop through the tiles in the rectangle and store their positions
|
||||||
for (int y = start_y; y <= end_y; y += tile16_size) {
|
for (int y = start_y; y <= end_y; y += tile16_size) {
|
||||||
for (int x = start_x; x <= end_x; x += tile16_size) {
|
for (int x = start_x; x <= end_x; x += tile16_size) {
|
||||||
// Determine which local map (512x512) the tile is in
|
// Determine which local map (512x512) the tile is in
|
||||||
int local_map_x = x / small_map_size;
|
int local_map_x = x / small_map_size;
|
||||||
int local_map_y = y / small_map_size;
|
int local_map_y = y / small_map_size;
|
||||||
|
|
||||||
// Calculate the tile's position within its local map
|
// Calculate the tile's position within its local map
|
||||||
int tile16_x = (x % small_map_size) / tile16_size;
|
int tile16_x = (x % small_map_size) / tile16_size;
|
||||||
int tile16_y = (y % small_map_size) / tile16_size;
|
int tile16_y = (y % small_map_size) / tile16_size;
|
||||||
|
|
||||||
// Calculate the index within the overall map structure
|
// Calculate the index within the overall map structure
|
||||||
int index_x = local_map_x * tiles_per_local_map + tile16_x;
|
int index_x = local_map_x * tiles_per_local_map + tile16_x;
|
||||||
int index_y = local_map_y * tiles_per_local_map + tile16_y;
|
int index_y = local_map_y * tiles_per_local_map + tile16_y;
|
||||||
|
|
||||||
selected_tiles_.push_back(ImVec2(index_x, index_y));
|
selected_tiles_.push_back(ImVec2(index_x, index_y));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// Clear and add the calculated rectangle points
|
|
||||||
selected_points_.clear();
|
|
||||||
selected_points_.push_back(drag_start_pos);
|
|
||||||
selected_points_.push_back(drag_end_pos);
|
|
||||||
select_rect_active_ = true;
|
|
||||||
}
|
}
|
||||||
|
// Clear and add the calculated rectangle points
|
||||||
|
selected_points_.clear();
|
||||||
|
selected_points_.push_back(drag_start_pos);
|
||||||
|
selected_points_.push_back(drag_end_pos);
|
||||||
|
select_rect_active_ = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -709,25 +695,27 @@ void Canvas::DrawInfoGrid(float grid_step, int tile_id_offset, int label_id) {
|
|||||||
DrawGridLines(grid_step);
|
DrawGridLines(grid_step);
|
||||||
DrawCustomHighlight(grid_step);
|
DrawCustomHighlight(grid_step);
|
||||||
|
|
||||||
if (enable_custom_labels_) {
|
if (!enable_custom_labels_) {
|
||||||
// Draw the contents of labels on the grid
|
return;
|
||||||
for (float x = fmodf(scrolling_.x, grid_step);
|
}
|
||||||
x < canvas_sz_.x * global_scale_; x += grid_step) {
|
|
||||||
for (float y = fmodf(scrolling_.y, grid_step);
|
|
||||||
y < canvas_sz_.y * global_scale_; y += grid_step) {
|
|
||||||
int tile_x = (x - scrolling_.x) / grid_step;
|
|
||||||
int tile_y = (y - scrolling_.y) / grid_step;
|
|
||||||
int tile_id = tile_x + (tile_y * tile_id_offset);
|
|
||||||
|
|
||||||
if (tile_id >= labels_[label_id].size()) {
|
// Draw the contents of labels on the grid
|
||||||
break;
|
for (float x = fmodf(scrolling_.x, grid_step);
|
||||||
}
|
x < canvas_sz_.x * global_scale_; x += grid_step) {
|
||||||
std::string label = labels_[label_id][tile_id];
|
for (float y = fmodf(scrolling_.y, grid_step);
|
||||||
draw_list_->AddText(
|
y < canvas_sz_.y * global_scale_; y += grid_step) {
|
||||||
ImVec2(canvas_p0_.x + x + (grid_step / 2) - tile_id_offset,
|
int tile_x = (x - scrolling_.x) / grid_step;
|
||||||
canvas_p0_.y + y + (grid_step / 2) - tile_id_offset),
|
int tile_y = (y - scrolling_.y) / grid_step;
|
||||||
kWhiteColor, label.data());
|
int tile_id = tile_x + (tile_y * tile_id_offset);
|
||||||
|
|
||||||
|
if (tile_id >= labels_[label_id].size()) {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
std::string label = labels_[label_id][tile_id];
|
||||||
|
draw_list_->AddText(
|
||||||
|
ImVec2(canvas_p0_.x + x + (grid_step / 2) - tile_id_offset,
|
||||||
|
canvas_p0_.y + y + (grid_step / 2) - tile_id_offset),
|
||||||
|
kWhiteColor, label.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -773,25 +761,26 @@ void Canvas::DrawGrid(float grid_step, int tile_id_offset) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (enable_custom_labels_) {
|
if (!enable_custom_labels_) {
|
||||||
// Draw the contents of labels on the grid
|
return;
|
||||||
for (float x = fmodf(scrolling_.x, grid_step);
|
}
|
||||||
x < canvas_sz_.x * global_scale_; x += grid_step) {
|
// Draw the contents of labels on the grid
|
||||||
for (float y = fmodf(scrolling_.y, grid_step);
|
for (float x = fmodf(scrolling_.x, grid_step);
|
||||||
y < canvas_sz_.y * global_scale_; y += grid_step) {
|
x < canvas_sz_.x * global_scale_; x += grid_step) {
|
||||||
int tile_x = (x - scrolling_.x) / grid_step;
|
for (float y = fmodf(scrolling_.y, grid_step);
|
||||||
int tile_y = (y - scrolling_.y) / grid_step;
|
y < canvas_sz_.y * global_scale_; y += grid_step) {
|
||||||
int tile_id = tile_x + (tile_y * tile_id_offset);
|
int tile_x = (x - scrolling_.x) / grid_step;
|
||||||
|
int tile_y = (y - scrolling_.y) / grid_step;
|
||||||
|
int tile_id = tile_x + (tile_y * tile_id_offset);
|
||||||
|
|
||||||
if (tile_id >= labels_[current_labels_].size()) {
|
if (tile_id >= labels_[current_labels_].size()) {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
std::string label = labels_[current_labels_][tile_id];
|
|
||||||
draw_list_->AddText(
|
|
||||||
ImVec2(canvas_p0_.x + x + (grid_step / 2) - tile_id_offset,
|
|
||||||
canvas_p0_.y + y + (grid_step / 2) - tile_id_offset),
|
|
||||||
kWhiteColor, label.data());
|
|
||||||
}
|
}
|
||||||
|
std::string label = labels_[current_labels_][tile_id];
|
||||||
|
draw_list_->AddText(
|
||||||
|
ImVec2(canvas_p0_.x + x + (grid_step / 2) - tile_id_offset,
|
||||||
|
canvas_p0_.y + y + (grid_step / 2) - tile_id_offset),
|
||||||
|
kWhiteColor, label.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -909,8 +898,8 @@ void GraphicsBinCanvasPipeline(int width, int height, int tile_size,
|
|||||||
void BitmapCanvasPipeline(gui::Canvas &canvas, gfx::Bitmap &bitmap, int width,
|
void BitmapCanvasPipeline(gui::Canvas &canvas, gfx::Bitmap &bitmap, int width,
|
||||||
int height, int tile_size, bool is_loaded,
|
int height, int tile_size, bool is_loaded,
|
||||||
bool scrollbar, int canvas_id) {
|
bool scrollbar, int canvas_id) {
|
||||||
auto draw_canvas = [](gui::Canvas &canvas, gfx::Bitmap &bitmap, int width,
|
auto draw_canvas = [&](gui::Canvas &canvas, gfx::Bitmap &bitmap, int width,
|
||||||
int height, int tile_size, bool is_loaded) {
|
int height, int tile_size, bool is_loaded) {
|
||||||
canvas.DrawBackground(ImVec2(width + 1, height + 1));
|
canvas.DrawBackground(ImVec2(width + 1, height + 1));
|
||||||
canvas.DrawContextMenu();
|
canvas.DrawContextMenu();
|
||||||
canvas.DrawBitmap(bitmap, 2, is_loaded);
|
canvas.DrawBitmap(bitmap, 2, is_loaded);
|
||||||
@@ -932,5 +921,4 @@ void BitmapCanvasPipeline(gui::Canvas &canvas, gfx::Bitmap &bitmap, int width,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace gui
|
} // namespace yaze::gui
|
||||||
} // namespace yaze
|
|
||||||
|
|||||||
@@ -34,28 +34,28 @@ enum class CanvasGridSize { k8x8, k16x16, k32x32, k64x64 };
|
|||||||
* on a canvas. It supports features such as bitmap drawing, context menu
|
* on a canvas. It supports features such as bitmap drawing, context menu
|
||||||
* handling, tile painting, custom grid, and more.
|
* handling, tile painting, custom grid, and more.
|
||||||
*/
|
*/
|
||||||
class Canvas : public SharedRom {
|
class Canvas {
|
||||||
public:
|
public:
|
||||||
Canvas() = default;
|
Canvas() = default;
|
||||||
explicit Canvas(const std::string &id) : canvas_id_(id) {
|
explicit Canvas(const std::string &id) : canvas_id_(id) {
|
||||||
context_id_ = id + "Context";
|
context_id_ = id + "Context";
|
||||||
}
|
}
|
||||||
explicit Canvas(const std::string &id, ImVec2 canvas_size)
|
explicit Canvas(const std::string &id, ImVec2 canvas_size)
|
||||||
: canvas_id_(id), custom_canvas_size_(true), canvas_sz_(canvas_size) {
|
: custom_canvas_size_(true), canvas_sz_(canvas_size), canvas_id_(id) {
|
||||||
context_id_ = id + "Context";
|
context_id_ = id + "Context";
|
||||||
}
|
}
|
||||||
explicit Canvas(const std::string &id, ImVec2 canvas_size,
|
explicit Canvas(const std::string &id, ImVec2 canvas_size,
|
||||||
CanvasGridSize grid_size)
|
CanvasGridSize grid_size)
|
||||||
: canvas_id_(id), custom_canvas_size_(true), canvas_sz_(canvas_size) {
|
: custom_canvas_size_(true), canvas_sz_(canvas_size), canvas_id_(id) {
|
||||||
context_id_ = id + "Context";
|
context_id_ = id + "Context";
|
||||||
SetCanvasGridSize(grid_size);
|
SetCanvasGridSize(grid_size);
|
||||||
}
|
}
|
||||||
explicit Canvas(const std::string &id, ImVec2 canvas_size,
|
explicit Canvas(const std::string &id, ImVec2 canvas_size,
|
||||||
CanvasGridSize grid_size, float global_scale)
|
CanvasGridSize grid_size, float global_scale)
|
||||||
: canvas_id_(id),
|
: custom_canvas_size_(true),
|
||||||
custom_canvas_size_(true),
|
global_scale_(global_scale),
|
||||||
canvas_sz_(canvas_size),
|
canvas_sz_(canvas_size),
|
||||||
global_scale_(global_scale) {
|
canvas_id_(id) {
|
||||||
context_id_ = id + "Context";
|
context_id_ = id + "Context";
|
||||||
SetCanvasGridSize(grid_size);
|
SetCanvasGridSize(grid_size);
|
||||||
}
|
}
|
||||||
@@ -81,12 +81,12 @@ class Canvas : public SharedRom {
|
|||||||
const std::function<void()> &event, int tile_size,
|
const std::function<void()> &event, int tile_size,
|
||||||
float scale = 1.0f);
|
float scale = 1.0f);
|
||||||
|
|
||||||
void UpdateInfoGrid(ImVec2 bg_size, int tile_size, float scale = 1.0f,
|
void UpdateInfoGrid(ImVec2 bg_size, float grid_size = 64.0f,
|
||||||
float grid_size = 64.0f, int label_id = 0);
|
int label_id = 0);
|
||||||
|
|
||||||
// Background for the Canvas represents region without any content drawn to
|
// Background for the Canvas represents region without any content drawn to
|
||||||
// it, but can be controlled by the user.
|
// it, but can be controlled by the user.
|
||||||
void DrawBackground(ImVec2 canvas_size = ImVec2(0, 0), bool drag = false);
|
void DrawBackground(ImVec2 canvas_size = ImVec2(0, 0));
|
||||||
|
|
||||||
// Context Menu refers to what happens when the right mouse button is pressed
|
// Context Menu refers to what happens when the right mouse button is pressed
|
||||||
// This routine also handles the scrolling for the canvas.
|
// This routine also handles the scrolling for the canvas.
|
||||||
@@ -111,8 +111,8 @@ class Canvas : public SharedRom {
|
|||||||
|
|
||||||
// Draws the contents of the Bitmap image to the Canvas
|
// Draws the contents of the Bitmap image to the Canvas
|
||||||
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale);
|
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale);
|
||||||
void DrawBitmap(Bitmap &bitmap, int x_offset, int y_offset, float scale = 1.0f,
|
void DrawBitmap(Bitmap &bitmap, int x_offset, int y_offset,
|
||||||
int alpha = 255);
|
float scale = 1.0f, int alpha = 255);
|
||||||
void DrawBitmap(Bitmap &bitmap, ImVec2 dest_pos, ImVec2 dest_size,
|
void DrawBitmap(Bitmap &bitmap, ImVec2 dest_pos, ImVec2 dest_size,
|
||||||
ImVec2 src_pos, ImVec2 src_size);
|
ImVec2 src_pos, ImVec2 src_size);
|
||||||
void DrawBitmapTable(const BitmapTable &gfx_bin);
|
void DrawBitmapTable(const BitmapTable &gfx_bin);
|
||||||
@@ -206,6 +206,9 @@ class Canvas : public SharedRom {
|
|||||||
|
|
||||||
auto hover_mouse_pos() const { return mouse_pos_in_canvas_; }
|
auto hover_mouse_pos() const { return mouse_pos_in_canvas_; }
|
||||||
|
|
||||||
|
void set_rom(Rom *rom) { rom_ = rom; }
|
||||||
|
Rom *rom() const { return rom_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool draggable_ = false;
|
bool draggable_ = false;
|
||||||
bool is_hovered_ = false;
|
bool is_hovered_ = false;
|
||||||
@@ -228,6 +231,7 @@ class Canvas : public SharedRom {
|
|||||||
uint64_t edit_palette_sub_index_ = 0;
|
uint64_t edit_palette_sub_index_ = 0;
|
||||||
|
|
||||||
Bitmap *bitmap_ = nullptr;
|
Bitmap *bitmap_ = nullptr;
|
||||||
|
Rom *rom_ = nullptr;
|
||||||
|
|
||||||
ImDrawList *draw_list_ = nullptr;
|
ImDrawList *draw_list_ = nullptr;
|
||||||
|
|
||||||
|
|||||||
@@ -649,6 +649,4 @@ absl::Status Rom::WriteColor(uint32_t address, const gfx::SnesColor &color) {
|
|||||||
return WriteShort(address, bgr);
|
return WriteShort(address, bgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Rom> SharedRom::shared_rom_ = nullptr;
|
|
||||||
|
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|||||||
@@ -272,40 +272,6 @@ absl::StatusOr<std::array<gfx::Bitmap, kNumLinkSheets>> LoadLinkGraphics(
|
|||||||
|
|
||||||
absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
|
absl::StatusOr<gfx::Bitmap> LoadFontGraphics(const Rom& rom);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief A class to hold a shared pointer to a Rom object.
|
|
||||||
*/
|
|
||||||
class SharedRom {
|
|
||||||
public:
|
|
||||||
SharedRom() = default;
|
|
||||||
virtual ~SharedRom() = default;
|
|
||||||
|
|
||||||
std::shared_ptr<Rom> shared_rom() {
|
|
||||||
if (!shared_rom_) {
|
|
||||||
shared_rom_ = std::make_shared<Rom>();
|
|
||||||
}
|
|
||||||
return shared_rom_;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto rom() {
|
|
||||||
if (!shared_rom_) {
|
|
||||||
shared_rom_ = std::make_shared<Rom>();
|
|
||||||
}
|
|
||||||
Rom* rom = shared_rom_.get();
|
|
||||||
return rom;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void set_rom(Rom* rom) {
|
|
||||||
if (!shared_rom_) {
|
|
||||||
shared_rom_ = std::make_shared<Rom>();
|
|
||||||
}
|
|
||||||
shared_rom_ = std::shared_ptr<Rom>(rom);
|
|
||||||
}
|
|
||||||
|
|
||||||
// private:
|
|
||||||
static std::shared_ptr<Rom> shared_rom_;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace yaze
|
} // namespace yaze
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -77,14 +77,6 @@
|
|||||||
|
|
||||||
// Enable native IME.
|
// Enable native IME.
|
||||||
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
SDL_SetHint(SDL_HINT_IME_SHOW_UI, "1");
|
||||||
if (!_controller->CreateWindow().ok()) {
|
|
||||||
printf("Error creating window: %s\n", SDL_GetError());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
if (!_controller->CreateRenderer().ok()) {
|
|
||||||
printf("Error creating renderer: %s\n", SDL_GetError());
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
ImGui_ImplSDL2_InitForSDLRenderer(_controller->window(),
|
ImGui_ImplSDL2_InitForSDLRenderer(_controller->window(),
|
||||||
yaze::core::Renderer::Get().renderer());
|
yaze::core::Renderer::Get().renderer());
|
||||||
@@ -93,7 +85,6 @@
|
|||||||
if (!LoadPackageFonts().ok()) {
|
if (!LoadPackageFonts().ok()) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
_controller->Initialize("");
|
|
||||||
_controller->set_active(true);
|
_controller->set_active(true);
|
||||||
|
|
||||||
_hoverGestureRecognizer =
|
_hoverGestureRecognizer =
|
||||||
@@ -357,9 +348,10 @@
|
|||||||
rom_data.resize(size);
|
rom_data.resize(size);
|
||||||
std::copy(bytes, bytes + size, rom_data.begin());
|
std::copy(bytes, bytes + size, rom_data.begin());
|
||||||
|
|
||||||
PRINT_IF_ERROR(yaze::SharedRom::shared_rom_->LoadFromData(rom_data));
|
// TODO: Re-implmenent this without the SharedRom singleton
|
||||||
|
// PRINT_IF_ERROR(yaze::SharedRom::shared_rom_->LoadFromData(rom_data));
|
||||||
std::string filename = std::string([selectedFileURL.path UTF8String]);
|
std::string filename = std::string([selectedFileURL.path UTF8String]);
|
||||||
yaze::SharedRom::shared_rom_->set_filename(filename);
|
// yaze::SharedRom::shared_rom_->set_filename(filename);
|
||||||
[selectedFileURL stopAccessingSecurityScopedResource];
|
[selectedFileURL stopAccessingSecurityScopedResource];
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user