mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-17 03:25:14 -04:00
Bunch of fixes for C code
This commit is contained in:
parent
783b4e0360
commit
d88f896998
@ -9,13 +9,11 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
public sealed class EditHotkeyScreen : MenuScreen {
|
||||
|
||||
const int keyI = 0, modifyI = 1, actionI = 2;
|
||||
HotkeyList hotkeys;
|
||||
Hotkey curHotkey, origHotkey;
|
||||
int selectedI = -1;
|
||||
static FastColour grey = new FastColour(150, 150, 150);
|
||||
|
||||
public EditHotkeyScreen(Game game, Hotkey original) : base(game) {
|
||||
hotkeys = game.Input.Hotkeys;
|
||||
origHotkey = original;
|
||||
curHotkey = original;
|
||||
}
|
||||
@ -97,15 +95,15 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
void SaveChangesClick(Game game, Widget widget) {
|
||||
if (origHotkey.BaseKey != Key.Unknown) {
|
||||
hotkeys.RemoveHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
hotkeys.UserRemovedHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
HotkeyList.Remove(origHotkey.BaseKey, origHotkey.Flags);
|
||||
HotkeyList.UserRemovedHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
}
|
||||
MenuInputWidget input = (MenuInputWidget)widgets[actionI];
|
||||
|
||||
if (curHotkey.BaseKey != Key.Unknown) {
|
||||
hotkeys.AddHotkey(curHotkey.BaseKey, curHotkey.Flags,
|
||||
HotkeyList.Add(curHotkey.BaseKey, curHotkey.Flags,
|
||||
input.Text.ToString(), curHotkey.StaysOpen);
|
||||
hotkeys.UserAddedHotkey(curHotkey.BaseKey, curHotkey.Flags,
|
||||
HotkeyList.UserAddedHotkey(curHotkey.BaseKey, curHotkey.Flags,
|
||||
curHotkey.StaysOpen, input.Text.ToString());
|
||||
}
|
||||
game.Gui.SetNewScreen(new HotkeyListScreen(game));
|
||||
@ -113,8 +111,8 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
void RemoveHotkeyClick(Game game, Widget widget) {
|
||||
if (origHotkey.BaseKey != Key.Unknown) {
|
||||
hotkeys.RemoveHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
hotkeys.UserRemovedHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
HotkeyList.Remove(origHotkey.BaseKey, origHotkey.Flags);
|
||||
HotkeyList.UserRemovedHotkey(origHotkey.BaseKey, origHotkey.Flags);
|
||||
}
|
||||
game.Gui.SetNewScreen(new HotkeyListScreen(game));
|
||||
}
|
||||
|
@ -12,12 +12,11 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
|
||||
public HotkeyListScreen(Game game) : base(game) {
|
||||
titleText = "Modify hotkeys";
|
||||
HotkeyList hotkeys = game.Input.Hotkeys;
|
||||
int count = hotkeys.Hotkeys.Count;
|
||||
entries = new string[hotkeys.Hotkeys.Count + items];
|
||||
int count = HotkeyList.Hotkeys.Count;
|
||||
entries = new string[count + items];
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Hotkey hKey = hotkeys.Hotkeys[i];
|
||||
Hotkey hKey = HotkeyList.Hotkeys[i];
|
||||
entries[i] = hKey.BaseKey + " |" + MakeFlagsString(hKey.Flags);
|
||||
}
|
||||
for (int i = 0; i < items; i++)
|
||||
@ -49,12 +48,10 @@ namespace ClassicalSharp.Gui.Screens {
|
||||
if (value.Contains("Shift")) flags |= 2;
|
||||
if (value.Contains("Alt")) flags |= 4;
|
||||
|
||||
Key hKey = (Key)Enum.Parse(typeof(Key), key);
|
||||
HotkeyList hotkeys = game.Input.Hotkeys;
|
||||
|
||||
for (int i = 0; i < hotkeys.Hotkeys.Count; i++) {
|
||||
Hotkey h = hotkeys.Hotkeys[i];
|
||||
if (h.BaseKey == hKey && h.Flags == flags) return h;
|
||||
Key baseKey = (Key)Enum.Parse(typeof(Key), key);
|
||||
for (int i = 0; i < HotkeyList.Hotkeys.Count; i++) {
|
||||
Hotkey h = HotkeyList.Hotkeys[i];
|
||||
if (h.BaseKey == baseKey && h.Flags == flags) return h;
|
||||
}
|
||||
return default(Hotkey);
|
||||
}
|
||||
|
@ -11,10 +11,6 @@ namespace ClassicalSharp {
|
||||
|
||||
public sealed class InputHandler {
|
||||
|
||||
#if !ANDROID
|
||||
public HotkeyList Hotkeys;
|
||||
#endif
|
||||
|
||||
Game game;
|
||||
bool[] buttonsDown = new bool[3];
|
||||
PickingHandler picking;
|
||||
@ -23,11 +19,7 @@ namespace ClassicalSharp {
|
||||
RegisterInputHandlers();
|
||||
Keys = new KeyMap();
|
||||
picking = new PickingHandler(game, this);
|
||||
|
||||
#if !ANDROID
|
||||
Hotkeys = new HotkeyList();
|
||||
Hotkeys.LoadSavedHotkeys();
|
||||
#endif
|
||||
HotkeyList.LoadSavedHotkeys();
|
||||
}
|
||||
|
||||
void RegisterInputHandlers() {
|
||||
@ -185,7 +177,7 @@ namespace ClassicalSharp {
|
||||
void HandleHotkey(Key key) {
|
||||
string text;
|
||||
bool more;
|
||||
if (!Hotkeys.IsHotkey(key, game.Input, out text, out more)) return;
|
||||
if (!HotkeyList.IsHotkey(key, game.Input, out text, out more)) return;
|
||||
|
||||
if (!more) {
|
||||
game.Server.SendChat(text);
|
||||
|
@ -7,12 +7,12 @@ using OpenTK.Input;
|
||||
namespace ClassicalSharp.Hotkeys {
|
||||
|
||||
/// <summary> Maintains the list of hotkeys defined by the client and by SetTextHotkey packets. </summary>
|
||||
public sealed class HotkeyList {
|
||||
public static class HotkeyList {
|
||||
|
||||
public List<Hotkey> Hotkeys = new List<Hotkey>();
|
||||
public static List<Hotkey> Hotkeys = new List<Hotkey>();
|
||||
|
||||
/// <summary> Creates or updates an existing hotkey with the given baseKey and modifier flags. </summary>
|
||||
public void AddHotkey(Key baseKey, byte flags, string text, bool more) {
|
||||
public static void Add(Key baseKey, byte flags, string text, bool more) {
|
||||
if (!UpdateExistingHotkey(baseKey, flags, text, more))
|
||||
AddNewHotkey(baseKey, flags, text, more);
|
||||
}
|
||||
@ -20,7 +20,7 @@ namespace ClassicalSharp.Hotkeys {
|
||||
/// <summary> Removes an existing hotkey with the given baseKey and modifier flags. </summary>
|
||||
/// <returns> Whether a hotkey with the given baseKey and modifier flags was found
|
||||
/// and subsequently removed. </returns>
|
||||
public bool RemoveHotkey(Key baseKey, byte flags) {
|
||||
public static bool Remove(Key baseKey, byte flags) {
|
||||
for (int i = 0; i < Hotkeys.Count; i++) {
|
||||
Hotkey hKey = Hotkeys[i];
|
||||
if (hKey.BaseKey == baseKey && hKey.Flags == flags) {
|
||||
@ -31,7 +31,7 @@ namespace ClassicalSharp.Hotkeys {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool UpdateExistingHotkey(Key baseKey, byte flags, string text, bool more) {
|
||||
static bool UpdateExistingHotkey(Key baseKey, byte flags, string text, bool more) {
|
||||
for (int i = 0; i < Hotkeys.Count; i++) {
|
||||
Hotkey hKey = Hotkeys[i];
|
||||
if (hKey.BaseKey == baseKey && hKey.Flags == flags) {
|
||||
@ -44,7 +44,7 @@ namespace ClassicalSharp.Hotkeys {
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddNewHotkey(Key baseKey, byte flags, string text, bool more) {
|
||||
static void AddNewHotkey(Key baseKey, byte flags, string text, bool more) {
|
||||
Hotkey hotkey;
|
||||
hotkey.BaseKey = baseKey;
|
||||
hotkey.Flags = flags;
|
||||
@ -60,8 +60,7 @@ namespace ClassicalSharp.Hotkeys {
|
||||
|
||||
/// <summary> Determines whether a hotkey is active based on the given key,
|
||||
/// and the currently active control, alt, and shift modifiers </summary>
|
||||
public bool IsHotkey(Key key, InputHandler input,
|
||||
out string text, out bool moreInput) {
|
||||
public static bool IsHotkey(Key key, InputHandler input, out string text, out bool moreInput) {
|
||||
byte flags = 0;
|
||||
if (input.ControlDown) flags |= 1;
|
||||
if (input.ShiftDown) flags |= 2;
|
||||
@ -82,7 +81,7 @@ namespace ClassicalSharp.Hotkeys {
|
||||
}
|
||||
|
||||
const string prefix = "hotkey-";
|
||||
public void LoadSavedHotkeys() {
|
||||
public static void LoadSavedHotkeys() {
|
||||
for (int i = 0; i < Options.OptionsKeys.Count; i++) {
|
||||
string key = Options.OptionsKeys[i];
|
||||
if (!Utils.CaselessStarts(key, prefix)) continue;
|
||||
@ -108,16 +107,16 @@ namespace ClassicalSharp.Hotkeys {
|
||||
Utils.LogDebug("Hotkey {0} has invalid arguments", key);
|
||||
continue;
|
||||
}
|
||||
AddHotkey(hotkey, flags, strText, moreInput);
|
||||
Add(hotkey, flags, strText, moreInput);
|
||||
}
|
||||
}
|
||||
|
||||
public void UserRemovedHotkey(Key baseKey, byte flags) {
|
||||
public static void UserRemovedHotkey(Key baseKey, byte flags) {
|
||||
string key = "hotkey-" + baseKey + "&" + flags;
|
||||
Options.Set(key, null);
|
||||
}
|
||||
|
||||
public void UserAddedHotkey(Key baseKey, byte flags, bool moreInput, string text) {
|
||||
public static void UserAddedHotkey(Key baseKey, byte flags, bool moreInput, string text) {
|
||||
string key = "hotkey-" + baseKey + "&" + flags;
|
||||
string value = moreInput + "&" + text;
|
||||
Options.Set(key, value);
|
||||
|
@ -22,7 +22,6 @@ namespace ClassicalSharp.Map {
|
||||
End, Int8, Int16, Int32, Int64,
|
||||
Real32, Real64, Int8Array, String,
|
||||
List, Compound, Int32Array,
|
||||
Invalid = 255,
|
||||
}
|
||||
|
||||
public sealed class NbtFile {
|
||||
@ -82,9 +81,7 @@ namespace ClassicalSharp.Map {
|
||||
|
||||
public unsafe NbtTag ReadTag(byte typeId, bool readTagName) {
|
||||
NbtTag tag = default(NbtTag);
|
||||
if (typeId == 0) {
|
||||
tag.TagId = NbtTagType.Invalid; return tag;
|
||||
}
|
||||
if (typeId == 0) return tag;
|
||||
|
||||
tag.Name = readTagName ? ReadString() : null;
|
||||
tag.TagId = (NbtTagType)typeId;
|
||||
@ -118,10 +115,10 @@ namespace ClassicalSharp.Map {
|
||||
tag.Value = list; break;
|
||||
|
||||
case NbtTagType.Compound:
|
||||
byte childTagId;
|
||||
Dictionary<string, NbtTag> children = new Dictionary<string, NbtTag>();
|
||||
NbtTag child;
|
||||
while ((child = ReadTag(reader.ReadByte(), true)).TagId != NbtTagType.Invalid) {
|
||||
children[child.Name] = child;
|
||||
while ((childTagId = reader.ReadByte()) != (byte)NbtTagType.End) {
|
||||
NbtTag child = ReadTag(childTagId, true); children[child.Name] = child;
|
||||
}
|
||||
tag.Value = children; break;
|
||||
|
||||
|
@ -105,12 +105,12 @@ namespace ClassicalSharp.Network.Protocols {
|
||||
|
||||
Utils.LogDebug("CPE Hotkey added: " + key + "," + keyMods + " : " + action);
|
||||
if (action == "") {
|
||||
game.Input.Hotkeys.RemoveHotkey(key, keyMods);
|
||||
HotkeyList.Remove(key, keyMods);
|
||||
} else if (action[action.Length - 1] == '◙') { // graphical form of \n
|
||||
action = action.Substring(0, action.Length - 1);
|
||||
game.Input.Hotkeys.AddHotkey(key, keyMods, action, false);
|
||||
HotkeyList.Add(key, keyMods, action, false);
|
||||
} else { // more input needed by user
|
||||
game.Input.Hotkeys.AddHotkey(key, keyMods, action, true);
|
||||
HotkeyList.Add(key, keyMods, action, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void Chat_SetLogName(STRING_PURE String* name) {
|
||||
String noColsName = String_InitAndClearArray(noColsBuffer);
|
||||
String_AppendColorless(&noColsName, name);
|
||||
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
for (i = 0; i < noColsName.length; i++) {
|
||||
if (Chat_AllowedLogChar(noColsName.buffer[i])) {
|
||||
String_Append(&Chat_LogName, noColsName.buffer[i]);
|
||||
@ -59,7 +59,7 @@ void Chat_OpenLog(DateTime* now) {
|
||||
}
|
||||
|
||||
/* Ensure multiple instances do not end up overwriting each other's log entries. */
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
for (i = 0; i < 20; i++) {
|
||||
UInt8 pathBuffer[String_BufferSize(FILENAME_SIZE)];
|
||||
String path = String_InitAndClearArray(pathBuffer);
|
||||
@ -137,8 +137,8 @@ void Chat_AddOf(STRING_PURE String* text, Int32 msgType) {
|
||||
|
||||
|
||||
typedef struct ChatCommand_ {
|
||||
String Name;
|
||||
String Help[6];
|
||||
const UInt8* Name;
|
||||
const UInt8* Help[5];
|
||||
void (*Execute)(STRING_PURE String* args, UInt32 argsCount);
|
||||
bool SingleplayerOnly;
|
||||
} ChatCommand;
|
||||
@ -146,10 +146,8 @@ typedef void (*ChatCommandConstructor)(ChatCommand* cmd);
|
||||
|
||||
#define COMMANDS_PREFIX "/client"
|
||||
#define COMMANDS_PREFIX_SPACE "/client "
|
||||
#define Command_SetName(raw) String name = String_FromConst(raw); cmd->Name = name;
|
||||
#define Command_SetHelp(Num, raw) String help ## Num = String_FromConst(raw); cmd->Help[Num] = help ## Num;
|
||||
ChatCommand commands_list[8];
|
||||
UInt32 commands_count;
|
||||
Int32 commands_count;
|
||||
|
||||
bool Commands_IsCommandPrefix(STRING_PURE String* input) {
|
||||
if (input->length == 0) return false;
|
||||
@ -167,8 +165,7 @@ void Commands_Register(ChatCommandConstructor constructor) {
|
||||
ErrorHandler_Fail("Commands_Register - hit max client commands");
|
||||
}
|
||||
|
||||
ChatCommand command;
|
||||
Platform_MemSet(&command, 0, sizeof(ChatCommand));
|
||||
ChatCommand command = { 0 };
|
||||
constructor(&command);
|
||||
commands_list[commands_count++] = command;
|
||||
}
|
||||
@ -182,10 +179,11 @@ void Commands_Log(const UInt8* format, void* a1) {
|
||||
|
||||
ChatCommand* Commands_GetMatch(STRING_PURE String* cmdName) {
|
||||
ChatCommand* match = NULL;
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
for (i = 0; i < commands_count; i++) {
|
||||
ChatCommand* cmd = &commands_list[i];
|
||||
if (!String_CaselessStarts(&cmd->Name, cmdName)) continue;
|
||||
String name = String_FromReadonly(cmd->Name);
|
||||
if (!String_CaselessStarts(&name, cmdName)) continue;
|
||||
|
||||
if (match != NULL) {
|
||||
Commands_Log("&e/client: Multiple commands found that start with: \"&f%s&e\".", cmdName);
|
||||
@ -209,11 +207,11 @@ ChatCommand* Commands_GetMatch(STRING_PURE String* cmdName) {
|
||||
void Commands_PrintDefined(void) {
|
||||
UInt8 strBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String str = String_InitAndClearArray(strBuffer);
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
|
||||
for (i = 0; i < commands_count; i++) {
|
||||
ChatCommand* cmd = &commands_list[i];
|
||||
String name = cmd->Name;
|
||||
String name = String_FromReadonly(cmd->Name);
|
||||
|
||||
if ((str.length + name.length + 2) > str.capacity) {
|
||||
Chat_Add(&str);
|
||||
@ -265,24 +263,24 @@ void HelpCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
ChatCommand* cmd = Commands_GetMatch(&args[1]);
|
||||
if (cmd == NULL) return;
|
||||
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_Elems(cmd->Help); i++) {
|
||||
String* help = &cmd->Help[i];
|
||||
if (help->length == 0) continue;
|
||||
Chat_Add(help);
|
||||
if (cmd->Help[i] == NULL) continue;
|
||||
String help = String_FromReadonly(cmd->Help[i]);
|
||||
Chat_Add(&help);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HelpCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("Help");
|
||||
Command_SetHelp(0, "&a/client help [command name]");
|
||||
Command_SetHelp(1, "&eDisplays the help for the given command.");
|
||||
cmd->Name = "Help";
|
||||
cmd->Help[0] = "&a/client help [command name]";
|
||||
cmd->Help[1] = "&eDisplays the help for the given command.";
|
||||
cmd->Execute = HelpCommand_Execute;
|
||||
}
|
||||
|
||||
void GpuInfoCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
UInt32 i;
|
||||
Int32 i;
|
||||
for (i = 0; i < Array_Elems(Gfx_ApiInfo); i++) {
|
||||
if (Gfx_ApiInfo[i].length == 0) continue;
|
||||
UInt8 msgBuffer[String_BufferSize(STRING_SIZE)];
|
||||
@ -295,9 +293,9 @@ void GpuInfoCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void GpuInfoCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("GpuInfo");
|
||||
Command_SetHelp(0, "&a/client gpuinfo");
|
||||
Command_SetHelp(1, "&eDisplays information about your GPU.");
|
||||
cmd->Name = "GpuInfo";
|
||||
cmd->Help[0] = "&a/client gpuinfo";
|
||||
cmd->Help[1] = "&eDisplays information about your GPU.";
|
||||
cmd->Execute = GpuInfoCommand_Execute;
|
||||
}
|
||||
|
||||
@ -312,12 +310,12 @@ void RenderTypeCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void RenderTypeCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("RenderType");
|
||||
Command_SetHelp(0, "&a/client rendertype [normal/legacy/legacyfast]");
|
||||
Command_SetHelp(1, "&bnormal: &eDefault renderer, with all environmental effects enabled.");
|
||||
Command_SetHelp(2, "&blegacy: &eMay be slightly slower than normal, but produces the same environmental effects.");
|
||||
Command_SetHelp(3, "&blegacyfast: &eSacrifices clouds, fog and overhead sky for faster performance.");
|
||||
Command_SetHelp(4, "&bnormalfast: &eSacrifices clouds, fog and overhead sky for faster performance.");
|
||||
cmd->Name = "RenderType";
|
||||
cmd->Help[0] = "&a/client rendertype [normal/legacy/legacyfast]";
|
||||
cmd->Help[1] = "&bnormal: &eDefault renderer, with all environmental effects enabled.";
|
||||
cmd->Help[2] = "&blegacy: &eMay be slightly slower than normal, but produces the same environmental effects.";
|
||||
cmd->Help[3] = "&blegacyfast: &eSacrifices clouds, fog and overhead sky for faster performance.";
|
||||
cmd->Help[4] = "&bnormalfast: &eSacrifices clouds, fog and overhead sky for faster performance.";
|
||||
cmd->Execute = RenderTypeCommand_Execute;
|
||||
}
|
||||
|
||||
@ -338,9 +336,9 @@ void ResolutionCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void ResolutionCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("Resolution");
|
||||
Command_SetHelp(0, "&a/client resolution [width] [height]");
|
||||
Command_SetHelp(1, "&ePrecisely sets the size of the rendered window.");
|
||||
cmd->Name = "Resolution";
|
||||
cmd->Help[0] = "&a/client resolution [width] [height]";
|
||||
cmd->Help[1] = "&ePrecisely sets the size of the rendered window.";
|
||||
cmd->Execute = ResolutionCommand_Execute;
|
||||
}
|
||||
|
||||
@ -357,10 +355,10 @@ void ModelCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void ModelCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("Model");
|
||||
Command_SetHelp(0, "&a/client model [name]");
|
||||
Command_SetHelp(1, "&bnames: &echibi, chicken, creeper, human, pig, sheep");
|
||||
Command_SetHelp(2, "&e skeleton, spider, zombie, sitting, <numerical block id>")
|
||||
cmd->Name = "Model";
|
||||
cmd->Help[0] = "&a/client model [name]";
|
||||
cmd->Help[1] = "&bnames: &echibi, chicken, creeper, human, pig, sheep";
|
||||
cmd->Help[2] = "&e skeleton, spider, zombie, sitting, <numerical block id>";
|
||||
cmd->SingleplayerOnly = true;
|
||||
cmd->Execute = ModelCommand_Execute;
|
||||
}
|
||||
@ -456,12 +454,12 @@ void CuboidCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void CuboidCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("Cuboid");
|
||||
Command_SetHelp(0, "&a/client cuboid [block] [persist]");
|
||||
Command_SetHelp(1, "&eFills the 3D rectangle between two points with [block].");
|
||||
Command_SetHelp(2, "&eIf no block is given, uses your currently held block.");
|
||||
Command_SetHelp(3, "&e If persist is given and is \"yes\", then the command");
|
||||
Command_SetHelp(4, "&e will repeatedly cuboid, without needing to be typed in again.");
|
||||
cmd->Name = "Cuboid";
|
||||
cmd->Help[0] = "&a/client cuboid [block] [persist]";
|
||||
cmd->Help[1] = "&eFills the 3D rectangle between two points with [block].";
|
||||
cmd->Help[2] = "&eIf no block is given, uses your currently held block.";
|
||||
cmd->Help[3] = "&e If persist is given and is \"yes\", then the command";
|
||||
cmd->Help[4] = "&e will repeatedly cuboid, without needing to be typed in again.";
|
||||
cmd->SingleplayerOnly = true;
|
||||
cmd->Execute = CuboidCommand_Execute;
|
||||
}
|
||||
@ -484,9 +482,9 @@ void TeleportCommand_Execute(STRING_PURE String* args, UInt32 argsCount) {
|
||||
}
|
||||
|
||||
void TeleportCommand_Make(ChatCommand* cmd) {
|
||||
Command_SetName("TP");
|
||||
Command_SetHelp(0, "&a/client tp [x y z]");
|
||||
Command_SetHelp(1, "&eMoves you to the given coordinates.");
|
||||
cmd->Name = "TP";
|
||||
cmd->Help[0] = "&a/client tp [x y z]";
|
||||
cmd->Help[1] = "&eMoves you to the given coordinates.";
|
||||
cmd->SingleplayerOnly = true;
|
||||
cmd->Execute = TeleportCommand_Execute;
|
||||
}
|
||||
@ -503,7 +501,7 @@ void Chat_Send(STRING_PURE String* text) {
|
||||
}
|
||||
}
|
||||
|
||||
void Commands_Init(void) {
|
||||
void Chat_Init(void) {
|
||||
Commands_Register(GpuInfoCommand_Make);
|
||||
Commands_Register(HelpCommand_Make);
|
||||
Commands_Register(RenderTypeCommand_Make);
|
||||
@ -511,6 +509,9 @@ void Commands_Init(void) {
|
||||
Commands_Register(ModelCommand_Make);
|
||||
Commands_Register(CuboidCommand_Make);
|
||||
Commands_Register(TeleportCommand_Make);
|
||||
|
||||
StringsBuffer_Init(&Chat_Log);
|
||||
StringsBuffer_Init(&Chat_InputLog);
|
||||
}
|
||||
|
||||
void Chat_Reset(void) {
|
||||
@ -518,14 +519,17 @@ void Chat_Reset(void) {
|
||||
String_Clear(&Chat_LogName);
|
||||
}
|
||||
|
||||
void Commands_Free(void) {
|
||||
void Chat_Free(void) {
|
||||
commands_count = 0;
|
||||
|
||||
StringsBuffer_Free(&Chat_Log);
|
||||
StringsBuffer_Free(&Chat_InputLog);
|
||||
}
|
||||
|
||||
IGameComponent Chat_MakeGameComponent(void) {
|
||||
IGameComponent comp = IGameComponent_MakeEmpty();
|
||||
comp.Init = Commands_Init;
|
||||
comp.Init = Chat_Init;
|
||||
comp.Reset = Chat_Reset;
|
||||
comp.Free = Commands_Free;
|
||||
comp.Free = Chat_Free;
|
||||
return comp;
|
||||
}
|
@ -183,7 +183,6 @@ void Fcm_Load(Stream* stream) {
|
||||
#define NBT_TAG_LIST 9
|
||||
#define NBT_TAG_COMPOUND 10
|
||||
#define NBT_TAG_INT32_ARRAY 11
|
||||
#define NBT_TAG_INVALID 255
|
||||
|
||||
struct NbtTag_;
|
||||
typedef struct NbtTag_ {
|
||||
@ -243,11 +242,10 @@ UInt8 NbtTag_U8_At(NbtTag* tag, Int32 i) {
|
||||
}
|
||||
|
||||
void Nbt_ReadTag(UInt8 typeId, bool readTagName, Stream* stream, NbtTag* parent) {
|
||||
NbtTag tag;
|
||||
tag.TagID = NBT_TAG_INVALID;
|
||||
tag.NameBuffer[0] = NULL;
|
||||
if (typeId == 0) return tag;
|
||||
if (typeId == NBT_TAG_END) return;
|
||||
|
||||
NbtTag tag;
|
||||
tag.NameBuffer[0] = NULL;
|
||||
tag.Name = readTagName ? ReadString() : null;
|
||||
tag.TagID = typeId;
|
||||
tag.Parent = parent;
|
||||
@ -284,7 +282,7 @@ void Nbt_ReadTag(UInt8 typeId, bool readTagName, Stream* stream, NbtTag* parent)
|
||||
break;
|
||||
|
||||
case NBT_TAG_COMPOUND:
|
||||
while ((childTagId = Stream_ReadUInt8(stream)) != NBT_TAG_INVALID) {
|
||||
while ((childTagId = Stream_ReadUInt8(stream)) != NBT_TAG_END) {
|
||||
Nbt_ReadTag(childTagId, true, stream, &tag);
|
||||
}
|
||||
break;
|
||||
|
@ -272,7 +272,7 @@ void TextAtlas_AddInt(TextAtlas* atlas, Int32 value, VertexP3fT2fC4b** vertices)
|
||||
}
|
||||
|
||||
UInt8 digits[STRING_SIZE];
|
||||
Int32 i, count = String_MakeInt32(value, digits);
|
||||
Int32 i, count = String_MakeUInt32((UInt32)value, digits);
|
||||
for (i = count - 1; i >= 0; i--) {
|
||||
TextAtlas_Add(atlas, digits[i] - '0' , vertices);
|
||||
}
|
||||
|
@ -1463,15 +1463,15 @@ void HotkeyListScreen_EntryClick(GuiElement* screenElem, GuiElement* w) {
|
||||
String alt = String_FromConst("Alt");
|
||||
|
||||
UInt8 flags = 0;
|
||||
if (String_ContainsString(&text, &ctrl)) flags |= HOTKEYS_FLAG_CTRL;
|
||||
if (String_ContainsString(&text, &shift)) flags |= HOTKEYS_FLAG_SHIFT;
|
||||
if (String_ContainsString(&text, &alt)) flags |= HOTKEYS_FLAG_ALT;
|
||||
if (String_ContainsString(&value, &ctrl)) flags |= HOTKEYS_FLAG_CTRL;
|
||||
if (String_ContainsString(&value, &shift)) flags |= HOTKEYS_FLAG_SHIFT;
|
||||
if (String_ContainsString(&value, &alt)) flags |= HOTKEYS_FLAG_ALT;
|
||||
|
||||
Key hKey = Utils_ParseEnum(&key, Key_Unknown, Key_Names, Array_Elems(Key_Names));
|
||||
Key baseKey = Utils_ParseEnum(&key, Key_Unknown, Key_Names, Array_Elems(Key_Names));
|
||||
Int32 i;
|
||||
for (i = 0; i < HotkeysText.Count; i++) {
|
||||
HotkeyData h = HotkeysList[i];
|
||||
if (h.BaseKey == hKey && h.Flags == flags) { original = h; break; }
|
||||
if (h.BaseKey == baseKey && h.Flags == flags) { original = h; break; }
|
||||
}
|
||||
Gui_SetNewScreen(EditHotkeyScreen_MakeInstance(original));
|
||||
}
|
||||
@ -1857,6 +1857,97 @@ Screen* MouseKeyBindingsScreen_MakeInstance(void) {
|
||||
/*########################################################################################################################*
|
||||
*--------------------------------------------------MenuOptionsScreen------------------------------------------------------*
|
||||
*#########################################################################################################################*/
|
||||
MenuOptionsScreen MenuOptionsScreen_Instance;
|
||||
GuiElementVTABLE MenuOptionsScreen_VTABLE;
|
||||
void Menu_GetBool(bool v, STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, v ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
bool Menu_SetBool(STRING_PURE String* raw, const UInt8* key) {
|
||||
bool isOn = String_CaselessEqualsConst(raw, "ON");
|
||||
Options_SetBool(key, isOn); return isOn;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_GetFPS(STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, FpsLimit_Names[Game_FpsLimit]);
|
||||
}
|
||||
void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
|
||||
UInt32 method = Utils_ParseEnum(raw, FpsLimit_VSync, FpsLimit_Names, Array_Elems(FpsLimit_Names));
|
||||
Game_SetFpsLimitMethod(method);
|
||||
|
||||
String value = String_FromReadonly(FpsLimit_Names[method]);
|
||||
Options_Set(OPTION_FPS_LIMIT, &value);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Set(MenuOptionsScreen* screen, Int32 i, STRING_PURE String* text) {
|
||||
screen->Buttons[i].SetValue(text);
|
||||
/* need to get btn again here (e.g. changing FPS invalidates all widgets) */
|
||||
|
||||
UInt8 titleBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String title = String_InitAndClearArray(titleBuffer);
|
||||
String_AppendConst(&title, screen->Buttons[i].OptName);
|
||||
String_AppendConst(&title, ": ");
|
||||
screen->Buttons[i].GetValue(&title);
|
||||
ButtonWidget_SetText(&screen->Buttons[i], &title);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeExtHelp(MenuOptionsScreen* screen) {
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
Elem_Free(&screen->ExtHelp);
|
||||
screen->ExtHelp.LinesCount = 0;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_RepositionExtHelp(MenuOptionsScreen* screen) {
|
||||
screen->ExtHelp.XOffset = Game_Width / 2 - screen->ExtHelp.Width / 2;
|
||||
screen->ExtHelp.YOffset = Game_Height / 2 + 100;
|
||||
Widget_Reposition(&screen->ExtHelp);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_SelectExtHelp(MenuOptionsScreen* screen, Int32 idx) {
|
||||
MenuOptionsScreen_FreeExtHelp(screen);
|
||||
if (screen->Descriptions == NULL || screen->ActiveI >= 0) return;
|
||||
const UInt8* desc = screen->Descriptions[idx];
|
||||
if (desc == NULL) return;
|
||||
|
||||
String descRaw = String_FromReadonly(desc);
|
||||
String descLines[5];
|
||||
UInt32 descLinesCount = Array_Elems(descLines);
|
||||
String_UNSAFE_Split(&descRaw, '%', descLines, &descLinesCount);
|
||||
|
||||
TextGroupWidget_Create(&screen->ExtHelp, descLinesCount, &screen->TextFont, NULL, screen->ExtHelp_Textures, screen->ExtHelp_Buffer);
|
||||
Widget_SetLocation((Widget*)(&screen->ExtHelp), ANCHOR_MIN, ANCHOR_MIN, 0, 0);
|
||||
Elem_Init(&screen->ExtHelp);
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < descLinesCount; i++) {
|
||||
TextGroupWidget_SetText(&screen->ExtHelp, i, &descLines[i]);
|
||||
}
|
||||
MenuOptionsScreen_RepositionExtHelp(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeInput(MenuOptionsScreen* screen) {
|
||||
if (screen->ActiveI == -1) return;
|
||||
|
||||
Int32 i;
|
||||
for (i = screen->WidgetsCount - 3; i < screen->WidgetsCount; i++) {
|
||||
Elem_Free(screen->WidgetsPtr[i]);
|
||||
screen->WidgetsPtr[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_EnterInput(MenuOptionsScreen* screen) {
|
||||
String text = screen->Input.Base.Text;
|
||||
MenuInputValidator* validator = &screen->Input.Validator;
|
||||
|
||||
if (validator->IsValidValue(validator, &text)) {
|
||||
MenuOptionsScreen_Set(screen, screen->ActiveI, &text);
|
||||
}
|
||||
|
||||
MenuOptionsScreen_SelectExtHelp(screen, screen->ActiveI);
|
||||
screen->ActiveI = -1;
|
||||
MenuOptionsScreen_FreeInput(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Init(GuiElement* elem) {
|
||||
MenuScreen_Init(elem);
|
||||
Key_KeyRepeat = true;
|
||||
@ -1887,7 +1978,7 @@ void MenuOptionsScreen_OnResize(GuiElement* elem) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)elem;
|
||||
MenuScreen_OnResize(elem);
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
RepositionExtendedHelp();
|
||||
MenuOptionsScreen_RepositionExtHelp(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_ContextLost(void* obj) {
|
||||
@ -1908,7 +1999,7 @@ bool MenuOptionsScreen_HandlesKeyDown(GuiElement* elem, Key key) {
|
||||
if (screen->ActiveI >= 0) {
|
||||
if (Elem_HandlesKeyDown(&screen->Input.Base, key)) return true;
|
||||
if (key == Key_Enter || key == Key_KeypadEnter) {
|
||||
EnterInput(); return true;
|
||||
MenuOptionsScreen_EnterInput(screen); return true;
|
||||
}
|
||||
}
|
||||
return MenuScreen_HandlesKeyDown(elem, key);
|
||||
@ -1927,7 +2018,7 @@ bool MenuOptionsScreen_HandlesMouseMove(GuiElement* elem, Int32 x, Int32 y) {
|
||||
if (screen->Descriptions == NULL || i >= screen->DescriptionsCount) return true;
|
||||
|
||||
screen->SelectedI = i;
|
||||
if (screen->ActiveI == -1) SelectExtendedHelp(i);
|
||||
if (screen->ActiveI == -1) MenuOptionsScreen_SelectExtHelp(screen, i);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1940,83 +2031,31 @@ void MenuOptionsScreen_Make(MenuOptionsScreen* screen, Int32 i, Int32 dir, Int32
|
||||
|
||||
ButtonWidget* btn = &screen->Buttons[i];
|
||||
screen->WidgetsPtr[i] = (Widget*)btn;
|
||||
ButtonWidget_Create(btn, 300, &title, &screen->TitleFont, onClick);
|
||||
ButtonWidget_Create(btn, &title, 300, &screen->TitleFont, onClick);
|
||||
Widget_SetLocation((Widget*)btn, ANCHOR_CENTRE, ANCHOR_CENTRE, 160 * dir, y);
|
||||
|
||||
btn->OptName = optName;
|
||||
btn->GetValue = getter;
|
||||
btn->SetValue = setter;
|
||||
return btn;
|
||||
}
|
||||
|
||||
void Menu_GetBool(bool v, STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, v ? "ON" : "OFF");
|
||||
}
|
||||
bool Menu_SetBool(STRING_PURE String* raw, const UInt8* key) {
|
||||
bool isOn = String_CaselessEqualsConst(raw, "ON");
|
||||
Options_SetBool(key, isOn); return isOn;
|
||||
void MenuOptionsScreen_OK(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
MenuOptionsScreen_EnterInput(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_GetFPS(STRING_TRANSIENT String* raw) {
|
||||
String_AppendConst(raw, FpsLimit_Names[Game_FpsLimit]);
|
||||
}
|
||||
void MenuOptionsScreen_SetFPS(STRING_PURE String* raw) {
|
||||
UInt32 method = Utils_ParseEnum(raw, FpsLimit_VSync, FpsLimit_Names, Array_Elems(FpsLimit_Names));
|
||||
Game_SetFpsLimitMethod(method);
|
||||
Options_Set(OPTION_FPS_LIMIT, FpsLimit_Names[method]);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_SelectExtHelp(MenuOptionsScreen* screen, Int32 idx) {
|
||||
MenuOptionsScreen_FreeExtHelp(screen);
|
||||
if (screen->Descriptions == NULL || screen->ActiveI >= 0) return;
|
||||
const UInt8* desc = screen->Descriptions[idx];
|
||||
if (desc == NULL) return;
|
||||
|
||||
String descRaw = String_FromReadonly(desc);
|
||||
String descLines[5];
|
||||
UInt32 descLinesCount = Array_Elems(descLines);
|
||||
String_UNSAFE_Split(&descRaw, '%', &descLines, &descLinesCount);
|
||||
|
||||
TextGroupWidget_Create(&screen->ExtHelp, descLinesCount, &screen->TextFont, NULL, &screen->ExtHelp_Textures, &screen->ExtHelp_Buffer);
|
||||
Widget_SetLocation((Widget*)(&screen->ExtHelp), ANCHOR_MIN, ANCHOR_MIN, 0, 0);
|
||||
Elem_Init(&screen->ExtHelp);
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < descLinesCount; i++) {
|
||||
TextGroupWidget_SetText(&screen->ExtHelp, i, &descLines[i]);
|
||||
}
|
||||
MenuOptionsScreen_RepositionExtHelp(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_RepositionExtHelp(MenuOptionsScreen* screen) {
|
||||
screen->ExtHelp.XOffset = Game_Width / 2 - screen->ExtHelp.Width / 2;
|
||||
screen->ExtHelp.YOffset = Game_Height / 2 + 100;
|
||||
Widget_Reposition(&screen->ExtHelp);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeExtHelp(MenuOptionsScreen* screen) {
|
||||
if (screen->ExtHelp.LinesCount == 0) return;
|
||||
Elem_Free(&screen->ExtHelp);
|
||||
screen->ExtHelp.LinesCount = 0;
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Set(MenuOptionsScreen* screen, Int32 i, STRING_PURE String* text) {
|
||||
screen->Buttons[i].SetValue(text);
|
||||
/* need to get btn again here (e.g. changing FPS invalidates all widgets) */
|
||||
|
||||
UInt8 titleBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String title = String_InitAndClearArray(titleBuffer);
|
||||
String_AppendConst(&title, screen->Buttons[i].OptName);
|
||||
String_AppendConst(&title, ": ");
|
||||
screen->Buttons[i].GetValue(&title);
|
||||
ButtonWidget_SetText(&screen->Buttons[i], &title);
|
||||
void MenuOptionsScreen_Default(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
String text = String_FromReadonly(screen->DefaultValues[screen->ActiveI]);
|
||||
InputWidget_Clear(&screen->Input.Base);
|
||||
InputWidget_AppendString(&screen->Input.Base, &text);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_Bool(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
ButtonWidget* button = (ButtonWidget*)widget;
|
||||
Int32 index = MenuScreen_Index((MenuScreen*)screen, (Widget*)widget);
|
||||
SelectExtendedHelp(index);
|
||||
MenuOptionsScreen_SelectExtHelp(screen, index);
|
||||
|
||||
UInt8 valueBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String value = String_InitAndClearArray(valueBuffer);
|
||||
@ -2031,7 +2070,7 @@ void MenuOptionsScreen_Enum(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
ButtonWidget* button = (ButtonWidget*)widget;
|
||||
Int32 index = MenuScreen_Index((MenuScreen*)screen, (Widget*)widget);
|
||||
SelectExtendedHelp(index);
|
||||
MenuOptionsScreen_SelectExtHelp(screen, index);
|
||||
|
||||
MenuInputValidator* validator = &screen->Validators[index];
|
||||
const UInt8** names = (const UInt8**)validator->Meta_Ptr[0];
|
||||
@ -2059,15 +2098,15 @@ void MenuOptionsScreen_Input(GuiElement* screenElem, GuiElement* widget) {
|
||||
|
||||
MenuInputValidator* validator = &screen->Validators[screen->ActiveI];
|
||||
MenuInputWidget_Create(&screen->Input, 400, 30, &value, &screen->TextFont, validator);
|
||||
Widget_SettLocation((Widget*)(&screen->Input), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110);
|
||||
Widget_SetLocation((Widget*)(&screen->Input), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 110);
|
||||
screen->Input.Base.ShowCaret = true;
|
||||
|
||||
String okMsg = String_FromConst("OK");
|
||||
ButtonWidget_Create(&screen->OK, 40, &okMsg, &screen->TitleFont, MenuOptionsScreen_OK);
|
||||
ButtonWidget_Create(&screen->OK, &okMsg, 40, &screen->TitleFont, MenuOptionsScreen_OK);
|
||||
Widget_SetLocation((Widget*)(&screen->OK), ANCHOR_CENTRE, ANCHOR_CENTRE, 240, 110);
|
||||
|
||||
String defMsg = String_FromConst("Default value")
|
||||
ButtonWidget_Create(&screen->Default, 200, &defMsg, &screen->TitleFont, MenuOptionsScreen_Default);
|
||||
ButtonWidget_Create(&screen->Default, &defMsg, 200, &screen->TitleFont, MenuOptionsScreen_Default);
|
||||
Widget_SetLocation((Widget*)(&screen->Default), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 150);
|
||||
|
||||
Widget** widgets = screen->WidgetsPtr;
|
||||
@ -2076,37 +2115,27 @@ void MenuOptionsScreen_Input(GuiElement* screenElem, GuiElement* widget) {
|
||||
widgets[screen->WidgetsCount - 3] = (Widget*)(&screen->Default);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_OK(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
MenuOptionsScreen_EnterInput(screen);
|
||||
}
|
||||
MenuOptionsScreen* MenuOptionsScreen_MakeInstance(Widget** widgets, Int32 count, Menu_ContextRecreated contextRecreated, MenuInputValidator* validators,
|
||||
const UInt8** descriptions, const UInt8** defaultValues, ButtonWidget* buttons, Int32 descsCount) {
|
||||
MenuOptionsScreen* screen = &MenuOptionsScreen_Instance;
|
||||
Platform_MemSet(screen, 0, sizeof(MenuOptionsScreen));
|
||||
MenuScreen_MakeInstance((MenuScreen*)screen, widgets, count, contextRecreated);
|
||||
screen->VTABLE = &MenuOptionsScreen_VTABLE;
|
||||
|
||||
void MenuOptionsScreen_Default(GuiElement* screenElem, GuiElement* widget) {
|
||||
MenuOptionsScreen* screen = (MenuOptionsScreen*)screenElem;
|
||||
String text = String_FromReadonly(screen->DefaultValues[screen->ActiveI]);
|
||||
InputWidget_Clear(&screen->Input.Base);
|
||||
InputWidget_AppendString(&screen->Input.Base, &text);
|
||||
}
|
||||
screen->VTABLE->HandlesKeyDown = MenuOptionsScreen_HandlesKeyDown;
|
||||
screen->VTABLE->HandlesKeyUp = MenuOptionsScreen_HandlesKeyUp;
|
||||
screen->VTABLE->HandlesKeyPress = MenuOptionsScreen_HandlesKeyPress;
|
||||
screen->VTABLE->HandlesMouseMove = MenuOptionsScreen_HandlesMouseMove;
|
||||
|
||||
void MenuOptionsScreen_EnterInput(MenuOptionsScreen* screen) {
|
||||
String text = screen->Input.Base.Text;
|
||||
MenuInputValidator* validator = &screen->Input.Validator;
|
||||
screen->OnResize = MenuOptionsScreen_OnResize;
|
||||
screen->VTABLE->Init = MenuOptionsScreen_Init;
|
||||
screen->VTABLE->Render = MenuOptionsScreen_Render;
|
||||
screen->VTABLE->Free = MenuOptionsScreen_Free;
|
||||
|
||||
if (validator->IsValidValue(validator, &text)) {
|
||||
MenuOptionsScreen_Set(screen, screen->ActiveI, &text);
|
||||
}
|
||||
|
||||
MenuOptionsScreen_SelectExtHelp(screen, screen->ActiveI);
|
||||
screen->ActiveI = -1;
|
||||
MenuOptionsScreen_FreeInput(screen);
|
||||
}
|
||||
|
||||
void MenuOptionsScreen_FreeInput(MenuOptionsScreen* screen) {
|
||||
if (screen->ActiveI == -1) return;
|
||||
|
||||
Int32 i;
|
||||
for (i = screen->WidgetsCount - 3; i < screen->WidgetsCount; i++) {
|
||||
Elem_Free(screen->WidgetsPtr[i]);
|
||||
screen->WidgetsPtr[i] = NULL;
|
||||
}
|
||||
screen->Validators = validators;
|
||||
screen->Descriptions = descriptions;
|
||||
screen->DefaultValues = defaultValues;
|
||||
screen->Buttons = buttons;
|
||||
screen->DescriptionsCount = descsCount;
|
||||
return screen;
|
||||
}
|
@ -136,8 +136,8 @@ bool String_AppendBool(STRING_TRANSIENT String* str, bool value) {
|
||||
return String_AppendConst(str, text);
|
||||
}
|
||||
|
||||
Int32 String_MakeInt32(Int32 num, UInt8* numBuffer) {
|
||||
Int32 len = 0;
|
||||
Int32 String_MakeUInt32(UInt32 num, UInt8* numBuffer) {
|
||||
UInt32 len = 0;
|
||||
|
||||
do {
|
||||
numBuffer[len] = (UInt8)('0' + (num % 10));
|
||||
@ -149,13 +149,16 @@ Int32 String_MakeInt32(Int32 num, UInt8* numBuffer) {
|
||||
bool String_AppendInt32(STRING_TRANSIENT String* str, Int32 num) {
|
||||
if (num < 0) {
|
||||
num = -num;
|
||||
if (!String_Append(str, (UInt8)'-')) return false;
|
||||
if (!String_Append(str, '-')) return false;
|
||||
}
|
||||
return String_AppendUInt32(str, (UInt32)num);
|
||||
}
|
||||
|
||||
bool String_AppendUInt32(STRING_TRANSIENT String* str, UInt32 num) {
|
||||
UInt8 numBuffer[STRING_INT32CHARS];
|
||||
Int32 numLen = String_MakeInt32(num, numBuffer);
|
||||
Int32 numLen = String_MakeUInt32(num, numBuffer);
|
||||
Int32 i;
|
||||
|
||||
|
||||
for (i = numLen - 1; i >= 0; i--) {
|
||||
if (!String_Append(str, numBuffer[i])) return false;
|
||||
}
|
||||
@ -167,7 +170,7 @@ bool String_AppendPaddedInt32(STRING_TRANSIENT String* str, Int32 num, Int32 min
|
||||
Int32 i;
|
||||
for (i = 0; i < minDigits; i++) { numBuffer[i] = '0'; }
|
||||
|
||||
Int32 numLen = String_MakeInt32(num, numBuffer);
|
||||
Int32 numLen = String_MakeUInt32(num, numBuffer);
|
||||
if (numLen < minDigits) numLen = minDigits;
|
||||
|
||||
for (i = numLen - 1; i >= 0; i--) {
|
||||
@ -335,34 +338,40 @@ Int32 String_Compare(STRING_PURE String* a, STRING_PURE String* b) {
|
||||
return a->length < b->length ? 1 : -1;
|
||||
}
|
||||
|
||||
void String_Format1(STRING_TRANSIENT String* str, const UInt8* format, void* a1) {
|
||||
void String_Format1(STRING_TRANSIENT String* str, const UInt8* format, const void* a1) {
|
||||
String_Format4(str, format, a1, NULL, NULL, NULL);
|
||||
}
|
||||
void String_Format2(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2) {
|
||||
void String_Format2(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2) {
|
||||
String_Format4(str, format, a1, a2, NULL, NULL);
|
||||
}
|
||||
void String_Format3(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2, void* a3) {
|
||||
void String_Format3(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2, const void* a3) {
|
||||
String_Format4(str, format, a1, a2, a3, NULL);
|
||||
}
|
||||
void String_Format4(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2, void* a3, void* a4) {
|
||||
void String_Format4(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2, const void* a3, const void* a4) {
|
||||
String formatStr = String_FromReadonly(format);
|
||||
void* args[4] = { a1, a2, a3, a4 };
|
||||
const void* args[4] = { a1, a2, a3, a4 };
|
||||
Int32 i, j = 0;
|
||||
|
||||
for (i = 0; i < formatStr.length; i++) {
|
||||
if (formatStr.buffer[i] != '%') { String_Append(str, formatStr.buffer[i]); continue; }
|
||||
|
||||
switch (formatStr.buffer[i + 1]) {
|
||||
case 'b': String_AppendInt32(str, *((UInt8*)args[j])); break;
|
||||
case 'i': String_AppendInt32(str, *((Int32*)args[j])); break;
|
||||
case 'f': String_AppendReal32(str, *((Real32*)args[j])); break;
|
||||
case 'p': String_AppendBool(str, *((bool*)args[j])); break;
|
||||
case 'c': String_AppendConst(str, (UInt8*)args[j]); break;
|
||||
case 's': String_AppendString(str, (String*)args[j]); break;
|
||||
default: ErrorHandler_Fail("Invalid type for string format");
|
||||
const void* arg = args[j++];
|
||||
switch (formatStr.buffer[i++]) {
|
||||
case 'b':
|
||||
String_AppendInt32(str, *((UInt8*)arg)); break;
|
||||
case 'i':
|
||||
String_AppendInt32(str, *((Int32*)arg)); break;
|
||||
case 'f':
|
||||
String_AppendReal32(str, *((Real32*)arg)); break;
|
||||
case 'p':
|
||||
String_AppendBool(str, *((bool*)arg)); break;
|
||||
case 'c':
|
||||
String_AppendConst(str, (UInt8*)arg); break;
|
||||
case 's':
|
||||
String_AppendString(str, (String*)arg); break;
|
||||
default:
|
||||
ErrorHandler_Fail("Invalid type for string format");
|
||||
}
|
||||
|
||||
i++; j++; /* skip over type following % */
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,12 @@ void String_UNSAFE_Split(STRING_REF String* str, UInt8 c, STRING_TRANSIENT Strin
|
||||
bool String_Equals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
bool String_CaselessEquals(STRING_PURE String* a, STRING_PURE String* b);
|
||||
bool String_CaselessEqualsConst(STRING_PURE String* a, STRING_PURE const UInt8* b);
|
||||
Int32 String_MakeInt32(Int32 num, UInt8* numBuffer);
|
||||
Int32 String_MakeUInt32(UInt32 num, UInt8* numBuffer);
|
||||
|
||||
bool String_Append(STRING_TRANSIENT String* str, UInt8 c);
|
||||
bool String_AppendBool(STRING_TRANSIENT String* str, bool value);
|
||||
bool String_AppendInt32(STRING_TRANSIENT String* str, Int32 num);
|
||||
bool String_AppendUInt32(STRING_TRANSIENT String* str, UInt32 num);
|
||||
/* Attempts to append an integer value to the end of a string, padding left with 0. */
|
||||
bool String_AppendPaddedInt32(STRING_TRANSIENT String* str, Int32 num, Int32 minDigits);
|
||||
bool String_AppendConst(STRING_TRANSIENT String* str, const UInt8* toAppend);
|
||||
@ -80,10 +81,10 @@ bool String_CaselessStarts(STRING_PURE String* str, STRING_PURE String* sub);
|
||||
bool String_CaselessEnds(STRING_PURE String* str, STRING_PURE String* sub);
|
||||
Int32 String_Compare(STRING_PURE String* a, STRING_PURE String* b);
|
||||
|
||||
void String_Format1(STRING_TRANSIENT String* str, const UInt8* format, void* a1);
|
||||
void String_Format2(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2);
|
||||
void String_Format3(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2, void* a3);
|
||||
void String_Format4(STRING_TRANSIENT String* str, const UInt8* format, void* a1, void* a2, void* a3, void* a4);
|
||||
void String_Format1(STRING_TRANSIENT String* str, const UInt8* format, const void* a1);
|
||||
void String_Format2(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2);
|
||||
void String_Format3(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2, const void* a3);
|
||||
void String_Format4(STRING_TRANSIENT String* str, const UInt8* format, const void* a1, const void* a2, const void* a3, const void* a4);
|
||||
|
||||
UInt16 Convert_CP437ToUnicode(UInt8 c);
|
||||
UInt8 Convert_UnicodeToCP437(UInt16 c);
|
||||
|
@ -12,20 +12,6 @@ typedef struct EntryList_ {
|
||||
StringsBuffer Entries;
|
||||
} EntryList;
|
||||
|
||||
void EntryList_Add(EntryList* list, STRING_PURE String* entry) {
|
||||
StringsBuffer_Add(&list->Entries, entry);
|
||||
EntryList_Save(list);
|
||||
}
|
||||
|
||||
bool EntryList_Has(EntryList* list, STRING_PURE String* entry) {
|
||||
Int32 i;
|
||||
for (i = 0; i < list->Entries.Count; i++) {
|
||||
String curEntry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (String_Equals(&curEntry, entry)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntryList_Load(EntryList* list) {
|
||||
String folder = String_FromRawArray(list->FolderBuffer);
|
||||
String filename = String_FromRawArray(list->FileBuffer);
|
||||
@ -80,6 +66,20 @@ void EntryList_Save(EntryList* list) {
|
||||
ErrorHandler_CheckOrFail(result, "EntryList_Save - close file");
|
||||
}
|
||||
|
||||
void EntryList_Add(EntryList* list, STRING_PURE String* entry) {
|
||||
StringsBuffer_Add(&list->Entries, entry);
|
||||
EntryList_Save(list);
|
||||
}
|
||||
|
||||
bool EntryList_Has(EntryList* list, STRING_PURE String* entry) {
|
||||
Int32 i;
|
||||
for (i = 0; i < list->Entries.Count; i++) {
|
||||
String curEntry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (String_Equals(&curEntry, entry)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void EntryList_Make(EntryList* list, STRING_PURE const UInt8* folder, STRING_PURE const UInt8* file) {
|
||||
String dstFolder = String_InitAndClearArray(list->FolderBuffer);
|
||||
String_AppendConst(&dstFolder, folder);
|
||||
@ -91,10 +91,19 @@ void EntryList_Make(EntryList* list, STRING_PURE const UInt8* folder, STRING_PUR
|
||||
}
|
||||
|
||||
#define TEXCACHE_FOLDER "texturecache"
|
||||
/* Because I didn't store milliseconds in original C# client */
|
||||
#define TEXCACHE_TICKS_PER_MS 10000LL
|
||||
EntryList cache_accepted, cache_denied, cache_eTags, cache_lastModified;
|
||||
|
||||
#define TexCache_InitAndMakePath(url) UInt8 pathBuffer[String_BufferSize(FILENAME_SIZE)]; \
|
||||
path = String_InitAndClearArray(pathBuffer); TextureCache_MakePath(&path, url);
|
||||
#define TexCache_InitAndMakePath(url) \
|
||||
UInt8 pathBuffer[String_BufferSize(FILENAME_SIZE)]; \
|
||||
path = String_InitAndClearArray(pathBuffer); \
|
||||
TextureCache_MakePath(&path, url);
|
||||
|
||||
#define TexCache_Crc32(url) \
|
||||
UInt8 crc32Buffer[STRING_INT32CHARS];\
|
||||
crc32 = String_InitAndClearArray(crc32Buffer);\
|
||||
String_AppendUInt32(&crc32, Utils_CRC32(url->buffer, url->length));
|
||||
|
||||
void TextureCache_Init(void) {
|
||||
EntryList_Make(&cache_accepted, TEXCACHE_FOLDER, "acceptedurls.txt");
|
||||
@ -108,6 +117,11 @@ bool TextureCache_HasDenied(STRING_PURE String* url) { return EntryList_Has(&c
|
||||
void TextureCache_Accept(STRING_PURE String* url) { EntryList_Add(&cache_accepted, url); }
|
||||
void TextureCache_Deny(STRING_PURE String* url) { EntryList_Add(&cache_denied, url); }
|
||||
|
||||
void TextureCache_MakePath(STRING_TRANSIENT String* path, STRING_PURE String* url) {
|
||||
String crc32; TexCache_Crc32(url);
|
||||
String_Format3(path, "%c%b%s", TEXCACHE_FOLDER, &Platform_DirectorySeparator, &crc32);
|
||||
}
|
||||
|
||||
bool TextureCache_HasUrl(STRING_PURE String* url) {
|
||||
String path; TexCache_InitAndMakePath(url);
|
||||
return Platform_FileExists(url);
|
||||
@ -128,11 +142,29 @@ bool TextureCache_GetStream(STRING_PURE String* url, Stream* stream) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void TexturePack_GetFromTags(STRING_PURE String* url, STRING_TRANSIENT String* result, EntryList* list) {
|
||||
String crc32; TexCache_Crc32(url);
|
||||
Int32 i;
|
||||
for (i = 0; i < list->Entries.Count; i++) {
|
||||
String entry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (!String_CaselessStarts(&entry, &crc32)) continue;
|
||||
|
||||
Int32 sepIndex = String_IndexOf(&entry, ' ', 0);
|
||||
if (sepIndex == -1) continue;
|
||||
|
||||
String value = String_UNSAFE_SubstringAt(&entry, sepIndex + 1);
|
||||
String_AppendString(result, &value);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureCache_GetLastModified(STRING_PURE String* url, DateTime* time) {
|
||||
string entry = GetFromTags(url, LastModified);
|
||||
long ticks = 0;
|
||||
if (entry != null && long.TryParse(entry, out ticks)) {
|
||||
return new DateTime(ticks, DateTimeKind.Utc);
|
||||
UInt8 entryBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String entry = String_InitAndClearArray(entryBuffer);
|
||||
TexturePack_GetFromTags(url, &entry, &cache_lastModified);
|
||||
|
||||
Int64 ticks;
|
||||
if (entry.length > 0 && Convert_TryParseInt64(&entry, &ticks)) {
|
||||
*time = DateTime_FromTotalMs(ticks / TEXCACHE_TICKS_PER_MS);
|
||||
} else {
|
||||
String path; TexCache_InitAndMakePath(url);
|
||||
return Platform_FileGetWriteTime(path);
|
||||
@ -140,23 +172,7 @@ void TextureCache_GetLastModified(STRING_PURE String* url, DateTime* time) {
|
||||
}
|
||||
|
||||
void TextureCache_GetETag(STRING_PURE String* url, STRING_PURE String* etag) {
|
||||
TexturePack_GetFromTags(url, etag, ETags);
|
||||
}
|
||||
|
||||
void TexturePack_GetFromTags(STRING_PURE String* url, STRING_TRANSIENT String* result, EntryList* list) {
|
||||
string crc32 = CRC32(url);
|
||||
|
||||
Int32 i;
|
||||
for (i = 0; i < list->Entries.Count; i++) {
|
||||
String entry = StringsBuffer_UNSAFE_Get(&list->Entries, i);
|
||||
if (!String_CaselessStarts(&entry, &crc32)) continue;
|
||||
|
||||
Int32 sepIndex = String_IndexOf(&entry, ' ');
|
||||
if (sepIndex == -1) continue;
|
||||
|
||||
String value = String_UNSAFE_SubstringAt(&entry, sepIndex + 1);
|
||||
String_AppendString(result, &value);
|
||||
}
|
||||
TexturePack_GetFromTags(url, etag, &cache_eTags);
|
||||
}
|
||||
|
||||
void* TextureCache_CreateFile(STRING_PURE String* path) {
|
||||
@ -167,7 +183,7 @@ void* TextureCache_CreateFile(STRING_PURE String* path) {
|
||||
}
|
||||
|
||||
void* file;
|
||||
ReturnCode result = Platform_FileCreate(&file, &path);
|
||||
ReturnCode result = Platform_FileCreate(&file, path);
|
||||
/* TODO: Should we just log failure to save? */
|
||||
ErrorHandler_CheckOrFail(result, "TextureCache_CreateFile - open file");
|
||||
return file;
|
||||
@ -193,19 +209,8 @@ void TextureCache_AddData(STRING_PURE String* url, UInt8* data, UInt32 length) {
|
||||
ErrorHandler_CheckOrFail(result, "TextureCache_AddData - close file");
|
||||
}
|
||||
|
||||
void TextureCache_AddETag(STRING_PURE String* url, STRING_PURE String* etag) {
|
||||
if (etag->length == 0) return;
|
||||
TextureCache_AddToTags(url, etag, ETags);
|
||||
}
|
||||
|
||||
void TextureCache_AddLastModified(STRING_PURE String* url, DateTime* lastModified) {
|
||||
if (lastModified->Year == 0 && lastModified->Month == 0) return;
|
||||
String data = lastModified.ToUniversalTime().Ticks.ToString();
|
||||
TextureCache_AddToTags(url, data, LastModified);
|
||||
}
|
||||
|
||||
void TextureCache_AddToTags(STRING_PURE String* url, STRING_PURE String* data, EntryList* list) {
|
||||
String crc32 = CRC32(url);
|
||||
String crc32; TexCache_Crc32(url);
|
||||
UInt8 entryBuffer[String_BufferSize(2048)];
|
||||
String entry = String_InitAndClearArray(entryBuffer);
|
||||
String_Format2(&entry, "%s %s", &crc32, data);
|
||||
@ -221,11 +226,17 @@ void TextureCache_AddToTags(STRING_PURE String* url, STRING_PURE String* data, E
|
||||
EntryList_Add(list, &entry);
|
||||
}
|
||||
|
||||
void TextureCache_MakePath(STRING_TRANSIENT String* path, STRING_PURE String* url) {
|
||||
return PathIO.Combine(folder, CRC32(url));
|
||||
void TextureCache_AddETag(STRING_PURE String* url, STRING_PURE String* etag) {
|
||||
if (etag->length == 0) return;
|
||||
TextureCache_AddToTags(url, etag, &cache_eTags);
|
||||
}
|
||||
|
||||
void TextureCache_CRC32(STRING_PURE String* url) {
|
||||
UInt32 crc32 = Utils_CRC32(url->buffer, url->length);
|
||||
return crc32.ToString();
|
||||
void TextureCache_AddLastModified(STRING_PURE String* url, DateTime* lastModified) {
|
||||
if (lastModified->Year == 0 && lastModified->Month == 0) return;
|
||||
Int64 ticks = DateTime_TotalMs(lastModified) * TEXCACHE_TICKS_PER_MS;
|
||||
|
||||
UInt8 dataBuffer[String_BufferSize(STRING_SIZE)];
|
||||
String data = String_InitAndClearArray(dataBuffer);
|
||||
String_AppendInt64(&data, ticks);
|
||||
TextureCache_AddToTags(url, &data, &cache_lastModified);
|
||||
}
|
@ -22,6 +22,7 @@ typedef struct Bitmap_ Bitmap;
|
||||
#define DATETIME_SECONDS_PER_HOUR (60 * 60)
|
||||
#define DATETIME_SECONDS_PER_DAY (60 * 60 * 24)
|
||||
|
||||
DateTime DateTime_FromTotalMs(Int64 ms);
|
||||
Int64 DateTime_TotalMs(DateTime* time);
|
||||
Int64 DateTime_MsBetween(DateTime* start, DateTime* end);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user