diff --git a/ClassicalSharp/2D/Screens/Menu/ListScreen.cs b/ClassicalSharp/2D/Screens/Menu/ListScreen.cs
index 17cbc9639..6b4bfe86b 100644
--- a/ClassicalSharp/2D/Screens/Menu/ListScreen.cs
+++ b/ClassicalSharp/2D/Screens/Menu/ListScreen.cs
@@ -68,8 +68,10 @@ namespace ClassicalSharp.Gui.Screens {
ButtonWidget MakeText(int i) {
string text = Get(currentIndex + i);
- return ButtonWidget.Create(game, 300, text, font, TextButtonClick)
+ ButtonWidget btn = ButtonWidget.Create(game, 300, "", font, TextButtonClick)
.SetLocation(Anchor.Centre, Anchor.Centre, 0, (i - 2) * 50);
+ UpdateText(btn, text);
+ return btn;
}
ButtonWidget Make(int x, string text, ClickHandler onClick) {
@@ -89,11 +91,15 @@ namespace ClassicalSharp.Gui.Screens {
currentIndex = index;
for (int i = 0; i < items; i++) {
- ((ButtonWidget)widgets[i]).SetText(Get(currentIndex + i));
+ UpdateText((ButtonWidget)widgets[i], Get(currentIndex + i));
}
UpdateArrows();
}
+ protected virtual void UpdateText(ButtonWidget widget, string text) {
+ widget.SetText(text);
+ }
+
void UpdateArrows() {
widgets[5].Disabled = false;
widgets[6].Disabled = false;
diff --git a/ClassicalSharp/ClassicalSharp.csproj b/ClassicalSharp/ClassicalSharp.csproj
index 0dc44be2c..d2b4397c8 100644
--- a/ClassicalSharp/ClassicalSharp.csproj
+++ b/ClassicalSharp/ClassicalSharp.csproj
@@ -257,7 +257,6 @@
-
diff --git a/ClassicalSharp/Platform/Font.cs b/ClassicalSharp/Platform/Font.cs
deleted file mode 100644
index 57b9d1c09..000000000
--- a/ClassicalSharp/Platform/Font.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
-#if ANDROID
-using System;
-
-namespace ClassicalSharp {
-
- // TODO: Actually apply this to the text
- public class Font : IDisposable {
-
- public int Size;
-
- public FontStyle Style;
-
- public Font(string name, int size, FontStyle style) {
- Size = size;
- Style = style;
- }
-
- public Font(Font font, FontStyle style) {
- Size = font.Size;
- Style = style;
- }
-
- public Font(string name, int size) {
- Size = size;
- Style = FontStyle.Regular;
- }
-
- void IDisposable.Dispose() {
- }
- }
-
- public enum FontStyle {
- Regular,
- Italic,
- Bold,
- Underline,
- }
-}
-#endif
\ No newline at end of file
diff --git a/src/Client/AsyncDownloader.c b/src/Client/AsyncDownloader.c
index 439e80e37..f4e9fdef5 100644
--- a/src/Client/AsyncDownloader.c
+++ b/src/Client/AsyncDownloader.c
@@ -96,10 +96,10 @@ static void AsyncDownloader_Add(String* url, bool priority, String* id, UInt8 ty
Platform_Log2("Adding %s (type %b)", &reqUrl, &type);
- if (lastModified != NULL) {
+ if (lastModified) {
req.LastModified = *lastModified;
}
- if (etag != NULL) {
+ if (etag) {
String reqEtag = String_FromEmptyArray(req.Etag); String_Set(&reqEtag, etag);
}
//request.Data = data; TODO: Implement this. do we need to copy or expect caller to malloc it?
@@ -206,7 +206,7 @@ bool AsyncDownloader_GetCurrent(struct AsyncRequest* request, Int32* progress) {
*progress = async_curProgress;
}
Platform_MutexUnlock(async_curRequestMutex);
- return request->ID[0] != NULL;
+ return request->ID[0];
}
static void AsyncDownloader_ProcessRequest(struct AsyncRequest* request) {
diff --git a/src/Client/BlockPhysics.c b/src/Client/BlockPhysics.c
index e4fe93faf..4fc9131f6 100644
--- a/src/Client/BlockPhysics.c
+++ b/src/Client/BlockPhysics.c
@@ -8,7 +8,7 @@
#include "Block.h"
#include "Lighting.h"
#include "Options.h"
-#include "TreeGen.h"
+#include "MapGenerator.h"
#include "Platform.h"
#include "Game.h"
#include "ErrorHandler.h"
@@ -121,7 +121,7 @@ void Physics_SetEnabled(bool enabled) {
static void Physics_Activate(Int32 index) {
BlockID block = World_Blocks[index];
PhysicsHandler activate = Physics_OnActivate[block];
- if (activate != NULL) activate(index, block);
+ if (activate) activate(index, block);
}
static void Physics_ActivateNeighbours(Int32 x, Int32 y, Int32 z, Int32 index) {
@@ -153,10 +153,10 @@ static void Physics_BlockChanged(void* obj, Vector3I p, BlockID oldBlock, BlockI
if (block == BLOCK_AIR) {
PhysicsHandler deleteHandler = Physics_OnDelete[oldBlock];
- if (deleteHandler != NULL) deleteHandler(index, oldBlock);
+ if (deleteHandler) deleteHandler(index, oldBlock);
} else {
PhysicsHandler placeHandler = Physics_OnPlace[block];
- if (placeHandler != NULL) placeHandler(index, block);
+ if (placeHandler) placeHandler(index, block);
}
Physics_ActivateNeighbours(p.X, p.Y, p.Z, index);
}
@@ -176,17 +176,17 @@ static void Physics_TickRandomBlocks(void) {
Int32 index = Random_Range(&physics_rnd, lo, hi);
BlockID block = World_Blocks[index];
PhysicsHandler tick = Physics_OnRandomTick[block];
- if (tick != NULL) tick(index, block);
+ if (tick) tick(index, block);
index = Random_Range(&physics_rnd, lo, hi);
block = World_Blocks[index];
tick = Physics_OnRandomTick[block];
- if (tick != NULL) tick(index, block);
+ if (tick) tick(index, block);
index = Random_Range(&physics_rnd, lo, hi);
block = World_Blocks[index];
tick = Physics_OnRandomTick[block];
- if (tick != NULL) tick(index, block);
+ if (tick) tick(index, block);
}
}
}
diff --git a/src/Client/Chat.c b/src/Client/Chat.c
index 8af1c66ff..c27f92ad2 100644
--- a/src/Client/Chat.c
+++ b/src/Client/Chat.c
@@ -201,7 +201,7 @@ static struct ChatCommand* Commands_GetMatch(STRING_PURE String* cmdName) {
String name = String_FromReadonly(cmd->Name);
if (!String_CaselessStarts(&name, cmdName)) continue;
- if (match != NULL) {
+ if (match) {
Commands_Log("&e/client: Multiple commands found that start with: \"&f%s&e\".", cmdName);
return NULL;
}
diff --git a/src/Client/ChunkUpdater.c b/src/Client/ChunkUpdater.c
index e499c33d0..32a358e18 100644
--- a/src/Client/ChunkUpdater.c
+++ b/src/Client/ChunkUpdater.c
@@ -122,7 +122,7 @@ static void ChunkUpdater_PerformAllocations(void) {
void ChunkUpdater_Refresh(void) {
ChunkUpdater_ChunkPos = Vector3I_MaxValue();
- if (MapRenderer_Chunks != NULL && World_Blocks != NULL) {
+ if (MapRenderer_Chunks && World_Blocks) {
ChunkUpdater_ClearChunkCache();
ChunkUpdater_ResetChunkCache();
@@ -355,7 +355,7 @@ void ChunkUpdater_DeleteChunk(struct ChunkInfo* info) {
#endif
Int32 i;
- if (info->NormalParts != NULL) {
+ if (info->NormalParts) {
struct ChunkPartInfo* ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset < 0) continue;
@@ -367,7 +367,7 @@ void ChunkUpdater_DeleteChunk(struct ChunkInfo* info) {
info->NormalParts = NULL;
}
- if (info->TranslucentParts != NULL) {
+ if (info->TranslucentParts) {
struct ChunkPartInfo* ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset < 0) continue;
@@ -392,14 +392,14 @@ void ChunkUpdater_BuildChunk(struct ChunkInfo* info, Int32* chunkUpdates) {
}
Int32 i;
- if (info->NormalParts != NULL) {
+ if (info->NormalParts) {
struct ChunkPartInfo* ptr = info->NormalParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_NormalPartsCount[i]++; }
}
}
- if (info->TranslucentParts != NULL) {
+ if (info->TranslucentParts) {
struct ChunkPartInfo* ptr = info->TranslucentParts;
for (i = 0; i < MapRenderer_1DUsedCount; i++, ptr += MapRenderer_ChunksCount) {
if (ptr->Offset >= 0) { MapRenderer_TranslucentPartsCount[i]++; }
diff --git a/src/Client/Client.vcxproj b/src/Client/Client.vcxproj
index d18b37157..796b8041e 100644
--- a/src/Client/Client.vcxproj
+++ b/src/Client/Client.vcxproj
@@ -232,7 +232,6 @@
-
@@ -241,7 +240,6 @@
-
@@ -296,12 +294,11 @@
-
-
+
@@ -314,7 +311,6 @@
-
diff --git a/src/Client/Client.vcxproj.filters b/src/Client/Client.vcxproj.filters
index 32ba46929..8711eee04 100644
--- a/src/Client/Client.vcxproj.filters
+++ b/src/Client/Client.vcxproj.filters
@@ -144,9 +144,6 @@
-
- Header Files\Generator
-
Header Files\Defines
@@ -258,9 +255,6 @@
Header Files\SelectionBox
-
- Header Files\Generator
-
Header Files\2D
@@ -365,9 +359,6 @@
-
- Source Files\Generator
-
Source Files\Platform
@@ -440,9 +431,6 @@
Source Files\SelectionBox
-
- Source Files\Generator
-
Source Files\2D
@@ -572,10 +560,10 @@
Source Files\Platform
-
+
Source Files\Platform
-
+
Source Files\Platform
diff --git a/src/Client/Entity.c b/src/Client/Entity.c
index ed6db1dd6..33ef0c1d5 100644
--- a/src/Client/Entity.c
+++ b/src/Client/Entity.c
@@ -344,7 +344,7 @@ void Entities_Free(void) {
Event_UnregisterVoid(&GfxEvents_ContextRecreated, NULL, Entities_ContextRecreated);
Event_UnregisterVoid(&ChatEvents_FontChanged, NULL, Entities_ChatFontChanged);
- if (ShadowComponent_ShadowTex != NULL) {
+ if (ShadowComponent_ShadowTex) {
Gfx_DeleteTexture(&ShadowComponent_ShadowTex);
}
}
diff --git a/src/Client/Formats.c b/src/Client/Formats.c
index aaf3f30fe..536976ba9 100644
--- a/src/Client/Formats.c
+++ b/src/Client/Formats.c
@@ -267,17 +267,9 @@ static UInt32 Nbt_ReadString(struct Stream* stream, UChar* strBuffer) {
UChar nameBuffer[NBT_SMALL_SIZE * 4];
Stream_Read(stream, nameBuffer, nameLen);
- /* TODO: Check how slow reading strings this way is */
- struct 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;
+ String str = String_Init(strBuffer, 0, NBT_SMALL_SIZE);
+ String_DecodeUtf8(&str, nameBuffer, nameLen);
+ return str.length;
}
typedef bool (*Nbt_Callback)(struct NbtTag* tag);
@@ -573,7 +565,7 @@ static bool Cw_Callback_5(struct NbtTag* tag) {
static bool Cw_Callback(struct NbtTag* tag) {
UInt32 depth = 0;
struct NbtTag* tmp = tag->Parent;
- while (tmp != NULL) { depth++; tmp = tmp->Parent; }
+ while (tmp) { depth++; tmp = tmp->Parent; }
switch (depth) {
case 1: return Cw_Callback_1(tag);
diff --git a/src/Client/Game.c b/src/Client/Game.c
index 043b7bfd7..adecf197c 100644
--- a/src/Client/Game.c
+++ b/src/Client/Game.c
@@ -202,7 +202,7 @@ void Game_UpdateBlock(Int32 x, Int32 y, Int32 z, BlockID block) {
BlockID oldBlock = World_GetBlock(x, y, z);
World_SetBlock(x, y, z, block);
- if (Weather_Heightmap != NULL) {
+ if (Weather_Heightmap) {
WeatherRenderer_OnBlockChanged(x, y, z, oldBlock, block);
}
Lighting_OnBlockChanged(x, y, z, oldBlock, block);
@@ -231,7 +231,7 @@ void Game_SetDefaultSkinType(struct Bitmap* bmp) {
Int32 i;
for (i = 0; i < ENTITIES_MAX_COUNT; i++) {
struct Entity* entity = Entities_List[i];
- if (entity == NULL || entity->TextureId != NULL) continue;
+ if (entity == NULL || entity->TextureId) continue;
entity->SkinType = Game_DefaultPlayerSkinType;
}
}
diff --git a/src/Client/Gui.c b/src/Client/Gui.c
index 58a636e25..7e6122bbe 100644
--- a/src/Client/Gui.c
+++ b/src/Client/Gui.c
@@ -116,7 +116,7 @@ static void Gui_Free(void) {
Gui_ReplaceActive(NULL);
Elem_TryFree(Gui_Status);
- if (Gui_Active != NULL) { Elem_TryFree(Gui_Active); }
+ if (Gui_Active) { Elem_TryFree(Gui_Active); }
Gfx_DeleteTexture(&Gui_GuiTex);
Gfx_DeleteTexture(&Gui_GuiClassicTex);
Gfx_DeleteTexture(&Gui_IconsTex);
@@ -142,7 +142,7 @@ void Gui_ReplaceActive(struct Screen* screen) {
Gui_SetActive(screen);
}
void Gui_FreeActive(void) {
- if (Gui_Active != NULL) { Elem_TryFree(Gui_Active); }
+ if (Gui_Active) { Elem_TryFree(Gui_Active); }
}
void Gui_SetActive(struct Screen* screen) {
@@ -155,7 +155,7 @@ void Gui_SetActive(struct Screen* screen) {
Game_SetCursorVisible(true);
}
- if (screen != NULL) { Elem_Init(screen); }
+ if (screen) { Elem_Init(screen); }
Gui_Active = screen;
}
void Gui_RefreshHud(void) { Elem_Recreate(Gui_HUD); }
@@ -216,10 +216,10 @@ void Gui_RenderGui(Real64 delta) {
if (Gui_Active == NULL || !Gui_Active->HidesHUD && !Gui_Active->RenderHUDOver) {
Elem_Render(Gui_HUD, delta);
}
- if (Gui_Active != NULL) {
+ if (Gui_Active) {
Elem_Render(Gui_Active, delta);
}
- if (Gui_Active != NULL && !Gui_Active->HidesHUD && Gui_Active->RenderHUDOver) {
+ if (Gui_Active && !Gui_Active->HidesHUD && Gui_Active->RenderHUDOver) {
Elem_Render(Gui_HUD, delta);
}
@@ -230,7 +230,7 @@ void Gui_RenderGui(Real64 delta) {
}
void Gui_OnResize(void) {
- if (Gui_Active != NULL) {
+ if (Gui_Active) {
Gui_Active->OnResize((struct GuiElem*)Gui_Active);
}
Gui_HUD->OnResize((struct GuiElem*)Gui_HUD);
diff --git a/src/Client/Gui.h b/src/Client/Gui.h
index a224ebade..9d1f69001 100644
--- a/src/Client/Gui.h
+++ b/src/Client/Gui.h
@@ -116,5 +116,5 @@ void TextAtlas_AddInt(struct TextAtlas* atlas, Int32 value, VertexP3fT2fC4b** ve
#define Elem_HandlesMouseScroll(elem, delta) (elem)->VTABLE->HandlesMouseScroll((struct GuiElem*)(elem), delta)
#define Widget_Reposition(widget) (widget)->Reposition((struct GuiElem*)(widget));
-#define Elem_TryFree(elem) if ((elem)->VTABLE != NULL) { Elem_Free(elem); }
+#define Elem_TryFree(elem) if ((elem)->VTABLE) { Elem_Free(elem); }
#endif
diff --git a/src/Client/InputHandler.c b/src/Client/InputHandler.c
index ee3cbfbb5..e535f2e3d 100644
--- a/src/Client/InputHandler.c
+++ b/src/Client/InputHandler.c
@@ -58,7 +58,7 @@ static void InputHandler_ButtonStateChanged(MouseButton button, bool pressed) {
}
void InputHandler_ScreenChanged(struct Screen* oldScreen, struct Screen* newScreen) {
- if (oldScreen != NULL && oldScreen->HandlesAllInput) {
+ if (oldScreen && oldScreen->HandlesAllInput) {
Platform_CurrentUTCTime(&input_lastClick);
}
diff --git a/src/Client/MapGenerator.c b/src/Client/MapGenerator.c
index 2b95be0ae..24f31e019 100644
--- a/src/Client/MapGenerator.c
+++ b/src/Client/MapGenerator.c
@@ -3,13 +3,11 @@
#include "ErrorHandler.h"
#include "ExtMath.h"
#include "Funcs.h"
-#include "Noise.h"
#include "Platform.h"
-#include "Random.h"
-#include "TreeGen.h"
-#include "Vectors.h"
Int32 Gen_MaxX, Gen_MaxY, Gen_MaxZ, Gen_Volume;
+#define Gen_Pack(x, y, z) (((y) * Gen_Length + (z)) * Gen_Width + (x))
+
static void Gen_Init(void) {
Gen_MaxX = Gen_Width - 1; Gen_MaxY = Gen_Height - 1; Gen_MaxZ = Gen_Length - 1;
Gen_Volume = Gen_Width * Gen_Length * Gen_Height;
@@ -24,6 +22,10 @@ static void Gen_Init(void) {
Gen_Done = false;
}
+
+/*########################################################################################################################*
+*-----------------------------------------------------Flatgrass gen-------------------------------------------------------*
+*#########################################################################################################################*/
static void FlatgrassGen_MapSet(Int32 yStart, Int32 yEnd, BlockID block) {
yStart = max(yStart, 0); yEnd = max(yEnd, 0);
Int32 y, yHeight = (yEnd - yStart) + 1;
@@ -53,6 +55,9 @@ void FlatgrassGen_Generate(void) {
}
+/*########################################################################################################################*
+*----------------------------------------------------Notchy map gen-------------------------------------------------------*
+*#########################################################################################################################*/
Int32 waterLevel, oneY, minHeight;
Int16* Heightmap;
Random rnd;
@@ -494,3 +499,171 @@ void NotchyGen_Generate(void) {
Platform_MemFree(&Heightmap);
Gen_Done = true;
}
+
+
+/*########################################################################################################################*
+*---------------------------------------------------Noise generation------------------------------------------------------*
+*#########################################################################################################################*/
+void ImprovedNoise_Init(UInt8* p, Random* rnd) {
+ /* shuffle randomly using fisher-yates */
+ Int32 i;
+ for (i = 0; i < 256; i++) { p[i] = i; }
+
+ for (i = 0; i < 256; i++) {
+ Int32 j = Random_Range(rnd, i, 256);
+ UInt8 temp = p[i]; p[i] = p[j]; p[j] = temp;
+ }
+
+ for (i = 0; i < 256; i++) {
+ p[i + 256] = p[i];
+ }
+}
+
+Real32 ImprovedNoise_Calc(UInt8* p, Real32 x, Real32 y) {
+ Int32 xFloor = x >= 0 ? (Int32)x : (Int32)x - 1;
+ Int32 yFloor = y >= 0 ? (Int32)y : (Int32)y - 1;
+ Int32 X = xFloor & 0xFF, Y = yFloor & 0xFF;
+ x -= xFloor; y -= yFloor;
+
+ Real32 u = x * x * x * (x * (x * 6 - 15) + 10); /* Fade(x) */
+ Real32 v = y * y * y * (y * (y * 6 - 15) + 10); /* Fade(y) */
+ Int32 A = p[X] + Y, B = p[X + 1] + Y;
+
+ /* Normally, calculating Grad involves a function call. However, we can directly pack this table
+ (since each value indicates either -1, 0 1) into a set of bit flags. This way we avoid needing
+ to call another function that performs branching */
+#define xFlags 0x46552222
+#define yFlags 0x2222550A
+
+ Int32 hash = (p[p[A]] & 0xF) << 1;
+ Real32 g22 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[A], x, y) */
+ hash = (p[p[B]] & 0xF) << 1;
+ Real32 g12 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[B], x - 1, y) */
+ Real32 c1 = g22 + u * (g12 - g22);
+
+ hash = (p[p[A + 1]] & 0xF) << 1;
+ Real32 g21 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[A + 1], x, y - 1) */
+ hash = (p[p[B + 1]] & 0xF) << 1;
+ Real32 g11 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[B + 1], x - 1, y - 1) */
+ Real32 c2 = g21 + u * (g11 - g21);
+
+ return c1 + v * (c2 - c1);
+}
+
+
+void OctaveNoise_Init(struct OctaveNoise* n, Random* rnd, Int32 octaves) {
+ n->octaves = octaves;
+ Int32 i;
+ for (i = 0; i < octaves; i++) {
+ ImprovedNoise_Init(n->p[i], rnd);
+ }
+}
+
+Real32 OctaveNoise_Calc(struct OctaveNoise* n, Real32 x, Real32 y) {
+ Real32 amplitude = 1, freq = 1;
+ Real32 sum = 0;
+ Int32 i;
+
+ for (i = 0; i < n->octaves; i++) {
+ sum += ImprovedNoise_Calc(n->p[i], x * freq, y * freq) * amplitude;
+ amplitude *= 2.0f;
+ freq *= 0.5f;
+ }
+ return sum;
+}
+
+
+void CombinedNoise_Init(struct CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 octaves2) {
+ OctaveNoise_Init(&n->noise1, rnd, octaves1);
+ OctaveNoise_Init(&n->noise2, rnd, octaves2);
+}
+
+Real32 CombinedNoise_Calc(struct CombinedNoise* n, Real32 x, Real32 y) {
+ Real32 offset = OctaveNoise_Calc(&n->noise2, x, y);
+ return OctaveNoise_Calc(&n->noise1, x + offset, y);
+}
+
+
+/*########################################################################################################################*
+*--------------------------------------------------Tree generation----------------------------------------------------*
+*#########################################################################################################################*/
+#define Tree_Pack(x, y, z) (((y) * Tree_Length + (z)) * Tree_Width + (x))
+
+bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight) {
+ /* check tree base */
+ Int32 baseHeight = treeHeight - 4;
+ Int32 x, y, z;
+
+ for (y = treeY; y < treeY + baseHeight; y++) {
+ for (z = treeZ - 1; z <= treeZ + 1; z++) {
+ for (x = treeX - 1; x <= treeX + 1; x++) {
+ if (x < 0 || y < 0 || z < 0 || x >= Tree_Width || y >= Tree_Height || z >= Tree_Length)
+ return false;
+ Int32 index = Tree_Pack(x, y, z);
+ if (Tree_Blocks[index] != BLOCK_AIR) return false;
+ }
+ }
+ }
+
+ /* and also check canopy */
+ for (y = treeY + baseHeight; y < treeY + treeHeight; y++) {
+ for (z = treeZ - 2; z <= treeZ + 2; z++) {
+ for (x = treeX - 2; x <= treeX + 2; x++) {
+ if (x < 0 || y < 0 || z < 0 || x >= Tree_Width || y >= Tree_Height || z >= Tree_Length)
+ return false;
+ Int32 index = Tree_Pack(x, y, z);
+ if (Tree_Blocks[index] != BLOCK_AIR) return false;
+ }
+ }
+ }
+ return true;
+}
+
+#define TreeGen_Place(x, y, z, block)\
+coords[count].X = (x); coords[count].Y = (y); coords[count].Z = (z);\
+blocks[count] = block; count++;
+
+Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockID* blocks) {
+ Int32 baseHeight = height - 4;
+ Int32 count = 0;
+ Int32 xx, y, zz;
+
+ /* leaves bottom layer */
+ for (y = treeY + baseHeight; y < treeY + baseHeight + 2; y++) {
+ for (zz = -2; zz <= 2; zz++) {
+ for (xx = -2; xx <= 2; xx++) {
+ Int32 x = treeX + xx, z = treeZ + zz;
+
+ if (Math_AbsI(xx) == 2 && Math_AbsI(zz) == 2) {
+ if (Random_Float(Tree_Rnd) >= 0.5f) {
+ TreeGen_Place(x, y, z, BLOCK_LEAVES);
+ }
+ } else {
+ TreeGen_Place(x, y, z, BLOCK_LEAVES);
+ }
+ }
+ }
+ }
+
+ /* leaves top layer */
+ Int32 bottomY = treeY + baseHeight + 2;
+ for (y = treeY + baseHeight + 2; y < treeY + height; y++) {
+ for (zz = -1; zz <= 1; zz++) {
+ for (xx = -1; xx <= 1; xx++) {
+ Int32 x = xx + treeX, z = zz + treeZ;
+
+ if (xx == 0 || zz == 0) {
+ TreeGen_Place(x, y, z, BLOCK_LEAVES);
+ } else if (y == bottomY && Random_Float(Tree_Rnd) >= 0.5f) {
+ TreeGen_Place(x, y, z, BLOCK_LEAVES);
+ }
+ }
+ }
+ }
+
+ /* then place trunk */
+ for (y = 0; y < height - 1; y++) {
+ TreeGen_Place(treeX, treeY + y, treeZ, BLOCK_LOG);
+ }
+ return count;
+}
diff --git a/src/Client/MapGenerator.h b/src/Client/MapGenerator.h
index 577f6d9ec..23ba4dce3 100644
--- a/src/Client/MapGenerator.h
+++ b/src/Client/MapGenerator.h
@@ -1,7 +1,9 @@
#ifndef CC_MAP_GEN_H
#define CC_MAP_GEN_H
#include "String.h"
-/* Implements flatgrass map generator, and original classic vanilla map generation.
+#include "Random.h"
+#include "Vectors.h"
+/* Implements flatgrass map generator, and original classic vanilla map generation (with perlin noise)
Based on: https://github.com/UnknownShadow200/ClassicalSharp/wiki/Minecraft-Classic-map-generation-algorithm
Thanks to Jerralish for originally reverse engineering classic's algorithm, then preparing a high level overview of the algorithm.
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
@@ -10,13 +12,33 @@
volatile Real32 Gen_CurrentProgress;
volatile const UChar* Gen_CurrentState;
volatile bool Gen_Done;
-Int32 Gen_Width, Gen_Height, Gen_Length;
-Int32 Gen_Seed;
+Int32 Gen_Width, Gen_Height, Gen_Length, Gen_Seed;
bool Gen_Vanilla;
BlockID* Gen_Blocks;
-#define Get_SetDimensions(x, y, z) Gen_Width = x; Gen_Height = y; Gen_Length = z;
-#define Gen_Pack(x, y, z) (((y) * Gen_Length + (z)) * Gen_Width + (x))
+#define Gen_SetDimensions(x, y, z) Gen_Width = x; Gen_Height = y; Gen_Length = z;
void FlatgrassGen_Generate(void);
void NotchyGen_Generate(void);
+
+#define NOISE_TABLE_SIZE 512
+void ImprovedNoise_Init(UInt8* p, Random* rnd);
+Real32 ImprovedNoise_Calc(UInt8* p, Real32 x, Real32 y);
+
+struct OctaveNoise { UInt8 p[8][NOISE_TABLE_SIZE]; Int32 octaves; };
+void OctaveNoise_Init(struct OctaveNoise* n, Random* rnd, Int32 octaves);
+Real32 OctaveNoise_Calc(struct OctaveNoise* n, Real32 x, Real32 y);
+
+struct CombinedNoise { struct OctaveNoise noise1, noise2; };
+void CombinedNoise_Init(struct CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 octaves2);
+Real32 CombinedNoise_Calc(struct CombinedNoise* n, Real32 x, Real32 y);
+
+
+Int32 Tree_Width, Tree_Height, Tree_Length;
+BlockID* Tree_Blocks;
+Random* Tree_Rnd;
+/* Appropriate buffer size to hold positions and blocks generated by the tree generator. */
+#define Tree_BufferCount 96
+
+bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight);
+Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockID* blocks);
#endif
diff --git a/src/Client/Menus.c b/src/Client/Menus.c
index 3bb943d10..05e849e86 100644
--- a/src/Client/Menus.c
+++ b/src/Client/Menus.c
@@ -226,7 +226,7 @@ static Int32 Menu_HandleMouseDown(struct GuiElem* screen, struct Widget** widget
if (widget == NULL || !Widget_Contains(widget, x, y)) continue;
if (widget->Disabled) return i;
- if (widget->MenuClick != NULL && btn == MouseButton_Left) {
+ if (widget->MenuClick && btn == MouseButton_Left) {
widget->MenuClick(screen, (struct GuiElem*)widget);
} else {
Elem_HandlesMouseDown(widget, x, y, btn);
@@ -240,7 +240,7 @@ static Int32 Menu_HandleMouseMove(struct Widget** widgets, Int32 count, Int32 x,
Int32 i;
for (i = 0; i < count; i++) {
struct Widget* widget = widgets[i];
- if (widget != NULL) widget->Active = false;
+ if (widget) widget->Active = false;
}
for (i = count - 1; i >= 0; i--) {
@@ -494,7 +494,7 @@ static Int32 MenuScreen_Index(struct MenuScreen* screen, struct Widget* w) {
static void MenuScreen_Remove(struct MenuScreen* screen, Int32 i) {
struct Widget** widgets = screen->Widgets;
- if (widgets[i] != NULL) { Elem_TryFree(widgets[i]); }
+ if (widgets[i]) { Elem_TryFree(widgets[i]); }
widgets[i] = NULL;
}
@@ -556,10 +556,10 @@ static void MenuScreen_Free(struct GuiElem* elem) {
struct MenuScreen* screen = (struct MenuScreen*)elem;
screen->ContextLost(screen);
- if (screen->TitleFont.Handle != NULL) {
+ if (screen->TitleFont.Handle) {
Platform_FontFree(&screen->TitleFont);
}
- if (screen->TextFont.Handle != NULL) {
+ if (screen->TextFont.Handle) {
Platform_FontFree(&screen->TextFont);
}
@@ -1103,7 +1103,7 @@ static void GenLevelScreen_Gen(struct GenLevelScreen* screen, bool vanilla) {
String msg = String_FromConst("&cOne of the map dimensions is invalid.");
Chat_Add(&msg);
} else {
- Get_SetDimensions(width, height, length);
+ Gen_SetDimensions(width, height, length);
Gen_Vanilla = vanilla; Gen_Seed = seed;
Gui_ReplaceActive(GeneratingScreen_MakeInstance());
}
@@ -1121,7 +1121,7 @@ static void GenLevelScreen_Notchy(struct GuiElem* elem, struct GuiElem* widget)
static void GenLevelScreen_InputClick(struct GuiElem* elem, struct GuiElem* widget) {
struct GenLevelScreen* screen = (struct GenLevelScreen*)elem;
- if (screen->Selected != NULL) screen->Selected->Base.ShowCaret = false;
+ if (screen->Selected) screen->Selected->Base.ShowCaret = false;
screen->Selected = (struct MenuInputWidget*)widget;
Elem_HandlesMouseDown(&screen->Selected->Base, Mouse_X, Mouse_Y, MouseButton_Left);
@@ -1167,7 +1167,7 @@ static void GenLevelScreen_Free(struct GuiElem* elem) {
static bool GenLevelScreen_HandlesKeyDown(struct GuiElem* elem, Key key) {
struct GenLevelScreen* screen = (struct GenLevelScreen*)elem;
- if (screen->Selected != NULL && Elem_HandlesKeyDown(&screen->Selected->Base, key)) return true;
+ if (screen->Selected && Elem_HandlesKeyDown(&screen->Selected->Base, key)) return true;
return MenuScreen_HandlesKeyDown(elem, key);
}
@@ -1242,7 +1242,7 @@ struct GuiElementVTABLE ClassicGenScreen_VTABLE;
struct ClassicGenScreen ClassicGenScreen_Instance;
static void ClassicGenScreen_Gen(Int32 size) {
Random rnd; Random_InitFromCurrentTime(&rnd);
- Get_SetDimensions(size, 64, size); Gen_Vanilla = true;
+ Gen_SetDimensions(size, 64, size); Gen_Vanilla = true;
Gen_Seed = Random_Next(&rnd, Int32_MaxValue);
Gui_ReplaceActive(GeneratingScreen_MakeInstance());
}
@@ -1309,7 +1309,7 @@ static void SaveLevelScreen_RemoveOverwrites(struct SaveLevelScreen* screen) {
}
static void SaveLevelScreen_MakeDesc(struct SaveLevelScreen* screen, STRING_PURE String* text) {
- if (screen->Widgets[5] != NULL) { Elem_TryFree(screen->Widgets[5]); }
+ if (screen->Widgets[5]) { Elem_TryFree(screen->Widgets[5]); }
TextWidget_Create(&screen->Desc, text, &screen->TextFont);
Widget_SetLocation((struct Widget*)(&screen->Desc), ANCHOR_CENTRE, ANCHOR_CENTRE, 0, 65);
diff --git a/src/Client/ModelCache.c b/src/Client/ModelCache.c
index 758c7ae1b..3bb39129f 100644
--- a/src/Client/ModelCache.c
+++ b/src/Client/ModelCache.c
@@ -54,7 +54,7 @@ void ModelCache_Register(STRING_REF const UChar* name, STRING_PURE const UChar*
model.Instance = instance;
ModelCache_Models[ModelCache_modelCount++] = model;
- if (defaultTexName != NULL) {
+ if (defaultTexName) {
String defaultTex = String_FromReadonly(defaultTexName);
instance->defaultTexIndex = ModelCache_GetTextureIndex(&defaultTex);
}
diff --git a/src/Client/Noise.c b/src/Client/Noise.c
deleted file mode 100644
index c964f76e7..000000000
--- a/src/Client/Noise.c
+++ /dev/null
@@ -1,80 +0,0 @@
-#include "Noise.h"
-
-void ImprovedNoise_Init(UInt8* p, Random* rnd) {
- /* shuffle randomly using fisher-yates */
- Int32 i;
- for (i = 0; i < 256; i++) { p[i] = i; }
-
- for (i = 0; i < 256; i++) {
- Int32 j = Random_Range(rnd, i, 256);
- UInt8 temp = p[i]; p[i] = p[j]; p[j] = temp;
- }
-
- for (i = 0; i < 256; i++) {
- p[i + 256] = p[i];
- }
-}
-
-Real32 ImprovedNoise_Calc(UInt8* p, Real32 x, Real32 y) {
- Int32 xFloor = x >= 0 ? (Int32)x : (Int32)x - 1;
- Int32 yFloor = y >= 0 ? (Int32)y : (Int32)y - 1;
- Int32 X = xFloor & 0xFF, Y = yFloor & 0xFF;
- x -= xFloor; y -= yFloor;
-
- Real32 u = x * x * x * (x * (x * 6 - 15) + 10); /* Fade(x) */
- Real32 v = y * y * y * (y * (y * 6 - 15) + 10); /* Fade(y) */
- Int32 A = p[X] + Y, B = p[X + 1] + Y;
-
- /* Normally, calculating Grad involves a function call. However, we can directly pack this table
- (since each value indicates either -1, 0 1) into a set of bit flags. This way we avoid needing
- to call another function that performs branching */
- #define xFlags 0x46552222
- #define yFlags 0x2222550A
-
- Int32 hash = (p[p[A]] & 0xF) << 1;
- Real32 g22 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[A], x, y) */
- hash = (p[p[B]] & 0xF) << 1;
- Real32 g12 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[B], x - 1, y) */
- Real32 c1 = g22 + u * (g12 - g22);
-
- hash = (p[p[A + 1]] & 0xF) << 1;
- Real32 g21 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[A + 1], x, y - 1) */
- hash = (p[p[B + 1]] & 0xF) << 1;
- Real32 g11 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[B + 1], x - 1, y - 1) */
- Real32 c2 = g21 + u * (g11 - g21);
-
- return c1 + v * (c2 - c1);
-}
-
-
-void OctaveNoise_Init(struct OctaveNoise* n, Random* rnd, Int32 octaves) {
- n->octaves = octaves;
- Int32 i;
- for (i = 0; i < octaves; i++) {
- ImprovedNoise_Init(n->p[i], rnd);
- }
-}
-
-Real32 OctaveNoise_Calc(struct OctaveNoise* n, Real32 x, Real32 y) {
- Real32 amplitude = 1, freq = 1;
- Real32 sum = 0;
- Int32 i;
-
- for (i = 0; i < n->octaves; i++) {
- sum += ImprovedNoise_Calc(n->p[i], x * freq, y * freq) * amplitude;
- amplitude *= 2.0f;
- freq *= 0.5f;
- }
- return sum;
-}
-
-
-void CombinedNoise_Init(struct CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 octaves2) {
- OctaveNoise_Init(&n->noise1, rnd, octaves1);
- OctaveNoise_Init(&n->noise2, rnd, octaves2);
-}
-
-Real32 CombinedNoise_Calc(struct CombinedNoise* n, Real32 x, Real32 y) {
- Real32 offset = OctaveNoise_Calc(&n->noise2, x, y);
- return OctaveNoise_Calc(&n->noise1, x + offset, y);
-}
diff --git a/src/Client/Noise.h b/src/Client/Noise.h
deleted file mode 100644
index 798c18438..000000000
--- a/src/Client/Noise.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef CC_IMPROVED_NOISE_H
-#define CC_IMPROVED_NOISE_H
-#include "Random.h"
-/* Implements perlin noise generation.
- Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
-*/
-
-#define NOISE_TABLE_SIZE 512
-void ImprovedNoise_Init(UInt8* p, Random* rnd);
-Real32 ImprovedNoise_Calc(UInt8* p, Real32 x, Real32 y);
-
-/* since we need structure to be a fixed size */
-#define MAX_OCTAVES 8
-struct OctaveNoise {
- UInt8 p[MAX_OCTAVES][NOISE_TABLE_SIZE];
- Int32 octaves;
-};
-
-void OctaveNoise_Init(struct OctaveNoise* n, Random* rnd, Int32 octaves);
-Real32 OctaveNoise_Calc(struct OctaveNoise* n, Real32 x, Real32 y);
-
-struct CombinedNoise {
- struct OctaveNoise noise1;
- struct OctaveNoise noise2;
-};
-
-void CombinedNoise_Init(struct CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 octaves2);
-Real32 CombinedNoise_Calc(struct CombinedNoise* n, Real32 x, Real32 y);
-#endif
diff --git a/src/Client/PacketHandlers.c b/src/Client/PacketHandlers.c
index 2d02aecc2..44782c258 100644
--- a/src/Client/PacketHandlers.c
+++ b/src/Client/PacketHandlers.c
@@ -114,7 +114,7 @@ static void Handlers_AddEntity(EntityID id, STRING_TRANSIENT String* displayName
struct LocalPlayer* p = &LocalPlayer_Instance;
if (id != ENTITIES_SELF_ID) {
struct Entity* oldEntity = Entities_List[id];
- if (oldEntity != NULL) Entities_Remove(id);
+ if (oldEntity) Entities_Remove(id);
struct NetPlayer* player = &NetPlayers_List[id];
NetPlayer_Init(player, displayName, skinName);
@@ -159,7 +159,7 @@ void Handlers_RemoveEntity(EntityID id) {
static void Handlers_UpdateLocation(EntityID playerId, struct LocationUpdate* update, bool interpolate) {
struct Entity* entity = Entities_List[playerId];
- if (entity != NULL) {
+ if (entity) {
entity->VTABLE->SetLocation(entity, update, interpolate);
}
}
@@ -453,7 +453,7 @@ static void Classic_LevelDataChunk(struct Stream* stream) {
static void Classic_LevelFinalise(struct Stream* stream) {
Gui_ReplaceActive(NULL);
Gui_Active = prevScreen;
- if (prevScreen != NULL && prevCursorVisible != Game_GetCursorVisible()) {
+ if (prevScreen && prevCursorVisible != Game_GetCursorVisible()) {
Game_SetCursorVisible(prevCursorVisible);
}
prevScreen = NULL;
@@ -944,7 +944,7 @@ static void CPE_ChangeModel(struct Stream* stream) {
String modelName = Handlers_ReadString(stream, modelNameBuffer);
struct Entity* entity = Entities_List[id];
- if (entity != NULL) { Entity_SetModel(entity, &modelName); }
+ if (entity) { Entity_SetModel(entity, &modelName); }
}
static void CPE_EnvSetMapAppearance(struct Stream* stream) {
diff --git a/src/Client/Screens.c b/src/Client/Screens.c
index 86c5746b8..a045e2f93 100644
--- a/src/Client/Screens.c
+++ b/src/Client/Screens.c
@@ -819,7 +819,7 @@ static void ChatScreen_CheckOtherStatuses(struct ChatScreen* screen) {
/* Is terrain / texture pack currently being downloaded? */
if (!hasRequest || !(String_Equals(&id, &terrain) || String_Equals(&id, &texPack))) {
- if (screen->Status.Textures[1].ID != NULL) {
+ if (screen->Status.Textures[1].ID) {
String empty = String_MakeNull();
TextGroupWidget_SetText(&screen->Status, 1, &empty);
}
diff --git a/src/Client/ServerConnection.c b/src/Client/ServerConnection.c
index 34c6fa27a..2187fd753 100644
--- a/src/Client/ServerConnection.c
+++ b/src/Client/ServerConnection.c
@@ -189,7 +189,7 @@ static void SPConnection_BeginConnect(void) {
}
Random rnd; Random_InitFromCurrentTime(&rnd);
- Get_SetDimensions(128, 64, 128); Gen_Vanilla = true;
+ Gen_SetDimensions(128, 64, 128); Gen_Vanilla = true;
Gen_Seed = Random_Next(&rnd, Int32_MaxValue);
Gui_ReplaceActive(GeneratingScreen_MakeInstance());
}
@@ -213,7 +213,7 @@ static void SPConnection_AddPortion(STRING_PURE String* text) {
String_UNSAFE_TrimEnd(&tmp);
UInt8 col = Drawer2D_LastCol(&tmp, tmp.length);
- if (col != NULL) SPConnection_LastCol = col;
+ if (col) SPConnection_LastCol = col;
Chat_Add(&tmp);
}
diff --git a/src/Client/SkyboxRenderer.c b/src/Client/SkyboxRenderer.c
index 97e094443..6a142d2d0 100644
--- a/src/Client/SkyboxRenderer.c
+++ b/src/Client/SkyboxRenderer.c
@@ -15,7 +15,7 @@ GfxResourceID skybox_tex, skybox_vb;
#define SKYBOX_COUNT (6 * 4)
bool SkyboxRenderer_ShouldRender(void) {
- return skybox_tex != NULL && !EnvRenderer_Minimal;
+ return skybox_tex && !EnvRenderer_Minimal;
}
static void SkyboxRenderer_TexturePackChanged(void* obj) {
@@ -49,11 +49,11 @@ void SkyboxRenderer_Render(Real64 deltaTime) {
Matrix_MulBy(&m, &rotX);
/* Rotate around camera */
- Vector3 pos = Game_CurrentCameraPos, zero = Vector3_Zero;
+ Vector3 camPos = Game_CurrentCameraPos, zero = Vector3_Zero;
Game_CurrentCameraPos = zero;
Camera_Active->GetView(&view);
Matrix_MulBy(&m, &view);
- Game_CurrentCameraPos = pos;
+ Game_CurrentCameraPos = camPos;
Gfx_LoadMatrix(&m);
Gfx_BindVb(skybox_vb);
diff --git a/src/Client/Stream.c b/src/Client/Stream.c
index 534d51dd4..4aa4b3bc6 100644
--- a/src/Client/Stream.c
+++ b/src/Client/Stream.c
@@ -433,6 +433,6 @@ void Stream_WriteLine(struct Stream* stream, STRING_TRANSIENT String* text) {
}
UInt8* ptr = Platform_NewLine;
- while (*ptr != NULL) { buffer[j++] = *ptr++; }
+ while (*ptr) { buffer[j++] = *ptr++; }
if (j > 0) Stream_Write(stream, buffer, j);
}
diff --git a/src/Client/String.c b/src/Client/String.c
index abea0aaac..6045e7f73 100644
--- a/src/Client/String.c
+++ b/src/Client/String.c
@@ -3,6 +3,7 @@
#include "ErrorHandler.h"
#include "Platform.h"
#include "ExtMath.h"
+#include "Stream.h"
#define Char_MakeLower(ch) if ((ch) >= 'A' && (ch) <= 'Z') { (ch) += ' '; }
UChar Char_ToLower(UChar c) {
@@ -23,20 +24,21 @@ String String_InitAndClear(STRING_REF UChar* buffer, UInt16 capacity) {
return str;
}
+UInt16 String_CalcLen(STRING_PURE UChar* raw, UInt16 capacity) {
+ UInt16 length = 0;
+ while (length < capacity && *raw) { raw++; length++; }
+ return length;
+}
+
String String_MakeNull(void) { return String_Init(NULL, 0, 0); }
String String_FromRaw(STRING_REF UChar* buffer, UInt16 capacity) {
- UInt16 length = 0;
- UChar* cur = buffer;
- while (length < capacity && *cur != NULL) { cur++; length++; }
-
- return String_Init(buffer, length, capacity);
+ return String_Init(buffer, String_CalcLen(buffer, capacity), capacity);
}
String String_FromReadonly(STRING_REF const UChar* buffer) {
- String str = String_FromRaw(buffer, UInt16_MaxValue);
- str.capacity = str.length;
- return str;
+ UInt16 len = String_CalcLen(buffer, UInt16_MaxValue);
+ return String_Init(buffer, len, len);
}
@@ -250,30 +252,28 @@ bool String_Hex64(STRING_TRANSIENT String* str, UInt64 value) {
return String_AppendConst(str, hex);
}
-bool String_AppendConst(STRING_TRANSIENT String* str, const UChar* toAppend) {
- UChar cur;
-
- while ((cur = *toAppend) != NULL) {
- if (!String_Append(str, cur)) return false;
- toAppend++;
+bool String_AppendConst(STRING_TRANSIENT String* str, const UChar* src) {
+ while (*src) {
+ if (!String_Append(str, *src)) return false;
+ src++;
}
return true;
}
-bool String_AppendString(STRING_TRANSIENT String* str, STRING_PURE String* toAppend) {
+bool String_AppendString(STRING_TRANSIENT String* str, STRING_PURE String* src) {
Int32 i;
- for (i = 0; i < toAppend->length; i++) {
- if (!String_Append(str, toAppend->buffer[i])) return false;
+ for (i = 0; i < src->length; i++) {
+ if (!String_Append(str, src->buffer[i])) return false;
}
return true;
}
-bool String_AppendColorless(STRING_TRANSIENT String* str, STRING_PURE String* toAppend) {
+bool String_AppendColorless(STRING_TRANSIENT String* str, STRING_PURE String* src) {
Int32 i;
- for (i = 0; i < toAppend->length; i++) {
- UChar c = toAppend->buffer[i];
+ for (i = 0; i < src->length; i++) {
+ UChar c = src->buffer[i];
if (c == '&') { i++; continue; } /* Skip over the following colour code */
if (!String_Append(str, c)) return false;
}
@@ -511,6 +511,17 @@ bool Convert_TryUnicodeToCP437(UInt16 c, UChar* value) {
*value = '?'; return false;
}
+void String_DecodeUtf8(STRING_TRANSIENT String* str, UInt8* data, UInt32 len) {
+ String name = String_FromConst("Decoding UTF8");
+ struct Stream mem; Stream_ReadonlyMemory(&mem, data, len, &name);
+ UInt16 codepoint;
+
+ while (mem.Meta_Mem_Left > 0) {
+ if (!Stream_ReadUtf8Char(&mem, &codepoint)) break;
+ String_Append(str, Convert_UnicodeToCP437(codepoint));
+ }
+}
+
bool Convert_TryParseUInt8(STRING_PURE String* str, UInt8* value) {
*value = 0; Int32 tmp;
if (!Convert_TryParseInt32(str, &tmp) || tmp < 0 || tmp > UInt8_MaxValue) return false;
diff --git a/src/Client/String.h b/src/Client/String.h
index e972069b7..3f8e7e88d 100644
--- a/src/Client/String.h
+++ b/src/Client/String.h
@@ -27,6 +27,7 @@ typedef struct String_ {
UInt16 capacity; /* Max number of characters that can be in buffer. */
} String;
+UInt16 String_CalcLen(STRING_PURE UChar* raw, UInt16 capacity);
String String_MakeNull(void);
String String_Init(STRING_REF UChar* buffer, UInt16 length, UInt16 capacity);
String String_InitAndClear(STRING_REF UChar* buffer, UInt16 capacity);
@@ -67,9 +68,9 @@ bool String_AppendUInt64(STRING_TRANSIENT String* str, UInt64 num);
bool String_AppendReal32(STRING_TRANSIENT String* str, Real32 num, Int32 fracDigits); /* TODO: Need to account for , or . for decimal */
bool String_Hex32(STRING_TRANSIENT String* str, UInt32 value);
bool String_Hex64(STRING_TRANSIENT String* str, UInt64 value);
-bool String_AppendConst(STRING_TRANSIENT String* str, const UChar* toAppend);
-bool String_AppendString(STRING_TRANSIENT String* str, STRING_PURE String* toAppend);
-bool String_AppendColorless(STRING_TRANSIENT String* str, STRING_PURE String* toAppend);
+bool String_AppendConst(STRING_TRANSIENT String* str, const UChar* src);
+bool String_AppendString(STRING_TRANSIENT String* str, STRING_PURE String* src);
+bool String_AppendColorless(STRING_TRANSIENT String* str, STRING_PURE String* src);
Int32 String_IndexOf(STRING_PURE String* str, UChar c, Int32 offset);
Int32 String_LastIndexOf(STRING_PURE String* str, UChar c);
@@ -93,6 +94,8 @@ void String_Format4(STRING_TRANSIENT String* str, const UChar* format, const voi
UInt16 Convert_CP437ToUnicode(UChar c);
UChar Convert_UnicodeToCP437(UInt16 c);
bool Convert_TryUnicodeToCP437(UInt16 c, UChar* value);
+void String_DecodeUtf8(STRING_TRANSIENT String* str, UInt8* data, UInt32 len);
+
bool Convert_TryParseUInt8(STRING_PURE String* str, UInt8* value);
bool Convert_TryParseInt16(STRING_PURE String* str, Int16* value);
bool Convert_TryParseUInt16(STRING_PURE String* str, UInt16* value);
diff --git a/src/Client/TreeGen.c b/src/Client/TreeGen.c
deleted file mode 100644
index e40bdfc3c..000000000
--- a/src/Client/TreeGen.c
+++ /dev/null
@@ -1,85 +0,0 @@
-#include "TreeGen.h"
-#include "BlockID.h"
-#include "ExtMath.h"
-#include "Vectors.h"
-
-bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight) {
- /* check tree base */
- Int32 baseHeight = treeHeight - 4;
- Int32 x, y, z;
-
- for (y = treeY; y < treeY + baseHeight; y++) {
- for (z = treeZ - 1; z <= treeZ + 1; z++) {
- for (x = treeX - 1; x <= treeX + 1; x++)
- {
- if (x < 0 || y < 0 || z < 0 || x >= Tree_Width || y >= Tree_Height || z >= Tree_Length)
- return false;
- Int32 index = Tree_Pack(x, y, z);
- if (Tree_Blocks[index] != BLOCK_AIR) return false;
- }
- }
- }
-
- /* and also check canopy */
- for (y = treeY + baseHeight; y < treeY + treeHeight; y++) {
- for (z = treeZ - 2; z <= treeZ + 2; z++) {
- for (x = treeX - 2; x <= treeX + 2; x++) {
- if (x < 0 || y < 0 || z < 0 || x >= Tree_Width || y >= Tree_Height || z >= Tree_Length)
- return false;
- Int32 index = Tree_Pack(x, y, z);
- if (Tree_Blocks[index] != BLOCK_AIR) return false;
- }
- }
- }
- return true;
-}
-
-#define TreeGen_Place(x, y, z, block)\
-coords[count].X = (x); coords[count].Y = (y); coords[count].Z = (z);\
-blocks[count] = block;\
-count++;
-
-Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockID* blocks) {
- Int32 baseHeight = height - 4;
- Int32 count = 0;
- Int32 xx, y, zz;
-
- /* leaves bottom layer */
- for (y = treeY + baseHeight; y < treeY + baseHeight + 2; y++) {
- for (zz = -2; zz <= 2; zz++) {
- for (xx = -2; xx <= 2; xx++) {
- Int32 x = treeX + xx, z = treeZ + zz;
-
- if (Math_AbsI(xx) == 2 && Math_AbsI(zz) == 2) {
- if (Random_Float(Tree_Rnd) >= 0.5f) {
- TreeGen_Place(x, y, z, BLOCK_LEAVES);
- }
- } else {
- TreeGen_Place(x, y, z, BLOCK_LEAVES);
- }
- }
- }
- }
-
- /* leaves top layer */
- Int32 bottomY = treeY + baseHeight + 2;
- for (y = treeY + baseHeight + 2; y < treeY + height; y++) {
- for (zz = -1; zz <= 1; zz++) {
- for (xx = -1; xx <= 1; xx++) {
- Int32 x = xx + treeX, z = zz + treeZ;
-
- if (xx == 0 || zz == 0) {
- TreeGen_Place(x, y, z, BLOCK_LEAVES);
- } else if (y == bottomY && Random_Float(Tree_Rnd) >= 0.5f) {
- TreeGen_Place(x, y, z, BLOCK_LEAVES);
- }
- }
- }
- }
-
- /* then place trunk */
- for (y = 0; y < height - 1; y++) {
- TreeGen_Place(treeX, treeY + y, treeZ, BLOCK_LOG);
- }
- return count;
-}
diff --git a/src/Client/TreeGen.h b/src/Client/TreeGen.h
deleted file mode 100644
index 84ddc2430..000000000
--- a/src/Client/TreeGen.h
+++ /dev/null
@@ -1,29 +0,0 @@
-#ifndef CC_TREE_GEN_H
-#define CC_TREE_GEN_H
-#include "Random.h"
-#include "Vectors.h"
-/* Implements original classic vanilla map generation
- Based on: https://github.com/UnknownShadow200/ClassicalSharp/wiki/Minecraft-Classic-map-generation-algorithm
- Thanks to Jerralish for originally reverse engineering classic's algorithm, then preparing a high level overview of the algorithm.
- I believe this process adheres to clean room reverse engineering.
- Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
-*/
-
-/* Dimensions of the map trees are generated on. */
-Int32 Tree_Width, Tree_Height, Tree_Length;
-/* Blocks of the map trees are generated on. */
-BlockID* Tree_Blocks;
-/* Random number generator used for trees. */
-Random* Tree_Rnd;
-
-/* Packs a coordinate into a single integer index. */
-#define Tree_Pack(x, y, z) (((y) * Tree_Length + (z)) * Tree_Width + (x))
-/* Appropriate buffer size to hold positions and blocks generated by the tree generator. */
-#define Tree_BufferCount 96
-
-/* Returns whether a tree can grow at the specified coordinates. */
-bool TreeGen_CanGrow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight);
-/* Plants a tree of the given height at the given coordinates.
-coords and blocks point to arrays which are filled with the generated positions and block ids. */
-Int32 TreeGen_Grow(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height, Vector3I* coords, BlockID* blocks);
-#endif
diff --git a/src/Client/Typedefs.h b/src/Client/Typedefs.h
index 28e66e645..d21c2025e 100644
--- a/src/Client/Typedefs.h
+++ b/src/Client/Typedefs.h
@@ -14,7 +14,7 @@ typedef signed __int8 Int8;
typedef signed __int16 Int16;
typedef signed __int32 Int32;
typedef signed __int64 Int64;
-#elif (__STDC_VERSION__ >= 199901L)
+#elif __GNUC__ || (__STDC_VERSION__ >= 199901L)
#include
typedef uint8_t UInt8;
typedef uint16_t UInt16;
diff --git a/src/Client/Widgets.c b/src/Client/Widgets.c
index e96387ed0..7cecc97ed 100644
--- a/src/Client/Widgets.c
+++ b/src/Client/Widgets.c
@@ -43,7 +43,7 @@ static void TextWidget_Init(struct GuiElem* elem) {
static void TextWidget_Render(struct GuiElem* elem, Real64 delta) {
struct TextWidget* widget = (struct TextWidget*)elem;
- if (widget->Texture.ID != NULL) {
+ if (widget->Texture.ID) {
Texture_RenderShaded(&widget->Texture, widget->Col);
}
}
@@ -713,7 +713,7 @@ static void TableWidget_Render(struct GuiElem* elem, Real64 delta) {
}
IsometricDrawer_EndBatch();
- if (widget->DescTex.ID != NULL) {
+ if (widget->DescTex.ID) {
Texture_Render(&widget->DescTex);
}
Gfx_SetTexturing(false);
@@ -949,7 +949,7 @@ static UChar InputWidget_GetLastCol(struct InputWidget* widget, Int32 indexX, In
InputWidget_FormatLine(widget, y, &line);
UChar code = Drawer2D_LastCol(&line, x);
- if (code != NULL) return code;
+ if (code) return code;
if (y > 0) { x = widget->Lines[y - 1].length; }
}
return NULL;
@@ -992,7 +992,7 @@ static void InputWidget_UpdateCaret(struct InputWidget* widget) {
/* Update the colour of the widget->CaretPos */
UChar code = InputWidget_GetLastCol(widget, widget->CaretX, widget->CaretY);
- if (code != NULL) widget->CaretCol = Drawer2D_Cols[code];
+ if (code) widget->CaretCol = Drawer2D_Cols[code];
}
static void InputWidget_RenderCaret(struct InputWidget* widget, Real64 delta) {
@@ -2265,7 +2265,7 @@ static Int32 TextGroupWidget_CalcY(struct TextGroupWidget* widget, Int32 index,
void TextGroupWidget_SetUsePlaceHolder(struct TextGroupWidget* widget, Int32 index, bool placeHolder) {
widget->PlaceholderHeight[index] = placeHolder;
- if (widget->Textures[index].ID != NULL) return;
+ if (widget->Textures[index].ID) return;
Int32 newHeight = placeHolder ? widget->DefaultHeight : 0;
widget->Textures[index].Y = TextGroupWidget_CalcY(widget, index, newHeight);
@@ -2277,7 +2277,7 @@ Int32 TextGroupWidget_UsedHeight(struct TextGroupWidget* widget) {
struct Texture* textures = widget->Textures;
for (i = 0; i < widget->LinesCount; i++) {
- if (textures[i].ID != NULL) break;
+ if (textures[i].ID) break;
}
for (; i < widget->LinesCount; i++) {
height += textures[i].Height;
diff --git a/src/Client/WinPlatform.c b/src/Client/WinPlatform.c
index b31a9a2ee..ad8f04ae9 100644
--- a/src/Client/WinPlatform.c
+++ b/src/Client/WinPlatform.c
@@ -173,32 +173,31 @@ ReturnCode Platform_DirectoryCreate(STRING_PURE String* path) {
}
ReturnCode Platform_EnumFiles(STRING_PURE String* path, void* obj, Platform_EnumFilesCallback callback) {
- /* Need to do directory\* to search for files in directory */
- UChar searchPatternBuffer[FILENAME_SIZE + 10];
- String searchPattern = String_InitAndClearArray(searchPatternBuffer);
- String_Format1(&searchPattern, "%s\\*", path);
+ WCHAR data[512]; Platform_UnicodeExpand(data, path);
+ /* Need to append \* to search for files in directory */
+ data[path->length + 0] = '\\';
+ data[path->length + 1] = '*';
+ data[path->length + 2] = NULL;
- WCHAR searchUnicode[String_BufferSize(FILENAME_SIZE)];
- Platform_UnicodeExpand(searchUnicode, &searchPattern);
-
- WIN32_FIND_DATAW data;
- HANDLE find = FindFirstFileW(searchUnicode, &data);
+ WIN32_FIND_DATAW entry;
+ HANDLE find = FindFirstFileW(data, &entry);
if (find == INVALID_HANDLE_VALUE) return GetLastError();
+ UInt8 fileBuffer[String_BufferSize(MAX_PATH)];
+ String file = String_InitAndClearArray(fileBuffer);
+
do {
- if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
- String path = String_Init((UChar*)data.cFileName, 0, MAX_PATH);
+ if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) continue;
+ String_Clear(&file);
Int32 i;
- /* unicode to code page 437*/
- for (i = 0; i < MAX_PATH && data.cFileName[i] != NULL; i++) {
- path.buffer[i] = Convert_UnicodeToCP437(data.cFileName[i]);
+ for (i = 0; i < MAX_PATH && entry.cFileName[i] != NULL; i++) {
+ String_Append(&file, Convert_UnicodeToCP437(entry.cFileName[i]));
}
- path.length = i;
- String filename = path; Utils_UNSAFE_GetFilename(&filename);
- callback(&filename, obj);
- } while (FindNextFileW(find, &data));
+ Utils_UNSAFE_GetFilename(&file);
+ callback(&file, obj);
+ } while (FindNextFileW(find, &entry));
ReturnCode code = GetLastError(); /* return code from FindNextFile */
FindClose(find);
@@ -308,17 +307,12 @@ void Platform_ThreadFreeHandle(void* handle) {
}
}
-CRITICAL_SECTION mutexList[3];
-Int32 mutexIndex;
+CRITICAL_SECTION mutexList[3]; Int32 mutexIndex;
void* Platform_MutexCreate(void) {
- if (mutexIndex == Array_Elems(mutexList)) {
- ErrorHandler_Fail("Cannot allocate another mutex");
- return NULL;
- } else {
- CRITICAL_SECTION* ptr = &mutexList[mutexIndex];
- InitializeCriticalSection(ptr); mutexIndex++;
- return ptr;
- }
+ if (mutexIndex == Array_Elems(mutexList)) ErrorHandler_Fail("Cannot allocate mutex");
+ CRITICAL_SECTION* ptr = &mutexList[mutexIndex];
+ InitializeCriticalSection(ptr); mutexIndex++;
+ return ptr;
}
void Platform_MutexFree(void* handle) {
diff --git a/src/Client/WinWindow.c b/src/Client/WinWindow.c
index 9d8eb5da9..6386f9799 100644
--- a/src/Client/WinWindow.c
+++ b/src/Client/WinWindow.c
@@ -380,7 +380,7 @@ static LRESULT CALLBACK Window_Procedure(HWND handle, UINT message, WPARAM wPara
case WM_DESTROY:
Window_Exists = false;
UnregisterClassA(win_ClassName, win_Instance);
- if (win_DC != NULL) ReleaseDC(win_Handle, win_DC);
+ if (win_DC) ReleaseDC(win_Handle, win_DC);
Event_RaiseVoid(&WindowEvents_Closed);
break;
}
@@ -449,12 +449,12 @@ void Window_GetClipboardText(STRING_TRANSIENT String* value) {
UInt8 c;
if (isUnicode) {
UInt16* text = (UInt16*)src;
- for (; *text != NULL; text++) {
+ for (; *text; text++) {
if (Convert_TryUnicodeToCP437(*text, &c)) String_Append(value, c);
}
} else {
UChar* text = (UChar*)src;
- for (; *text != NULL; text++) {
+ for (; *text; text++) {
if (Convert_TryUnicodeToCP437(*text, &c)) String_Append(value, c);
}
}
@@ -611,7 +611,7 @@ void Window_ProcessEvents(void) {
}
HWND foreground = GetForegroundWindow();
- if (foreground != NULL) {
+ if (foreground) {
Window_Focused = foreground == win_Handle;
}
}
diff --git a/src/Client/PosixPlatform.c b/src/Client/X11Platform.c
similarity index 74%
rename from src/Client/PosixPlatform.c
rename to src/Client/X11Platform.c
index 2d2612c1b..19ec768a3 100644
--- a/src/Client/PosixPlatform.c
+++ b/src/Client/X11Platform.c
@@ -1,10 +1,10 @@
#include "Platform.h"
-#define CC_BUILD_X11 0
#if CC_BUILD_X11
#include "PackedCol.h"
#include "Drawer2D.h"
#include "Stream.h"
#include "ErrorHandler.h"
+#include "Constants.h"
#include
#include
#include
@@ -35,8 +35,9 @@ static void Platform_UnicodeExpand(UInt8* dst, STRING_PURE String* src) {
*dst = NULL;
}
-void Platform_Init(void);
-void Platform_Free(void);
+void Platform_Init(void) { }
+void Platform_Free(void) { }
+
void Platform_Exit(ReturnCode code) { exit(code); }
STRING_PURE String Platform_GetCommandLineArgs(void);
@@ -123,15 +124,23 @@ ReturnCode Platform_EnumFiles(STRING_PURE String* path, void* obj, Platform_Enum
DIR* dirPtr = opendir(data);
if (dirPtr == NULL) return errno;
+ UInt8 fileBuffer[String_BufferSize(FILENAME_SIZE)];
+ String file = String_InitAndClearArray(fileBuffer);
struct dirent* entry;
+
+ /* TODO: does this also include subdirectories */
while (entry = readdir(dirPtr)) {
- puts(ep->d_name);
- /* TODO: does this also include subdirectories */
+ UInt16 len = String_CalcLen(entry->d_name, UInt16_MaxValue);
+ String_Clear(&file);
+ String_DecodeUtf8(&file, entry->d_name, len);
+
+ Utils_UNSAFE_GetFilename(&file);
+ callback(&file, obj);
}
int result = errno; /* return code from readdir */
closedir(dirPtr);
- return result;
+ return result;
}
ReturnCode Platform_FileGetModifiedTime(STRING_PURE String* path, DateTime* time) {
@@ -200,17 +209,60 @@ ReturnCode Platform_FileLength(void* file, UInt32* length) {
*length = st.st_size; return 0;
}
-void Platform_ThreadSleep(UInt32 milliseconds);
-typedef void Platform_ThreadFunc(void);
-void* Platform_ThreadStart(Platform_ThreadFunc* func);
-void Platform_ThreadJoin(void* handle);
-/* Frees handle to thread - NOT THE THREAD ITSELF */
-void Platform_ThreadFreeHandle(void* handle);
+void Platform_ThreadSleep(UInt32 milliseconds) {
+ usleep(milliseconds * 1000);
+}
-void* Platform_MutexCreate(void);
-void Platform_MutexFree(void* handle);
-void Platform_MutexLock(void* handle);
-void Platform_MutexUnlock(void* handle);
+void* Platform_ThreadStartCallback(void* lpParam) {
+ Platform_ThreadFunc* func = (Platform_ThreadFunc*)lpParam;
+ (*func)();
+ return NULL;
+}
+
+pthread_t threadList[3]; Int32 threadIndex;
+void* Platform_ThreadStart(Platform_ThreadFunc* func) {
+ if (threadIndex == Array_Elems(threadIndex)) ErrorHandler_Fail("Cannot allocate thread");
+ pthread_t* ptr = &threadList[threadIndex];
+ int result = pthread_create(ptr, NULL, Platform_ThreadStartCallback, func);
+
+ ErrorHandler_CheckOrFail(result, "Creating thread");
+ threadIndex++; return ptr;
+}
+
+void Platform_ThreadJoin(void* handle) {
+ int result = pthread_join(*((pthread_t*)handle), NULL);
+ ErrorHandler_CheckOrFail(result, "Joining thread");
+}
+
+void Platform_ThreadFreeHandle(void* handle) {
+ int result = pthread_detach(*((pthread_t*)handle));
+ ErrorHandler_CheckOrFail(result, "Detaching thread");
+}
+
+pthread_mutex_t mutexList[3]; Int32 mutexIndex;
+void* Platform_MutexCreate(void) {
+ if (mutexIndex == Array_Elems(mutexList)) ErrorHandler_Fail("Cannot allocate mutex");
+ pthread_mutex_t* ptr = &mutexList[mutexIndex];
+ int result = pthread_mutex_init(ptr, NULL);
+
+ ErrorHandler_CheckOrFail(result, "Creating mutex");
+ mutexIndex++; return ptr;
+}
+
+void Platform_MutexFree(void* handle) {
+ int result = pthread_mutex_destroy((pthread_mutex_t*)handle);
+ ErrorHandler_CheckOrFail(result, "Destroying mutex");
+}
+
+void Platform_MutexLock(void* handle) {
+ int result = pthread_mutex_lock((pthread_mutex_t*)handle);
+ ErrorHandler_CheckOrFail(result, "Locking mutex");
+}
+
+void Platform_MutexUnlock(void* handle) {
+ int result = pthread_mutex_unlock((pthread_mutex_t*)handle);
+ ErrorHandler_CheckOrFail(result, "Unlocking mutex");
+}
void* Platform_EventCreate(void);
void Platform_EventFree(void* handle);
diff --git a/src/Client/X11Window.c b/src/Client/X11Window.c
index c4a458f3b..a321a750f 100644
--- a/src/Client/X11Window.c
+++ b/src/Client/X11Window.c
@@ -261,7 +261,7 @@ UInt8 Window_GetWindowState(void) {
Int32 maximised = 0, i;
/* TODO: Check this works right */
- if (items > 0 && data != NULL) {
+ if (data && items) {
for (i = 0; i < items; i++) {
Atom atom = data[i];
@@ -274,8 +274,8 @@ UInt8 Window_GetWindowState(void) {
fullscreen = true;
}
}
- XFree(data);
}
+ if (data) XFree(data);
if (minimised) return WINDOW_STATE_MINIMISED;
if (maximised == 2) return WINDOW_STATE_MAXIMISED;
@@ -427,8 +427,8 @@ void Window_ToggleKey(XKeyEvent* keyEvent, bool pressed) {
}
Atom Window_GetSelectionProperty(XEvent* e) {
- Atom property = e->xselectionrequest.property;
- if (property != NULL) return property;
+ Atom prop = e->xselectionrequest.property;
+ if (prop) return prop;
/* For obsolete clients. See ICCCM spec, selections chapter for reasoning. */
return e->xselectionrequest.target;
@@ -479,17 +479,15 @@ void Window_ProcessEvents(void) {
case KeyPress:
{
ToggleKey(&e.xkey, true);
- UInt8 data[16];
+ UInt8 data[16]; UInt8 convBuffer[16];
int status = XLookupString(&e.xkey, data, Array_Elems(data), NULL, NULL);
- String name = String_FromConst("Translate key press");
- struct Stream mem; Stream_ReadonlyMemory(&mem, data, status, &name);
-
/* TODO: Is this even right... */
- UInt16 codepoint;
- while (Stream_ReadUtf8Char(&mem, &codepoint)) {
- Event_RaiseInt(&KeyEvents_Press, Convert_UnicodeToCP437(codepoint));
- }
+ String conv = String_FromEmptyArray(convBuffer);
+ String_DecodeUtf8(&conv, data, status);
+
+ Int32 i;
+ for (i = 0; i < conv.length; i++) { Event_RaiseInt(&KeyEvents_Press, conv.buffer[i]); }
} break;
case KeyRelease:
@@ -559,21 +557,13 @@ void Window_ProcessEvents(void) {
XGetWindowProperty(win_display, win_handle, xa_data_sel, 0, 1024, false, NULL,
&prop_type, &prop_format, items, &bytes_after, &data);
-
XDeleteProperty(win_display, win_handle, xa_data_sel);
- if (items == 0) break;
-
- if (prop_type == xa_utf8_string) {
- String name = String_FromConst("Clipboard get");
- struct Stream mem; Stream_ReadonlyMemory(&mem, data, items, &name);
+ if (data && items && prop_type == xa_utf8_string) {
String_Clear(&clipboard_paste_text);
- UInt16 codepoint;
- while (Stream_ReadUtf8Char(&mem, &codepoint)) {
- String_Append(&clipboard_paste_text, Convert_UnicodeToCP437(codepoint));
- }
+ String_DecodeUtf8(&clipboard_paste_text, data, items);
}
- XFree(data);
+ if (data) XFree(data);
}
break;
@@ -737,10 +727,10 @@ static void GLContext_GetAttribs(struct GraphicsMode mode, Int32* attribs) {
attribs[i++] = GLX_BLUE_SIZE; attribs[i++] = color.B;
attribs[i++] = GLX_ALPHA_SIZE; attribs[i++] = color.A;
- if (mode.DepthBits > 0) {
+ if (mode.DepthBits) {
attribs[i++] = GLX_DEPTH_SIZE; attribs[i++] = mode.DepthBits;
}
- if (mode.StencilBits > 0) {
+ if (mode.StencilBits) {
attribs[i++] = GLX_STENCIL_SIZE; attribs[i++] = mode.StencilBits;
}
if (mode.Buffers > 1) {
@@ -761,7 +751,7 @@ static XVisualInfo GLContext_SelectVisual(struct GraphicsMode* mode) {
if (major >= 1 && minor >= 3) {
/* ChooseFBConfig returns an array of GLXFBConfig opaque structures */
GLXFBConfig* fbconfigs = glXChooseFBConfig(win_display, win_screen, attribs, &fbcount);
- if (fbcount > 0 && fbconfigs != NULL) {
+ if (fbconfigs && fbcount) {
/* Use the first GLXFBConfig from the fbconfigs array (best match) */
visual = glXGetVisualFromFBConfig(win_display, *fbconfigs);
XFree(fbconfigs);