Trying to overrwrite farthest chunks to the player instead of near ones. Not working very well...
This commit is contained in:
18
gameloop.h
18
gameloop.h
@@ -255,7 +255,8 @@ int gameLoop(
|
||||
world, seed,
|
||||
chunkLoadCoords.x,
|
||||
chunkLoadCoords.y,
|
||||
chunkLoadCoords.z, 1, 1
|
||||
chunkLoadCoords.z, 1, 1,
|
||||
playerPosition
|
||||
);
|
||||
loadScreen(
|
||||
renderer,
|
||||
@@ -273,22 +274,27 @@ int gameLoop(
|
||||
case 5:
|
||||
/* Look to see if there are chunks that need to be
|
||||
loaded in*/
|
||||
for(i = 0; i < CHUNKARR_SIZE; i++) {
|
||||
if(chunkLoadNum < CHUNKARR_SIZE) {
|
||||
chunkLoadCoords.x =
|
||||
((i % CHUNKARR_DIAM) -
|
||||
((chunkLoadNum % CHUNKARR_DIAM) -
|
||||
CHUNKARR_RAD) * 64 + playerPosition.x - 64;
|
||||
chunkLoadCoords.y =
|
||||
(((i / CHUNKARR_DIAM) % CHUNKARR_DIAM) -
|
||||
(((chunkLoadNum / CHUNKARR_DIAM) % CHUNKARR_DIAM) -
|
||||
CHUNKARR_RAD) * 64 + playerPosition.y - 64;
|
||||
chunkLoadCoords.z =
|
||||
((i / (CHUNKARR_DIAM * CHUNKARR_DIAM)) -
|
||||
((chunkLoadNum / (CHUNKARR_DIAM * CHUNKARR_DIAM)) -
|
||||
CHUNKARR_RAD) * 64 + playerPosition.z - 64;
|
||||
chunkLoadNum++;
|
||||
|
||||
genChunk(
|
||||
world, seed,
|
||||
chunkLoadCoords.x,
|
||||
chunkLoadCoords.y,
|
||||
chunkLoadCoords.z, 1, 0
|
||||
chunkLoadCoords.z, 1, 0,
|
||||
playerPosition
|
||||
);
|
||||
} else {
|
||||
chunkLoadNum = 0;
|
||||
}
|
||||
|
||||
f9 = sin(cameraAngle_H),
|
||||
|
||||
45
structs.h
45
structs.h
@@ -2,15 +2,35 @@
|
||||
#define CHUNKARR_RAD (CHUNKARR_DIAM - 1) / 2
|
||||
#define CHUNKARR_SIZE CHUNKARR_DIAM*CHUNKARR_DIAM*CHUNKARR_DIAM
|
||||
|
||||
typedef struct _Coords Coords;
|
||||
typedef struct _IntCoords IntCoords;
|
||||
typedef struct _Chunk Chunk;
|
||||
typedef struct _World World;
|
||||
typedef struct _Player Player;
|
||||
typedef struct _InvSlot InvSlot;
|
||||
typedef struct _Inventory Inventory;
|
||||
typedef struct _Coords Coords;
|
||||
typedef struct _IntCoords IntCoords;
|
||||
typedef struct _Inputs Inputs;
|
||||
|
||||
/*
|
||||
_Coords
|
||||
Stores xyz coordinates
|
||||
*/
|
||||
struct _Coords {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
/*
|
||||
_IntCoords
|
||||
Stores xyz integer coordinates
|
||||
*/
|
||||
struct _IntCoords {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
/*
|
||||
_Chunk
|
||||
Stores blocks in a chunk, a hash to make it easier to look up,
|
||||
@@ -22,6 +42,7 @@ typedef struct _Inputs Inputs;
|
||||
will be sorted by coordhash.
|
||||
*/
|
||||
struct _Chunk {
|
||||
IntCoords center;
|
||||
int coordHash;
|
||||
int loaded;
|
||||
int *blocks;
|
||||
@@ -71,26 +92,6 @@ struct _Inventory {
|
||||
InvSlot armor[4];
|
||||
};
|
||||
|
||||
/*
|
||||
_Coords
|
||||
Stores xyz coordinates
|
||||
*/
|
||||
struct _Coords {
|
||||
float x;
|
||||
float y;
|
||||
float z;
|
||||
};
|
||||
|
||||
/*
|
||||
_IntCoords
|
||||
Stores xyz integer coordinates
|
||||
*/
|
||||
struct _IntCoords {
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
};
|
||||
|
||||
/*
|
||||
_Inputs
|
||||
Stores the state of the different inputs (keyboard/mouse) for
|
||||
|
||||
314
terrain.h
314
terrain.h
@@ -11,12 +11,13 @@ int setCube(
|
||||
);
|
||||
int ch_setBlock (int*, int, int, int, int);
|
||||
void genStructure (World*, int, int, int, int);
|
||||
void genChunk(
|
||||
int genChunk(
|
||||
World*,
|
||||
unsigned int,
|
||||
int, int, int,
|
||||
int,
|
||||
int
|
||||
int,
|
||||
Coords
|
||||
);
|
||||
|
||||
/*
|
||||
@@ -26,6 +27,9 @@ void genChunk(
|
||||
void initChunks(World *world) {
|
||||
static int i;
|
||||
for(i = 0; i < CHUNKARR_SIZE; i++) {
|
||||
world->chunk[i].center.x = 0;
|
||||
world->chunk[i].center.y = 0;
|
||||
world->chunk[i].center.z = 0;
|
||||
world->chunk[i].coordHash = 0;
|
||||
world->chunk[i].loaded = 0;
|
||||
world->chunk[i].blocks = NULL;
|
||||
@@ -266,14 +270,15 @@ void genStructure(
|
||||
Fills the chunk array with generated terrain. If force is set
|
||||
to true, a chunk at the same coordinates will be overwritten.
|
||||
*/
|
||||
void genChunk(
|
||||
int genChunk(
|
||||
World *world,
|
||||
unsigned int seed,
|
||||
int xOffset,
|
||||
int yOffset,
|
||||
int zOffset,
|
||||
int type,
|
||||
int force
|
||||
int force,
|
||||
Coords coords
|
||||
) {
|
||||
xOffset = (xOffset / 64) * 64;
|
||||
yOffset = (yOffset / 64) * 64;
|
||||
@@ -281,7 +286,7 @@ void genChunk(
|
||||
// To make sure structure generation accross chunks is
|
||||
// different, but predictable
|
||||
srand(seed * (xOffset * yOffset * zOffset + 1));
|
||||
int heightmap[64][64], i, x, z, loadedMin;
|
||||
int heightmap[64][64], i, x, z, loadedMin, distMax, distMaxI;
|
||||
static int count = 0;
|
||||
|
||||
Chunk *chunk = chunkLookup(world, xOffset, yOffset, zOffset);
|
||||
@@ -289,163 +294,184 @@ void genChunk(
|
||||
// Only generate if that chunk hasn't been generated yet.
|
||||
i = 0;
|
||||
if(chunk == NULL) {
|
||||
// See if there is an empty slot
|
||||
for(; i < CHUNKARR_SIZE && world->chunk[i].loaded; i++);
|
||||
|
||||
// Pick out the oldest chunk (loaded) and overrwrite it.
|
||||
/* TODO: Find oldest chunk by which one is farthest away from
|
||||
the player*/
|
||||
the player */
|
||||
if(i == CHUNKARR_SIZE) {
|
||||
loadedMin = 0;
|
||||
/*
|
||||
loadedMin = world->chunk[0].loaded;
|
||||
for(i = 0; i < CHUNKARR_SIZE; i++)
|
||||
if(
|
||||
world->chunk[i].loaded <=
|
||||
world->chunk[i].loaded <
|
||||
world->chunk[loadedMin].loaded
|
||||
) loadedMin = i;
|
||||
i = loadedMin;
|
||||
*/
|
||||
distMax = 0;
|
||||
distMaxI = 0;
|
||||
for(i = 0; i < CHUNKARR_SIZE; i++) {
|
||||
int dist = sqrt(
|
||||
pow(coords.x - world->chunk[i].center.x, 2) +
|
||||
pow(coords.y - world->chunk[i].center.y, 2) +
|
||||
pow(coords.z - world->chunk[i].center.z, 2)
|
||||
);
|
||||
if(dist > distMax) {
|
||||
distMax = dist;
|
||||
distMaxI = i;
|
||||
}
|
||||
}
|
||||
i = distMaxI;
|
||||
}
|
||||
chunk = &world->chunk[i];
|
||||
} else if(!force) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If there is no array, allocate one.
|
||||
if(chunk->loaded) {
|
||||
// TODO: Save chunk to disk
|
||||
} else {
|
||||
chunk->blocks = (int*)calloc(262144, sizeof(int));
|
||||
}
|
||||
// If there is no array, allocate one.
|
||||
if(chunk->loaded) {
|
||||
// TODO: Save chunk to disk
|
||||
} else {
|
||||
chunk->blocks = (int*)calloc(262144, sizeof(int));
|
||||
}
|
||||
|
||||
if(chunk->blocks == NULL) {
|
||||
printf("genChunk: memory allocation fail\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int *blocks = chunk->blocks;
|
||||
|
||||
for(int i = 0; i < 262144; i++)
|
||||
blocks[i] = 0;
|
||||
|
||||
// Generate a hash
|
||||
static int hashX, hashY, hashZ;
|
||||
|
||||
hashX = xOffset >> 6;
|
||||
hashY = yOffset >> 6;
|
||||
hashZ = zOffset >> 6;
|
||||
|
||||
hashX &= 0b1111111111;
|
||||
hashY &= 0b1111111111;
|
||||
hashZ &= 0b1111111111;
|
||||
|
||||
hashY <<= 10;
|
||||
hashZ <<= 20;
|
||||
|
||||
chunk->coordHash = hashX | hashY | hashZ;
|
||||
chunk->coordHash++;
|
||||
|
||||
chunk->center.x = xOffset + 32;
|
||||
chunk->center.y = xOffset + 32;
|
||||
chunk->center.z = xOffset + 32;
|
||||
|
||||
// What we have here won't cause a segfault, so it is safe to
|
||||
// mark the chunk as loaded and set its stamp.
|
||||
chunk->loaded = ++count;
|
||||
|
||||
printf(
|
||||
"chunk hash: %#016x\tx: %i\ty: %i\tz: %i\tstamp: %i\taddr: %p\tgenerated\n",
|
||||
chunk->coordHash,
|
||||
xOffset, yOffset, zOffset,
|
||||
chunk->loaded, chunk
|
||||
);
|
||||
|
||||
|
||||
switch(type) {
|
||||
// Classic terrain
|
||||
case 0:
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int y = 32; y < 64; y++)
|
||||
for(int z = 0; z < 64; z++)
|
||||
ch_setBlock(blocks, x, y, z,
|
||||
randm(2) == 0 ? randm(8) : 0);
|
||||
break;
|
||||
|
||||
if(chunk->blocks == NULL) {
|
||||
printf("genChunk: memory allocation fail");
|
||||
return;
|
||||
}
|
||||
|
||||
int *blocks = chunk->blocks;
|
||||
|
||||
for(int i = 0; i < 262144; i++)
|
||||
blocks[i] = 0;
|
||||
|
||||
// Generate a hash
|
||||
static int hashX, hashY, hashZ;
|
||||
|
||||
hashX = xOffset >> 6;
|
||||
hashY = yOffset >> 6;
|
||||
hashZ = zOffset >> 6;
|
||||
|
||||
hashX &= 0b1111111111;
|
||||
hashY &= 0b1111111111;
|
||||
hashZ &= 0b1111111111;
|
||||
|
||||
hashY <<= 10;
|
||||
hashZ <<= 20;
|
||||
|
||||
chunk->coordHash = hashX | hashY | hashZ;
|
||||
chunk->coordHash++;
|
||||
|
||||
// What we have here won't cause a segfault, so it is safe to
|
||||
// mark the chunk as loaded and set its stamp.
|
||||
chunk->loaded = ++count;
|
||||
|
||||
/*
|
||||
printf(
|
||||
"chunk hash: %#016x\tx: %i\ty: %i\tz: %i\tstamp: %i\taddr: %p\tgenerated\n",
|
||||
chunk->coordHash,
|
||||
xOffset, yOffset, zOffset,
|
||||
chunk->loaded, chunk
|
||||
);
|
||||
*/
|
||||
|
||||
switch(type) {
|
||||
// Classic terrain
|
||||
case 0:
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int y = 32; y < 64; y++)
|
||||
for(int z = 0; z < 64; z++)
|
||||
ch_setBlock(blocks, x, y, z,
|
||||
randm(2) == 0 ? randm(8) : 0);
|
||||
break;
|
||||
|
||||
// New terrain
|
||||
case 1:
|
||||
// Generate heightmap
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int z = 0; z < 64; z++) {
|
||||
heightmap[x][z] =
|
||||
perlin2d( // Detail noise
|
||||
seed,
|
||||
x + xOffset + 16777215,
|
||||
z + zOffset + 16777215,
|
||||
0.0625
|
||||
)
|
||||
* 16 +
|
||||
perlin2d( // Detail noise
|
||||
seed,
|
||||
x + xOffset + 16777215,
|
||||
z + zOffset + 16777215,
|
||||
0.0078125
|
||||
)
|
||||
* 64;
|
||||
}
|
||||
|
||||
// Make terrain from heightmap
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int y = 0; y < 64; y++)
|
||||
for(int z = 0; z < 64; z++)
|
||||
if(y + yOffset > heightmap[x][z] + 4)
|
||||
ch_setBlock(blocks, x, y, z, 4);
|
||||
else if(y + yOffset > heightmap[x][z])
|
||||
ch_setBlock(blocks, x, y, z, 2);
|
||||
else if(y + yOffset == heightmap[x][z])
|
||||
ch_setBlock(blocks, x, y, z, 1);
|
||||
else
|
||||
ch_setBlock(blocks, x, y, z, 0);
|
||||
|
||||
// Generate structures
|
||||
// TODO: fix structures not properly generating in some
|
||||
// chunks
|
||||
for(i = randm(16) + 64; i > 0; i--) {
|
||||
x = randm(64);
|
||||
z = randm(64);
|
||||
if(
|
||||
heightmap[x][z] >= yOffset &&
|
||||
heightmap[x][z] < yOffset + 64
|
||||
) {
|
||||
genStructure(
|
||||
world,
|
||||
x + xOffset, heightmap[x][z] - 1, z + zOffset,
|
||||
0
|
||||
);
|
||||
}
|
||||
// New terrain
|
||||
case 1:
|
||||
// Generate heightmap
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int z = 0; z < 64; z++) {
|
||||
heightmap[x][z] =
|
||||
perlin2d( // Detail noise
|
||||
seed,
|
||||
x + xOffset + 16777215,
|
||||
z + zOffset + 16777215,
|
||||
0.0625
|
||||
)
|
||||
* 16 +
|
||||
perlin2d( // Detail noise
|
||||
seed,
|
||||
x + xOffset + 16777215,
|
||||
z + zOffset + 16777215,
|
||||
0.0078125
|
||||
)
|
||||
* 64;
|
||||
}
|
||||
|
||||
for(i = randm(2); i > 0; i--) {
|
||||
x = randm(64);
|
||||
z = randm(64);
|
||||
if(
|
||||
heightmap[x][z] >= yOffset &&
|
||||
heightmap[x][z] < yOffset + 64
|
||||
) {
|
||||
genStructure(
|
||||
world,
|
||||
x + xOffset, heightmap[x][z] + 1, z + zOffset,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Debug stone
|
||||
case 2:
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int z = 0; z < 64; z++) {
|
||||
for(int y = 0; y < 32; y++)
|
||||
// Make terrain from heightmap
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int y = 0; y < 64; y++)
|
||||
for(int z = 0; z < 64; z++)
|
||||
if(y + yOffset > heightmap[x][z] + 4)
|
||||
ch_setBlock(blocks, x, y, z, 4);
|
||||
for(int y = 32; y < 64; y++)
|
||||
ch_setBlock(blocks, x, y, z, 5);
|
||||
}
|
||||
}
|
||||
else if(y + yOffset > heightmap[x][z])
|
||||
ch_setBlock(blocks, x, y, z, 2);
|
||||
else if(y + yOffset == heightmap[x][z])
|
||||
ch_setBlock(blocks, x, y, z, 1);
|
||||
else
|
||||
ch_setBlock(blocks, x, y, z, 0);
|
||||
|
||||
// Generate structures
|
||||
// TODO: fix structures not properly generating in some
|
||||
// chunks
|
||||
for(i = randm(16) + 64; i > 0; i--) {
|
||||
x = randm(64);
|
||||
z = randm(64);
|
||||
if(
|
||||
heightmap[x][z] >= yOffset &&
|
||||
heightmap[x][z] < yOffset + 64
|
||||
) {
|
||||
genStructure(
|
||||
world,
|
||||
x + xOffset, heightmap[x][z] - 1, z + zOffset,
|
||||
0
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for(i = randm(2); i > 0; i--) {
|
||||
x = randm(64);
|
||||
z = randm(64);
|
||||
if(
|
||||
heightmap[x][z] >= yOffset &&
|
||||
heightmap[x][z] < yOffset + 64
|
||||
) {
|
||||
genStructure(
|
||||
world,
|
||||
x + xOffset, heightmap[x][z] + 1, z + zOffset,
|
||||
1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
// Sort all chunks
|
||||
sortChunks(world);
|
||||
// Debug stone
|
||||
case 2:
|
||||
for(int x = 0; x < 64; x++)
|
||||
for(int z = 0; z < 64; z++) {
|
||||
for(int y = 0; y < 32; y++)
|
||||
ch_setBlock(blocks, x, y, z, 4);
|
||||
for(int y = 32; y < 64; y++)
|
||||
ch_setBlock(blocks, x, y, z, 5);
|
||||
}
|
||||
}
|
||||
|
||||
// Sort all chunks
|
||||
sortChunks(world);
|
||||
return 1;
|
||||
}
|
||||
|
||||
19
utility.h
19
utility.h
@@ -1,7 +1,6 @@
|
||||
int randm(int);
|
||||
int nmod(int, int);
|
||||
float perlin2d(int, double, double, double);
|
||||
int heartbeat(SDL_Window*, SDL_Event*, SDL_Renderer*);
|
||||
|
||||
/*
|
||||
randm
|
||||
@@ -88,21 +87,3 @@ float perlin2d(
|
||||
|
||||
return fin/div;
|
||||
}
|
||||
|
||||
/*
|
||||
heartbeat
|
||||
Pushes render to screen and checks to see if user wants to
|
||||
quit. If quit event is recieved, returns 0.
|
||||
*/
|
||||
int heartbeat(
|
||||
SDL_Window *window,
|
||||
SDL_Event *event,
|
||||
SDL_Renderer *renderer
|
||||
) {
|
||||
SDL_RenderPresent(renderer);
|
||||
SDL_UpdateWindowSurface(window);
|
||||
while(SDL_PollEvent(event)) {
|
||||
if(event->type == SDL_QUIT) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user