From 10bd6222be82a7f64ddef76b963a0e6cfbe4b97a Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 27 Apr 2024 08:44:03 +1000 Subject: [PATCH] Move touch UI functionality to its own file --- src/AudioBackend.c | 2 +- src/Block.c | 3 +- src/Game.c | 8 +- src/Graphics_D3D11.c | 4 +- src/Graphics_D3D9.c | 4 +- src/Graphics_Dreamcast.c | 4 +- src/Graphics_GCWii.c | 4 +- src/Graphics_N64.c | 4 +- src/Graphics_NDS.c | 4 +- src/Graphics_PS1.c | 2 +- src/Graphics_PS2.c | 4 +- src/Graphics_PS3.c | 4 +- src/Graphics_PSP.c | 4 +- src/Graphics_PSVita.c | 4 +- src/Graphics_Saturn.c | 4 +- src/Graphics_SoftGPU.c | 4 +- src/Graphics_WiiU.c | 4 +- src/Graphics_Xbox.c | 4 +- src/Graphics_Xbox360.c | 4 +- src/Gui.c | 25 +- src/Gui.h | 5 +- src/Input.h | 16 - src/Menus.c | 425 +--------------------- src/Menus.h | 19 +- src/Platform_GCWii.c | 7 +- src/Platform_NDS.c | 7 +- src/Platform_Xbox.c | 7 +- src/Resources.c | 2 +- src/Screens.c | 305 +--------------- src/Screens.h | 3 + src/Stream.c | 4 +- src/TouchUI.c | 765 +++++++++++++++++++++++++++++++++++++++ src/_GLShared.h | 4 +- 33 files changed, 869 insertions(+), 800 deletions(-) create mode 100644 src/TouchUI.c diff --git a/src/AudioBackend.c b/src/AudioBackend.c index 5a4297c18..fafe33c75 100644 --- a/src/AudioBackend.c +++ b/src/AudioBackend.c @@ -624,7 +624,7 @@ void Audio_Close(struct AudioContext* ctx) { ctx->sampleRate = 0; } -static float Log10(float volume) { return Math_Log(volume) / Math_Log(10); } +static float Log10(float volume) { return Math_Log2(volume) / Math_Log2(10); } static void UpdateVolume(struct AudioContext* ctx) { /* Object doesn't exist until Audio_SetFormat is called */ diff --git a/src/Block.c b/src/Block.c index 293ed4390..9a974f0b7 100644 --- a/src/Block.c +++ b/src/Block.c @@ -512,7 +512,8 @@ int Block_FindID(const cc_string* name) { cc_string blockName; int block; - for (block = BLOCK_AIR; block < BLOCK_COUNT; block++) { + for (block = BLOCK_AIR; block < BLOCK_COUNT; block++) + { blockName = Block_UNSAFE_GetName(block); if (String_CaselessEquals(&blockName, name)) return block; } diff --git a/src/Game.c b/src/Game.c index 84cc4ab80..3f7d161a8 100644 --- a/src/Game.c +++ b/src/Game.c @@ -487,7 +487,7 @@ static void UpdateViewMatrix(void) { FrustumCulling_CalcFrustumEquations(&Gfx.Projection, &Gfx.View); } -static void Render3DFrame(double delta, float t) { +static void Render3DFrame(float delta, float t) { Vec3 pos; Gfx_LoadMatrix(MATRIX_PROJECTION, &Gfx.Projection); Gfx_LoadMatrix(MATRIX_VIEW, &Gfx.View); @@ -531,7 +531,7 @@ static void Render3DFrame(double delta, float t) { if (!Game_HideGui) HeldBlockRenderer_Render(delta); } -static void Render3D_Anaglyph(double delta, float t) { +static void Render3D_Anaglyph(float delta, float t) { struct Matrix proj = Gfx.Projection; struct Matrix view = Gfx.View; @@ -603,7 +603,7 @@ void Game_TakeScreenshot(void) { #endif } -static CC_INLINE void Game_DrawFrame(double delta, float t) { +static CC_INLINE void Game_DrawFrame(float delta, float t) { UpdateViewMatrix(); if (!Gui_GetBlocksWorld()) { @@ -635,7 +635,7 @@ static CC_INLINE void Game_DrawFrame(double delta, float t) { } #ifdef CC_BUILD_SPLITSCREEN -static void DrawSplitscreen(double delta, float t, int i, int x, int y, int w, int h) { +static void DrawSplitscreen(float delta, float t, int i, int x, int y, int w, int h) { Gfx_SetViewport(x, y, w, h); Entities.CurPlayer = &LocalPlayer_Instances[i]; diff --git a/src/Graphics_D3D11.c b/src/Graphics_D3D11.c index 1896d0a48..19f57f626 100644 --- a/src/Graphics_D3D11.c +++ b/src/Graphics_D3D11.c @@ -440,7 +440,7 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { // Deliberately swap zNear/zFar in projection matrix calculation to produce // a projection matrix that results in a reversed depth buffer @@ -450,7 +450,7 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f // Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh // NOTE: This calculation is shared with Direct3D 9 backend - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Graphics_D3D9.c b/src/Graphics_D3D9.c index 3d3a4c60d..8cf140ade 100644 --- a/src/Graphics_D3D9.c +++ b/src/Graphics_D3D9.c @@ -760,7 +760,7 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { /* Deliberately swap zNear/zFar in projection matrix calculation to produce */ /* a projection matrix that results in a reversed depth buffer */ @@ -770,7 +770,7 @@ void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, f /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */ /* NOTE: This calculation is shared with Direct3D 11 backend */ - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Graphics_Dreamcast.c b/src/Graphics_Dreamcast.c index 5a9440724..29f9e3145 100644 --- a/src/Graphics_Dreamcast.c +++ b/src/Graphics_Dreamcast.c @@ -104,10 +104,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */ diff --git a/src/Graphics_GCWii.c b/src/Graphics_GCWii.c index 48deb9a63..923b0cff3 100644 --- a/src/Graphics_GCWii.c +++ b/src/Graphics_GCWii.c @@ -446,10 +446,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -zFar / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); // Transposed, source guPersepctive https://github.com/devkitPro/libogc/blob/master/libogc/gu.c *matrix = Matrix_Identity; diff --git a/src/Graphics_N64.c b/src/Graphics_N64.c index ab106de45..1b26f0458 100644 --- a/src/Graphics_N64.c +++ b/src/Graphics_N64.c @@ -281,10 +281,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */ diff --git a/src/Graphics_NDS.c b/src/Graphics_NDS.c index d38054556..c88b1e370 100644 --- a/src/Graphics_NDS.c +++ b/src/Graphics_NDS.c @@ -220,10 +220,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */ diff --git a/src/Graphics_PS1.c b/src/Graphics_PS1.c index 203eed67e..ce21f156d 100644 --- a/src/Graphics_PS1.c +++ b/src/Graphics_PS1.c @@ -489,7 +489,7 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.01f; /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */ diff --git a/src/Graphics_PS2.c b/src/Graphics_PS2.c index ba7b1d050..383bd8677 100644 --- a/src/Graphics_PS2.c +++ b/src/Graphics_PS2.c @@ -412,11 +412,11 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear_ = zFar; float zFar_ = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For pos FOV based perspective matrix, left/right/top/bottom are calculated as: */ diff --git a/src/Graphics_PS3.c b/src/Graphics_PS3.c index 7c0bfbf3c..3283ba3dc 100644 --- a/src/Graphics_PS3.c +++ b/src/Graphics_PS3.c @@ -354,10 +354,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); // Same as Direct3D9 // TODO: should it be like OpenGL? ??? diff --git a/src/Graphics_PSP.c b/src/Graphics_PSP.c index 47d40e936..82b53a93e 100644 --- a/src/Graphics_PSP.c +++ b/src/Graphics_PSP.c @@ -205,10 +205,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); // Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum // For a FOV based perspective matrix, left/right/top/bottom are calculated as: diff --git a/src/Graphics_PSVita.c b/src/Graphics_PSVita.c index ce3932ee5..c96a799b6 100644 --- a/src/Graphics_PSVita.c +++ b/src/Graphics_PSVita.c @@ -728,10 +728,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); // Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum // For a FOV based perspective matrix, left/right/top/bottom are calculated as: diff --git a/src/Graphics_Saturn.c b/src/Graphics_Saturn.c index febb4f4af..0949fde19 100644 --- a/src/Graphics_Saturn.c +++ b/src/Graphics_Saturn.c @@ -272,11 +272,11 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.01f; /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */ - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Graphics_SoftGPU.c b/src/Graphics_SoftGPU.c index 669e46fc5..5b19f26fe 100644 --- a/src/Graphics_SoftGPU.c +++ b/src/Graphics_SoftGPU.c @@ -255,10 +255,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For pos FOV based perspective matrix, left/right/top/bottom are calculated as: */ diff --git a/src/Graphics_WiiU.c b/src/Graphics_WiiU.c index 521e77c46..899c0a3da 100644 --- a/src/Graphics_WiiU.c +++ b/src/Graphics_WiiU.c @@ -374,11 +374,11 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { // TODO verify this float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Graphics_Xbox.c b/src/Graphics_Xbox.c index c6479f89c..5580892bd 100644 --- a/src/Graphics_Xbox.c +++ b/src/Graphics_Xbox.c @@ -508,12 +508,12 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float } // https://github.com/XboxDev/nxdk/blob/master/samples/mesh/math3d.c#L292 -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; /* Source https://learn.microsoft.com/en-us/windows/win32/direct3d9/d3dxmatrixperspectivefovrh */ /* NOTE: This calculation is shared with Direct3D 11 backend */ - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Graphics_Xbox360.c b/src/Graphics_Xbox360.c index d485b4915..745729c02 100644 --- a/src/Graphics_Xbox360.c +++ b/src/Graphics_Xbox360.c @@ -349,11 +349,11 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = zNear / (zNear - zFar); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { // TODO verify this float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); *matrix = Matrix_Identity; matrix->row1.x = c / aspect; diff --git a/src/Gui.c b/src/Gui.c index e727c2b1e..06ebef00a 100644 --- a/src/Gui.c +++ b/src/Gui.c @@ -248,13 +248,12 @@ void Gui_Remove(struct Screen* s) { } void Gui_Add(struct Screen* s, int priority) { + struct Screen* existing; int i; Gui_RemoveCore(s); - /* Backwards loop since removing changes count and gui_screens */ - for (i = Gui.ScreensCount - 1; i >= 0; i--) - { - if (priorities[i] == priority) Gui_RemoveCore(Gui_Screens[i]); - } + + existing = Gui_GetScreen(priority); + if (existing) Gui_RemoveCore(existing); Gui_AddCore(s, priority); Gui_OnScreensChanged(); @@ -287,6 +286,15 @@ struct Screen* Gui_GetClosable(void) { return NULL; } +struct Screen* Gui_GetScreen(int priority) { + int i; + for (i = 0; i < Gui.ScreensCount; i++) + { + if (priorities[i] == priority) return Gui_Screens[i]; + } + return NULL; +} + void Gui_UpdateInputGrab(void) { Gui.InputGrab = Gui_GetInputGrab(); Camera_CheckFocus(); @@ -700,13 +708,6 @@ static void OnInit(void) { Event_Register_(&WindowEvents.Resized, NULL, OnResize); Event_Register_(&InputEvents.TextChanged, NULL, OnTextChanged); -#ifdef CC_BUILD_TOUCH - #define DEFAULT_SP_ONSCREEN (ONSCREEN_BTN_FLY | ONSCREEN_BTN_SPEED) - #define DEFAULT_MP_ONSCREEN (ONSCREEN_BTN_FLY | ONSCREEN_BTN_SPEED | ONSCREEN_BTN_CHAT) - Gui._onscreenButtons = Options_GetInt(OPT_TOUCH_BUTTONS, 0, Int32_MaxValue, - Server.IsSinglePlayer ? DEFAULT_SP_ONSCREEN : DEFAULT_MP_ONSCREEN); -#endif - LoadOptions(); Gui_ShowDefault(); } diff --git a/src/Gui.h b/src/Gui.h index c89a4fc2e..c9d9cc7b7 100644 --- a/src/Gui.h +++ b/src/Gui.h @@ -45,8 +45,7 @@ CC_VAR extern struct _GuiData { float RawHotbarScale, RawChatScale, RawInventoryScale, RawCrosshairScale; GfxResourceID GuiTex, GuiClassicTex, IconsTex, TouchTex; int DefaultLines; - /* (internal) Bitmask of on-screen buttons, see Input.h */ - int _onscreenButtons; + int __unused; float RawTouchScale; /* The highest priority screen that has grabbed input. */ struct Screen* InputGrab; @@ -259,6 +258,8 @@ CC_API struct Screen* Gui_GetInputGrab(void); struct Screen* Gui_GetBlocksWorld(void); /* Returns highest priority screen that is closable. */ struct Screen* Gui_GetClosable(void); +/* Returns screen with the given priority */ +CC_API struct Screen* Gui_GetScreen(int priority); void Gui_UpdateInputGrab(void); void Gui_ShowPauseMenu(void); diff --git a/src/Input.h b/src/Input.h index 7c7ea39ec..642090569 100644 --- a/src/Input.h +++ b/src/Input.h @@ -242,20 +242,4 @@ void InputHandler_OnScreensChanged(void); void InputHandler_DeleteBlock(void); void InputHandler_PlaceBlock(void); void InputHandler_PickBlock(void); - -/* Enumeration of on-screen buttons for touch GUI */ -#define ONSCREEN_BTN_CHAT (1 << 0) -#define ONSCREEN_BTN_LIST (1 << 1) -#define ONSCREEN_BTN_SPAWN (1 << 2) -#define ONSCREEN_BTN_SETSPAWN (1 << 3) -#define ONSCREEN_BTN_FLY (1 << 4) -#define ONSCREEN_BTN_NOCLIP (1 << 5) -#define ONSCREEN_BTN_SPEED (1 << 6) -#define ONSCREEN_BTN_HALFSPEED (1 << 7) -#define ONSCREEN_BTN_CAMERA (1 << 8) -#define ONSCREEN_BTN_DELETE (1 << 9) -#define ONSCREEN_BTN_PICK (1 << 10) -#define ONSCREEN_BTN_PLACE (1 << 11) -#define ONSCREEN_BTN_SWITCH (1 << 12) -#define ONSCREEN_MAX_BTNS 13 #endif diff --git a/src/Menus.c b/src/Menus.c index 121ee366d..f4875120e 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -41,34 +41,33 @@ struct MenuOptionDesc { Widget_LeftClick OnClick; Button_Get GetValue; Button_Set SetValue; }; -struct SimpleButtonDesc { short x, y; const char* title; Widget_LeftClick onClick; }; /*########################################################################################################################* *--------------------------------------------------------Menu base--------------------------------------------------------* *#########################################################################################################################*/ -static void Menu_AddButtons(void* screen, struct ButtonWidget* btns, int width, const struct SimpleButtonDesc* descs, int count) { +void Menu_AddButtons(void* screen, struct ButtonWidget* btns, int width, const struct SimpleButtonDesc* descs, int count) { int i; for (i = 0; i < count; i++) { ButtonWidget_Add(screen, &btns[i], width, descs[i].onClick); } } -static void Menu_LayoutButtons(struct ButtonWidget* btns, const struct SimpleButtonDesc* descs, int count) { +void Menu_LayoutButtons(struct ButtonWidget* btns, const struct SimpleButtonDesc* descs, int count) { int i; for (i = 0; i < count; i++) { Widget_SetLocation(&btns[i], ANCHOR_CENTRE, ANCHOR_CENTRE, descs[i].x, descs[i].y); } } -static void Menu_SetButtons(struct ButtonWidget* btns, struct FontDesc* font, const struct SimpleButtonDesc* descs, int count) { +void Menu_SetButtons(struct ButtonWidget* btns, struct FontDesc* font, const struct SimpleButtonDesc* descs, int count) { int i; for (i = 0; i < count; i++) { ButtonWidget_SetConst(&btns[i], descs[i].title, font); } } -static void Menu_LayoutBack(struct ButtonWidget* btn) { +void Menu_LayoutBack(struct ButtonWidget* btn) { Widget_SetLocation(btn, ANCHOR_CENTRE, ANCHOR_MAX, 0, 25); } static void Menu_CloseKeyboard(void* s) { OnscreenKeyboard_Close(); } @@ -470,7 +469,7 @@ void ListScreen_Show(void) { /*########################################################################################################################* *--------------------------------------------------------MenuScreen-------------------------------------------------------* *#########################################################################################################################*/ -static void MenuScreen_Render2(void* screen, float delta) { +void MenuScreen_Render2(void* screen, float delta) { Menu_RenderBounds(); Screen_Render2Widgets(screen, delta); } @@ -2204,7 +2203,6 @@ void HotbarBindingsScreen_Show(void) { /*########################################################################################################################* *--------------------------------------------------MenuInputOverlay-------------------------------------------------------* *#########################################################################################################################*/ -typedef void (*MenuInputDone)(const cc_string* value, cc_bool valid); static struct MenuInputOverlay { Screen_Body cc_bool screenMode; @@ -3966,416 +3964,3 @@ void TexPackOverlay_Show(const cc_string* url) { s->reqID = Http_AsyncGetHeaders(url, HTTP_FLAG_PRIORITY); Gui_Add((struct Screen*)s, GUI_PRIORITY_TEXPACK); } - - -#ifdef CC_BUILD_TOUCH -/*########################################################################################################################* -*---------------------------------------------------TouchControlsScreen---------------------------------------------------* -*#########################################################################################################################*/ -#define ONSCREEN_PAGE_BTNS 8 -static struct TouchOnscreenScreen { - Screen_Body - struct ButtonWidget back, left, right; - struct ButtonWidget btns[ONSCREEN_PAGE_BTNS]; - const struct SimpleButtonDesc* btnDescs; - struct FontDesc font; -} TouchOnscreenScreen; - -static struct Widget* touchOnscreen_widgets[3 + ONSCREEN_PAGE_BTNS] = { - (struct Widget*)&TouchOnscreenScreen.back, (struct Widget*)&TouchOnscreenScreen.left, - (struct Widget*)&TouchOnscreenScreen.right, (struct Widget*)&TouchOnscreenScreen.btns[0], - (struct Widget*)&TouchOnscreenScreen.btns[1], (struct Widget*)&TouchOnscreenScreen.btns[2], - (struct Widget*)&TouchOnscreenScreen.btns[3], (struct Widget*)&TouchOnscreenScreen.btns[4], - (struct Widget*)&TouchOnscreenScreen.btns[5], (struct Widget*)&TouchOnscreenScreen.btns[6], - (struct Widget*)&TouchOnscreenScreen.btns[7] -}; - -static void TouchOnscreen_UpdateColors(struct TouchOnscreenScreen* s) { - PackedCol grey = PackedCol_Make(0x7F, 0x7F, 0x7F, 0xFF); - int i, bit; - - for (i = 0; i < ONSCREEN_PAGE_BTNS; i++) - { - bit = s->btns[i].meta.val; - s->btns[i].color = (Gui._onscreenButtons & bit) ? PACKEDCOL_WHITE : grey; - } -} - -static void TouchOnscreen_Any(void* screen, void* w) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - struct ButtonWidget* btn = (struct ButtonWidget*)w; - int bit = btn->meta.val; - - if (Gui._onscreenButtons & bit) { - Gui._onscreenButtons &= ~bit; - } else { - Gui._onscreenButtons |= bit; - } - - Options_SetInt(OPT_TOUCH_BUTTONS, Gui._onscreenButtons); - TouchOnscreen_UpdateColors(s); - TouchScreen_Refresh(); -} -static void TouchOnscreen_More(void* s, void* w) { TouchCtrlsScreen_Show(); } - -static const struct SimpleButtonDesc touchOnscreen_page1[ONSCREEN_PAGE_BTNS] = { - { -120, -50, "Chat", TouchOnscreen_Any }, { 120, -50, "Tablist", TouchOnscreen_Any }, - { -120, 0, "Spawn", TouchOnscreen_Any }, { 120, 0, "Set spawn", TouchOnscreen_Any }, - { -120, 50, "Fly", TouchOnscreen_Any }, { 120, 50, "Noclip", TouchOnscreen_Any }, - { -120, 100, "Speed", TouchOnscreen_Any }, { 120, 100, "Half speed", TouchOnscreen_Any } -}; -static const struct SimpleButtonDesc touchOnscreen_page2[ONSCREEN_PAGE_BTNS] = { - { -120, -50, "Third person", TouchOnscreen_Any }, { 120, -50, "Delete", TouchOnscreen_Any }, - { -120, 0, "Pick", TouchOnscreen_Any }, { 120, 0, "Place", TouchOnscreen_Any }, - { -120, 50, "Switch hotbar", TouchOnscreen_Any }, { 120, 50, "---", TouchOnscreen_Any }, - { -120, 100, "---", TouchOnscreen_Any }, { 120, 100, "---", TouchOnscreen_Any } -}; - -static void TouchOnscreen_Left(void* screen, void* b); -static void TouchOnscreen_Right(void* screen, void* b); - -static void TouchOnscreen_RemakeWidgets(struct TouchOnscreenScreen* s, cc_bool page1) { - int i; - int offset = page1 ? 0 : ONSCREEN_PAGE_BTNS; - s->btnDescs = page1 ? touchOnscreen_page1 : touchOnscreen_page2; - - s->widgets = touchOnscreen_widgets; - s->numWidgets = 0; - s->maxWidgets = Array_Elems(touchOnscreen_widgets); - - Menu_AddButtons(s, s->btns, 200, s->btnDescs, ONSCREEN_PAGE_BTNS); - ButtonWidget_Add(s, &s->back, 400, TouchOnscreen_More); - ButtonWidget_Add(s, &s->left, 40, TouchOnscreen_Left); - ButtonWidget_Add(s, &s->right, 40, TouchOnscreen_Right); - - Widget_SetDisabled(&s->left, page1); - Widget_SetDisabled(&s->right, !page1); - - for (i = 0; i < ONSCREEN_PAGE_BTNS; i++) - { - s->btns[i].meta.val = 1 << (i + offset); - } -} - -static void TouchOnscreen_Left(void* screen, void* b) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - TouchOnscreen_RemakeWidgets(s, true); - Gui_Refresh((struct Screen*)s); - TouchOnscreen_UpdateColors(s); -} - -static void TouchOnscreen_Right(void* screen, void* b) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - TouchOnscreen_RemakeWidgets(s, false); - Gui_Refresh((struct Screen*)s); - TouchOnscreen_UpdateColors(s); -} - -static void TouchOnscreenScreen_ContextLost(void* screen) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - Font_Free(&s->font); - Screen_ContextLost(screen); -} - -static void TouchOnscreenScreen_ContextRecreated(void* screen) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - Gui_MakeTitleFont(&s->font); - Screen_UpdateVb(screen); - Menu_SetButtons(s->btns, &s->font, s->btnDescs, ONSCREEN_PAGE_BTNS); - ButtonWidget_SetConst(&s->back, "Done", &s->font); - ButtonWidget_SetConst(&s->left, "<", &s->font); - ButtonWidget_SetConst(&s->right, ">", &s->font); -} - -static void TouchOnscreenScreen_Layout(void* screen) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - Menu_LayoutButtons(s->btns, s->btnDescs, ONSCREEN_PAGE_BTNS); - Menu_LayoutBack(&s->back); - Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -260, 0); - Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 260, 0); -} - -static void TouchOnscreenScreen_Init(void* screen) { - struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; - TouchOnscreen_RemakeWidgets(s, true); - TouchOnscreen_UpdateColors(screen); - - s->maxVertices = Screen_CalcDefaultMaxVertices(s); -} - -static const struct ScreenVTABLE TouchOnscreenScreen_VTABLE = { - TouchOnscreenScreen_Init, Screen_NullUpdate, Screen_NullFunc, - MenuScreen_Render2, Screen_BuildMesh, - Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, - Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, - TouchOnscreenScreen_Layout, TouchOnscreenScreen_ContextLost, TouchOnscreenScreen_ContextRecreated -}; -void TouchOnscreenScreen_Show(void) { - struct TouchOnscreenScreen* s = &TouchOnscreenScreen; - s->grabsInput = true; - s->closable = true; - s->VTABLE = &TouchOnscreenScreen_VTABLE; - - Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); -} - - -/*########################################################################################################################* -*---------------------------------------------------TouchControlsScreen---------------------------------------------------* -*#########################################################################################################################*/ -#define TOUCHCTRLS_BTNS 5 -static struct TouchCtrlsScreen { - Screen_Body - struct ButtonWidget back; - struct ButtonWidget btns[TOUCHCTRLS_BTNS]; - struct FontDesc font; -} TouchCtrlsScreen; - -static struct Widget* touchCtrls_widgets[TOUCHCTRLS_BTNS + 1]; - -static const char* GetTapDesc(int mode) { - if (mode == INPUT_MODE_PLACE) return "Tap: Place"; - if (mode == INPUT_MODE_DELETE) return "Tap: Delete"; - return "Tap: None"; -} -static void TouchCtrls_UpdateTapText(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - ButtonWidget_SetConst(&s->btns[0], GetTapDesc(Input_TapMode), &s->font); - s->dirty = true; -} - -static const char* GetHoldDesc(int mode) { - if (mode == INPUT_MODE_PLACE) return "Hold: Place"; - if (mode == INPUT_MODE_DELETE) return "Hold: Delete"; - return "Hold: None"; -} -static void TouchCtrls_UpdateHoldText(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - ButtonWidget_SetConst(&s->btns[1], GetHoldDesc(Input_HoldMode), &s->font); - s->dirty = true; -} - -static void TouchCtrls_UpdateSensitivity(void* screen) { - cc_string value; char valueBuffer[STRING_SIZE]; - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - String_InitArray(value, valueBuffer); - - String_AppendConst(&value, "Sensitivity: "); - MiscOptionsScreen_GetSensitivity(&value); - ButtonWidget_Set(&s->btns[2], &value, &s->font); - s->dirty = true; -} - -static void TouchCtrls_UpdateScale(void* screen) { - cc_string value; char valueBuffer[STRING_SIZE]; - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - String_InitArray(value, valueBuffer); - - String_AppendConst(&value, "Scale: "); - String_AppendFloat(&value, Gui.RawTouchScale, 1); - ButtonWidget_Set(&s->btns[3], &value, &s->font); - s->dirty = true; -} - -static void TouchCtrls_More(void* s, void* w) { TouchMoreScreen_Show(); } -static void TouchCtrls_Onscreen(void* s, void* w) { TouchOnscreenScreen_Show(); } - -static void TouchCtrls_Tap(void* s, void* w) { - Input_TapMode = (Input_TapMode + 1) % INPUT_MODE_COUNT; - TouchCtrls_UpdateTapText(s); -} -static void TouchCtrls_Hold(void* s, void* w) { - Input_HoldMode = (Input_HoldMode + 1) % INPUT_MODE_COUNT; - TouchCtrls_UpdateHoldText(s); -} - -static void TouchCtrls_SensitivityDone(const cc_string* value, cc_bool valid) { - if (!valid) return; - MiscOptionsScreen_SetSensitivity(value); - TouchCtrls_UpdateSensitivity(&TouchCtrlsScreen); -} - -static void TouchCtrls_Sensitivity(void* screen, void* w) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - static struct MenuInputDesc desc; - cc_string value; char valueBuffer[STRING_SIZE]; - String_InitArray(value, valueBuffer); - - MenuInput_Int(desc, 1, 200, 30); - MiscOptionsScreen_GetSensitivity(&value); - MenuInputOverlay_Show(&desc, &value, TouchCtrls_SensitivityDone, true); - /* Fix Sensitivity button getting stuck as 'active' */ - /* (input overlay swallows subsequent pointer events) */ - s->btns[2].active = 0; -} - -static void TouchCtrls_ScaleDone(const cc_string* value, cc_bool valid) { - if (!valid) return; - ChatOptionsScreen_SetScale(value, &Gui.RawTouchScale, OPT_TOUCH_SCALE); - TouchCtrls_UpdateScale(&TouchCtrlsScreen); -} - -static void TouchCtrls_Scale(void* screen, void* w) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - static struct MenuInputDesc desc; - cc_string value; char valueBuffer[STRING_SIZE]; - String_InitArray(value, valueBuffer); - - MenuInput_Float(desc, 0.25f, 5.0f, 1.0f); - String_AppendFloat(&value, Gui.RawTouchScale, 1); - MenuInputOverlay_Show(&desc, &value, TouchCtrls_ScaleDone, true); - s->btns[3].active = 0; -} - -static const struct SimpleButtonDesc touchCtrls_btns[5] = { - { -102, -50, "", TouchCtrls_Tap }, - { 102, -50, "", TouchCtrls_Hold }, - { -102, 0, "", TouchCtrls_Sensitivity }, - { 102, 0, "", TouchCtrls_Scale }, - { 0, 50, "On-screen controls", TouchCtrls_Onscreen } -}; - -static void TouchCtrlsScreen_ContextLost(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - Font_Free(&s->font); - Screen_ContextLost(screen); -} - -static void TouchCtrlsScreen_ContextRecreated(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - Gui_MakeTitleFont(&s->font); - Screen_UpdateVb(screen); - Menu_SetButtons(s->btns, &s->font, touchCtrls_btns, TOUCHCTRLS_BTNS); - ButtonWidget_SetConst(&s->back, "Done", &s->font); - - TouchCtrls_UpdateTapText(s); - TouchCtrls_UpdateHoldText(s); - TouchCtrls_UpdateSensitivity(s); - TouchCtrls_UpdateScale(s); -} - -static void TouchCtrlsScreen_Layout(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - Menu_LayoutButtons(s->btns, touchCtrls_btns, TOUCHCTRLS_BTNS); - Menu_LayoutBack(&s->back); -} - -static void TouchCtrlsScreen_Init(void* screen) { - struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; - s->widgets = touchCtrls_widgets; - s->numWidgets = 0; - s->maxWidgets = Array_Elems(touchCtrls_widgets); - - Menu_AddButtons(s, s->btns, 195, touchCtrls_btns, 4); - Menu_AddButtons(s, s->btns + 4, 400, touchCtrls_btns + 4, 1); - ButtonWidget_Add(s, &s->back, 400, TouchCtrls_More); - - s->maxVertices = Screen_CalcDefaultMaxVertices(s); -} - -static const struct ScreenVTABLE TouchCtrlsScreen_VTABLE = { - TouchCtrlsScreen_Init, Screen_NullUpdate, Screen_NullFunc, - MenuScreen_Render2, Screen_BuildMesh, - Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, - Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, - TouchCtrlsScreen_Layout, TouchCtrlsScreen_ContextLost, TouchCtrlsScreen_ContextRecreated -}; -void TouchCtrlsScreen_Show(void) { - struct TouchCtrlsScreen* s = &TouchCtrlsScreen; - s->grabsInput = true; - s->closable = true; - s->VTABLE = &TouchCtrlsScreen_VTABLE; - - Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); -} - - -/*########################################################################################################################* -*-----------------------------------------------------TouchMoreScreen-----------------------------------------------------* -*#########################################################################################################################*/ -#define TOUCHMORE_BTNS 6 -static struct TouchMoreScreen { - Screen_Body - struct ButtonWidget back; - struct ButtonWidget btns[TOUCHMORE_BTNS]; -} TouchMoreScreen; - -static struct Widget* touchMore_widgets[TOUCHMORE_BTNS + 1]; - -static void TouchMore_Take(void* s, void* w) { - Gui_Remove((struct Screen*)&TouchMoreScreen); - Game_ScreenshotRequested = true; -} -static void TouchMore_Screen(void* s, void* w) { - Gui_Remove((struct Screen*)&TouchMoreScreen); - Game_ToggleFullscreen(); -} -static void TouchMore_Ctrls(void* s, void* w) { TouchCtrlsScreen_Show(); } -static void TouchMore_Menu(void* s, void* w) { - Gui_Remove((struct Screen*)&TouchMoreScreen); - Gui_ShowPauseMenu(); -} -static void TouchMore_Game(void* s, void* w) { - Gui_Remove((struct Screen*)&TouchMoreScreen); -} -static void TouchMore_Chat(void* s, void* w) { - Gui_Remove((struct Screen*)&TouchMoreScreen); - ChatScreen_OpenInput(&String_Empty); -} -static void TouchMore_Fog(void* s, void* w) { Game_CycleViewDistance(); } - -static const struct SimpleButtonDesc touchMore_btns[TOUCHMORE_BTNS] = { - { -102, -50, "Screenshot", TouchMore_Take }, - { -102, 0, "Fullscreen", TouchMore_Screen }, - { 102, -50, "Chat", TouchMore_Chat }, - { 102, 0, "Fog", TouchMore_Fog }, - { 0, 50, "Controls", TouchMore_Ctrls }, - { 0, 100, "Main menu", TouchMore_Menu } -}; - -static void TouchMoreScreen_ContextRecreated(void* screen) { - struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; - struct FontDesc titleFont; - Gui_MakeTitleFont(&titleFont); - Screen_UpdateVb(screen); - - Menu_SetButtons(s->btns, &titleFont, touchMore_btns, TOUCHMORE_BTNS); - ButtonWidget_SetConst(&s->back, "Back to game", &titleFont); - Font_Free(&titleFont); -} - -static void TouchMoreScreen_Layout(void* screen) { - struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; - Menu_LayoutButtons(s->btns, touchMore_btns, TOUCHMORE_BTNS); - Menu_LayoutBack(&s->back); -} - -static void TouchMoreScreen_Init(void* screen) { - struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; - s->widgets = touchMore_widgets; - s->numWidgets = 0; - s->maxWidgets = Array_Elems(touchMore_widgets); - - Menu_AddButtons(s, s->btns, 195, touchMore_btns, 4); - Menu_AddButtons(s, s->btns + 4, 400, touchMore_btns + 4, 2); - ButtonWidget_Add(s, &s->back, 400, TouchMore_Game); - - s->maxVertices = Screen_CalcDefaultMaxVertices(s); -} - -static const struct ScreenVTABLE TouchMoreScreen_VTABLE = { - TouchMoreScreen_Init, Screen_NullUpdate, Screen_NullFunc, - MenuScreen_Render2, Screen_BuildMesh, - Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, - Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, - TouchMoreScreen_Layout, Screen_ContextLost, TouchMoreScreen_ContextRecreated -}; -void TouchMoreScreen_Show(void) { - struct TouchMoreScreen* s = &TouchMoreScreen; - s->grabsInput = true; - s->closable = true; - s->VTABLE = &TouchMoreScreen_VTABLE; - - Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); -} -#endif diff --git a/src/Menus.h b/src/Menus.h index 78346ce47..84f55d122 100644 --- a/src/Menus.h +++ b/src/Menus.h @@ -1,15 +1,28 @@ #ifndef CC_MENUS_H #define CC_MENUS_H -#include "Core.h" +#include "Gui.h" /* Contains all 2D menu screen implementations. Copyright 2014-2023 ClassiCube | Licensed under BSD-3 */ struct Screen; +struct MenuInputDesc; +struct FontDesc; +struct ButtonWidget; + int Menu_InputDown(void* screen, int key); int Menu_PointerDown(void* screen, int id, int x, int y); int Menu_PointerMove(void* screen, int id, int x, int y); +struct SimpleButtonDesc { short x, y; const char* title; Widget_LeftClick onClick; }; +void Menu_AddButtons(void* screen, struct ButtonWidget* btns, int width, + const struct SimpleButtonDesc* descs, int count); +void Menu_LayoutButtons(struct ButtonWidget* btns, + const struct SimpleButtonDesc* descs, int count); +void Menu_SetButtons(struct ButtonWidget* btns, struct FontDesc* font, + const struct SimpleButtonDesc* descs, int count); +void Menu_LayoutBack(struct ButtonWidget* btn); + void PauseScreen_Show(void); void OptionsGroupScreen_Show(void); void ClassicOptionsScreen_Show(void); @@ -49,4 +62,8 @@ void TouchCtrlsScreen_Show(void); void TouchMoreScreen_Show(void); void TouchOnscreenScreen_Show(void); #endif + +void MenuScreen_Render2(void* screen, float delta); +typedef void (*MenuInputDone)(const cc_string* value, cc_bool valid); +void MenuInputOverlay_Show(struct MenuInputDesc* desc, const cc_string* value, MenuInputDone onDone, cc_bool screenMode); #endif diff --git a/src/Platform_GCWii.c b/src/Platform_GCWii.c index 2e498a539..9f660cd84 100644 --- a/src/Platform_GCWii.c +++ b/src/Platform_GCWii.c @@ -189,8 +189,6 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall } static cc_result File_Do(cc_file* file, const cc_string* path, int mode) { - if (!fat_available) return ENOSYS; - char str[NATIVE_STR_LEN]; GetNativePath(str, path); *file = open(str, mode, 0); @@ -198,12 +196,17 @@ static cc_result File_Do(cc_file* file, const cc_string* path, int mode) { } cc_result File_Open(cc_file* file, const cc_string* path) { + if (!fat_available) return ReturnCode_FileNotFound; return File_Do(file, path, O_RDONLY); } + cc_result File_Create(cc_file* file, const cc_string* path) { + if (!fat_available) return ENOTSUP; return File_Do(file, path, O_RDWR | O_CREAT | O_TRUNC); } + cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) { + if (!fat_available) return ENOTSUP; return File_Do(file, path, O_RDWR | O_CREAT); } diff --git a/src/Platform_NDS.c b/src/Platform_NDS.c index 9558b051c..440a76dd5 100644 --- a/src/Platform_NDS.c +++ b/src/Platform_NDS.c @@ -145,8 +145,6 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall } static cc_result File_Do(cc_file* file, const cc_string* path, int mode) { - if (!fat_available) return ENOSYS; - char str[NATIVE_STR_LEN]; GetNativePath(str, path); *file = open(str, mode, 0); @@ -154,12 +152,17 @@ static cc_result File_Do(cc_file* file, const cc_string* path, int mode) { } cc_result File_Open(cc_file* file, const cc_string* path) { + if (!fat_available) return ReturnCode_FileNotFound; return File_Do(file, path, O_RDONLY); } + cc_result File_Create(cc_file* file, const cc_string* path) { + if (!fat_available) return ENOTSUP; return File_Do(file, path, O_RDWR | O_CREAT | O_TRUNC); } + cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) { + if (!fat_available) return ENOTSUP; return File_Do(file, path, O_RDWR | O_CREAT); } diff --git a/src/Platform_Xbox.c b/src/Platform_Xbox.c index 9ac670794..cea3e781e 100644 --- a/src/Platform_Xbox.c +++ b/src/Platform_Xbox.c @@ -169,8 +169,6 @@ cc_result Directory_Enum(const cc_string* dirPath, void* obj, Directory_EnumCall } static cc_result DoFile(cc_file* file, const cc_string* path, DWORD access, DWORD createMode) { - if (!hdd_mounted) return ERR_NOT_SUPPORTED; - char str[NATIVE_STR_LEN]; GetNativePath(str, path); cc_result res; @@ -180,12 +178,17 @@ static cc_result DoFile(cc_file* file, const cc_string* path, DWORD access, DWOR } cc_result File_Open(cc_file* file, const cc_string* path) { + if (!hdd_mounted) return ReturnCode_FileNotFound; return DoFile(file, path, GENERIC_READ, OPEN_EXISTING); } + cc_result File_Create(cc_file* file, const cc_string* path) { + if (!hdd_mounted) return ERR_NOT_SUPPORTED; return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, CREATE_ALWAYS); } + cc_result File_OpenOrCreate(cc_file* file, const cc_string* path) { + if (!hdd_mounted) return ERR_NOT_SUPPORTED; return DoFile(file, path, GENERIC_WRITE | GENERIC_READ, OPEN_ALWAYS); } diff --git a/src/Resources.c b/src/Resources.c index 167fc7aba..4040634aa 100644 --- a/src/Resources.c +++ b/src/Resources.c @@ -297,7 +297,7 @@ static cc_result ZipWriter_FixupLocalFile(struct Stream* s, struct ResourceZipEn e->crc32 = crc ^ 0xffffffffUL; /* then fixup the header */ - if ((res = s->Seek(s, e->offset))) return res; + if ((res = s->Seek(s, e->offset))) return res; if ((res = ZipWriter_LocalFile(s, e))) return res; return s->Seek(s, dataEnd); } diff --git a/src/Screens.c b/src/Screens.c index e8ca0fe43..af7a71589 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -211,7 +211,7 @@ static void HUDScreen_ContextRecreated(void* screen) { HUDScreen_RemakeLine2(s); } -static int HUDScreen_LayoutHotbar(void) { +int HUDScreen_LayoutHotbar(void) { struct HUDScreen* s = &HUDScreen_Instance; s->hotbar.scale = Gui_GetHotbarScale(); Widget_Layout(&s->hotbar); @@ -871,10 +871,10 @@ static const struct ScreenVTABLE TabListOverlay_VTABLE = { TabListOverlay_PointerDown, Screen_PointerUp, Screen_FPointer, Screen_FMouseScroll, TabListOverlay_Layout, TabListOverlay_ContextLost, TabListOverlay_ContextRecreated }; -void TabListOverlay_Show(void) { +void TabListOverlay_Show(cc_bool staysOpen) { struct TabListOverlay* s = &TabListOverlay_Instance; s->VTABLE = &TabListOverlay_VTABLE; - s->staysOpen = false; + s->staysOpen = staysOpen; Gui_Add((struct Screen*)s, GUI_PRIORITY_TABLIST); } @@ -1318,7 +1318,7 @@ static int ChatScreen_KeyDown(void* screen, int key) { if (KeyBind_Claims(KEYBIND_TABLIST, key) && handlesList) { if (!tablist_active && !Server.IsSinglePlayer) { - TabListOverlay_Show(); + TabListOverlay_Show(false); } return true; } @@ -2198,300 +2198,3 @@ void DisconnectScreen_Show(const cc_string* title, const cc_string* message) { Gui_Remove(Gui_Screens[i]); } } - - -/*########################################################################################################################* -*--------------------------------------------------------TouchScreen------------------------------------------------------* -*#########################################################################################################################*/ -#ifdef CC_BUILD_TOUCH -#define TOUCH_EXTRA_BTNS 2 -#define TOUCH_MAX_BTNS (ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS + 1) -struct TouchButtonDesc { - const char* text; - cc_uint8 bind, x, y; - Widget_LeftClick OnClick; - cc_bool* enabled; -}; - -static struct TouchScreen { - Screen_Body - const struct TouchButtonDesc* descs; - int numOnscreen, numBtns; - struct FontDesc font; - struct ThumbstickWidget thumbstick; - const struct TouchButtonDesc* onscreenDescs[ONSCREEN_MAX_BTNS]; - struct ButtonWidget onscreen[ONSCREEN_MAX_BTNS]; - struct ButtonWidget btns[TOUCH_EXTRA_BTNS], more; -} TouchScreen; - -static struct Widget* touch_widgets[ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS + 2] = { - NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL, NULL, - NULL,NULL, (struct Widget*)&TouchScreen.thumbstick, (struct Widget*)&TouchScreen.more -}; -#define TOUCH_MAX_VERTICES (THUMBSTICKWIDGET_MAX + TOUCH_MAX_BTNS * BUTTONWIDGET_MAX) - -static void TouchScreen_ChatClick(void* s, void* w) { ChatScreen_OpenInput(&String_Empty); } -static void TouchScreen_RespawnClick(void* s, void* w) { LocalPlayer_HandleRespawn(Entities.CurPlayer); } -static void TouchScreen_SetSpawnClick(void* s, void* w) { LocalPlayer_HandleSetSpawn(Entities.CurPlayer); } -static void TouchScreen_FlyClick(void* s, void* w) { LocalPlayer_HandleFly(Entities.CurPlayer); } -static void TouchScreen_NoclipClick(void* s, void* w) { LocalPlayer_HandleNoclip(Entities.CurPlayer); } -static void TouchScreen_CameraClick(void* s, void* w) { Camera_CycleActive(); } -static void TouchScreen_MoreClick(void* s, void* w) { TouchMoreScreen_Show(); } -static void TouchScreen_SwitchClick(void* s, void* w) { Inventory_SwitchHotbar(); } -static void TouchScreen_DeleteClick(void* s, void* w) { InputHandler_DeleteBlock(); } /* TODO: also Send CPEClick packet */ -static void TouchScreen_PlaceClick(void* s, void* w) { InputHandler_PlaceBlock(); } -static void TouchScreen_PickClick(void* s, void* w) { InputHandler_PickBlock(); } - -static void TouchScreen_TabClick(void* s, void* w) { - if (tablist_active) { - Gui_Remove((struct Screen*)&TabListOverlay_Instance); - } else { - TabListOverlay_Show(); - TabListOverlay_Instance.staysOpen = true; - } -} - -static void TouchScreen_SpeedClick(void* s, void* w) { - struct HacksComp* hacks = &Entities.CurPlayer->Hacks; - if (hacks->Enabled) hacks->Speeding = !hacks->Speeding; -} -static void TouchScreen_HalfClick(void* s, void* w) { - struct HacksComp* hacks = &Entities.CurPlayer->Hacks; - if (hacks->Enabled) hacks->HalfSpeeding = !hacks->HalfSpeeding; -} - -static void TouchScreen_BindClick(void* screen, void* widget) { - struct TouchScreen* s = (struct TouchScreen*)screen; - struct ButtonWidget* btn = (struct ButtonWidget*)widget; - - int i = btn->meta.val; - Input_Set(KeyBinds_Normal[s->descs[i].bind], true); -} - -static const struct TouchButtonDesc onscreenDescs[ONSCREEN_MAX_BTNS] = { - { "Chat", 0,0,0, TouchScreen_ChatClick }, - { "Tablist", 0,0,0, TouchScreen_TabClick }, - { "Respawn", 0,0,0, TouchScreen_RespawnClick, &LocalPlayer_Instances[0].Hacks.CanRespawn }, - { "Set spawn", 0,0,0, TouchScreen_SetSpawnClick, &LocalPlayer_Instances[0].Hacks.CanRespawn }, - { "Fly", 0,0,0, TouchScreen_FlyClick, &LocalPlayer_Instances[0].Hacks.CanFly }, - { "Noclip", 0,0,0, TouchScreen_NoclipClick, &LocalPlayer_Instances[0].Hacks.CanNoclip }, - { "Speed", 0,0,0, TouchScreen_SpeedClick, &LocalPlayer_Instances[0].Hacks.CanSpeed }, - { "\xabSpeed", 0,0,0, TouchScreen_HalfClick, &LocalPlayer_Instances[0].Hacks.CanSpeed }, - { "Camera", 0,0,0, TouchScreen_CameraClick, &LocalPlayer_Instances[0].Hacks.CanUseThirdPerson }, - { "Delete", 0,0,0, TouchScreen_DeleteClick }, - { "Pick", 0,0,0, TouchScreen_PickClick }, - { "Place", 0,0,0, TouchScreen_PlaceClick }, - { "Hotbar", 0,0,0, TouchScreen_SwitchClick } -}; -static const struct TouchButtonDesc normDescs[1] = { - { "\x1E", KEYBIND_JUMP, 50, 10, TouchScreen_BindClick } -}; -static const struct TouchButtonDesc hackDescs[2] = { - { "\x1E", KEYBIND_FLY_UP, 50, 70, TouchScreen_BindClick }, - { "\x1F", KEYBIND_FLY_DOWN, 50, 10, TouchScreen_BindClick } -}; - -#define TOUCHSCREEN_BTN_COLOR PackedCol_Make(255, 255, 255, 220) -static void TouchScreen_InitButtons(struct TouchScreen* s) { - struct HacksComp* hacks = &Entities.CurPlayer->Hacks; - const struct TouchButtonDesc* desc; - int i, j; - for (i = 0; i < ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS; i++) s->widgets[i] = NULL; - - for (i = 0, j = 0; i < ONSCREEN_MAX_BTNS; i++) - { - if (!(Gui._onscreenButtons & (1 << i))) continue; - desc = &onscreenDescs[i]; - - ButtonWidget_Init(&s->onscreen[j], 100, desc->OnClick); - if (desc->enabled) Widget_SetDisabled(&s->onscreen[j], !(*desc->enabled)); - - s->onscreenDescs[j] = desc; - s->widgets[j] = (struct Widget*)&s->onscreen[j]; - j++; - } - - s->numOnscreen = j; - if (hacks->Flying || hacks->Noclip) { - s->descs = hackDescs; - s->numBtns = Array_Elems(hackDescs); - } else { - s->descs = normDescs; - s->numBtns = Array_Elems(normDescs); - } - - for (i = 0; i < s->numBtns; i++) - { - s->widgets[i + ONSCREEN_MAX_BTNS] = (struct Widget*)&s->btns[i]; - ButtonWidget_Init(&s->btns[i], 60, s->descs[i].OnClick); - s->btns[i].color = TOUCHSCREEN_BTN_COLOR; - s->btns[i].meta.val = i; - } -} - -void TouchScreen_Refresh(void) { - struct TouchScreen* s = &TouchScreen; - /* InitButtons changes number of widgets, hence */ - /* must destroy graphics resources BEFORE that */ - Screen_ContextLost(s); - TouchScreen_InitButtons(s); - Gui_Refresh((struct Screen*)s); -} -static void TouchScreen_HacksChanged(void* s) { TouchScreen_Refresh(); } - -static void TouchScreen_ContextLost(void* screen) { - struct TouchScreen* s = (struct TouchScreen*)screen; - Font_Free(&s->font); - Screen_ContextLost(screen); -} - -static void TouchScreen_ContextRecreated(void* screen) { - struct TouchScreen* s = (struct TouchScreen*)screen; - const struct TouchButtonDesc* desc; - int i; - Screen_UpdateVb(screen); - Gui_MakeTitleFont(&s->font); - - for (i = 0; i < s->numOnscreen; i++) - { - desc = s->onscreenDescs[i]; - ButtonWidget_SetConst(&s->onscreen[i], desc->text, &s->font); - } - for (i = 0; i < s->numBtns; i++) - { - desc = &s->descs[i]; - ButtonWidget_SetConst(&s->btns[i], desc->text, &s->font); - } - ButtonWidget_SetConst(&s->more, "...", &s->font); -} - -static void TouchScreen_Render(void* screen, float delta) { - if (Gui.InputGrab) return; - Screen_Render2Widgets(screen, delta); -} - -static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { - struct TouchScreen* s = (struct TouchScreen*)screen; - struct Widget* w; - int i; - //Chat_Add1("POINTER DOWN: %i", &id); - if (Gui.InputGrab) return false; - - i = Screen_DoPointerDown(screen, id, x, y); - if (i < ONSCREEN_MAX_BTNS) return i >= 0; - - /* Clicking on other buttons then */ - w = s->widgets[i]; - w->active |= id; - - /* Clicking on jump or fly buttons should still move camera */ - for (i = 0; i < s->numBtns; i++) - { - if (w == (struct Widget*)&s->btns[i]) return TOUCH_TYPE_GUI | TOUCH_TYPE_CAMERA; - } - return TOUCH_TYPE_GUI; -} - -static void 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; - s->more.active &= ~id; - - for (i = 0; i < s->numBtns; i++) - { - if (!(s->btns[i].active & id)) continue; - - if (s->descs[i].bind < KEYBIND_COUNT) { - Input_Set(KeyBinds_Normal[s->descs[i].bind], false); - } - s->btns[i].active &= ~id; - return; - } -} - -static void TouchScreen_Layout(void* screen) { - struct TouchScreen* s = (struct TouchScreen*)screen; - const struct TouchButtonDesc* desc; - float scale = Gui.RawTouchScale; - int i, x, y, height; - - /* Need to align these relative to the hotbar */ - height = HUDScreen_LayoutHotbar(); - - for (i = 0; i < s->numBtns; i++) - { - desc = &s->descs[i]; - Widget_SetLocation(&s->btns[i], ANCHOR_MAX, ANCHOR_MAX, desc->x, desc->y); - s->btns[i].yOffset += height; - - /* TODO: Maybe move scaling to be part of button instead */ - s->btns[i].minWidth = Display_ScaleX(60 * scale); - s->btns[i].minHeight = Display_ScaleY(60 * scale); - Widget_Layout(&s->btns[i]); - } - - for (i = 0, x = 10, y = 10; i < s->numOnscreen; i++, y += 40) - { - Widget_SetLocation(&s->onscreen[i], ANCHOR_MAX, ANCHOR_MIN, x, y); - if (s->onscreen[i].y + s->onscreen[i].height <= s->btns[0].y) continue; - - // overflowed onto jump/fly buttons, move to next column - y = 10; - x += 110; - Widget_SetLocation(&s->onscreen[i], ANCHOR_MAX, ANCHOR_MIN, x, y); - } - Widget_SetLocation(&s->more, ANCHOR_CENTRE, ANCHOR_MIN, 0, 10); - - Widget_SetLocation(&s->thumbstick, ANCHOR_MIN, ANCHOR_MAX, 30, 5); - s->thumbstick.yOffset += height; - s->thumbstick.scale = scale; - Widget_Layout(&s->thumbstick); -} - -static void TouchScreen_GetMovement(struct LocalPlayer* p, float* xMoving, float* zMoving) { - ThumbstickWidget_GetMovement(&TouchScreen.thumbstick, xMoving, zMoving); -} -static struct LocalPlayerInput touchInput = { TouchScreen_GetMovement }; -static cc_bool touchHooked; - -static void TouchScreen_Init(void* screen) { - struct TouchScreen* s = (struct TouchScreen*)screen; - - s->widgets = touch_widgets; - s->numWidgets = Array_Elems(touch_widgets); - s->maxVertices = TOUCH_MAX_VERTICES; - Event_Register_(&UserEvents.HacksStateChanged, screen, TouchScreen_HacksChanged); - Event_Register_(&UserEvents.HackPermsChanged, screen, TouchScreen_HacksChanged); - - TouchScreen_InitButtons(s); - ButtonWidget_Init(&s->more, 40, TouchScreen_MoreClick); - s->more.color = TOUCHSCREEN_BTN_COLOR; - ThumbstickWidget_Init(&s->thumbstick); - - if (touchHooked) return; - touchHooked = true; - LocalPlayerInput_Add(&touchInput); -} - -static void TouchScreen_Free(void* s) { - Event_Unregister_(&UserEvents.HacksStateChanged, s, TouchScreen_HacksChanged); - Event_Unregister_(&UserEvents.HackPermsChanged, s, TouchScreen_HacksChanged); -} - -static const struct ScreenVTABLE TouchScreen_VTABLE = { - TouchScreen_Init, Screen_NullUpdate, TouchScreen_Free, - TouchScreen_Render, Screen_BuildMesh, - Screen_FInput, Screen_InputUp, Screen_FKeyPress, Screen_FText, - TouchScreen_PointerDown, TouchScreen_PointerUp, Screen_FPointer, Screen_FMouseScroll, - TouchScreen_Layout, TouchScreen_ContextLost, TouchScreen_ContextRecreated -}; -void TouchScreen_Show(void) { - struct TouchScreen* s = &TouchScreen; - s->VTABLE = &TouchScreen_VTABLE; - - if (!Gui.TouchUI) return; - Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCH); -} -#endif diff --git a/src/Screens.h b/src/Screens.h index 7774b6694..f0d2c57e6 100644 --- a/src/Screens.h +++ b/src/Screens.h @@ -34,6 +34,9 @@ void TouchScreen_Refresh(void); void TouchScreen_Show(void); #endif +int HUDScreen_LayoutHotbar(void); +void TabListOverlay_Show(cc_bool staysOpen); + /* Opens chat input for the HUD with the given initial text. */ void ChatScreen_OpenInput(const cc_string* text); /* Appends text to the chat input in the HUD. */ diff --git a/src/Stream.c b/src/Stream.c index 32b890f42..80199f0ce 100644 --- a/src/Stream.c +++ b/src/Stream.c @@ -339,7 +339,7 @@ static cc_result Stream_BufferedSeek(struct Stream* s, cc_uint32 position) { s->meta.buffered.cur = s->meta.buffered.base; s->meta.buffered.left = 0; - s->meta.buffered.end = position; + s->meta.buffered.end = position; return res; } @@ -350,7 +350,7 @@ void Stream_ReadonlyBuffered(struct Stream* s, struct Stream* source, void* data s->Seek = Stream_BufferedSeek; s->meta.buffered.left = 0; - s->meta.buffered.end = 0; + s->meta.buffered.end = 0; s->meta.buffered.cur = (cc_uint8*)data; s->meta.buffered.base = (cc_uint8*)data; s->meta.buffered.length = size; diff --git a/src/TouchUI.c b/src/TouchUI.c new file mode 100644 index 000000000..4496cd145 --- /dev/null +++ b/src/TouchUI.c @@ -0,0 +1,765 @@ +#include "Screens.h" +#ifdef CC_BUILD_TOUCH +#include "Widgets.h" +#include "Game.h" +#include "Event.h" +#include "Platform.h" +#include "Inventory.h" +#include "Drawer2D.h" +#include "Graphics.h" +#include "Funcs.h" +#include "TexturePack.h" +#include "Model.h" +#include "Generator.h" +#include "Server.h" +#include "Chat.h" +#include "ExtMath.h" +#include "Window.h" +#include "Camera.h" +#include "Http.h" +#include "Block.h" +#include "Menus.h" +#include "World.h" +#include "Input.h" +#include "Utils.h" +#include "Options.h" + + +/* Enumeration of on-screen buttons for touch GUI */ +#define ONSCREEN_BTN_CHAT (1 << 0) +#define ONSCREEN_BTN_LIST (1 << 1) +#define ONSCREEN_BTN_SPAWN (1 << 2) +#define ONSCREEN_BTN_SETSPAWN (1 << 3) +#define ONSCREEN_BTN_FLY (1 << 4) +#define ONSCREEN_BTN_NOCLIP (1 << 5) +#define ONSCREEN_BTN_SPEED (1 << 6) +#define ONSCREEN_BTN_HALFSPEED (1 << 7) +#define ONSCREEN_BTN_CAMERA (1 << 8) +#define ONSCREEN_BTN_DELETE (1 << 9) +#define ONSCREEN_BTN_PICK (1 << 10) +#define ONSCREEN_BTN_PLACE (1 << 11) +#define ONSCREEN_BTN_SWITCH (1 << 12) +#define ONSCREEN_MAX_BTNS 13 + +static int GetOnscreenButtons(void) { + #define DEFAULT_SP_ONSCREEN (ONSCREEN_BTN_FLY | ONSCREEN_BTN_SPEED) + #define DEFAULT_MP_ONSCREEN (ONSCREEN_BTN_FLY | ONSCREEN_BTN_SPEED | ONSCREEN_BTN_CHAT) + + return Options_GetInt(OPT_TOUCH_BUTTONS, 0, Int32_MaxValue, + Server.IsSinglePlayer ? DEFAULT_SP_ONSCREEN : DEFAULT_MP_ONSCREEN); +} + +/*########################################################################################################################* +*---------------------------------------------------TouchControlsScreen---------------------------------------------------* +*#########################################################################################################################*/ +#define ONSCREEN_PAGE_BTNS 8 +static struct TouchOnscreenScreen { + Screen_Body + struct ButtonWidget back, left, right; + struct ButtonWidget btns[ONSCREEN_PAGE_BTNS]; + const struct SimpleButtonDesc* btnDescs; + struct FontDesc font; +} TouchOnscreenScreen; + +static struct Widget* touchOnscreen_widgets[3 + ONSCREEN_PAGE_BTNS] = { + (struct Widget*)&TouchOnscreenScreen.back, (struct Widget*)&TouchOnscreenScreen.left, + (struct Widget*)&TouchOnscreenScreen.right, (struct Widget*)&TouchOnscreenScreen.btns[0], + (struct Widget*)&TouchOnscreenScreen.btns[1], (struct Widget*)&TouchOnscreenScreen.btns[2], + (struct Widget*)&TouchOnscreenScreen.btns[3], (struct Widget*)&TouchOnscreenScreen.btns[4], + (struct Widget*)&TouchOnscreenScreen.btns[5], (struct Widget*)&TouchOnscreenScreen.btns[6], + (struct Widget*)&TouchOnscreenScreen.btns[7] +}; + +static void TouchOnscreen_UpdateColors(struct TouchOnscreenScreen* s) { + PackedCol grey = PackedCol_Make(0x7F, 0x7F, 0x7F, 0xFF); + int buttons = GetOnscreenButtons(); + int i, bit; + + for (i = 0; i < ONSCREEN_PAGE_BTNS; i++) + { + bit = s->btns[i].meta.val; + s->btns[i].color = (buttons & bit) ? PACKEDCOL_WHITE : grey; + } +} + +static void TouchOnscreen_Any(void* screen, void* w) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + struct ButtonWidget* btn = (struct ButtonWidget*)w; + int buttons = GetOnscreenButtons(); + int bit = btn->meta.val; + + if (buttons & bit) { + buttons &= ~bit; + } else { + buttons |= bit; + } + + Options_SetInt(OPT_TOUCH_BUTTONS, buttons); + TouchOnscreen_UpdateColors(s); + TouchScreen_Refresh(); +} +static void TouchOnscreen_More(void* s, void* w) { TouchCtrlsScreen_Show(); } + +static const struct SimpleButtonDesc touchOnscreen_page1[ONSCREEN_PAGE_BTNS] = { + { -120, -50, "Chat", TouchOnscreen_Any }, { 120, -50, "Tablist", TouchOnscreen_Any }, + { -120, 0, "Spawn", TouchOnscreen_Any }, { 120, 0, "Set spawn", TouchOnscreen_Any }, + { -120, 50, "Fly", TouchOnscreen_Any }, { 120, 50, "Noclip", TouchOnscreen_Any }, + { -120, 100, "Speed", TouchOnscreen_Any }, { 120, 100, "Half speed", TouchOnscreen_Any } +}; +static const struct SimpleButtonDesc touchOnscreen_page2[ONSCREEN_PAGE_BTNS] = { + { -120, -50, "Third person", TouchOnscreen_Any }, { 120, -50, "Delete", TouchOnscreen_Any }, + { -120, 0, "Pick", TouchOnscreen_Any }, { 120, 0, "Place", TouchOnscreen_Any }, + { -120, 50, "Switch hotbar", TouchOnscreen_Any }, { 120, 50, "---", TouchOnscreen_Any }, + { -120, 100, "---", TouchOnscreen_Any }, { 120, 100, "---", TouchOnscreen_Any } +}; + +static void TouchOnscreen_Left(void* screen, void* b); +static void TouchOnscreen_Right(void* screen, void* b); + +static void TouchOnscreen_RemakeWidgets(struct TouchOnscreenScreen* s, cc_bool page1) { + int i; + int offset = page1 ? 0 : ONSCREEN_PAGE_BTNS; + s->btnDescs = page1 ? touchOnscreen_page1 : touchOnscreen_page2; + + s->widgets = touchOnscreen_widgets; + s->numWidgets = 0; + s->maxWidgets = Array_Elems(touchOnscreen_widgets); + + Menu_AddButtons(s, s->btns, 200, s->btnDescs, ONSCREEN_PAGE_BTNS); + ButtonWidget_Add(s, &s->back, 400, TouchOnscreen_More); + ButtonWidget_Add(s, &s->left, 40, TouchOnscreen_Left); + ButtonWidget_Add(s, &s->right, 40, TouchOnscreen_Right); + + Widget_SetDisabled(&s->left, page1); + Widget_SetDisabled(&s->right, !page1); + + for (i = 0; i < ONSCREEN_PAGE_BTNS; i++) + { + s->btns[i].meta.val = 1 << (i + offset); + } +} + +static void TouchOnscreen_Left(void* screen, void* b) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + TouchOnscreen_RemakeWidgets(s, true); + Gui_Refresh((struct Screen*)s); + TouchOnscreen_UpdateColors(s); +} + +static void TouchOnscreen_Right(void* screen, void* b) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + TouchOnscreen_RemakeWidgets(s, false); + Gui_Refresh((struct Screen*)s); + TouchOnscreen_UpdateColors(s); +} + +static void TouchOnscreenScreen_ContextLost(void* screen) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + Font_Free(&s->font); + Screen_ContextLost(screen); +} + +static void TouchOnscreenScreen_ContextRecreated(void* screen) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + Gui_MakeTitleFont(&s->font); + Screen_UpdateVb(screen); + Menu_SetButtons(s->btns, &s->font, s->btnDescs, ONSCREEN_PAGE_BTNS); + ButtonWidget_SetConst(&s->back, "Done", &s->font); + ButtonWidget_SetConst(&s->left, "<", &s->font); + ButtonWidget_SetConst(&s->right, ">", &s->font); +} + +static void TouchOnscreenScreen_Layout(void* screen) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + Menu_LayoutButtons(s->btns, s->btnDescs, ONSCREEN_PAGE_BTNS); + Menu_LayoutBack(&s->back); + Widget_SetLocation(&s->left, ANCHOR_CENTRE, ANCHOR_CENTRE, -260, 0); + Widget_SetLocation(&s->right, ANCHOR_CENTRE, ANCHOR_CENTRE, 260, 0); +} + +static void TouchOnscreenScreen_Init(void* screen) { + struct TouchOnscreenScreen* s = (struct TouchOnscreenScreen*)screen; + TouchOnscreen_RemakeWidgets(s, true); + TouchOnscreen_UpdateColors(screen); + + s->maxVertices = Screen_CalcDefaultMaxVertices(s); +} + +static const struct ScreenVTABLE TouchOnscreenScreen_VTABLE = { + TouchOnscreenScreen_Init, Screen_NullUpdate, Screen_NullFunc, + MenuScreen_Render2, Screen_BuildMesh, + Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, + Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, + TouchOnscreenScreen_Layout, TouchOnscreenScreen_ContextLost, TouchOnscreenScreen_ContextRecreated +}; +void TouchOnscreenScreen_Show(void) { + struct TouchOnscreenScreen* s = &TouchOnscreenScreen; + s->grabsInput = true; + s->closable = true; + s->VTABLE = &TouchOnscreenScreen_VTABLE; + + Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); +} + + +/*########################################################################################################################* +*---------------------------------------------------TouchControlsScreen---------------------------------------------------* +*#########################################################################################################################*/ +#define TOUCHCTRLS_BTNS 5 +static struct TouchCtrlsScreen { + Screen_Body + struct ButtonWidget back; + struct ButtonWidget btns[TOUCHCTRLS_BTNS]; + struct FontDesc font; +} TouchCtrlsScreen; + +static struct Widget* touchCtrls_widgets[TOUCHCTRLS_BTNS + 1]; + +static const char* GetTapDesc(int mode) { + if (mode == INPUT_MODE_PLACE) return "Tap: Place"; + if (mode == INPUT_MODE_DELETE) return "Tap: Delete"; + return "Tap: None"; +} +static void TouchCtrls_UpdateTapText(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + ButtonWidget_SetConst(&s->btns[0], GetTapDesc(Input_TapMode), &s->font); + s->dirty = true; +} + +static const char* GetHoldDesc(int mode) { + if (mode == INPUT_MODE_PLACE) return "Hold: Place"; + if (mode == INPUT_MODE_DELETE) return "Hold: Delete"; + return "Hold: None"; +} +static void TouchCtrls_UpdateHoldText(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + ButtonWidget_SetConst(&s->btns[1], GetHoldDesc(Input_HoldMode), &s->font); + s->dirty = true; +} + +static void TouchCtrls_UpdateSensitivity(void* screen) { + cc_string value; char valueBuffer[STRING_SIZE]; + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + String_InitArray(value, valueBuffer); + + String_Format1(&value, "Sensitivity: %i", &Camera.Sensitivity); + ButtonWidget_Set(&s->btns[2], &value, &s->font); + s->dirty = true; +} + +static void TouchCtrls_UpdateScale(void* screen) { + cc_string value; char valueBuffer[STRING_SIZE]; + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + String_InitArray(value, valueBuffer); + + String_AppendConst(&value, "Scale: "); + String_AppendFloat(&value, Gui.RawTouchScale, 1); + ButtonWidget_Set(&s->btns[3], &value, &s->font); + s->dirty = true; +} + +static void TouchCtrls_More(void* s, void* w) { TouchMoreScreen_Show(); } +static void TouchCtrls_Onscreen(void* s, void* w) { TouchOnscreenScreen_Show(); } + +static void TouchCtrls_Tap(void* s, void* w) { + Input_TapMode = (Input_TapMode + 1) % INPUT_MODE_COUNT; + TouchCtrls_UpdateTapText(s); +} +static void TouchCtrls_Hold(void* s, void* w) { + Input_HoldMode = (Input_HoldMode + 1) % INPUT_MODE_COUNT; + TouchCtrls_UpdateHoldText(s); +} + +static void TouchCtrls_SensitivityDone(const cc_string* value, cc_bool valid) { + int sensitivity; + if (!valid) return; + + Convert_ParseInt(value, &sensitivity); + Camera.Sensitivity = sensitivity; + Options_Set(OPT_SENSITIVITY, value); + TouchCtrls_UpdateSensitivity(&TouchCtrlsScreen); +} + +static void TouchCtrls_Sensitivity(void* screen, void* w) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + static struct MenuInputDesc desc; + cc_string value; char valueBuffer[STRING_SIZE]; + String_InitArray(value, valueBuffer); + + MenuInput_Int(desc, 1, 200, 30); + String_AppendInt(&value, Camera.Sensitivity); + MenuInputOverlay_Show(&desc, &value, TouchCtrls_SensitivityDone, true); + /* Fix Sensitivity button getting stuck as 'active' */ + /* (input overlay swallows subsequent pointer events) */ + s->btns[2].active = 0; +} + +static void TouchCtrls_ScaleDone(const cc_string* value, cc_bool valid) { + if (!valid) return; + Convert_ParseFloat(value, &Gui.RawTouchScale); + Options_Set(OPT_TOUCH_SCALE, value); + + TouchCtrls_UpdateScale(&TouchCtrlsScreen); + Gui_LayoutAll(); +} + +static void TouchCtrls_Scale(void* screen, void* w) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + static struct MenuInputDesc desc; + cc_string value; char valueBuffer[STRING_SIZE]; + String_InitArray(value, valueBuffer); + + MenuInput_Float(desc, 0.25f, 5.0f, 1.0f); + String_AppendFloat(&value, Gui.RawTouchScale, 1); + MenuInputOverlay_Show(&desc, &value, TouchCtrls_ScaleDone, true); + s->btns[3].active = 0; +} + +static const struct SimpleButtonDesc touchCtrls_btns[5] = { + { -102, -50, "", TouchCtrls_Tap }, + { 102, -50, "", TouchCtrls_Hold }, + { -102, 0, "", TouchCtrls_Sensitivity }, + { 102, 0, "", TouchCtrls_Scale }, + { 0, 50, "On-screen controls", TouchCtrls_Onscreen } +}; + +static void TouchCtrlsScreen_ContextLost(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + Font_Free(&s->font); + Screen_ContextLost(screen); +} + +static void TouchCtrlsScreen_ContextRecreated(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + Gui_MakeTitleFont(&s->font); + Screen_UpdateVb(screen); + Menu_SetButtons(s->btns, &s->font, touchCtrls_btns, TOUCHCTRLS_BTNS); + ButtonWidget_SetConst(&s->back, "Done", &s->font); + + TouchCtrls_UpdateTapText(s); + TouchCtrls_UpdateHoldText(s); + TouchCtrls_UpdateSensitivity(s); + TouchCtrls_UpdateScale(s); +} + +static void TouchCtrlsScreen_Layout(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + Menu_LayoutButtons(s->btns, touchCtrls_btns, TOUCHCTRLS_BTNS); + Menu_LayoutBack(&s->back); +} + +static void TouchCtrlsScreen_Init(void* screen) { + struct TouchCtrlsScreen* s = (struct TouchCtrlsScreen*)screen; + s->widgets = touchCtrls_widgets; + s->numWidgets = 0; + s->maxWidgets = Array_Elems(touchCtrls_widgets); + + Menu_AddButtons(s, s->btns, 195, touchCtrls_btns, 4); + Menu_AddButtons(s, s->btns + 4, 400, touchCtrls_btns + 4, 1); + ButtonWidget_Add(s, &s->back, 400, TouchCtrls_More); + + s->maxVertices = Screen_CalcDefaultMaxVertices(s); +} + +static const struct ScreenVTABLE TouchCtrlsScreen_VTABLE = { + TouchCtrlsScreen_Init, Screen_NullUpdate, Screen_NullFunc, + MenuScreen_Render2, Screen_BuildMesh, + Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, + Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, + TouchCtrlsScreen_Layout, TouchCtrlsScreen_ContextLost, TouchCtrlsScreen_ContextRecreated +}; +void TouchCtrlsScreen_Show(void) { + struct TouchCtrlsScreen* s = &TouchCtrlsScreen; + s->grabsInput = true; + s->closable = true; + s->VTABLE = &TouchCtrlsScreen_VTABLE; + + Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); +} + + +/*########################################################################################################################* +*-----------------------------------------------------TouchMoreScreen-----------------------------------------------------* +*#########################################################################################################################*/ +#define TOUCHMORE_BTNS 6 +static struct TouchMoreScreen { + Screen_Body + struct ButtonWidget back; + struct ButtonWidget btns[TOUCHMORE_BTNS]; +} TouchMoreScreen; + +static struct Widget* touchMore_widgets[TOUCHMORE_BTNS + 1]; + +static void TouchMore_Take(void* s, void* w) { + Gui_Remove((struct Screen*)&TouchMoreScreen); + Game_ScreenshotRequested = true; +} +static void TouchMore_Screen(void* s, void* w) { + Gui_Remove((struct Screen*)&TouchMoreScreen); + Game_ToggleFullscreen(); +} +static void TouchMore_Ctrls(void* s, void* w) { TouchCtrlsScreen_Show(); } +static void TouchMore_Menu(void* s, void* w) { + Gui_Remove((struct Screen*)&TouchMoreScreen); + Gui_ShowPauseMenu(); +} +static void TouchMore_Game(void* s, void* w) { + Gui_Remove((struct Screen*)&TouchMoreScreen); +} +static void TouchMore_Chat(void* s, void* w) { + Gui_Remove((struct Screen*)&TouchMoreScreen); + ChatScreen_OpenInput(&String_Empty); +} +static void TouchMore_Fog(void* s, void* w) { Game_CycleViewDistance(); } + +static const struct SimpleButtonDesc touchMore_btns[TOUCHMORE_BTNS] = { + { -102, -50, "Screenshot", TouchMore_Take }, + { -102, 0, "Fullscreen", TouchMore_Screen }, + { 102, -50, "Chat", TouchMore_Chat }, + { 102, 0, "Fog", TouchMore_Fog }, + { 0, 50, "Controls", TouchMore_Ctrls }, + { 0, 100, "Main menu", TouchMore_Menu } +}; + +static void TouchMoreScreen_ContextRecreated(void* screen) { + struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; + struct FontDesc titleFont; + Gui_MakeTitleFont(&titleFont); + Screen_UpdateVb(screen); + + Menu_SetButtons(s->btns, &titleFont, touchMore_btns, TOUCHMORE_BTNS); + ButtonWidget_SetConst(&s->back, "Back to game", &titleFont); + Font_Free(&titleFont); +} + +static void TouchMoreScreen_Layout(void* screen) { + struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; + Menu_LayoutButtons(s->btns, touchMore_btns, TOUCHMORE_BTNS); + Menu_LayoutBack(&s->back); +} + +static void TouchMoreScreen_Init(void* screen) { + struct TouchMoreScreen* s = (struct TouchMoreScreen*)screen; + s->widgets = touchMore_widgets; + s->numWidgets = 0; + s->maxWidgets = Array_Elems(touchMore_widgets); + + Menu_AddButtons(s, s->btns, 195, touchMore_btns, 4); + Menu_AddButtons(s, s->btns + 4, 400, touchMore_btns + 4, 2); + ButtonWidget_Add(s, &s->back, 400, TouchMore_Game); + + s->maxVertices = Screen_CalcDefaultMaxVertices(s); +} + +static const struct ScreenVTABLE TouchMoreScreen_VTABLE = { + TouchMoreScreen_Init, Screen_NullUpdate, Screen_NullFunc, + MenuScreen_Render2, Screen_BuildMesh, + Menu_InputDown, Screen_InputUp, Screen_TKeyPress, Screen_TText, + Menu_PointerDown, Screen_PointerUp, Menu_PointerMove, Screen_TMouseScroll, + TouchMoreScreen_Layout, Screen_ContextLost, TouchMoreScreen_ContextRecreated +}; +void TouchMoreScreen_Show(void) { + struct TouchMoreScreen* s = &TouchMoreScreen; + s->grabsInput = true; + s->closable = true; + s->VTABLE = &TouchMoreScreen_VTABLE; + + Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCHMORE); +} + + +/*########################################################################################################################* +*--------------------------------------------------------TouchScreen------------------------------------------------------* +*#########################################################################################################################*/ +#define TOUCH_EXTRA_BTNS 2 +#define TOUCH_MAX_BTNS (ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS + 1) +struct TouchButtonDesc { + const char* text; + cc_uint8 bind, x, y; + Widget_LeftClick OnClick; + cc_bool* enabled; +}; + +static struct TouchScreen { + Screen_Body + const struct TouchButtonDesc* descs; + int numOnscreen, numBtns; + struct FontDesc font; + struct ThumbstickWidget thumbstick; + const struct TouchButtonDesc* onscreenDescs[ONSCREEN_MAX_BTNS]; + struct ButtonWidget onscreen[ONSCREEN_MAX_BTNS]; + struct ButtonWidget btns[TOUCH_EXTRA_BTNS], more; +} TouchScreen; + +static struct Widget* touch_widgets[ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS + 2] = { + NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL, NULL,NULL,NULL,NULL, NULL, + NULL,NULL, (struct Widget*)&TouchScreen.thumbstick, (struct Widget*)&TouchScreen.more +}; +#define TOUCH_MAX_VERTICES (THUMBSTICKWIDGET_MAX + TOUCH_MAX_BTNS * BUTTONWIDGET_MAX) + +static void TouchScreen_ChatClick(void* s, void* w) { ChatScreen_OpenInput(&String_Empty); } +static void TouchScreen_RespawnClick(void* s, void* w) { LocalPlayer_HandleRespawn(Entities.CurPlayer); } +static void TouchScreen_SetSpawnClick(void* s, void* w) { LocalPlayer_HandleSetSpawn(Entities.CurPlayer); } +static void TouchScreen_FlyClick(void* s, void* w) { LocalPlayer_HandleFly(Entities.CurPlayer); } +static void TouchScreen_NoclipClick(void* s, void* w) { LocalPlayer_HandleNoclip(Entities.CurPlayer); } +static void TouchScreen_CameraClick(void* s, void* w) { Camera_CycleActive(); } +static void TouchScreen_MoreClick(void* s, void* w) { TouchMoreScreen_Show(); } +static void TouchScreen_SwitchClick(void* s, void* w) { Inventory_SwitchHotbar(); } +static void TouchScreen_DeleteClick(void* s, void* w) { InputHandler_DeleteBlock(); } /* TODO: also Send CPEClick packet */ +static void TouchScreen_PlaceClick(void* s, void* w) { InputHandler_PlaceBlock(); } +static void TouchScreen_PickClick(void* s, void* w) { InputHandler_PickBlock(); } + +static void TouchScreen_TabClick(void* s, void* w) { + struct Screen* tablist = Gui_GetScreen(GUI_PRIORITY_TABLIST); + if (tablist) { + Gui_Remove(tablist); + } else { + TabListOverlay_Show(true); + } +} + +static void TouchScreen_SpeedClick(void* s, void* w) { + struct HacksComp* hacks = &Entities.CurPlayer->Hacks; + if (hacks->Enabled) hacks->Speeding = !hacks->Speeding; +} +static void TouchScreen_HalfClick(void* s, void* w) { + struct HacksComp* hacks = &Entities.CurPlayer->Hacks; + if (hacks->Enabled) hacks->HalfSpeeding = !hacks->HalfSpeeding; +} + +static void TouchScreen_BindClick(void* screen, void* widget) { + struct TouchScreen* s = (struct TouchScreen*)screen; + struct ButtonWidget* btn = (struct ButtonWidget*)widget; + + int i = btn->meta.val; + Input_Set(KeyBinds_Normal[s->descs[i].bind], true); +} + +static const struct TouchButtonDesc onscreenDescs[ONSCREEN_MAX_BTNS] = { + { "Chat", 0,0,0, TouchScreen_ChatClick }, + { "Tablist", 0,0,0, TouchScreen_TabClick }, + { "Respawn", 0,0,0, TouchScreen_RespawnClick, &LocalPlayer_Instances[0].Hacks.CanRespawn }, + { "Set spawn", 0,0,0, TouchScreen_SetSpawnClick, &LocalPlayer_Instances[0].Hacks.CanRespawn }, + { "Fly", 0,0,0, TouchScreen_FlyClick, &LocalPlayer_Instances[0].Hacks.CanFly }, + { "Noclip", 0,0,0, TouchScreen_NoclipClick, &LocalPlayer_Instances[0].Hacks.CanNoclip }, + { "Speed", 0,0,0, TouchScreen_SpeedClick, &LocalPlayer_Instances[0].Hacks.CanSpeed }, + { "\xabSpeed", 0,0,0, TouchScreen_HalfClick, &LocalPlayer_Instances[0].Hacks.CanSpeed }, + { "Camera", 0,0,0, TouchScreen_CameraClick, &LocalPlayer_Instances[0].Hacks.CanUseThirdPerson }, + { "Delete", 0,0,0, TouchScreen_DeleteClick }, + { "Pick", 0,0,0, TouchScreen_PickClick }, + { "Place", 0,0,0, TouchScreen_PlaceClick }, + { "Hotbar", 0,0,0, TouchScreen_SwitchClick } +}; +static const struct TouchButtonDesc normDescs[1] = { + { "\x1E", KEYBIND_JUMP, 50, 10, TouchScreen_BindClick } +}; +static const struct TouchButtonDesc hackDescs[2] = { + { "\x1E", KEYBIND_FLY_UP, 50, 70, TouchScreen_BindClick }, + { "\x1F", KEYBIND_FLY_DOWN, 50, 10, TouchScreen_BindClick } +}; + +#define TOUCHSCREEN_BTN_COLOR PackedCol_Make(255, 255, 255, 220) +static void TouchScreen_InitButtons(struct TouchScreen* s) { + struct HacksComp* hacks = &Entities.CurPlayer->Hacks; + const struct TouchButtonDesc* desc; + int buttons = GetOnscreenButtons(); + int i, j; + for (i = 0; i < ONSCREEN_MAX_BTNS + TOUCH_EXTRA_BTNS; i++) s->widgets[i] = NULL; + + for (i = 0, j = 0; i < ONSCREEN_MAX_BTNS; i++) + { + if (!(buttons & (1 << i))) continue; + desc = &onscreenDescs[i]; + + ButtonWidget_Init(&s->onscreen[j], 100, desc->OnClick); + if (desc->enabled) Widget_SetDisabled(&s->onscreen[j], !(*desc->enabled)); + + s->onscreenDescs[j] = desc; + s->widgets[j] = (struct Widget*)&s->onscreen[j]; + j++; + } + + s->numOnscreen = j; + if (hacks->Flying || hacks->Noclip) { + s->descs = hackDescs; + s->numBtns = Array_Elems(hackDescs); + } else { + s->descs = normDescs; + s->numBtns = Array_Elems(normDescs); + } + + for (i = 0; i < s->numBtns; i++) + { + s->widgets[i + ONSCREEN_MAX_BTNS] = (struct Widget*)&s->btns[i]; + ButtonWidget_Init(&s->btns[i], 60, s->descs[i].OnClick); + s->btns[i].color = TOUCHSCREEN_BTN_COLOR; + s->btns[i].meta.val = i; + } +} + +void TouchScreen_Refresh(void) { + struct TouchScreen* s = &TouchScreen; + /* InitButtons changes number of widgets, hence */ + /* must destroy graphics resources BEFORE that */ + Screen_ContextLost(s); + TouchScreen_InitButtons(s); + Gui_Refresh((struct Screen*)s); +} +static void TouchScreen_HacksChanged(void* s) { TouchScreen_Refresh(); } + +static void TouchScreen_ContextLost(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + Font_Free(&s->font); + Screen_ContextLost(screen); +} + +static void TouchScreen_ContextRecreated(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + const struct TouchButtonDesc* desc; + int i; + Screen_UpdateVb(screen); + Gui_MakeTitleFont(&s->font); + + for (i = 0; i < s->numOnscreen; i++) + { + desc = s->onscreenDescs[i]; + ButtonWidget_SetConst(&s->onscreen[i], desc->text, &s->font); + } + for (i = 0; i < s->numBtns; i++) + { + desc = &s->descs[i]; + ButtonWidget_SetConst(&s->btns[i], desc->text, &s->font); + } + ButtonWidget_SetConst(&s->more, "...", &s->font); +} + +static void TouchScreen_Render(void* screen, float delta) { + if (Gui.InputGrab) return; + Screen_Render2Widgets(screen, delta); +} + +static int TouchScreen_PointerDown(void* screen, int id, int x, int y) { + struct TouchScreen* s = (struct TouchScreen*)screen; + struct Widget* w; + int i; + //Chat_Add1("POINTER DOWN: %i", &id); + if (Gui.InputGrab) return false; + + i = Screen_DoPointerDown(screen, id, x, y); + if (i < ONSCREEN_MAX_BTNS) return i >= 0; + + /* Clicking on other buttons then */ + w = s->widgets[i]; + w->active |= id; + + /* Clicking on jump or fly buttons should still move camera */ + for (i = 0; i < s->numBtns; i++) + { + if (w == (struct Widget*)&s->btns[i]) return TOUCH_TYPE_GUI | TOUCH_TYPE_CAMERA; + } + return TOUCH_TYPE_GUI; +} + +static void 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; + s->more.active &= ~id; + + for (i = 0; i < s->numBtns; i++) + { + if (!(s->btns[i].active & id)) continue; + + if (s->descs[i].bind < KEYBIND_COUNT) { + Input_Set(KeyBinds_Normal[s->descs[i].bind], false); + } + s->btns[i].active &= ~id; + return; + } +} + +static void TouchScreen_Layout(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + const struct TouchButtonDesc* desc; + float scale = Gui.RawTouchScale; + int i, x, y, height; + + /* Need to align these relative to the hotbar */ + height = HUDScreen_LayoutHotbar(); + + for (i = 0; i < s->numBtns; i++) + { + desc = &s->descs[i]; + Widget_SetLocation(&s->btns[i], ANCHOR_MAX, ANCHOR_MAX, desc->x, desc->y); + s->btns[i].yOffset += height; + + /* TODO: Maybe move scaling to be part of button instead */ + s->btns[i].minWidth = Display_ScaleX(60 * scale); + s->btns[i].minHeight = Display_ScaleY(60 * scale); + Widget_Layout(&s->btns[i]); + } + + for (i = 0, x = 10, y = 10; i < s->numOnscreen; i++, y += 40) + { + Widget_SetLocation(&s->onscreen[i], ANCHOR_MAX, ANCHOR_MIN, x, y); + if (s->onscreen[i].y + s->onscreen[i].height <= s->btns[0].y) continue; + + // overflowed onto jump/fly buttons, move to next column + y = 10; + x += 110; + Widget_SetLocation(&s->onscreen[i], ANCHOR_MAX, ANCHOR_MIN, x, y); + } + Widget_SetLocation(&s->more, ANCHOR_CENTRE, ANCHOR_MIN, 0, 10); + + Widget_SetLocation(&s->thumbstick, ANCHOR_MIN, ANCHOR_MAX, 30, 5); + s->thumbstick.yOffset += height; + s->thumbstick.scale = scale; + Widget_Layout(&s->thumbstick); +} + +static void TouchScreen_GetMovement(struct LocalPlayer* p, float* xMoving, float* zMoving) { + ThumbstickWidget_GetMovement(&TouchScreen.thumbstick, xMoving, zMoving); +} +static struct LocalPlayerInput touchInput = { TouchScreen_GetMovement }; +static cc_bool touchHooked; + +static void TouchScreen_Init(void* screen) { + struct TouchScreen* s = (struct TouchScreen*)screen; + + s->widgets = touch_widgets; + s->numWidgets = Array_Elems(touch_widgets); + s->maxVertices = TOUCH_MAX_VERTICES; + Event_Register_(&UserEvents.HacksStateChanged, screen, TouchScreen_HacksChanged); + Event_Register_(&UserEvents.HackPermsChanged, screen, TouchScreen_HacksChanged); + + TouchScreen_InitButtons(s); + ButtonWidget_Init(&s->more, 40, TouchScreen_MoreClick); + s->more.color = TOUCHSCREEN_BTN_COLOR; + ThumbstickWidget_Init(&s->thumbstick); + + if (touchHooked) return; + touchHooked = true; + LocalPlayerInput_Add(&touchInput); +} + +static void TouchScreen_Free(void* s) { + Event_Unregister_(&UserEvents.HacksStateChanged, s, TouchScreen_HacksChanged); + Event_Unregister_(&UserEvents.HackPermsChanged, s, TouchScreen_HacksChanged); +} + +static const struct ScreenVTABLE TouchScreen_VTABLE = { + TouchScreen_Init, Screen_NullUpdate, TouchScreen_Free, + TouchScreen_Render, Screen_BuildMesh, + Screen_FInput, Screen_InputUp, Screen_FKeyPress, Screen_FText, + TouchScreen_PointerDown, TouchScreen_PointerUp, Screen_FPointer, Screen_FMouseScroll, + TouchScreen_Layout, TouchScreen_ContextLost, TouchScreen_ContextRecreated +}; +void TouchScreen_Show(void) { + struct TouchScreen* s = &TouchScreen; + s->VTABLE = &TouchScreen_VTABLE; + + if (!Gui.TouchUI) return; + Gui_Add((struct Screen*)s, GUI_PRIORITY_TOUCH); +} +#endif diff --git a/src/_GLShared.h b/src/_GLShared.h index 70f365e9b..bc0b47041 100644 --- a/src/_GLShared.h +++ b/src/_GLShared.h @@ -215,10 +215,10 @@ void Gfx_CalcOrthoMatrix(struct Matrix* matrix, float width, float height, float matrix->row4.z = -(zFar + zNear) / (zFar - zNear); } -static double Cotangent(double x) { return Math_Cos(x) / Math_Sin(x); } +static float Cotangent(float x) { return Math_CosF(x) / Math_SinF(x); } void Gfx_CalcPerspectiveMatrix(struct Matrix* matrix, float fov, float aspect, float zFar) { float zNear = 0.1f; - float c = (float)Cotangent(0.5f * fov); + float c = Cotangent(0.5f * fov); /* Transposed, source https://learn.microsoft.com/en-us/windows/win32/opengl/glfrustum */ /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */