mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 13:30:02 +00:00
Merge pull request #9426 from unknownbrackets/input-state
Remove various legacy parts of the InputState
This commit is contained in:
commit
7e007c3973
@ -909,8 +909,6 @@ add_library(native STATIC
|
||||
ext/native/ui/view.h
|
||||
ext/native/ui/viewgroup.cpp
|
||||
ext/native/ui/viewgroup.h
|
||||
ext/native/ui/virtual_input.cpp
|
||||
ext/native/ui/virtual_input.h
|
||||
ext/native/util/hash/hash.cpp
|
||||
ext/native/util/hash/hash.h
|
||||
ext/native/util/random/rng.h
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "input/input_state.h" // KeyDef, AxisPos
|
||||
#include "input/input_state.h" // KeyDef
|
||||
#include "input/keycodes.h" // keyboard keys
|
||||
#include "../Core/HLE/sceCtrl.h" // psp keys
|
||||
|
||||
|
@ -200,11 +200,6 @@ void UpdateRunLoop(InputState *input_state) {
|
||||
}
|
||||
NativeUpdate(*input_state);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state->lock);
|
||||
EndInputState(input_state);
|
||||
}
|
||||
|
||||
if (GetUIState() != UISTATE_EXIT) {
|
||||
NativeRender(graphicsContext);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "base/NativeApp.h"
|
||||
#include "base/timeutil.h"
|
||||
#include "math/math_util.h"
|
||||
#include "ui/virtual_input.h"
|
||||
#include "ui/ui_context.h"
|
||||
|
||||
static u32 GetButtonColor() {
|
||||
|
@ -553,9 +553,6 @@ UI::EventReturn CreditsScreen::OnOK(UI::EventParams &e) {
|
||||
void CreditsScreen::update(InputState &input_state) {
|
||||
UIScreen::update(input_state);
|
||||
UpdateUIState(UISTATE_MENU);
|
||||
if (input_state.pad_buttons_down & PAD_BUTTON_BACK) {
|
||||
screenManager()->finishDialog(this, DR_OK);
|
||||
}
|
||||
frames_++;
|
||||
}
|
||||
|
||||
|
@ -932,7 +932,6 @@ bool NativeKey(const KeyInput &key) {
|
||||
}
|
||||
}
|
||||
#endif
|
||||
g_buttonTracker.Process(key);
|
||||
bool retval = false;
|
||||
if (screenManager)
|
||||
retval = screenManager->key(key);
|
||||
|
@ -44,15 +44,9 @@ inline static void ExecuteInputPoll() {
|
||||
// If that becomes an issue, maybe should poll to a copy of inputstate and only hold the lock while
|
||||
// copying that one to the real one?
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
input_state.pad_buttons = 0;
|
||||
input_state.pad_lstick_x = 0;
|
||||
input_state.pad_lstick_y = 0;
|
||||
input_state.pad_rstick_x = 0;
|
||||
input_state.pad_rstick_y = 0;
|
||||
if (host && (focused || !g_Config.bGamepadOnlyFocused)) {
|
||||
host->PollControllers(input_state);
|
||||
}
|
||||
UpdateInputState(&input_state);
|
||||
}
|
||||
|
||||
static void RunInputThread() {
|
||||
|
@ -512,8 +512,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
|
||||
androidVersion = jAndroidVersion;
|
||||
deviceType = jdeviceType;
|
||||
|
||||
g_buttonTracker.Reset();
|
||||
|
||||
left_joystick_x_async = 0;
|
||||
left_joystick_y_async = 0;
|
||||
right_joystick_x_async = 0;
|
||||
@ -676,24 +674,8 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeRenderer_displayRender(JNIEnv *env,
|
||||
}
|
||||
|
||||
if (renderer_inited) {
|
||||
// TODO: Look into if these locks are a perf loss
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
|
||||
input_state.pad_lstick_x = left_joystick_x_async;
|
||||
input_state.pad_lstick_y = left_joystick_y_async;
|
||||
input_state.pad_rstick_x = right_joystick_x_async;
|
||||
input_state.pad_rstick_y = right_joystick_y_async;
|
||||
|
||||
UpdateInputState(&input_state);
|
||||
}
|
||||
NativeUpdate(input_state);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
EndInputState(&input_state);
|
||||
}
|
||||
|
||||
NativeRender(graphicsContext);
|
||||
time_update();
|
||||
} else {
|
||||
@ -1062,24 +1044,8 @@ extern "C" bool JNICALL Java_org_ppsspp_ppsspp_NativeActivity_runEGLRenderLoop(J
|
||||
setCurrentThreadName("AndroidRender");
|
||||
}
|
||||
|
||||
// TODO: Look into if these locks are a perf loss
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
|
||||
input_state.pad_lstick_x = left_joystick_x_async;
|
||||
input_state.pad_lstick_y = left_joystick_y_async;
|
||||
input_state.pad_rstick_x = right_joystick_x_async;
|
||||
input_state.pad_rstick_y = right_joystick_y_async;
|
||||
|
||||
UpdateInputState(&input_state);
|
||||
}
|
||||
NativeUpdate(input_state);
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
EndInputState(&input_state);
|
||||
}
|
||||
|
||||
NativeRender(graphicsContext);
|
||||
time_update();
|
||||
|
||||
|
@ -90,7 +90,6 @@ LOCAL_SRC_FILES :=\
|
||||
ui/ui_screen.cpp \
|
||||
ui/ui_context.cpp \
|
||||
ui/screen.cpp \
|
||||
ui/virtual_input.cpp \
|
||||
util/text/utf8.cpp \
|
||||
util/text/parsers.cpp \
|
||||
util/text/wrap_text.cpp \
|
||||
|
@ -346,36 +346,6 @@ int System_GetPropertyInt(SystemProperty prop) {
|
||||
|
||||
InputState input_state;
|
||||
|
||||
static const int legacyKeyMap[] {
|
||||
NKCODE_X, //A
|
||||
NKCODE_S, //B
|
||||
NKCODE_Z, //X
|
||||
NKCODE_A, //Y
|
||||
NKCODE_W, //LBUMPER
|
||||
NKCODE_Q, //RBUMPER
|
||||
NKCODE_1, //START
|
||||
NKCODE_2, //SELECT
|
||||
NKCODE_DPAD_UP, //UP
|
||||
NKCODE_DPAD_DOWN, //DOWN
|
||||
NKCODE_DPAD_LEFT, //LEFT
|
||||
NKCODE_DPAD_RIGHT, //RIGHT
|
||||
0, //MENU (SwipeDown)
|
||||
NKCODE_ESCAPE, //BACK
|
||||
NKCODE_I, //JOY UP
|
||||
NKCODE_K, //JOY DOWN
|
||||
NKCODE_J, //JOY LEFT
|
||||
NKCODE_L, //JOY RIGHT
|
||||
};
|
||||
|
||||
void SimulateGamepad(const uint8_t *keys, InputState *input) {
|
||||
// Legacy key mapping.
|
||||
input->pad_buttons = 0;
|
||||
input->pad_lstick_x = 0;
|
||||
input->pad_lstick_y = 0;
|
||||
input->pad_rstick_x = 0;
|
||||
input->pad_rstick_y = 0;
|
||||
}
|
||||
|
||||
extern void mixaudio(void *userdata, Uint8 *stream, int len) {
|
||||
NativeMix((short *)stream, len / 4);
|
||||
}
|
||||
@ -684,7 +654,6 @@ int main(int argc, char *argv[]) {
|
||||
int framecount = 0;
|
||||
float t = 0;
|
||||
float lastT = 0;
|
||||
uint32_t pad_buttons = 0; // legacy pad buttons
|
||||
while (true) {
|
||||
input_state.accelerometer_valid = false;
|
||||
input_state.mouse_valid = true;
|
||||
@ -744,11 +713,6 @@ int main(int argc, char *argv[]) {
|
||||
key.keyCode = mapped->second;
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
|
||||
for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
|
||||
if (legacyKeyMap[i] == key.keyCode)
|
||||
pad_buttons |= 1 << i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_KEYUP:
|
||||
@ -763,10 +727,6 @@ int main(int argc, char *argv[]) {
|
||||
key.keyCode = mapped->second;
|
||||
key.deviceId = DEVICE_ID_KEYBOARD;
|
||||
NativeKey(key);
|
||||
for (int i = 0; i < ARRAY_SIZE(legacyKeyMap); i++) {
|
||||
if (legacyKeyMap[i] == key.keyCode)
|
||||
pad_buttons &= ~(1 << i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_TEXTINPUT:
|
||||
@ -876,9 +836,6 @@ int main(int argc, char *argv[]) {
|
||||
if (g_QuitRequested)
|
||||
break;
|
||||
const uint8_t *keys = SDL_GetKeyboardState(NULL);
|
||||
SimulateGamepad(keys, &input_state);
|
||||
input_state.pad_buttons = pad_buttons;
|
||||
UpdateInputState(&input_state, true);
|
||||
UpdateRunLoop(&input_state);
|
||||
if (g_QuitRequested)
|
||||
break;
|
||||
|
@ -338,7 +338,6 @@ void MainUI::paintGL()
|
||||
SDL_PumpEvents();
|
||||
#endif
|
||||
updateAccelerometer();
|
||||
UpdateInputState(&input_state);
|
||||
time_update();
|
||||
UpdateRunLoop(&input_state);
|
||||
}
|
||||
|
@ -28,33 +28,6 @@ const char *GetDeviceName(int deviceId) {
|
||||
}
|
||||
}
|
||||
|
||||
// Default pad mapping to button bits. Used for UI and stuff that doesn't use PPSSPP's key mapping system.
|
||||
int MapPadButtonFixed(int keycode) {
|
||||
switch (keycode) {
|
||||
case NKCODE_BACK: return PAD_BUTTON_BACK; // Back
|
||||
case NKCODE_MENU: return PAD_BUTTON_MENU; // Menu
|
||||
|
||||
case NKCODE_Z:
|
||||
case NKCODE_SPACE:
|
||||
case NKCODE_BUTTON_1:
|
||||
case NKCODE_BUTTON_A: // same as NKCODE_OUYA_BUTTON_O and NKCODE_BUTTON_CROSS_PS3
|
||||
return PAD_BUTTON_A;
|
||||
|
||||
case NKCODE_ESCAPE:
|
||||
case NKCODE_BUTTON_2:
|
||||
case NKCODE_BUTTON_B: // same as NKCODE_OUYA_BUTTON_A and NKCODE_BUTTON_CIRCLE_PS3:
|
||||
return PAD_BUTTON_B;
|
||||
|
||||
case NKCODE_DPAD_LEFT: return PAD_BUTTON_LEFT;
|
||||
case NKCODE_DPAD_RIGHT: return PAD_BUTTON_RIGHT;
|
||||
case NKCODE_DPAD_UP: return PAD_BUTTON_UP;
|
||||
case NKCODE_DPAD_DOWN: return PAD_BUTTON_DOWN;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<KeyDef> dpadKeys;
|
||||
std::vector<KeyDef> confirmKeys;
|
||||
std::vector<KeyDef> cancelKeys;
|
||||
@ -88,38 +61,3 @@ void SetTabLeftRightKeys(const std::vector<KeyDef> &tabLeft, const std::vector<K
|
||||
tabLeftKeys = tabLeft;
|
||||
tabRightKeys = tabRight;
|
||||
}
|
||||
|
||||
uint32_t ButtonTracker::Update() {
|
||||
pad_buttons_ |= pad_buttons_async_set;
|
||||
pad_buttons_ &= ~pad_buttons_async_clear;
|
||||
return pad_buttons_;
|
||||
}
|
||||
|
||||
void ButtonTracker::Process(const KeyInput &input) {
|
||||
int btn = MapPadButtonFixed(input.keyCode);
|
||||
if (btn == 0)
|
||||
return;
|
||||
|
||||
// For now, use a fixed mapping. Good enough for the basics on most platforms.
|
||||
if (input.flags & KEY_DOWN) {
|
||||
pad_buttons_async_set |= btn;
|
||||
pad_buttons_async_clear &= ~btn;
|
||||
}
|
||||
if (input.flags & KEY_UP) {
|
||||
pad_buttons_async_set &= ~btn;
|
||||
pad_buttons_async_clear |= btn;
|
||||
}
|
||||
}
|
||||
|
||||
ButtonTracker g_buttonTracker;
|
||||
|
||||
void UpdateInputState(InputState *input, bool merge) {
|
||||
uint32_t btns = g_buttonTracker.Update();
|
||||
input->pad_buttons = merge ? (input->pad_buttons | btns) : btns;
|
||||
input->pad_buttons_down = (input->pad_last_buttons ^ input->pad_buttons) & input->pad_buttons;
|
||||
input->pad_buttons_up = (input->pad_last_buttons ^ input->pad_buttons) & input->pad_last_buttons;
|
||||
}
|
||||
|
||||
void EndInputState(InputState *input) {
|
||||
input->pad_last_buttons = input->pad_buttons;
|
||||
}
|
||||
|
@ -105,49 +105,17 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Represents a single bindable axis direction
|
||||
struct AxisPos {
|
||||
int axis;
|
||||
float position;
|
||||
|
||||
bool operator < (const AxisPos &other) const {
|
||||
if (axis < other.axis) return true;
|
||||
if (axis > other.axis) return false;
|
||||
return position < other.position;
|
||||
}
|
||||
bool operator == (const AxisPos &other) const {
|
||||
return axis == other.axis && position == other.position;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Collection of all possible inputs, and automatically computed
|
||||
// deltas where applicable.
|
||||
struct InputState {
|
||||
// Lock this whenever you access the data in this struct.
|
||||
mutable std::mutex lock;
|
||||
InputState()
|
||||
: pad_buttons(0),
|
||||
pad_last_buttons(0),
|
||||
pad_buttons_down(0),
|
||||
pad_buttons_up(0),
|
||||
mouse_valid(false),
|
||||
: mouse_valid(false),
|
||||
accelerometer_valid(false) {
|
||||
memset(pointer_down, 0, sizeof(pointer_down));
|
||||
}
|
||||
|
||||
// Gamepad style input. For ease of use.
|
||||
int pad_buttons; // bitfield
|
||||
int pad_last_buttons;
|
||||
int pad_buttons_down; // buttons just pressed this frame
|
||||
int pad_buttons_up; // buttons just pressed last frame
|
||||
float pad_lstick_x;
|
||||
float pad_lstick_y;
|
||||
float pad_rstick_x;
|
||||
float pad_rstick_y;
|
||||
float pad_ltrigger;
|
||||
float pad_rtrigger;
|
||||
|
||||
// Mouse/touch style input
|
||||
// There are up to 8 mice / fingers.
|
||||
volatile bool mouse_valid;
|
||||
@ -164,9 +132,6 @@ private:
|
||||
DISALLOW_COPY_AND_ASSIGN(InputState);
|
||||
};
|
||||
|
||||
void UpdateInputState(InputState *input, bool merge = false);
|
||||
void EndInputState(InputState *input);
|
||||
|
||||
enum {
|
||||
TOUCH_MOVE = 1 << 0,
|
||||
TOUCH_DOWN = 1 << 1,
|
||||
@ -222,28 +187,6 @@ struct AxisInput {
|
||||
int flags;
|
||||
};
|
||||
|
||||
|
||||
class ButtonTracker {
|
||||
public:
|
||||
ButtonTracker() { Reset(); }
|
||||
void Reset() {
|
||||
pad_buttons_ = 0;
|
||||
pad_buttons_async_set = 0;
|
||||
pad_buttons_async_clear = 0;
|
||||
}
|
||||
void Process(const KeyInput &input);
|
||||
uint32_t Update();
|
||||
uint32_t GetPadButtons() const { return pad_buttons_; }
|
||||
|
||||
private:
|
||||
uint32_t pad_buttons_;
|
||||
uint32_t pad_buttons_async_set;
|
||||
uint32_t pad_buttons_async_clear;
|
||||
};
|
||||
|
||||
// Platforms should call g_buttonTracker.Process().
|
||||
extern ButtonTracker g_buttonTracker;
|
||||
|
||||
// Is there a nicer place for this stuff? It's here to avoid dozens of linking errors in UnitTest..
|
||||
extern std::vector<KeyDef> dpadKeys;
|
||||
extern std::vector<KeyDef> confirmKeys;
|
||||
|
@ -281,7 +281,6 @@
|
||||
<ClInclude Include="ui\ui_screen.h" />
|
||||
<ClInclude Include="ui\view.h" />
|
||||
<ClInclude Include="ui\viewgroup.h" />
|
||||
<ClInclude Include="ui\virtual_input.h" />
|
||||
<ClInclude Include="util\random\rng.h" />
|
||||
<ClInclude Include="util\text\parsers.h" />
|
||||
<ClInclude Include="util\text\shiftjis.h" />
|
||||
@ -743,7 +742,6 @@
|
||||
<ClCompile Include="ui\ui_screen.cpp" />
|
||||
<ClCompile Include="ui\view.cpp" />
|
||||
<ClCompile Include="ui\viewgroup.cpp" />
|
||||
<ClCompile Include="ui\virtual_input.cpp" />
|
||||
<ClCompile Include="util\hash\hash.cpp" />
|
||||
<ClCompile Include="util\text\parsers.cpp" />
|
||||
<ClCompile Include="util\text\utf8.cpp" />
|
||||
|
@ -146,9 +146,6 @@
|
||||
<ClInclude Include="util\random\rng.h">
|
||||
<Filter>util</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ui\virtual_input.h">
|
||||
<Filter>ui</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="math\curves.h">
|
||||
<Filter>math</Filter>
|
||||
</ClInclude>
|
||||
@ -415,9 +412,6 @@
|
||||
<ClCompile Include="math\lin\plane.cpp">
|
||||
<Filter>math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ui\virtual_input.cpp">
|
||||
<Filter>ui</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="math\curves.cpp">
|
||||
<Filter>math</Filter>
|
||||
</ClCompile>
|
||||
|
@ -4,7 +4,6 @@ set(SRCS
|
||||
view.cpp
|
||||
viewgroup.cpp
|
||||
screen.cpp
|
||||
virtual_input.cpp
|
||||
)
|
||||
|
||||
set(SRCS ${SRCS})
|
||||
|
@ -1,167 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <algorithm>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "gfx_es2/draw_buffer.h"
|
||||
#include "gfx/texture_atlas.h"
|
||||
#include "input/input_state.h"
|
||||
#include "virtual_input.h"
|
||||
|
||||
TouchButton::TouchButton(const Atlas *atlas, int imageIndex, int overlayImageIndex, int button, int rotationAngle, bool mirror_h)
|
||||
: atlas_(atlas), imageIndex_(imageIndex), overlayImageIndex_(overlayImageIndex), button_(button), mirror_h_(mirror_h)
|
||||
{
|
||||
memset(pointerDown, 0, sizeof(pointerDown));
|
||||
w_ = atlas_->images[imageIndex_].w;
|
||||
h_ = atlas_->images[imageIndex_].h;
|
||||
rotationAngle_ = (float)rotationAngle * 3.1415927 / 180.0f;
|
||||
isDown_ = false;
|
||||
}
|
||||
|
||||
void TouchButton::update(InputState &input_state)
|
||||
{
|
||||
bool down = false;
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
if (input_state.pointer_down[i] && isInside(input_state.pointer_x[i], input_state.pointer_y[i]))
|
||||
down = true;
|
||||
}
|
||||
|
||||
if (down)
|
||||
input_state.pad_buttons |= button_;
|
||||
|
||||
isDown_ = (input_state.pad_buttons & button_) != 0;
|
||||
}
|
||||
|
||||
void TouchButton::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay)
|
||||
{
|
||||
float scale = 1.0f;
|
||||
if (isDown_) {
|
||||
color |= 0xFF000000;
|
||||
colorOverlay |= 0xFF000000;
|
||||
scale = 2.0f;
|
||||
}
|
||||
scale *= scale_;
|
||||
// We only mirror background
|
||||
db.DrawImageRotated(imageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, color, mirror_h_);
|
||||
if (overlayImageIndex_ != -1)
|
||||
db.DrawImageRotated(overlayImageIndex_, x_ + w_*scale_/2, y_ + h_*scale_/2, scale, rotationAngle_, colorOverlay);
|
||||
}
|
||||
|
||||
TouchCrossPad::TouchCrossPad(const Atlas *atlas, int arrowIndex, int overlayIndex)
|
||||
: atlas_(atlas), arrowIndex_(arrowIndex), overlayIndex_(overlayIndex), down_(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void TouchCrossPad::update(InputState &input_state)
|
||||
{
|
||||
float stick_size_ = radius_ * 2;
|
||||
float inv_stick_size = 1.0f / (stick_size_ * scale_);
|
||||
const float deadzone = 0.17f;
|
||||
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
if (input_state.pointer_down[i]) {
|
||||
float dx = (input_state.pointer_x[i] - x_) * inv_stick_size;
|
||||
float dy = (input_state.pointer_y[i] - y_) * inv_stick_size;
|
||||
float rad = sqrtf(dx*dx+dy*dy);
|
||||
if (rad < deadzone || rad > 1.0f)
|
||||
continue;
|
||||
|
||||
if (dx == 0 && dy == 0)
|
||||
continue;
|
||||
|
||||
int direction = (int)(floorf((atan2f(dy, dx) / (2 * M_PI) * 8) + 0.5f)) & 7;
|
||||
|
||||
input_state.pad_buttons &= ~(PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN);
|
||||
switch (direction) {
|
||||
case 0: input_state.pad_buttons |= PAD_BUTTON_RIGHT; break;
|
||||
case 1: input_state.pad_buttons |= PAD_BUTTON_RIGHT | PAD_BUTTON_DOWN; break;
|
||||
case 2: input_state.pad_buttons |= PAD_BUTTON_DOWN; break;
|
||||
case 3: input_state.pad_buttons |= PAD_BUTTON_DOWN | PAD_BUTTON_LEFT; break;
|
||||
case 4: input_state.pad_buttons |= PAD_BUTTON_LEFT; break;
|
||||
case 5: input_state.pad_buttons |= PAD_BUTTON_UP | PAD_BUTTON_LEFT; break;
|
||||
case 6: input_state.pad_buttons |= PAD_BUTTON_UP; break;
|
||||
case 7: input_state.pad_buttons |= PAD_BUTTON_UP | PAD_BUTTON_RIGHT; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
down_ = input_state.pad_buttons & (PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | PAD_BUTTON_UP | PAD_BUTTON_DOWN);
|
||||
}
|
||||
|
||||
void TouchCrossPad::draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay)
|
||||
{
|
||||
static const float xoff[4] = {1, 0, -1, 0};
|
||||
static const float yoff[4] = {0, 1, 0, -1};
|
||||
static const int dir[4] = {PAD_BUTTON_RIGHT, PAD_BUTTON_DOWN, PAD_BUTTON_LEFT, PAD_BUTTON_UP};
|
||||
for (int i = 0; i < 4; i++) {
|
||||
float x = x_ + xoff[i] * scale_ * radius_;
|
||||
float y = y_ + yoff[i] * scale_ * radius_;
|
||||
float angle = i * M_PI / 2;
|
||||
float imgScale = (down_ & dir[i]) ? scale_ * 2 : scale_;
|
||||
db.DrawImageRotated(arrowIndex_, x, y, imgScale, angle + PI, color, false);
|
||||
if (overlayIndex_ != -1)
|
||||
db.DrawImageRotated(overlayIndex_, x, y, imgScale, angle + PI, colorOverlay);
|
||||
}
|
||||
}
|
||||
|
||||
TouchStick::TouchStick(const Atlas *atlas, int bgImageIndex, int stickImageIndex, int stick)
|
||||
: atlas_(atlas), bgImageIndex_(bgImageIndex), stickImageIndex_(stickImageIndex), stick_(stick)
|
||||
{
|
||||
stick_size_ = atlas_->images[bgImageIndex].w / 3.5f;
|
||||
memset(dragging_, 0, sizeof(dragging_));
|
||||
memset(lastPointerDown_, 0, sizeof(lastPointerDown_));
|
||||
}
|
||||
|
||||
void TouchStick::update(InputState &input_state)
|
||||
{
|
||||
float inv_stick_size = 1.0f / (stick_size_ * scale_);
|
||||
for (int i = 0; i < MAX_POINTERS; i++) {
|
||||
if (input_state.pointer_down[i]) {
|
||||
float dx = (input_state.pointer_x[i] - stick_x_) * inv_stick_size;
|
||||
float dy = (input_state.pointer_y[i] - stick_y_) * inv_stick_size;
|
||||
// Ignore outside box
|
||||
if (!dragging_[i] && (fabsf(dx) > 1.4f || fabsf(dy) > 1.4f))
|
||||
goto skip;
|
||||
if (!lastPointerDown_[i] && (fabsf(dx) < 1.4f && fabsf(dy) < 1.4f)) {
|
||||
dragging_[i] = true;
|
||||
}
|
||||
if (!dragging_[i])
|
||||
goto skip;
|
||||
|
||||
// Do not clamp to a circle! The PSP has nearly square range!
|
||||
|
||||
// Old code to clamp to a circle
|
||||
// float len = sqrtf(dx * dx + dy * dy);
|
||||
// if (len > 1.0f) {
|
||||
// dx /= len;
|
||||
// dy /= len;
|
||||
//}
|
||||
|
||||
// Still need to clamp to a square
|
||||
dx = std::min(1.0f, std::max(-1.0f, dx));
|
||||
dy = std::min(1.0f, std::max(-1.0f, dy));
|
||||
|
||||
if (stick_ == 0) {
|
||||
input_state.pad_lstick_x = dx;
|
||||
input_state.pad_lstick_y = -dy;
|
||||
} else if (stick_ == 1) {
|
||||
input_state.pad_rstick_x = dx;
|
||||
input_state.pad_rstick_y = -dy;
|
||||
}
|
||||
|
||||
} else {
|
||||
dragging_[i] = false;
|
||||
}
|
||||
skip:
|
||||
lastPointerDown_[i] = input_state.pointer_down[i];
|
||||
}
|
||||
|
||||
stick_delta_x_ = input_state.pad_lstick_x;
|
||||
stick_delta_y_ = -input_state.pad_lstick_y;
|
||||
}
|
||||
|
||||
void TouchStick::draw(DrawBuffer &db, uint32_t color)
|
||||
{
|
||||
if (bgImageIndex_ != -1)
|
||||
db.DrawImage(bgImageIndex_, stick_x_, stick_y_, 1.0f * scale_, color, ALIGN_CENTER);
|
||||
db.DrawImage(stickImageIndex_, stick_x_ + stick_delta_x_ * stick_size_ * scale_, stick_y_ + stick_delta_y_ * stick_size_ * scale_, 1.0f * scale_, color, ALIGN_CENTER);
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "math/math_util.h"
|
||||
#include "gfx/texture_atlas.h"
|
||||
|
||||
class DrawBuffer;
|
||||
|
||||
// Multitouch-enabled emulation of a hardware button.
|
||||
// Many of these can be pressed simultaneously with multitouch.
|
||||
// (any finger will work, simultaneously with other virtual button/stick actions).
|
||||
class TouchButton
|
||||
{
|
||||
public:
|
||||
TouchButton(const Atlas *atlas, int imageIndex, int overlayImageIndex, int button, int rotationAngle = 0, bool mirror_h = false);
|
||||
|
||||
void update(InputState &input_state);
|
||||
void draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay);
|
||||
|
||||
void setPos(float x, float y, float scale = 1.0f) {
|
||||
scale_ = scale;
|
||||
x_ = x - w_ * scale / 2;
|
||||
y_ = y - h_ * scale / 2;
|
||||
}
|
||||
|
||||
private:
|
||||
virtual bool isInside(float px, float py) const
|
||||
{
|
||||
float margin = 5.0f;
|
||||
return px >= x_ - margin * scale_ && py >= y_ - margin * scale_ && px <= x_ + (w_ + margin) * scale_ && py <= y_ + (h_ + margin) * scale_;
|
||||
}
|
||||
|
||||
const Atlas *atlas_;
|
||||
|
||||
int imageIndex_;
|
||||
int overlayImageIndex_;
|
||||
int button_;
|
||||
float rotationAngle_;
|
||||
bool mirror_h_;
|
||||
|
||||
float x_, y_;
|
||||
float w_;
|
||||
float h_;
|
||||
float scale_;
|
||||
|
||||
bool isDown_;
|
||||
|
||||
// TODO: simplify into flags.
|
||||
bool pointerDown[MAX_POINTERS];
|
||||
};
|
||||
|
||||
// 4-in-one directional pad, with support for single touch diagonals.
|
||||
class TouchCrossPad
|
||||
{
|
||||
public:
|
||||
TouchCrossPad(const Atlas *atlas, int arrowIndex, int overlayIndex);
|
||||
|
||||
void update(InputState &input_state);
|
||||
void draw(DrawBuffer &db, uint32_t color, uint32_t colorOverlay);
|
||||
|
||||
void setPos(float x, float y, float radius, float scale = 1.0f) {
|
||||
x_ = x;
|
||||
y_ = y;
|
||||
radius_ = radius;
|
||||
scale_ = scale;
|
||||
}
|
||||
|
||||
private:
|
||||
const Atlas *atlas_;
|
||||
|
||||
float x_;
|
||||
float y_;
|
||||
float radius_;
|
||||
float scale_;
|
||||
|
||||
int arrowIndex_;
|
||||
int overlayIndex_;
|
||||
int down_;
|
||||
};
|
||||
|
||||
|
||||
// Multi-touch enabled virtual joystick
|
||||
// Many of these can be used simultaneously with multitouch.
|
||||
// (any finger will work, simultaneously with other virtual button/stick actions).
|
||||
class TouchStick
|
||||
{
|
||||
public:
|
||||
TouchStick(const Atlas *atlas, int bgImageIndex, int stickImageIndex, int stick);
|
||||
|
||||
void update(InputState &input_state);
|
||||
void draw(DrawBuffer &db, uint32_t color);
|
||||
|
||||
void setPos(float x, float y, float scale = 1.0f) {
|
||||
stick_x_ = x;
|
||||
stick_y_ = y;
|
||||
scale_ = scale;
|
||||
}
|
||||
|
||||
private:
|
||||
const Atlas *atlas_;
|
||||
int bgImageIndex_;
|
||||
int stickImageIndex_;
|
||||
int stick_;
|
||||
int stick_size_;
|
||||
float stick_x_;
|
||||
float stick_y_;
|
||||
float scale_;
|
||||
bool dragging_[MAX_POINTERS];
|
||||
bool lastPointerDown_[MAX_POINTERS];
|
||||
|
||||
// maintained for drawing only
|
||||
float stick_delta_x_;
|
||||
float stick_delta_y_;
|
||||
};
|
||||
|
@ -256,9 +256,7 @@ static GraphicsContext *graphicsContext;
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(input_state.lock);
|
||||
UpdateInputState(&input_state);
|
||||
NativeUpdate(input_state);
|
||||
EndInputState(&input_state);
|
||||
}
|
||||
|
||||
NativeRender(graphicsContext);
|
||||
|
Loading…
Reference in New Issue
Block a user