| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- #include "Textbox.h"
- #include <cstring>
- #include <cstdlib>
- #include "utility/misc.h"
- #include "input/Input.h"
- using WalrusRPG::MAGIC_TOKEN;
- using WalrusRPG::COMMAND_LEGNTH;
- using WalrusRPG::Textbox;
- using WalrusRPG::TextboxState;
- using WalrusRPG::TextboxChar;
- using WalrusRPG::Graphics::Font;
- using WalrusRPG::Graphics::CharacterParameters;
- using WalrusRPG::Graphics::Pixel;
- using WalrusRPG::Input::Key;
- namespace
- {
- signed strlen_tokens(const char *str)
- {
- signed len = 0;
- for (; str[len]; ++len)
- {
- if (str[len] == MAGIC_TOKEN)
- len += COMMAND_LEGNTH;
- }
- return len;
- }
- }
- Textbox::Textbox(Font fnt)
- : fnt(fnt), buffer(0), buffer_index(-1), global_string_offset(0),
- current_color(0, 0, 0), letter_wait(0), letter_wait_cooldown(10),
- dimensions(40, 4, 200, 32), state(Waiting)
- {
- }
- Textbox::~Textbox()
- {
- }
- void Textbox::set_text(char *new_text)
- {
- letter_wait = 0;
- letter_wait_cooldown = 10;
- buffer_index = -1;
- global_string_offset = 0;
- nb_line_to_update = 0;
- for (unsigned i = 0; i < nb_lines; ++i)
- {
- line_nb_characters[i] = 0;
- line_widths[i] = 0;
- }
- buffer.clear();
- for (signed i = 0; i < strlen_tokens(new_text); ++i)
- {
- TextboxChar t;
- if (new_text[i] == MAGIC_TOKEN)
- {
- t.c = MAGIC_TOKEN;
- t.routine = new_text[i + 1];
- t.arg1 = new_text[i + 2];
- t.arg2 = new_text[i + 3];
- t.arg3 = new_text[i + 4];
- i += COMMAND_LEGNTH;
- }
- else
- {
- t.c = new_text[i];
- t.routine = 0;
- t.arg1 = 0;
- t.arg2 = 0;
- t.arg3 = 0;
- }
- buffer.push_back(t);
- }
- state = Updating;
- }
- void Textbox::add_letter(unsigned nb_letters)
- {
- if (state != Updating)
- return;
- if (buffer.size() <= 0)
- return;
- for (unsigned i = 0;
- (i < nb_letters) &&
- (buffer_index < 0 || buffer_index < static_cast<signed>(buffer.size()) - 1);
- ++i)
- {
- ++buffer_index;
- if (buffer[buffer_index].c == MAGIC_TOKEN)
- {
- switch (buffer[buffer_index].routine)
- {
- // wait a bit
- case 0x81:
- letter_wait = buffer[buffer_index].arg1;
- break;
- }
- line_nb_characters[nb_line_to_update]++;
- }
- else
- {
- CharacterParameters &p =
- fnt.chars[static_cast<signed>(buffer[buffer_index].c)];
- TextboxChar &t = buffer[buffer_index];
- if (t.c == '\n')
- {
- if (nb_line_to_update + 1 >= nb_lines)
- {
- line_nb_characters[nb_line_to_update]++;
- // --buffer_index;
- state = Full;
- return;
- }
- nb_line_to_update++;
- }
- if (line_widths[nb_line_to_update] + p.dimensions.width + 1 >
- dimensions.width)
- {
- if (nb_line_to_update + 1 >= nb_lines)
- {
- --buffer_index;
- state = Full;
- return;
- }
- nb_line_to_update++;
- }
- if (t.c == ' ')
- line_widths[nb_line_to_update] += fnt.space_width;
- else
- line_widths[nb_line_to_update] += p.dimensions.width + 1;
- line_nb_characters[nb_line_to_update]++;
- }
- }
- if (buffer_index >= static_cast<signed>(buffer.size() - 1))
- {
- state = Done;
- }
- letter_wait = letter_wait_cooldown;
- }
- void Textbox::update(unsigned dt)
- {
- switch (state)
- {
- case Waiting:
- return;
- break;
- case Updating:
- if ((buffer_index >= 0) &&
- (buffer_index >= static_cast<signed>(buffer.size())))
- return;
- letter_wait -= dt;
- if (letter_wait <= 0)
- {
- unsigned add = (-letter_wait) / letter_wait_cooldown + 1;
- add_letter(add);
- }
- break;
- case Full:
- if (key_pressed(Key::K_A))
- {
- for (unsigned i = 0; i < nb_lines - 1; ++i)
- global_string_offset += line_nb_characters[i];
- line_widths[0] = line_widths[nb_lines - 1];
- line_nb_characters[0] = line_nb_characters[nb_lines - 1];
- for (unsigned i = 1; i < nb_lines; ++i)
- {
- line_widths[i] = 0;
- line_nb_characters[i] = 0;
- }
- nb_line_to_update = 1;
- state = Updating;
- }
- default:
- break;
- }
- }
- void Textbox::render(unsigned dt)
- {
- UNUSED(dt);
- if (buffer_index < 0)
- return;
- current_color = 0xFFFF;
- put_rectangle(dimensions, Graphics::Black);
- // signed cur_x_max = cur_x + dimensions.width;
- unsigned global_index = global_string_offset;
- for (unsigned l = 0; l < nb_lines; l++)
- {
- unsigned cur_x = dimensions.x;
- unsigned cur_y = dimensions.y + l * fnt.baseline;
- for (unsigned line_index = 0; line_index < line_nb_characters[l]; ++line_index)
- {
- TextboxChar b = buffer[global_index + line_index];
- char c = b.c;
- if (c == MAGIC_TOKEN)
- {
- switch (b.routine)
- {
- // Change current color
- case 0x01:
- current_color = ((b.arg1 << 8) + b.arg2);
- break;
- }
- continue;
- }
- fnt.draw(cur_x, cur_y, c, current_color);
- if (c == '\n')
- continue;
- else if (c == ' ')
- cur_x += fnt.space_width;
- else
- cur_x += fnt.chars[static_cast<signed>(c)].dimensions.width + 1;
- }
- global_index += line_nb_characters[l];
- }
- if (state == Full)
- {
- put_rectangle({dimensions.x + static_cast<signed>(dimensions.width),
- dimensions.y + static_cast<signed>(dimensions.height), 3, 3},
- Graphics::Red);
- }
- if (state == Done)
- {
- put_rectangle({dimensions.x + static_cast<signed>(dimensions.width),
- dimensions.y + static_cast<signed>(dimensions.height), 3, 3},
- Graphics::Blue);
- }
- }
|