Fix a bunch of stuff

This commit is contained in:
UnknownShadow200 2018-04-20 12:57:05 +10:00
parent 20e9adbd24
commit 8a25708f6f
15 changed files with 154 additions and 72 deletions

View File

@ -13,6 +13,28 @@
#include "Funcs.h"
#include "Block.h"
#define CHAT_LOGTIMES_DEF_ELEMS 256
#define CHAT_LOGTIMES_EXPAND_ELEMS 512
Int64 Chat_DefaultLogTimes[CHAT_LOGTIMES_DEF_ELEMS];
Int64* Chat_LogTimes = &Chat_DefaultLogTimes;
UInt32 Chat_LogTimesCount = CHAT_LOGTIMES_DEF_ELEMS, Chat_LogTimesUsed;
void Chat_GetLogTime(UInt32 index, Int64* timeMs) {
if (index >= Chat_LogTimesUsed) ErrorHandler_Fail("Tries to get time past LogTime end");
*timeMs = Chat_LogTimes[index];
}
void Chat_AppendLogTime(void) {
DateTime now = Platform_CurrentUTCTime();
UInt32 count = Chat_LogTimesUsed;
if (count == Chat_LogTimesCount) {
StringsBuffer_Resize(&Chat_LogTimes, &Chat_LogTimesCount, sizeof(Int64),
CHAT_LOGTIMES_DEF_ELEMS, CHAT_LOGTIMES_EXPAND_ELEMS);
}
Chat_LogTimes[Chat_LogTimesUsed++] = DateTime_TotalMs(&now);
}
void ChatLine_Make(ChatLine* line, STRING_TRANSIENT String* text) {
String dst = String_InitAndClearArray(line->Buffer);
String_AppendString(&dst, text);
@ -113,6 +135,7 @@ void Chat_AddOf(STRING_PURE String* text, Int32 msgType) {
if (msgType == MSG_TYPE_NORMAL) {
StringsBuffer_Add(&Chat_Log, text);
Chat_AppendLog(text);
Chat_AppendLogTime();
} else if (msgType >= MSG_TYPE_STATUS_1 && msgType <= MSG_TYPE_STATUS_3) {
ChatLine_Make(&Chat_Status[msgType - MSG_TYPE_STATUS_1], text);
} else if (msgType >= MSG_TYPE_BOTTOMRIGHT_1 && msgType <= MSG_TYPE_BOTTOMRIGHT_3) {
@ -511,6 +534,7 @@ void Chat_Reset(void) {
void Chat_Free(void) {
commands_count = 0;
if (Chat_LogTimes != Chat_DefaultLogTimes) Platform_MemFree(Chat_LogTimes);
StringsBuffer_Free(&Chat_Log);
StringsBuffer_Free(&Chat_InputLog);

View File

@ -22,6 +22,7 @@
typedef struct ChatLine_ { UInt8 Buffer[String_BufferSize(STRING_SIZE)]; DateTime Received; } ChatLine;
ChatLine Chat_Status[3], Chat_BottomRight[3], Chat_ClientStatus[3], Chat_Announcement;
StringsBuffer Chat_Log, Chat_InputLog;
void Chat_GetLogTime(UInt32 index, Int64* timeMS);
IGameComponent Chat_MakeGameComponent(void);
void Chat_SetLogName(STRING_PURE String* name);

View File

@ -184,8 +184,7 @@ void Fcm_Load(Stream* stream) {
#define NBT_TAG_COMPOUND 10
#define NBT_TAG_INT32_ARRAY 11
/* supported utf8 codepoint can be up to 3 bytes big */
#define NBT_SMALL_SIZE (STRING_SIZE * 3)
#define NBT_SMALL_SIZE STRING_SIZE
struct NbtTag_;
typedef struct NbtTag_ {
struct NbtTag_* Parent;
@ -244,14 +243,23 @@ UInt8 NbtTag_U8_At(NbtTag* tag, Int32 i) {
return tag->DataBig[i];
}
UInt32 Nbt_ReadString(Stream* stream, UInt8* buffer) {
UInt32 Nbt_ReadString(Stream* stream, UInt8* strBuffer) {
UInt16 nameLen = Stream_ReadUInt16_BE(stream);
if (nameLen > NBT_SMALL_SIZE) ErrorHandler_Fail("NBT String too long");
if (nameLen > NBT_SMALL_SIZE * 4) ErrorHandler_Fail("NBT String too long");
UInt8 nameBuffer[NBT_SMALL_SIZE * 4];
Stream_Read(stream, nameBuffer, nameLen);
/* TODO: this is wrong, we need to UTF8 decode here*/
encoding.utf8.decode(buffer, nameLen);
Stream_Read(stream, buffer, nameLen);
return nameLen;
/* TODO: Check how slow reading strings this way is */
Stream memStream;
Stream_ReadonlyMemory(&memStream, nameBuffer, nameLen, &stream->Name);
UInt16 codepoint;
UInt32 i;
for (i = 0; i < NBT_SMALL_SIZE; i++) {
if (!Stream_ReadUtf8Char(&memStream, &codepoint)) break;
strBuffer[i] = Convert_UnicodeToCP437(codepoint);
}
return i;
}
void Nbt_ReadTag(UInt8 typeId, bool readTagName, Stream* stream, NbtTag* parent) {

View File

@ -18,6 +18,16 @@
#include "Chat.h"
#include "Platform.h"
UInt8 Game_UsernameBuffer[String_BufferSize(STRING_SIZE)];
extern String Game_Username = String_FromEmptyArray(Game_UsernameBuffer);
UInt8 Game_MppassBuffer[String_BufferSize(STRING_SIZE)];
extern String Game_Mppass = String_FromEmptyArray(Game_MppassBuffer);
UInt8 Game_IPAddressBuffer[String_BufferSize(STRING_SIZE)];
extern String Game_IPAddress = String_FromEmptyArray(Game_IPAddressBuffer);
UInt8 Game_FontNameBuffer[String_BufferSize(STRING_SIZE)];
extern String Game_FontName = String_FromEmptyArray(Game_FontNameBuffer);
Int32 Game_GetWindowScale(void) {
Real32 windowScale = min(Game_Width / 640.0f, Game_Height / 480.0f);
return 1 + (Int32)windowScale;

View File

@ -20,9 +20,9 @@ PickedPos Game_CameraClipPos;
GfxResourceID Game_DefaultIb;
bool Game_UseCPEBlocks;
String Game_Username;
String Game_Mppass;
String Game_IPAddress;
extern String Game_Username;
extern String Game_Mppass;
extern String Game_IPAddress;
Int32 Game_Port;
Int32 Game_ViewDistance;
Int32 Game_MaxViewDistance;
@ -51,7 +51,7 @@ bool Game_SmoothLighting;
bool Game_ChatLogging;
bool Game_AutoRotate;
bool Game_SmoothCamera;
String Game_FontName;
extern String Game_FontName;
Int32 Game_ChatLines;
bool Game_ClickableChat;
bool Game_HideGui;

View File

@ -332,7 +332,8 @@ void InputHandler_MouseWheel(void* obj, Real32 delta) {
if (!hotbar && Camera_Active->Zoom(delta)) return;
if (InputHandler_DoFovZoom(delta) || !Inventory_CanChangeHeldBlock) return;
Gui.hudScreen.hotbar.HandlesMouseScroll(delta);
Widget* hotbarW = HUDScreen_GetHotbar(Gui_HUD);
Elem_HandlesMouseScroll(hotbarW, delta);
}
void InputHandler_MouseMove(void* obj, Int32 xDelta, Int32 yDelta) {

View File

@ -43,6 +43,10 @@ UInt32 Platform_FilePosition(void* file);
UInt32 Platform_FileLength(void* file);
void Platform_ThreadSleep(UInt32 milliseconds);
typedef void Platform_ThreadFunc(void);
void* Platform_ThreadStart(Platform_ThreadFunc* func);
/* Frees handle to thread - NOT THE THREAD ITSELF */
void Platform_ThreadFreeHandle(void* handle);
void Platform_MakeFont(FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style);
void Platform_FreeFont(FontDesc* desc);

View File

@ -1093,16 +1093,16 @@ void ChatScreen_Render(GuiElement* elem, Real64 delta) {
if (screen->HandlesAllInput) {
Elem_Render(&screen->Chat, delta);
} else {
Int64 nowMS = DateTime_TotalMs(&now);
/* Only render recent chat */
for (i = 0; i < screen->Chat.LinesCount; i++) {
Texture tex = screen->Chat.Textures[i];
Int32 logIdx = screen->ChatIndex + i;
if (tex.ID == NULL) continue;
if (logIdx < 0 || logIdx >= Chat_Log.Count) continue;
DateTime received = game.Chat.Log[logIdx].Received;
if (DateTime_MsBetween(&received, &now) <= 10000) {
Texture_Render(&tex);
}
Int64 received; Chat_GetLogTime(logIdx, &received);
if ((nowMS - received) <= 10 * 1000) Texture_Render(&tex);
}
}
@ -1114,7 +1114,7 @@ void ChatScreen_Render(GuiElement* elem, Real64 delta) {
}
}
if (screen->Announcement.Texture.ID != NULL && DateTime_MsBetween(&Chat_Announcement.Received, &now) > 5000) {
if (screen->Announcement.Texture.ID != NULL && DateTime_MsBetween(&Chat_Announcement.Received, &now) > 5 * 1000) {
Elem_Free(&screen->Announcement);
}
}
@ -1376,6 +1376,11 @@ void HUDScreen_AppendInput(Screen* hud, STRING_PURE String* text) {
InputWidget_AppendString(&widget->Base, text);
}
Widget* HUDScreen_GetHotbar(Screen* hud) {
HUDScreen* screen = (HUDScreen*)hud;
return &screen->Hotbar;
}
/*########################################################################################################################*
*----------------------------------------------------DisconnectScreen-----------------------------------------------------*

View File

@ -13,13 +13,11 @@ Screen* LoadingScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String
Screen* GeneratingScreen_MakeInstance(void);
Screen* HUDScreen_MakeInstance(void);
IGameComponent HUDScreen_MakeComponent(void);
void HUDScreen_OpenInput(Screen* hud, STRING_PURE String* text);
void HUDScreen_AppendInput(Screen* hud, STRING_PURE String* text);
Screen* DisconnectScreen_MakeInstance(STRING_PURE String* title, STRING_PURE String* message);
Screen* OptionsGroupScreen_MakeInstance(void);
Screen* PauseScreen_MakeInstance(void);
/* Raw pointer to inventory screen. DO NOT USE THIS. Use InventoryScreen_MakeInstance() */
extern Screen* InventoryScreen_UNSAFE_RawPointer;
void HUDScreen_OpenInput(Screen* hud, STRING_PURE String* text);
void HUDScreen_AppendInput(Screen* hud, STRING_PURE String* text);
Widget* HUDScreen_GetHotbar(Screen* hud);
#endif

View File

@ -52,7 +52,15 @@ void ServerConnection_BeginGeneration(Int32 width, Int32 height, Int32 length, I
Gui_SetNewScreen(GeneratingScreen_MakeInstance());
Gen_Width = width; Gen_Height = height; Gen_Length = length; Gen_Seed = seed;
gen.GenerateAsync();
void* threadHandle;
if (vanilla) {
threadHandle = Platform_ThreadStart(&NotchyGen_Generate);
} else {
threadHandle = Platform_ThreadStart(&FlatgrassGen_Generate);
}
/* don't leak thread handle here */
Platform_ThreadFreeHandle(threadHandle);
}
void ServerConnection_EndGeneration(void) {

View File

@ -236,45 +236,47 @@ void Stream_WriteUInt32_BE(Stream* stream, UInt32 value) {
/*########################################################################################################################*
*--------------------------------------------------Read/Write strings-----------------------------------------------------*
*#########################################################################################################################*/
bool Stream_ReadLine(Stream* stream, STRING_TRANSIENT String* text) {
String_Clear(text);
for (;;) {
UInt32 byteCount = 0, read = 0;
bool Stream_ReadUtf8Char(Stream* stream, UInt16* codepoint) {
UInt32 read = 0;
UInt8 header;
ReturnCode code = stream->Read(stream, &header, 1, &read);
if (read == 0) return false; /* end of stream */
if (!ErrorHandler_Check(code)) { Stream_Fail(stream, code, "reading line from"); }
if (!ErrorHandler_Check(code)) { Stream_Fail(stream, code, "reading utf8 from"); }
/* Header byte is just the raw codepoint (common case) */
if (header <= 0x7F) { *codepoint = header; return true; }
/* Header byte encodes variable number of following bytes */
/* The remaining bits of the header form first part of the character */
Int32 bit;
for (bit = 7; bit >= 0; bit--) {
if ((header & (1 << bit)) != 0) {
Int32 byteCount = 0, i;
for (i = 7; i >= 0; i--) {
if ((header & (1 << i)) != 0) {
byteCount++;
header &= (UInt8)~(1 << bit);
header &= (UInt8)~(1 << i);
} else {
break;
}
}
UInt16 codeword;
if (byteCount == 0) {
codeword = (UInt8)header;
} else {
codeword = header;
Int32 i;
*codepoint = header;
for (i = 0; i < byteCount - 1; i++) {
codeword <<= 6;
*codepoint <<= 6;
/* Top two bits of each are always 10 */
codeword |= (UInt16)(Stream_ReadUInt8(stream) & 0x3F);
}
*codepoint |= (UInt16)(Stream_ReadUInt8(stream) & 0x3F);
}
return true;
}
bool Stream_ReadLine(Stream* stream, STRING_TRANSIENT String* text) {
String_Clear(text);
for (;;) {
UInt16 codepoint;
if (!Stream_ReadUtf8Char(stream, &codepoint)) return false;
/* Handle \r\n or \n line endings */
if (codeword == '\r') continue;
if (codeword == '\n') return true;
String_Append(text, Convert_UnicodeToCP437(codeword));
if (codepoint == '\r') continue;
if (codepoint == '\n') return true;
String_Append(text, Convert_UnicodeToCP437(codepoint));
}
}

View File

@ -57,6 +57,8 @@ void Stream_WriteUInt32_LE(Stream* stream, UInt32 value);
void Stream_WriteUInt32_BE(Stream* stream, UInt32 value);
#define Stream_WriteInt32_BE(stream, value) Stream_WriteUInt32_BE(stream, (UInt32)(value))
/* Reads a UTF8 encoded character from the given stream. Returns false if end of stream. */
bool Stream_ReadUtf8Char(Stream* stream, UInt16* codepoint);
/* Reads a line of UTF8 encoding text from the given stream. Returns false if end of stream. */
bool Stream_ReadLine(Stream* stream, STRING_TRANSIENT String* text);
/* Writes a line of UTF8 encoded text to the given stream. */

View File

@ -574,10 +574,10 @@ void StringsBuffer_Init(StringsBuffer* buffer) {
}
void StringsBuffer_Free(StringsBuffer* buffer) {
if (buffer->TextBufferElems > STRINGSBUFFER_BUFFER_DEF_SIZE) {
if (buffer->TextBuffer != buffer->DefaultBuffer) {
Platform_MemFree(buffer->TextBuffer);
}
if (buffer->FlagsBufferElems > STRINGSBUFFER_FLAGS_DEF_ELEMS) {
if (buffer->FlagsBuffer != buffer->DefaultFlags) {
Platform_MemFree(buffer->FlagsBuffer);
}
StringsBuffer_UNSAFE_Reset(buffer);
@ -603,20 +603,23 @@ String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index) {
return String_Init(&buffer->TextBuffer[offset], (UInt16)len, (UInt16)len);
}
void StringsBuffer_ResizeArray(void** buffer, UInt32 curSize, UInt32 newSize, bool reallocing) {
void StringsBuffer_Resize(void** buffer, UInt32* elems, UInt32 elemSize, UInt32 defElems, UInt32 expandElems) {
/* We use a statically allocated buffer initally, so can't realloc first time */
void* dst;
void* cur = *buffer;
if (!reallocing) {
UInt32 curElems = *elems, newSize = (curElems + expandElems) * elemSize;
if (curElems <= defElems) {
dst = Platform_MemAlloc(newSize);
if (dst == NULL) ErrorHandler_Fail("Failed allocating memory for StringsBuffer");
Platform_MemCpy(dst, cur, curSize);
Platform_MemCpy(dst, cur, curElems * elemSize);
} else {
dst = Platform_MemRealloc(cur, newSize);
if (dst == NULL) ErrorHandler_Fail("Failed allocating memory for resizing StringsBuffer");
}
*buffer = dst;
*elems = curElems + expandElems;
}
void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text) {
@ -625,11 +628,8 @@ void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text) {
if (buffer->FlagsBufferElems == 0) {
ErrorHandler_Fail("StringsBuffer not properly initalised");
}
UInt32 curElemSize = buffer->FlagsBufferElems * sizeof(UInt32);
UInt32 newElemsSize = (buffer->FlagsBufferElems + STRINGSBUFFER_FLAGS_EXPAND_ELEMS) * sizeof(UInt32);
bool reallocingElems = buffer->FlagsBufferElems > STRINGSBUFFER_FLAGS_DEF_ELEMS;
StringsBuffer_ResizeArray(&buffer->FlagsBuffer, curElemSize, newElemsSize, reallocingElems);
StringsBuffer_Resize(&buffer->FlagsBuffer, &buffer->FlagsBufferElems, sizeof(UInt32),
STRINGSBUFFER_FLAGS_DEF_ELEMS, STRINGSBUFFER_FLAGS_EXPAND_ELEMS);
}
if (text->length > STRINGSBUFFER_LEN_MASK) {
@ -638,10 +638,8 @@ void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text) {
UInt32 textOffset = buffer->UsedElems;
if (textOffset + text->length >= buffer->TextBufferElems) {
UInt32 curTextSize = buffer->TextBufferElems;
UInt32 newTextSize = buffer->TextBufferElems + STRINGSBUFFER_BUFFER_EXPAND_SIZE;
bool reallocingText = buffer->TextBufferElems > STRINGSBUFFER_BUFFER_DEF_SIZE;
StringsBuffer_ResizeArray(&buffer->FlagsBuffer, curTextSize, newTextSize, reallocingText);
StringsBuffer_Resize(&buffer->TextBuffer, &buffer->TextBufferElems, sizeof(UInt8),
STRINGSBUFFER_BUFFER_DEF_SIZE, STRINGSBUFFER_BUFFER_EXPAND_SIZE);
}
if (text->length > 0) {

View File

@ -114,6 +114,7 @@ void StringsBuffer_Free(StringsBuffer* buffer);
void StringsBuffer_UNSAFE_Reset(StringsBuffer* buffer);
void StringsBuffer_Get(StringsBuffer* buffer, UInt32 index, STRING_TRANSIENT String* text);
STRING_REF String StringsBuffer_UNSAFE_Get(StringsBuffer* buffer, UInt32 index);
void StringsBuffer_Resize(void** buffer, UInt32* elems, UInt32 elemSize, UInt32 defElems, UInt32 expandElems);
void StringsBuffer_Add(StringsBuffer* buffer, STRING_PURE String* text);
void StringsBuffer_Remove(StringsBuffer* buffer, UInt32 index);
Int32 StringsBuffer_Compare(StringsBuffer* buffer, UInt32 idxA, UInt32 idxB);

View File

@ -228,6 +228,26 @@ void Platform_ThreadSleep(UInt32 milliseconds) {
Sleep(milliseconds);
}
DWORD WINAPI Platform_ThreadStartCallback(LPVOID lpParam) {
Platform_ThreadFunc* func = (Platform_ThreadFunc*)lpParam;
(*func)();
return 0;
}
void* Platform_ThreadStart(Platform_ThreadFunc* func) {
void* handle = CreateThread(NULL, 0, Platform_ThreadStartCallback, func, 0, NULL);
if (handle == NULL) {
ErrorHandler_FailWithCode(GetLastError(), "Creating thread");
}
return handle;
}
void Platform_ThreadFreeHandle(void* handle) {
if (!CloseHandle((HANDLE)handle)) {
ErrorHandler_FailWithCode(GetLastError(), "Freeing thread handle");
}
}
void Platform_MakeFont(FontDesc* desc, STRING_PURE String* fontName, UInt16 size, UInt16 style) {
desc->Size = size;