From f28cb1f73b74bbcc14875bd12fa328e9ea9d3f98 Mon Sep 17 00:00:00 2001 From: EPICGameGuy Date: Fri, 5 Jan 2024 01:07:28 -0500 Subject: [PATCH] Added keyboard prompt object --- include/input/keyboard.hpp | 25 ++++++- .../components/transform_component.hpp | 7 ++ include/objects/text_object.hpp | 11 ++- include/objects/text_prompt.hpp | 18 +++++ src/input/keyboard.cpp | 70 ++++++++++++++++--- src/objects/movement.cc | 30 ++++---- src/objects/text_object.cc | 10 +++ src/objects/text_prompt.cc | 58 +++++++++++++++ src/world/levels/level1.cc | 7 +- 9 files changed, 208 insertions(+), 28 deletions(-) create mode 100644 include/objects/text_prompt.hpp create mode 100644 src/objects/text_prompt.cc diff --git a/include/input/keyboard.hpp b/include/input/keyboard.hpp index 9eb667e..5cc90d0 100644 --- a/include/input/keyboard.hpp +++ b/include/input/keyboard.hpp @@ -1,11 +1,34 @@ #pragma once +#include +#include + #include "libpad.h" #include "tamtypes.h" namespace Input::Keyboard { +enum class KeyStatus : uint8_t { + none = 0, + pressed = 1, + holding = 2, + released = 3, +}; + void init(); void read_inputs(); -u8 get_key_status(unsigned char key); +KeyStatus get_key_status(unsigned char ascii_key); +unsigned char convert_ascii_to_keyboard_key(unsigned char ascii_key); +unsigned char convert_keyboard_key_to_ascii(unsigned char keyboard_key); + +// Note: convert ascii keys to keyboard keys before looking up keys in the array +std::array& get_all_key_statuses(); + +// Returns true if a key has been just pressed or is held down +bool is_key_down(unsigned char key); + +// Returns true if a key has been just released or wasn't pressed +bool is_key_up(unsigned char key); + +bool is_shift_down(); } // namespace Input::Keyboard \ No newline at end of file diff --git a/include/objects/components/transform_component.hpp b/include/objects/components/transform_component.hpp index be4b804..5053fe9 100644 --- a/include/objects/components/transform_component.hpp +++ b/include/objects/components/transform_component.hpp @@ -4,6 +4,13 @@ #include +class TransformComponent; + +class RootComponentInterface +{ +public: + virtual TransformComponent* get_root_component() = 0; +}; class TransformComponent { diff --git a/include/objects/text_object.hpp b/include/objects/text_object.hpp index ec3abf8..b8fed44 100644 --- a/include/objects/text_object.hpp +++ b/include/objects/text_object.hpp @@ -3,8 +3,7 @@ #include "utils/debuggable.hpp" #include "components/transform_component.hpp" - -class TextObject: public TextRenderable, public Debuggable +class TextObject: public TextRenderable, public RootComponentInterface, public Debuggable { public: TextObject(); @@ -14,8 +13,14 @@ class TextObject: public TextRenderable, public Debuggable void draw(bool flush = false); TransformComponent transform; + virtual TransformComponent* get_root_component() override { return &transform; } + + virtual void set_text(std::string_view new_text); + std::string_view get_text() const; - std::string text; virtual const char* get_name() const override; virtual const char* get_type_name() const { return typeid(TextObject).name(); } + +protected: + std::string text; }; \ No newline at end of file diff --git a/include/objects/text_prompt.hpp b/include/objects/text_prompt.hpp new file mode 100644 index 0000000..53b1f42 --- /dev/null +++ b/include/objects/text_prompt.hpp @@ -0,0 +1,18 @@ +#pragma once +#include "objects/text_object.hpp" +#include "tick.hpp" + +class TextPrompt: public Tickable, public RootComponentInterface +{ +public: + std::string prompt; + std::string inputted_text; + + // Actual 3d text rendered + TextObject text_object; + + virtual void tick(float deltaTime) override; + virtual TransformComponent* get_root_component() override { return text_object.get_root_component(); } + + void set_prompt(std::string_view new_prompt); +}; \ No newline at end of file diff --git a/src/input/keyboard.cpp b/src/input/keyboard.cpp index 5942a62..c451cd0 100644 --- a/src/input/keyboard.cpp +++ b/src/input/keyboard.cpp @@ -7,14 +7,18 @@ #include "libkbd.h" #include "ps2kbd.h" -static u8 keyboard_status[256]; - namespace Input { -void Keyboard::init() +static std::array keyboard_status; + +std::array& Keyboard::get_all_key_statuses() { + return keyboard_status; +} - memset(keyboard_status, sizeof(keyboard_status), 0); +void Keyboard::init() +{ + memset(keyboard_status.data(), sizeof(keyboard_status), 0); { int ret = SifLoadModule("ps2kbd.irx"_p.to_full_filepath(), 0, nullptr); @@ -29,24 +33,70 @@ void Keyboard::init() } PS2KbdSetReadmode(PS2KBD_READMODE_RAW); + PS2KbdSetBlockingMode(false); } void Keyboard::read_inputs() { + for (int i = 0; i < 256; ++i) + { + if (keyboard_status[i] == KeyStatus::pressed) + { + keyboard_status[i] = KeyStatus::holding; + } + else if (keyboard_status[i] == KeyStatus::released) + { + keyboard_status[i] = KeyStatus::none; + } + } + PS2KbdRawKey key; while (PS2KbdReadRaw(&key) != 0) { unsigned char c = (key.key + 'a') - 4; - //printf("New key: %u, %u, (%u, %c)\n", key.key, key.state, c, c); - keyboard_status[key.key] = key.state & 0xF; + printf("New key: %u, %u, (%u, %c)\n", key.key, key.state, c, c); + if (key.state & 1) + { + keyboard_status[key.key] = KeyStatus::pressed; + } + else + { + keyboard_status[key.key] = KeyStatus::released; + } } } -u8 Keyboard::get_key_status(unsigned char key) +Keyboard::KeyStatus Keyboard::get_key_status(unsigned char ascii_key) +{ + return keyboard_status[convert_ascii_to_keyboard_key(ascii_key)]; +} + +unsigned char Keyboard::convert_ascii_to_keyboard_key(unsigned char ascii_key) +{ + return (ascii_key - 'a') + 4; +} + +unsigned char Keyboard::convert_keyboard_key_to_ascii(unsigned char keyboard_key) +{ + return (keyboard_key + 'a') - 4; +} + +bool Keyboard::is_key_down(unsigned char key) +{ + const KeyStatus k = Keyboard::get_key_status(key); + return k == KeyStatus::holding || k == KeyStatus::pressed; +} + +bool Keyboard::is_key_up(unsigned char key) +{ + const KeyStatus k = Keyboard::get_key_status(key); + return k == KeyStatus::released || k == KeyStatus::none; +} + +bool Keyboard::is_shift_down() { - const unsigned char actual_key = (key - 'a') + 4; - //check(actual_key >= 0 && actual_key <= 255); - return keyboard_status[actual_key]; + const KeyStatus k = keyboard_status[225]; + return k == KeyStatus::holding || k == KeyStatus::pressed; } } // namespace Input \ No newline at end of file diff --git a/src/objects/movement.cc b/src/objects/movement.cc index a886fec..c849992 100644 --- a/src/objects/movement.cc +++ b/src/objects/movement.cc @@ -141,17 +141,20 @@ void ThirdPersonMovement::calculate_rotation_input(float delta_time) input_vector.yaw = (buttons.rjoy_h - 128.f) / 128.f; input_vector.pitch = (buttons.rjoy_v - 128.f) / 128.f; - // Left arrow - input_vector.yaw += Input::Keyboard::get_key_status(173) * -1; + { + using namespace Input::Keyboard; + // Left arrow + input_vector.yaw += is_key_down(173) * -1; - // Right arrow - input_vector.yaw += Input::Keyboard::get_key_status(172); + // Right arrow + input_vector.yaw += is_key_down(172); - // Up arrow - input_vector.pitch += Input::Keyboard::get_key_status(175); + // Up arrow + input_vector.pitch += is_key_down(175); - // Down arrow - input_vector.pitch += Input::Keyboard::get_key_status(174) * -1; + // Down arrow + input_vector.pitch += is_key_down(174) * -1; + } const float input_length = input_vector.length(); if (input_length > dead_zone) @@ -197,11 +200,14 @@ void ThirdPersonMovement::calculate_movement_input(float delta_time) input_vector += ((buttons.ljoy_h - 128.f) / 128.f) * right_movement_vector; input_vector += ((buttons.ljoy_v - 128.f) / 128.f) * forward_movement_vector; - input_vector += Input::Keyboard::get_key_status('a') * right_movement_vector * -1; - input_vector += Input::Keyboard::get_key_status('d') * right_movement_vector; + { + using namespace Input::Keyboard; + input_vector += is_key_down('a') * right_movement_vector * -1; + input_vector += is_key_down('d') * right_movement_vector; - input_vector += Input::Keyboard::get_key_status('s') * forward_movement_vector; - input_vector += Input::Keyboard::get_key_status('w') * forward_movement_vector * -1; + input_vector += is_key_down('s') * forward_movement_vector; + input_vector += is_key_down('w') * forward_movement_vector * -1; + } if (paddata & PAD_CROSS) { diff --git a/src/objects/text_object.cc b/src/objects/text_object.cc index ffad1b3..d953efc 100644 --- a/src/objects/text_object.cc +++ b/src/objects/text_object.cc @@ -27,6 +27,16 @@ void TextObject::render(const GS::GSState& gs_state) } } +void TextObject::set_text(std::string_view new_text) +{ + text = new_text; +} + +std::string_view TextObject::get_text() const +{ + return text; +} + const char* TextObject::get_name() const { if (text.size() > 0) diff --git a/src/objects/text_prompt.cc b/src/objects/text_prompt.cc new file mode 100644 index 0000000..b9fa36a --- /dev/null +++ b/src/objects/text_prompt.cc @@ -0,0 +1,58 @@ +#include "objects/text_prompt.hpp" + +#include "input/keyboard.hpp" + +#include +#include + +void TextPrompt::tick(float deltaTime) +{ + using namespace Input::Keyboard; + + bool new_text = false; + + const auto& keyboard_keys = get_all_key_statuses(); + for (int i = 0; i < 256; ++i) + { + if (keyboard_keys[i] == KeyStatus::pressed) + { + const unsigned char ascii_key = convert_keyboard_key_to_ascii(i); + if (isalpha(ascii_key)) + { + inputted_text += ascii_key; + new_text = true; + } + else if (ascii_key == '.' || ascii_key == ',') + { + inputted_text += ascii_key; + new_text = true; + } + else if (i == 56 && is_shift_down()) + { + inputted_text += '?'; + new_text = true; + } + else if (i == 44) // space bar + { + inputted_text += ' '; + new_text = true; + } + else if (i == 42 && inputted_text.size() > 0) // delete key + { + inputted_text.pop_back(); + new_text = true; + } + } + } + + if (new_text) + { + text_object.set_text(prompt + "\n" + inputted_text); + } +} + +void TextPrompt::set_prompt(std::string_view new_prompt) +{ + prompt = new_prompt; + text_object.set_text(prompt + "\n" + inputted_text); +} \ No newline at end of file diff --git a/src/world/levels/level1.cc b/src/world/levels/level1.cc index a9289aa..90af5f6 100644 --- a/src/world/levels/level1.cc +++ b/src/world/levels/level1.cc @@ -4,6 +4,7 @@ #include "objects/teapot.hpp" #include "objects/camera.hpp" #include "objects/movement.hpp" +#include "objects/text_prompt.hpp" #include "input/gamepad.hpp" @@ -49,10 +50,11 @@ class Level1: public World::Level Level1(Asset::Reference level) : World::Level(level) { - printf("Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"); - // Player teapot player.teapot_model.transform.set_location(Vector(0.f, 0.f, 0.f)); + + t1.get_root_component()->set_location(Vector(100.f, 0.f, 0.f)); + t1.set_prompt("Welcome to level one!"); } virtual void initialize() override @@ -65,6 +67,7 @@ class Level1: public World::Level } Level1Player player; + TextPrompt t1; }; static struct Level1ConstructorHelper