diff --git a/src/Screens.c b/src/Screens.c index 6f2ae4984..c2ced7d36 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -1876,30 +1876,26 @@ void DisconnectScreen_Show(const cc_string* title, const cc_string* message) { *--------------------------------------------------------TouchScreen------------------------------------------------------* *#########################################################################################################################*/ #ifdef CC_BUILD_TOUCH +#define TOUCH_NUM_BTNS 3 static struct TouchScreen { Screen_Body - cc_uint8 binds[7]; + cc_uint8 binds[TOUCH_NUM_BTNS]; struct FontDesc font; - struct ButtonWidget btns[7]; + struct ThumbstickWidget thumbstick; + struct ButtonWidget btns[TOUCH_NUM_BTNS]; } TouchScreen; -static struct Widget* touch_widgets[7] = { - (struct Widget*)&TouchScreen.btns[0], (struct Widget*)&TouchScreen.btns[1], - (struct Widget*)&TouchScreen.btns[2], (struct Widget*)&TouchScreen.btns[3], - (struct Widget*)&TouchScreen.btns[4], (struct Widget*)&TouchScreen.btns[5], - (struct Widget*)&TouchScreen.btns[6], +static struct Widget* touch_widgets[4] = { + (struct Widget*)&TouchScreen.thumbstick, (struct Widget*)&TouchScreen.btns[0], + (struct Widget*)&TouchScreen.btns[1], (struct Widget*)&TouchScreen.btns[2] }; -#define TOUCH_MAX_VERTICES (7 * BUTTONWIDGET_MAX) +#define TOUCH_MAX_VERTICES (THUMBSTICKWIDGET_MAX + TOUCH_NUM_BTNS * BUTTONWIDGET_MAX) static const struct TouchBindDesc { const char* text; cc_uint8 bind, width; cc_int16 x, y; -} touchDescs[7] = { - { "<", KEYBIND_LEFT, 40, 10, 50 }, - { ">", KEYBIND_RIGHT, 40, 150, 50 }, - { "^", KEYBIND_FORWARD, 40, 80, 90 }, - { "\\/", KEYBIND_BACK, 40, 80, 10 }, +} touchDescs[TOUCH_NUM_BTNS] = { { "Jump", KEYBIND_JUMP, 100, 50, 90 }, { "", KEYBIND_COUNT, 100, 50, 50 }, { "More", KEYBIND_COUNT, 100, 50, 10 }, @@ -1913,7 +1909,7 @@ static void TouchScreen_ContextLost(void* screen) { static void TouchScreen_UpdateModeText(void* screen) { struct TouchScreen* s = (struct TouchScreen*)screen; - ButtonWidget_SetConst(&s->btns[5], Input_Placing ? "Place" : "Delete", &s->font); + ButtonWidget_SetConst(&s->btns[1], Input_Placing ? "Place" : "Delete", &s->font); } static void TouchScreen_ModeClick(void* s, void* w) { @@ -1929,7 +1925,7 @@ static void TouchScreen_ContextRecreated(void* screen) { Screen_CreateVb(screen); Drawer2D_MakeFont(&s->font, 16, FONT_FLAGS_BOLD); - for (i = 0; i < s->numWidgets; i++) { + for (i = 0; i < TOUCH_NUM_BTNS; i++) { desc = &touchDescs[i]; ButtonWidget_SetConst(&s->btns[i], desc->text, &s->font); } @@ -1951,7 +1947,11 @@ static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { //Chat_Add1("POINTER DOWN: %i", &id); if (Gui_GetInputGrab()) return false; - for (i = 0; i < s->numWidgets; i++) { + if (Widget_Contains(&s->thumbstick, x, y)) { + s->thumbstick.active |= id; return true; + } + + for (i = 0; i < TOUCH_NUM_BTNS; i++) { if (!Widget_Contains(&s->btns[i], x, y)) continue; if (s->binds[i] < KEYBIND_COUNT) { @@ -1969,8 +1969,9 @@ static int TouchScreen_PointerUp(void* screen, int id, int x, int y) { struct TouchScreen* s = (struct TouchScreen*)screen; int i; //Chat_Add1("POINTER UP: %i", &id); + s->thumbstick.active &= ~id; - for (i = 0; i < s->numWidgets; i++) { + for (i = 0; i < TOUCH_NUM_BTNS; i++) { if (!(s->btns[i].active & id)) continue; if (s->binds[i] < KEYBIND_COUNT) { @@ -1982,6 +1983,11 @@ static int TouchScreen_PointerUp(void* screen, int id, int x, int y) { return false; } +static void TouchScreen_GetMovement(float* xMoving, float* zMoving) { + ThumbstickWidget_GetMovement(&TouchScreen.thumbstick, xMoving, zMoving); +} + +struct LocalPlayerInput touchInput; static void TouchScreen_Init(void* screen) { struct TouchScreen* s = (struct TouchScreen*)screen; int i; @@ -1990,13 +1996,17 @@ static void TouchScreen_Init(void* screen) { s->numWidgets = Array_Elems(touch_widgets); s->maxVertices = TOUCH_MAX_VERTICES; - for (i = 0; i < s->numWidgets; i++) { + for (i = 0; i < TOUCH_NUM_BTNS; i++) { ButtonWidget_Init(&s->btns[i], touchDescs[i].width, NULL); s->binds[i] = touchDescs[i].bind; } - s->btns[5].MenuClick = TouchScreen_ModeClick; - s->btns[6].MenuClick = TouchScreen_MoreClick; + s->btns[1].MenuClick = TouchScreen_ModeClick; + s->btns[2].MenuClick = TouchScreen_MoreClick; + + ThumbstickWidget_Init(&s->thumbstick); + touchInput.GetMovement = TouchScreen_GetMovement; + LocalPlayer_Instance.input.next = &touchInput; } static void TouchScreen_Layout(void* screen) { @@ -2007,12 +2017,14 @@ static void TouchScreen_Layout(void* screen) { HUDScreen_Layout(Gui_HUD); height = Gui_HUD->hotbar.height; - for (i = 0; i < s->numWidgets; i++) { - Widget_SetLocation(&s->btns[i], i < 4 ? ANCHOR_MIN : ANCHOR_MAX, - ANCHOR_MAX, touchDescs[i].x, touchDescs[i].y); + for (i = 0; i < TOUCH_NUM_BTNS; i++) { + Widget_SetLocation(&s->btns[i], ANCHOR_MAX, ANCHOR_MAX, + touchDescs[i].x, touchDescs[i].y); s->btns[i].yOffset += height; Widget_Layout(&s->btns[i]); } + + Widget_SetLocation(&s->thumbstick, ANCHOR_MIN, ANCHOR_MAX, 30, 30); } static const struct ScreenVTABLE TouchScreen_VTABLE = { diff --git a/src/Widgets.c b/src/Widgets.c index d0523bfe2..194e07a6f 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -2500,3 +2500,58 @@ void SpecialInputWidget_Create(struct SpecialInputWidget* w, struct FontDesc* fo w->target = target; SpecialInputWidget_InitTabs(w); } + + +/*########################################################################################################################* +*----------------------------------------------------ThumbstickWidget-----------------------------------------------------* +*#########################################################################################################################*/ +#ifdef CC_BUILD_TOUCH +static void ThumbstickWidget_BuildMesh(void* widget, struct VertexTextured** vertices) { + struct ThumbstickWidget* w = (struct ThumbstickWidget*)widget; + struct Texture tex = { 0 }; + + tex.X = w->x; tex.Y = w->y; + tex.Width = w->width; tex.Height = w->height; + tex.uv.U2 = 1; tex.uv.V2 = 1; + Gfx_Make2DQuad(&tex, PACKEDCOL_WHITE, vertices); +} + +static int ThumbstickWidget_Render2(void* widget, int offset) { + struct ThumbstickWidget* w = (struct ThumbstickWidget*)widget; + if (Gui.TouchTex) { + Gfx_BindTexture(Gui.TouchTex); + Gfx_DrawVb_IndexedTris_Range(4, offset); + } + return offset + 4; +} + +static const struct WidgetVTABLE ThumbstickWidget_VTABLE = { + NULL, Screen_NullFunc, Widget_CalcPosition, + Widget_Key, Widget_Key, Widget_MouseScroll, + Widget_Pointer, Widget_Pointer, Widget_PointerMove, + ThumbstickWidget_BuildMesh, ThumbstickWidget_Render2 +}; +void ThumbstickWidget_Init(struct ThumbstickWidget* w) { + Widget_Reset(w); + w->VTABLE = &ThumbstickWidget_VTABLE; + w->width = Display_ScaleX(128); + w->height = Display_ScaleY(128); +} + +void ThumbstickWidget_GetMovement(struct ThumbstickWidget* w, float* xMoving, float* zMoving) { + int i, dx, dy; + float len; + + for (i = 0; i < INPUT_MAX_POINTERS; i++) { + if (!(w->active & (1 << i))) continue; + + dx = Pointers[i].x - (w->x + w->width / 2); + dy = Pointers[i].y - (w->y + w->height / 2); + len = Math_SqrtF(dx * dx + dy * dy); + + if (!len) continue; + *xMoving += dx / len; + *zMoving += dy / len; + } +} +#endif diff --git a/src/Widgets.h b/src/Widgets.h index 23e997626..3f8c4267c 100644 --- a/src/Widgets.h +++ b/src/Widgets.h @@ -281,4 +281,12 @@ CC_NOINLINE void SpecialInputWidget_Create(struct SpecialInputWidget* w, struct CC_NOINLINE void SpecialInputWidget_Redraw(struct SpecialInputWidget* w); CC_NOINLINE void SpecialInputWidget_UpdateCols(struct SpecialInputWidget* w); CC_NOINLINE void SpecialInputWidget_SetActive(struct SpecialInputWidget* w, cc_bool active); + +#ifdef CC_BUILD_TOUCH +struct ThumbstickWidget { Widget_Body }; +#define THUMBSTICKWIDGET_MAX 4 + +void ThumbstickWidget_Init(struct ThumbstickWidget* w); +void ThumbstickWidget_GetMovement(struct ThumbstickWidget* w, float* xMoving, float* zMoving); +#endif #endif