Actually have a semi working world loader.
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -69,4 +69,4 @@ build
|
||||
.vscode
|
||||
lib
|
||||
|
||||
assets/tileset.png
|
||||
assets/testworld/tileset.png
|
@ -7,6 +7,9 @@
|
||||
|
||||
#include "dawngame.h"
|
||||
|
||||
primitive_t *primitive;
|
||||
float i;
|
||||
|
||||
game_t * gameInit(platform_t *platform) {
|
||||
// Create the game
|
||||
game_t *game = malloc(sizeof(game_t));
|
||||
@ -19,15 +22,40 @@ game_t * gameInit(platform_t *platform) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Load the Shader
|
||||
game->shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag");
|
||||
|
||||
// Prepare the camera.
|
||||
game->camera = cameraCreate();
|
||||
cameraLookAt(game->camera, 50, 50, 50, 0, 0, 0 );
|
||||
cameraPerspective(game->camera, 45.0f, 1920.0f/1080.0f, 0.5f, 500.0f);
|
||||
|
||||
// Load the world
|
||||
game->world = worldLoad("testworld/");
|
||||
|
||||
// Pass to the main game to handle
|
||||
return game;
|
||||
}
|
||||
|
||||
uint32_t gameUpdate(game_t *game) {
|
||||
return engineUpdate(game->engine);
|
||||
uint32_t result;
|
||||
|
||||
// Update the engine.
|
||||
result = engineUpdate(game->engine);
|
||||
if(result != 0) return result;
|
||||
|
||||
// Prepare for rendering
|
||||
shaderUse(game->shader);
|
||||
shaderUseCamera(game->shader, game->camera);
|
||||
worldRender(game->world, game->shader);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gameDispose(game_t *game) {
|
||||
worldDispose(game->world);
|
||||
shaderDipose(game->shader);
|
||||
cameraDispose(game->camera);
|
||||
engineDispose(game->engine);
|
||||
free(game);
|
||||
}
|
||||
|
@ -7,11 +7,21 @@
|
||||
#include <malloc.h>
|
||||
#include "../engine/engine.h"
|
||||
|
||||
#include "../engine/file/asset.h"
|
||||
#include "../engine/display/shader.h"
|
||||
#include "../engine/display/camera.h"
|
||||
#include "world/world.h"
|
||||
|
||||
/////////////////////////////// TYPE DEFINITIONS ///////////////////////////////
|
||||
/** Context about Dawn Game */
|
||||
typedef struct {
|
||||
/** The engine context for the game */
|
||||
engine_t *engine;
|
||||
|
||||
/** Rendering items */
|
||||
camera_t *camera;
|
||||
shader_t *shader;
|
||||
world_t *world;
|
||||
} dawngame_t;
|
||||
#define GAMETYPE_T dawngame_t
|
||||
|
||||
|
@ -1,24 +1,39 @@
|
||||
#include "chunk.h"
|
||||
|
||||
void chunkLoad(chunklist_t *list, chunk_t *chunk,
|
||||
void chunkLoad(world_t *world, chunk_t *chunk,
|
||||
int32_t x, int32_t y, int32_t z
|
||||
) {
|
||||
int32_t tx, ty, tz, i;
|
||||
tile_t *tile;
|
||||
tiledef_t *tileDef;
|
||||
tilesetdiv_t *div;
|
||||
char *buffer, *seek, *current;
|
||||
char fileName[128];
|
||||
|
||||
//TODO: Actually load here, this should be combined with below
|
||||
for(i = 0; i < list->tileCount; i++) {
|
||||
(chunk->tiles + i)->id = (i%2) + 1;
|
||||
}
|
||||
// Determine file name of the chunk.
|
||||
fileName[0] = '\0';
|
||||
strcat(fileName, world->assetWorldDirectory);
|
||||
strcat(fileName, "chunks/");
|
||||
strcat(fileName, "%d_%d_%d.txt");
|
||||
sprintf(fileName, fileName, x, y, z);
|
||||
|
||||
// Load contents of chunk
|
||||
buffer = assetStringLoad(fileName);
|
||||
if(buffer == NULL) return;
|
||||
seek = buffer;
|
||||
|
||||
// Determine the size of our primitive.
|
||||
int32_t indiceCount = 0, verticeCount = 0;
|
||||
for(i = 0; i < list->tileCount; i++) {
|
||||
for(i = 0; i < world->tileCount; i++) {
|
||||
// Get the tile
|
||||
tile = chunk->tiles + i;
|
||||
|
||||
// Now load from the buffer.
|
||||
current = strtok_r(seek, ";", &seek);
|
||||
tile->id = current[0] - 48;
|
||||
|
||||
if(tile->id == TILE_NULL) continue;
|
||||
tileDef = list->tilemap->tileDefinitions + tile->id;
|
||||
tileDef = world->tilemap->tileDefinitions + tile->id;
|
||||
if(tileDef->verticeCount == 0 || tileDef->indiceCount == 0) continue;
|
||||
|
||||
tile->verticeStart = verticeCount;
|
||||
@ -29,7 +44,10 @@ void chunkLoad(chunklist_t *list, chunk_t *chunk,
|
||||
}
|
||||
|
||||
// Now we know how big the primitive needs to be!
|
||||
chunk->primitive = primitiveCreate(verticeCount, indiceCount);
|
||||
free(buffer);
|
||||
if(indiceCount > 0) {
|
||||
chunk->primitive = primitiveCreate(verticeCount, indiceCount);
|
||||
}
|
||||
|
||||
// For each tile
|
||||
i = 0;
|
||||
@ -41,21 +59,21 @@ void chunkLoad(chunklist_t *list, chunk_t *chunk,
|
||||
|
||||
// Should Chunk bother rendering?
|
||||
if(tile->id == TILE_NULL) continue;
|
||||
tileDef = list->tilemap->tileDefinitions + tile->id;
|
||||
tileDef = world->tilemap->tileDefinitions + tile->id;
|
||||
if(tileDef->verticeCount == 0 || tileDef->indiceCount == 0) continue;
|
||||
|
||||
// Render the tile's primitive
|
||||
tileRender(list, chunk, tile, tileDef, tx, ty, tz);
|
||||
tileRender(world, chunk, tile, tileDef, tx, ty, tz);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void chunkUnload(chunklist_t *list, chunk_t *chunk) {
|
||||
void chunkUnload(world_t *world, chunk_t *chunk) {
|
||||
// Unload the primitive
|
||||
primitiveDispose(chunk->primitive);
|
||||
chunk->primitive = NULL;
|
||||
|
||||
// Load chunks to zero. TODO: Necessary?
|
||||
memset(chunk->tiles, TILE_NULL, list->count);
|
||||
memset(chunk->tiles, TILE_NULL, world->count);
|
||||
}
|
31
src/dawn/world/chunk.h
Normal file
31
src/dawn/world/chunk.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include <string.h>
|
||||
#include "worldtypes.h"
|
||||
#include "tile.h"
|
||||
#include "../../engine/file/asset.h"
|
||||
#include "../../engine/util/string.h"
|
||||
|
||||
#define CHUNK_WIDTH 16
|
||||
#define CHUNK_HEIGHT 16
|
||||
#define CHUNK_DEPTH 8
|
||||
|
||||
/**
|
||||
* Loads a given chunk.
|
||||
*
|
||||
* @param list World to load the chunk for.
|
||||
* @param chunk The chunk to load.
|
||||
* @param x X of the chunk.
|
||||
* @param y Y of the chunk.
|
||||
* @param z Z of the chunk.
|
||||
*/
|
||||
void chunkLoad(world_t *world, chunk_t *chunk,
|
||||
int32_t x, int32_t y, int32_t z
|
||||
);
|
||||
|
||||
/**
|
||||
* Unload a given chunk.
|
||||
*
|
||||
* @param world World that the chunk belongs to.
|
||||
* @param chunk Chunk to unload.
|
||||
*/
|
||||
void chunkUnload(world_t *world, chunk_t *chunk);
|
@ -7,25 +7,15 @@
|
||||
|
||||
#include "tile.h"
|
||||
|
||||
tilemap_t * tileMapCreate(tileset_t *tileset) {
|
||||
tilemap_t * tileMapCreate(int32_t columns, int32_t rows) {
|
||||
tilemap_t *tilemap = malloc(sizeof(tilemap_t));
|
||||
if(tilemap == NULL) return NULL;
|
||||
|
||||
tilemap->tileset = tileset;
|
||||
tilemap->tileDefinitions = calloc(tileset->columns * tileset->rows,
|
||||
sizeof(tiledef_t)
|
||||
);
|
||||
tilemap->tileDefinitions = calloc(columns * rows, sizeof(tiledef_t));
|
||||
if(!tilemap->tileDefinitions) {
|
||||
free(tilemap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(tilemap->tileDefinitions + 1)->verticeCount = 4;
|
||||
(tilemap->tileDefinitions + 1)->indiceCount = 6;
|
||||
|
||||
(tilemap->tileDefinitions + 2)->verticeCount = 8;
|
||||
(tilemap->tileDefinitions + 2)->indiceCount = 36;
|
||||
|
||||
return tilemap;
|
||||
}
|
||||
|
||||
@ -34,17 +24,11 @@ void tileMapDispose(tilemap_t *tilemap) {
|
||||
free(tilemap);
|
||||
}
|
||||
|
||||
void tileRender(chunklist_t *list, chunk_t *chunk,
|
||||
void tileRender(world_t *world, chunk_t *chunk,
|
||||
tile_t *tile, tiledef_t *tileDef, int32_t x, int32_t y, int32_t z
|
||||
) {
|
||||
if(tile->id == 2) {
|
||||
cubeBuffer(chunk->primitive,
|
||||
x, y, z,
|
||||
1, 1, 1,
|
||||
tile->verticeStart, tile->indiceStart
|
||||
);
|
||||
} else {
|
||||
tilesetdiv_t *div = list->tilemap->tileset->divisions + tile->id;
|
||||
if(tile->id == 1) {
|
||||
tilesetdiv_t *div = world->tileset->divisions + tile->id;
|
||||
quadBuffer(chunk->primitive, z,
|
||||
x, y, div->x0, div->y0,
|
||||
x+1, y+1, div->x1, div->y1,
|
@ -4,12 +4,15 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include "defs.h"
|
||||
#include "../display/tileset.h"
|
||||
#include "../display/primitives/quad.h"
|
||||
#include "../display/primitives/cube.h"
|
||||
|
||||
#include "worldtypes.h"
|
||||
|
||||
#include "../../engine/display/tileset.h"
|
||||
#include "../../engine/display/primitives/quad.h"
|
||||
#include "../../engine/display/primitives/cube.h"
|
||||
|
||||
#define TILE_NULL 0
|
||||
#define TILE_FLAG_DYNAMIC (tileflag_t)1
|
||||
@ -17,10 +20,11 @@
|
||||
/**
|
||||
* Creates a tilemap from a tileset.
|
||||
*
|
||||
* @param tileset Tileset to create from.
|
||||
* @param columns Count of columns in the tilemap.
|
||||
* @param rows Count of rows in the tilemap.
|
||||
* @returns The tilemap.
|
||||
*/
|
||||
tilemap_t * tileMapCreate(tileset_t *tileset);
|
||||
tilemap_t * tileMapCreate(int32_t columns, int32_t rows);
|
||||
|
||||
/**
|
||||
* Destroys a previously created tilemap.
|
||||
@ -32,7 +36,7 @@ void tileMapDispose(tilemap_t *tilemap);
|
||||
/**
|
||||
* Rendedrs a given chunk tile.
|
||||
*
|
||||
* @param list The chunk list that the chunk belongs to.
|
||||
* @param world The world that the chunk belongs to.
|
||||
* @param chunk The chunk to render against.
|
||||
* @param tile The tile to render.
|
||||
* @param tileDef The tile's definition information.
|
||||
@ -40,6 +44,6 @@ void tileMapDispose(tilemap_t *tilemap);
|
||||
* @param y The Y Coordinate of the tile (chunk space).
|
||||
* @param z The Z Coordinate of the tile (chunk space).
|
||||
*/
|
||||
void tileRender(chunklist_t *list, chunk_t *chunk,
|
||||
void tileRender(world_t *world, chunk_t *chunk,
|
||||
tile_t *tile, tiledef_t *tileDef, int32_t x, int32_t y, int32_t z
|
||||
);
|
229
src/dawn/world/world.c
Normal file
229
src/dawn/world/world.c
Normal file
@ -0,0 +1,229 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "world.h"
|
||||
|
||||
world_t * worldLoad(char *assetWorldDirectory) {
|
||||
// Define our local variables
|
||||
char file [128];
|
||||
char *reading, *version, *textureFilename, *temp;
|
||||
world_t *world;
|
||||
chunk_t *chunk;
|
||||
int32_t i, x, y, z;
|
||||
|
||||
// Load the world file.
|
||||
file[0] = '\0';
|
||||
strcat(file, assetWorldDirectory);
|
||||
strcat(file, "world.txt");
|
||||
char *worldData = assetStringLoad(file);
|
||||
if(worldData == NULL) return NULL;
|
||||
|
||||
// Create the world
|
||||
world = malloc(sizeof(world_t));
|
||||
world->assetWorldDirectory = assetWorldDirectory;
|
||||
|
||||
// Now begin parsing, first we need to know which version of the file format
|
||||
// we are using.
|
||||
reading = worldData;
|
||||
version = strtok_r(reading, ";", &reading);
|
||||
|
||||
// Now load the tileset texture filename
|
||||
textureFilename = strtok_r(reading, ";", &reading);
|
||||
|
||||
// Load tileset texture.
|
||||
file[0] = '\0';
|
||||
strcat(file, assetWorldDirectory);
|
||||
strcat(file, textureFilename);
|
||||
world->texture = assetTextureLoad(file);
|
||||
|
||||
// Finished actual loading.
|
||||
free(worldData);
|
||||
|
||||
// Create the tileset
|
||||
world->tileset = tilesetCreate(
|
||||
world->texture->width/16, world->texture->height/16,
|
||||
world->texture->width, world->texture->height,
|
||||
0, 0, 0, 0
|
||||
);
|
||||
|
||||
// Create the Tilemap
|
||||
world->tilemap = tileMapCreate(world->tileset->columns, world->tileset->rows);
|
||||
(world->tilemap->tileDefinitions + 1)->indiceCount = 6;
|
||||
(world->tilemap->tileDefinitions + 1)->verticeCount = 4;
|
||||
|
||||
// Prepare the chunk lists
|
||||
world->x = 0, world->y = 0, world->z = 0;
|
||||
world->count = WORLD_WIDTH * WORLD_HEIGHT * WORLD_DEPTH;
|
||||
world->tileCount = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH;
|
||||
|
||||
//Create chunks
|
||||
world->chunks = malloc(world->count * sizeof(chunk_t));
|
||||
world->chunkList = malloc(world->count * sizeof(chunk_t *));
|
||||
|
||||
// Load initial chunks, ZYX order is important here.
|
||||
i = 0;
|
||||
for(z = 0; z < WORLD_DEPTH; z++) {
|
||||
for(y = 0; y < WORLD_HEIGHT; y++) {
|
||||
for(x = 0; x < WORLD_WIDTH; x++) {
|
||||
chunk = world->chunks + i;
|
||||
world->chunkList[i] = chunk;
|
||||
|
||||
// Load initial coordinates
|
||||
chunk->x = x;
|
||||
chunk->y = y;
|
||||
chunk->z = z;
|
||||
chunk->primitive = NULL;
|
||||
|
||||
// Init the chunk.
|
||||
chunk->tiles = calloc(world->tileCount, sizeof(tile_t));
|
||||
chunkLoad(world, chunk, x, y, z);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
void worldRender(world_t *world, shader_t *shader) {
|
||||
int32_t i, j, tx, ty, tz;
|
||||
float x, y, z;
|
||||
chunk_t *chunk;
|
||||
tile_t *tile;
|
||||
tiledef_t *tileDef;
|
||||
|
||||
shaderUseTexture(shader, world->texture);
|
||||
|
||||
for(i = 0; i < world->count; i++) {
|
||||
chunk = world->chunks + i;
|
||||
if(chunk->primitive == NULL) continue;
|
||||
|
||||
x = (chunk->x * CHUNK_WIDTH);
|
||||
y = (chunk->y * CHUNK_HEIGHT);
|
||||
z = (chunk->z * CHUNK_DEPTH);
|
||||
|
||||
// Re-render every single tile in the chunk.
|
||||
|
||||
// j = 0;
|
||||
// for(tx = 0; tx < CHUNK_WIDTH; tx++) {
|
||||
// for(ty = 0; ty < CHUNK_HEIGHT; ty++) {
|
||||
// for(tz = 0; tz < CHUNK_DEPTH; tz++) {
|
||||
// // Get tile for position...
|
||||
// tile = chunk->tiles + (j++);
|
||||
|
||||
// // Should Tile bother rendering?
|
||||
// if(tile->id == TILE_NULL) continue;
|
||||
// tileDef = list->tilemap->tileDefinitions + tile->id;
|
||||
// if(tileDef->verticeCount == 0 || tileDef->indiceCount == 0) continue;
|
||||
|
||||
// tileRender(list, chunk, tile, tileDef, tx, ty, tz);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
shaderUsePosition(shader, x, y, z, 0, 0, 0);
|
||||
primitiveDraw(chunk->primitive, 0, chunk->primitive->indiceCount);
|
||||
}
|
||||
}
|
||||
|
||||
void worldDispose(world_t *world) {
|
||||
int32_t i;
|
||||
chunk_t *chunk;
|
||||
|
||||
// Unload the chunks
|
||||
for(i = 0; i < world->count; i++) {
|
||||
chunk = world->chunks + i;
|
||||
chunkUnload(world, chunk);
|
||||
free(chunk->tiles);
|
||||
}
|
||||
|
||||
free(world->chunks);
|
||||
textureDispose(world->texture);
|
||||
tilesetDispose(world->tileset);
|
||||
tileMapDispose(world->tilemap);
|
||||
free(world);
|
||||
}
|
||||
|
||||
void worldShift(world_t *world, int32_t x, int32_t y, int32_t z) {
|
||||
int32_t i,
|
||||
/** New List Coordinates */
|
||||
lx, ly, lz,
|
||||
/** New Local Chunk Coordinates */
|
||||
nx, ny, nz,
|
||||
/** New Absolute Chunk Coordinates */
|
||||
ax, ay, az,
|
||||
/** New Chunk Index */
|
||||
ni,
|
||||
/** Precalculated width * height */
|
||||
wh
|
||||
;
|
||||
chunk_t *chunk;
|
||||
chunk_t **chunkList;
|
||||
|
||||
// Calculate the new chunklist coordinates
|
||||
lx = world->x + x;
|
||||
ly = world->y + y;
|
||||
lz = world->z + z;
|
||||
|
||||
// Precalc width * height.
|
||||
wh = WORLD_WIDTH * WORLD_HEIGHT;
|
||||
|
||||
chunkList = malloc(world->count * sizeof(chunk_t *));
|
||||
for(i = 0; i < world->count; i++) {
|
||||
chunk = world->chunkList[i];
|
||||
|
||||
// Calculate the new local positions for the chunk.
|
||||
nx = mathMod(chunk->x - world->x - x, WORLD_WIDTH);
|
||||
ny = mathMod(chunk->y - world->y - y, WORLD_HEIGHT);
|
||||
nz = mathMod(chunk->z - world->z - z, WORLD_DEPTH);
|
||||
|
||||
// Load the chunk if we need to. We also use this to calculate new absolutes
|
||||
if(
|
||||
(ax = lx + nx) != chunk->x ||
|
||||
(ly + ny) != chunk->y ||
|
||||
(lz + nz) != chunk->z
|
||||
) {
|
||||
// Calculate those things that may have not been done within the if
|
||||
ay = ly + ny;
|
||||
az = lz + nz;
|
||||
|
||||
// Load new chunk.
|
||||
chunkUnload(world, chunk);
|
||||
chunkLoad(world, chunk, ax, ay, az);
|
||||
|
||||
// Update the absolute coordinates.
|
||||
chunk->x = ax;
|
||||
chunk->y = ay;
|
||||
chunk->z = az;
|
||||
}
|
||||
|
||||
// Now, based off those new local positions, calculate the new index.
|
||||
ni = (
|
||||
nx +
|
||||
(ny * WORLD_WIDTH) +
|
||||
(nz * wh)
|
||||
);
|
||||
chunkList[ni] = chunk;
|
||||
}
|
||||
|
||||
// Update Absolutes.
|
||||
world->x = lx;
|
||||
world->y = ly;
|
||||
world->z = lz;
|
||||
|
||||
// Now copy that array over.
|
||||
memcpy(world->chunkList, chunkList, sizeof(chunk_t *) * world->count);
|
||||
free(chunkList);
|
||||
}
|
||||
|
||||
void worldAlign(world_t *world, int32_t x, int32_t y, int32_t z) {
|
||||
int32_t lx, ly, lz;
|
||||
lx = x - world->x;
|
||||
ly = y - world->y;
|
||||
lz = z - world->z;
|
||||
worldShift(world, lx, ly, lz);
|
||||
}
|
68
src/dawn/world/world.h
Normal file
68
src/dawn/world/world.h
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <malloc.h>
|
||||
#include <stdint.h>
|
||||
#include "worldtypes.h"
|
||||
#include "tile.h"
|
||||
#include "chunk.h"
|
||||
#include "../../engine/display/shader.h"
|
||||
#include "../../engine/display/primitive.h"
|
||||
#include "../../engine/display/tileset.h"
|
||||
#include "../../engine/display/texture.h"
|
||||
#include "../../engine/file/asset.h"
|
||||
#include "../../engine/util/string.h"
|
||||
#include "../../engine/util/math.h"
|
||||
|
||||
#define WORLD_WIDTH 1
|
||||
#define WORLD_HEIGHT WORLD_WIDTH
|
||||
#define WORLD_DEPTH WORLD_HEIGHT
|
||||
|
||||
#define CHUNK_WIDTH 16
|
||||
#define CHUNK_HEIGHT 16
|
||||
#define CHUNK_DEPTH 8
|
||||
|
||||
/**
|
||||
* Create a world object.
|
||||
*
|
||||
* @returns The newly created world.
|
||||
*/
|
||||
world_t * worldLoad(char *fileName);
|
||||
|
||||
/**
|
||||
* Render a world object to the graphics device.
|
||||
*
|
||||
* @param world The world to render.
|
||||
* @param shader The shader to render to.
|
||||
*/
|
||||
void worldRender(world_t *world, shader_t *shader);
|
||||
|
||||
/**
|
||||
* Cleans up a previously created world.
|
||||
*
|
||||
* @param world World to cleanup.
|
||||
*/
|
||||
void worldDispose(world_t *world);
|
||||
|
||||
/**
|
||||
* Shift the world chunk list along a set of axis (in absolute space).
|
||||
*
|
||||
* @param world World to shift.
|
||||
* @param x X movement to shift chunk along.
|
||||
* @param y Y movement to shift chunk along.
|
||||
* @param z Z movement to shift chunk along.
|
||||
*/
|
||||
void worldShift(world_t *world, int32_t x, int32_t y, int32_t z);
|
||||
|
||||
/**
|
||||
* Align the world chunk list (in absolute space).
|
||||
*
|
||||
* @param world World to align.
|
||||
* @param x X movement to shift chunk along.
|
||||
* @param y Y movement to shift chunk along.
|
||||
* @param z Z movement to shift chunk along.
|
||||
*/
|
||||
void worldAlign(world_t *world, int32_t x, int32_t y, int32_t z);
|
@ -1,9 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include "../display/primitive.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../display/tileset.h"
|
||||
#include "../../engine/display/primitive.h"
|
||||
#include "../../engine/display/texture.h"
|
||||
#include "../../engine/display/tileset.h"
|
||||
|
||||
typedef uint8_t tileflag_t;
|
||||
typedef uint8_t tileid_t;
|
||||
@ -21,7 +22,6 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
tiledef_t *tileDefinitions;
|
||||
tileset_t *tileset;
|
||||
} tilemap_t;
|
||||
|
||||
typedef struct chunk_t {
|
||||
@ -30,19 +30,16 @@ typedef struct chunk_t {
|
||||
primitive_t *primitive;
|
||||
} chunk_t;
|
||||
|
||||
typedef struct chunklist_t {
|
||||
int32_t width, height, depth;
|
||||
typedef struct {
|
||||
char *assetWorldDirectory;
|
||||
|
||||
texture_t *texture;
|
||||
tileset_t *tileset;
|
||||
tilemap_t *tilemap;
|
||||
|
||||
int32_t x, y, z;
|
||||
int32_t count;
|
||||
int32_t tileCount;
|
||||
chunk_t **chunkList;
|
||||
tilemap_t *tilemap;
|
||||
chunk_t *chunks;
|
||||
} chunklist_t;
|
||||
|
||||
typedef struct {
|
||||
chunklist_t *chunkList;
|
||||
texture_t *texture;
|
||||
tileset_t *tileset;
|
||||
tilemap_t *tilemap;
|
||||
} world_t;
|
@ -104,9 +104,9 @@ void cubeBuffer(primitive_t *prim,
|
||||
primitive_t * cubeCreate(float w, float h, float d) {
|
||||
primitive_t *cube = primitiveCreate(CUBE_VERTICE_COUNT, CUBE_INDICE_COUNT);
|
||||
cubeBuffer(cube,
|
||||
-0.5, -0.5, -0.5,
|
||||
w, h, d,
|
||||
0, 0
|
||||
-w/2, -h/2, -d/2,
|
||||
w, h, d,
|
||||
0, 0
|
||||
);
|
||||
return cube;
|
||||
}
|
@ -6,16 +6,6 @@
|
||||
*/
|
||||
#include "engine.h"
|
||||
|
||||
camera_t *camera;
|
||||
shader_t *shader;
|
||||
world_t *world;
|
||||
|
||||
texture_t *texture;
|
||||
spritebatch_t *batch;
|
||||
tileset_t *tileset;
|
||||
|
||||
primitive_t *primitive;
|
||||
|
||||
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
|
||||
// Create the engine instance.
|
||||
engine_t *engine = malloc(sizeof(engine_t));
|
||||
@ -39,37 +29,11 @@ engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag");
|
||||
camera = cameraCreate();
|
||||
cameraLookAt(camera,
|
||||
20, 20, 20,
|
||||
0, 0, 0
|
||||
);
|
||||
cameraLookAt(camera,
|
||||
6, 6, 8,
|
||||
0, 0, 0
|
||||
);
|
||||
cameraPerspective(camera, 45.0f, 1920.0f/1080.0f, 0.5f, 100.0f);
|
||||
shaderUseCamera(shader, camera);
|
||||
|
||||
world = worldCreate();
|
||||
texture = assetTextureLoad("tileset.png");
|
||||
tileset = tilesetCreate(
|
||||
texture->width/16, texture->height/16,
|
||||
texture->width, texture->height,
|
||||
0, 0,
|
||||
0, 0
|
||||
);
|
||||
|
||||
return engine;
|
||||
}
|
||||
|
||||
uint32_t engineUpdate(engine_t *engine) {
|
||||
shaderUse(shader);
|
||||
renderFrame(engine->render);
|
||||
|
||||
worldRender(world, shader);
|
||||
|
||||
inputUpdate(engine->input);
|
||||
return 0;
|
||||
}
|
||||
|
@ -9,15 +9,6 @@
|
||||
#include "input/input.h"
|
||||
#include "./platform.h"
|
||||
|
||||
#include "file/asset.h"
|
||||
#include "display/shader.h"
|
||||
#include "display/camera.h"
|
||||
#include "world/world.h"
|
||||
#include "world/chunklist.h"
|
||||
#include "display/spritebatch.h"
|
||||
#include "display/tileset.h"
|
||||
#include "display/texture.h"
|
||||
|
||||
/** Information about the current engine context. */
|
||||
typedef struct {
|
||||
/** Name of the game running. */
|
||||
|
13
src/engine/util/string.h
Normal file
13
src/engine/util/string.h
Normal file
@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <string.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
# define strtok_r strtok_s
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#pragma once
|
||||
#include "defs.h"
|
||||
#include "tile.h"
|
||||
|
||||
#define CHUNK_WIDTH 3
|
||||
#define CHUNK_HEIGHT CHUNK_WIDTH
|
||||
#define CHUNK_DEPTH CHUNK_HEIGHT
|
||||
|
||||
/**
|
||||
* Loads a given chunk.
|
||||
*
|
||||
* @param list List to load the chunk for.
|
||||
* @param chunk The chunk to load.
|
||||
* @param x X of the chunk.
|
||||
* @param y Y of the chunk.
|
||||
* @param z Z of the chunk.
|
||||
*/
|
||||
void chunkLoad(chunklist_t *list, chunk_t *chunk,
|
||||
int32_t x, int32_t y, int32_t z
|
||||
);
|
||||
|
||||
/**
|
||||
* Unload a given chunk.
|
||||
*
|
||||
* @param list List that the chunk belongs to.
|
||||
* @param chunk Chunk to unload.
|
||||
*/
|
||||
void chunkUnload(chunklist_t *list, chunk_t *chunk);
|
@ -1,195 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "chunklist.h"
|
||||
|
||||
chunklist_t * chunkListCreate(int32_t width, int32_t height, int32_t depth,
|
||||
tilemap_t *tilemap
|
||||
) {
|
||||
chunklist_t *list;
|
||||
chunk_t *chunk;
|
||||
int32_t i, x, y, z;
|
||||
|
||||
list = malloc(sizeof(chunklist_t));
|
||||
if(!list) return NULL;
|
||||
|
||||
list->width = width, list->height = height, list->depth = depth;
|
||||
list->x = 0, list->y = 0, list->z = 0;
|
||||
list->count = width * height * depth;
|
||||
list->tileCount = CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH;
|
||||
list->tilemap = tilemap;
|
||||
|
||||
//Create chunks
|
||||
list->chunks = malloc(list->count * sizeof(chunk_t));
|
||||
if(list->chunks == NULL) {
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list->chunkList = malloc(list->count * sizeof(chunk_t *));
|
||||
if(list->chunkList == NULL) {
|
||||
free(list->chunks);
|
||||
free(list);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Load initial chunks, ZYX order is important here.
|
||||
i = 0;
|
||||
for(z = 0; z < depth; z++) {
|
||||
for(y = 0; y < height; y++) {
|
||||
for(x = 0; x < width; x++) {
|
||||
chunk = list->chunks + i;
|
||||
list->chunkList[i] = chunk;
|
||||
|
||||
// Load initial coordinates
|
||||
chunk->x = x;
|
||||
chunk->y = y;
|
||||
chunk->z = z;
|
||||
|
||||
// Init the chunk.
|
||||
chunk->tiles = calloc(list->tileCount, sizeof(tile_t));
|
||||
chunkLoad(list, chunk, x, y, z);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void chunkListDispose(chunklist_t *list) {
|
||||
int32_t i;
|
||||
chunk_t *chunk;
|
||||
|
||||
// Unload the chunks
|
||||
for(i = 0; i < list->count; i++) {
|
||||
chunk = list->chunks + i;
|
||||
chunkUnload(list, chunk);
|
||||
free(chunk->tiles);
|
||||
}
|
||||
|
||||
free(list->chunks);
|
||||
free(list);
|
||||
}
|
||||
|
||||
void chunkListShift(chunklist_t *list, int32_t x, int32_t y, int32_t z) {
|
||||
int32_t i,
|
||||
/** New List Coordinates */
|
||||
lx, ly, lz,
|
||||
/** New Local Chunk Coordinates */
|
||||
nx, ny, nz,
|
||||
/** New Absolute Chunk Coordinates */
|
||||
ax, ay, az,
|
||||
/** New Chunk Index */
|
||||
ni,
|
||||
/** Precalculated width * height */
|
||||
wh
|
||||
;
|
||||
chunk_t *chunk;
|
||||
chunk_t **chunkList;
|
||||
|
||||
// Calculate the new chunklist coordinates
|
||||
lx = list->x + x;
|
||||
ly = list->y + y;
|
||||
lz = list->z + z;
|
||||
|
||||
// Precalc width * height.
|
||||
wh = list->width * list->height;
|
||||
|
||||
chunkList = malloc(list->count * sizeof(chunk_t *));
|
||||
for(i = 0; i < list->count; i++) {
|
||||
chunk = list->chunkList[i];
|
||||
|
||||
// Calculate the new local positions for the chunk.
|
||||
nx = mathMod(chunk->x - list->x - x, list->width);
|
||||
ny = mathMod(chunk->y - list->y - y, list->height);
|
||||
nz = mathMod(chunk->z - list->z - z, list->depth);
|
||||
|
||||
// Load the chunk if we need to. We also use this to calculate new absolutes
|
||||
if(
|
||||
(ax = lx + nx) != chunk->x ||
|
||||
(ly + ny) != chunk->y ||
|
||||
(lz + nz) != chunk->z
|
||||
) {
|
||||
// Calculate those things that may have not been done within the if
|
||||
ay = ly + ny;
|
||||
az = lz + nz;
|
||||
|
||||
// Load new chunk.
|
||||
chunkUnload(list, chunk);
|
||||
chunkLoad(list, chunk, ax, ay, az);
|
||||
|
||||
// Update the absolute coordinates.
|
||||
chunk->x = ax;
|
||||
chunk->y = ay;
|
||||
chunk->z = az;
|
||||
}
|
||||
|
||||
// Now, based off those new local positions, calculate the new index.
|
||||
ni = (
|
||||
nx +
|
||||
(ny * list->width) +
|
||||
(nz * wh)
|
||||
);
|
||||
chunkList[ni] = chunk;
|
||||
}
|
||||
|
||||
// Update Absolutes.
|
||||
list->x = lx;
|
||||
list->y = ly;
|
||||
list->z = lz;
|
||||
|
||||
// Now copy that array over.
|
||||
memcpy(list->chunkList, chunkList, sizeof(chunk_t *) * list->count);
|
||||
free(chunkList);
|
||||
}
|
||||
|
||||
void chunkListAlign(chunklist_t *list, int32_t x, int32_t y, int32_t z) {
|
||||
int32_t lx, ly, lz;
|
||||
|
||||
lx = x - list->x;
|
||||
ly = y - list->y;
|
||||
lz = z - list->z;
|
||||
|
||||
chunkListShift(list, lx, ly, lz);
|
||||
}
|
||||
|
||||
void chunkListRender(chunklist_t *list, shader_t *shader) {
|
||||
int32_t i, j, tx, ty, tz;
|
||||
float x, y, z;
|
||||
chunk_t *chunk;
|
||||
tile_t *tile;
|
||||
tiledef_t *tileDef;
|
||||
|
||||
for(i = 0; i < list->count; i++) {
|
||||
chunk = list->chunks + i;
|
||||
x = (chunk->x * CHUNK_WIDTH);
|
||||
y = (chunk->y * CHUNK_HEIGHT);
|
||||
z = (chunk->z * CHUNK_DEPTH);
|
||||
|
||||
// // Re-render every single tile in the chunk.
|
||||
// j = 0;
|
||||
// for(tx = 0; tx < CHUNK_WIDTH; tx++) {
|
||||
// for(ty = 0; ty < CHUNK_HEIGHT; ty++) {
|
||||
// for(tz = 0; tz < CHUNK_DEPTH; tz++) {
|
||||
// // Get tile for position...
|
||||
// tile = chunk->tiles + (j++);
|
||||
|
||||
// // Should Tile bother rendering?
|
||||
// if(tile->id == TILE_NULL) continue;
|
||||
// tileDef = list->tilemap->tileDefinitions + tile->id;
|
||||
// if(tileDef->verticeCount == 0 || tileDef->indiceCount == 0) continue;
|
||||
|
||||
// tileRender(list, chunk, tile, tileDef, tx, ty, tz);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
shaderUsePosition(shader, x, y, z, 0, 0, 0);
|
||||
primitiveDraw(chunk->primitive, 0, chunk->primitive->indiceCount);
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <malloc.h>
|
||||
#include "defs.h"
|
||||
#include "tile.h"
|
||||
#include "chunk.h"
|
||||
#include "./../util/math.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/primitive.h"
|
||||
#include "../display/texture.h"
|
||||
|
||||
/**
|
||||
* Creates a new chunk list. Chunk lists are managed to be memory efficient by
|
||||
* only keeping a small fraction of the overall size loaded at any given time.
|
||||
*
|
||||
* @param width The width (x axis) of chunks to keep loaded.
|
||||
* @param height The height (y axis) of chunks to keep loaded.
|
||||
* @param depth The depth (z axis) of chunks to keep loaded.
|
||||
* @param tilemap Tilemap of the chunk list.
|
||||
* @return A new chunk list.
|
||||
*/
|
||||
chunklist_t * chunkListCreate(int32_t width, int32_t height, int32_t depth,
|
||||
tilemap_t *tilemap
|
||||
);
|
||||
|
||||
/**
|
||||
* Disposes and frees a previously created list. This does not free the chunks
|
||||
* themselves.
|
||||
|
||||
* @param list The list to free.
|
||||
*/
|
||||
void chunkListDispose(chunklist_t *list);
|
||||
|
||||
/**
|
||||
* Shift the chunk list along a set of axis (in absolute space).
|
||||
*
|
||||
* @param list List to shift.
|
||||
* @param x X movement to shift chunk along.
|
||||
* @param y Y movement to shift chunk along.
|
||||
* @param z Z movement to shift chunk along.
|
||||
*/
|
||||
void chunkListShift(chunklist_t *list, int32_t x, int32_t y, int32_t z);
|
||||
|
||||
/**
|
||||
* Align the chunk list (in absolute space).
|
||||
*
|
||||
* @param list List to align.
|
||||
* @param x X movement to shift chunk along.
|
||||
* @param y Y movement to shift chunk along.
|
||||
* @param z Z movement to shift chunk along.
|
||||
*/
|
||||
void chunkListAlign(chunklist_t *list, int32_t x, int32_t y, int32_t z);
|
||||
|
||||
/**
|
||||
* Renders a given chunk list.
|
||||
*
|
||||
* @param list The list to render.
|
||||
* @param shader The shader to use.
|
||||
*/
|
||||
void chunkListRender(chunklist_t *list, shader_t *shader);
|
@ -1,68 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2021 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "world.h"
|
||||
|
||||
world_t * worldCreate() {
|
||||
world_t *world = malloc(sizeof(world_t));
|
||||
if(world == NULL) return NULL;
|
||||
|
||||
// Texture
|
||||
world->texture = assetTextureLoad("tileset.png");
|
||||
if(world->texture == NULL) {
|
||||
free(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Tileset
|
||||
world->tileset = tilesetCreate(
|
||||
world->texture->width/16, world->texture->height/16,
|
||||
world->texture->width, world->texture->height,
|
||||
0, 0, 0, 0
|
||||
);
|
||||
if(world->tileset == NULL) {
|
||||
textureDispose(world->texture);
|
||||
free(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Tilemap
|
||||
world->tilemap = tileMapCreate(world->tileset);
|
||||
if(world->tilemap == NULL) {
|
||||
textureDispose(world->texture);
|
||||
tilesetDispose(world->tileset);
|
||||
free(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Chunk Lists
|
||||
world->chunkList = chunkListCreate(1, 1, 1, world->tilemap);
|
||||
if(world->chunkList == NULL) {
|
||||
textureDispose(world->texture);
|
||||
tilesetDispose(world->tileset);
|
||||
tileMapDispose(world->tilemap);
|
||||
free(world);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
void worldRender(world_t *world, shader_t *shader) {
|
||||
int32_t i;
|
||||
|
||||
shaderUseTexture(shader, world->texture);
|
||||
chunkListRender(world->chunkList, shader);
|
||||
}
|
||||
|
||||
void worldDispose(world_t *world) {
|
||||
textureDispose(world->texture);
|
||||
tilesetDispose(world->tileset);
|
||||
tileMapDispose(world->tilemap);
|
||||
chunkListDispose(world->chunkList);
|
||||
free(world);
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// Copyright (c) 2021 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "defs.h"
|
||||
#include "chunklist.h"
|
||||
#include "tile.h"
|
||||
#include "../display/shader.h"
|
||||
#include "../display/tileset.h"
|
||||
#include "../display/texture.h"
|
||||
#include "../file/asset.h"
|
||||
|
||||
|
||||
world_t * worldCreate();
|
||||
|
||||
void worldRender(world_t *world, shader_t *shader);
|
||||
|
||||
void worldDispose(world_t *world);
|
6
tools/map/index.js
Normal file
6
tools/map/index.js
Normal file
@ -0,0 +1,6 @@
|
||||
const fs = require('fs');
|
||||
|
||||
let buffer = "";
|
||||
for(let i = 0; i < (16*16*8); i++) buffer += "0;";
|
||||
|
||||
fs.writeFileSync('out.txt', buffer);
|
Reference in New Issue
Block a user