4#include <unordered_map>
7#include "absl/status/status.h"
8#include "absl/strings/str_format.h"
9#include "absl/strings/str_replace.h"
25using ImGui::BeginChild;
26using ImGui::BeginTable;
30using ImGui::InputText;
31using ImGui::InputTextMultiline;
33using ImGui::Separator;
34using ImGui::TableHeadersRow;
35using ImGui::TableNextColumn;
36using ImGui::TableSetupColumn;
38using ImGui::TextWrapped;
41 ImGuiTableFlags_Borders |
42 ImGuiTableFlags_Resizable;
45 ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable;
60 std::vector<uint8_t> data(0x4000, 0);
61 for (
int i = 0; i < 0x4000; i++) {
90 std::cout <<
"Message #" << each_message.ID <<
" at address "
92 std::cout <<
" " << each_message.RawString << std::endl;
96 std::string parsed_message =
"";
97 for (
const auto&
byte : each_message.Data) {
99 if (CharEncoder.contains(
byte)) {
100 parsed_message.push_back(CharEncoder.at(
byte));
107 parsed_message.append(dictionaryEntry.Contents);
111 if (!textElement.
Empty()) {
115 parsed_message.append(
"\n");
122 std::cout <<
" > " << parsed_message << std::endl;
128 return absl::OkStatus();
139 TableSetupColumn(
"List");
140 TableSetupColumn(
"Contents");
141 TableSetupColumn(
"Commands");
142 TableSetupColumn(
"Dictionary");
161 return absl::OkStatus();
169 if (BeginChild(
"##MessagesList", ImVec2(0, 0),
true,
170 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
172 TableSetupColumn(
"ID");
173 TableSetupColumn(
"Contents");
174 TableSetupColumn(
"Data");
200 if (InputTextMultiline(
"##MessageEditor",
202 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
208 Text(
"Font Graphics");
210 BeginChild(
"MessageEditorCanvas", ImVec2(0, 130));
220 Text(
"Message Preview");
221 if (Button(
"Refresh Bitmap")) {
225 BeginChild(
"CurrentGfxFont", ImVec2(0, 0),
true,
226 ImGuiWindowFlags_AlwaysVerticalScrollbar);
237 if (BeginChild(
"##TextCommands", ImVec2(0, 0),
true,
238 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
239 for (
const auto& text_element : TextCommands) {
240 if (Button(text_element.GenericToken.c_str())) {
243 TextWrapped(
"%s", text_element.Description.c_str());
251 if (ImGui::BeginChild(
"##DictionaryChild", ImVec2(0, 0),
true,
252 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
254 TableSetupColumn(
"ID");
255 TableSetupColumn(
"Contents");
261 Text(
"%s", dictionary.Contents.c_str());
276 std::vector<uint8_t> raw_message;
277 std::vector<uint8_t> parsed_message;
279 std::string current_raw_message;
280 std::string current_parsed_message;
282 uint8_t current_byte = 0;
283 while (current_byte != 0xFF) {
284 current_byte =
rom()->data()[pos++];
287 MessageData(message_id++, pos, current_raw_message, raw_message,
288 current_parsed_message, parsed_message);
293 parsed_message.clear();
294 current_raw_message.clear();
295 current_parsed_message.clear();
300 raw_message.push_back(current_byte);
304 if (!text_element.
Empty()) {
305 parsed_message.push_back(current_byte);
307 current_byte =
rom()->data()[pos++];
308 raw_message.push_back(current_byte);
309 parsed_message.push_back(current_byte);
312 current_raw_message.append(
314 current_parsed_message.append(
326 if (!text_element.
Empty()) {
329 parsed_message.push_back(current_byte);
335 if (dictionary >= 0) {
336 current_raw_message.append(
"[");
338 current_raw_message.append(
":");
340 current_raw_message.append(
"]");
347 for (uint32_t i = address; i < address_end; i++) {
348 parsed_message.push_back(
rom()->data()[i]);
356 if (CharEncoder.contains(current_byte)) {
357 std::string str =
"";
358 str.push_back(CharEncoder.at(current_byte));
359 current_raw_message.append(str);
360 current_parsed_message.append(str);
361 parsed_message.push_back(current_byte);
369 uint8_t current_byte;
370 std::vector<uint8_t> temp_bytes_raw;
371 std::vector<uint8_t> temp_bytes_parsed;
373 std::string current_message_raw;
374 std::string current_message_parsed;
378 current_byte =
rom()->data()[pos++];
382 MessageData(message_id++, pos, current_message_raw, temp_bytes_raw,
383 current_message_parsed, temp_bytes_parsed);
387 temp_bytes_raw.clear();
388 temp_bytes_parsed.clear();
389 current_message_raw.clear();
390 current_message_parsed.clear();
393 }
else if (current_byte == 0xFF) {
397 temp_bytes_raw.push_back(current_byte);
402 if (!text_element.
Empty()) {
403 temp_bytes_parsed.push_back(current_byte);
405 current_byte =
rom()->data()[pos++];
406 temp_bytes_raw.push_back(current_byte);
407 temp_bytes_parsed.push_back(current_byte);
410 current_message_raw.append(
412 current_message_parsed.append(
424 if (!text_element.
Empty()) {
427 temp_bytes_parsed.push_back(current_byte);
434 if (dictionary >= 0) {
435 current_message_raw.append(
"[");
437 current_message_raw.append(
":");
439 current_message_raw.append(
"]");
446 for (uint32_t i = address; i < address_end; i++) {
447 temp_bytes_parsed.push_back(
rom()->data()[i]);
455 if (CharEncoder.contains(current_byte)) {
456 std::string str =
"";
457 str.push_back(CharEncoder.at(current_byte));
458 current_message_raw.append(str);
459 current_message_parsed.append(str);
460 temp_bytes_parsed.push_back(current_byte);
466 std::vector<DictionaryEntry> dictionary) {
467 std::string temp = str;
468 for (
const auto& entry : dictionary) {
469 if (absl::StrContains(temp, entry.Contents)) {
470 temp = absl::StrReplaceAll(temp, {{entry.Contents, entry.Contents}});
484 int sizex,
int sizey) {
485 const int num_x_tiles = 16;
486 const int img_width = 512;
487 int draw_id = srcx + (srcy * 32);
488 for (
int yl = 0; yl < sizey * 8; yl++) {
489 for (
int xl = 0; xl < 4; xl++) {
495 int tx = ((draw_id / num_x_tiles) * img_width) +
496 ((draw_id - ((draw_id / 16) * 16)) * 4);
501 int index = x + (y * 172) + (mx * 2) + (my * 172);
502 if ((pixel & 0x0F) != 0) {
504 (uint8_t)((pixel & 0x0F) + (0 * 4));
507 if (((pixel >> 4) & 0x0F) != 0) {
509 (uint8_t)(((pixel >> 4) & 0x0F) + (0 * 4));
516 for (
const auto c : str) {
526 for (
const uint8_t& value : text) {
533 int srcy = value / 16;
534 int srcx = value - (value & (~0xF));
543 }
else if (value ==
kLine1) {
549 }
else if (value ==
kLine2) {
552 }
else if (value ==
kLine3) {
555 }
else if (value == 0x6B || value == 0x6D || value == 0x6E ||
556 value == 0x77 || value == 0x78 || value == 0x79 ||
561 }
else if (value == 0x6C)
567 }
else if (value == 0x6A) {
581 for (
int i = 0; i < (172 * 4096); i++) {
595 return absl::OkStatus();
600 if (ImGui::GetClipboardText() !=
nullptr) {
604 return absl::OkStatus();
613 return absl::OkStatus();
625 return absl::OkStatus();
629 std::vector<uint8_t> backup =
rom()->vector();
631 for (
int i = 0; i < 100; i++) {
636 bool in_second_bank =
false;
639 for (
const auto value : message.Data) {
651 in_second_bank =
true;
670 return absl::OkStatus();
675 std::string bankSTR = bank ?
"1st" :
"2nd";
677 bank ? absl::StrFormat(
"%X4", pos & 0xFFFF)
678 : absl::StrFormat(
"%X4", (pos -
kTextData2) & 0xFFFF);
679 std::string message = absl::StrFormat(
680 "There is too much text data in the %s block to save.\n"
681 "Available: %X4 | Used: %s",
682 bankSTR, space, posSTR);
void UpdateBitmap(gfx::Bitmap *bitmap)
Used to update a bitmap on the screen.
static Renderer & GetInstance()
DictionaryEntry GetDictionaryFromID(uint8_t value)
gui::Canvas font_gfx_canvas_
void DrawTileToPreview(int x, int y, int srcx, int srcy, int pal, int sizex=1, int sizey=1)
void DrawCurrentMessage()
absl::Status Paste() override
std::string DisplayTextOverflowError(int pos, bool bank)
std::vector< std::string > parsed_messages_
void DrawCharacterToPreview(char c)
std::vector< uint8_t > current_font_gfx16_data_
absl::Status Copy() override
MessageData current_message_
TextBox message_text_box_
void DrawMessagePreview()
absl::Status Cut() override
gfx::Bitmap font_gfx_bitmap_
gfx::SnesPalette font_preview_colors_
gfx::Bitmap current_font_gfx16_bitmap_
absl::Status Update() override
absl::Status Initialize()
std::vector< MessageData > list_of_texts_
std::vector< uint8_t > font_gfx16_data_
gui::Canvas current_font_gfx16_canvas_
std::vector< DictionaryEntry > all_dictionaries_
void DrawStringToPreview(std::string str)
uint8_t width_array[kWidthArraySize]
absl::Status Undo() override
Represents a palette of colors for the Super Nintendo Entertainment System (SNES).
void AddColor(const SnesColor &color)
auto mutable_color(int i)
void DrawBackground(ImVec2 canvas_size=ImVec2(0, 0), bool drag=false)
void DrawGrid(float grid_step=64.0f, int tile_id_offset=8)
void DrawBitmap(const Bitmap &bitmap, int border_offset=0, bool ready=true)
void DrawContextMenu(gfx::Bitmap *bitmap=nullptr)
#define RETURN_IF_ERROR(expression)
uint32_t Get24LocalFromPC(uint8_t *data, int addr, bool pc)
std::string UppercaseHexLong(uint32_t dword)
std::string UppercaseHexWord(uint16_t word, bool leading)
const std::string DICTIONARYTOKEN
uint8_t FindDictionaryEntry(uint8_t value)
constexpr uint8_t DICTOFF
constexpr int kPointersDictionaries
constexpr int kTextDataEnd
constexpr int kCurrentMessageHeight
constexpr int kFontGfxMessageDepth
std::vector< DictionaryEntry > BuildDictionaryEntries(app::Rom *rom)
constexpr int kFontGfxMessageSize
constexpr uint8_t kWidthArraySize
const uint8_t kMessageTerminator
const std::string BANKToken
constexpr ImGuiTableFlags kDictTableFlags
uint8_t FindMatchingCharacter(char value)
constexpr int kCurrentMessageWidth
TextElement FindMatchingSpecial(uint8_t value)
constexpr ImGuiTableFlags kMessageTableFlags
constexpr int kTextData2End
constexpr uint8_t kBlockTerminator
TextElement FindMatchingCommand(uint8_t b)
constexpr int kCharactersWidth
std::vector< uint8_t > ParseMessageToData(std::string str)
std::string ParseTextDataByte(uint8_t value)
constexpr uint8_t kScrollVertical
std::string ReplaceAllDictionaryWords(std::string str, std::vector< DictionaryEntry > dictionary)
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
std::vector< uint8_t > Data
std::string GetParameterizedToken(uint8_t value=0)