improve String API

This commit is contained in:
UnknownShadow200 2017-04-29 19:43:36 +10:00
parent bcbb4824f8
commit 8075786147
5 changed files with 65 additions and 51 deletions

View File

@ -5,16 +5,18 @@
void Block_Reset(Game* game) {
Block_Init();
// TODO: Make this part of TerrainAtlas2D maybe?
/* TODO: Make this part of TerrainAtlas2D maybe? */
//Block_RecalculateSpriteBB(game->TerrainAtlas.AtlasBitmap);
}
void Block_Init() {
#define DefinedCustomBlocks_Len (Block_Count >> 5)
for (Int32 i = 0; i < DefinedCustomBlocks_Len; i++)
for (Int32 i = 0; i < DefinedCustomBlocks_Len; i++) {
DefinedCustomBlocks[i] = 0;
for (Int32 block = 0; block < Block_Count; block++)
}
for (Int32 block = 0; block < Block_Count; block++) {
Block_ResetProps((BlockID)block);
}
Block_UpdateCullingAll();
}
@ -33,11 +35,11 @@ void Block_SetDefaultPerms() {
}
void Block_SetCollide(BlockID block, UInt8 collide) {
// necessary for cases where servers redefined core blocks before extended types were introduced
/* necessary for cases where servers redefined core blocks before extended types were introduced. */
collide = DefaultSet_MapOldCollide(block, collide);
Block_ExtendedCollide[block] = collide;
// Reduce extended collision types to their simpler forms
/* Reduce extended collision types to their simpler forms. */
if (collide == CollideType_Ice) collide = CollideType_Solid;
if (collide == CollideType_SlipperyIce) collide = CollideType_Solid;
@ -47,8 +49,9 @@ void Block_SetCollide(BlockID block, UInt8 collide) {
}
void Block_SetDrawType(BlockID block, UInt8 draw) {
if (draw == DrawType_Opaque && Block_Collide[block] != CollideType_Solid)
if (draw == DrawType_Opaque && Block_Collide[block] != CollideType_Solid) {
draw = DrawType_Transparent;
}
Block_Draw[block] = draw;
Vector3 zero = Vector3_Zero, one = Vector3_One;
@ -85,7 +88,7 @@ void Block_ResetProps(BlockID block) {
if (block >= Block_CpeCount) {
#if USE16_BIT
// give some random texture ids
/* give some random texture ids */
Block_SetTex((block * 10 + (block % 7) + 20) % 80, Side_Top, block);
Block_SetTex((block * 8 + (block & 5) + 5) % 80, Side_Bottom, block);
Block_SetSide((block * 4 + (block / 4) + 4) % 80, block);
@ -117,16 +120,13 @@ String Block_DefaultName(BlockID block) {
if (block >= 256) return "ID " + block;
#endif
if (block >= Block_CpeCount) {
String str;
String_Constant(&str, "Invalid");
return str;
return String_FromConstant("Invalid");
}
String blockNames;
// TODO: how much performance impact here
String_Constant(&blockNames, Block_RawNames);
/* TODO: how much performance impact here. */
String blockNames = String_FromConstant(Block_RawNames);
// Find start and end of this particular block name
/* Find start and end of this particular block name. */
Int32 start = 0;
for (Int32 i = 0; i < block; i++) {
start = String_IndexOf(&blockNames, ' ', start) + 1;
@ -134,8 +134,7 @@ String Block_DefaultName(BlockID block) {
Int32 end = String_IndexOf(&blockNames, ' ', start);
if (end == -1) end = blockNames.length;
String buffer;
String_Empty(&buffer, Block_NamePtr(block), STRING_SIZE);
String buffer = String_FromBuffer(Block_NamePtr(block), STRING_SIZE);
Block_SplitUppercase(&buffer, &blockNames, start, end);
return buffer;
}
@ -218,8 +217,7 @@ void Block_CalcRenderBounds(BlockID block) {
min.X -= 0.1f / 16.0f; max.X -= 0.1f / 16.0f;
min.Z -= 0.1f / 16.0f; max.Z -= 0.1f / 16.0f;
min.Y -= 1.5f / 16.0f; max.Y -= 1.5f / 16.0f;
}
else if (Block_Draw[block] == DrawType_Translucent && Block_Collide[block] != CollideType_Solid) {
} else if (Block_Draw[block] == DrawType_Translucent && Block_Collide[block] != CollideType_Solid) {
min.X += 0.1f / 16.0f; max.X += 0.1f / 16.0f;
min.Z += 0.1f / 16.0f; max.Z += 0.1f / 16.0f;
min.Y -= 0.1f / 16.0f; max.Y -= 0.1f / 16.0f;
@ -274,8 +272,9 @@ Real32 Block_GetSpriteBB_TopY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp)
for (Int32 y = 0; y < size; y++) {
UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
for (Int32 x = 0; x < size; x++) {
if ((UInt8)(row[x] >> 24) != 0)
if ((UInt8)(row[x] >> 24) != 0) {
return 1 - (float)y / size;
}
}
}
return 0;
@ -285,8 +284,9 @@ Real32 Block_GetSpriteBB_BottomY(Int32 size, Int32 tileX, Int32 tileY, Bitmap* b
for (Int32 y = size - 1; y >= 0; y--) {
UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
for (Int32 x = 0; x < size; x++) {
if ((UInt8)(row[x] >> 24) != 0)
if ((UInt8)(row[x] >> 24) != 0) {
return 1 - (float)(y + 1) / size;
}
}
}
return 1;
@ -296,8 +296,9 @@ Real32 Block_GetSpriteBB_LeftX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bmp
for (Int32 x = 0; x < size; x++) {
for (Int32 y = 0; y < size; y++) {
UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
if ((UInt8)(row[x] >> 24) != 0)
if ((UInt8)(row[x] >> 24) != 0) {
return (float)x / size;
}
}
}
return 1;
@ -307,8 +308,9 @@ Real32 Block_GetSpriteBB_RightX(Int32 size, Int32 tileX, Int32 tileY, Bitmap* bm
for (Int32 x = size - 1; x >= 0; x--) {
for (Int32 y = 0; y < size; y++) {
UInt32* row = Bitmap_GetRow(bmp, tileY * size + y) + (tileX * size);
if ((UInt8)(row[x] >> 24) != 0)
if ((UInt8)(row[x] >> 24) != 0) {
return (float)(x + 1) / size;
}
}
}
return 0;
@ -367,22 +369,22 @@ void Block_CalcCulling(BlockID block, BlockID other) {
}
bool Block_IsHidden(BlockID block, BlockID other, Int32 side) {
// Sprite blocks can never hide faces.
/* Sprite blocks can never hide faces. */
if (Block_Draw[block] == DrawType_Sprite) return false;
// NOTE: Water is always culled by lava
/* NOTE: Water is always culled by lava. */
if ((block == BlockID_Water || block == BlockID_StillWater)
&& (other == BlockID_Lava || other == BlockID_StillLava))
return true;
// All blocks (except for say leaves) cull with themselves.
/* All blocks (except for say leaves) cull with themselves. */
if (block == other) return Block_Draw[block] != DrawType_TransparentThick;
// An opaque neighbour (asides from lava) culls the face.
/* An opaque neighbour (asides from lava) culls the face. */
if (Block_Draw[other] == DrawType_Opaque && !Block_IsLiquid(other)) return true;
if (Block_Draw[block] != DrawType_Translucent || Block_Draw[other] != DrawType_Translucent) return false;
// e.g. for water / ice, don't need to draw water.
/* e.g. for water / ice, don't need to draw water. */
UInt8 bType = Block_Collide[block], oType = Block_Collide[other];
bool canSkip = (bType == CollideType_Solid && oType == CollideType_Solid)
|| bType != CollideType_Solid;
@ -405,11 +407,11 @@ bool Block_IsFaceHidden(BlockID block, BlockID other, Int32 side) {
}
void Block_SetXStretch(BlockID block, bool stretch) {
Block_CanStretch[block] &= 0xC3; // ~0x3C
Block_CanStretch[block] &= 0xC3; /* ~0x3C */
Block_CanStretch[block] |= (stretch ? 0x3C : (UInt8)0);
}
void Block_SetZStretch(BlockID block, bool stretch) {
Block_CanStretch[block] &= 0xFC; // ~0x03
Block_CanStretch[block] &= 0xFC; /* ~0x03 */
Block_CanStretch[block] |= (stretch ? 0x03 : (UInt8)0);
}

View File

@ -6,7 +6,7 @@
#include "ExtMath.h"
/* External variables */
/* TODO: how do they even work? */
String CurrentState;
Real32 CurrentProgress;
/* Internal variables */
@ -28,6 +28,7 @@ void NotchyGen_Init(Int32 width, Int32 height, Int32 length,
minHeight = Height;
CurrentProgress = 0.0f;
CurrentState = String_FromConstant("");
}
@ -39,7 +40,7 @@ void NotchyGen_CreateHeightmap() {
OctaveNoise_Init(&n3, &rnd, 6);
Int32 index = 0;
//CurrentState = "Building heightmap";
CurrentState = String_FromConstant("Building heightmap");
for (Int32 z = 0; z < Length; z++) {
CurrentProgress = (Real32)z / Length;
@ -64,7 +65,7 @@ void NotchyGen_CreateHeightmap() {
void NotchyGen_CreateStrata() {
OctaveNoise n;
OctaveNoise_Init(&n, &rnd, 8);
//CurrentState = "Creating strata";
CurrentState = String_FromConstant("Creating strata");
Int32 hMapIndex = 0, maxY = Height - 1, mapIndex = 0;
/* Try to bulk fill bottom of the map if possible */
Int32 minStoneY = NotchyGen_CreateStrataFast();
@ -120,7 +121,7 @@ void NotchyGen_CreateSurfaceLayer() {
OctaveNoise n1, n2;
OctaveNoise_Init(&n1, &rnd, 8);
OctaveNoise_Init(&n2, &rnd, 8);
//CurrentState = "Creating surface";
CurrentState = String_FromConstant("Creating surface");
/* TODO: update heightmap */
Int32 hMapIndex = 0;
@ -143,7 +144,7 @@ void NotchyGen_CreateSurfaceLayer() {
void NotchyGen_PlantFlowers() {
Int32 numPatches = Width * Length / 3000;
//CurrentState = "Planting flowers";
CurrentState = String_FromConstant("Planting flowers");
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
@ -170,7 +171,7 @@ void NotchyGen_PlantFlowers() {
void NotchyGen_PlantMushrooms() {
Int32 numPatches = volume / 2000;
//CurrentState = "Planting mushrooms";
CurrentState = String_FromConstant("Planting mushrooms");
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
@ -201,7 +202,7 @@ void NotchyGen_PlantMushrooms() {
void NotchyGen_PlantTrees() {
Int32 numPatches = Width * Length / 4000;
//CurrentState = "Planting trees";
CurrentState = String_FromConstant("Planting trees");
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
@ -231,7 +232,7 @@ void NotchyGen_PlantTrees() {
}
bool NotchyGen_CanGrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight) {
// check tree base
/* check tree base */
Int32 baseHeight = treeHeight - 4;
for (Int32 y = treeY; y < treeY + baseHeight; y++)
for (Int32 z = treeZ - 1; z <= treeZ + 1; z++)
@ -243,7 +244,7 @@ bool NotchyGen_CanGrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeig
if (Blocks[index] != 0) return false;
}
// and also check canopy
/* and also check canopy */
for (Int32 y = treeY + baseHeight; y < treeY + treeHeight; y++)
for (Int32 z = treeZ - 2; z <= treeZ + 2; z++)
for (Int32 x = treeX - 2; x <= treeX + 2; x++)
@ -260,7 +261,7 @@ void NotchyGen_GrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height) {
Int32 baseHeight = height - 4;
Int32 index = 0;
// leaves bottom layer
/* leaves bottom layer */
for (Int32 y = treeY + baseHeight; y < treeY + baseHeight + 2; y++)
for (Int32 zz = -2; zz <= 2; zz++)
for (Int32 xx = -2; xx <= 2; xx++)
@ -276,7 +277,7 @@ void NotchyGen_GrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height) {
}
}
// leaves top layer
/* leaves top layer */
Int32 bottomY = treeY + baseHeight + 2;
for (Int32 y = treeY + baseHeight + 2; y < treeY + height; y++)
for (Int32 zz = -1; zz <= 1; zz++)
@ -292,7 +293,7 @@ void NotchyGen_GrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height) {
}
}
// then place trunk
/* then place trunk */
index = (treeY * Length + treeZ) * Width + treeX;
for (Int32 y = 0; y < height - 1; y++) {
Blocks[index] = BlockID_Log;

View File

@ -2,6 +2,7 @@
#define CS_NOTCHY_GEN_H
#include "Compiler.h"
#include "Typedefs.h"
#include "String.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.
@ -9,6 +10,12 @@
Copyright 2014 - 2017 ClassicalSharp | Licensed under BSD-3
*/
/* Progress of current operation. */
extern Real32 CurrentProgress;
/* Name of current operation being performed. */
extern String CurrentState;
/* Initalises state for map generation. */
CLIENT_FUNC void NotchyGen_Init(Int32 width, Int32 height, Int32 length,

View File

@ -1,13 +1,15 @@
#include "String.h"
#include "Funcs.h"
void String_Empty(String* str, UInt8* buffer, UInt16 capacity) {
str->buffer = buffer;
str->capacity = capacity;
str->length = 0;
String String_FromBuffer(UInt8* buffer, UInt16 capacity) {
String str;
str.buffer = buffer;
str.capacity = capacity;
str.length = 0;
return str;
}
void String_Constant(String* str, const UInt8* buffer) {
String String_FromConstant(const UInt8* buffer) {
UInt16 length = 0;
UInt8 cur = 0;
UInt8* ptr = buffer;
@ -16,9 +18,11 @@ void String_Constant(String* str, const UInt8* buffer) {
length++; buffer++;
}
str->buffer = ptr;
str->capacity = length;
str->length = length;
String str;
str.buffer = ptr;
str.capacity = length;
str.length = length;
return str;
}
bool String_Equals(String* a, String* b) {

View File

@ -19,10 +19,10 @@ typedef struct String {
} String;
/* Constructs a new string, filled with NULL characters. */
void String_Empty(String* str, UInt8* buffer, UInt16 capacity);
String String_FromBuffer(UInt8* buffer, UInt16 capacity);
/* Constructs a new string from a constant readonly string. */
void String_Constant(String* str, const UInt8* buffer);
String String_FromConstant(const UInt8* buffer);
/* Returns whether two strings have same contents. */
bool String_Equals(String* a, String* b);