瀏覽代碼

Working and fixed bugs. Hurray for Psyduck! :D

Eiyeron Fulmincendii 9 年之前
父節點
當前提交
0344abb9cc
共有 7 個文件被更改,包括 323 次插入12 次删除
  1. 二進制
      data/out.wrf
  2. 1 1
      src/engine/StateMachine.cpp
  3. 35 9
      src/map/StateMap.cpp
  4. 6 1
      src/map/StateMap.h
  5. 1 1
      src/render/Font.cpp
  6. 220 0
      src/textbox/Textbox.cpp
  7. 60 0
      src/textbox/Textbox.h

二進制
data/out.wrf


+ 1 - 1
src/engine/StateMachine.cpp

@@ -101,7 +101,7 @@ void StateMachine::run()
             stack.back()->render(100 * frame_time / TIMER_FREQ);
             last_frame = frame_stamp;
 
-            Text::print_format(0, 0, "WRPG build %s", git_version);
+            // Text::print_format(0, 0, "WRPG build %s", git_version);
             if (frame_time != 0 && update_time != 0)
             {
                 Text::print_format(0, 240 - 8, "%ufps, %uups", TIMER_FREQ / frame_time,

+ 35 - 9
src/map/StateMap.cpp

@@ -1,9 +1,9 @@
 #include "StateMap.h"
 #include "Graphics.h"
+#include "input/Input.h"
 #include "render/Text.h"
 #include "piaf/Archive.h"
 
-
 using WalrusRPG::States::StateMap;
 using namespace WalrusRPG;
 using namespace WalrusRPG::Graphics;
@@ -11,7 +11,10 @@ using WalrusRPG::Utils::Rect;
 using WalrusRPG::PIAF::Archive;
 using WalrusRPG::PIAF::File;
 using WalrusRPG::Graphics::Texture;
+using namespace WalrusRPG::Input;
+using WalrusRPG::Input::Key;
 using WalrusRPG::Graphics::Font;
+using WalrusRPG::Textbox;
 
 namespace
 {
@@ -32,21 +35,44 @@ 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"))
+    : 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);
+    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);
-
-    print_debug_camera_data(camera, txt);
-    print_debug_map_data(map, txt);
+    // map.render(camera, dt);
+    fill(Black);
+    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});
+    // print_debug_camera_data(camera, txt);
+    // print_debug_map_data(map, txt);
 }

+ 6 - 1
src/map/StateMap.h

@@ -5,6 +5,8 @@
 #include "piaf/Archive.h"
 #include "Map.h"
 #include "render/Font.h"
+#include "render/Animator.h"
+#include "textbox/Textbox.h"
 
 namespace WalrusRPG
 {
@@ -13,12 +15,15 @@ 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);
             void render(unsigned dt);

+ 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.

+ 220 - 0
src/textbox/Textbox.cpp

@@ -0,0 +1,220 @@
+#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
+{
+	size_t strlen_tokens(const char *str)
+	{
+		size_t len = 0;
+		for(;str[len];++len)
+		{
+			if(str[len] == MAGIC_TOKEN)
+				len +=4;
+		}
+		return len;
+	}
+}
+
+Textbox::Textbox(Font fnt)
+: 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)
+{
+}
+
+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 (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)
+	{
+		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;
+	add_letter(1);
+
+}
+
+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 < 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[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::update(unsigned dt)
+{
+	switch(state)
+	{
+		case Waiting:
+		return;
+		break;
+		case Updating:
+			if((buffer_index >= 0) && (buffer_index >= 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(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];
+
+				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++)
+		{
+			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];
+		}
+	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);
+	}
+}

+ 60 - 0
src/textbox/Textbox.h

@@ -0,0 +1,60 @@
+#ifndef INCLUDE_TEXTBOX_H
+#define INCLUDE_TEXTBOX_H
+
+#include "Graphics.h"
+#include "render/Font.h"
+#include "render/SpriteRenderer.h"
+#include "utility/Rect.h"
+#include "TINYSTL/vector.h"
+
+namespace WalrusRPG
+{
+	constexpr char MAGIC_TOKEN = '\xFF';
+	constexpr unsigned COMMAND_LEGNTH = 4;
+	
+	struct TextboxChar
+	{
+		char c;
+		uint8_t routine;
+		uint8_t arg1;
+		uint8_t arg2;
+		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;
+		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();
+		
+		void set_text(char *new_msg);
+
+		void update(unsigned dt);
+		void render(unsigned dt);
+	};
+}
+#endif