This commit is contained in:
2026-05-19 22:35:10 +02:00
parent d93e71e716
commit 0b45643ef2
21 changed files with 806 additions and 235 deletions

View File

@@ -1,35 +1,103 @@
#include <game/input.hpp>
#include <window/window.hpp>
#include <object/ui/uitextbox.hpp>
#include <state/gamestate.hpp>
namespace Game {
const bool* Input::mCurrentKeyStates = nullptr;
const bool* Input::mPreviousKeyStates = nullptr;
std::vector<Uint8> Input::mPreviousKeyStates = {};
int Input::mNumKeys = 0;
int Input::mPrevNumKeys = 0;
SDL_MouseButtonFlags Input::mCurrentMouseButtonStates = 0;
SDL_MouseButtonFlags Input::mPreviousMouseButtonStates = 0;
float Input::mMouseX = 0.0f;
float Input::mMouseY = 0.0f;
std::mutex Input::mTextMutex;
std::vector<std::string> Input::mPendingText;
void Input::update() {
mPreviousKeyStates = mCurrentKeyStates;
// Copy the previous keyboard state (snapshot) so we can detect just-pressed
if (mCurrentKeyStates && mNumKeys > 0) {
mPreviousKeyStates.assign(mCurrentKeyStates, mCurrentKeyStates + mNumKeys);
mPrevNumKeys = mNumKeys;
} else {
// If we don't have a previous snapshot, initialize previous vector to zeros with current size
if (mNumKeys > 0) mPreviousKeyStates.assign(mNumKeys, 0);
mPrevNumKeys = mNumKeys;
}
mCurrentKeyStates = SDL_GetKeyboardState(&mNumKeys);
mPreviousMouseButtonStates = mCurrentMouseButtonStates;
mCurrentMouseButtonStates = SDL_GetMouseState(&mMouseX, &mMouseY);
float rawMouseX = 0.0f;
float rawMouseY = 0.0f;
mCurrentMouseButtonStates = SDL_GetMouseState(&rawMouseX, &rawMouseY);
// Convert mouse coordinates from real display/window pixels into
// centered logical game coordinates (1280x720 world space).
static constexpr float LOGICAL_WIDTH = 1280.0f;
static constexpr float LOGICAL_HEIGHT = 720.0f;
float displayW = LOGICAL_WIDTH;
float displayH = LOGICAL_HEIGHT;
SDL_Window* sdlWindow = Window::Window::getSDLWindowBackend();
if (sdlWindow) {
int windowPixelsW = static_cast<int>(LOGICAL_WIDTH);
int windowPixelsH = static_cast<int>(LOGICAL_HEIGHT);
SDL_GetWindowSizeInPixels(sdlWindow, &windowPixelsW, &windowPixelsH);
SDL_DisplayID displayId = SDL_GetDisplayForWindow(sdlWindow);
const SDL_DisplayMode* displayMode = SDL_GetCurrentDisplayMode(displayId);
if (displayMode && displayMode->w > 0 && displayMode->h > 0) {
displayW = static_cast<float>(displayMode->w);
displayH = static_cast<float>(displayMode->h);
} else if (windowPixelsW > 0 && windowPixelsH > 0) {
displayW = static_cast<float>(windowPixelsW);
displayH = static_cast<float>(windowPixelsH);
}
}
const float invScaleX = LOGICAL_WIDTH / displayW;
const float invScaleY = LOGICAL_HEIGHT / displayH;
mMouseX = rawMouseX * invScaleX - (LOGICAL_WIDTH * 0.5f);
mMouseY = rawMouseY * invScaleY - (LOGICAL_HEIGHT * 0.5f);
// Consume and deliver queued text input from window thread to focused textbox
std::vector<std::string> texts;
consumeText(texts);
if (!texts.empty()) {
auto entities = State::GameState::getInstance().getEntitiesSnapshot();
for (auto* e : entities) {
if (!e) continue;
auto* tb = dynamic_cast<Game::Object::UITextBox*>(e);
if (tb && tb->isFocused()) {
for (auto& s : texts) {
tb->insertText(s);
}
break; // Deliver to first focused textbox only
}
}
}
}
bool Input::isKeyPressed(SDL_Scancode key) {
if (key < 0 || key >= mNumKeys) return false;
return mCurrentKeyStates[key];
return mCurrentKeyStates && mCurrentKeyStates[key];
}
bool Input::isKeyJustPressed(SDL_Scancode key) {
if (key < 0 || key >= mNumKeys) return false;
return mCurrentKeyStates[key] && (!mPreviousKeyStates || !mPreviousKeyStates[key]);
bool cur = mCurrentKeyStates && mCurrentKeyStates[key];
bool prev = (key < static_cast<int>(mPreviousKeyStates.size())) ? static_cast<bool>(mPreviousKeyStates[key]) : false;
return cur && !prev;
}
bool Input::isKeyJustReleased(SDL_Scancode key) {
if (key < 0 || key >= mNumKeys) return false;
return (!mCurrentKeyStates[key]) && mPreviousKeyStates && mPreviousKeyStates[key];
bool cur = mCurrentKeyStates && mCurrentKeyStates[key];
bool prev = (key < static_cast<int>(mPreviousKeyStates.size())) ? static_cast<bool>(mPreviousKeyStates[key]) : false;
return !cur && prev;
}
bool Input::isMouseButtonPressed(Uint8 button) {
@@ -51,4 +119,14 @@ namespace Game {
float Input::getMouseY() {
return mMouseY;
}
void Input::pushText(const std::string& utf8) {
std::scoped_lock lock(mTextMutex);
mPendingText.push_back(utf8);
}
void Input::consumeText(std::vector<std::string>& out) {
std::scoped_lock lock(mTextMutex);
out.swap(mPendingText);
}
}