Eiyeron Fulmincendii 9 vuotta sitten
vanhempi
commit
321172e163
7 muutettua tiedostoa jossa 185 lisäystä ja 60 poistoa
  1. BIN
      data/haeccity.wrf
  2. BIN
      data/out.wrf
  3. 26 20
      src/map/StateMap.cpp
  4. 4 0
      src/map/StateMap.h
  5. 1 1
      src/render/Font.cpp
  6. 135 38
      src/textbox/Textbox.cpp
  7. 19 1
      src/textbox/Textbox.h

BIN
data/haeccity.wrf


BIN
data/out.wrf


+ 26 - 20
src/map/StateMap.cpp

@@ -35,37 +35,43 @@ namespace
 
 // TODO : We definitely need a Resource Manager
 StateMap::StateMap(int x, int y, Map &map)
-    : camera(x, y), map(map), data("data/out.wrf"), tex_haeccity(data.get("t_haeccity")),
-      txt(tex_haeccity, data.get("f_haeccity")), box(txt)
+    : started(false), camera(x, y), map(map), data("data/out.wrf"), tex_haeccity(data.get("t_haecci")),
+      txt(tex_haeccity, data.get("f_haecci")), tex_psyduck(data.get("psyduck")), box(txt)
 {
+    box.set_text((char* )"Hello world! I am ""\xFF\x01\xf0\x00\x00Howard\xFF\x01\xff\xff\x00"".\n"
+                    "\xFF\x81\x78\x00\x00"
+                    "\xFF\x81\x0a\x00\x00"
+                    "\xFF\x01\xf0\x00\x00""Howard""\xFF\x01\xff\xff\x00"" the Psyduck!\n"
+                    "How goes? I'm fine, headache-y but fine.\n"
+                    "I wonder... Heh, Let's see if it works correctly, shall we?");
+    WalrusRPG::Animation p;
+    p.stripe.push_back({0, 10});
+    p.stripe.push_back({1, 10});
+    anim.add_animation(0, p);
 }
 
 void StateMap::update(unsigned dt)
 {
-    camera.update(dt);
-    box.update(dt);
-    if(Input::key_pressed(K_A))
-    {
-        box.set_text((char* )"Hello world!, I am "
-                        "\xFF\x01\xf0\x00\x00"
-                        "Howard"
-                        "\xFF\x01\xff\xff\x00"
-                        ". "
-                        "\xFF\x81\x3c\x00\x00"
-                        "\xFF\x81\x0a\x00\x00"
-                        "\xFF\x01\xf0\x00\x00"
-                        "Howard"
-                        "\xFF\x01\xff\xff\x00"
-                        " the Psyduck!");
-
+    if(!started){
+        if(key_down(K_A))
+            started = true;
+        return;
     }
+    unsigned t = dt*(key_down(K_B)?16:1);
+    camera.update(t);
+    anim.update(t);
+    box.update(t);
 }
 
 void StateMap::render(unsigned dt)
 {
-    // fill(Black);
     map.render(camera, dt);
-    box.render(dt);
     print_debug_camera_data(camera, txt);
     print_debug_map_data(map, txt);
+    if(!started) return;
+    box.render(dt);
+    if(box.state == WalrusRPG::TextboxState::Updating)
+        Graphics::put_sprite(tex_psyduck, 4, 4, {32*static_cast<signed>(anim.get_animation_frame(0)), 0, 32, 32});
+    else
+        Graphics::put_sprite(tex_psyduck, 4, 4, {0, 0, 32, 32});
 }

+ 4 - 0
src/map/StateMap.h

@@ -5,6 +5,7 @@
 #include "piaf/Archive.h"
 #include "Map.h"
 #include "render/Font.h"
+#include "render/Animator.h"
 #include "textbox/Textbox.h"
 
 namespace WalrusRPG
@@ -14,11 +15,14 @@ namespace WalrusRPG
         class StateMap : public State
         {
           protected:
+            bool started;
             Camera camera;
             Map &map;
             WalrusRPG::PIAF::Archive data;
             WalrusRPG::Graphics::Texture tex_haeccity;
+            WalrusRPG::Graphics::Texture tex_psyduck;
             WalrusRPG::Graphics::Font txt;
+            WalrusRPG::Animator anim;
             WalrusRPG::Textbox box;
           public:
             StateMap(int x, int y, Map &map);

+ 1 - 1
src/render/Font.cpp

@@ -28,7 +28,7 @@ Font::Font(Texture &font_tex, WalrusRPG::PIAF::File font_config)
         // printf("Bad checksum : %x != %x\n", expected_checksum, calculated_checksum);
     }
 
-    baseline = read_big_endian_value<uint8_t>(&ptr[12]);
+    baseline = read_big_endian_value<uint32_t>(&ptr[12]);
     space_width = read_big_endian_value<uint32_t>(&ptr[20]);
 
     // Stupid thing to accelerate a biiiit the font loading, I think.

+ 135 - 38
src/textbox/Textbox.cpp

@@ -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);
 	}
 }

+ 19 - 1
src/textbox/Textbox.h

@@ -3,6 +3,7 @@
 
 #include "Graphics.h"
 #include "render/Font.h"
+#include "utility/Rect.h"
 #include "TINYSTL/vector.h"
 
 namespace WalrusRPG
@@ -19,16 +20,33 @@ namespace WalrusRPG
 		uint8_t arg3;
 	};
 
+	enum TextboxState
+	{
+		Waiting,
+		Updating,
+		Full,
+		Done
+	};
+
 	class Textbox
 	{
+	static constexpr unsigned nb_lines = 3;
 	private:
 		Graphics::Font fnt;
 		tinystl::vector<TextboxChar> buffer;
-		unsigned buffer_index;
+		signed buffer_index;
+		unsigned global_string_offset;
+		unsigned nb_line_to_update;
+		unsigned line_nb_characters[nb_lines];
+		unsigned line_widths[nb_lines];
 		Graphics::Pixel current_color;
 		signed letter_wait;
 		signed letter_wait_cooldown;
+		Utils::Rect dimensions;
+
+		void add_letter(unsigned nb_letters);
 	public:
+		TextboxState state;
 		Textbox(Graphics::Font fnt);
 		~Textbox();