mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-18 03:55:19 -04:00
Port InventoryScreen to C.
This commit is contained in:
parent
6812ba97ab
commit
71a21714a0
@ -222,9 +222,8 @@ namespace ClassicalSharp.Renderers {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Skeleton implementation of a player entity so we can reuse
|
||||
/// block model rendering code. </summary>
|
||||
internal class FakePlayer : Player {
|
||||
/// <summary> Skeleton implementation of player entity so we can reuse block model rendering code. </summary>
|
||||
class FakePlayer : Player {
|
||||
|
||||
public FakePlayer(Game game) : base(game) {
|
||||
NoShade = true;
|
||||
|
@ -295,7 +295,6 @@
|
||||
<ClCompile Include="OpenGLApi.c" />
|
||||
<ClCompile Include="Options.c" />
|
||||
<ClCompile Include="PackedCol.c" />
|
||||
<ClCompile Include="Funcs.c" />
|
||||
<ClCompile Include="GraphicsCommon.c" />
|
||||
<ClCompile Include="Matrix.c" />
|
||||
<ClCompile Include="Noise.c" />
|
||||
|
@ -419,9 +419,6 @@
|
||||
<ClCompile Include="VertexStructs.c">
|
||||
<Filter>Source Files\Math</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Funcs.c">
|
||||
<Filter>Source Files\Utils</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="PackedCol.c">
|
||||
<Filter>Source Files\2D\Utils</Filter>
|
||||
</ClCompile>
|
||||
|
@ -29,24 +29,18 @@ typedef struct LocationUpdate_ {
|
||||
Real32 RotX, RotY, RotZ, HeadX;
|
||||
/* Whether this update includes an absolute or relative position. */
|
||||
bool IncludesPosition;
|
||||
/* Whether the positon is absolute, or relative to the last positionreceived from the server. */
|
||||
/* Whether the positon is absolute, or relative to the last position received from the server. */
|
||||
bool RelativePosition;
|
||||
} LocationUpdate;
|
||||
|
||||
/* Clamps the given angle so it lies between [0, 360). */
|
||||
Real32 LocationUpdate_Clamp(Real32 degrees);
|
||||
|
||||
/* Constructs a location update with values for every field.
|
||||
You should generally prefer using the alternative constructors. */
|
||||
void LocationUpdate_Construct(LocationUpdate* update, Real32 x, Real32 y, Real32 z,
|
||||
Real32 rotX, Real32 rotY, Real32 rotZ, Real32 headX, bool incPos, bool relPos);
|
||||
/* Constructs a location update that does not have any position or orientation information. */
|
||||
void LocationUpdate_Empty(LocationUpdate* update);
|
||||
/* Constructs a location update that only consists of orientation information. */
|
||||
void LocationUpdate_MakeOri(LocationUpdate* update, Real32 rotY, Real32 headX);
|
||||
/* Constructs a location update that only consists of position information. */
|
||||
void LocationUpdate_MakePos(LocationUpdate* update, Vector3 pos, bool rel);
|
||||
/* Constructs a location update that consists of position and orientation information. */
|
||||
void LocationUpdate_MakePosAndOri(LocationUpdate* update, Vector3 pos, Real32 rotY, Real32 headX, bool rel);
|
||||
|
||||
|
||||
|
@ -1,10 +0,0 @@
|
||||
#include "Funcs.h"
|
||||
|
||||
bool Char_IsUpper(UInt8 c) {
|
||||
return c >= 'A' && c <= 'Z';
|
||||
}
|
||||
|
||||
UInt8 Char_ToLower(UInt8 c) {
|
||||
if (!Char_IsUpper(c)) return c;
|
||||
return (UInt8)(c + ' ');
|
||||
}
|
@ -15,11 +15,6 @@
|
||||
/* returns number of elements in given array. */
|
||||
#define Array_NumElements(arr) (sizeof(arr) / sizeof(arr[0]))
|
||||
|
||||
/* returns whether character is uppercase letter */
|
||||
bool Char_IsUpper(UInt8 c);
|
||||
/* Converts uppercase letter to lowercase */
|
||||
UInt8 Char_ToLower(UInt8 c);
|
||||
|
||||
#define QuickSort_Swap_Maybe()\
|
||||
if (i <= j) {\
|
||||
key = keys[i]; keys[i] = keys[j]; keys[j] = key;\
|
||||
|
@ -36,12 +36,12 @@ void GuiElement_Reset(GuiElement* elem) {
|
||||
|
||||
void Screen_Reset(Screen* screen) {
|
||||
GuiElement_Reset(&screen->Base);
|
||||
screen->HandlesAllInput = false;
|
||||
screen->BlocksWorld = false;
|
||||
screen->HidesHUD = false;
|
||||
screen->RenderHUDOver = false;
|
||||
screen->OnResize = NULL;
|
||||
screen->OnContextLost = NULL;
|
||||
screen->HandlesAllInput = false;
|
||||
screen->BlocksWorld = false;
|
||||
screen->HidesHUD = false;
|
||||
screen->RenderHUDOver = false;
|
||||
screen->OnResize = NULL;
|
||||
screen->OnContextLost = NULL;
|
||||
screen->OnContextRecreated = NULL;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,41 @@ UInt8 Hotkeys_LWJGL[256] = {
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
void Hotkeys_QuickSort(Int32 left, Int32 right) {
|
||||
HotkeyData* keys = HotkeysList; HotkeyData key;
|
||||
|
||||
while (left < right) {
|
||||
Int32 i = left, j = right;
|
||||
UInt8 pivot = keys[(i + j) / 2].Flags;
|
||||
|
||||
/* partition the list */
|
||||
while (i <= j) {
|
||||
while (pivot > keys[i].Flags) i++;
|
||||
while (pivot < keys[j].Flags) j--;
|
||||
QuickSort_Swap_Maybe();
|
||||
}
|
||||
/* recurse into the smaller subset */
|
||||
QuickSort_Recurse(Hotkeys_QuickSort)
|
||||
}
|
||||
}
|
||||
|
||||
void Hotkeys_AddNewHotkey(Key baseKey, UInt8 flags, STRING_PURE String* text, bool more) {
|
||||
HotkeyData hKey;
|
||||
hKey.BaseKey = baseKey;
|
||||
hKey.Flags = flags;
|
||||
hKey.TextIndex = HotkeysText.Count;
|
||||
hKey.StaysOpen = more;
|
||||
|
||||
if (HotkeysText.Count == HOTKEYS_MAX_COUNT) {
|
||||
ErrorHandler_Fail("Cannot define more than 256 hotkeys");
|
||||
}
|
||||
|
||||
HotkeysList[HotkeysText.Count] = hKey;
|
||||
StringsBuffer_Add(&HotkeysText, text);
|
||||
/* sort so that hotkeys with largest modifiers are first */
|
||||
Hotkeys_QuickSort(0, HotkeysText.Count - 1);
|
||||
}
|
||||
|
||||
void Hotkeys_Add(Key baseKey, UInt8 flags, STRING_PURE String* text, bool more) {
|
||||
UInt32 i;
|
||||
for (i = 0; i < HotkeysText.Count; i++) {
|
||||
@ -53,41 +88,6 @@ bool Hotkeys_Remove(Key baseKey, UInt8 flags) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void Hotkeys_AddNewHotkey(Key baseKey, UInt8 flags, STRING_PURE String* text, bool more) {
|
||||
HotkeyData hKey;
|
||||
hKey.BaseKey = baseKey;
|
||||
hKey.Flags = flags;
|
||||
hKey.TextIndex = HotkeysText.Count;
|
||||
hKey.StaysOpen = more;
|
||||
|
||||
if (HotkeysText.Count == HOTKEYS_MAX_COUNT) {
|
||||
ErrorHandler_Fail("Cannot define more than 256 hotkeys");
|
||||
}
|
||||
|
||||
HotkeysList[HotkeysText.Count] = hKey;
|
||||
StringsBuffer_Add(&HotkeysText, text);
|
||||
/* sort so that hotkeys with largest modifiers are first */
|
||||
Hotkeys_QuickSort(0, HotkeysText.Count - 1);
|
||||
}
|
||||
|
||||
void Hotkeys_QuickSort(Int32 left, Int32 right) {
|
||||
HotkeyData* keys = HotkeysList; HotkeyData key;
|
||||
|
||||
while (left < right) {
|
||||
Int32 i = left, j = right;
|
||||
UInt8 pivot = keys[(i + j) / 2].Flags;
|
||||
|
||||
/* partition the list */
|
||||
while (i <= j) {
|
||||
while (pivot > keys[i].Flags) i++;
|
||||
while (pivot < keys[j].Flags) j--;
|
||||
QuickSort_Swap_Maybe();
|
||||
}
|
||||
/* recurse into the smaller subset */
|
||||
QuickSort_Recurse(Hotkeys_QuickSort)
|
||||
}
|
||||
}
|
||||
|
||||
bool Hotkeys_IsHotkey(Key key, STRING_TRANSIENT String* text, bool* moreInput) {
|
||||
UInt8 flags = 0;
|
||||
if (Key_IsControlPressed()) flags |= 1;
|
||||
|
@ -3,6 +3,10 @@
|
||||
#include "Typedefs.h"
|
||||
#include "Input.h"
|
||||
#include "String.h"
|
||||
/* Maintains list of hotkeys defined by the client and SetTextHotkey packets.
|
||||
Copyright 2017 ClassicalSharp | Licensed under BSD-3
|
||||
*/
|
||||
|
||||
|
||||
extern UInt8 Hotkeys_LWJGL[256];
|
||||
typedef struct HotkeyData_ {
|
||||
|
@ -154,7 +154,7 @@ void KeyBind_Save(void) {
|
||||
for (i = 0; i < KeyBind_Count; i++) {
|
||||
KeyBind_MakeName(name);
|
||||
String value = String_FromReadonly(Key_Names[i]);
|
||||
Options_Set(name.buffer, value);
|
||||
Options_Set(name.buffer, &value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ IModel* ModelCache_Get(STRING_PURE String* name) {
|
||||
Int32 i;
|
||||
for (i = 0; i < ModelCache_modelCount; i++) {
|
||||
CachedModel* m = &ModelCache_Models[i];
|
||||
if (!String_Equals(&m->Name, name)) continue;
|
||||
if (!String_CaselessEquals(&m->Name, name)) continue;
|
||||
|
||||
if (!m->Instance->initalised) {
|
||||
m->Instance->CreateParts();
|
||||
@ -38,7 +38,7 @@ Int32 ModelCache_GetTextureIndex(STRING_PURE String* texName) {
|
||||
Int32 i;
|
||||
for (i = 0; i < ModelCache_texCount; i++) {
|
||||
CachedTexture* tex = &ModelCache_Textures[i];
|
||||
if (String_Equals(&tex->Name, texName)) return 1;
|
||||
if (String_CaselessEquals(&tex->Name, texName)) return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
@ -3,6 +3,8 @@
|
||||
#include "Game.h"
|
||||
#include "Event.h"
|
||||
#include "GraphicsCommon.h"
|
||||
#include "Platform.h"
|
||||
#include "Inventory.h"
|
||||
|
||||
void Screen_FreeWidgets(Widget** widgets, UInt32 widgetsCount) {
|
||||
if (widgets == NULL) return;
|
||||
@ -96,5 +98,151 @@ void ClickableScreen_Create(ClickableScreen* screen) {
|
||||
screen->OnWidgetSelected = ClickableScreen_DefaultWidgetSelected;
|
||||
}
|
||||
|
||||
Screen AA;
|
||||
extern Screen* InventoryScreen_Unsafe_RawPointer = &AA;
|
||||
typedef struct InventoryScreen_ {
|
||||
Screen Base;
|
||||
FontDesc Font;
|
||||
TableWidget Table;
|
||||
bool ReleasedInv;
|
||||
} InventoryScreen;
|
||||
InventoryScreen InventoryScreen_Instance;
|
||||
|
||||
void InventoryScreen_OnBlockChanged(void) {
|
||||
TableWidget_OnInventoryChanged(&InventoryScreen_Instance.Table);
|
||||
}
|
||||
|
||||
void InventoryScreen_ContextLost(void) {
|
||||
GuiElement* elem = &InventoryScreen_Instance.Table.Base.Base;
|
||||
elem->Free(elem);
|
||||
}
|
||||
|
||||
void InventoryScreen_ContextRecreated(void) {
|
||||
GuiElement* elem = &InventoryScreen_Instance.Table.Base.Base;
|
||||
elem->Recreate(elem);
|
||||
}
|
||||
|
||||
void InventoryScreen_Init(GuiElement* elem) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
screen->Font.Size = 16;
|
||||
Platform_MakeFont(&screen->Font, &Game_FontName);
|
||||
elem = &screen->Table.Base.Base;
|
||||
TableWidget_Create(&screen->Table);
|
||||
screen->Table.Font = screen->Font;
|
||||
screen->Table.ElementsPerRow = Game_PureClassic ? 9 : 10;
|
||||
elem->Init(&elem);
|
||||
|
||||
Key_KeyRepeat = true;
|
||||
Event_RegisterVoid(&BlockEvents_PermissionsChanged, InventoryScreen_OnBlockChanged);
|
||||
Event_RegisterVoid(&BlockEvents_BlockDefChanged, InventoryScreen_OnBlockChanged);
|
||||
Event_RegisterVoid(&GfxEvents_ContextLost, InventoryScreen_ContextLost);
|
||||
Event_RegisterVoid(&GfxEvents_ContextRecreated, InventoryScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
void InventoryScreen_Render(GuiElement* elem, Real64 delta) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
elem = &screen->Table.Base.Base;
|
||||
elem->Render(elem, delta);
|
||||
}
|
||||
|
||||
void InventoryScreen_OnResize(Screen* elem) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
Widget* widget = &screen->Table.Base;
|
||||
widget->Reposition(widget);
|
||||
}
|
||||
|
||||
void InventoryScreen_Free(GuiElement* elem) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
Platform_FreeFont(&screen->Font);
|
||||
elem = &screen->Table.Base.Base;
|
||||
elem->Free(&elem);
|
||||
|
||||
Key_KeyRepeat = false;
|
||||
Event_UnregisterVoid(&BlockEvents_PermissionsChanged, InventoryScreen_OnBlockChanged);
|
||||
Event_UnregisterVoid(&BlockEvents_BlockDefChanged, InventoryScreen_OnBlockChanged);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextLost, InventoryScreen_ContextLost);
|
||||
Event_UnregisterVoid(&GfxEvents_ContextRecreated, InventoryScreen_ContextRecreated);
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
TableWidget* table = &screen->Table;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
if (key == KeyBind_Get(KeyBind_PauseOrExit)) {
|
||||
gGui_SetNewScreen(NULL);
|
||||
} else if (key == KeyBind_Get(KeyBind_Inventory) && screen->ReleasedInv) {
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (key == Key_Enter && table->SelectedIndex != -1) {
|
||||
Inventory_SetSelectedBlock(table->Elements[table->SelectedIndex]);
|
||||
Gui_SetNewScreen(NULL);
|
||||
} else if (elem->HandlesKeyDown(elem, key)) {
|
||||
} else {
|
||||
game.Gui.hudScreen.hotbar.HandlesKeyDown(key);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesKeyUp(GuiElement* elem, Key key) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
if (key == KeyBind_Get(KeyBind_Inventory)) {
|
||||
screen->ReleasedInv = true; return true;
|
||||
}
|
||||
return game.Gui.hudScreen.hotbar.HandlesKeyUp(key);
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
TableWidget* table = &screen->Table;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
if (table->Scroll.DraggingMouse || game.Gui.hudScreen.hotbar.HandlesMouseDown(x, y, btn))
|
||||
return true;
|
||||
|
||||
bool handled = elem->HandlesMouseDown(elem, x, y, btn);
|
||||
if ((!handled || table->PendingClose) && btn == MouseButton_Left) {
|
||||
bool hotbar = Key_IsControlPressed();
|
||||
if (!hotbar) Gui_SetNewScreen(NULL);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesMouseUp(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
return elem->HandlesMouseUp(elem, x, y, btn);
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
return elem->HandlesMouseMove(elem, x, y);
|
||||
}
|
||||
|
||||
bool InventoryScreen_HandlesMouseScroll(GuiElement* elem, Real32 delta) {
|
||||
InventoryScreen* screen = (InventoryScreen*)elem;
|
||||
GuiElement* elem = &screen->Table.Base.Base;
|
||||
|
||||
bool hotbar = Key_IsAltPressed() || Key_IsControlPressed() || Key_IsShiftPressed();
|
||||
if (hotbar) return false;
|
||||
return elem->HandlesMouseScroll(elem, delta);
|
||||
}
|
||||
|
||||
Screen* InventoryScreen_GetInstance(void) {
|
||||
InventoryScreen* screen = &InventoryScreen_Instance;
|
||||
Platform_MemSet(&screen, 0, sizeof(InventoryScreen));
|
||||
Screen_Reset(&screen->Base);
|
||||
|
||||
screen->Base.Base.HandlesKeyDown = InventoryScreen_HandlesKeyDown;
|
||||
screen->Base.Base.HandlesKeyUp = InventoryScreen_HandlesKeyUp;
|
||||
screen->Base.Base.HandlesMouseDown = InventoryScreen_HandlesMouseDown;
|
||||
screen->Base.Base.HandlesMouseUp = InventoryScreen_HandlesMouseUp;
|
||||
screen->Base.Base.HandlesMouseMove = InventoryScreen_HandlesMouseMove;
|
||||
screen->Base.Base.HandlesMouseScroll = InventoryScreen_HandlesMouseScroll;
|
||||
|
||||
screen->Base.OnContextLost = InventoryScreen_ContextLost;
|
||||
screen->Base.OnContextRecreated = InventoryScreen_ContextRecreated;
|
||||
screen->Base.OnResize = InventoryScreen_OnResize;
|
||||
screen->Base.Base.Init = InventoryScreen_Init;
|
||||
screen->Base.Base.Render = InventoryScreen_Render;
|
||||
screen->Base.Base.Free = InventoryScreen_Free;
|
||||
|
||||
return &screen->Base;
|
||||
}
|
||||
extern Screen* InventoryScreen_Unsafe_RawPointer = &InventoryScreen_Instance.Base;
|
||||
|
@ -3,6 +3,12 @@
|
||||
#include "ErrorHandler.h"
|
||||
#include "Platform.h"
|
||||
|
||||
bool Char_IsUpper(UInt8 c) { return c >= 'A' && c <= 'Z'; }
|
||||
UInt8 Char_ToLower(UInt8 c) {
|
||||
if (!Char_IsUpper(c)) return c;
|
||||
return (UInt8)(c + ' ');
|
||||
}
|
||||
|
||||
String String_Init(STRING_REF UInt8* buffer, UInt16 length, UInt16 capacity) {
|
||||
String str;
|
||||
str.buffer = buffer;
|
||||
@ -81,8 +87,8 @@ bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b) {
|
||||
Int32 i;
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
UInt8 aCur = Char_ToLower(a->buffer[i]);
|
||||
UInt8 bCur = Char_ToLower(b->buffer[i]);
|
||||
UInt8 aCur = a->buffer[i]; if (aCur >= 'A' && aCur <= 'Z') { aCur += ' '; }
|
||||
UInt8 bCur = b->buffer[i]; if (bCur >= 'A' && bCur <= 'Z') { bCur += ' '; }
|
||||
if (aCur != bCur) return false;
|
||||
}
|
||||
return true;
|
||||
@ -131,9 +137,7 @@ bool String_AppendInt32(STRING_TRANSIENT String* str, Int32 num) {
|
||||
bool String_AppendPaddedInt32(STRING_TRANSIENT String* str, Int32 num, Int32 minDigits) {
|
||||
UInt8 numBuffer[STRING_INT32CHARS];
|
||||
Int32 i;
|
||||
for (i = 0; i < minDigits; i++) {
|
||||
numBuffer[i] = '0';
|
||||
}
|
||||
for (i = 0; i < minDigits; i++) { numBuffer[i] = '0'; }
|
||||
|
||||
Int32 numLen = String_MakeInt32(num, numBuffer);
|
||||
if (numLen < minDigits) numLen = minDigits;
|
||||
|
@ -19,6 +19,9 @@
|
||||
Thus it is **NOT SAFE** to allocate a string on the stack. */
|
||||
#define STRING_REF
|
||||
|
||||
bool Char_IsUpper(UInt8 c);
|
||||
UInt8 Char_ToLower(UInt8 c);
|
||||
|
||||
typedef struct String_ {
|
||||
UInt8* buffer; /* Pointer to raw characters. Size is capacity + 1, as buffer is null terminated. */
|
||||
UInt16 length; /* Number of characters used. */
|
||||
|
Loading…
x
Reference in New Issue
Block a user