Simplify menu input code

This commit is contained in:
UnknownShadow200 2019-08-08 22:02:42 +10:00
parent 25d6518931
commit 283f753b3e
4 changed files with 184 additions and 209 deletions

View File

@ -109,9 +109,8 @@ struct SaveLevelScreen {
struct MenuOptionsScreen { struct MenuOptionsScreen {
MenuScreen_Layout MenuScreen_Layout
struct ButtonWidget* buttons; struct ButtonWidget* buttons;
struct InputValidator* validators; struct MenuInputDesc* descs;
const char** descriptions; const char** descriptions;
const char** defaultValues;
int activeI, selectedI, descriptionsCount; int activeI, selectedI, descriptionsCount;
struct ButtonWidget ok, Default; struct ButtonWidget ok, Default;
struct MenuInputWidget input; struct MenuInputWidget input;
@ -176,9 +175,9 @@ static void Menu_Label(void* s, int i, struct TextWidget* label, const String* t
Widget_SetLocation(menu->widgets[i], horAnchor, verAnchor, x, y); Widget_SetLocation(menu->widgets[i], horAnchor, verAnchor, x, y);
} }
static void Menu_Input(void* s, int i, struct MenuInputWidget* input, int width, const String* text, FontDesc* font, struct InputValidator* v, int horAnchor, int verAnchor, int x, int y) { static void Menu_Input(void* s, int i, struct MenuInputWidget* input, int width, const String* text, FontDesc* font, struct MenuInputDesc* desc, int horAnchor, int verAnchor, int x, int y) {
struct Menu* menu = (struct Menu*)s; struct Menu* menu = (struct Menu*)s;
MenuInputWidget_Create(input, width, 30, text, font, v); MenuInputWidget_Create(input, width, 30, text, font, desc);
menu->widgets[i] = (struct Widget*)input; menu->widgets[i] = (struct Widget*)input;
Widget_SetLocation(menu->widgets[i], horAnchor, verAnchor, x, y); Widget_SetLocation(menu->widgets[i], horAnchor, verAnchor, x, y);
@ -954,10 +953,10 @@ static void EditHotkeyScreen_ContextRecreated(void* screen) {
static const String cancel = String_FromConst("Cancel"); static const String cancel = String_FromConst("Cancel");
struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen; struct EditHotkeyScreen* s = (struct EditHotkeyScreen*)screen;
struct InputValidator v; struct MenuInputDesc desc;
String text; bool existed; String text; bool existed;
InputValidator_String(v); MenuInput_String(desc);
existed = s->origHotkey.Trigger != KEY_NONE; existed = s->origHotkey.Trigger != KEY_NONE;
if (existed) { if (existed) {
text = StringsBuffer_UNSAFE_Get(&HotkeysText, s->origHotkey.TextIndex); text = StringsBuffer_UNSAFE_Get(&HotkeysText, s->origHotkey.TextIndex);
@ -973,7 +972,7 @@ static void EditHotkeyScreen_ContextRecreated(void* screen) {
EditHotkeyScreen_RemoveHotkey); EditHotkeyScreen_RemoveHotkey);
Menu_Back(s, 5, &s->buttons[5], "Cancel", &s->titleFont, Menu_SwitchHotkeys); Menu_Back(s, 5, &s->buttons[5], "Cancel", &s->titleFont, Menu_SwitchHotkeys);
Menu_Input(s, 6, &s->input, 500, &text, &s->textFont, &v, Menu_Input(s, 6, &s->input, 500, &text, &s->textFont, &desc,
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35); ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -35);
} }
@ -1006,12 +1005,12 @@ struct Screen* EditHotkeyScreen_MakeInstance(struct HotkeyData original) {
static struct GenLevelScreen GenLevelScreen_Instance; static struct GenLevelScreen GenLevelScreen_Instance;
CC_NOINLINE static int GenLevelScreen_GetInt(struct GenLevelScreen* s, int index) { CC_NOINLINE static int GenLevelScreen_GetInt(struct GenLevelScreen* s, int index) {
struct MenuInputWidget* input = &s->inputs[index]; struct MenuInputWidget* input = &s->inputs[index];
struct InputValidator* v; struct MenuInputDesc* desc;
String text = input->base.text; String text = input->base.text;
int value; int value;
v = &input->validator; desc = &input->desc;
if (!v->VTABLE->IsValidValue(v, &text)) return 0; if (!desc->VTABLE->IsValidValue(desc, &text)) return 0;
Convert_ParseInt(&text, &value); return value; Convert_ParseInt(&text, &value); return value;
} }
@ -1063,22 +1062,25 @@ static void GenLevelScreen_InputClick(void* screen, void* input) {
s->selected->base.showCaret = true; s->selected->base.showCaret = true;
} }
static void GenLevelScreen_Input(struct GenLevelScreen* s, int i, int y, bool seed, String* value) { static void GenLevelScreen_Input(struct GenLevelScreen* s, int i, int y, bool seed, int def) {
String tmp; char tmpBuffer[STRING_SIZE];
struct MenuInputWidget* input = &s->inputs[i]; struct MenuInputWidget* input = &s->inputs[i];
struct InputValidator v; struct MenuInputDesc desc;
if (seed) { if (seed) {
InputValidator_Seed(v); MenuInput_Seed(desc);
} else { } else {
InputValidator_Int(v, 1, 8192); MenuInput_Int(desc, 1, 8192, def);
} }
Menu_Input(s, i, input, 200, value, &s->textFont, &v, String_InitArray(tmp, tmpBuffer);
desc.VTABLE->GetDefault(&desc, &tmp);
Menu_Input(s, i, input, 200, &tmp, &s->textFont, &desc,
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, y); ANCHOR_CENTRE, ANCHOR_CENTRE, 0, y);
input->base.showCaret = false; input->base.showCaret = false;
input->base.MenuClick = GenLevelScreen_InputClick; input->base.MenuClick = GenLevelScreen_InputClick;
value->length = 0;
} }
static void GenLevelScreen_Label(struct GenLevelScreen* s, int i, int x, int y, const char* title) { static void GenLevelScreen_Label(struct GenLevelScreen* s, int i, int x, int y, const char* title) {
@ -1114,18 +1116,12 @@ static void GenLevelScreen_ContextRecreated(void* screen) {
static const String title = String_FromConst("Generate new level"); static const String title = String_FromConst("Generate new level");
static const String flat = String_FromConst("Flatgrass"); static const String flat = String_FromConst("Flatgrass");
static const String norm = String_FromConst("Vanilla"); static const String norm = String_FromConst("Vanilla");
String tmp; char tmpBuffer[STRING_SIZE]; struct GenLevelScreen* s = (struct GenLevelScreen*)screen;
struct GenLevelScreen* s = (struct GenLevelScreen*)screen; GenLevelScreen_Input(s, 0, -80, false, World.Width);
String_InitArray(tmp, tmpBuffer); GenLevelScreen_Input(s, 1, -40, false, World.Height);
GenLevelScreen_Input(s, 2, 0, false, World.Length);
String_AppendInt(&tmp, World.Width); GenLevelScreen_Input(s, 3, 40, true, 0);
GenLevelScreen_Input(s, 0, -80, false, &tmp);
String_AppendInt(&tmp, World.Height);
GenLevelScreen_Input(s, 1, -40, false, &tmp);
String_AppendInt(&tmp, World.Length);
GenLevelScreen_Input(s, 2, 0, false, &tmp);
GenLevelScreen_Input(s, 3, 40, true, &tmp);
GenLevelScreen_Label(s, 0, -150, -80, "Width:"); GenLevelScreen_Label(s, 0, -150, -80, "Width:");
GenLevelScreen_Label(s, 1, -150, -40, "Height:"); GenLevelScreen_Label(s, 1, -150, -40, "Height:");
@ -1334,8 +1330,8 @@ static void SaveLevelScreen_ContextRecreated(void* screen) {
static const String mcEdit = String_FromConst("&eCan be imported into MCEdit"); static const String mcEdit = String_FromConst("&eCan be imported into MCEdit");
struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen; struct SaveLevelScreen* s = (struct SaveLevelScreen*)screen;
struct InputValidator v; struct MenuInputDesc desc;
InputValidator_Path(v); MenuInput_Path(desc);
Menu_Button(s, 0, &s->buttons[0], 300, &save, &s->titleFont, SaveLevelScreen_Classic, Menu_Button(s, 0, &s->buttons[0], 300, &save, &s->titleFont, SaveLevelScreen_Classic,
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 20); ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 20);
@ -1345,7 +1341,7 @@ static void SaveLevelScreen_ContextRecreated(void* screen) {
ANCHOR_CENTRE, ANCHOR_CENTRE, 110, 120); ANCHOR_CENTRE, ANCHOR_CENTRE, 110, 120);
Menu_Back(s, 3, &s->buttons[2], "Cancel", &s->titleFont, Menu_SwitchPause); Menu_Back(s, 3, &s->buttons[2], "Cancel", &s->titleFont, Menu_SwitchPause);
Menu_Input(s, 4, &s->input, 500, &String_Empty, &s->textFont, &v, Menu_Input(s, 4, &s->input, 500, &String_Empty, &s->textFont, &desc,
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30); ANCHOR_CENTRE, ANCHOR_CENTRE, 0, -30);
s->widgets[5] = NULL; /* description widget placeholder */ s->widgets[5] = NULL; /* description widget placeholder */
} }
@ -1962,10 +1958,10 @@ static void MenuOptionsScreen_FreeInput(struct MenuOptionsScreen* s) {
} }
static void MenuOptionsScreen_EnterInput(struct MenuOptionsScreen* s) { static void MenuOptionsScreen_EnterInput(struct MenuOptionsScreen* s) {
struct InputValidator* v = &s->input.validator; struct MenuInputDesc* desc = &s->input.desc;
String text = s->input.base.text; String text = s->input.base.text;
if (v->VTABLE->IsValidValue(v, &text)) { if (desc->VTABLE->IsValidValue(desc, &text)) {
MenuOptionsScreen_Set(s, s->activeI, &text); MenuOptionsScreen_Set(s, s->activeI, &text);
} }
@ -2077,10 +2073,16 @@ static void MenuOptionsScreen_OK(void* screen, void* widget) {
} }
static void MenuOptionsScreen_Default(void* screen, void* widget) { static void MenuOptionsScreen_Default(void* screen, void* widget) {
String value; char valueBuffer[STRING_SIZE];
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
String text = String_FromReadonly(s->defaultValues[s->activeI]); struct MenuInputDesc* desc;
desc = &s->descs[s->activeI];
String_InitArray(value, valueBuffer);
desc->VTABLE->GetDefault(desc, &value);
InputWidget_Clear(&s->input.base); InputWidget_Clear(&s->input.base);
InputWidget_AppendString(&s->input.base, &text); InputWidget_AppendString(&s->input.base, &value);
} }
static void MenuOptionsScreen_Bool(void* screen, void* widget) { static void MenuOptionsScreen_Bool(void* screen, void* widget) {
@ -2105,7 +2107,7 @@ static void MenuOptionsScreen_Enum(void* screen, void* widget) {
struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen; struct MenuOptionsScreen* s = (struct MenuOptionsScreen*)screen;
struct ButtonWidget* btn = (struct ButtonWidget*)widget; struct ButtonWidget* btn = (struct ButtonWidget*)widget;
int index; int index;
struct InputValidator* v; struct MenuInputDesc* desc;
const char** names; const char** names;
int raw, count; int raw, count;
@ -2114,9 +2116,9 @@ static void MenuOptionsScreen_Enum(void* screen, void* widget) {
String_InitArray(value, valueBuffer); String_InitArray(value, valueBuffer);
btn->GetValue(&value); btn->GetValue(&value);
v = &s->validators[index]; desc = &s->descs[index];
names = v->Meta.e.Names; names = desc->meta.e.Names;
count = v->Meta.e.Count; count = desc->meta.e.Count;
raw = (Utils_ParseEnum(&value, 0, names, count) + 1) % count; raw = (Utils_ParseEnum(&value, 0, names, count) + 1) % count;
value = String_FromReadonly(names[raw]); value = String_FromReadonly(names[raw]);
@ -2140,7 +2142,7 @@ static void MenuOptionsScreen_Input(void* screen, void* widget) {
btn->GetValue(&value); btn->GetValue(&value);
i = s->widgetsCount; i = s->widgetsCount;
Menu_Input(s, i - 1, &s->input, 400, &value, &s->textFont, &s->validators[s->activeI], Menu_Input(s, i - 1, &s->input, 400, &value, &s->textFont, &s->descs[s->activeI],
ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110); ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110);
Menu_Button(s, i - 2, &s->ok, 40, &okay, &s->titleFont, MenuOptionsScreen_OK, Menu_Button(s, i - 2, &s->ok, 40, &okay, &s->titleFont, MenuOptionsScreen_OK,
ANCHOR_CENTRE, ANCHOR_CENTRE, 240, 110); ANCHOR_CENTRE, ANCHOR_CENTRE, 240, 110);
@ -2155,7 +2157,7 @@ static struct ScreenVTABLE MenuOptionsScreen_VTABLE = {
MenuOptionsScreen_OnResize, MenuOptionsScreen_ContextLost, NULL, MenuOptionsScreen_OnResize, MenuOptionsScreen_ContextLost, NULL,
}; };
struct Screen* MenuOptionsScreen_MakeInstance(struct Widget** widgets, int count, struct ButtonWidget* buttons, Event_Void_Callback contextRecreated, struct Screen* MenuOptionsScreen_MakeInstance(struct Widget** widgets, int count, struct ButtonWidget* buttons, Event_Void_Callback contextRecreated,
struct InputValidator* validators, const char** defaultValues, const char** descriptions, int descsCount) { struct MenuInputDesc* descs, const char** descriptions, int descsCount) {
struct MenuOptionsScreen* s = &MenuOptionsScreen_Instance; struct MenuOptionsScreen* s = &MenuOptionsScreen_Instance;
s->handlesAllInput = true; s->handlesAllInput = true;
s->closable = true; s->closable = true;
@ -2168,8 +2170,7 @@ struct Screen* MenuOptionsScreen_MakeInstance(struct Widget** widgets, int count
s->VTABLE->ContextRecreated = contextRecreated; s->VTABLE->ContextRecreated = contextRecreated;
s->buttons = buttons; s->buttons = buttons;
s->validators = validators; s->descs = descs;
s->defaultValues = defaultValues;
s->descriptions = descriptions; s->descriptions = descriptions;
s->descriptionsCount = descsCount; s->descriptionsCount = descsCount;
@ -2271,14 +2272,14 @@ static void ClassicOptionsScreen_ContextRecreated(void* screen) {
struct Screen* ClassicOptionsScreen_MakeInstance(void) { struct Screen* ClassicOptionsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[11]; static struct ButtonWidget buttons[11];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons)]; static struct Widget* widgets[Array_Elems(buttons)];
InputValidator_Enum(validators[2], ViewDist_Names, VIEW_COUNT); MenuInput_Enum(descs[2], ViewDist_Names, VIEW_COUNT);
InputValidator_Enum(validators[7], FpsLimit_Names, FPS_LIMIT_COUNT); MenuInput_Enum(descs[7], FpsLimit_Names, FPS_LIMIT_COUNT);
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
ClassicOptionsScreen_ContextRecreated, validators, NULL, NULL, 0); ClassicOptionsScreen_ContextRecreated, descs, NULL, 0);
} }
@ -2359,42 +2360,23 @@ static String String_InitAndClear(STRING_REF char* buffer, int capacity) {
struct Screen* EnvSettingsScreen_MakeInstance(void) { struct Screen* EnvSettingsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[11]; static struct ButtonWidget buttons[11];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static const char* defaultValues[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons) + 3]; static struct Widget* widgets[Array_Elems(buttons) + 3];
static char cloudHeightBuffer[STRING_INT_CHARS]; MenuInput_Hex(descs[0], Env_DefaultCloudsCol);
static char edgeHeightBuffer[STRING_INT_CHARS]; MenuInput_Hex(descs[1], Env_DefaultSkyCol);
String cloudHeight, edgeHeight; MenuInput_Hex(descs[2], Env_DefaultFogCol);
MenuInput_Float(descs[3], 0, 1000, 1);
MenuInput_Int(descs[4], -10000, 10000, World.Height + 2);
cloudHeight = String_InitAndClear(cloudHeightBuffer, STRING_INT_CHARS); MenuInput_Hex(descs[5], Env_DefaultSunCol);
String_AppendInt(&cloudHeight, World.Height + 2); MenuInput_Hex(descs[6], Env_DefaultShadowCol);
edgeHeight = String_InitAndClear(edgeHeightBuffer, STRING_INT_CHARS); MenuInput_Enum(descs[7], Weather_Names, Array_Elems(Weather_Names));
String_AppendInt(&edgeHeight, World.Height / 2); MenuInput_Float(descs[8], -100, 100, 1);
MenuInput_Int(descs[9], -2048, 2048, World.Height / 2);
InputValidator_Hex(validators[0]);
defaultValues[0] = ENV_DEFAULT_CLOUDSCOL_HEX;
InputValidator_Hex(validators[1]);
defaultValues[1] = ENV_DEFAULT_SKYCOL_HEX;
InputValidator_Hex(validators[2]);
defaultValues[2] = ENV_DEFAULT_FOGCOL_HEX;
InputValidator_Float(validators[3], 0.00f, 1000.00f);
defaultValues[3] = "1";
InputValidator_Int(validators[4], -10000, 10000);
defaultValues[4] = cloudHeightBuffer;
InputValidator_Hex(validators[5]);
defaultValues[5] = ENV_DEFAULT_SUNCOL_HEX;
InputValidator_Hex(validators[6]);
defaultValues[6] = ENV_DEFAULT_SHADOWCOL_HEX;
InputValidator_Enum(validators[7], Weather_Names, Array_Elems(Weather_Names));
InputValidator_Float(validators[8], -100.00f, 100.00f);
defaultValues[8] = "1";
InputValidator_Int(validators[9], -2048, 2048);
defaultValues[9] = edgeHeightBuffer;
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
EnvSettingsScreen_ContextRecreated, validators, defaultValues, NULL, 0); EnvSettingsScreen_ContextRecreated, descs, NULL, 0);
} }
@ -2455,37 +2437,35 @@ static void GraphicsOptionsScreen_ContextRecreated(void* screen) {
struct Screen* GraphicsOptionsScreen_MakeInstance(void) { struct Screen* GraphicsOptionsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[7]; static struct ButtonWidget buttons[7];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static const char* defaultValues[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons) + 3]; static struct Widget* widgets[Array_Elems(buttons) + 3];
static const char* descs[Array_Elems(buttons)]; static const char* extDescs[Array_Elems(buttons)];
descs[0] = \ extDescs[0] = \
"&eVSync: &fNumber of frames rendered is at most the monitor's refresh rate.\n" \ "&eVSync: &fNumber of frames rendered is at most the monitor's refresh rate.\n" \
"&e30/60/120/144 FPS: &fRenders 30/60/120/144 frames at most each second.\n" \ "&e30/60/120/144 FPS: &fRenders 30/60/120/144 frames at most each second.\n" \
"&eNoLimit: &fRenders as many frames as possible each second.\n" \ "&eNoLimit: &fRenders as many frames as possible each second.\n" \
"&cUsing NoLimit mode is discouraged."; "&cUsing NoLimit mode is discouraged.";
descs[2] = "&cNote: &eSmooth lighting is still experimental and can heavily reduce performance."; extDescs[2] = "&cNote: &eSmooth lighting is still experimental and can heavily reduce performance.";
descs[3] = \ extDescs[3] = \
"&eNone: &fNo names of players are drawn.\n" \ "&eNone: &fNo names of players are drawn.\n" \
"&eHovered: &fName of the targeted player is drawn see-through.\n" \ "&eHovered: &fName of the targeted player is drawn see-through.\n" \
"&eAll: &fNames of all other players are drawn normally.\n" \ "&eAll: &fNames of all other players are drawn normally.\n" \
"&eAllHovered: &fAll names of players are drawn see-through.\n" \ "&eAllHovered: &fAll names of players are drawn see-through.\n" \
"&eAllUnscaled: &fAll names of players are drawn see-through without scaling."; "&eAllUnscaled: &fAll names of players are drawn see-through without scaling.";
descs[4] = \ extDescs[4] = \
"&eNone: &fNo entity shadows are drawn.\n" \ "&eNone: &fNo entity shadows are drawn.\n" \
"&eSnapToBlock: &fA square shadow is shown on block you are directly above.\n" \ "&eSnapToBlock: &fA square shadow is shown on block you are directly above.\n" \
"&eCircle: &fA circular shadow is shown across the blocks you are above.\n" \ "&eCircle: &fA circular shadow is shown across the blocks you are above.\n" \
"&eCircleAll: &fA circular shadow is shown underneath all entities."; "&eCircleAll: &fA circular shadow is shown underneath all entities.";
InputValidator_Enum(validators[0], FpsLimit_Names, FPS_LIMIT_COUNT); MenuInput_Enum(descs[0], FpsLimit_Names, FPS_LIMIT_COUNT);
InputValidator_Int(validators[1], 8, 4096); MenuInput_Int(descs[1], 8, 4096, 512);
defaultValues[1] = "512"; MenuInput_Enum(descs[3], NameMode_Names, NAME_MODE_COUNT);
InputValidator_Enum(validators[3], NameMode_Names, NAME_MODE_COUNT); MenuInput_Enum(descs[4], ShadowMode_Names, SHADOW_MODE_COUNT);
InputValidator_Enum(validators[4], ShadowMode_Names, SHADOW_MODE_COUNT);
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
GraphicsOptionsScreen_ContextRecreated, validators, defaultValues, descs, Array_Elems(descs)); GraphicsOptionsScreen_ContextRecreated, descs, extDescs, Array_Elems(extDescs));
} }
@ -2569,21 +2549,16 @@ static void GuiOptionsScreen_ContextRecreated(void* screen) {
struct Screen* GuiOptionsScreen_MakeInstance(void) { struct Screen* GuiOptionsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[11]; static struct ButtonWidget buttons[11];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static const char* defaultValues[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons) + 3]; static struct Widget* widgets[Array_Elems(buttons) + 3];
InputValidator_Float(validators[2], 0.25f, 4.00f); MenuInput_Float(descs[2], 0.25f, 4.00f, 1);
defaultValues[2] = "1"; MenuInput_Float(descs[3], 0.25f, 4.00f, 1);
InputValidator_Float(validators[3], 0.25f, 4.00f); MenuInput_Float(descs[6], 0.25f, 4.00f, 1);
defaultValues[3] = "1"; MenuInput_Int(descs[7], 0, 30, 10);
InputValidator_Float(validators[6], 0.25f, 4.00f);
defaultValues[6] = "1";
InputValidator_Int(validators[7], 0, 30);
defaultValues[7] = "10";
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
GuiOptionsScreen_ContextRecreated, validators, defaultValues, NULL, 0); GuiOptionsScreen_ContextRecreated, descs, NULL, 0);
} }
@ -2718,29 +2693,24 @@ static void HacksSettingsScreen_ContextRecreated(void* screen) {
struct Screen* HacksSettingsScreen_MakeInstance(void) { struct Screen* HacksSettingsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[11]; static struct ButtonWidget buttons[11];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static const char* defaultValues[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons) + 3]; static struct Widget* widgets[Array_Elems(buttons) + 3];
static const char* descs[Array_Elems(buttons)]; static const char* extDescs[Array_Elems(buttons)];
descs[2] = "&eIf &fON&e, then the third person cameras will limit\n&etheir zoom distance if they hit a solid block."; extDescs[2] = "&eIf &fON&e, then the third person cameras will limit\n&etheir zoom distance if they hit a solid block.";
descs[3] = "&eSets how many blocks high you can jump up.\n&eNote: You jump much higher when holding down the Speed key binding."; extDescs[3] = "&eSets how many blocks high you can jump up.\n&eNote: You jump much higher when holding down the Speed key binding.";
descs[7] = \ extDescs[7] = \
"&eIf &fON&e, placing blocks that intersect your own position cause\n" \ "&eIf &fON&e, placing blocks that intersect your own position cause\n" \
"&ethe block to be placed, and you to be moved out of the way.\n" \ "&ethe block to be placed, and you to be moved out of the way.\n" \
"&fThis is mainly useful for quick pillaring/towering."; "&fThis is mainly useful for quick pillaring/towering.";
descs[8] = "&eIf &fOFF&e, you will immediately stop when in noclip\n&emode and no movement keys are held down."; extDescs[8] = "&eIf &fOFF&e, you will immediately stop when in noclip\n&emode and no movement keys are held down.";
InputValidator_Float(validators[1], 0.10f, 50.00f); MenuInput_Float(descs[1], 0.1f, 50, 10);
defaultValues[1] = "10"; MenuInput_Float(descs[3], 0.1f, 2048, 1.233f);
InputValidator_Float(validators[3], 0.10f, 2048.00f); MenuInput_Int(descs[9], 1, 179, 70);
/* TODO: User may not always use . for decimal point, need to account for that */
defaultValues[3] = "1.233";
InputValidator_Int(validators[9], 1, 179);
defaultValues[9] = "70";
struct Screen* s = MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, struct Screen* s = MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
HacksSettingsScreen_ContextRecreated, validators, defaultValues, descs, Array_Elems(buttons)); HacksSettingsScreen_ContextRecreated, descs, extDescs, Array_Elems(extDescs));
s->VTABLE->ContextLost = HacksSettingsScreen_ContextLost; s->VTABLE->ContextLost = HacksSettingsScreen_ContextLost;
return s; return s;
} }
@ -2818,25 +2788,20 @@ static void MiscOptionsScreen_ContextRecreated(void* screen) {
struct Screen* MiscOptionsScreen_MakeInstance(void) { struct Screen* MiscOptionsScreen_MakeInstance(void) {
static struct ButtonWidget buttons[9]; static struct ButtonWidget buttons[9];
static struct InputValidator validators[Array_Elems(buttons)]; static struct MenuInputDesc descs[Array_Elems(buttons)];
static const char* defaultValues[Array_Elems(buttons)];
static struct Widget* widgets[Array_Elems(buttons) + 3]; static struct Widget* widgets[Array_Elems(buttons) + 3];
InputValidator_Float(validators[0], 1.00f, 1024.00f); MenuInput_Float(descs[0], 1, 1024, 5);
defaultValues[0] = "5"; MenuInput_Int(descs[1], 0, 100, 0);
InputValidator_Int(validators[1], 0, 100); MenuInput_Int(descs[2], 0, 100, 0);
defaultValues[1] = "0";
InputValidator_Int(validators[2], 0, 100);
defaultValues[2] = "0";
InputValidator_Int(validators[7], 1, 200);
#ifdef CC_BUILD_WIN #ifdef CC_BUILD_WIN
defaultValues[7] = "40"; MenuInput_Int(descs[7], 1, 200, 40);
#else #else
defaultValues[7] = "30"; MenuInput_Int(descs[7], 1, 200, 30);
#endif #endif
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
MiscOptionsScreen_ContextRecreated, validators, defaultValues, NULL, 0); MiscOptionsScreen_ContextRecreated, descs, NULL, 0);
} }
@ -2909,7 +2874,7 @@ struct Screen* NostalgiaScreen_MakeInstance(void) {
static struct Widget* widgets[Array_Elems(buttons) + 1]; static struct Widget* widgets[Array_Elems(buttons) + 1];
return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons, return MenuOptionsScreen_MakeInstance(widgets, Array_Elems(widgets), buttons,
NostalgiaScreen_ContextRecreated, NULL, NULL, NULL, 0); NostalgiaScreen_ContextRecreated, NULL, NULL, 0);
} }

