Merge branch 'master' of github.com:UnknownShadow200/ClassicalSharp

This commit is contained in:
UnknownShadow200 2017-04-13 07:55:51 +10:00
commit 99733d2ab3
9 changed files with 235 additions and 37 deletions

View file

@ -9,11 +9,14 @@
// defined with this macro as being exported.
#ifdef CLIENT_EXPORTS
#define CLIENT_API __declspec(dllexport)
#define CLIENT_FUNC __declspec(dllexport)
#else
#define CLIENT_API __declspec(dllimport)
#define CLIENT_FUNC __declspec(dllimport)
#endif
#define EXPORT_FUNC __declspec(dllexport)
#define IMPORT_FUNC __declspec(dllimport)
/*
#include "Client.h"

View file

@ -1,6 +1,7 @@
#ifndef CS_FUNCS_H
#define CS_FUNCS_H
#define min(x, y) (x) < (y) ? (x) : (y)
#define max(x, y) (x) > (y) ? (x) : (y)
#define min(x, y) ((x) < (y) ? (x) : (y))
#define max(x, y) ((x) > (y) ? (x) : (y))
#define abs(x) (x >= 0 ? x : -x)
#endif

View file

@ -7,7 +7,7 @@ void ImprovedNoise_Init(UInt8* p, Random* rnd) {
}
for (Int32 i = 0; i < 256; i++) {
Int32 j = Random_NextRange(rnd, i, 256);
Int32 j = Random_Range(rnd, i, 256);
UInt8 temp = p[i]; p[i] = p[j]; p[j] = temp;
}
@ -16,14 +16,14 @@ void ImprovedNoise_Init(UInt8* p, Random* rnd) {
}
}
Real64 ImprovedNoise_Compute(UInt8* p, Real64 x, Real64 y) {
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;
Real64 u = x * x * x * (x * (x * 6 - 15) + 10); /* Fade(x) */
Real64 v = y * y * y * (y * (y * 6 - 15) + 10); /* Fade(y) */
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
@ -33,16 +33,16 @@ Real64 ImprovedNoise_Compute(UInt8* p, Real64 x, Real64 y) {
#define yFlags 0x2222550A
Int32 hash = (p[p[A]] & 0xF) << 1;
Real64 g22 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[A], x, y) */
Real32 g22 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[A], x, y) */
hash = (p[p[B]] & 0xF) << 1;
Real64 g12 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * y; /* Grad(p[p[B], x - 1, y) */
Real64 c1 = g22 + u * (g12 - g22);
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;
Real64 g21 = (((xFlags >> hash) & 3) - 1) * x + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[A + 1], x, y - 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;
Real64 g11 = (((xFlags >> hash) & 3) - 1) * (x - 1) + (((yFlags >> hash) & 3) - 1) * (y - 1); /* Grad(p[p[B + 1], x - 1, y - 1) */
Real64 c2 = g21 + u * (g11 - g21);
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);
}
@ -55,12 +55,12 @@ void OctaveNoise_Init(OctaveNoise* n, Random* rnd, Int32 octaves) {
}
}
Real64 OctaveNoise_Compute(OctaveNoise* n, Real64 x, Real64 y) {
Real64 amplitude = 1, freq = 1;
Real64 sum = 0;
Real32 OctaveNoise_Calc(OctaveNoise* n, Real32 x, Real32 y) {
Real32 amplitude = 1, freq = 1;
Real32 sum = 0;
for (Int32 i = 0; i < n->octaves; i++) {
sum += ImprovedNoise_Compute(n->p[i], x * freq, y * freq) * amplitude;
sum += ImprovedNoise_Calc(n->p[i], x * freq, y * freq) * amplitude;
amplitude *= 2.0;
freq *= 0.5;
}
@ -73,7 +73,7 @@ void CombinedNoise_Init(CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 oct
OctaveNoise_Init(&n->noise2, rnd, octaves2);
}
Real64 CombinedNoise_Compute(CombinedNoise* n, Real64 x, Real64 y) {
Real64 offset = OctaveNoise_Compute(&n->noise2, x, y);
return OctaveNoise_Compute(&n->noise1, x + offset, y);
Real32 CombinedNoise_Calc(CombinedNoise* n, Real32 x, Real32 y) {
Real32 offset = OctaveNoise_Calc(&n->noise2, x, y);
return OctaveNoise_Calc(&n->noise1, x + offset, y);
}

View file

@ -5,7 +5,7 @@
#define NOISE_TABLE_SIZE 512
void ImprovedNoise_Init(UInt8* p, Random* rnd);
Real64 ImprovedNoise_Compute(UInt8* p, Real64 x, Real64 y);
Real32 ImprovedNoise_Calc(UInt8* p, Real32 x, Real32 y);
/* since we need structure to be a fixed size */
@ -15,7 +15,7 @@ typedef struct {
Int32 octaves;
} OctaveNoise;
void OctaveNoise_Init(OctaveNoise* n, Random* rnd, Int32 octaves);
Real64 OctaveNoise_Compute(OctaveNoise* n, Real64 x, Real64 y);
Real32 OctaveNoise_Calc(OctaveNoise* n, Real32 x, Real32 y);
typedef struct {
@ -23,6 +23,6 @@ typedef struct {
OctaveNoise noise2;
} CombinedNoise;
void CombinedNoise_Init(CombinedNoise* n, Random* rnd, Int32 octaves1, Int32 octaves2);
Real64 CombinedNoise_Compute(CombinedNoise* n, Real64 x, Real64 y);
Real32 CombinedNoise_Calc(CombinedNoise* n, Real32 x, Real32 y);
#endif

View file

@ -15,7 +15,7 @@ Real32 CurrentProgress;
/* Internal variables */
Int32 Width, Height, Length;
Int32 waterLevel, oneY, minHeight;
Int32 waterLevel, oneY, volume, minHeight;
BlockID* Blocks;
Int16* Heightmap;
Random rnd;
@ -26,6 +26,7 @@ void NotchyGen_Init(Int32 width, Int32 height, Int32 length,
Blocks = blocks; Heightmap = heightmap;
oneY = Width * Length;
volume = Width * Length * Height;
waterLevel = Height / 2;
Random_Init(&rnd, seed);
minHeight = Height;
@ -47,10 +48,10 @@ void NotchyGen_CreateHeightmap() {
for (Int32 z = 0; z < Length; z++) {
CurrentProgress = (Real32)z / Length;
for (Int32 x = 0; x < Width; x++) {
Real64 hLow = CombinedNoise_Compute(&n1, x * 1.3f, z * 1.3f) / 6 - 4, height = hLow;
Real32 hLow = CombinedNoise_Calc(&n1, x * 1.3f, z * 1.3f) / 6 - 4, height = hLow;
if (OctaveNoise_Compute(&n3, x, z) <= 0) {
Real64 hHigh = CombinedNoise_Compute(&n2, x * 1.3f, z * 1.3f) / 5 + 6;
if (OctaveNoise_Calc(&n3, x, z) <= 0) {
Real32 hHigh = CombinedNoise_Calc(&n2, x * 1.3f, z * 1.3f) / 5 + 6;
height = max(hLow, hHigh);
}
@ -75,7 +76,7 @@ void NotchyGen_CreateStrata() {
for (Int32 z = 0; z < Length; z++) {
CurrentProgress = (Real32)z / Length;
for (Int32 x = 0; x < Width; x++) {
Int32 dirtThickness = (Int32)(OctaveNoise_Compute(&n, x, z) / 24 - 4);
Int32 dirtThickness = (Int32)(OctaveNoise_Calc(&n, x, z) / 24 - 4);
Int32 dirtHeight = Heightmap[hMapIndex++];
Int32 stoneHeight = dirtHeight + dirtThickness;
@ -100,7 +101,7 @@ Int32 NotchyGen_CreateStrataFast() {
/* Make lava layer at bottom */
Int32 mapIndex = 0;
for (Int32 z = 0; z < Length; z++)
for (int x = 0; x < Width; x++)
for (Int32 x = 0; x < Width; x++)
{
Blocks[mapIndex++] = Block_Lava;
}
@ -117,4 +118,188 @@ Int32 NotchyGen_CreateStrataFast() {
Blocks[mapIndex++] = Block_Stone;
}
return stoneHeight;
}
void NotchyGen_CreateSurfaceLayer() {
OctaveNoise n1, n2;
OctaveNoise_Init(&n1, &rnd, 8);
OctaveNoise_Init(&n2, &rnd, 8);
//CurrentState = "Creating surface";
/* TODO: update heightmap */
Int32 hMapIndex = 0;
for (Int32 z = 0; z < Length; z++) {
CurrentProgress = (Real32)z / Length;
for (Int32 x = 0; x < Width; x++) {
Int32 y = Heightmap[hMapIndex++];
if (y < 0 || y >= Height) continue;
Int32 index = (y * Length + z) * Width + x;
BlockID blockAbove = y >= (Height - 1) ? Block_Air : Blocks[index + oneY];
if (blockAbove == Block_Water && (OctaveNoise_Calc(&n2, x, z) > 12)) {
Blocks[index] = Block_Gravel;
} else if (blockAbove == Block_Air) {
Blocks[index] = (y <= waterLevel && (OctaveNoise_Calc(&n1, x, z) > 8)) ? Block_Sand : Block_Grass;
}
}
}
}
void NotchyGen_PlantFlowers() {
Int32 numPatches = Width * Length / 3000;
//CurrentState = "Planting flowers";
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
BlockID type = (BlockID)(Block_Dandelion + Random_Next(&rnd, 2));
Int32 patchX = Random_Next(&rnd, Width), patchZ = Random_Next(&rnd, Length);
for (Int32 j = 0; j < 10; j++) {
Int32 flowerX = patchX, flowerZ = patchZ;
for (Int32 k = 0; k < 5; k++) {
flowerX += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
flowerZ += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
if (flowerX < 0 || flowerZ < 0 || flowerX >= Width || flowerZ >= Length)
continue;
Int32 flowerY = Heightmap[flowerZ * Width + flowerX] + 1;
if (flowerY <= 0 || flowerY >= Height) continue;
Int32 index = (flowerY * Length + flowerZ) * Width + flowerX;
if (Blocks[index] == Block_Air && Blocks[index - oneY] == Block_Grass)
Blocks[index] = type;
}
}
}
}
void NotchyGen_PlantMushrooms() {
Int32 numPatches = volume / 2000;
//CurrentState = "Planting mushrooms";
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
BlockID type = (BlockID)(Block_BrownMushroom + Random_Next(&rnd, 2));
Int32 patchX = Random_Next(&rnd, Width);
Int32 patchY = Random_Next(&rnd, Height);
Int32 patchZ = Random_Next(&rnd, Length);
for (Int32 j = 0; j < 20; j++) {
Int32 mushX = patchX, mushY = patchY, mushZ = patchZ;
for (Int32 k = 0; k < 5; k++) {
mushX += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
mushZ += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
if (mushX < 0 || mushZ < 0 || mushX >= Width || mushZ >= Length)
continue;
Int32 solidHeight = Heightmap[mushZ * Width + mushX];
if (mushY >= (solidHeight - 1))
continue;
Int32 index = (mushY * Length + mushZ) * Width + mushX;
if (Blocks[index] == Block_Air && Blocks[index - oneY] == Block_Stone)
Blocks[index] = type;
}
}
}
}
void NotchyGen_PlantTrees() {
Int32 numPatches = Width * Length / 4000;
//CurrentState = "Planting trees";
for (Int32 i = 0; i < numPatches; i++) {
CurrentProgress = (Real32)i / numPatches;
Int32 patchX = Random_Next(&rnd, Width), patchZ = Random_Next(&rnd, Length);
for (Int32 j = 0; j < 20; j++) {
Int32 treeX = patchX, treeZ = patchZ;
for (Int32 k = 0; k < 20; k++) {
treeX += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
treeZ += Random_Next(&rnd, 6) - Random_Next(&rnd, 6);
if (treeX < 0 || treeZ < 0 || treeX >= Width ||
treeZ >= Length || Random_Float(&rnd) >= 0.25)
continue;
Int32 treeY = Heightmap[treeZ * Width + treeX] + 1;
Int32 treeHeight = 5 + Random_Next(&rnd, 3);
Int32 index = (treeY * Length + treeZ) * Width + treeX;
BlockID blockUnder = treeY > 0 ? Blocks[index - oneY] : Block_Air;
if (blockUnder == Block_Grass && NotchyGen_CanGrowTree(treeX, treeY, treeZ, treeHeight)) {
NotchyGen_GrowTree(treeX, treeY, treeZ, treeHeight);
}
}
}
}
}
bool NotchyGen_CanGrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight) {
// check tree base
Int32 baseHeight = treeHeight - 4;
for (Int32 y = treeY; y < treeY + baseHeight; y++)
for (Int32 z = treeZ - 1; z <= treeZ + 1; z++)
for (Int32 x = treeX - 1; x <= treeX + 1; x++)
{
if (x < 0 || y < 0 || z < 0 || x >= Width || y >= Height || z >= Length)
return false;
Int32 index = (y * Length + z) * Width + x;
if (Blocks[index] != 0) return false;
}
// 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++)
{
if (x < 0 || y < 0 || z < 0 || x >= Width || y >= Height || z >= Length)
return false;
Int32 index = (y * Length + z) * Width + x;
if (Blocks[index] != 0) return false;
}
return true;
}
void Notchy_GenTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height) {
Int32 baseHeight = height - 4;
Int32 index = 0;
// 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++)
{
Int32 x = xx + treeX, z = zz + treeZ;
index = (y * Length + z) * Width + x;
if (abs(xx) == 2 && abs(zz) == 2) {
if (Random_Float(&rnd) >= 0.5f)
Blocks[index] = Block_Leaves;
} else {
Blocks[index] = Block_Leaves;
}
}
// 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++)
for (Int32 xx = -1; xx <= 1; xx++)
{
Int32 x = xx + treeX, z = zz + treeZ;
index = (y * Length + z) * Width + x;
if (xx == 0 || zz == 0) {
Blocks[index] = Block_Leaves;
} else if (y == bottomY && Random_Float(&rnd) >= 0.5f) {
Blocks[index] = Block_Leaves;
}
}
// then place trunk
index = (treeY * Length + treeZ) * Width + treeX;
for (Int32 y = 0; y < height - 1; y++) {
Blocks[index] = Block_Log;
index += oneY;
}
}

View file

@ -3,10 +3,16 @@
#include "Compiler.h"
#include "Typedefs.h"
CLIENT_API void NotchyGen_Init(Int32 width, Int32 height, Int32 length,
CLIENT_FUNC void NotchyGen_Init(Int32 width, Int32 height, Int32 length,
Int32 seed, BlockID* blocks, Int16* heightmap);
CLIENT_API void NotchyGen_CreateHeightmap();
CLIENT_API void NotchyGen_CreateStrata();
CLIENT_FUNC void NotchyGen_CreateHeightmap();
CLIENT_FUNC void NotchyGen_CreateStrata();
Int32 NotchyGen_CreateStrataFast();
CLIENT_FUNC void NotchyGen_CreateSurfaceLayer();
CLIENT_FUNC void NotchyGen_PlantFlowers();
CLIENT_FUNC void NotchyGen_PlantMushrooms();
CLIENT_FUNC void NotchyGen_PlantTrees();
bool NotchyGen_CanGrowTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 treeHeight);
void Notchy_GenTree(Int32 treeX, Int32 treeY, Int32 treeZ, Int32 height);
#endif

View file

@ -9,7 +9,7 @@ void Random_Init(Random* seed, Int32 seedInit) {
*seed = (seedInit ^ value) & mask;
}
Int32 Random_NextRange(Random* seed, Int32 min, Int32 max) {
Int32 Random_Range(Random* seed, Int32 min, Int32 max) {
return min + Random_Next(seed, max - min);
}
@ -29,7 +29,7 @@ Int32 Random_Next(Random* seed, Int32 n) {
return val;
}
Real32 Random_NextFloat(Random* seed) {
Real32 Random_Float(Random* seed) {
*seed = (*seed * value + 0xBLL) & mask;
Int32 raw = (Int32)((UInt64)*seed >> (48 - 24));
return raw / ((Real32)(1 << 24));

View file

@ -6,7 +6,7 @@
typedef Int64 Random;
void Random_Init(Random* rnd, Int32 seed);
Int32 Random_NextRange(Random* rnd, Int32 min, Int32 max);
Int32 Random_Range(Random* rnd, Int32 min, Int32 max);
Int32 Random_Next(Random* rnd, Int32 n);
Real32 Random_NextFloat(Random* rnd);
Real32 Random_Float(Random* rnd);
#endif

View file

@ -15,6 +15,9 @@ typedef signed __int64 Int64;
typedef float Real32;
typedef double Real64;
typedef UInt8 bool;
#define true 1
#define false 0
typedef UInt8 BlockID;
typedef UInt8 EntityID;