mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 09:35:23 -04:00
Move hotbar rendering mostly over to the new rendering method
This commit is contained in:
parent
ddec30a59d
commit
e9d897499d
@ -1028,7 +1028,7 @@ void Logger_Hook(void) {
|
|||||||
SetUnhandledExceptionFilter(UnhandledFilter);
|
SetUnhandledExceptionFilter(UnhandledFilter);
|
||||||
DynamicLib_LoadAll(&imagehlp, funcs, Array_Elems(funcs), &lib);
|
DynamicLib_LoadAll(&imagehlp, funcs, Array_Elems(funcs), &lib);
|
||||||
|
|
||||||
/* Windows 9x requires GetCurrentProcessId - see old DBGHELP docs */
|
/* Windows 9x requires process IDs instead - see old DBGHELP docs */
|
||||||
/* https://documentation.help/DbgHelp/documentation.pdf */
|
/* https://documentation.help/DbgHelp/documentation.pdf */
|
||||||
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
|
||||||
osInfo.dwPlatformId = 0;
|
osInfo.dwPlatformId = 0;
|
||||||
|
@ -76,7 +76,7 @@ static struct HUDScreen {
|
|||||||
int lastFov;
|
int lastFov;
|
||||||
struct HotbarWidget hotbar;
|
struct HotbarWidget hotbar;
|
||||||
} HUDScreen_Instance;
|
} HUDScreen_Instance;
|
||||||
#define HUD_MAX_VERTICES (TEXTWIDGET_MAX * 2 + 4)
|
#define HUD_MAX_VERTICES (4 + TEXTWIDGET_MAX * 2 + HOTBAR_MAX_VERTICES)
|
||||||
|
|
||||||
static void HUDScreen_RemakeLine1(struct HUDScreen* s) {
|
static void HUDScreen_RemakeLine1(struct HUDScreen* s) {
|
||||||
cc_string status; char statusBuffer[STRING_SIZE * 2];
|
cc_string status; char statusBuffer[STRING_SIZE * 2];
|
||||||
@ -277,6 +277,10 @@ static void HUDScreen_HacksChanged(void* obj) {
|
|||||||
((struct HUDScreen*)obj)->hacksChanged = true;
|
((struct HUDScreen*)obj)->hacksChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void HUDScreen_NeedRedrawing(void* obj) {
|
||||||
|
((struct HUDScreen*)obj)->dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
static void HUDScreen_Init(void* screen) {
|
static void HUDScreen_Init(void* screen) {
|
||||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||||
s->maxVertices = HUD_MAX_VERTICES;
|
s->maxVertices = HUD_MAX_VERTICES;
|
||||||
@ -284,7 +288,16 @@ static void HUDScreen_Init(void* screen) {
|
|||||||
HotbarWidget_Create(&s->hotbar);
|
HotbarWidget_Create(&s->hotbar);
|
||||||
TextWidget_Init(&s->line1);
|
TextWidget_Init(&s->line1);
|
||||||
TextWidget_Init(&s->line2);
|
TextWidget_Init(&s->line2);
|
||||||
Event_Register_(&UserEvents.HacksStateChanged, screen, HUDScreen_HacksChanged);
|
|
||||||
|
Event_Register_(&UserEvents.HacksStateChanged, s, HUDScreen_HacksChanged);
|
||||||
|
Event_Register_(&TextureEvents.AtlasChanged, s, HUDScreen_NeedRedrawing);
|
||||||
|
Event_Register_(&BlockEvents.BlockDefChanged, s, HUDScreen_NeedRedrawing);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HUDScreen_Free(void* screen) {
|
||||||
|
Event_Unregister_(&UserEvents.HacksStateChanged, screen, HUDScreen_HacksChanged);
|
||||||
|
Event_Unregister_(&TextureEvents.AtlasChanged, screen, HUDScreen_NeedRedrawing);
|
||||||
|
Event_Unregister_(&BlockEvents.BlockDefChanged, screen, HUDScreen_NeedRedrawing);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HUDScreen_UpdateFPS(struct HUDScreen* s, double delta) {
|
static void HUDScreen_UpdateFPS(struct HUDScreen* s, double delta) {
|
||||||
@ -300,7 +313,8 @@ static void HUDScreen_UpdateFPS(struct HUDScreen* s, double delta) {
|
|||||||
|
|
||||||
static void HUDScreen_Update(void* screen, double delta) {
|
static void HUDScreen_Update(void* screen, double delta) {
|
||||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||||
HUDScreen_UpdateFPS(s, delta);
|
HUDScreen_UpdateFPS(s, delta);
|
||||||
|
HotbarWidget_Update(&s->hotbar, delta);
|
||||||
if (Game_ClassicMode) return;
|
if (Game_ClassicMode) return;
|
||||||
|
|
||||||
if (IsOnlyChatActive() && Gui.ShowFPS) {
|
if (IsOnlyChatActive() && Gui.ShowFPS) {
|
||||||
@ -327,13 +341,16 @@ static void HUDScreen_BuildMesh(void* screen) {
|
|||||||
struct HUDScreen* s = (struct HUDScreen*)screen;
|
struct HUDScreen* s = (struct HUDScreen*)screen;
|
||||||
struct VertexTextured* data;
|
struct VertexTextured* data;
|
||||||
struct VertexTextured** ptr;
|
struct VertexTextured** ptr;
|
||||||
|
struct VertexTextured* DS;
|
||||||
|
|
||||||
data = Screen_LockVb(s);
|
data = Screen_LockVb(s);
|
||||||
ptr = &data;
|
ptr = &data;
|
||||||
|
DS = data;
|
||||||
|
|
||||||
HUDScreen_BuildCrosshairsMesh(ptr);
|
HUDScreen_BuildCrosshairsMesh(ptr);
|
||||||
Widget_BuildMesh(&s->line1, ptr);
|
Widget_BuildMesh(&s->line1, ptr);
|
||||||
Widget_BuildMesh(&s->line2, ptr);
|
Widget_BuildMesh(&s->line2, ptr);
|
||||||
|
Widget_BuildMesh(&s->hotbar, ptr);
|
||||||
Gfx_UnlockDynamicVb(s->vb);
|
Gfx_UnlockDynamicVb(s->vb);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,8 +360,6 @@ static void HUDScreen_Render(void* screen, double delta) {
|
|||||||
|
|
||||||
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
Gfx_SetVertexFormat(VERTEX_FORMAT_TEXTURED);
|
||||||
Gfx_BindDynamicVb(s->vb);
|
Gfx_BindDynamicVb(s->vb);
|
||||||
|
|
||||||
/* TODO: If Game_ShowFps is off and not classic mode, we should just return here */
|
|
||||||
if (Gui.ShowFPS) Widget_Render2(&s->line1, 4);
|
if (Gui.ShowFPS) Widget_Render2(&s->line1, 4);
|
||||||
|
|
||||||
if (Game_ClassicMode) {
|
if (Game_ClassicMode) {
|
||||||
@ -355,20 +370,17 @@ static void HUDScreen_Render(void* screen, double delta) {
|
|||||||
/* TODO swap these two lines back */
|
/* TODO swap these two lines back */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Gui_GetBlocksWorld()) Elem_Render(&s->hotbar, delta);
|
if (Gui_GetBlocksWorld()) return;
|
||||||
|
Gfx_BindDynamicVb(s->vb);
|
||||||
|
Widget_Render2(&s->hotbar, 12);
|
||||||
|
|
||||||
if (!Gui.IconsTex) return;
|
if (Gui.IconsTex && !tablist_active) {
|
||||||
if (!tablist_active && !Gui_GetBlocksWorld()) {
|
|
||||||
Gfx_BindTexture(Gui.IconsTex);
|
Gfx_BindTexture(Gui.IconsTex);
|
||||||
Gfx_BindDynamicVb(s->vb);
|
Gfx_BindDynamicVb(s->vb); /* Have to rebind for mobile right now... */
|
||||||
Gfx_DrawVb_IndexedTris(4);
|
Gfx_DrawVb_IndexedTris(4);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HUDScreen_Free(void* screen) {
|
|
||||||
Event_Unregister_(&UserEvents.HacksStateChanged, screen, HUDScreen_HacksChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct ScreenVTABLE HUDScreen_VTABLE = {
|
static const struct ScreenVTABLE HUDScreen_VTABLE = {
|
||||||
HUDScreen_Init, HUDScreen_Update, HUDScreen_Free,
|
HUDScreen_Init, HUDScreen_Update, HUDScreen_Free,
|
||||||
HUDScreen_Render, HUDScreen_BuildMesh,
|
HUDScreen_Render, HUDScreen_BuildMesh,
|
||||||
|
113
src/Widgets.c
113
src/Widgets.c
@ -387,28 +387,20 @@ void ScrollbarWidget_Create(struct ScrollbarWidget* w) {
|
|||||||
*#########################################################################################################################*/
|
*#########################################################################################################################*/
|
||||||
#define HotbarWidget_TileX(w, idx) (int)(w->x + w->slotXOffset + w->slotWidth * (idx))
|
#define HotbarWidget_TileX(w, idx) (int)(w->x + w->slotXOffset + w->slotWidth * (idx))
|
||||||
|
|
||||||
static void HotbarWidget_RenderHotbarOutline(struct HotbarWidget* w) {
|
static void HotbarWidget_BuildOutlineMesh(struct HotbarWidget* w, struct VertexTextured** vertices) {
|
||||||
GfxResourceID tex;
|
|
||||||
int x;
|
int x;
|
||||||
|
Gfx_Make2DQuad(&w->backTex, PACKEDCOL_WHITE, vertices);
|
||||||
tex = Gui.ClassicTexture ? Gui.GuiClassicTex : Gui.GuiTex;
|
|
||||||
w->backTex.ID = tex;
|
|
||||||
Texture_Render(&w->backTex);
|
|
||||||
|
|
||||||
x = HotbarWidget_TileX(w, Inventory.SelectedIndex);
|
x = HotbarWidget_TileX(w, Inventory.SelectedIndex);
|
||||||
w->selTex.ID = tex;
|
w->selTex.X = (int)(x - w->selWidth / 2);
|
||||||
w->selTex.X = (int)(x - w->selWidth / 2);
|
Gfx_Make2DQuad(&w->selTex, PACKEDCOL_WHITE, vertices);
|
||||||
Gfx_Draw2DTexture(&w->selTex, PACKEDCOL_WHITE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HotbarWidget_RenderHotbarBlocks(struct HotbarWidget* w) {
|
static void HotbarWidget_BuildEntriesMesh(struct HotbarWidget* w, struct VertexTextured** vertices) {
|
||||||
/* TODO: Should hotbar use its own VB? */
|
int i, x, y;
|
||||||
struct VertexTextured vertices[HOTBAR_MAX_VERTICES];
|
|
||||||
int state[HOTBAR_MAX_VERTICES / 4];
|
|
||||||
int i, x, y, count;
|
|
||||||
float scale;
|
float scale;
|
||||||
|
|
||||||
IsometricDrawer_BeginBatch(vertices, state);
|
IsometricDrawer_BeginBatch(*vertices, w->state);
|
||||||
scale = w->elemSize / 2.0f;
|
scale = w->elemSize / 2.0f;
|
||||||
|
|
||||||
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
|
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++) {
|
||||||
@ -420,12 +412,62 @@ static void HotbarWidget_RenderHotbarBlocks(struct HotbarWidget* w) {
|
|||||||
#endif
|
#endif
|
||||||
IsometricDrawer_AddBatch(Inventory_Get(i), scale, x, y);
|
IsometricDrawer_AddBatch(Inventory_Get(i), scale, x, y);
|
||||||
}
|
}
|
||||||
|
w->verticesCount = IsometricDrawer_EndBatch();
|
||||||
|
}
|
||||||
|
|
||||||
count = IsometricDrawer_EndBatch();
|
static void HotbarWidget_BuildMesh(void* widget, struct VertexTextured** vertices) {
|
||||||
if (count == 0) return;
|
struct HotbarWidget* w = (struct HotbarWidget*)widget;
|
||||||
|
struct VertexTextured* data = *vertices;
|
||||||
|
|
||||||
Gfx_SetDynamicVbData(Models.Vb, vertices, count);
|
HotbarWidget_BuildOutlineMesh(w, vertices);
|
||||||
IsometricDrawer_Render(count, 0, state);
|
HotbarWidget_BuildEntriesMesh(w, vertices);
|
||||||
|
*vertices = data + HOTBAR_MAX_VERTICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void HotbarWidget_RenderOutline(struct HotbarWidget* w, int offset) {
|
||||||
|
GfxResourceID tex;
|
||||||
|
tex = Gui.ClassicTexture ? Gui.GuiClassicTex : Gui.GuiTex;
|
||||||
|
|
||||||
|
Gfx_BindTexture(tex);
|
||||||
|
Gfx_DrawVb_IndexedTris_Range(8, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HotbarWidget_RenderEntries(struct HotbarWidget* w, int offset) {
|
||||||
|
if (w->verticesCount == 0) return;
|
||||||
|
IsometricDrawer_Render(w->verticesCount, offset, w->state);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int HotbarWidget_Render2(void* widget, int offset) {
|
||||||
|
struct HotbarWidget* w = (struct HotbarWidget*)widget;
|
||||||
|
HotbarWidget_RenderOutline(w, offset );
|
||||||
|
HotbarWidget_RenderEntries(w, offset + 8);
|
||||||
|
|
||||||
|
#ifdef CC_BUILD_TOUCH
|
||||||
|
if (!Input_TouchMode) return HOTBAR_MAX_VERTICES;
|
||||||
|
w->ellipsisTex.X = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2;
|
||||||
|
w->ellipsisTex.Y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2;
|
||||||
|
Texture_Render(&w->ellipsisTex);
|
||||||
|
#endif
|
||||||
|
return HOTBAR_MAX_VERTICES;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HotbarWidget_Update(struct HotbarWidget* w, double delta) {
|
||||||
|
#ifdef CC_BUILD_TOUCH
|
||||||
|
int i;
|
||||||
|
if (!Input_TouchMode) return;
|
||||||
|
|
||||||
|
for (i = 0; i < HOTBAR_MAX_INDEX; i++) {
|
||||||
|
if(w->touchId[i] != -1) {
|
||||||
|
w->touchTime[i] += delta;
|
||||||
|
if(w->touchTime[i] > 1) {
|
||||||
|
w->touchId[i] = -1;
|
||||||
|
w->touchTime[i] = 0;
|
||||||
|
Inventory_Set(i, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int HotbarWidget_ScrolledIndex(struct HotbarWidget* w, float delta, int index, int dir) {
|
static int HotbarWidget_ScrolledIndex(struct HotbarWidget* w, float delta, int index, int dir) {
|
||||||
@ -462,33 +504,9 @@ static void HotbarWidget_Reposition(void* widget) {
|
|||||||
Tex_SetUV(w->selTex, 0,22/256.0f, 24/256.0f,44/256.0f);
|
Tex_SetUV(w->selTex, 0,22/256.0f, 24/256.0f,44/256.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HotbarWidget_Render(void* widget, double delta) {
|
|
||||||
struct HotbarWidget* w = (struct HotbarWidget*)widget;
|
|
||||||
HotbarWidget_RenderHotbarOutline(w);
|
|
||||||
HotbarWidget_RenderHotbarBlocks(w);
|
|
||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
|
||||||
if (!Input_TouchMode) return;
|
|
||||||
w->ellipsisTex.X = HotbarWidget_TileX(w, HOTBAR_MAX_INDEX) - w->ellipsisTex.Width / 2;
|
|
||||||
w->ellipsisTex.Y = w->y + (w->height / 2) - w->ellipsisTex.Height / 2;
|
|
||||||
Texture_Render(&w->ellipsisTex);
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < HOTBAR_MAX_INDEX; i++) {
|
|
||||||
if(w->touchId[i] != -1) {
|
|
||||||
w->touchTime[i] += delta;
|
|
||||||
if(w->touchTime[i] > 1) {
|
|
||||||
w->touchId[i] = -1;
|
|
||||||
w->touchTime[i] = 0;
|
|
||||||
Inventory_Set(i, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static int HotbarWidget_MapKey(int key) {
|
static int HotbarWidget_MapKey(int key) {
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < 9; i++)
|
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR; i++)
|
||||||
{
|
{
|
||||||
if (key == KeyBinds[KEYBIND_HOTBAR_1 + i]) return i;
|
if (key == KeyBinds[KEYBIND_HOTBAR_1 + i]) return i;
|
||||||
}
|
}
|
||||||
@ -611,9 +629,10 @@ static void HotbarWidget_Free(void* widget) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct WidgetVTABLE HotbarWidget_VTABLE = {
|
static const struct WidgetVTABLE HotbarWidget_VTABLE = {
|
||||||
HotbarWidget_Render, HotbarWidget_Free, HotbarWidget_Reposition,
|
NULL, HotbarWidget_Free, HotbarWidget_Reposition,
|
||||||
HotbarWidget_KeyDown, HotbarWidget_InputUp, HotbarWidget_MouseScroll,
|
HotbarWidget_KeyDown, HotbarWidget_InputUp, HotbarWidget_MouseScroll,
|
||||||
HotbarWidget_PointerDown, HotbarWidget_PointerUp, HotbarWidget_PointerMove
|
HotbarWidget_PointerDown, HotbarWidget_PointerUp, HotbarWidget_PointerMove,
|
||||||
|
HotbarWidget_BuildMesh, HotbarWidget_Render2,
|
||||||
};
|
};
|
||||||
void HotbarWidget_Create(struct HotbarWidget* w) {
|
void HotbarWidget_Create(struct HotbarWidget* w) {
|
||||||
Widget_Reset(w);
|
Widget_Reset(w);
|
||||||
@ -621,6 +640,8 @@ void HotbarWidget_Create(struct HotbarWidget* w) {
|
|||||||
w->horAnchor = ANCHOR_CENTRE;
|
w->horAnchor = ANCHOR_CENTRE;
|
||||||
w->verAnchor = ANCHOR_MAX;
|
w->verAnchor = ANCHOR_MAX;
|
||||||
w->scale = 1;
|
w->scale = 1;
|
||||||
|
w->verticesCount = 0;
|
||||||
|
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR - 1; i++) {
|
for (i = 0; i < INVENTORY_BLOCKS_PER_HOTBAR - 1; i++) {
|
||||||
|
@ -64,6 +64,7 @@ struct ScrollbarWidget {
|
|||||||
/* Resets state of the given scrollbar widget to default. */
|
/* Resets state of the given scrollbar widget to default. */
|
||||||
CC_NOINLINE void ScrollbarWidget_Create(struct ScrollbarWidget* w);
|
CC_NOINLINE void ScrollbarWidget_Create(struct ScrollbarWidget* w);
|
||||||
|
|
||||||
|
#define HOTBAR_CORE_VERTICES (INVENTORY_BLOCKS_PER_HOTBAR * ISOMETRICDRAWER_MAXVERTICES)
|
||||||
/* A row of blocks with a background. */
|
/* A row of blocks with a background. */
|
||||||
struct HotbarWidget {
|
struct HotbarWidget {
|
||||||
Widget_Body
|
Widget_Body
|
||||||
@ -73,16 +74,19 @@ struct HotbarWidget {
|
|||||||
float scrollAcc, scale;
|
float scrollAcc, scale;
|
||||||
cc_bool altHandled;
|
cc_bool altHandled;
|
||||||
struct Texture ellipsisTex;
|
struct Texture ellipsisTex;
|
||||||
|
int state[HOTBAR_CORE_VERTICES / 4];
|
||||||
|
int verticesCount;
|
||||||
#ifdef CC_BUILD_TOUCH
|
#ifdef CC_BUILD_TOUCH
|
||||||
int touchId[HOTBAR_MAX_INDEX];
|
int touchId[HOTBAR_MAX_INDEX];
|
||||||
double touchTime[HOTBAR_MAX_INDEX];
|
double touchTime[HOTBAR_MAX_INDEX];
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
#define HOTBAR_MAX_VERTICES (INVENTORY_BLOCKS_PER_HOTBAR * ISOMETRICDRAWER_MAXVERTICES)
|
#define HOTBAR_MAX_VERTICES (4 + 4 + HOTBAR_CORE_VERTICES)
|
||||||
|
|
||||||
/* Resets state of the given hotbar widget to default. */
|
/* Resets state of the given hotbar widget to default. */
|
||||||
CC_NOINLINE void HotbarWidget_Create(struct HotbarWidget* w);
|
CC_NOINLINE void HotbarWidget_Create(struct HotbarWidget* w);
|
||||||
CC_NOINLINE void HotbarWidget_SetFont(struct HotbarWidget* w, struct FontDesc* font);
|
CC_NOINLINE void HotbarWidget_SetFont(struct HotbarWidget* w, struct FontDesc* font);
|
||||||
|
CC_NOINLINE void HotbarWidget_Update(struct HotbarWidget* w, double delta);
|
||||||
|
|
||||||
#define TABLE_MAX_VERTICES (8 * 10 * ISOMETRICDRAWER_MAXVERTICES)
|
#define TABLE_MAX_VERTICES (8 * 10 * ISOMETRICDRAWER_MAXVERTICES)
|
||||||
/* A table of blocks. */
|
/* A table of blocks. */
|
||||||
|
@ -144,10 +144,11 @@ void Window_UpdateRawMouse(void) {
|
|||||||
|
|
||||||
touchPosition touch;
|
touchPosition touch;
|
||||||
hidTouchRead(&touch);
|
hidTouchRead(&touch);
|
||||||
|
|
||||||
Event_RaiseRawMove(&PointerEvents.RawMoved,
|
Event_RaiseRawMove(&PointerEvents.RawMoved,
|
||||||
x - cursorPrevX, y - cursorPrevY);
|
touch.px - cursorPrevX, touch.py - cursorPrevY);
|
||||||
cursorPrevX = x;
|
cursorPrevX = touch.px;
|
||||||
cursorPrevY = y;
|
cursorPrevY = touch.py;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*########################################################################################################################*
|
/*########################################################################################################################*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user