From feaf213fa216a1c3fe6e91d5f18772f22930596d Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sun, 4 Nov 2018 13:23:40 +1100 Subject: [PATCH] yet more c90 rewrite --- src/Deflate.c | 13 +- src/Deflate.h | 4 +- src/Drawer2D.h | 3 +- src/Entity.c | 81 ++++++------ src/EntityComponents.c | 3 +- src/ErrorHandler.c | 25 ++-- src/Formats.c | 7 +- src/Menus.c | 21 ++-- src/Model.c | 20 ++- src/Screens.c | 22 ++-- src/String.h | 2 + src/TexturePack.c | 4 +- src/TexturePack.h | 2 +- src/Widgets.c | 279 ++++++++++++++++++++++++----------------- src/Widgets.h | 2 +- 15 files changed, 273 insertions(+), 215 deletions(-) diff --git a/src/Deflate.c b/src/Deflate.c index c977b6a6b..89eb0bcd1 100644 --- a/src/Deflate.c +++ b/src/Deflate.c @@ -23,7 +23,8 @@ void GZipHeader_Init(struct GZipHeader* header) { } ReturnCode GZipHeader_Read(struct Stream* s, struct GZipHeader* header) { - ReturnCode res; uint8_t tmp; + uint8_t tmp; + ReturnCode res; switch (header->State) { case GZIP_STATE_HEADER1: @@ -104,7 +105,8 @@ void ZLibHeader_Init(struct ZLibHeader* header) { } ReturnCode ZLibHeader_Read(struct Stream* s, struct ZLibHeader* header) { - ReturnCode res; uint8_t tmp; + uint8_t tmp; + ReturnCode res; switch (header->State) { case ZLIB_STATE_COMPRESSIONMETHOD: @@ -196,7 +198,8 @@ static void Huffman_Build(struct HuffmanTable* table, uint8_t* bitLens, int coun offset += bl_count[i]; /* Last codeword is actually: code + (bl_count[i] - 1) */ - /* When decoding we peform < against this value though, so we need to add 1 here */ + /* When decoding we peform < against this value though, so need to add 1 here */ + /* This way, don't need to special case bit lengths with 0 codewords when decoding */ if (bl_count[i]) { table->EndCodewords[i] = code + bl_count[i]; } else { @@ -306,7 +309,7 @@ void Inflate_Init(struct InflateState* state, struct Stream* source) { state->LastBlock = false; state->Bits = 0; state->NumBits = 0; - state->NextIn = state->Input; + state->NextIn = state->Input; state->AvailIn = 0; state->Output = NULL; state->AvailOut = 0; @@ -420,7 +423,7 @@ void Inflate_Process(struct InflateState* state) { } break; case 1: { /* Fixed/static huffman compressed */ - Huffman_Build(&state->Table.Lits, fixed_lits, INFLATE_MAX_LITS); + Huffman_Build(&state->Table.Lits, fixed_lits, INFLATE_MAX_LITS); Huffman_Build(&state->TableDists, fixed_dists, INFLATE_MAX_DISTS); state->State = Inflate_NextCompressState(state); } break; diff --git a/src/Deflate.h b/src/Deflate.h index 9c05ebce0..7fd5a43d6 100644 --- a/src/Deflate.h +++ b/src/Deflate.h @@ -75,8 +75,8 @@ NOINLINE_ void Inflate_MakeStream(struct Stream* stream, struct InflateState* st #define DEFLATE_HASH_SIZE 0x1000UL #define DEFLATE_HASH_MASK 0x0FFFUL struct DeflateState { - uint32_t Bits; /* Holds bits across byte boundaries*/ - uint32_t NumBits; /* Number of bits in Bits buffer*/ + uint32_t Bits; /* Holds bits across byte boundaries */ + uint32_t NumBits; /* Number of bits in Bits buffer */ uint32_t InputPosition; uint8_t* NextOut; /* Pointer within Output buffer to next byte that can be written */ diff --git a/src/Drawer2D.h b/src/Drawer2D.h index 3e03be313..be33632de 100644 --- a/src/Drawer2D.h +++ b/src/Drawer2D.h @@ -40,8 +40,9 @@ void Drawer2D_Make2DTexture(struct Texture* tex, Bitmap* bmp, Size2D used, int X bool Drawer2D_ValidColCodeAt(const String* text, int i); bool Drawer2D_ValidColCode(char c); +/* Whether text is empty or consists purely of valid colour codes. */ bool Drawer2D_IsEmptyText(const String* text); -/* Returns the last valid colour code in the given input, or \0 if no valid colour code was found. */ +/* Returns the last valid colour code in the given input, or \0 if not found. */ char Drawer2D_LastCol(const String* text, int start); bool Drawer2D_IsWhiteCol(char c); diff --git a/src/Entity.c b/src/Entity.c index 3c7bb59a1..ab4b5beca 100644 --- a/src/Entity.c +++ b/src/Entity.c @@ -528,6 +528,7 @@ static void Player_DrawName(struct Player* player) { struct Model* model = e->Model; Vector3 pos; float scale; + VertexP3fT2fC4b vertices[4]; if (player->NameTex.X == PLAYER_NAME_EMPTY_TEX) return; if (!player->NameTex.ID) Player_MakeNameTexture(player); @@ -548,7 +549,6 @@ static void Player_DrawName(struct Player* player) { size.X *= tempW * 0.2f; size.Y *= tempW * 0.2f; } - VertexP3fT2fC4b vertices[4]; TextureRec rec = { 0.0f, 0.0f, player->NameTex.U2, player->NameTex.V2 }; PackedCol col = PACKEDCOL_WHITE; Particle_DoRender(&size, &pos, &rec, col, vertices); @@ -664,26 +664,27 @@ static void Player_ClearHat(Bitmap* bmp, uint8_t skinType) { } } -static void Player_EnsurePow2(struct Player* player, Bitmap* bmp) { - int width = Math_NextPowOf2(bmp->Width); - int height = Math_NextPowOf2(bmp->Height); +static void Player_EnsurePow2(struct Player* p, Bitmap* bmp) { + uint32_t stride; + int width, height; Bitmap scaled; + int y; + width = Math_NextPowOf2(bmp->Width); + height = Math_NextPowOf2(bmp->Height); if (width == bmp->Width && height == bmp->Height) return; Bitmap_Allocate(&scaled, width, height); - int y; - uint32_t stride = (uint32_t)(bmp->Width) * BITMAP_SIZEOF_PIXEL; + p->Base.uScale = (float)bmp->Width / width; + p->Base.vScale = (float)bmp->Height / height; + stride = bmp->Width * BITMAP_SIZEOF_PIXEL; + for (y = 0; y < bmp->Height; y++) { uint32_t* src = Bitmap_GetRow(bmp, y); uint32_t* dst = Bitmap_GetRow(&scaled, y); Mem_Copy(dst, src, stride); } - struct Entity* entity = &player->Base; - entity->uScale = (float)bmp->Width / width; - entity->vScale = (float)bmp->Height / height; - Mem_Free(bmp->Scan0); *bmp = scaled; } @@ -831,16 +832,18 @@ static void LocalPlayer_SetLocation(struct Entity* e, struct LocationUpdate* upd } void LocalPlayer_Tick(struct Entity* e, double delta) { - if (!World_Blocks) return; struct LocalPlayer* p = (struct LocalPlayer*)e; struct HacksComp* hacks = &p->Hacks; - - e->StepSize = hacks->FullBlockStep && hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed ? 1.0f : 0.5f; - p->OldVelocity = e->Velocity; float xMoving = 0, zMoving = 0; - LocalInterpComp_AdvanceState(&p->Interp); - bool wasOnGround = e->OnGround; + bool wasOnGround; + Vector3 headingVelocity; + if (!World_Blocks) return; + e->StepSize = hacks->FullBlockStep && hacks->Enabled && hacks->CanAnyHacks && hacks->CanSpeed ? 1.0f : 0.5f; + p->OldVelocity = e->Velocity; + wasOnGround = e->OnGround; + + LocalInterpComp_AdvanceState(&p->Interp); LocalPlayer_HandleInput(&xMoving, &zMoving); hacks->Floating = hacks->Noclip || hacks->Flying; if (!hacks->Floating && hacks->CanBePushed) PhysicsComp_DoEntityPush(e); @@ -851,7 +854,7 @@ void LocalPlayer_Tick(struct Entity* e, double delta) { } PhysicsComp_UpdateVelocityState(&p->Physics); - Vector3 headingVelocity = Vector3_RotateY3(xMoving, 0, zMoving, e->HeadY * MATH_DEG2RAD); + headingVelocity = Vector3_RotateY3(xMoving, 0, zMoving, e->HeadY * MATH_DEG2RAD); PhysicsComp_PhysicsTick(&p->Physics, headingVelocity); /* Fixes high jump, when holding down a movement key, jump, fly, then let go of fly key */ @@ -861,7 +864,7 @@ void LocalPlayer_Tick(struct Entity* e, double delta) { AnimatedComp_Update(e, p->Interp.Prev.Pos, p->Interp.Next.Pos, delta); TiltComp_Update(&p->Tilt, delta); - Player_CheckSkin((struct Player*)p); + Player_CheckSkin(&p->Base); SoundComp_Tick(wasOnGround); } @@ -928,7 +931,7 @@ struct EntityVTABLE localPlayer_VTABLE = { void LocalPlayer_Init(void) { struct LocalPlayer* p = &LocalPlayer_Instance; Player_Init(&p->Base); - Player_SetName((struct Player*)p, &Game_Username, &Game_Username); + Player_SetName(&p->Base, &Game_Username, &Game_Username); p->Collisions.Entity = &p->Base; HacksComp_Init(&p->Hacks); @@ -944,22 +947,26 @@ void LocalPlayer_Init(void) { static bool LocalPlayer_IsSolidCollide(BlockID b) { return Block_Collide[b] == COLLIDE_SOLID; } static void LocalPlayer_DoRespawn(void) { struct LocalPlayer* p = &LocalPlayer_Instance; - Vector3 spawn = p->Spawn; - Vector3I P; + struct LocationUpdate update; struct AABB bb; + Vector3 spawn = p->Spawn; + Vector3I pos; + BlockID block; + float height, spawnY; + int y; if (!World_Blocks) return; - Vector3I_Floor(&P, &spawn); + Vector3I_Floor(&pos, &spawn); /* Spawn player at highest valid position */ - if (World_IsValidPos_3I(P)) { + if (World_IsValidPos_3I(pos)) { AABB_Make(&bb, &spawn, &p->Base.Size); - int y; - for (y = P.Y; y <= World_Height; y++) { - float spawnY = Respawn_HighestFreeY(&bb); + for (y = pos.Y; y <= World_Height; y++) { + spawnY = Respawn_HighestFreeY(&bb); + if (spawnY == RESPAWN_NOT_FOUND) { - BlockID block = World_GetPhysicsBlock(P.X, y, P.Z); - float height = Block_Collide[block] == COLLIDE_SOLID ? Block_MaxBB[block].Y : 0.0f; + block = World_GetPhysicsBlock(pos.X, y, pos.Z); + height = Block_Collide[block] == COLLIDE_SOLID ? Block_MaxBB[block].Y : 0.0f; spawn.Y = y + height + ENTITY_ADJUSTMENT; break; } @@ -967,8 +974,8 @@ static void LocalPlayer_DoRespawn(void) { } } - spawn.Y += 2.0f / 16.0f; - struct LocationUpdate update; LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, false); + spawn.Y += 2.0f/16.0f; + LocationUpdate_MakePosAndOri(&update, spawn, p->SpawnRotY, p->SpawnHeadX, false); p->Base.VTABLE->SetLocation(&p->Base, &update, false); p->Base.Velocity = Vector3_Zero; @@ -1063,7 +1070,7 @@ static void NetPlayer_SetLocation(struct Entity* e, struct LocationUpdate* updat static void NetPlayer_Tick(struct Entity* e, double delta) { struct NetPlayer* p = (struct NetPlayer*)e; - Player_CheckSkin((struct Player*)p); + Player_CheckSkin(&p->Base); NetInterpComp_AdvanceState(&p->Interp); AnimatedComp_Update(e, p->Interp.Prev.Pos, p->Interp.Next.Pos, delta); } @@ -1086,16 +1093,16 @@ static void NetPlayer_RenderName(struct Entity* e) { distance = Model_RenderDistance(e); threshold = Entities_NameMode == NAME_MODE_ALL_UNSCALED ? 8192 * 8192 : 32 * 32; - if (distance <= (float)threshold) Player_DrawName((struct Player*)p); + if (distance <= (float)threshold) Player_DrawName(&p->Base); } struct EntityVTABLE netPlayer_VTABLE = { NetPlayer_Tick, Player_Despawn, NetPlayer_SetLocation, Entity_GetCol, NetPlayer_RenderModel, NetPlayer_RenderName, Player_ContextLost, Player_ContextRecreated, }; -void NetPlayer_Init(struct NetPlayer* player, const String* displayName, const String* skinName) { - Mem_Set(player, 0, sizeof(struct NetPlayer)); - Player_Init(&player->Base); - Player_SetName((struct Player*)player, displayName, skinName); - player->Base.VTABLE = &netPlayer_VTABLE; +void NetPlayer_Init(struct NetPlayer* p, const String* displayName, const String* skinName) { + Mem_Set(p, 0, sizeof(struct NetPlayer)); + Player_Init(&p->Base); + Player_SetName(&p->Base, displayName, skinName); + p->Base.VTABLE = &netPlayer_VTABLE; } diff --git a/src/EntityComponents.c b/src/EntityComponents.c index e88a0cd39..0923c15ad 100644 --- a/src/EntityComponents.c +++ b/src/EntityComponents.c @@ -166,8 +166,7 @@ void HacksComp_Init(struct HacksComp* hacks) { hacks->NoclipSlide = true; hacks->CanBePushed = true; - String str = String_FromArray(hacks->__HacksFlagsBuffer); - hacks->HacksFlags = str; + String_InitArray(hacks->HacksFlags, hacks->__HacksFlagsBuffer); } bool HacksComp_CanJumpHigher(struct HacksComp* hacks) { diff --git a/src/ErrorHandler.c b/src/ErrorHandler.c index 7d283f86c..26c18bac0 100644 --- a/src/ErrorHandler.c +++ b/src/ErrorHandler.c @@ -485,14 +485,21 @@ static void X11_MessageBox(const char* title, const char* text, X11Window* w) { X11Button ok = { 0 }; X11Textbox body = { 0 }; + XFontStruct* font; + Atom wmDelete; + int x, y, width, height; + XSizeHints hints = { 0 }; + int mouseX = -1, mouseY = -1, over; + XEvent e; + X11Window_Init(w); XMapWindow(dpy, w->win); XStoreName(dpy, w->win, title); - Atom wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); + wmDelete = XInternAtom(dpy, "WM_DELETE_WINDOW", False); XSetWMProtocols(dpy, w->win, &wmDelete, 1); - XFontStruct* font = XQueryFont(dpy, XGContextFromGC(w->gc)); + font = XQueryFont(dpy, XGContextFromGC(w->gc)); if (!font) return; /* Compute size of widgets */ @@ -504,10 +511,10 @@ static void X11_MessageBox(const char* title, const char* text, X11Window* w) { ok.Height = ok.Text.Height + 10; /* Compute size and position of window */ - int width = body.Width + 20; - int height = body.Height + 20 + ok.Height + 20; - int x = DisplayWidth (dpy, DefaultScreen(dpy))/2 - width/2; - int y = DisplayHeight(dpy, DefaultScreen(dpy))/2 - height/2; + width = body.Width + 20; + height = body.Height + 20 + ok.Height + 20; + x = DisplayWidth (dpy, DefaultScreen(dpy))/2 - width/2; + y = DisplayHeight(dpy, DefaultScreen(dpy))/2 - height/2; XMoveResizeWindow(dpy, w->win, x, y, width, height); /* Adjust bounds of widgets */ @@ -518,7 +525,6 @@ static void X11_MessageBox(const char* title, const char* text, X11Window* w) { XFreeFontInfo(NULL, font, 1); XUnmapWindow(dpy, w->win); /* Make window non resizeable */ - XSizeHints hints = { 0 }; hints.flags = PSize | PMinSize | PMaxSize; hints.min_width = hints.max_width = hints.base_width = width; hints.min_height = hints.max_height = hints.base_height = height; @@ -527,9 +533,6 @@ static void X11_MessageBox(const char* title, const char* text, X11Window* w) { XMapRaised(dpy, w->win); XFlush(dpy); - XEvent e; - int mouseX = -1, mouseY = -1; - for (;;) { XNextEvent(dpy, &e); @@ -538,7 +541,7 @@ static void X11_MessageBox(const char* title, const char* text, X11Window* w) { case ButtonPress: case ButtonRelease: if (e.xbutton.button != Button1) break; - int over = X11Button_Contains(&ok, mouseX, mouseY); + over = X11Button_Contains(&ok, mouseX, mouseY); if (ok.Clicked && e.type == ButtonRelease) { if (over) return; diff --git a/src/Formats.c b/src/Formats.c index df1a1aec6..7487a15fc 100644 --- a/src/Formats.c +++ b/src/Formats.c @@ -305,9 +305,10 @@ static ReturnCode Nbt_ReadTag(uint8_t typeId, bool readTagName, struct Stream* s uint32_t i, count; if (typeId == NBT_END) return 0; - tag.TagID = typeId; tag.Parent = parent; - tag.Name = String_Init(tag.NameBuffer, 0, NBT_STRING_SIZE); + tag.TagID = typeId; + tag.Parent = parent; tag.DataSize = 0; + String_InitArray(tag.Name, tag.NameBuffer); if (readTagName) { res = Nbt_ReadString(stream, &tag.Name); @@ -343,7 +344,7 @@ static ReturnCode Nbt_ReadTag(uint8_t typeId, bool readTagName, struct Stream* s } break; case NBT_STR: - tag.Value.Str.Text = String_Init(tag.Value.Str.Buffer, 0, NBT_STRING_SIZE); + String_InitArray(tag.Value.Str.Text, tag.Value.Str.Buffer); res = Nbt_ReadString(stream, &tag.Value.Str.Text); break; diff --git a/src/Menus.c b/src/Menus.c index e32aea02b..269a90690 100644 --- a/src/Menus.c +++ b/src/Menus.c @@ -1267,9 +1267,7 @@ static void SaveLevelScreen_Schematic(void* a, void* b) { SaveLevelScreen_Save(a static void SaveLevelScreen_Init(void* screen) { struct SaveLevelScreen* s = screen; - String str = String_FromArray(s->__TextPathBuffer); - s->TextPath = str; - + String_InitArray(s->TextPath, s->__TextPathBuffer); Key_KeyRepeat = true; MenuScreen_Init(s); } @@ -3158,9 +3156,8 @@ struct Screen* UrlWarningOverlay_MakeInstance(const String* url) { s->Widgets = widgets; s->WidgetsCount = Array_Elems(widgets); - String dstUrl = String_FromArray(s->__UrlBuffer); - String_Copy(&dstUrl, url); - s->Url = dstUrl; + String_InitArray(s->Url, s->__UrlBuffer); + String_Copy(&s->Url, url); s->VTABLE = &UrlWarningOverlay_VTABLE; return (struct Screen*)s; @@ -3225,9 +3222,8 @@ struct Screen* ConfirmDenyOverlay_MakeInstance(const String* url, bool alwaysDen s->Widgets = widgets; s->WidgetsCount = Array_Elems(widgets); - String dstUrl = String_FromArray(s->__UrlBuffer); - String_Copy(&dstUrl, url); - s->Url = dstUrl; + String_InitArray(s->Url, s->__UrlBuffer); + String_Copy(&s->Url, url); s->AlwaysDeny = alwaysDeny; s->VTABLE = &ConfirmDenyOverlay_VTABLE; @@ -3337,12 +3333,11 @@ struct Screen* TexPackOverlay_MakeInstance(const String* url) { s->Widgets = widgets; s->WidgetsCount = Array_Elems(widgets); - String identifier = String_FromArray(s->__IdentifierBuffer); - String_Format1(&identifier, "CL_%s", url); - s->Identifier = identifier; + String_InitArray(s->Identifier, s->__IdentifierBuffer); + String_Format1(&s->Identifier, "CL_%s", url); s->ContentLength = 0; - AsyncDownloader_GetContentLength(url, true, &identifier); + AsyncDownloader_GetContentLength(url, true, &s->Identifier); s->VTABLE = &TexPackOverlay_VTABLE; return (struct Screen*)s; } diff --git a/src/Model.c b/src/Model.c index 3028743ea..55bb2bda3 100644 --- a/src/Model.c +++ b/src/Model.c @@ -113,10 +113,14 @@ void Model_Render(struct Model* model, struct Entity* entity) { } void Model_SetupState(struct Model* model, struct Entity* entity) { - model->index = 0; - PackedCol col = entity->VTABLE->GetCol(entity); + PackedCol col; + bool _64x64; + float yawDelta; - bool _64x64 = entity->SkinType != SKIN_64x32; + model->index = 0; + col = entity->VTABLE->GetCol(entity); + + _64x64 = entity->SkinType != SKIN_64x32; /* only apply when using humanoid skins */ _64x64 &= model->UsesHumanSkin || entity->MobTextureId; @@ -131,10 +135,11 @@ void Model_SetupState(struct Model* model, struct Entity* entity) { } else { Model_Cols[1] = col; Model_Cols[2] = col; Model_Cols[4] = col; } + Model_Cols[3] = Model_Cols[2]; Model_Cols[5] = Model_Cols[4]; + yawDelta = entity->HeadY - entity->RotY; - float yawDelta = entity->HeadY - entity->RotY; Model_cosHead = (float)Math_Cos(yawDelta * MATH_DEG2RAD); Model_sinHead = (float)Math_Sin(yawDelta * MATH_DEG2RAD); Model_ActiveModel = model; @@ -148,9 +153,11 @@ void Model_UpdateVB(void) { void Model_ApplyTexture(struct Entity* entity) { struct Model* model = Model_ActiveModel; - GfxResourceID tex = model->UsesHumanSkin ? entity->TextureId : entity->MobTextureId; struct CachedTexture* data; + GfxResourceID tex; + bool _64x64; + tex = model->UsesHumanSkin ? entity->TextureId : entity->MobTextureId; if (tex) { Model_skinType = entity->SkinType; } else { @@ -160,7 +167,8 @@ void Model_ApplyTexture(struct Entity* entity) { } Gfx_BindTexture(tex); - bool _64x64 = Model_skinType != SKIN_64x32; + _64x64 = Model_skinType != SKIN_64x32; + Model_uScale = entity->uScale * 0.015625f; Model_vScale = entity->vScale * (_64x64 ? 0.015625f : 0.03125f); } diff --git a/src/Screens.c b/src/Screens.c index 2c1c0edba..395cd0e54 100644 --- a/src/Screens.c +++ b/src/Screens.c @@ -597,13 +597,10 @@ struct Screen* LoadingScreen_MakeInstance(const String* title, const String* mes s->VTABLE = &LoadingScreen_VTABLE; s->Progress = 0.0f; - String title_copy = String_FromArray(s->__TitleBuffer); - String_AppendString(&title_copy, title); - s->TitleStr = title_copy; - - String message_copy = String_FromArray(s->__MessageBuffer); - String_AppendString(&message_copy, message); - s->MessageStr = message_copy; + String_InitArray(s->TitleStr, s->__TitleBuffer); + String_AppendString(&s->TitleStr, title); + String_InitArray(s->MessageStr, s->__MessageBuffer); + String_AppendString(&s->MessageStr, message); s->HandlesAllInput = true; s->BlocksWorld = true; @@ -1540,13 +1537,10 @@ struct Screen* DisconnectScreen_MakeInstance(const String* title, const String* s->BlocksWorld = true; s->HidesHUD = true; - String title_copy = String_FromArray(s->__TitleBuffer); - String_AppendString(&title_copy, title); - s->TitleStr = title_copy; - - String message_copy = String_FromArray(s->__MessageBuffer); - String_AppendString(&message_copy, message); - s->MessageStr = message_copy; + String_InitArray(s->TitleStr, s->__TitleBuffer); + String_AppendString(&s->TitleStr, title); + String_InitArray(s->MessageStr, s->__MessageBuffer); + String_AppendString(&s->MessageStr, message); char whyBuffer[STRING_SIZE]; String why = String_FromArray(whyBuffer); diff --git a/src/String.h b/src/String.h index fbc2f9f79..8e4abe872 100644 --- a/src/String.h +++ b/src/String.h @@ -45,6 +45,8 @@ NOINLINE_ String String_FromReadonly(STRING_REF const char* buffer); #define String_FromRawArray(buffer) String_FromRaw(buffer, sizeof(buffer)) /* Constructs a string from a compile time array (leaving 1 byte of room for null terminator) */ #define String_NT_Array(buffer) { buffer, 0, (sizeof(buffer) - 1)} +/* Initialises a string from a compile time array. */ +#define String_InitArray(str, buffr) str.buffer = buffr; str.length = 0; str.capacity = sizeof(buffr); /* Removes all colour codes from the given string. */ NOINLINE_ void String_StripCols(String* str); diff --git a/src/TexturePack.c b/src/TexturePack.c index 1947d9d42..04c32e58c 100644 --- a/src/TexturePack.c +++ b/src/TexturePack.c @@ -204,7 +204,8 @@ static void EntryList_Load(struct EntryList* list) { char lineBuffer[FILENAME_SIZE]; String line = String_FromArray(lineBuffer); - struct Stream stream; + uint8_t buffer[2048]; + struct Stream stream, buffered; ReturnCode res; String_Format3(&path, "%c%r%c", list->Folder, &Directory_Separator, list->Filename); @@ -213,7 +214,6 @@ static void EntryList_Load(struct EntryList* list) { if (res) { Chat_LogError2(res, "opening", &path); return; } /* ReadLine reads single byte at a time */ - uint8_t buffer[2048]; struct Stream buffered; Stream_ReadonlyBuffered(&buffered, &stream, buffer, sizeof(buffer)); for (;;) { diff --git a/src/TexturePack.h b/src/TexturePack.h index 48e64e2d4..e4bdbaa0c 100644 --- a/src/TexturePack.h +++ b/src/TexturePack.h @@ -52,7 +52,7 @@ bool TextureCache_Has(const String* url); /* Attempts to get the cached data stream for the given url. */ bool TextureCache_Get(const String* url, struct Stream* stream); /* Attempts to get the Last-Modified header cached for the given URL. */ -/* If header is not found, returns last time the cached datastream was modified. */ +/* If header is not found, returns last time the cached data was modified. */ void TextureCache_GetLastModified(const String* url, TimeMS* time); /* Attempts to get the ETag header cached for the given URL. */ void TextureCache_GetETag(const String* url, String* etag); diff --git a/src/Widgets.c b/src/Widgets.c index ae6ce4cfd..35f40b584 100644 --- a/src/Widgets.c +++ b/src/Widgets.c @@ -117,7 +117,10 @@ static void ButtonWidget_Reposition(void* widget) { static void ButtonWidget_Render(void* widget, double delta) { struct ButtonWidget* w = widget; - struct Texture back = w->Active ? Button_SelectedTex : Button_ShadowTex; + struct Texture back; + PackedCol col; + + back = w->Active ? Button_SelectedTex : Button_ShadowTex; if (w->Disabled) back = Button_DisabledTex; back.ID = Game_UseClassicGui ? Gui_GuiClassicTex : Gui_GuiTex; @@ -147,7 +150,7 @@ static void ButtonWidget_Render(void* widget, double delta) { PackedCol disabledCol = PACKEDCOL_CONST(160, 160, 160, 255); if (!w->Texture.ID) return; - PackedCol col = w->Disabled ? disabledCol : (w->Active ? activeCol : normCol); + col = w->Disabled ? disabledCol : (w->Active ? activeCol : normCol); Texture_RenderShaded(&w->Texture, col); } @@ -503,13 +506,13 @@ static int Table_Height(struct TableWidget* w) { #define TABLE_MAX_VERTICES (8 * 10 * ISOMETRICDRAWER_MAXVERTICES) -static bool TableWidget_GetCoords(struct TableWidget* w, int i, int* winX, int* winY) { - int x = i % w->ElementsPerRow, y = i / w->ElementsPerRow; - *winX = w->X + w->BlockSize * x; - *winY = w->Y + w->BlockSize * y + 3; +static bool TableWidget_GetCoords(struct TableWidget* w, int i, int* cellX, int* cellY) { + int x, y; + x = i % w->ElementsPerRow; + y = i / w->ElementsPerRow - w->Scroll.ScrollY; - *winY -= w->Scroll.ScrollY * w->BlockSize; - y -= w->Scroll.ScrollY; + *cellX = w->X + w->BlockSize * x; + *cellY = w->Y + w->BlockSize * y + 3; return y >= 0 && y < TABLE_MAX_ROWS_DISPLAYED; } @@ -536,8 +539,10 @@ static void TableWidget_MoveCursorToSelected(struct TableWidget* w) { } static void TableWidget_MakeBlockDesc(String* desc, BlockID block) { + String name; if (Game_PureClassic) { String_AppendConst(desc, "Select block"); return; } - String name = Block_UNSAFE_GetName(block); + + name = Block_UNSAFE_GetName(block); String_AppendString(desc, &name); if (Game_ClassicMode) return; @@ -574,9 +579,9 @@ static void TableWidget_RecreateDescTex(struct TableWidget* w) { } void TableWidget_MakeDescTex(struct TableWidget* w, BlockID block) { + struct DrawTextArgs args; char descBuffer[STRING_SIZE * 2]; String desc = String_FromArray(descBuffer); - struct DrawTextArgs args; Gfx_DeleteTexture(&w->DescTex.ID); if (block == BLOCK_AIR) return; @@ -627,6 +632,9 @@ static void TableWidget_Init(void* widget) { static void TableWidget_Render(void* widget, double delta) { struct TableWidget* w = widget; + VertexP3fT2fC4b vertices[TABLE_MAX_VERTICES]; + int i, x, y; + /* These were sourced by taking a screenshot of vanilla Then using paint to extract the colour components Then using wolfram alpha to solve the glblendfunc equation */ @@ -644,8 +652,8 @@ static void TableWidget_Render(void* widget, double delta) { int blockSize = w->BlockSize; if (w->SelectedIndex != -1 && Game_ClassicMode) { - int x, y; TableWidget_GetCoords(w, w->SelectedIndex, &x, &y); + float off = blockSize * 0.1f; int size = (int)(blockSize + off * 2); GfxCommon_Draw2DGradient((int)(x - off), (int)(y - off), @@ -654,11 +662,8 @@ static void TableWidget_Render(void* widget, double delta) { Gfx_SetTexturing(true); Gfx_SetBatchFormat(VERTEX_FORMAT_P3FT2FC4B); - VertexP3fT2fC4b vertices[TABLE_MAX_VERTICES]; IsometricDrawer_BeginBatch(vertices, w->VB); - int i; for (i = 0; i < w->ElementsCount; i++) { - int x, y; if (!TableWidget_GetCoords(w, i, &x, &y)) continue; /* We want to always draw the selected block on top of others */ @@ -669,8 +674,8 @@ static void TableWidget_Render(void* widget, double delta) { i = w->SelectedIndex; if (i != -1) { - int x, y; TableWidget_GetCoords(w, i, &x, &y); + IsometricDrawer_DrawBatch(w->Elements[i], (blockSize + w->SelBlockExpand) * 0.7f / 2.0f, x + blockSize / 2, y + blockSize / 2); @@ -872,13 +877,13 @@ static void InputWidget_FormatLine(struct InputWidget* w, int i, String* line) { } static void InputWidget_CalculateLineSizes(struct InputWidget* w) { - char lineBuffer[STRING_SIZE]; - String line = String_FromArray(lineBuffer); - struct DrawTextArgs args; Size2D size; int y; + char lineBuffer[STRING_SIZE]; + String line = String_FromArray(lineBuffer); + for (y = 0; y < INPUTWIDGET_MAX_LINES; y++) { w->LineSizes[y] = Size2D_Empty; } @@ -1042,14 +1047,16 @@ static bool InputWidget_CheckCol(struct InputWidget* w, int index) { } static void InputWidget_BackspaceKey(struct InputWidget* w) { + int i, len; + if (InputWidget_ControlDown()) { if (w->CaretPos == -1) { w->CaretPos = w->Text.length - 1; } - int len = WordWrap_GetBackLength(&w->Text, w->CaretPos); + len = WordWrap_GetBackLength(&w->Text, w->CaretPos); if (!len) return; w->CaretPos -= len; if (w->CaretPos < 0) { w->CaretPos = 0; } - int i; + for (i = 0; i <= len; i++) { String_DeleteAt(&w->Text, w->CaretPos); } @@ -1214,10 +1221,12 @@ static bool InputWidget_KeyPress(void* widget, char keyChar) { static bool InputWidget_MouseDown(void* widget, int x, int y, MouseButton button) { struct InputWidget* w = widget; + struct DrawTextArgs args; + if (button != MouseButton_Left) return true; x -= w->InputTex.X; y -= w->InputTex.Y; - struct DrawTextArgs args; DrawTextArgs_MakeEmpty(&args, &w->Font, true); + DrawTextArgs_MakeEmpty(&args, &w->Font, true); int offset = 0, charHeight = w->CaretTex.Height; char lineBuffer[STRING_SIZE]; @@ -1399,7 +1408,7 @@ struct MenuInputValidator MenuInputValidator_Path(void) { struct MenuInputValidator MenuInputValidator_Enum(const char** names, int namesCount) { struct MenuInputValidator v; - v.VTABLE = NULL; + v.VTABLE = NULL; v.Meta._Enum.Names = names; v.Meta._Enum.Count = namesCount; return v; @@ -1444,14 +1453,18 @@ static void MenuInputWidget_Render(void* widget, double delta) { static void MenuInputWidget_RemakeTexture(void* widget) { struct MenuInputWidget* w = widget; + struct MenuInputValidator* v; struct DrawTextArgs args; + Size2D size; + Bitmap bmp; + DrawTextArgs_Make(&args, &w->Base.Lines[0], &w->Base.Font, false); - Size2D size = Drawer2D_MeasureText(&args); + size = Drawer2D_MeasureText(&args); w->Base.CaretAccumulator = 0.0; char rangeBuffer[STRING_SIZE]; String range = String_FromArray(rangeBuffer); - struct MenuInputValidator* v = &w->Validator; + v = &w->Validator; v->VTABLE->GetRange(v, &range); /* Ensure we don't have 0 text height */ @@ -1465,7 +1478,7 @@ static void MenuInputWidget_RemakeTexture(void* widget) { w->Base.Height = max(size.Height, w->MinHeight); Size2D adjSize = size; adjSize.Width = w->Base.Width; - Bitmap bmp; Bitmap_AllocateClearedPow2(&bmp, adjSize.Width, adjSize.Height); + Bitmap_AllocateClearedPow2(&bmp, adjSize.Width, adjSize.Height); { Drawer2D_DrawText(&bmp, &args, w->Base.Padding, 0); @@ -1491,13 +1504,14 @@ static void MenuInputWidget_RemakeTexture(void* widget) { static bool MenuInputWidget_AllowedChar(void* widget, char c) { struct InputWidget* w = widget; struct MenuInputValidator* v; + int maxChars; bool valid; if (c == '&') return false; v = &((struct MenuInputWidget*)w)->Validator; if (!v->VTABLE->IsValidChar(v, c)) return false; - int maxChars = w->GetMaxLines() * INPUTWIDGET_LEN; + maxChars = w->GetMaxLines() * INPUTWIDGET_LEN; if (w->Text.length == maxChars) return false; /* See if the new string is in valid format */ @@ -1524,8 +1538,7 @@ void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, co w->Base.ConvertPercents = false; w->Base.Padding = 3; - String inputStr = String_FromArray(w->__TextBuffer); - w->Base.Text = inputStr; + String_InitArray(w->Base.Text, w->__TextBuffer); w->Base.GetMaxLines = MenuInputWidget_GetMaxLines; w->Base.RemakeTexture = MenuInputWidget_RemakeTexture; @@ -1541,19 +1554,21 @@ void MenuInputWidget_Create(struct MenuInputWidget* w, int width, int height, co *#########################################################################################################################*/ static void ChatInputWidget_RemakeTexture(void* widget) { struct InputWidget* w = widget; - int totalHeight = 0, maxWidth = 0, i; + struct DrawTextArgs args; + Size2D size = { 0, 0 }; + Bitmap bmp; + int i; w->CaretAccumulator = 0; for (i = 0; i < w->GetMaxLines(); i++) { - totalHeight += w->LineSizes[i].Height; - maxWidth = max(maxWidth, w->LineSizes[i].Width); + size.Height += w->LineSizes[i].Height; + size.Width = max(size.Width, w->LineSizes[i].Width); } - Size2D size = { maxWidth, totalHeight }; int realHeight = 0; - Bitmap bmp; Bitmap_AllocateClearedPow2(&bmp, size.Width, size.Height); + Bitmap_AllocateClearedPow2(&bmp, size.Width, size.Height); - struct DrawTextArgs args; DrawTextArgs_MakeEmpty(&args, &w->Font, true); + DrawTextArgs_MakeEmpty(&args, &w->Font, true); if (w->Prefix.length) { args.Text = w->Prefix; Drawer2D_DrawText(&bmp, &args, 0, 0); @@ -1566,7 +1581,7 @@ static void ChatInputWidget_RemakeTexture(void* widget) { if (!w->Lines[i].length) break; line.length = 0; - /* Colour code goes to next line */ + /* Colour code continues in next line */ char lastCol = InputWidget_GetLastCol(w, 0, i); if (!Drawer2D_IsWhiteCol(lastCol)) { String_Append(&line, '&'); String_Append(&line, lastCol); @@ -1632,8 +1647,11 @@ static void ChatInputWidget_OnPressedEnter(void* widget) { static void ChatInputWidget_UpKey(struct InputWidget* w) { struct ChatInputWidget* W = (struct ChatInputWidget*)w; + String prevInput; + int pos; + if (InputWidget_ControlDown()) { - int pos = w->CaretPos == -1 ? w->Text.length : w->CaretPos; + pos = w->CaretPos == -1 ? w->Text.length : w->CaretPos; if (pos < INPUTWIDGET_LEN) return; w->CaretPos = pos - INPUTWIDGET_LEN; @@ -1650,7 +1668,7 @@ static void ChatInputWidget_UpKey(struct InputWidget* w) { w->Text.length = 0; if (W->TypingLogPos < 0) W->TypingLogPos = 0; - String prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, W->TypingLogPos); + prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, W->TypingLogPos); String_AppendString(&w->Text, &prevInput); w->CaretPos = -1; @@ -1659,8 +1677,11 @@ static void ChatInputWidget_UpKey(struct InputWidget* w) { static void ChatInputWidget_DownKey(struct InputWidget* w) { struct ChatInputWidget* W = (struct ChatInputWidget*)w; + String prevInput; + int lines; + if (InputWidget_ControlDown()) { - int lines = w->GetMaxLines(); + lines = w->GetMaxLines(); if (w->CaretPos == -1 || w->CaretPos >= (lines - 1) * INPUTWIDGET_LEN) return; w->CaretPos += INPUTWIDGET_LEN; @@ -1676,7 +1697,7 @@ static void ChatInputWidget_DownKey(struct InputWidget* w) { W->TypingLogPos = Chat_InputLog.Count; String_AppendString(&w->Text, &W->OrigStr); } else { - String prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, W->TypingLogPos); + prevInput = StringsBuffer_UNSAFE_Get(&Chat_InputLog, W->TypingLogPos); String_AppendString(&w->Text, &prevInput); } @@ -1690,18 +1711,18 @@ static bool ChatInputWidget_IsNameChar(char c) { } static void ChatInputWidget_TabKey(struct InputWidget* w) { + EntityID matches[TABLIST_MAX_NAMES]; + String part, match; int end = w->CaretPos == -1 ? w->Text.length - 1 : w->CaretPos; - int start = end; + int beg = end; char* buffer = w->Text.buffer; - while (start >= 0 && ChatInputWidget_IsNameChar(buffer[start])) { start--; } - start++; - if (end < 0 || start > end) return; + while (beg >= 0 && ChatInputWidget_IsNameChar(buffer[beg])) { beg--; } + beg++; + if (end < 0 || beg > end) return; - String part = String_UNSAFE_Substring(&w->Text, start, (end + 1) - start); + part = String_UNSAFE_Substring(&w->Text, beg, (end + 1) - beg); Chat_AddOf(&String_Empty, MSG_TYPE_CLIENTSTATUS_3); - - EntityID matches[TABLIST_MAX_NAMES]; int i, matchesCount = 0; for (i = 0; i < TABLIST_MAX_NAMES; i++) { @@ -1715,13 +1736,13 @@ static void ChatInputWidget_TabKey(struct InputWidget* w) { if (matchesCount == 1) { if (w->CaretPos == -1) end++; - int len = end - start, j; + int len = end - beg, j; for (j = 0; j < len; j++) { - String_DeleteAt(&w->Text, start); + String_DeleteAt(&w->Text, beg); } if (w->CaretPos != -1) w->CaretPos -= len; - String match = TabList_UNSAFE_GetPlayer(matches[0]); + match = TabList_UNSAFE_GetPlayer(matches[0]); InputWidget_AppendString(w, &match); } else if (matchesCount > 1) { char strBuffer[STRING_SIZE]; @@ -1729,7 +1750,7 @@ static void ChatInputWidget_TabKey(struct InputWidget* w) { String_Format1(&str, "&e%i matching names: ", &matchesCount); for (i = 0; i < matchesCount; i++) { - String match = TabList_UNSAFE_GetPlayer(matches[i]); + match = TabList_UNSAFE_GetPlayer(matches[i]); if ((str.length + match.length + 1) > STRING_SIZE) break; String_AppendString(&str, &match); @@ -1771,10 +1792,8 @@ void ChatInputWidget_Create(struct ChatInputWidget* w, const FontDesc* font) { w->Base.RemakeTexture = ChatInputWidget_RemakeTexture; w->Base.OnPressedEnter = ChatInputWidget_OnPressedEnter; - String inputStr = String_FromArray(w->__TextBuffer); - w->Base.Text = inputStr; - String origStr = String_FromArray(w->__OrigBuffer); - w->OrigStr = origStr; + String_InitArray(w->Base.Text, w->__TextBuffer); + String_InitArray(w->OrigStr, w->__OrigBuffer); } @@ -1827,40 +1846,41 @@ void PlayerListWidget_GetNameUnder(struct PlayerListWidget* w, int x, int y, Str static void PlayerListWidget_UpdateTableDimensions(struct PlayerListWidget* w) { int width = w->XMax - w->XMin, height = w->YHeight; - w->X = (w->XMin ) - LIST_BOUNDS_SIZE; + w->X = (w->XMin ) - LIST_BOUNDS_SIZE; w->Y = (Game_Height / 2 - height / 2) - LIST_BOUNDS_SIZE; w->Width = width + LIST_BOUNDS_SIZE * 2; w->Height = height + LIST_BOUNDS_SIZE * 2; } static int PlayerListWidget_GetColumnWidth(struct PlayerListWidget* w, int column) { - int i = column * LIST_NAMES_PER_COLUMN; + int i = column * LIST_NAMES_PER_COLUMN; + int end = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); int maxWidth = 0; - int maxIndex = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); - for (; i < maxIndex; i++) { + for (; i < end; i++) { maxWidth = max(maxWidth, w->Textures[i].Width); } return maxWidth + LIST_COLUMN_PADDING + w->ElementOffset; } static int PlayerListWidget_GetColumnHeight(struct PlayerListWidget* w, int column) { - int i = column * LIST_NAMES_PER_COLUMN; - int total = 0; - int maxIndex = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); + int i = column * LIST_NAMES_PER_COLUMN; + int end = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); + int height = 0; - for (; i < maxIndex; i++) { - total += w->Textures[i].Height + 1; + for (; i < end; i++) { + height += w->Textures[i].Height + 1; } - return total; + return height; } static void PlayerListWidget_SetColumnPos(struct PlayerListWidget* w, int column, int x, int y) { - int i = column * LIST_NAMES_PER_COLUMN; - int maxIndex = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); + struct Texture tex; + int i = column * LIST_NAMES_PER_COLUMN; + int end = min(w->NamesCount, i + LIST_NAMES_PER_COLUMN); - for (; i < maxIndex; i++) { - struct Texture tex = w->Textures[i]; + for (; i < end; i++) { + tex = w->Textures[i]; tex.X = x; tex.Y = y - 10; y += tex.Height + 1; @@ -1909,11 +1929,12 @@ static void PlayerListWidget_Reposition(void* widget) { } static void PlayerListWidget_AddName(struct PlayerListWidget* w, EntityID id, int index) { + String name; /* insert at end of list */ if (index == -1) { index = w->NamesCount; w->NamesCount++; } - String name = TabList_UNSAFE_GetList(id); - w->IDs[index] = id; + name = TabList_UNSAFE_GetList(id); + w->IDs[index] = id; PlayerListWidget_DrawName(&w->Textures[index], w, &name); } @@ -1950,11 +1971,12 @@ static void PlayerListWidget_AddGroup(struct PlayerListWidget* w, int id, int* i static int PlayerListWidget_GetGroupCount(struct PlayerListWidget* w, int id, int i) { String group = TabList_UNSAFE_GetGroup(id); + String curGroup; int count = 0; for (; i < w->NamesCount; i++, count++) { - String curGroup = TabList_UNSAFE_GetGroup(w->IDs[i]); - if (!String_CaselessEquals(&group, &curGroup)) return count; + curGroup = TabList_UNSAFE_GetGroup(w->IDs[i]); + if (!String_CaselessEquals(&group, &curGroup)) break; } return count; } @@ -2089,8 +2111,8 @@ static void PlayerListWidget_Init(void* widget) { } PlayerListWidget_SortAndReposition(w); - TextWidget_Create(&w->Overview, &title, &w->Font); - Widget_SetLocation(&w->Overview, ANCHOR_CENTRE, ANCHOR_MIN, 0, 0); + TextWidget_Create(&w->Title, &title, &w->Font); + Widget_SetLocation(&w->Title, ANCHOR_CENTRE, ANCHOR_MIN, 0, 0); Event_RegisterInt(&TabListEvents_Added, w, PlayerListWidget_TabEntryAdded); Event_RegisterInt(&TabListEvents_Changed, w, PlayerListWidget_TabEntryChanged); @@ -2099,26 +2121,29 @@ static void PlayerListWidget_Init(void* widget) { static void PlayerListWidget_Render(void* widget, double delta) { struct PlayerListWidget* w = widget; - struct TextWidget* overview = &w->Overview; - PackedCol topCol = PACKEDCOL_CONST(0, 0, 0, 180); + struct TextWidget* title = &w->Title; + struct Texture tex; + int offset, height; + int i, selectedI; + PackedCol topCol = PACKEDCOL_CONST( 0, 0, 0, 180); PackedCol bottomCol = PACKEDCOL_CONST(50, 50, 50, 205); Gfx_SetTexturing(false); - int offset = overview->Height + 10; - int height = max(300, w->Height + overview->Height); + offset = title->Height + 10; + height = max(300, w->Height + title->Height); GfxCommon_Draw2DGradient(w->X, w->Y - offset, w->Width, height, topCol, bottomCol); Gfx_SetTexturing(true); - overview->YOffset = w->Y - offset + 5; - Widget_Reposition(overview); - Elem_Render(overview, delta); + title->YOffset = w->Y - offset + 5; + Widget_Reposition(title); + Elem_Render(title, delta); - int i, highlightedI = PlayerListWidget_HighlightedName(w, Mouse_X, Mouse_Y); + selectedI = PlayerListWidget_HighlightedName(w, Mouse_X, Mouse_Y); for (i = 0; i < w->NamesCount; i++) { if (!w->Textures[i].ID) continue; - struct Texture tex = w->Textures[i]; - if (i == highlightedI) tex.X += 4; + tex = w->Textures[i]; + if (i == selectedI) tex.X += 4; Texture_Render(&tex); } } @@ -2130,7 +2155,7 @@ static void PlayerListWidget_Free(void* widget) { Gfx_DeleteTexture(&w->Textures[i].ID); } - Elem_TryFree(&w->Overview); + Elem_TryFree(&w->Title); Event_UnregisterInt(&TabListEvents_Added, w, PlayerListWidget_TabEntryAdded); Event_UnregisterInt(&TabListEvents_Changed, w, PlayerListWidget_TabEntryChanged); Event_UnregisterInt(&TabListEvents_Removed, w, PlayerListWidget_TabEntryRemoved); @@ -2160,8 +2185,8 @@ void PlayerListWidget_Create(struct PlayerListWidget* w, const FontDesc* font, b *#########################################################################################################################*/ #define TextGroupWidget_LineBuffer(w, i) ((w)->Buffer + (i) * TEXTGROUPWIDGET_LEN) String TextGroupWidget_UNSAFE_Get(struct TextGroupWidget* w, int i) { - int length = w->LineLengths[i]; - return String_Init(TextGroupWidget_LineBuffer(w, i), length, length); + int len = w->LineLengths[i]; + return String_Init(TextGroupWidget_LineBuffer(w, i), len, len); } void TextGroupWidget_GetText(struct TextGroupWidget* w, int index, String* text) { @@ -2170,9 +2195,11 @@ void TextGroupWidget_GetText(struct TextGroupWidget* w, int index, String* text) } void TextGroupWidget_PushUpAndReplaceLast(struct TextGroupWidget* w, const String* text) { - int y = w->Y; + int max_index; + int i, y = w->Y; + Gfx_DeleteTexture(&w->Textures[0].ID); - int i, max_index = w->LinesCount - 1; + max_index = w->LinesCount - 1; /* Move contents of X line to X - 1 line */ for (i = 0; i < max_index; i++) { @@ -2276,13 +2303,15 @@ struct Portion { int16_t Beg, Len, LineBeg, LineLen; }; #define TEXTGROUPWIDGET_PACKED_LEN 0x7FFF static int TextGroupWidget_NextUrl(char* chars, int charsLen, int i) { + int start, left; + for (; i < charsLen; i++) { if (!(chars[i] == 'h' || chars[i] == '&')) continue; - int left = charsLen - i; + left = charsLen - i; if (left < TEXTGROUPWIDGET_HTTP_LEN) return charsLen; /* colour codes at start of URL */ - int start = i; + start = i; while (left >= 2 && chars[i] == '&') { left -= 2; i += 2; } if (left < TEXTGROUPWIDGET_HTTP_LEN) continue; @@ -2299,9 +2328,12 @@ static int TextGroupWidget_NextUrl(char* chars, int charsLen, int i) { static int TextGroupWidget_UrlEnd(char* chars, int charsLen, int32_t* begs, int begsLen, int i) { int start = i, j; + int next, left; + bool isBeg; + for (; i < charsLen && chars[i] != ' '; i++) { /* Is this character the start of a line */ - bool isBeg = false; + isBeg = false; for (j = 0; j < begsLen; j++) { if (i == begs[j]) { isBeg = true; break; } } @@ -2311,7 +2343,7 @@ static int TextGroupWidget_UrlEnd(char* chars, int charsLen, int32_t* begs, int if (chars[i] != '>') break; /* Does this line start with "> ", making it a multiline */ - int next = i + 1, left = charsLen - next; + next = i + 1; left = charsLen - next; while (left >= 2 && chars[next] == '&') { left -= 2; next += 2; } if (left == 0 || chars[next] != ' ') break; @@ -2321,7 +2353,10 @@ static int TextGroupWidget_UrlEnd(char* chars, int charsLen, int32_t* begs, int } static void TextGroupWidget_Output(struct Portion bit, int lineBeg, int lineEnd, struct Portion** portions) { + struct Portion* cur; + int overBy, underBy; if (bit.Beg >= lineEnd || !bit.Len) return; + bit.LineBeg = bit.Beg; bit.LineLen = bit.Len & TEXTGROUPWIDGET_PACKED_LEN; @@ -2329,18 +2364,18 @@ static void TextGroupWidget_Output(struct Portion bit, int lineBeg, int lineEnd, if (bit.Beg >= lineBeg) { } else if (bit.Beg + bit.LineLen > lineBeg) { /* Adjust start of portion to be within this line */ - int underBy = lineBeg - bit.Beg; + underBy = lineBeg - bit.Beg; bit.LineBeg += underBy; bit.LineLen -= underBy; } else { return; } /* Limit length of portion to be within this line */ - int overBy = (bit.LineBeg + bit.LineLen) - lineEnd; + overBy = (bit.LineBeg + bit.LineLen) - lineEnd; if (overBy > 0) bit.LineLen -= overBy; bit.LineBeg -= lineBeg; if (!bit.LineLen) return; - struct Portion* cur = *portions; *cur++ = bit; *portions = cur; + cur = *portions; *cur++ = bit; *portions = cur; } static int TextGroupWidget_Reduce(struct TextGroupWidget* w, char* chars, int target, struct Portion* portions) { @@ -2348,20 +2383,22 @@ static int TextGroupWidget_Reduce(struct TextGroupWidget* w, char* chars, int ta int32_t begs[TEXTGROUPWIDGET_MAX_LINES]; int32_t ends[TEXTGROUPWIDGET_MAX_LINES]; struct Portion bit; - int i, total = 0, end = 0; + int len, nextStart; + int i, total = 0, end; for (i = 0; i < w->LinesCount; i++) { - int lineLen = w->LineLengths[i]; + len = w->LineLengths[i]; begs[i] = -1; ends[i] = -1; - if (!lineLen) continue; + if (!len) continue; begs[i] = total; - Mem_Copy(&chars[total], TextGroupWidget_LineBuffer(w, i), lineLen); - total += lineLen; ends[i] = total; + Mem_Copy(&chars[total], TextGroupWidget_LineBuffer(w, i), len); + total += len; ends[i] = total; } + end = 0; for (;;) { - int nextStart = TextGroupWidget_NextUrl(chars, total, end); + nextStart = TextGroupWidget_NextUrl(chars, total, end); /* add normal portion between urls */ bit.Beg = end; @@ -2397,25 +2434,28 @@ static void TextGroupWidget_FormatUrl(String* text, const String* url) { static bool TextGroupWidget_GetUrl(struct TextGroupWidget* w, String* text, int index, int mouseX) { char chars[TEXTGROUPWIDGET_MAX_LINES * TEXTGROUPWIDGET_LEN]; struct Portion portions[2 * (TEXTGROUPWIDGET_LEN / TEXTGROUPWIDGET_HTTP_LEN)]; + struct Portion bit; struct DrawTextArgs args = { 0 }; - String line; + String line, url; + int portionsCount; + int i, x, width; mouseX -= w->Textures[index].X; args.UseShadow = true; line = TextGroupWidget_UNSAFE_Get(w, index); if (Game_ClassicMode) return false; - int i, x, portionsCount = TextGroupWidget_Reduce(w, chars, index, portions); + portionsCount = TextGroupWidget_Reduce(w, chars, index, portions); for (i = 0, x = 0; i < portionsCount; i++) { - struct Portion bit = portions[i]; + bit = portions[i]; args.Text = String_UNSAFE_Substring(&line, bit.LineBeg, bit.LineLen); args.Font = (bit.Len & TEXTGROUPWIDGET_URL) ? w->UnderlineFont : w->Font; - int width = Drawer2D_MeasureText(&args).Width; + width = Drawer2D_MeasureText(&args).Width; if ((bit.Len & TEXTGROUPWIDGET_URL) && mouseX >= x && mouseX < x + width) { bit.Len &= TEXTGROUPWIDGET_PACKED_LEN; - String url = String_Init(&chars[bit.Beg], bit.Len, bit.Len); + url = String_Init(&chars[bit.Beg], bit.Len, bit.Len); TextGroupWidget_FormatUrl(text, &url); return true; @@ -2460,33 +2500,38 @@ static bool TextGroupWidget_MightHaveUrls(struct TextGroupWidget* w) { static void TextGroupWidget_DrawAdvanced(struct TextGroupWidget* w, struct Texture* tex, struct DrawTextArgs* args, int index, const String* text) { char chars[TEXTGROUPWIDGET_MAX_LINES * TEXTGROUPWIDGET_LEN]; struct Portion portions[2 * (TEXTGROUPWIDGET_LEN / TEXTGROUPWIDGET_HTTP_LEN)]; - int i, x, portionsCount = TextGroupWidget_Reduce(w, chars, index, portions); - - Size2D total = { 0, 0 }; + struct Portion bit; + Size2D size = { 0, 0 }; Size2D partSizes[Array_Elems(portions)]; Bitmap bmp; + int portionsCount; + int i, x; + portionsCount = TextGroupWidget_Reduce(w, chars, index, portions); for (i = 0; i < portionsCount; i++) { - struct Portion bit = portions[i]; + bit = portions[i]; + args->Text = String_UNSAFE_Substring(text, bit.LineBeg, bit.LineLen); args->Font = (bit.Len & TEXTGROUPWIDGET_URL) ? w->UnderlineFont : w->Font; partSizes[i] = Drawer2D_MeasureText(args); - total.Height = max(partSizes[i].Height, total.Height); - total.Width += partSizes[i].Width; + size.Height = max(partSizes[i].Height, size.Height); + size.Width += partSizes[i].Width; } - Bitmap_AllocateClearedPow2(&bmp, total.Width, total.Height); + Bitmap_AllocateClearedPow2(&bmp, size.Width, size.Height); { - for (i = 0, x = 0; i < portionsCount; i++) { - struct Portion bit = portions[i]; + x = 0; + for (i = 0; i < portionsCount; i++) { + bit = portions[i]; + args->Text = String_UNSAFE_Substring(text, bit.LineBeg, bit.LineLen); args->Font = (bit.Len & TEXTGROUPWIDGET_URL) ? w->UnderlineFont : w->Font; Drawer2D_DrawText(&bmp, args, x, 0); x += partSizes[i].Width; } - Drawer2D_Make2DTexture(tex, &bmp, total, 0, 0); + Drawer2D_Make2DTexture(tex, &bmp, size, 0, 0); } Mem_Free(bmp.Scan0); } diff --git a/src/Widgets.h b/src/Widgets.h index 39989e055..e41a70d2a 100644 --- a/src/Widgets.h +++ b/src/Widgets.h @@ -183,7 +183,7 @@ struct PlayerListWidget { int NamesCount, ElementOffset; int XMin, XMax, YHeight; bool Classic; - struct TextWidget Overview; + struct TextWidget Title; uint16_t IDs[TABLIST_MAX_NAMES * 2]; struct Texture Textures[TABLIST_MAX_NAMES * 2]; };