Move touch UI functionality to its own file

This commit is contained in:
UnknownShadow200 2024-04-27 08:44:03 +10:00
parent 7932a5be3c
commit 10bd6222be
33 changed files with 869 additions and 800 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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];

View File

@ -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;

View File

@ -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;

View File

@ -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: */

View File

@ -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;

View File

@ -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: */

View File

@ -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: */

View File

@ -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 */

View File

@ -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: */

View File

@ -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? ???

View File

@ -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:

View File

@ -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:

View File

@ -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;

View File

@ -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: */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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();
}

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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

View File

@ -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. */

View File

@ -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;

765
src/TouchUI.c Normal file
View File

@ -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

View File

@ -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: */