View File

@ -1295,111 +1295,124 @@ CC_NOINLINE static void InputWidget_Create(struct InputWidget* w, FontDesc* font
/*########################################################################################################################* /*########################################################################################################################*
*---------------------------------------------------InputValidator----------------------------------------------------* *-----------------------------------------------------MenuInputDesc-------------------------------------------------------*
*#########################################################################################################################*/ *#########################################################################################################################*/
static void Hex_Range(struct InputValidator* v, String* range) { static void Hex_Range(struct MenuInputDesc* d, String* range) {
String_AppendConst(range, "&7(#000000 - #FFFFFF)"); String_AppendConst(range, "&7(#000000 - #FFFFFF)");
} }
static bool Hex_ValidChar(struct InputValidator* v, char c) { static bool Hex_ValidChar(struct MenuInputDesc* d, char c) {
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f'); return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'F') || (c >= 'a' && c <= 'f');
} }
static bool Hex_ValidString(struct InputValidator* v, const String* s) { static bool Hex_ValidString(struct MenuInputDesc* d, const String* s) {
return s->length <= 6; return s->length <= 6;
} }
static bool Hex_ValidValue(struct InputValidator* v, const String* s) { static bool Hex_ValidValue(struct MenuInputDesc* d, const String* s) {
PackedCol col; PackedCol col;
return PackedCol_TryParseHex(s, &col); return PackedCol_TryParseHex(s, &col);
} }
struct InputValidatorVTABLE HexValidator_VTABLE = { static void Hex_Default(struct MenuInputDesc* d, String* value) {
Hex_Range, Hex_ValidChar, Hex_ValidString, Hex_ValidValue, PackedCol_ToHex(value, d->meta.h.Default);
};
static void Int_Range(struct InputValidator* v, String* range) {
String_Format2(range, "&7(%i - %i)", &v->Meta.i.Min, &v->Meta.i.Max);
} }
static bool Int_ValidChar(struct InputValidator* v, char c) { struct MenuInputVTABLE HexValidator_VTABLE = {
Hex_Range, Hex_ValidChar, Hex_ValidString, Hex_ValidValue, Hex_Default
};
static void Int_Range(struct MenuInputDesc* d, String* range) {
String_Format2(range, "&7(%i - %i)", &d->meta.i.Min, &d->meta.i.Max);
}
static bool Int_ValidChar(struct MenuInputDesc* d, char c) {
return (c >= '0' && c <= '9') || c == '-'; return (c >= '0' && c <= '9') || c == '-';
} }
static bool Int_ValidString(struct InputValidator* v, const String* s) { static bool Int_ValidString(struct MenuInputDesc* d, const String* s) {
int value; int value;
if (s->length == 1 && s->buffer[0] == '-') return true; /* input is just a minus sign */ if (s->length == 1 && s->buffer[0] == '-') return true; /* input is just a minus sign */
return Convert_ParseInt(s, &value); return Convert_ParseInt(s, &value);
} }
static bool Int_ValidValue(struct InputValidator* v, const String* s) { static bool Int_ValidValue(struct MenuInputDesc* d, const String* s) {
int value, min = v->Meta.i.Min, max = v->Meta.i.Max; int value, min = d->meta.i.Min, max = d->meta.i.Max;
return Convert_ParseInt(s, &value) && min <= value && value <= max; return Convert_ParseInt(s, &value) && min <= value && value <= max;
} }
struct InputValidatorVTABLE IntValidator_VTABLE = { static void Int_Default(struct MenuInputDesc* d, String* value) {
Int_Range, Int_ValidChar, Int_ValidString, Int_ValidValue, String_AppendInt(value, d->meta.i.Default);
}
struct MenuInputVTABLE IntValidator_VTABLE = {
Int_Range, Int_ValidChar, Int_ValidString, Int_ValidValue, Int_Default
}; };
static void Seed_Range(struct InputValidator* v, String* range) { static void Seed_Range(struct MenuInputDesc* d, String* range) {
String_AppendConst(range, "&7(an integer)"); String_AppendConst(range, "&7(an integer)");
} }
static void Seed_NoDefault(struct MenuInputDesc* d, String* value) { }
struct InputValidatorVTABLE SeedValidator_VTABLE = { struct MenuInputVTABLE SeedValidator_VTABLE = {
Seed_Range, Int_ValidChar, Int_ValidString, Int_ValidValue, Seed_Range, Int_ValidChar, Int_ValidString, Int_ValidValue, Seed_NoDefault
}; };
static void Float_Range(struct InputValidator* v, String* range) { static void Float_Range(struct MenuInputDesc* d, String* range) {
String_Format2(range, "&7(%f2 - %f2)", &v->Meta.f.Min, &v->Meta.f.Max); String_Format2(range, "&7(%f2 - %f2)", &d->meta.f.Min, &d->meta.f.Max);
} }
static bool Float_ValidChar(struct InputValidator* v, char c) { static bool Float_ValidChar(struct MenuInputDesc* d, char c) {
return (c >= '0' && c <= '9') || c == '-' || c == '.' || c == ','; return (c >= '0' && c <= '9') || c == '-' || c == '.' || c == ',';
} }
static bool Float_ValidString(struct InputValidator* v, const String* s) { static bool Float_ValidString(struct MenuInputDesc* d, const String* s) {
float value; float value;
if (s->length == 1 && Float_ValidChar(v, s->buffer[0])) return true; if (s->length == 1 && Float_ValidChar(d, s->buffer[0])) return true;
return Convert_ParseFloat(s, &value); return Convert_ParseFloat(s, &value);
} }
static bool Float_ValidValue(struct InputValidator* v, const String* s) { static bool Float_ValidValue(struct MenuInputDesc* d, const String* s) {
float value, min = v->Meta.f.Min, max = v->Meta.f.Max; float value, min = d->meta.f.Min, max = d->meta.f.Max;
return Convert_ParseFloat(s, &value) && min <= value && value <= max; return Convert_ParseFloat(s, &value) && min <= value && value <= max;
} }
struct InputValidatorVTABLE FloatValidator_VTABLE = { static void Float_Default(struct MenuInputDesc* d, String* value) {
Float_Range, Float_ValidChar, Float_ValidString, Float_ValidValue, String_AppendFloat(value, d->meta.f.Default, 3);
}
struct MenuInputVTABLE FloatValidator_VTABLE = {
Float_Range, Float_ValidChar, Float_ValidString, Float_ValidValue, Float_Default
}; };
static void Path_Range(struct InputValidator* v, String* range) { static void Path_Range(struct MenuInputDesc* d, String* range) {
String_AppendConst(range, "&7(Enter name)"); String_AppendConst(range, "&7(Enter name)");
} }
static bool Path_ValidChar(struct InputValidator* v, char c) { static bool Path_ValidChar(struct MenuInputDesc* d, char c) {
return !(c == '/' || c == '\\' || c == '?' || c == '*' || c == ':' return !(c == '/' || c == '\\' || c == '?' || c == '*' || c == ':'
|| c == '<' || c == '>' || c == '|' || c == '"' || c == '.'); || c == '<' || c == '>' || c == '|' || c == '"' || c == '.');
} }
static bool Path_ValidString(struct InputValidator* v, const String* s) { return true; } static bool Path_ValidString(struct MenuInputDesc* d, const String* s) { return true; }
struct InputValidatorVTABLE PathValidator_VTABLE = { struct MenuInputVTABLE PathValidator_VTABLE = {
Path_Range, Path_ValidChar, Path_ValidString, Path_ValidString, Path_Range, Path_ValidChar, Path_ValidString, Path_ValidString, Seed_NoDefault
}; };
static void String_Range(struct InputValidator* v, String* range) { static void String_Range(struct MenuInputDesc* d, String* range) {
String_AppendConst(range, "&7(Enter text)"); String_AppendConst(range, "&7(Enter text)");
} }
static bool String_ValidChar(struct InputValidator* v, char c) { static bool String_ValidChar(struct MenuInputDesc* d, char c) {
return c != '&'; return c != '&';
} }
static bool String_ValidString(struct InputValidator* v, const String* s) { static bool String_ValidString(struct MenuInputDesc* d, const String* s) {
return s->length <= STRING_SIZE; return s->length <= STRING_SIZE;
} }
struct InputValidatorVTABLE StringValidator_VTABLE = { struct MenuInputVTABLE StringValidator_VTABLE = {
String_Range, String_ValidChar, String_ValidString, String_ValidString, String_Range, String_ValidChar, String_ValidString, String_ValidString, Seed_NoDefault
}; };
@ -1421,7 +1434,7 @@ static void MenuInputWidget_Render(void* widget, double delta) {
static void MenuInputWidget_RemakeTexture(void* widget) { static void MenuInputWidget_RemakeTexture(void* widget) {
String range; char rangeBuffer[STRING_SIZE]; String range; char rangeBuffer[STRING_SIZE];
struct MenuInputWidget* w = (struct MenuInputWidget*)widget; struct MenuInputWidget* w = (struct MenuInputWidget*)widget;
struct InputValidator* v; struct MenuInputDesc* desc;
struct DrawTextArgs args; struct DrawTextArgs args;
struct Texture* tex; struct Texture* tex;
Size2D size, adjSize; Size2D size, adjSize;
@ -1435,8 +1448,8 @@ static void MenuInputWidget_RemakeTexture(void* widget) {
w->base.caretAccumulator = 0.0; w->base.caretAccumulator = 0.0;
String_InitArray(range, rangeBuffer); String_InitArray(range, rangeBuffer);
v = &w->validator; desc = &w->desc;
v->VTABLE->GetRange(v, &range); desc->VTABLE->GetRange(desc, &range);
w->base.width = max(size.Width, w->minWidth); w->base.width = max(size.Width, w->minWidth);
w->base.height = max(size.Height, w->minHeight); w->base.height = max(size.Height, w->minHeight);
@ -1467,20 +1480,20 @@ static void MenuInputWidget_RemakeTexture(void* widget) {
static bool MenuInputWidget_AllowedChar(void* widget, char c) { static bool MenuInputWidget_AllowedChar(void* widget, char c) {
struct InputWidget* w = (struct InputWidget*)widget; struct InputWidget* w = (struct InputWidget*)widget;
struct InputValidator* v; struct MenuInputDesc* desc;
int maxChars; int maxChars;
bool valid; bool valid;
if (c == '&') return false; if (c == '&') return false;
v = &((struct MenuInputWidget*)w)->validator; desc = &((struct MenuInputWidget*)w)->desc;
if (!v->VTABLE->IsValidChar(v, c)) return false; if (!desc->VTABLE->IsValidChar(desc, c)) return false;
maxChars = w->GetMaxLines() * INPUTWIDGET_LEN; maxChars = w->GetMaxLines() * INPUTWIDGET_LEN;
if (w->text.length == maxChars) return false; if (w->text.length == maxChars) return false;
/* See if the new string is in valid format */ /* See if the new string is in valid format */
InputWidget_AppendChar(w, c); InputWidget_AppendChar(w, c);
valid = v->VTABLE->IsValidString(v, &w->text); valid = desc->VTABLE->IsValidString(desc, &w->text);
InputWidget_DeleteChar(w); InputWidget_DeleteChar(w);
return valid; return valid;
} }
@ -1492,13 +1505,13 @@ static struct WidgetVTABLE MenuInputWidget_VTABLE = {
InputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll, InputWidget_MouseDown, Widget_Mouse, Widget_MouseMove, Widget_MouseScroll,
InputWidget_Reposition, InputWidget_Reposition,
}; };
void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, const String* text, FontDesc* font, struct InputValidator* validator) { void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, const String* text, FontDesc* font, struct MenuInputDesc* desc) {
InputWidget_Create(&w->base, font, &String_Empty); InputWidget_Create(&w->base, font, &String_Empty);
w->base.VTABLE = &MenuInputWidget_VTABLE; w->base.VTABLE = &MenuInputWidget_VTABLE;
w->minWidth = width; w->minWidth = width;
w->minHeight = height; w->minHeight = height;
w->validator = *validator; w->desc = *desc;
w->base.convertPercents = false; w->base.convertPercents = false;
w->base.padding = 3; w->base.padding = 3;

View File

@ -128,50 +128,53 @@ CC_NOINLINE void InputWidget_AppendString(struct InputWidget* w, const String* t
CC_NOINLINE void InputWidget_Append(struct InputWidget* w, char c); CC_NOINLINE void InputWidget_Append(struct InputWidget* w, char c);
struct InputValidator; struct MenuInputDesc;
struct InputValidatorVTABLE { struct MenuInputVTABLE {
/* Returns a description of the range of valid values (e.g. "0 - 100") */ /* Returns a description of the range of valid values (e.g. "0 - 100") */
void (*GetRange)(struct InputValidator* v, String* range); void (*GetRange)(struct MenuInputDesc* d, String* range);
/* Whether the given character is acceptable for this input */ /* Whether the given character is acceptable for this input */
bool (*IsValidChar)(struct InputValidator* v, char c); bool (*IsValidChar)(struct MenuInputDesc* d, char c);
/* Whether the characters of the given string are acceptable for this input */ /* Whether the characters of the given string are acceptable for this input */
/* e.g. for an integer, '-' is only valid for the first character */ /* e.g. for an integer, '-' is only valid for the first character */
bool (*IsValidString)(struct InputValidator* v, const String* s); bool (*IsValidString)(struct MenuInputDesc* d, const String* s);
/* Whether the characters of the given string produce a valid value */ /* Whether the characters of the given string produce a valid value */
bool (*IsValidValue)(struct InputValidator* v, const String* s); bool (*IsValidValue)(struct MenuInputDesc* d, const String* s);
/* Gets the default value for this input. */
void (*GetDefault)(struct MenuInputDesc* d, String* value);
}; };
struct InputValidator { struct MenuInputDesc {
struct InputValidatorVTABLE* VTABLE; struct MenuInputVTABLE* VTABLE;
union { union {
struct { const char** Names; int Count; } e; struct { const char** Names; int Count; } e;
struct { int Min, Max; } i; struct { int Min, Max, Default; } i;
struct { float Min, Max; } f; struct { float Min, Max, Default; } f;
} Meta; struct { PackedCol Default; } h;
} meta;
}; };
extern struct InputValidatorVTABLE HexValidator_VTABLE; extern struct MenuInputVTABLE HexValidator_VTABLE;
extern struct InputValidatorVTABLE IntValidator_VTABLE; extern struct MenuInputVTABLE IntValidator_VTABLE;
extern struct InputValidatorVTABLE SeedValidator_VTABLE; extern struct MenuInputVTABLE SeedValidator_VTABLE;
extern struct InputValidatorVTABLE FloatValidator_VTABLE; extern struct MenuInputVTABLE FloatValidator_VTABLE;
extern struct InputValidatorVTABLE PathValidator_VTABLE; extern struct MenuInputVTABLE PathValidator_VTABLE;
extern struct InputValidatorVTABLE StringValidator_VTABLE; extern struct MenuInputVTABLE StringValidator_VTABLE;
#define InputValidator_Hex(v) v.VTABLE = &HexValidator_VTABLE; #define MenuInput_Hex(v, def) v.VTABLE = &HexValidator_VTABLE; v.meta.h.Default = def;
#define InputValidator_Int(v, lo, hi) v.VTABLE = &IntValidator_VTABLE; v.Meta.i.Min = lo; v.Meta.i.Max = hi; #define MenuInput_Int(v, lo, hi, def) v.VTABLE = &IntValidator_VTABLE; v.meta.i.Min = lo; v.meta.i.Max = hi; v.meta.i.Default = def;
#define InputValidator_Seed(v) v.VTABLE = &SeedValidator_VTABLE; v.Meta.i.Min = Int32_MinValue; v.Meta.i.Max = Int32_MaxValue; #define MenuInput_Seed(v) v.VTABLE = &SeedValidator_VTABLE; v.meta.i.Min = Int32_MinValue; v.meta.i.Max = Int32_MaxValue;
#define InputValidator_Float(v, lo, hi) v.VTABLE = &FloatValidator_VTABLE; v.Meta.f.Min = lo; v.Meta.f.Max = hi; #define MenuInput_Float(v, lo, hi, def) v.VTABLE = &FloatValidator_VTABLE; v.meta.f.Min = lo; v.meta.f.Max = hi; v.meta.f.Default = def;
#define InputValidator_Path(v) v.VTABLE = &PathValidator_VTABLE; #define MenuInput_Path(v) v.VTABLE = &PathValidator_VTABLE;
#define InputValidator_Enum(v, names, count) v.VTABLE = NULL; v.Meta.e.Names = names; v.Meta.e.Count = count; #define MenuInput_Enum(v, names, count) v.VTABLE = NULL; v.meta.e.Names = names; v.meta.e.Count = count;
#define InputValidator_String(v) v.VTABLE = &StringValidator_VTABLE; #define MenuInput_String(v) v.VTABLE = &StringValidator_VTABLE;
struct MenuInputWidget { struct MenuInputWidget {
struct InputWidget base; struct InputWidget base;
int minWidth, minHeight; int minWidth, minHeight;
struct InputValidator validator; struct MenuInputDesc desc;
char _textBuffer[INPUTWIDGET_LEN]; char _textBuffer[INPUTWIDGET_LEN];
}; };
CC_NOINLINE void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, const String* text, FontDesc* font, struct InputValidator* v); CC_NOINLINE void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, const String* text, FontDesc* font, struct MenuInputDesc* d);
struct ChatInputWidget { struct ChatInputWidget {

View File

@ -117,12 +117,6 @@ extern const char* Weather_Names[3];
extern const PackedCol Env_DefaultSkyCol, Env_DefaultFogCol, Env_DefaultCloudsCol, Env_DefaultSkyboxCol; extern const PackedCol Env_DefaultSkyCol, Env_DefaultFogCol, Env_DefaultCloudsCol, Env_DefaultSkyboxCol;
extern const PackedCol Env_DefaultSunCol, Env_DefaultShadowCol; extern const PackedCol Env_DefaultSunCol, Env_DefaultShadowCol;
#define ENV_DEFAULT_SKYCOL_HEX "99CCFF"
#define ENV_DEFAULT_FOGCOL_HEX "FFFFFF"
#define ENV_DEFAULT_CLOUDSCOL_HEX "FFFFFF"
#define ENV_DEFAULT_SUNCOL_HEX "FFFFFF"
#define ENV_DEFAULT_SHADOWCOL_HEX "9B9B9B"
/* If url is empty, extracts default texture pack. */ /* If url is empty, extracts default texture pack. */
/* Else tries extracting cached texture pack for the given URL, */ /* Else tries extracting cached texture pack for the given URL, */
/* then asynchronously downloads the texture pack from the given URL. */ /* then asynchronously downloads the texture pack from the given URL. */