menu
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user