4#include <unordered_map>
7#include "absl/status/status.h"
8#include "absl/strings/str_format.h"
9#include "absl/strings/str_replace.h"
18#include "imgui/misc/cpp/imgui_stdlib.h"
26using ImGui::BeginChild;
27using ImGui::BeginTable;
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++) {
87 return absl::OkStatus();
98 TableSetupColumn(
"List");
99 TableSetupColumn(
"Contents");
100 TableSetupColumn(
"Commands");
101 TableSetupColumn(
"Dictionary");
120 return absl::OkStatus();
124 if (BeginChild(
"##MessagesList", ImVec2(0, 0),
true,
125 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
127 TableSetupColumn(
"ID");
128 TableSetupColumn(
"Contents");
129 TableSetupColumn(
"Data");
154 if (InputTextMultiline(
"##MessageEditor",
156 ImVec2(ImGui::GetContentRegionAvail().x, 0))) {
162 Text(
"Font Graphics");
164 BeginChild(
"MessageEditorCanvas", ImVec2(0, 130));
174 Text(
"Message Preview");
175 if (Button(
"Refresh Bitmap")) {
179 BeginChild(
"CurrentGfxFont", ImVec2(0, 0),
true,
180 ImGuiWindowFlags_AlwaysVerticalScrollbar);
191 if (BeginChild(
"##TextCommands", ImVec2(0, 0),
true,
192 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
193 for (
const auto &text_element : TextCommands) {
194 if (Button(text_element.GenericToken.c_str())) {
197 TextWrapped(
"%s", text_element.Description.c_str());
205 if (ImGui::BeginChild(
"##DictionaryChild", ImVec2(0, 0),
true,
206 ImGuiWindowFlags_AlwaysVerticalScrollbar)) {
208 TableSetupColumn(
"ID");
209 TableSetupColumn(
"Contents");
215 Text(
"%s", dictionary.Contents.c_str());
230 std::vector<uint8_t> raw_message;
231 std::vector<uint8_t> parsed_message;
233 std::string current_raw_message;
234 std::string current_parsed_message;
236 uint8_t current_byte = 0;
237 while (current_byte != 0xFF) {
238 current_byte =
rom()->data()[pos++];
241 MessageData(message_id++, pos, current_raw_message, raw_message,
242 current_parsed_message, parsed_message));
243 std::cout <<
"Message ID: " << message_id << std::endl;
244 std::cout <<
"Raw: " << current_raw_message << std::endl;
245 std::cout <<
"Parsed: " << current_parsed_message << std::endl;
246 std::cout <<
"Raw Bytes: ";
247 for (
const auto &
byte : raw_message) {
250 std::cout << std::endl;
251 std::cout <<
"Parsed Bytes: ";
252 for (
const auto &
byte : parsed_message) {
255 std::cout << std::endl;
257 parsed_message.clear();
258 current_raw_message.clear();
259 current_parsed_message.clear();
263 raw_message.push_back(current_byte);
266 if (!text_element.
Empty()) {
267 parsed_message.push_back(current_byte);
269 current_byte =
rom()->data()[pos++];
270 raw_message.push_back(current_byte);
271 parsed_message.push_back(current_byte);
274 current_raw_message.append(text_element.
GetParamToken(current_byte));
275 current_parsed_message.append(text_element.
GetParamToken(current_byte));
286 if (!text_element.
Empty()) {
289 parsed_message.push_back(current_byte);
295 if (dictionary >= 0) {
296 current_raw_message.append(
"[");
298 current_raw_message.append(
":");
300 current_raw_message.append(
"]");
305 rom()->mutable_data(),
308 for (uint32_t i = address; i < address_end; i++) {
309 parsed_message.push_back(
rom()->data()[i]);
317 if (CharEncoder.contains(current_byte)) {
318 std::string str =
"";
319 str.push_back(CharEncoder.at(current_byte));
320 current_raw_message.append(str);
321 current_parsed_message.append(str);
322 parsed_message.push_back(current_byte);
330 uint8_t current_byte;
331 std::vector<uint8_t> temp_bytes_raw;
332 std::vector<uint8_t> temp_bytes_parsed;
334 std::string current_message_raw;
335 std::string current_message_parsed;
339 current_byte =
rom()->data()[pos++];
343 MessageData(message_id++, pos, current_message_raw, temp_bytes_raw,
344 current_message_parsed, temp_bytes_parsed);
348 temp_bytes_raw.clear();
349 temp_bytes_parsed.clear();
350 current_message_raw.clear();
351 current_message_parsed.clear();
354 }
else if (current_byte == 0xFF) {
358 temp_bytes_raw.push_back(current_byte);
363 if (!text_element.
Empty()) {
364 temp_bytes_parsed.push_back(current_byte);
366 current_byte =
rom()->data()[pos++];
367 temp_bytes_raw.push_back(current_byte);
368 temp_bytes_parsed.push_back(current_byte);
371 current_message_raw.append(text_element.
GetParamToken(current_byte));
372 current_message_parsed.append(text_element.
GetParamToken(current_byte));
383 if (!text_element.
Empty()) {
386 temp_bytes_parsed.push_back(current_byte);
393 if (dictionary >= 0) {
394 current_message_raw.append(
"[");
396 current_message_raw.append(
":");
398 current_message_raw.append(
"]");
403 rom()->mutable_data(),
406 for (uint32_t i = address; i < address_end; i++) {
407 temp_bytes_parsed.push_back(
rom()->data()[i]);
415 if (CharEncoder.contains(current_byte)) {
416 std::string str =
"";
417 str.push_back(CharEncoder.at(current_byte));
418 current_message_raw.append(str);
419 current_message_parsed.append(str);
420 temp_bytes_parsed.push_back(current_byte);
426 std::vector<DictionaryEntry> dictionary) {
427 std::string temp = str;
428 for (
const auto &entry : dictionary) {
429 if (absl::StrContains(temp, entry.Contents)) {
430 temp = absl::StrReplaceAll(temp, {{entry.Contents, entry.Contents}});
444 int sizex,
int sizey) {
445 const int num_x_tiles = 16;
446 const int img_width = 512;
447 int draw_id = srcx + (srcy * 32);
448 for (
int yl = 0; yl < sizey * 8; yl++) {
449 for (
int xl = 0; xl < 4; xl++) {
455 int tx = ((draw_id / num_x_tiles) * img_width) +
456 ((draw_id - ((draw_id / 16) * 16)) * 4);
461 int index = x + (y * 172) + (mx * 2) + (my * 172);
462 if ((pixel & 0x0F) != 0) {
464 (uint8_t)((pixel & 0x0F) + (0 * 4));
467 if (((pixel >> 4) & 0x0F) != 0) {
469 (uint8_t)(((pixel >> 4) & 0x0F) + (0 * 4));
476 for (
const auto c : str) {
486 for (
const uint8_t &value : text) {
493 int srcy = value / 16;
494 int srcx = value - (value & (~0xF));
503 }
else if (value ==
kLine1) {
509 }
else if (value ==
kLine2) {
512 }
else if (value ==
kLine3) {
515 }
else if (value == 0x6B || value == 0x6D || value == 0x6E ||
516 value == 0x77 || value == 0x78 || value == 0x79 ||
521 }
else if (value == 0x6C)
527 }
else if (value == 0x6A) {
541 for (
int i = 0; i < (172 * 4096); i++) {
555 return absl::OkStatus();
560 if (ImGui::GetClipboardText() !=
nullptr) {
564 return absl::OkStatus();
573 return absl::OkStatus();
585 return absl::OkStatus();
589 std::vector<uint8_t> backup =
rom()->vector();
596 bool in_second_bank =
false;
599 for (
const auto value : message.Data) {
611 in_second_bank =
true;
630 return absl::OkStatus();
635 std::string bankSTR = bank ?
"1st" :
"2nd";
637 bank ? absl::StrFormat(
"%X4", pos & 0xFFFF)
638 : absl::StrFormat(
"%X4", (pos -
kTextData2) & 0xFFFF);
639 std::string message = absl::StrFormat(
640 "There is too much text data in the %s block to save.\n"
641 "Available: %X4 | Used: %s",
642 bankSTR, space, posSTR);
void UpdateBitmap(gfx::Bitmap *bitmap)
Used to update a bitmap on the screen.
std::vector< std::string > parsed_messages_
absl::Status Copy() 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
void DrawTileToPreview(int x, int y, int srcx, int srcy, int pal, int sizex=1, int sizey=1)
absl::Status Cut() override
void DrawMessagePreview()
TextBox message_text_box_
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_
absl::Status Initialize()
void DrawCurrentMessage()
DictionaryEntry GetDictionaryFromID(uint8_t value)
std::vector< DictionaryEntry > all_dictionaries_
gfx::Bitmap current_font_gfx16_bitmap_
gfx::Bitmap font_gfx_bitmap_
static Renderer & GetInstance()
#define RETURN_IF_ERROR(expression)
Editors are the view controllers for the application.
constexpr int kCharactersWidth
uint8_t FindMatchingCharacter(char value)
const std::string kBankToken
const uint8_t kMessageTerminator
const std::string DICTIONARYTOKEN
constexpr uint8_t kScrollVertical
std::string ParseTextDataByte(uint8_t value)
constexpr int kCurrentMessageWidth
uint8_t FindDictionaryEntry(uint8_t value)
constexpr int kCurrentMessageHeight
constexpr uint8_t kBlockTerminator
std::string ReplaceAllDictionaryWords(std::string str, std::vector< DictionaryEntry > dictionary)
constexpr int kPointersDictionaries
constexpr int kFontGfxMessageSize
std::vector< std::string > ParseMessageData(std::vector< MessageData > &message_data, const std::vector< DictionaryEntry > &dictionary_entries)
constexpr int kFontGfxMessageDepth
constexpr int kTextData2End
std::vector< DictionaryEntry > BuildDictionaryEntries(Rom *rom)
TextElement FindMatchingSpecial(uint8_t value)
std::vector< uint8_t > ParseMessageToData(std::string str)
constexpr uint8_t kWidthArraySize
constexpr uint8_t DICTOFF
constexpr ImGuiTableFlags kMessageTableFlags
constexpr ImGuiTableFlags kDictTableFlags
TextElement FindMatchingCommand(uint8_t b)
constexpr int kTextDataEnd
std::vector< uint8_t > SnesTo8bppSheet(const std::vector< uint8_t > &sheet, int bpp, int num_sheets)
std::string HexWord(uint16_t word, HexStringParams params)
std::string HexByte(uint8_t byte, HexStringParams params)
std::string HexLong(uint32_t dword, HexStringParams params)
Main namespace for the application.
uint32_t Get24LocalFromPC(uint8_t *data, int addr, bool pc=true)
std::string GetParamToken(uint8_t value=0) const