4#include <unordered_map>
7#include "absl/status/status.h"
8#include "absl/strings/str_cat.h"
9#include "absl/strings/str_format.h"
10#include "absl/strings/str_replace.h"
19#include "imgui/misc/cpp/imgui_stdlib.h"
27using ImGui::BeginChild;
28using ImGui::BeginTable;
32using ImGui::InputTextMultiline;
34using ImGui::Separator;
35using ImGui::TableHeadersRow;
36using ImGui::TableNextColumn;
37using ImGui::TableSetupColumn;
39using ImGui::TextWrapped;
42 ImGuiTableFlags_Borders |
43 ImGuiTableFlags_Resizable;
58 std::vector<uint8_t> data(0x4000, 0);
59 for (
int i = 0; i < 0x4000; i++) {
97 TableSetupColumn(
"List");
98 TableSetupColumn(
"Contents");
99 TableSetupColumn(
"Commands");
100 TableSetupColumn(
"Dictionary");
121 return absl::OkStatus();
125 if (BeginChild(
"##MessagesList", ImVec2(0, 0),
true,
126 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
128 TableSetupColumn(
"ID");
129 TableSetupColumn(
"Contents");
130 TableSetupColumn(
"Data");
153 if (!
rom()->is_loaded()) {
157 if (InputTextMultiline(
"##MessageEditor",
159 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
165 Text(
"Font Graphics");
167 BeginChild(
"MessageEditorCanvas", ImVec2(0, 130));
177 Text(
"Message Preview");
178 if (Button(
"Create Preview")) {
181 if (Button(
"Refresh Bitmap")) {
185 if (Button(
"View Palette")) {
186 ImGui::OpenPopup(
"Palette");
188 if (ImGui::BeginPopup(
"Palette")) {
194 true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
205 ImGui::BeginChild(
"##TextCommands",
206 ImVec2(0, ImGui::GetWindowContentRegionMax().y / 2),
true,
207 ImGuiWindowFlags_AlwaysVerticalScrollbar);
208 for (
const auto& text_element : TextCommands) {
209 if (Button(text_element.GenericToken.c_str())) {
213 TextWrapped(
"%s", text_element.Description.c_str());
220 ImGui::BeginChild(
"##SpecialChars",
221 ImVec2(0, ImGui::GetWindowContentRegionMax().y / 2),
true,
222 ImGuiWindowFlags_AlwaysVerticalScrollbar);
223 for (
const auto& text_element : SpecialChars) {
224 if (Button(text_element.GenericToken.c_str())) {
236 if (ImGui::BeginChild(
"##DictionaryChild",
237 ImVec2(200, ImGui::GetWindowContentRegionMax().y / 2),
238 true, ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
240 TableSetupColumn(
"ID");
241 TableSetupColumn(
"Contents");
247 Text(
"%s", dictionary.Contents.c_str());
256 ImGui::Text(
"Import Messages");
259 static char import_path[256] =
"";
260 ImGui::InputText(
"Import File", import_path,
sizeof(import_path));
262 if (ImGui::Button(
"Import")) {
268 ImGui::Text(
"Export Messages");
271 static char export_path[256] =
"";
272 ImGui::InputText(
"Export File", export_path,
sizeof(export_path));
274 if (ImGui::Button(
"Export")) {
280 int sizex,
int sizey) {
281 const int num_x_tiles = 16;
282 const int img_width = 512;
283 int draw_id = srcx + (srcy * 32);
284 for (
int yl = 0; yl < sizey * 8; yl++) {
285 for (
int xl = 0; xl < 4; xl++) {
291 int tx = ((draw_id / num_x_tiles) * img_width) +
292 ((draw_id - ((draw_id / 16) * 16)) * 4);
297 int index = x + (y * 172) + (mx * 2) + (my * 172);
298 if ((pixel & 0x0F) != 0) {
300 (uint8_t)((pixel & 0x0F) + (0 * 4));
303 if (((pixel >> 4) & 0x0F) != 0) {
305 (uint8_t)(((pixel >> 4) & 0x0F) + (0 * 4));
312 for (
const auto c : str) {
322 for (
const uint8_t& value : text) {
329 int srcy = value / 16;
330 int srcx = value - (value & (~0xF));
339 }
else if (value ==
kLine1) {
345 }
else if (value ==
kLine2) {
348 }
else if (value ==
kLine3) {
351 }
else if (value == 0x6B || value == 0x6D || value == 0x6E ||
352 value == 0x77 || value == 0x78 || value == 0x79 ||
357 }
else if (value == 0x6C)
363 }
else if (value == 0x6A) {
371 std::cerr <<
"Invalid dictionary entry: " << pos << std::endl;
395 std::vector<uint8_t> backup =
rom()->
vector();
402 bool in_second_bank =
false;
405 for (
const auto value : message.Data) {
417 in_second_bank =
true;
435 return absl::OkStatus();
440 std::string bankSTR = bank ?
"1st" :
"2nd";
442 bank ? absl::StrFormat(
"%X4", pos & 0xFFFF)
443 : absl::StrFormat(
"%X4", (pos -
kTextData2) & 0xFFFF);
444 std::string message = absl::StrFormat(
445 "There is too much text data in the %s block to save.\n"
446 "Available: %X4 | Used: %s",
447 bankSTR, space, posSTR);
457 return absl::OkStatus();
462 if (ImGui::GetClipboardText() !=
nullptr) {
466 return absl::OkStatus();
475 return absl::OkStatus();
487 return absl::OkStatus();
493 return absl::OkStatus();
516 if (ImGui::Begin(
"Find Text",
nullptr, ImGuiWindowFlags_AlwaysAutoResize)) {
517 static char find_text[256] =
"";
518 ImGui::InputText(
"Search", find_text, IM_ARRAYSIZE(find_text));
520 if (ImGui::Button(
"Find Next")) {
525 if (ImGui::Button(
"Find All")) {
530 if (ImGui::Button(
"Replace")) {
540 return absl::OkStatus();
545 std::ifstream file(path);
546 if (!file.is_open()) {
547 return absl::NotFoundError(
"Failed to open file");
554 while (std::getline(file, line)) {
558 if (line.empty() || line[0] ==
'#') {
564 size_t equal_pos = line.find(
'=');
565 if (equal_pos == std::string::npos) {
566 return absl::InvalidArgumentError(
567 absl::StrFormat(
"Invalid format at line %d", line_number));
570 std::string id_str = line.substr(0, equal_pos);
571 std::string content = line.substr(equal_pos + 1);
575 if (!absl::SimpleAtoi(id_str, &
id)) {
576 return absl::InvalidArgumentError(
577 absl::StrFormat(
"Invalid ID at line %d", line_number));
582 if (message.ID ==
id) {
583 message.ContentsParsed = content;
590 return absl::OkStatus();
595 std::ofstream file(path);
596 if (!file.is_open()) {
597 return absl::NotFoundError(
"Failed to open file");
601 file <<
"# Message Export\n";
602 file <<
"# Format: ID=content\n\n";
606 file << absl::StrFormat(
"%d=%s\n", message.ID, message.ContentsParsed);
609 return absl::OkStatus();
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.
void RenderBitmap(gfx::Bitmap *bitmap)
Used to render a bitmap to the screen.
std::vector< std::string > parsed_messages_
absl::Status Copy() override
absl::Status Find() override
absl::Status Update() override
std::array< uint8_t, kWidthArraySize > width_array
absl::Status Paste() override
std::string DisplayTextOverflowError(int pos, bool bank)
gui::Canvas current_font_gfx16_canvas_
gui::Canvas font_gfx_canvas_
void DrawCharacterToPreview(char c)
void DrawStringToPreview(std::string str)
absl::Status Undo() override
absl::Status Load() override
void DrawTileToPreview(int x, int y, int srcx, int srcy, int pal, int sizex=1, int sizey=1)
absl::Status ExportMessagesToFile(const std::string &filename)
void Initialize() override
absl::Status Cut() override
void DrawMessagePreview()
std::vector< MessageData > list_of_texts_
std::vector< uint8_t > font_gfx16_data_
std::vector< uint8_t > current_font_gfx16_data_
gfx::SnesPalette font_preview_colors_
MessageData current_message_
gui::TextBox message_text_box_
void DrawCurrentMessage()
void DrawSpecialCharacters()
absl::Status Redo() override
std::vector< DictionaryEntry > all_dictionaries_
gfx::Bitmap current_font_gfx16_bitmap_
gfx::Bitmap font_gfx_bitmap_
absl::Status Save() override
absl::Status ImportMessagesFromFile(const std::string &filename)
static Renderer & GetInstance()
#define RETURN_IF_ERROR(expression)
#define CLEAR_AND_RETURN_STATUS(status)
Editors are the view controllers for the application.
constexpr int kCharactersWidth
uint8_t FindMatchingCharacter(char value)
const uint8_t kMessageTerminator
constexpr uint8_t kScrollVertical
constexpr int kFontGfx16Size
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 int kFontGfxMessageDepth
void ReadAllTextData(Rom *rom, std::vector< MessageData > &list_of_texts_)
constexpr int kTextData2End
std::vector< DictionaryEntry > BuildDictionaryEntries(Rom *rom)
std::vector< uint8_t > ParseMessageToData(std::string str)
constexpr uint8_t kWidthArraySize
constexpr uint8_t DICTOFF
constexpr ImGuiTableFlags kMessageTableFlags
constexpr int kTextDataEnd
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
absl::Status DisplayPalette(gfx::SnesPalette &palette, bool loaded)
std::string HexWord(uint16_t word, HexStringParams params)
std::string HexLong(uint32_t dword, HexStringParams params)
Main namespace for the application.