5#include "absl/status/status.h"
15#include "imgui/imgui.h"
26 std::array<uint8_t, 0x200> &all_tiles_types) {
33 tile16_blockset_bmp.
width(), tile16_blockset_bmp.
height(),
34 tile16_blockset_bmp.
depth(), tile16_blockset_bmp.
vector());
45 ImVector<std::string> tile16_names;
46 for (
int i = 0; i < 0x200; ++i) {
48 tile16_names.push_back(str);
59 Checkbox(
"X Flip", &
x_flip);
60 Checkbox(
"Y Flip", &
y_flip);
64 return absl::OkStatus();
69 return absl::InvalidArgumentError(
"Blockset not initialized, open a ROM.");
73 if (BeginMenu(
"View")) {
74 Checkbox(
"Show Collision Types",
79 if (BeginMenu(
"Edit")) {
80 if (MenuItem(
"Copy Current Tile16")) {
83 if (MenuItem(
"Paste to Current Tile16")) {
87 if (MenuItem(
"Save to Scratch Space 1")) {
90 if (MenuItem(
"Save to Scratch Space 2")) {
93 if (MenuItem(
"Save to Scratch Space 3")) {
96 if (MenuItem(
"Save to Scratch Space 4")) {
100 if (MenuItem(
"Load from Scratch Space 1")) {
103 if (MenuItem(
"Load from Scratch Space 2")) {
106 if (MenuItem(
"Load from Scratch Space 3")) {
109 if (MenuItem(
"Load from Scratch Space 4")) {
115 if (BeginMenu(
"Help")) {
116 if (MenuItem(
"About Tile16 Editor")) {
117 OpenPopup(
"About Tile16 Editor");
126 if (BeginPopupModal(
"About Tile16 Editor", NULL,
127 ImGuiWindowFlags_AlwaysAutoResize)) {
128 Text(
"Tile16 Editor for Link to the Past");
129 Text(
"This editor allows you to edit 16x16 tiles used in the game.");
131 BulletText(
"Edit Tile16 graphics by placing 8x8 tiles in the quadrants");
132 BulletText(
"Copy and paste Tile16 graphics");
133 BulletText(
"Save and load Tile16 graphics to/from scratch space");
134 BulletText(
"Preview Tile16 graphics at a larger size");
136 if (Button(
"Close")) {
142 if (BeginTabBar(
"Tile16 Editor Tabs")) {
147 return absl::OkStatus();
151 if (BeginTabItem(
"Tile16 Editing")) {
154 TableSetupColumn(
"Blockset", ImGuiTableColumnFlags_WidthFixed,
155 GetContentRegionAvail().x);
156 TableSetupColumn(
"Properties", ImGuiTableColumnFlags_WidthStretch,
157 GetContentRegionAvail().x);
191 auto ow_main_pal_group =
rom()->palette_group().overworld_main;
197 return absl::OkStatus();
201 constexpr int tile8_size = 8;
202 constexpr int tile16_size = 16;
206 int tile_index_x =
static_cast<int>(click_position.x) / tile8_size;
207 int tile_index_y =
static_cast<int>(click_position.y) / tile8_size;
210 tile_index_x = std::min(1, std::max(0, tile_index_x));
211 tile_index_y = std::min(1, std::max(0, tile_index_y));
215 int start_x = tile_index_x * tile8_size;
216 int start_y = tile_index_y * tile8_size;
219 for (
int y = 0; y < tile8_size; ++y) {
220 for (
int x = 0; x < tile8_size; ++x) {
222 int pixel_x = start_x + x;
223 int pixel_y = start_y + y;
224 int pixel_index = pixel_y * tile16_size + pixel_x;
227 int gfx_pixel_index = y * tile8_size + x;
231 gfx_pixel_index = y * tile8_size + (tile8_size - 1 - x);
234 gfx_pixel_index = (tile8_size - 1 - y) * tile8_size + x;
238 (tile8_size - 1 - y) * tile8_size + (tile8_size - 1 - x);
248 return absl::OkStatus();
252 auto ow_main_pal_group =
rom()->palette_group().overworld_main;
255 if (BeginTabBar(
"Tile16EditorTabs")) {
257 if (BeginTabItem(
"Edit")) {
262 TableSetupColumn(
"Tile8 Selector", ImGuiTableColumnFlags_WidthFixed,
263 GetContentRegionAvail().x * 0.6f);
265 TableSetupColumn(
"Tile16 Editor", ImGuiTableColumnFlags_WidthStretch,
266 GetContentRegionAvail().x * 0.4f);
273 if (BeginChild(
"Tile8 Selector", ImVec2(0, 0x175),
true)) {
290 if (BeginChild(
"Tile16 Editor", ImVec2(0, 0x175),
true)) {
317 TableSetupColumn(
"Properties", ImGuiTableColumnFlags_WidthFixed,
318 GetContentRegionAvail().x * 0.5f);
320 TableSetupColumn(
"Actions", ImGuiTableColumnFlags_WidthStretch,
321 GetContentRegionAvail().x * 0.5f);
328 Text(
"Tile Properties:");
360 if (Button(
"Copy Current Tile16")) {
364 if (Button(
"Paste to Current Tile16")) {
370 Text(
"Scratch Space:");
373 for (
int i = 0; i < 4; i++) {
374 if (i > 0) SameLine();
377 if (Button((
"Slot " + std::to_string(i)).c_str())) {
381 if (Button((
"Clear##" + std::to_string(i)).c_str())) {
385 if (Button((
"Empty##" + std::to_string(i)).c_str())) {
398 if (BeginTabItem(
"Preview")) {
399 if (BeginChild(
"Tile16Preview", ImVec2(0, 0),
true)) {
403 ImGui::Image((ImTextureID)(intptr_t)texture, ImVec2(128, 128));
409 Text(
"X Flip: %s",
x_flip ?
"Yes" :
"No");
410 Text(
"Y Flip: %s",
y_flip ?
"Yes" :
"No");
432 return absl::OkStatus();
436 auto ow_main_pal_group =
rom()->palette_group().overworld_main;
439 std::vector<std::future<std::array<uint8_t, 0x40>>> futures;
441 for (
int index = 0; index < 1024; index++) {
442 auto task_function = [&]() {
443 std::array<uint8_t, 0x40> tile_data;
445 for (
int ty = 0; ty < 8; ty++) {
446 for (
int tx = 0; tx < 8; tx++) {
449 int position = tx + (ty * 0x08);
453 int x = (index % num_columns) * 8 + tx;
454 int y = (index / num_columns) * 8 + ty;
455 int gfx_position = x + (y * 0x100);
464 tile_data[position] = value;
469 futures.emplace_back(std::async(std::launch::async, task_function));
472 for (
auto &future : futures) {
474 auto tile_data = future.get();
477 tile_bitmap.Create(0x08, 0x08, 0x08, tile_data);
478 tile_bitmap.SetPaletteWithTransparent(ow_main_pal_group[0],
485 return absl::OkStatus();
491 auto ow_main_pal_group =
rom()->palette_group().overworld_main;
494 return absl::OkStatus();
497#pragma mark - Tile16Transfer
500 if (BeginTabItem(
"Tile16 Transfer")) {
503 TableSetupColumn(
"Current ROM Tiles", ImGuiTableColumnFlags_WidthFixed,
504 GetContentRegionAvail().x / 2);
505 TableSetupColumn(
"Transfer ROM Tiles", ImGuiTableColumnFlags_WidthFixed,
506 GetContentRegionAvail().x / 2);
521 return absl::OkStatus();
526 if (Button(
"Load ROM")) {
527 auto transfer_rom = std::make_unique<Rom>();
555 return absl::OkStatus();
560 return absl::InvalidArgumentError(
"Invalid tile ID");
569 return absl::OkStatus();
574 return absl::FailedPreconditionError(
"Clipboard is empty");
582 return absl::OkStatus();
586 if (slot < 0 || slot >= 4) {
587 return absl::InvalidArgumentError(
"Invalid scratch space slot");
596 return absl::OkStatus();
600 if (slot < 0 || slot >= 4) {
601 return absl::InvalidArgumentError(
"Invalid scratch space slot");
605 return absl::FailedPreconditionError(
"Scratch space slot is empty");
613 return absl::OkStatus();
617 if (slot < 0 || slot >= 4) {
618 return absl::InvalidArgumentError(
"Invalid scratch space slot");
622 return absl::OkStatus();
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath.
void CreateAndRenderBitmap(int width, int height, int depth, const std::vector< uint8_t > &data, gfx::Bitmap &bitmap, gfx::SnesPalette &palette)
void UpdateBitmap(gfx::Bitmap *bitmap)
Used to update a bitmap on the screen.
static Renderer & GetInstance()
void RenderBitmap(gfx::Bitmap *bitmap)
Used to render a bitmap to the screen.
static Renderer & GetInstance()
absl::Status SaveTile16ToScratchSpace(int slot)
gfx::Bitmap current_gfx_bmp_
util::NotifyValue< uint32_t > notify_tile16
absl::Status UpdateTransferTileCanvas()
bool map_blockset_loaded_
std::array< uint8_t, 0x200 > all_tiles_types_
absl::Status PasteTile16FromClipboard()
absl::Status LoadTile16FromScratchSpace(int slot)
gfx::SnesPalette palette_
absl::Status UpdateTile16Transfer()
absl::Status UpdateTile16Edit()
absl::Status Initialize(const gfx::Bitmap &tile16_blockset_bmp, const gfx::Bitmap ¤t_gfx_bmp, std::array< uint8_t, 0x200 > &all_tiles_types)
absl::Status UpdateBlockset()
absl::Status SetCurrentTile(int id)
gfx::Bitmap clipboard_tile16_
std::array< gfx::Bitmap, 4 > scratch_space_
std::array< gfx::Bitmap, zelda3::kNumTile16Individual > * tile16_individual_
absl::Status DrawToCurrentTile16(ImVec2 pos)
gui::Canvas transfer_canvas_
bool transfer_blockset_loaded_
gui::Canvas tile16_edit_canvas_
gui::Canvas blockset_canvas_
gui::Canvas tile8_source_canvas_
absl::Status transfer_status_
zelda3::Overworld transfer_overworld_
gfx::Bitmap tile16_blockset_bmp_
gfx::Bitmap transfer_blockset_bmp_
std::vector< gfx::Bitmap > current_gfx_individual_
absl::Status CopyTile16ToClipboard(int tile_id)
std::array< gfx::Bitmap, kNumGfxSheets > transfer_gfx_
absl::Status ClearScratchSpace(int slot)
gui::Table tile_edit_table_
gfx::Bitmap current_tile16_bmp_
std::array< bool, 4 > scratch_space_used_
util::NotifyValue< uint8_t > notify_palette
Represents a bitmap image.
const SnesPalette & palette() const
const std::vector< uint8_t > & vector() const
static std::unordered_map< uint8_t, gfx::Paletteset > palettesets_
#define TABLE_BORDERS_RESIZABLE
#define PRINT_IF_ERROR(expression)
#define RETURN_IF_ERROR(expression)
#define ASSIGN_OR_RETURN(type_variable_name, expression)
Editors are the view controllers for the application.
void BitmapCanvasPipeline(gui::Canvas &canvas, gfx::Bitmap &bitmap, int width, int height, int tile_size, bool is_loaded, bool scrollbar, int canvas_id)
void AddTableColumn(Table &table, const std::string &label, GuiElement element)
void DrawTable(Table ¶ms)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
void BeginChildWithScrollbar(const char *str_id)
std::string HexByte(uint8_t byte, HexStringParams params)
constexpr int kNumTile16Individual
Main namespace for the application.
absl::StatusOr< std::array< gfx::Bitmap, kNumGfxSheets > > LoadAllGraphicsData(Rom &rom, bool defer_render)
This function iterates over all graphics sheets in the Rom and loads them into memory....