diff --git a/ClassicalSharp/2D/Screens/Menu/HotkeyListScreen.cs b/ClassicalSharp/2D/Screens/Menu/HotkeyListScreen.cs index 9b680dc96..001b3ebf6 100644 --- a/ClassicalSharp/2D/Screens/Menu/HotkeyListScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/HotkeyListScreen.cs @@ -21,7 +21,7 @@ namespace ClassicalSharp.Gui.Screens { entries[i] = hKey.BaseKey + " |" + MakeFlagsString(hKey.Flags); } for (int i = 0; i < items; i++) - entries[count + i] = "-----"; + entries[count + i] = empty; } internal static string MakeFlagsString(byte flags) { @@ -35,7 +35,7 @@ namespace ClassicalSharp.Gui.Screens { protected override void TextButtonClick(Game game, Widget widget) { string text = ((ButtonWidget)widget).Text; Hotkey original = default(Hotkey); - if (text != "-----") + if (text != empty) original = Parse(text); game.Gui.SetNewScreen(new EditHotkeyScreen(game, original)); } diff --git a/ClassicalSharp/2D/Screens/Menu/ListScreen.cs b/ClassicalSharp/2D/Screens/Menu/ListScreen.cs index 2d882b3c9..3fc47eab1 100644 --- a/ClassicalSharp/2D/Screens/Menu/ListScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/ListScreen.cs @@ -16,6 +16,7 @@ namespace ClassicalSharp.Gui.Screens { protected int currentIndex; protected ButtonWidget[] buttons; protected const int items = 5; + protected const string empty = "-----"; TextWidget title; protected string titleText; @@ -54,7 +55,7 @@ namespace ClassicalSharp.Gui.Screens { void MoveForwards(Game g, Widget w) { PageClick(true); } string Get(int index) { - return index < entries.Length ? entries[index] : "-----"; + return index < entries.Length ? entries[index] : empty; } public override void Dispose() { diff --git a/ClassicalSharp/2D/Screens/Menu/TexturePackScreen.cs b/ClassicalSharp/2D/Screens/Menu/TexturePackScreen.cs index a65f0d616..bf8518ba8 100644 --- a/ClassicalSharp/2D/Screens/Menu/TexturePackScreen.cs +++ b/ClassicalSharp/2D/Screens/Menu/TexturePackScreen.cs @@ -24,11 +24,11 @@ namespace ClassicalSharp.Gui.Screens { string path = Path.Combine(dir, file); if (!File.Exists(path)) return; - int index = currentIndex; + int curPage = currentIndex; game.DefaultTexturePack = file; TexturePack.ExtractDefault(game); Recreate(); - SetCurrentIndex(index); + SetCurrentIndex(curPage); } } } \ No newline at end of file diff --git a/ClassicalSharp/MeshBuilder/Builder.cs b/ClassicalSharp/MeshBuilder/Builder.cs index a112fa626..54d45ddf1 100644 --- a/ClassicalSharp/MeshBuilder/Builder.cs +++ b/ClassicalSharp/MeshBuilder/Builder.cs @@ -283,7 +283,7 @@ namespace ClassicalSharp { } index++; - if (counts[index] == 0 || y == 0 || + if (counts[index] == 0 || (hidden[tileIdx + chunk[cIndex - 324]] & (1 << Side.Bottom)) != 0) { counts[index] = 0; } else { diff --git a/src/Client/Menus.c b/src/Client/Menus.c index c1ecebd95..fd793c086 100644 --- a/src/Client/Menus.c +++ b/src/Client/Menus.c @@ -28,7 +28,7 @@ typedef struct ListScreen_ { Screen_Layout FontDesc Font; Int32 CurrentIndex; - Widget_LeftClick TextButtonClick; + Widget_LeftClick EntryClick; String TitleText; ButtonWidget Buttons[FILES_SCREEN_BUTTONS]; TextWidget Title; @@ -188,23 +188,32 @@ Int32 Menu_HandleMouseMove(Widget** widgets, Int32 count, Int32 x, Int32 y) { return -1; } +Int32 Menu_Index(Widget** widgets, Int32 widgetsCount, Widget* w) { + Int32 i; + for (i = 0; i < widgetsCount; i++) { + if (widgets[i] == w) return i; + } + return -1; +} + /*########################################################################################################################* *--------------------------------------------------------ListScreen-------------------------------------------------------* *#########################################################################################################################*/ GuiElementVTABLE ListScreen_VTABLE; ListScreen ListScreen_Instance; +#define LIST_SCREEN_EMPTY "-----" STRING_REF String ListScreen_UNSAFE_Get(ListScreen* screen, UInt32 index) { if (index < screen->Entries.Count) { return StringsBuffer_UNSAFE_Get(&screen->Entries, index); } else { - String str = String_FromConst("-----"); return str; + String str = String_FromConst(LIST_SCREEN_EMPTY); return str; } } void ListScreen_MakeText(ListScreen* screen, Int32 idx, Int32 x, Int32 y, String* text) { ButtonWidget* widget = &screen->Buttons[idx]; - ButtonWidget_Create(widget, text, 300, &screen->Font, screen->TextButtonClick); + ButtonWidget_Create(widget, text, 300, &screen->Font, screen->EntryClick); Widget_SetLocation((Widget*)widget, ANCHOR_CENTRE, ANCHOR_CENTRE, x, y); } @@ -278,6 +287,24 @@ void ListScreen_ContextRecreated(void* obj) { ListScreen_UpdateArrows(screen); } +void ListScreen_Sort(Int32 left, Int32 right) { + StringsBuffer* buffer = &ListScreen_Instance.Entries; + UInt32* keys = buffer->FlagsBuffer; UInt32 key; + while (left < right) { + Int32 i = left, j = right; + Int32 pivot = (i + j) / 2; + + /* partition the list */ + while (i <= j) { + while (StringsBuffer_Compare(buffer, pivot, i) > 0) i++; + while (StringsBuffer_Compare(buffer, pivot, j) < 0) j--; + QuickSort_Swap_Maybe(); + } + /* recurse into the smaller subset */ + QuickSort_Recurse(ListScreen_QuickSort) + } +} + void ListScreen_Init(GuiElement* elem) { ListScreen* screen = (ListScreen*)elem; Platform_MakeFont(&screen->Font, &Game_FontName, 16, FONT_STYLE_BOLD); @@ -331,7 +358,7 @@ void ListScreen_OnResize(GuiElement* elem) { Menu_RepositionWidgets(screen->Widgets, Array_Elems(screen->Widgets)); } -Screen* ListScreen_MakeInstance(void) { +ListScreen* ListScreen_MakeInstance(void) { ListScreen* screen = &ListScreen_Instance; Platform_MemSet(screen, 0, sizeof(ListScreen) - sizeof(StringsBuffer)); StringsBuffer_UNSAFE_Reset(&screen->Entries); @@ -347,7 +374,7 @@ Screen* ListScreen_MakeInstance(void) { screen->VTABLE->Render = ListScreen_Render; screen->VTABLE->Free = ListScreen_Free; screen->HandlesAllInput = true; - return (Screen*)screen; + return screen; } @@ -356,11 +383,7 @@ Screen* ListScreen_MakeInstance(void) { *#########################################################################################################################*/ GuiElementVTABLE MenuScreen_VTABLE; Int32 MenuScreen_Index(MenuScreen* screen, Widget* w) { - Int32 i; - for (i = 0; i < screen->WidgetsCount; i++) { - if (screen->WidgetsPtr[i] == w) return i; - } - return -1; + return Menu_Index(screen->WidgetsPtr, screen->WidgetsCount, w); } bool MenuScreen_HandlesMouseDown(GuiElement* elem, Int32 x, Int32 y, MouseButton btn) { @@ -1107,6 +1130,7 @@ Screen* GenLevelScreen_MakeInstance(void) { return (Screen*)screen; } + /*########################################################################################################################* *----------------------------------------------------ClassicGenScreen-----------------------------------------------------* *#########################################################################################################################*/ @@ -1156,4 +1180,58 @@ Screen* ClassicGenScreen_MakeInstance(void) { screen->VTABLE->Init = ClassicGenScreen_Init; return (Screen*)screen; -} \ No newline at end of file +} + + +/*########################################################################################################################* +*---------------------------------------------------TexturePackScreen-----------------------------------------------------* +*#########################################################################################################################*/ +void TexturePackScreen_EntryClick(GuiElement* screenElem, GuiElement* w) { + ListScreen* screen = (ListScreen*)screenElem; + UInt8 pathBuffer[String_BufferSize(FILENAME_SIZE)]; + String path = String_InitAndClearArray(pathBuffer); + + Int32 curPage = screen->CurrentIndex; + Int32 idx = Menu_Index(screen->Widgets, Array_Elems(screen->Widgets), (Widget*)w); + String filename = StringsBuffer_UNSAFE_Get(&screen->Entries, curPage + idx); + + String_AppendConst(&path, "texpacks"); + String_Append(&path, Platform_DirectorySeparator); + String_Append(&path, &filename); + if (!Platform_FileExists(&path)) return; + + game.DefaultTexturePack = filename; + TexturePack_ExtractDefault(); + Elem_Recreate(screen); + ListScreen_SetCurrentIndex(screen, curPage); +} + +void TexturePackScreen_SelectEntry(STRING_PURE String* path, void* obj) { + String zip = String_FromConst(".zip"); + if (!String_CaselessEnds(path, &zip)) return; + + /* folder1/folder2/entry.zip --> entry.zip */ + String filename = *path; + Int32 lastDir = String_LastIndexOf(&filename, Platform_DirectorySeparator); + if (lastDir >= 0) { + filename = String_UNSAFE_SubstringAt(&filename, lastDir + 1); + } + + StringsBuffer* entries = (StringsBuffer*)obj; + StringsBuffer_Add(entries, &filename); +} + +Screen* TexturePackScreen_MakeInstance(void) { + ListScreen* screen = ListScreen_MakeInstance(); + String title = String_FromConst("Select a texture pack zip"); + screen->TitleText = title; + screen->EntryClick = TexturePackScreen_EntryClick; + + String path = String_FromConst("texpacks"); + Platform_EnumFiles(&path, &screen->Entries, TexturePackScreen_SelectEntry); + if (screen->Entries.Count > 0) { + ListScreen_Sort(0, screen->Entries.Count - 1); + } + + return (Screen*)screen; +} diff --git a/src/Client/String.c b/src/Client/String.c index f16a40b87..107b2790b 100644 --- a/src/Client/String.c +++ b/src/Client/String.c @@ -211,11 +211,6 @@ Int32 String_LastIndexOf(STRING_PURE String* str, UInt8 c) { return -1; } -UInt8 String_CharAt(STRING_PURE String* str, Int32 offset) { - if (offset < 0 || offset >= str->length) return NULL; - return str->buffer[offset]; -} - void String_InsertAt(STRING_TRANSIENT String* str, Int32 offset, UInt8 c) { if (offset < 0 || offset > str->length) { ErrorHandler_Fail("Offset for InsertAt out of range"); @@ -571,4 +566,10 @@ void StringsBuffer_Remove(StringsBuffer* buffer, UInt32 index) { buffer->Count--; buffer->UsedElems -= len; +} + +Int32 StringsBuffer_Compare(StringsBuffer* buffer, UInt32 idxA, UInt32 idxB) { + String strA = StringsBuffer_UNSAFE_Get(buffer, idxA); + String strB = StringsBuffer_UNSAFE_Get(buffer, idxB); + return String_Compare(&strA, &strB); } \ No newline at end of file diff --git a/src/Client/String.h b/src/Client/String.h index 28b1bbf23..ffeaa280a 100644 --- a/src/Client/String.h +++ b/src/Client/String.h @@ -65,7 +65,6 @@ bool String_AppendColorless(STRING_TRANSIENT String* str, STRING_PURE String* to Int32 String_IndexOf(STRING_PURE String* str, UInt8 c, Int32 offset); Int32 String_LastIndexOf(STRING_PURE String* str, UInt8 c); -UInt8 String_CharAt(STRING_PURE String* str, Int32 offset); void String_InsertAt(STRING_TRANSIENT String* str, Int32 offset, UInt8 c); void String_DeleteAt(STRING_TRANSIENT String* str, Int32 offset); @@ -104,4 +103,5 @@ void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT Str STRING_REF String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index); void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text); void StringsBuffer_Remove(StringsBuffer* buffer, UInt32 index); +Int32 StringsBuffer_Compare(StringsBuffer* buffer, UInt32 idxA, UInt32 idxB); #endif \ No newline at end of file