7#include "absl/status/status.h"
8#include "absl/strings/str_cat.h"
9#include "absl/strings/str_format.h"
22#include "imgui/misc/cpp/imgui_stdlib.h"
32 std::string bankSTR = bank ?
"1st" :
"2nd";
34 bank ? absl::StrFormat(
"%X4", pos & 0xFFFF)
35 : absl::StrFormat(
"%X4", (pos -
kTextData2) & 0xFFFF);
36 std::string message = absl::StrFormat(
37 "There is too much text data in the %s block to save.\n"
38 "Available: %X4 | Used: %s",
39 bankSTR, space, posSTR);
45using ImGui::BeginChild;
46using ImGui::BeginTable;
50using ImGui::InputTextMultiline;
54using ImGui::Separator;
55using ImGui::TableHeadersRow;
56using ImGui::TableNextColumn;
57using ImGui::TableSetupColumn;
59using ImGui::TextWrapped;
62 ImGuiTableFlags_Borders |
63 ImGuiTableFlags_Resizable;
73 .display_name =
"Message List",
75 .category =
"Message",
79 card_registry->RegisterCard({
80 .card_id =
MakeCardId(
"message.message_editor"),
81 .display_name =
"Message Editor",
83 .category =
"Message",
87 card_registry->RegisterCard({
89 .display_name =
"Font Atlas",
91 .category =
"Message",
95 card_registry->RegisterCard({
97 .display_name =
"Dictionary",
99 .category =
"Message",
104 card_registry->ShowCard(
MakeCardId(
"message.message_list"));
114 for (
int i = 0; i < 0x4000; i++) {
129 LOG_INFO(
"MessageEditor",
"Font bitmap created and texture queued");
133 if (load_font.ok()) {
145 return absl::OkStatus();
155 if (list_visible && *list_visible) {
158 if (list_card.
Begin(list_visible)) {
165 bool* editor_visible = card_registry->GetVisibilityFlag(
MakeCardId(
"message.message_editor"));
166 if (editor_visible && *editor_visible) {
169 if (editor_card.
Begin(editor_visible)) {
176 bool* font_visible = card_registry->GetVisibilityFlag(
MakeCardId(
"message.font_atlas"));
177 if (font_visible && *font_visible) {
180 if (font_card.
Begin(font_visible)) {
188 bool* dict_visible = card_registry->GetVisibilityFlag(
MakeCardId(
"message.dictionary"));
189 if (dict_visible && *dict_visible) {
192 if (dict_card.
Begin(dict_visible)) {
200 return absl::OkStatus();
205 if (BeginChild(
"##MessagesList", ImVec2(0, 0),
true,
206 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
209 TableSetupColumn(
"ID");
210 TableSetupColumn(
"Contents");
211 TableSetupColumn(
"Data");
231 PushID(expanded_message.ID + 0x18D);
232 if (Button(
util::HexWord(expanded_message.ID + 0x18D).c_str())) {
243 TextWrapped(
"%s",
util::HexLong(expanded_message.Address).c_str());
255 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
258 temp.erase(std::remove(temp.begin(), temp.end(),
'\n'), temp.end());
265 ImGui::BeginChild(
"##MessagePreview", ImVec2(0, 0),
true, 1);
266 Text(
"Message Preview");
267 if (Button(
"View Palette")) {
268 ImGui::OpenPopup(
"Palette");
270 if (ImGui::BeginPopup(
"Palette")) {
275 BeginChild(
"CurrentGfxFont", ImVec2(348, 0),
true,
276 ImGuiWindowFlags_NoScrollWithMouse);
282 if (ImGui::IsWindowHovered()) {
283 float wheel = ImGui::GetIO().MouseWheel;
286 }
else if (wheel < 0 &&
316 ImGui::BeginChild(
"##ExpandedMessageSettings", ImVec2(0, 100),
true,
317 ImGuiWindowFlags_AlwaysVerticalScrollbar);
318 ImGui::Text(
"Expanded Messages");
319 static std::string expanded_message_path =
"";
320 if (ImGui::Button(
"Load Expanded Message")) {
322 if (!expanded_message_path.empty()) {
328 popup_manager->Show(
"Error");
335 ImGui::Text(
"Expanded Path: %s", expanded_message_path.c_str());
337 if (ImGui::Button(
"Add New Message")) {
344 if (ImGui::Button(
"Save Expanded Messages")) {
353 ImGui::BeginChild(
"##TextCommands",
354 ImVec2(0, ImGui::GetContentRegionAvail().y / 2),
true,
355 ImGuiWindowFlags_AlwaysVerticalScrollbar);
356 static uint8_t command_parameter = 0;
358 for (
const auto& text_element : TextCommands) {
359 if (Button(text_element.GenericToken.c_str())) {
361 text_element.GetParamToken(command_parameter));
364 TextWrapped(
"%s", text_element.Description.c_str());
371 ImGui::BeginChild(
"##SpecialChars",
372 ImVec2(0, ImGui::GetContentRegionAvail().y / 2),
true,
373 ImGuiWindowFlags_AlwaysVerticalScrollbar);
374 for (
const auto& text_element : SpecialChars) {
375 if (Button(text_element.GenericToken.c_str())) {
379 TextWrapped(
"%s", text_element.Description.c_str());
386 if (ImGui::BeginChild(
"##DictionaryChild",
387 ImVec2(0, ImGui::GetContentRegionAvail().y),
true,
388 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
390 TableSetupColumn(
"ID");
391 TableSetupColumn(
"Contents");
397 Text(
"%s", dictionary.Contents.c_str());
411 LOG_WARN(
"MessageEditor",
"Preview data is empty, skipping bitmap update");
422 LOG_ERROR(
"MessageEditor",
"Bitmap surface is null after set_data()");
430 LOG_DEBUG(
"MessageEditor",
"Updated message preview bitmap (size: %zu) and queued texture update",
440 LOG_INFO(
"MessageEditor",
"Created message preview bitmap (%dx%d) with 8-bit depth and queued texture creation",
446 std::vector<uint8_t> backup =
rom()->
vector();
454 bool in_second_bank =
false;
457 for (
const auto value : message.Data) {
464 return absl::InternalError(DisplayTextOverflowError(pos,
true));
469 in_second_bank =
true;
481 std::copy(backup.begin(), backup.end(),
rom()->mutable_data());
482 return absl::InternalError(DisplayTextOverflowError(pos,
false));
487 return absl::OkStatus();
492 std::copy(expanded_message.Data.begin(), expanded_message.Data.end(),
500 return absl::OkStatus();
509 return absl::OkStatus();
514 if (ImGui::GetClipboardText() !=
nullptr) {
518 return absl::OkStatus();
527 return absl::OkStatus();
539 return absl::OkStatus();
545 return absl::OkStatus();
568 if (ImGui::Begin(
"Find Text",
nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
569 static char find_text[256] =
"";
570 ImGui::InputText(
"Search", find_text, IM_ARRAYSIZE(find_text));
572 if (ImGui::Button(
"Find Next")) {
577 if (ImGui::Button(
"Find All")) {
582 if (ImGui::Button(
"Replace")) {
592 return absl::OkStatus();
auto palette_group() const
absl::Status WriteByte(int addr, uint8_t value)
absl::Status SaveToFile(const SaveSettings &settings)
bool * GetVisibilityFlag(size_t session_id, const std::string &base_card_id)
Get visibility flag pointer for a card.
void RegisterCard(size_t session_id, const CardInfo &base_info)
Register a card for a specific session.
EditorDependencies dependencies_
std::string MakeCardId(const std::string &base_id) const
std::vector< std::string > parsed_messages_
absl::Status Copy() override
std::vector< MessageData > expanded_messages_
absl::Status Find() override
absl::Status SaveExpandedMessages()
absl::Status Update() override
void DrawExpandedMessageSettings()
absl::Status Paste() override
gui::Canvas current_font_gfx16_canvas_
gui::Canvas font_gfx_canvas_
absl::Status Undo() override
absl::Status Load() override
std::array< uint8_t, 0x4000 > raw_font_gfx_data_
void Initialize() override
absl::Status Cut() override
void DrawMessagePreview()
Rom expanded_message_bin_
std::vector< MessageData > list_of_texts_
gfx::SnesPalette font_preview_colors_
MessageData current_message_
MessagePreview message_preview_
gui::TextBox message_text_box_
void DrawCurrentMessage()
void DrawSpecialCharacters()
absl::Status Redo() override
gfx::Bitmap current_font_gfx16_bitmap_
gfx::Bitmap font_gfx_bitmap_
absl::Status Save() override
void QueueTextureCommand(TextureCommandType type, Bitmap *bitmap)
void Create(int width, int height, int depth, std::span< uint8_t > data)
Create a bitmap with the given dimensions and data.
SnesPalette * mutable_palette()
void set_data(const std::vector< uint8_t > &data)
void SetPalette(const SnesPalette &palette)
Set the palette for the bitmap.
SDL_Surface * surface() const
RAII timer for automatic timing management.
void DrawBitmap(Bitmap &bitmap, int border_offset, float scale)
bool DrawTileSelector(int size, int size_y=0)
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0))
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
Draggable, dockable card for editor sub-windows.
bool Begin(bool *p_open=nullptr)
void SetDefaultSize(float width, float height)
static std::string ShowOpenFileDialog()
ShowOpenFileDialog opens a file dialog and returns the selected filepath. Uses global feature flag to...
#define ICON_MD_FONT_DOWNLOAD
#define LOG_DEBUG(category, format,...)
#define LOG_ERROR(category, format,...)
#define LOG_WARN(category, format,...)
#define LOG_INFO(category, format,...)
#define PRINT_IF_ERROR(expression)
#define RETURN_IF_ERROR(expression)
std::string DisplayTextOverflowError(int pos, bool bank)
constexpr int kCharactersWidth
std::vector< MessageData > ReadAllTextData(uint8_t *rom, int pos)
absl::Status LoadExpandedMessages(std::string &expanded_message_path, std::vector< std::string > &parsed_messages, std::vector< MessageData > &expanded_messages, std::vector< DictionaryEntry > &dictionary)
constexpr int kCurrentMessageWidth
constexpr int kCurrentMessageHeight
constexpr uint8_t kBlockTerminator
constexpr int kFontGfxMessageSize
std::vector< std::string > ParseMessageData(std::vector< MessageData > &message_data, const std::vector< DictionaryEntry > &dictionary_entries)
constexpr uint8_t kMessageTerminator
constexpr int kFontGfxMessageDepth
constexpr int kTextData2End
std::vector< DictionaryEntry > BuildDictionaryEntries(Rom *rom)
std::vector< uint8_t > ParseMessageToData(std::string str)
constexpr uint8_t kWidthArraySize
constexpr ImGuiTableFlags kMessageTableFlags
constexpr int kTextDataEnd
std::vector< uint8_t > SnesTo8bppSheet(std::span< uint8_t > sheet, int bpp, int num_sheets)
void EndCanvas(Canvas &canvas)
void BeginCanvas(Canvas &canvas, ImVec2 child_size)
void MemoryEditorPopup(const std::string &label, std::span< uint8_t > memory)
IMGUI_API bool DisplayPalette(gfx::SnesPalette &palette, bool loaded)
bool InputHexByte(const char *label, uint8_t *data, float input_width, bool no_step)
std::string HexWord(uint16_t word, HexStringParams params)
std::string HexLong(uint32_t dword, HexStringParams params)
Main namespace for the application.
absl::StatusOr< gfx::Bitmap > LoadFontGraphics(const Rom &rom)
PopupManager * popup_manager
EditorCardRegistry * card_registry
std::vector< uint8_t > Data
std::vector< uint8_t > current_preview_data_
void DrawMessagePreview(const MessageData &message)
std::array< uint8_t, kWidthArraySize > width_array
std::vector< uint8_t > font_gfx16_data_2_
std::vector< uint8_t > font_gfx16_data_
std::vector< DictionaryEntry > all_dictionaries_