|
|
@@ -2,11 +2,17 @@
|
|
|
#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
|
|
|
{
|
|
|
@@ -23,7 +29,7 @@ namespace
|
|
|
}
|
|
|
|
|
|
Textbox::Textbox(Font fnt)
|
|
|
-: fnt(fnt), buffer(), buffer_index(0), current_color(0, 0, 0), letter_wait(0), letter_wait_cooldown(10)
|
|
|
+: fnt(fnt), buffer(0), buffer_index(-1), current_color(0, 0, 0), letter_wait(0), letter_wait_cooldown(10), dimensions(40, 4, 200, 32), state(Waiting), global_string_offset(0)
|
|
|
{
|
|
|
}
|
|
|
|
|
|
@@ -35,7 +41,15 @@ void Textbox::set_text(char *new_text)
|
|
|
{
|
|
|
letter_wait = 0;
|
|
|
letter_wait_cooldown = 10;
|
|
|
- buffer_index = 0;
|
|
|
+ buffer_index = -1;
|
|
|
+ global_string_offset = 0;
|
|
|
+ nb_line_to_update = 0;
|
|
|
+ for (int i = 0; i < nb_lines; ++i)
|
|
|
+ {
|
|
|
+ line_nb_characters[i] = 0;
|
|
|
+ line_widths[i] = 0;
|
|
|
+ }
|
|
|
+
|
|
|
buffer.clear();
|
|
|
for (size_t i = 0; i < strlen_tokens(new_text); ++i)
|
|
|
{
|
|
|
@@ -48,7 +62,6 @@ void Textbox::set_text(char *new_text)
|
|
|
t.arg2 = new_text[i+3];
|
|
|
t.arg3 = new_text[i+4];
|
|
|
i += COMMAND_LEGNTH;
|
|
|
- // printf("t.routine : %02x\n", t.routine);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
@@ -57,24 +70,21 @@ void Textbox::set_text(char *new_text)
|
|
|
t.arg1 = 0;
|
|
|
t.arg2 = 0;
|
|
|
t.arg3 = 0;
|
|
|
- // printf("t.c : %c\n", t.c);
|
|
|
}
|
|
|
buffer.push_back(t);
|
|
|
}
|
|
|
-}
|
|
|
+ state = Updating;
|
|
|
+ add_letter(1);
|
|
|
|
|
|
+}
|
|
|
|
|
|
-void Textbox::update(unsigned dt)
|
|
|
+void Textbox::add_letter(unsigned nb_letters)
|
|
|
{
|
|
|
- if(buffer_index >= buffer.size())
|
|
|
- return;
|
|
|
- letter_wait -= dt;
|
|
|
- if(letter_wait <= 0)
|
|
|
+ if(state != Updating) return;
|
|
|
+ if(buffer.size() <= 0) return;
|
|
|
+ for(unsigned i = 0; (i < nb_letters) && (buffer_index < 0 || buffer_index < buffer.size() - 1); ++i)
|
|
|
{
|
|
|
- unsigned add = (-letter_wait)/letter_wait_cooldown + 1;
|
|
|
- buffer_index = (buffer_index+add < buffer.size()? buffer_index+add : buffer.size());
|
|
|
- letter_wait = letter_wait_cooldown;
|
|
|
-
|
|
|
+ ++buffer_index;
|
|
|
if(buffer[buffer_index].c == MAGIC_TOKEN)
|
|
|
{
|
|
|
switch(buffer[buffer_index].routine)
|
|
|
@@ -84,40 +94,127 @@ void Textbox::update(unsigned dt)
|
|
|
letter_wait = buffer[buffer_index].arg1;
|
|
|
break;
|
|
|
}
|
|
|
- buffer_index++;
|
|
|
+ line_nb_characters[nb_line_to_update]++;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ CharacterParameters& p = fnt.chars[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 >= buffer.size()-1){
|
|
|
+ state = Done;
|
|
|
+ }
|
|
|
+ letter_wait = letter_wait_cooldown;
|
|
|
}
|
|
|
|
|
|
-void Textbox::render(unsigned dt)
|
|
|
+void Textbox::update(unsigned dt)
|
|
|
{
|
|
|
- unsigned cur_x = 0;
|
|
|
- unsigned cur_y = 0;
|
|
|
- current_color = 0xFFFF;
|
|
|
-
|
|
|
- for (unsigned i = 0; i < buffer_index; ++i)
|
|
|
+ switch(state)
|
|
|
{
|
|
|
- char c = buffer[i].c;
|
|
|
- if( c == MAGIC_TOKEN) {
|
|
|
- switch(buffer[i].routine)
|
|
|
+ case Waiting:
|
|
|
+ return;
|
|
|
+ break;
|
|
|
+ case Updating:
|
|
|
+ if((buffer_index >= 0) && (buffer_index >= buffer.size()))
|
|
|
+ return;
|
|
|
+ letter_wait -= dt;
|
|
|
+ if(letter_wait <= 0)
|
|
|
{
|
|
|
- // Change current color
|
|
|
- case 0x01:
|
|
|
- current_color = ((buffer[i].arg1<<8) + buffer[i].arg2);
|
|
|
- break;
|
|
|
+ unsigned add = (-letter_wait)/letter_wait_cooldown + 1;
|
|
|
+ add_letter(add);
|
|
|
}
|
|
|
- continue;
|
|
|
- }
|
|
|
+ break;
|
|
|
+ case Full:
|
|
|
+ if(key_pressed(Key::K_A))
|
|
|
+ {
|
|
|
+ for(int 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];
|
|
|
|
|
|
- if(fnt.chars[c].dimensions.width + cur_x > 320)
|
|
|
+ for (int i = 1; i < nb_lines; ++i)
|
|
|
+ {
|
|
|
+ line_widths[i] = 0;
|
|
|
+ line_nb_characters[i] = 0;
|
|
|
+ }
|
|
|
+ nb_line_to_update = 1;
|
|
|
+ state = Updating;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void Textbox::render(unsigned dt)
|
|
|
+{
|
|
|
+ if(buffer_index < 0) return;
|
|
|
+ current_color = 0xFFFF;
|
|
|
+ put_rectangle(dimensions, Graphics::DarkGray);
|
|
|
+ // signed cur_x_max = cur_x + dimensions.width;
|
|
|
+ unsigned global_index = global_string_offset;
|
|
|
+ for(unsigned l = 0; l < nb_lines; l++)
|
|
|
{
|
|
|
- cur_x = 0;
|
|
|
- cur_y += fnt.baseline;
|
|
|
+ unsigned cur_x = dimensions.x;
|
|
|
+ unsigned cur_y = dimensions.y + l*fnt.baseline;
|
|
|
+ for (int 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[c].dimensions.width + 1;
|
|
|
+ }
|
|
|
+ global_index += line_nb_characters[l];
|
|
|
}
|
|
|
- fnt.draw(cur_x, cur_y, c, current_color);
|
|
|
- if(c == ' ')
|
|
|
- cur_x += fnt.space_width;
|
|
|
- else
|
|
|
- cur_x += fnt.chars[(unsigned char)c].dimensions.width + 1;
|
|
|
+ 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);
|
|
|
}
|
|
|
}
|