Refactored.

This commit is contained in:
2021-04-22 13:55:34 +10:00
parent c10754f31b
commit f7c1380f06
62 changed files with 1033 additions and 1391 deletions

3
.gitignore vendored
View File

@ -69,4 +69,5 @@ build
.vscode .vscode
lib lib
assets/testworld/tileset.png assets/testworld/tileset.png
oldsrc

View File

@ -15,7 +15,7 @@ include(FetchContent)
set(DEPS_DIR "${PROJECT_BINARY_DIR}/_deps") set(DEPS_DIR "${PROJECT_BINARY_DIR}/_deps")
#################################### PROJECT ################################### #################################### PROJECT ###################################
project(Dawn VERSION 1.0) project(DawnGame VERSION 1.0)
##################################### SRCS ##################################### ##################################### SRCS #####################################
file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/src/*.c) file(GLOB_RECURSE SOURCE_FILES ${CMAKE_SOURCE_DIR}/src/*.c)
@ -24,6 +24,7 @@ file(COPY ${CMAKE_CURRENT_LIST_DIR}/assets DESTINATION ${CMAKE_CURRENT_BINARY_DI
##################################### LIBS ##################################### ##################################### LIBS #####################################
include_directories(${CMAKE_SOURCE_DIR}/lib/stb) include_directories(${CMAKE_SOURCE_DIR}/lib/stb)
include_directories(${CMAKE_SOURCE_DIR}/include)
################################## EXECUTABLE ################################## ################################## EXECUTABLE ##################################
add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES}) add_executable(${PROJECT_NAME} ${HEADER_FILES} ${SOURCE_FILES})

29
include/dawn/dawn.h Normal file
View File

@ -0,0 +1,29 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "libs.h"
#include "display/camera.h"
#include "display/primitive.h"
#include "display/render.h"
#include "display/shader.h"
#include "display/spritebatch.h"
#include "display/texture.h"
#include "display/tileset.h"
#include "file/asset.h"
#include "game/game.h"
#include "input/input.h"
#include "util/list.h"
#include "world/entity/entity.h"
#include "world/map/chunk.h"
#include "world/map/map.h"
#include "world/map/tile.h"
#include "world/world.h"

View File

@ -0,0 +1,18 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
/** The math for the camera is stored here. */
typedef struct {
/** View Matrix (Where the camera looks) */
mat4 view;
/** Projection Matrix (How the camera looks) */
mat4 projection;
} camera_t;

View File

@ -0,0 +1,30 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#define PRIMITIVE_POSITIONS_PER_VERTICE 3
#define PRIMITIVE_COORDINATES_PER_VERTICE 2
/** Structure containing information about a primitive */
typedef struct {
int32_t verticeCount;
int32_t indiceCount;
GLuint vertexBuffer;
GLuint indexBuffer;
} primitive_t;
/** Structure containing vertice position information */
typedef struct {
float x, y, z;
float u, v;
} vertice_t;
/** Indice that references a specific vertice */
typedef unsigned int indice_t;

View File

@ -0,0 +1,19 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
/**
* Contains information about the current render state, can be used for querying
* how the renderer is currently set up.
*/
typedef struct {
/** Resolution (in pixels) */
int32_t width, height;
} render_t;
/** Current render state */
extern render_t RENDER_STATE;

View File

@ -0,0 +1,41 @@
/**
* Copyright (c) 2021 Dominic Msters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
#define SHADER_UNI_VIEW "u_View"
#define SHADER_UNI_PROJ "u_Proj"
#define SHADER_UNI_TEXT "u_Text"
#define SHADER_UNI_MODL "u_Modl"
/**
* Structure containing information about an OpenGL Shader. For simplicity sake
* we demand certain uninforms to be present on the shader target.
*/
typedef struct {
/** Pointer to an uploaded vertex shader program */
GLuint shaderVertex;
/** Pointer to an uploaded fragment shader program */
GLuint shaderFrag;
/** Pointer to an uploaded shader program linked */
GLuint shaderProgram;
/** Matrix for the view matrix */
GLint uniView;
/** Matrix for the projection matrix */
GLint uniProj;
/** Uniform for the current texture */
GLint uniText;
/** Uniform for the current model world position */
GLint uniModl;
} shader_t;

View File

@ -0,0 +1,21 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../libs.h"
/** Definition of a Sprite Batch. */
typedef struct {
/** Maximum sprites the batch can hold. */
int32_t maxSprites;
/** The current/next sprite index. */
int32_t currentSprite;
/** Internal primitive */
primitive_t *primitive;
} spritebatch_t;

View File

@ -0,0 +1,23 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
/**
* Structure detailing information about a texture.
* Because we plan to upload the pixels of a texture into the GPU, we don't
* store the pixels in memory because we don't need to!
*/
typedef struct {
int32_t width;
int32_t height;
GLuint id;
} texture_t;
/** Information about a single pixel. */
typedef struct {
uint8_t r, g, b, a ;
} pixel_t;

View File

@ -0,0 +1,24 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
/** Division of a texture */
typedef struct {
float x0, y0, x1, y1;
} tilesetdiv_t;
/** Definition of a Tileset */
typedef struct {
/** Count of X/Y divisions */
int32_t columns, rows;
/** Count of divisions (unused) */
int32_t count;
/** Division information */
tilesetdiv_t *divisions;
} tileset_t;

View File

@ -0,0 +1,9 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
/** Prefix of all asset load methods, may be customizable in future. */
#define ASSET_PREFIX "../assets/"

25
include/dawn/game/game.h Normal file
View File

@ -0,0 +1,25 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../display/shader.h"
#include "../display/camera.h"
/** Name of the current game */
#define GAME_NAME "Dawn"
/** Describes the current game */
typedef struct {
/** Describes the name of a specific game. */
char *name;
/** World Rendering stuff. */
shader_t *shaderWorld;
camera_t cameraWorld;
} game_t;
/** The current running game state. */
extern game_t GAME_STATE;

View File

@ -0,0 +1,69 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "../util/list.h"
/** Inputs */
#define GAME_INPUT_UP (inputbind_t)0x01
#define GAME_INPUT_DOWN (inputbind_t)0x02
#define GAME_INPUT_LEFT (inputbind_t)0x03
#define GAME_INPUT_RIGHT (inputbind_t)0x04
#define INPUT_NULL (inputbind_t)0x00
#define INPUT_BIND_COUNT 128
#define INPUT_SOURCE_COUNT 4096
/**
* Input Bind, a specific action bind reference for the game engine to use.
* e.g. "Jump" or "Walk Forward".
*/
typedef uint8_t inputbind_t;
/**
* Input source identifier. It's up to the platform itself to decide what the
* hell this number refers to. For most platforms it will be an input, such as a
* keyboard scancode or a (pad number * button count) + button.
*/
typedef uint32_t inputsource_t;
/**
* Value that represents the state of an input. Defined as 0-1 where 0 is set
* to be completely off / netural state, and 1 is completely on / full state.
*/
typedef float inputval_t;
/**
* Structure for the entire input mapping.
*/
typedef struct {
/** Float of the input between 0 and 1. */
inputval_t inputsA[INPUT_BIND_COUNT];
/** Float of the input between 0 and 1. */
inputval_t inputsB[INPUT_BIND_COUNT];
/** Flippable state */
inputval_t *current, *previous;
/**
* Binding Map, Array of lists where index = binding and entry is a list of
* input sources.
*/
list_t *bindMap[INPUT_BIND_COUNT];
/**
* Input buffer array. Keeps track of raw values from the inputs.
* The engine will read from the buffer when necessary.
*/
inputval_t buffer[INPUT_SOURCE_COUNT];
/** Float of the GameTime that the input was actuated last. */
float times[INPUT_BIND_COUNT];
} input_t;
/** The current input state */
extern input_t INPUT_STATE;

21
include/dawn/libs.h Normal file
View File

@ -0,0 +1,21 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
// Static Libs
#include <cglm/cglm.h>
#include <glad/glad.h>
// Standard Libs
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <malloc.h>
#include <string.h>
#if defined(_WIN32) || defined(_WIN64)
# define strtok_r strtok_s
#endif

31
include/dawn/util/list.h Normal file
View File

@ -0,0 +1,31 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
/**
* Entry within a given linked list.
* @param data* The pointer to the data that is within the entry.
* @param prev* Pointer to the previous entry in the list.
* @param next* Pointer to the next entry in the list.
*/
typedef struct listentry_t {
void *data;
struct listentry_t *prev;
struct listentry_t *next;
} listentry_t;
/**
* Linked List of elements, Doubly Linked.
* @param size The count of elements currently within the list
* @param start* First element within the list.
* @param end* Last element within the list.
*/
typedef struct {
uint32_t size;
listentry_t *start;
listentry_t *end;
} list_t;

View File

@ -0,0 +1,23 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#define ENTITY_COUNT 64
typedef struct {
int32_t gridX, gridY, gridZ;
int32_t oldGridX, oldGridY, oldGridZ;
float positionX, positionY, positionZ;
} entity_t;
typedef struct {
entity_t entities[ENTITY_COUNT]
} entitystate_t;
extern entitystate_t ENTITY_STATE;

View File

@ -1,21 +1,24 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <string.h> #include "../../libs.h"
#include "../../display/primitive.h"
#include "tile.h" #include "tile.h"
#include "../file/asset.h"
#include "../input/input.h"
#include "../util/string.h"
/** When loading a chunk, how many chars to offset (ASCII char to byte) */ /** When loading a chunk, how many chars to offset (ASCII char to byte) */
#define CHUNK_TILE_LOAD_ASCII 48 #define CHUNK_TILE_LOAD_ASCII 48
/** Width (in tiles) of chunks. */ /** Width (in tiles) of chunks. */
#define CHUNK_WIDTH 16 #define CHUNK_WIDTH 16
/** Heihgt (in tiles) of chunks. */ /** Height (in tiles) of chunks. */
#define CHUNK_HEIGHT 16 #define CHUNK_HEIGHT 16
/** Depth (in tiles) of chunks. */ /** Depth (in tiles) of chunks. */
#define CHUNK_DEPTH 8 #define CHUNK_DEPTH 8
/** Count of tiles in the chunk. */ /** Count of tiles in the chunk. */
#define CHUNK_TILE_COUNT CHUNK_WIDTH*CHUNK_HEIGHT*CHUNK_DEPTH #define CHUNK_TILE_COUNT CHUNK_WIDTH * CHUNK_HEIGHT * CHUNK_DEPTH
/** Representation of a chunk, a group of tiles that can be buffered around. */ /** Representation of a chunk, a group of tiles that can be buffered around. */
typedef struct { typedef struct {
@ -27,23 +30,4 @@ typedef struct {
/** Ready to be rendered chunk 3d primitive */ /** Ready to be rendered chunk 3d primitive */
primitive_t *primitive; primitive_t *primitive;
} chunk_t; } chunk_t;
/**
* Loads a given chunk.
*
* @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(chunk_t *chunk, tilemap_t *tilemap,
int32_t x, int32_t y, int32_t z
);
/**
* Unload a given chunk.
*
* @param chunk Chunk to unload.
*/
void chunkUnload(chunk_t *chunk);

View File

@ -0,0 +1,46 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "../../libs.h"
#include "tile.h"
#include "chunk.h"
#include "../../display/texture.h"
#include "../../display/tileset.h"
/** Width of map (in chunks) */
#define MAP_WIDTH 3
/** Height of map (in chunks) */
#define MAP_HEIGHT MAP_WIDTH
/** Depth of map (in chunks) */
#define MAP_DEPTH 2
/** Count of chunks in the world */
#define MAP_CHUNK_COUNT MAP_WIDTH * MAP_HEIGHT * MAP_DEPTH
#define MAP_ASSET_TEXTURE "world/tileset.png"
typedef struct {
/** Tile definitions */
tiledef_t *tileDefinitions;
/** Tileset predivided */
tileset_t *tileset;
/** Texture of the tileset */
texture_t *texture;
/** Current (chunk) coordinates of the first chunk in the chunk list */
int32_t x, y, z;
/** Current chunk list, ordered */
chunk_t *chunkList[MAP_CHUNK_COUNT];
/** Chunk array, unordered */
chunk_t chunks[MAP_CHUNK_COUNT];
} map_t;
extern map_t MAP_STATE;

View File

@ -0,0 +1,29 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../../libs.h"
/** Width of a tile (in pixels) */
#define TILE_WIDTH 16
/** Height of a tile (in pixels) */
#define TILE_HEIGHT 16
/** What a NULL tile is represented as. */
#define TILE_NULL 0x00
/** Bitwise Flags from tiles. */
typedef uint8_t tileflag_t;
/** Tile ID */
typedef uint8_t tileid_t;
/** Representation of the information of a tile within a tilemap. */
typedef struct {
/** Flags of the tile */
tileflag_t flags;
/** How many indices and vertices a tile with this definition has. */
int32_t indiceCount, verticeCount;
} tiledef_t;

View File

@ -0,0 +1,9 @@
// Copyright (c) 2021 Dominic Masters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include "../libs.h"
#include "map/chunk.h"
#include "map/map.h"

View File

@ -7,16 +7,6 @@
#include "camera.h" #include "camera.h"
camera_t * cameraCreate() {
camera_t *camera = malloc(sizeof(camera_t));
if(!camera) return NULL;
return camera;
}
void cameraDispose(camera_t *camera) {
free(camera);
}
void cameraLookAt(camera_t *camera, void cameraLookAt(camera_t *camera,
float x, float y, float z, float targetX, float targetY, float targetZ float x, float y, float z, float targetX, float targetY, float targetZ
) { ) {

View File

@ -4,31 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <cglm/cglm.h> #include <dawn/dawn.h>
#include <malloc.h>
/** The math for the camera is stored here. */
typedef struct {
/** View Matrix (Where the camera looks) */
mat4 view;
/** Projection Matrix (How the camera looks) */
mat4 projection;
} camera_t;
/**
* Create a new camera instance.
*
* @return A new camera instance.
*/
camera_t * cameraCreate();
/**
* Cleanup a previously created camera
*
* @param camera Camera instance to dispose.
*/
void cameraDispose(camera_t *camera);
/** /**
* Make a camera look at a position in world space while itself being positioned * Make a camera look at a position in world space while itself being positioned

View File

@ -6,30 +6,7 @@
*/ */
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include <glad/glad.h>
#include <malloc.h>
#define PRIMITIVE_POSITIONS_PER_VERTICE 3
#define PRIMITIVE_COORDINATES_PER_VERTICE 2
/** Structure containing information about a primitive */
typedef struct {
int32_t verticeCount;
int32_t indiceCount;
GLuint vertexBuffer;
GLuint indexBuffer;
} primitive_t;
/** Structure containing vertice position information */
typedef struct {
float x, y, z;
float u, v;
} vertice_t;
/** Indice that references a specific vertice */
typedef unsigned int indice_t;
/** /**
* Creates a new primitive. * Creates a new primitive.

View File

@ -4,8 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include <malloc.h>
#include "../primitive.h" #include "../primitive.h"
#define CUBE_VERTICE_COUNT 8 #define CUBE_VERTICE_COUNT 8

View File

@ -46,7 +46,9 @@ primitive_t * quadCreate(float z,
float x0, float y0, float u0, float v0, float x0, float y0, float u0, float v0,
float x1, float y1, float u1, float v1 float x1, float y1, float u1, float v1
) { ) {
primitive_t *primitive = primitiveCreate(4, 6); primitive_t *primitive = primitiveCreate(
QUAD_VERTICE_COUNT, QUAD_INDICE_COUNT
);
quadBuffer(primitive, z, quadBuffer(primitive, z,
x0, y0, u0, v0, x0, y0, u0, v0,

View File

@ -4,7 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include "../primitive.h" #include "../primitive.h"
#define QUAD_VERTICE_COUNT 4 #define QUAD_VERTICE_COUNT 4

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (c) 2021 Dominic Msters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
@ -7,13 +7,9 @@
#include "render.h" #include "render.h"
render_t * renderInit(char *name) { render_t RENDER_STATE;
// Initialize the renderer
render_t *render = malloc(sizeof(render_t));
if(!render) return NULL;
// render->width = WINDOW_WIDTH_DEFAULT;
// render->height = WINDOW_HEIGHT_DEFAULT;
void renderInit() {
// Enable GL things. // Enable GL things.
glEnable(GL_BLEND); glEnable(GL_BLEND);
glEnable(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D);
@ -23,22 +19,18 @@ render_t * renderInit(char *name) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glDepthMask(GL_TRUE); glDepthMask(GL_TRUE);
glDepthFunc(GL_LEQUAL); glDepthFunc(GL_LEQUAL);
return render;
} }
void renderFrame(render_t *render) { void renderFrameStart() {
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
} }
bool renderDispose(render_t *render) { void renderDispose() {
// Free up the renderer
free(render);
return true;
} }
void renderSetResolution(render_t *render, uint32_t width, uint32_t height) { void renderSetResolution(int32_t width, int32_t height) {
render->width = width; RENDER_STATE.width = width;
render->height = height; RENDER_STATE.height = height;
glViewport(0, 0, width, height); glViewport(0, 0, width, height);
} }

View File

@ -1,58 +1,31 @@
/** // Copyright (c) 2021 Dominic Masters
* Copyright (c) 2021 Dominic Msters //
* // This software is released under the MIT License.
* This software is released under the MIT License. // https://opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
#pragma once #pragma once
#include <dawn/dawn.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <malloc.h>
#include <glad/glad.h>
#include <cglm/call.h>
#include "primitive.h"
/**
* Contains information about the current render state, can be used for querying
* how the renderer is currently set up.
*/
typedef struct {
/** Resolution (in pixels) */
int32_t width, height;
} render_t;
/** /**
* Initialize the renderer. * Initialize the renderer.
*
* @param name String of the windows' name.
* @return Rendering Context information.
*/ */
render_t * renderInit(char *name); void renderInit();
/** /**
* Render a single frame of the render loop. The renderer is not (currently) * Render a single frame of the render loop. The renderer is not (currently)
* responsible for render looping. * responsible for render looping.
*
* @param render The renderer to loop for.
*/ */
void renderFrame(render_t *render); void renderFrameStart();
/** /**
* Cleanup a render context. * Cleanup a render context.
*
* @param render Renderer to cleanup.
* @return True or False if Successful/Not.
*/ */
bool renderDispose(render_t *render); void renderDispose();
/** /**
* Set the internal display resolution. * Sets the internal display resolution.
* *
* @param render Renderer to set resolution for. * @param width Width of the display (in pixels).
* @param width Width (in pixels) of the viewport. * @param height Height of the display (in pixels).
* @param height Height (in pixels) of the viewport.
*/ */
void renderSetResolution(render_t *render, uint32_t width, uint32_t height); void renderSetResolution(int32_t width, int32_t height);

View File

@ -90,7 +90,7 @@ shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource) {
return shader; return shader;
} }
bool shaderDipose(shader_t *shader) { bool shaderDispose(shader_t *shader) {
glDeleteProgram(shader->shaderProgram); glDeleteProgram(shader->shaderProgram);
glDeleteShader(shader->shaderVertex); glDeleteShader(shader->shaderVertex);
glDeleteShader(shader->shaderFrag); glDeleteShader(shader->shaderFrag);

View File

@ -6,45 +6,7 @@
*/ */
#pragma once #pragma once
#include <dawn/dawn.h>
#include <glad/glad.h>
#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
#include "camera.h"
#include "texture.h"
#define SHADER_UNI_VIEW "u_View"
#define SHADER_UNI_PROJ "u_Proj"
#define SHADER_UNI_TEXT "u_Text"
#define SHADER_UNI_MODL "u_Modl"
/**
* Structure containing information about an OpenGL Shader. For simplicity sake
* we demand certain uninforms to be present on the shader target.
*/
typedef struct {
/** Pointer to an uploaded vertex shader program */
GLuint shaderVertex;
/** Pointer to an uploaded fragment shader program */
GLuint shaderFrag;
/** Pointer to an uploaded shader program linked */
GLuint shaderProgram;
/** Matrix for the view matrix */
GLint uniView;
/** Matrix for the projection matrix */
GLint uniProj;
/** Uniform for the current texture */
GLint uniText;
/** Uniform for the current model world position */
GLint uniModl;
} shader_t;
/** /**
* Create a shader from vertex and fragment shader code. * Create a shader from vertex and fragment shader code.
@ -61,7 +23,7 @@ shader_t * shaderCompile(char *vertexShaderSource, char* fragmentShaderSource);
* @param shader The shader to unload * @param shader The shader to unload
* @return True if successfully disposed. * @return True if successfully disposed.
*/ */
bool shaderDipose(shader_t *shader); bool shaderDispose(shader_t *shader);
/** /**
* Attaches the supplied shader as the current shader. * Attaches the supplied shader as the current shader.

View File

@ -4,22 +4,11 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include "primitive.h" #include "primitive.h"
#include "primitives/quad.h" #include "primitives/quad.h"
#include "../util/math.h" #include "../util/math.h"
typedef struct {
/** Maximum sprites the batch can hold. */
int32_t maxSprites;
/** The current/next sprite index. */
int32_t currentSprite;
/** Internal primitive */
primitive_t *primitive;
} spritebatch_t;
/** /**
* Creates a new Sprite Batch made of standard quads. * Creates a new Sprite Batch made of standard quads.
* *

View File

@ -4,26 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include <glad/glad.h>
#include <malloc.h>
#include <memory.h>
/**
* Structure detailing information about a texture.
* Because we plan to upload the pixels of a texture into the GPU, we don't
* store the pixels in memory because we don't need to!
*/
typedef struct {
int32_t width;
int32_t height;
GLuint id;
} texture_t;
/** Information about a single pixel. */
typedef struct {
uint8_t r, g, b, a ;
} pixel_t;
/** /**
* Creates a new texture that can be written in to. * Creates a new texture that can be written in to.

View File

@ -4,26 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include <malloc.h>
/** Division of a texture */
typedef struct {
float x0, y0, x1, y1;
} tilesetdiv_t;
/** Definition of a Tileset */
typedef struct {
/** Count of X/Y divisions */
int32_t columns, rows;
/** Count of divisions (unused) */
int32_t count;
/** Division information */
tilesetdiv_t *divisions;
} tileset_t;
/** /**
* Create a tileset. Tilesets will be pre-divided to save performance later. * Create a tileset. Tilesets will be pre-divided to save performance later.

View File

@ -1,46 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "engine.h"
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount) {
// Create the engine instance.
engine_t *engine = malloc(sizeof(engine_t));
if(engine == NULL) return NULL;
engine->name = name;
engine->platform = platform;
// Setup the renderer.
engine->render = renderInit(name);
if(engine->render == NULL) {
free(engine);
return NULL;
}
// Setup the input manager.
engine->input = inputInit(inputCount, platform->inputSourceCount);
if(engine->input == NULL) {
free(engine->render);
free(engine);
return NULL;
}
return engine;
}
uint32_t engineUpdate(engine_t *engine) {
renderFrame(engine->render);
inputUpdate(engine->input);
return 0;
}
bool engineDispose(engine_t *engine) {
if(!renderDispose(engine->render)) return false;
free(engine);
return true;
}

View File

@ -1,52 +0,0 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <stdbool.h>
#include "display/render.h"
#include "input/input.h"
#include "./platform.h"
/** Information about the current engine context. */
typedef struct {
/** Name of the game running. */
char *name;
/** Platform the game is running on */
platform_t *platform;
/** Renderer for the engine. */
render_t *render;
/** Input Manager for the engine. */
input_t *input;
} engine_t;
/**
* Initialize the engine context.
*
* @param platform The platform that the game is running on.
* @param name Name of the game being initialized.
* @param inputCount Count of input binds that exist in-engine.
* @return The engine context.
*/
engine_t * engineInit(platform_t *platform, char *name, uint32_t inputCount);
/**
* Start the main engine loop.
*
* @param engine The game to start the loop for.
* @return 0 if success (and loop to continue), 1 for non error terminate.
*/
uint32_t engineUpdate(engine_t *engine);
/**
* Cleanup a previously constructed game engine instance.
*
* @param engine The engine to cleanup.
* @return True if successful or not.
*/
bool engineDispose(engine_t *engine);

View File

@ -7,10 +7,9 @@
#include "asset.h" #include "asset.h"
#ifndef STB_IMAGE_IMPLEMENTATION // Due to some bullshit, this is here.
#define STB_IMAGE_IMPLEMENTATION #define STB_IMAGE_IMPLEMENTATION
#include <stb_image.h> #include <stb_image.h>
#endif
char * assetStringLoad(char *assetName) { char * assetStringLoad(char *assetName) {
// Open a buffer. // Open a buffer.

View File

@ -6,17 +6,10 @@
*/ */
#pragma once #pragma once
#include <stdbool.h> #include <dawn/dawn.h>
#include <stdio.h>
#include <stdint.h>
#include <malloc.h>
#include <string.h>
#include "../display/shader.h" #include "../display/shader.h"
#include "../display/texture.h" #include "../display/texture.h"
/** Prefix of all asset load methods, may be customizable in future. */
#define ASSET_PREFIX "../assets/"
/** /**
* Method to load an asset into memory as a raw string. * Method to load an asset into memory as a raw string.
* *

View File

@ -1,5 +1,5 @@
/** /**
* Copyright (c) 2021 Dominic Msters * Copyright (c) 2021 Dominic Masters
* *
* This software is released under the MIT License. * This software is released under the MIT License.
* https://opensource.org/licenses/MIT * https://opensource.org/licenses/MIT
@ -7,61 +7,52 @@
#include "game.h" #include "game.h"
game_t * gameInit(platform_t *platform) { game_t GAME_STATE;
// Create the game
game_t *game = malloc(sizeof(game_t));
if(game == NULL) return NULL;
// Load the game engine bool gameInit() {
game->engine = engineInit(platform, GAME_NAME, GAME_INPUT_COUNT); // Init the game
if(game->engine == NULL) { GAME_STATE.name = GAME_NAME;
free(game);
return NULL;
}
// Load the Shader // Init the renderer.
game->shader = assetShaderLoad("shaders/test.vert", "shaders/test.frag"); renderInit();
inputInit();
// Prepare the camera. worldInit();
game->camera = cameraCreate();
uint32_t d = 10;
cameraLookAt(game->camera, d, d, d, 0, 0, 0);
cameraPerspective(game->camera, 45.0f, 1920.0f/1080.0f, 0.5f, 500.0f);
// Load the world // Load the world shader.
game->world = worldLoad("testworld/"); GAME_STATE.shaderWorld = assetShaderLoad(
playerCreate(&game->world->entities, 0); "shaders/test.vert", "shaders/test.frag"
// Pass to the main game to handle
return game;
}
uint32_t gameUpdate(game_t *game) {
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, game->camera,
game->engine->input
); );
return 0; // Init the input manger.
return true;
} }
void gameDispose(game_t *game) { bool gameUpdate() {
worldDispose(game->world); renderFrameStart();
shaderDipose(game->shader); inputUpdate();
cameraDispose(game->camera);
engineDispose(game->engine); // Attach the world shader
free(game); shaderUse(GAME_STATE.shaderWorld);
// Set up the camera.
int32_t d = 50;
cameraLookAt(&GAME_STATE.cameraWorld, d, d, d, 0, 0, 0);
cameraPerspective(&GAME_STATE.cameraWorld, 45.0f,
((float)RENDER_STATE.width) / ((float)RENDER_STATE.height),
0.5f, 500.0f
);
shaderUseCamera(GAME_STATE.shaderWorld, &GAME_STATE.cameraWorld);
// Render the game scene.
worldRender();
if(inputIsPressed(INPUT_NULL)) return false;
return true;
} }
engine_t * gameGetEngine(game_t *game) { void gameDispose() {
return game->engine; shaderDispose(GAME_STATE.shaderWorld);
worldDispose();
inputDispose();
renderDispose();
} }

View File

@ -1,62 +1,32 @@
/** // Copyright (c) 2021 Dominic Masters
* Copyright (c) 2021 Dominic Msters //
* // This software is released under the MIT License.
* This software is released under the MIT License. // https://opensource.org/licenses/MIT
* https://opensource.org/licenses/MIT
*/
#pragma once #pragma once
#include <stdbool.h> #include <dawn/dawn.h>
#include "../engine.h" #include "../display/render.h"
#include "../platform.h"
#include "../display/camera.h" #include "../display/camera.h"
#include "../display/shader.h" #include "../display/shader.h"
#include "../file/asset.h"
#include "../input/input.h"
#include "../world/world.h" #include "../world/world.h"
#include "../world/entity/player.h"
/////////////////////////////////// CONSTANTS //////////////////////////////////
/** Name of the Game */
#define GAME_NAME "Dawn Game"
/** Inputs */
#define GAME_INPUT_UP (inputbind_t)0x01
#define GAME_INPUT_DOWN (inputbind_t)0x02
#define GAME_INPUT_LEFT (inputbind_t)0x03
#define GAME_INPUT_RIGHT (inputbind_t)0x04
#define GAME_INPUT_COUNT 5
/////////////////////////////// TYPE DEFINITIONS ///////////////////////////////
/** Information about the current game context. */
typedef struct game_t {
/** The engine context for the game */
engine_t *engine;
/** Rendering items */
camera_t *camera;
shader_t *shader;
world_t *world;
} game_t;
/** /**
* Initialize the game context. * Initialize the game context.
* *
* @return The game instance context. * @return True if successful, otherwise false.
*/ */
game_t * gameInit(platform_t *platform); bool gameInit();
/** /**
* Start the main game loop. * Tick the main game loop.
* *
* @param game The game to start the loop for. * @return True if successful, false if safe exit requested..
* @return Refer to engineUpdate. 0 for loop continue, 1 for safe exit.
*/ */
uint32_t gameUpdate(game_t *game); bool gameUpdate();
/** /**
* Cleanup a previously constructed. * Cleanup the game instance.
* @param game The game to cleanup.
*/ */
void gameDispose(game_t *game); void gameDispose();

View File

@ -7,114 +7,96 @@
#include "input.h" #include "input.h"
input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount) { input_t INPUT_STATE;
uint32_t i;
// Create the input manager void inputInit() {
input_t *input = malloc(sizeof(input_t)); int32_t i;
if(!input) return NULL;
// Setup the bind lists // Setup the bind lists
input->inputBindCount = inputBindCount; for(i = 0; i < INPUT_BIND_COUNT; i++) {
input->bindMap = malloc(sizeof(list_t) * inputBindCount); INPUT_STATE.bindMap[i] = listCreate();
for(i = 0; i < inputBindCount; i++) {
input->bindMap[i] = listCreate();
} }
// Create the current & previous input states INPUT_STATE.current = INPUT_STATE.inputsA;
input->current = malloc(sizeof(inputval_t) * inputBindCount); INPUT_STATE.previous = INPUT_STATE.inputsB;
input->previous = malloc(sizeof(inputval_t) * inputBindCount);
// Create the input actuate times array.
input->times = malloc(sizeof(float) * inputBindCount);
// Create the buffer, zero all the values out. // Create the buffer, zero all the values out.
input->buffer = calloc(inputSourceCount, sizeof(inputval_t)); memset(&INPUT_STATE.buffer, 0, sizeof(inputval_t)*INPUT_SOURCE_COUNT);
// Pass off the input manager
return input;
} }
void inputUpdate(input_t *input) { void inputUpdate() {
uint32_t i; int32_t i;
listentry_t *item; listentry_t *item;
inputval_t value; inputval_t value;
// Flip the states to save memory. // Flip the states to save memory.
float * currentCurrent = input->current; inputval_t *currentCurrent = INPUT_STATE.current;
input->current = input->previous; INPUT_STATE.current = INPUT_STATE.previous;
input->previous = currentCurrent; INPUT_STATE.previous = currentCurrent;
// Now look at each bind... // Now look at each bind...
for(i = 0; i < input->inputBindCount; i++) { for(i = 0; i < INPUT_BIND_COUNT; i++) {
// Now get the list of input sources bound to this input // Now get the list of input sources bound to this input
item = input->bindMap[i]->start; item = INPUT_STATE.bindMap[i]->start;
value = 0; value = 0;
// For each input source, add the value from the buffer // For each input source, add the value from the buffer
while(item != NULL) { while(item != NULL) {
value += input->buffer[(inputsource_t)item->data]; value += INPUT_STATE.buffer[(inputsource_t)item->data];
item = item->next; item = item->next;
} }
// Set to the current state. // Set to the current state.
input->current[i] = value; INPUT_STATE.current[i] = value;
} }
} }
void inputDispose(input_t *input) { void inputDispose() {
uint32_t i; int32_t i;
// Free up the bind lists // Free up the bind lists
for(i = 0; i < input->inputBindCount; i++) { for(i = 0; i < INPUT_BIND_COUNT; i++) {
listDispose(input->bindMap[i], false); listDispose(INPUT_STATE.bindMap[i], false);
} }
free(input->buffer);
free(input->times);
free(input->previous);
free(input->current);
free(input->bindMap);
free(input);
} }
void inputBind(input_t *input, inputbind_t bind, inputsource_t source) { void inputBind(inputbind_t bind, inputsource_t source) {
listAdd(input->bindMap[bind], source); listAdd(INPUT_STATE.bindMap[bind], (void *)source);
} }
void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source) { void inputUnbind(inputbind_t bind, inputsource_t source) {
listRemove(input->bindMap[bind], source); listRemove(INPUT_STATE.bindMap[bind], (void *)source);
} }
bool inputIsDown(input_t *input, inputbind_t binding) { bool inputIsDown(inputbind_t binding) {
return input->current[binding] != 0; return INPUT_STATE.current[binding] != 0;
} }
bool inputIsUp(input_t *input, inputbind_t binding) { bool inputIsUp(inputbind_t binding) {
return input->current[binding] == 0; return INPUT_STATE.current[binding] == 0;
} }
bool inputIsPressed(input_t *input, inputbind_t binding) { bool inputIsPressed(inputbind_t binding) {
return ( return (
input->previous[binding] == 0 && INPUT_STATE.previous[binding] == 0 &&
input->current[binding] != 0 INPUT_STATE.current[binding] != 0
); );
} }
bool inputIsReleased(input_t *input, inputbind_t binding) { bool inputIsReleased(inputbind_t binding) {
return input->current[binding] == 0 && input->previous[binding] != 0; return INPUT_STATE.current[binding]==0 && INPUT_STATE.previous[binding] != 0;
} }
inputval_t inputGetAxis(input_t *input, inputbind_t binding) { inputval_t inputGetAxis(inputbind_t binding) {
return input->current[binding]; return INPUT_STATE.current[binding];
} }
float inputGetFullAxis(input_t *input, inputbind_t positive, float inputGetFullAxis(inputbind_t positive,
inputbind_t negative inputbind_t negative
) { ) {
return input->current[negative] + input->current[positive]; return INPUT_STATE.current[negative] + INPUT_STATE.current[positive];
} }
float inputGetAccuated(input_t *input, inputbind_t binding) { float inputGetAccuated(inputbind_t binding) {
return input->times[binding]; return INPUT_STATE.times[binding];
} }

View File

@ -1,158 +1,86 @@
// Copyright (c) 2021 Dominic Msters // Copyright (c) 2021 Dominic Masters
// //
// This software is released under the MIT License. // This software is released under the MIT License.
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdbool.h> #include <dawn/dawn.h>
#include <stdint.h>
#include <malloc.h>
#include <memory.h>
#include <string.h>
#include "../util/list.h" #include "../util/list.h"
#include "../platform.h"
/////////////////////////////////// CONSTANTS //////////////////////////////////
#define INPUT_NULL (inputbind_t)0x00
/////////////////////////////// Type Definitions ///////////////////////////////
/**
* Input Bind, a specific action bind reference for the game engine to use.
* e.g. "Jump" or "Walk Forward".
*/
typedef uint8_t inputbind_t;
/**
* Input source identifier. It's up to the platform itself to decide what the
* hell this number refers to. For most platforms it will be an input, such as a
* keyboard scancode or a (pad number * button count) + button.
*/
typedef uint32_t inputsource_t;
/**
* Value that represents the state of an input. Defined as 0-1 where 0 is set
* to be completely off / netural state, and 1 is completely on / full state.
*/
typedef float inputval_t;
/**
* Structure for the entire input mapping.
*/
typedef struct {
/** How many input bindings are in the input managers' scope */
uint32_t inputBindCount;
/** Float of the input between 0 and 1. For teh current frame */
inputval_t *current;
/** Float of the input between 0 and 1. For the last frame */
inputval_t *previous;
/**
* Input buffer array. Keeps track of raw values from the inputs.
* The engine will read from the buffer when necessary.
*/
inputval_t *buffer;
/** Float of the GameTime that the input was actuated last. */
float *times;
/**
* Binding Map, Array of lists where index = binding and entry is a list of
* input sources.
*/
list_t **bindMap;
} input_t;
//////////////////////////////////// Methods ///////////////////////////////////
/** /**
* Initializes the input manager. * Initializes the input manager.
*
* @param inputCount The input binding counts to allow for.
* @param inputSourceCount The input source count to allow for.
* @return The input manager
*/ */
input_t * inputInit(uint32_t inputBindCount, uint32_t inputSourceCount); void inputInit();
/** /**
* Tick the input manager. * Tick the input manager.
* @param input The input to update.
*/ */
void inputUpdate(input_t *input); void inputUpdate();
/** /**
* Destroy the input manager and cleanup. * Destroy the input manager and cleanup.
* @param input The input to destroy.
*/ */
void inputDispose(input_t *input); void inputDispose();
/** /**
* Binds the given input binding to the input source. Essentially allowing any * Binds the given input binding to the input source. Essentially allowing any
* time we fetch the state of bind, we will read the value from source. * time we fetch the state of bind, we will read the value from source.
* *
* @param input The input manager to bind for.
* @param bind The binding to bind against. * @param bind The binding to bind against.
* @param source The source that is being bound. * @param source The source that is being bound.
*/ */
void inputBind(input_t *input, inputbind_t bind, inputsource_t source); void inputBind(inputbind_t bind, inputsource_t source);
/** /**
* Unbind a previously bound input source from a binding. This method is costly. * Unbind a previously bound input source from a binding. This method is costly.
* *
* @param input The input manager to bind for.
* @param bind The binding to unbind from. * @param bind The binding to unbind from.
* @param source The source that is being unbound. * @param source The source that is being unbound.
*/ */
void inputUnbind(input_t *input, inputbind_t bind, inputsource_t source); void inputUnbind(inputbind_t bind, inputsource_t source);
/** /**
* Is the current input "down", being pressed, being moved, not in a state * Is the current input "down", being pressed, being moved, not in a state
* of rest. * of rest.
* *
* @param state The input state to check against.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return True if the input vector is non-zero. * @return True if the input vector is non-zero.
*/ */
bool inputIsDown(input_t *state, inputbind_t binding); bool inputIsDown(inputbind_t binding);
/** /**
* Is the current input "up", in a state of rest, not being actioned, moved. * Is the current input "up", in a state of rest, not being actioned, moved.
* *
* @param state The input state to check against.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return True if input vector is zero * @return True if input vector is zero
*/ */
bool inputIsUp(input_t *state, inputbind_t binding); bool inputIsUp(inputbind_t binding);
/** /**
* Returns true on the first tick that an input was actioned/downed. * Returns true on the first tick that an input was actioned/downed.
* *
* @param input The input manager.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return True if the input vector was non-zeroed this tick but not last. * @return True if the input vector was non-zeroed this tick but not last.
*/ */
bool inputIsPressed(input_t *input, inputbind_t binding); bool inputIsPressed(inputbind_t binding);
/** /**
* Returns true on the first tick that an input was released/upped. * Returns true on the first tick that an input was released/upped.
* *
* @param input The input manager.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return True if the input vector was zeroed this tick but not last. * @return True if the input vector was zeroed this tick but not last.
*/ */
bool inputIsReleased(input_t *input, inputbind_t binding); bool inputIsReleased(inputbind_t binding);
/** /**
* Returns the raw input value as a float between 0 and 1. For digital (buttons) * Returns the raw input value as a float between 0 and 1. For digital (buttons)
* this will typicall be 0 or 1 only. Other analogue inputs will have anywhere * this will typicall be 0 or 1 only. Other analogue inputs will have anywhere
* within the range. * within the range.
* *
* @param input The input manager to check against.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return Input state of the axis. * @return Input state of the axis.
*/ */
inputval_t inputGetAxis(input_t *input, inputbind_t binding); inputval_t inputGetAxis(inputbind_t binding);
/** /**
* Returns a raw input value between -1 and 1 between two axis. This would be * Returns a raw input value between -1 and 1 between two axis. This would be
@ -160,21 +88,17 @@ inputval_t inputGetAxis(input_t *input, inputbind_t binding);
* for a positive input and another for a negative input, typically a game * for a positive input and another for a negative input, typically a game
* controller's analogue sticks. * controller's analogue sticks.
* *
* @param input The input manager to check against.
* @param postitive The positive axis binding. * @param postitive The positive axis binding.
* @param negative The negative axis binding. * @param negative The negative axis binding.
* @return A float between -1 and 1 representing the result of both. * @return A float between -1 and 1 representing the result of both.
*/ */
float inputGetFullAxis(input_t *input, inputbind_t positive, float inputGetFullAxis(inputbind_t positive, inputbind_t negative);
inputbind_t negative
);
/** /**
* Returns the time that an input was actuated at. Actuate would count as a * Returns the time that an input was actuated at. Actuate would count as a
* non-zero input for analogue inputs. * non-zero input for analogue inputs.
* *
* @param input The input manager to check against.
* @param binding The previously bound input binding. * @param binding The previously bound input binding.
* @return Game Engine time that an input was non-zeroed * @return Game Engine time that an input was non-zeroed
*/ */
float inputGetAccuated(input_t *input, inputbind_t binding); float inputGetAccuated(inputbind_t binding);

View File

@ -1,31 +0,0 @@
// Copyright (c) 2021 Dominic Msters
//
// This software is released under the MIT License.
// https://opensource.org/licenses/MIT
#pragma once
#include <malloc.h>
#include <stdint.h>
#ifndef PLATFORMINPUT_T
#define PLATFORMINPUT_T void
#endif
/** Definition for the platform's input source */
typedef PLATFORMINPUT_T platforminput_t;
/**
* Contains information about the running platform. Essentially this is just
* some context as to what is running the game engine itself. It's mostly for
* metadata purposes but there may be some technical information required for
* the engine.
*/
typedef struct {
/** Internal name of the platform */
char *name;
/** Dimensions of the screen (in pixels) */
uint32_t screenWidth, screenHeight;
/** Count of input sources that exist in engine. */
uint32_t inputSourceCount;
} platform_t;

View File

@ -9,19 +9,9 @@ GLFWwindow *window = NULL;
game_t *runningGame = NULL; game_t *runningGame = NULL;
int32_t main() { int32_t main() {
// Create out platform context
platform_t platform = {
.name = "glfw",
.screenWidth = WINDOW_WIDTH_DEFAULT,
.screenHeight = WINDOW_HEIGHT_DEFAULT,
.inputSourceCount = 400
};
// Attempt to init GLFW // Attempt to init GLFW
if(!glfwInit()) return NULL; if(!glfwInit()) return NULL;
window = glfwCreateWindow(platform.screenWidth, platform.screenHeight, window = glfwCreateWindow(WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT,
"", NULL, NULL "", NULL, NULL
); );
if(!window) { if(!window) {
@ -37,28 +27,28 @@ int32_t main() {
glfwSetWindowSizeCallback(window, &glfwOnResize); glfwSetWindowSizeCallback(window, &glfwOnResize);
glfwSetKeyCallback(window, &glfwOnKey); glfwSetKeyCallback(window, &glfwOnKey);
// Create the game instance // Init the game
runningGame = gameInit(&platform); if(gameInit()) {
if(runningGame == NULL) return 1; // Bind initial keys
inputBind(INPUT_NULL, (inputsource_t)GLFW_KEY_ESCAPE);
// Update the window title. // Init the render resolution
glfwSetWindowTitle(window, runningGame->engine->name); renderSetResolution(WINDOW_WIDTH_DEFAULT, WINDOW_HEIGHT_DEFAULT);
// Bind inputs // Update the window title.
inputBind(runningGame->engine->input, INPUT_NULL, glfwSetWindowTitle(window, GAME_STATE.name);
(inputsource_t *)GLFW_KEY_ESCAPE
);
// Main Render Loop // Main Render Loop
while(!glfwWindowShouldClose(window)) { while(!glfwWindowShouldClose(window)) {
gameUpdate(runningGame); if(!gameUpdate()) break;
glfwSwapBuffers(window); glfwSwapBuffers(window);
glfwPollEvents(); glfwPollEvents();
}
// Game has finished running, cleanup.
gameDispose();
} }
// Game has finished running, cleanup.
gameDispose(runningGame);
// Terminate the GLFW context. // Terminate the GLFW context.
glfwSetWindowSizeCallback(window, NULL); glfwSetWindowSizeCallback(window, NULL);
@ -68,19 +58,15 @@ int32_t main() {
} }
void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) { void glfwOnResize(GLFWwindow *window, int32_t width, int32_t height) {
runningGame->engine->platform->screenWidth = width; renderSetResolution(width, height);
runningGame->engine->platform->screenWidth = height;
renderSetResolution(runningGame->engine->render, width, height);
} }
void glfwOnKey(GLFWwindow *window, void glfwOnKey(GLFWwindow *window,
int32_t key, int32_t scancode, int32_t action, int32_t mods int32_t key, int32_t scancode, int32_t action, int32_t mods
) { ) {
if(runningGame == NULL) return;
if(action == GLFW_PRESS) { if(action == GLFW_PRESS) {
runningGame->engine->input->buffer[key] = 1; INPUT_STATE.buffer[key] = 1;
} else if(action == GLFW_RELEASE) { } else if(action == GLFW_RELEASE) {
runningGame->engine->input->buffer[key] = 0; INPUT_STATE.buffer[key] = 0;
} }
} }

View File

@ -8,21 +8,16 @@
// I load GLAD and GLFW Here because they need to be included in specific orders // I load GLAD and GLFW Here because they need to be included in specific orders
#include <glad/glad.h> #include <glad/glad.h>
#include <GLFW/glfw3.h> #include <GLFW/glfw3.h>
#include <stdint.h> #include <dawn/dawn.h>
#include "../../display/render.h"
#define PLATFORMINPUT_T uint32_t
#include "../../platform.h"
#include "../../game/game.h" #include "../../game/game.h"
#include "../../input/input.h" #include "../../input/input.h"
#include "../../display/render.h"
#define WINDOW_WIDTH_DEFAULT 480 #define WINDOW_WIDTH_DEFAULT 480
#define WINDOW_HEIGHT_DEFAULT 270 #define WINDOW_HEIGHT_DEFAULT 270
/** The GLFW Window Context Pointer */ /** The GLFW Window Context Pointer */
extern GLFWwindow *window; extern GLFWwindow *window;
extern game_t *runningGame;
/** /**
* Entry of the program * Entry of the program

View File

@ -1,57 +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 <glad/glad.h>
#include <malloc.h>
#include <memory.h>
/**
* Structure detailing information about a texture.
* Because we plan to upload the pixels of a texture into the GPU, we don't
* store the pixels in memory because we don't need to!
*/
typedef struct {
int32_t width;
int32_t height;
GLuint id;
} texture_t;
/** Information about a single pixel. */
typedef struct {
uint8_t r, g, b, a ;
} pixel_t;
/**
* Creates a new texture that can be written in to.
*
* @param width Width of the texture (in pixels).
* @param height Height of the texture (in pixels).
* @param pixels Default pixel array, set to NULL to set all pixel data to 0.
* @return The newly created texture instance.
*/
texture_t * textureCreate(int32_t width, int32_t height, pixel_t *pixels);
/**
* Buffer pixel data onto the GPU. Pixel buffering is rather costly so avoid
* doing this too often.
*
* @param texture Texture to buffer in to.
* @param x X coordinate in texture space to render to.
* @param y Y coordinate in texture space to render to.
* @param width Width of the pixel region you're buffering.
* @param height Height of the pixel region you're buffering.
* @param pixels Array of pixels to buffer onto the GPU.
*/
void textureBufferPixels(texture_t *texture,
int32_t x, int32_t y, int32_t width, int32_t height, pixel_t *pixels
);
/**
* Clean a previously created texture.
* @param texture Texture to clean up.
*/
void textureDispose(texture_t *texture);

View File

@ -4,36 +4,7 @@
// https://opensource.org/licenses/MIT // https://opensource.org/licenses/MIT
#pragma once #pragma once
#include <stdio.h> #include <dawn/dawn.h>
#include <stdbool.h>
#include <malloc.h>
#include <stdint.h>
/**
* Entry within a given linked list.
* @param data* The pointer to the data that is within the entry.
* @param prev* Pointer to the previous entry in the list.
* @param next* Pointer to the next entry in the list.
*/
typedef struct listentry_t {
void *data;
struct listentry_t *prev;
struct listentry_t *next;
} listentry_t;
/**
* Linked List of elements, Doubly Linked.
* @param size The count of elements currently within the list
* @param start* First element within the list.
* @param end* Last element within the list.
*/
typedef struct {
uint32_t size;
listentry_t *start;
listentry_t *end;
} list_t;
//Method definitions
/** /**
* Creates a new linked list * Creates a new linked list

View File

@ -1,13 +0,0 @@
/**
* 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

View File

@ -1,86 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "chunk.h"
void chunkLoad(chunk_t *chunk, tilemap_t *tilemap,
int32_t x, int32_t y, int32_t z
){
int32_t tx, ty, tz, i;
tileid_t tileId;
tiledef_t *tileDef;
tilesetdiv_t *div;
char *buffer, *seek, *current;
char fileName[128];
// Determine file name of the chunk.
fileName[0] = '\0';
strcat(fileName, "world/chunks/%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 < CHUNK_TILE_COUNT; i++) {
// Now load from the buffer.
current = strtok_r(seek, ";", &seek);
*(chunk->tiles + i) = current[0] - CHUNK_TILE_LOAD_ASCII;
tileId = *(chunk->tiles + i);
if(tileId == TILE_NULL) continue;
// Increment tile definition.
tileDef = tilemap->tileDefinitions+tileId;
verticeCount += tileDef->verticeCount;
indiceCount += tileDef->indiceCount;
}
// Now we know how big the primitive needs to be!
free(buffer);
if(indiceCount == 0) return;
chunk->primitive = primitiveCreate(verticeCount, indiceCount);
// For each tile
i = 0;
verticeCount = 0, indiceCount = 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...
tileId = *(chunk->tiles + (i++));
if(tileId == TILE_NULL) continue;
// Get the definition.
tileDef = tilemap->tileDefinitions+tileId;
if(tileDef->tileRender == NULL) continue;
// Render the tile's primitive
tileDef->tileRender(tileId, tilemap, tileDef,
chunk->primitive, verticeCount, indiceCount,
tx, ty, tz
);
// Prepare for the next render.
verticeCount += tileDef->verticeCount;
indiceCount += tileDef->indiceCount;
}
}
}
}
void chunkUnload(chunk_t *chunk) {
// Load chunks to zero. TODO: Necessary?
memset(chunk->tiles, TILE_NULL, CHUNK_TILE_COUNT);
// Unload the primitive
if(chunk->primitive == NULL) return;
primitiveDispose(chunk->primitive);
chunk->primitive = NULL;
}

View File

@ -7,15 +7,8 @@
#include "entity.h" #include "entity.h"
void entitySystemInit(entitysystem_t *entitySystem) { entitystate_t ENTITY_STATE;
memset(&entitySystem->entities, ENTITY_TYPE_NULL,
sizeof(entityid_t) * ENTITY_COUNT_MAX
);
}
void entitySystemUpdate(entitysystem_t *entitySystem, void entityStateInit() {
shader_t *shader, camera_t *camera, memset(ENTITY_STATE.entities, NULL, sizeof(entity_t) * ENTITY_COUNT);
input_t *input
) {
entitySystem->callbacks[0].render(entitySystem, 0, shader, camera, input);
} }

View File

@ -1,46 +1,11 @@
// Copyright (c) 2021 Dominic Masters /**
// * Copyright (c) 2021 Dominic Masters
// This software is released under the MIT License. *
// https://opensource.org/licenses/MIT * This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once #pragma once
#include <stdint.h> #include <dawn/dawn.h>
#include <string.h>
#include <malloc.h>
#include "../../input/input.h"
#include "../../display/primitive.h"
#include "../../display/shader.h"
#include "../../display/camera.h"
#define ENTITY_COUNT_MAX 32
#define ENTITY_TYPE_NULL 0 void entityStateInit();
#define ENTITY_TYPE_PLAYER 1
/** ID used to identify an entity's type */
typedef uint8_t entityid_t;
typedef struct entitysystem_t entitysystem_t;
/** Entity Callbacks */
typedef struct entitycallbacks_t {
void (*dispose)(entitysystem_t *, int32_t);
void (*render)(entitysystem_t *, int32_t, shader_t *, camera_t *, input_t *);
} entitycallbacks_t;
typedef struct {
float x, y, z;
} entitypos_t;
/** Entity System */
typedef struct entitysystem_t {
entityid_t entities[ENTITY_COUNT_MAX];
entitycallbacks_t callbacks[ENTITY_COUNT_MAX];
entitypos_t positions[ENTITY_COUNT_MAX]
primitive_t *primitives[ENTITY_COUNT_MAX];
} entitysystem_t;
void entitySystemInit(entitysystem_t *entitySystem);
void entitySystemUpdate(entitysystem_t *entitySystem,
shader_t *shader, camera_t *camera,
input_t *input
);

View File

@ -1,39 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "player.h"
void playerCreate(entitysystem_t *system, int32_t index) {
system->entities[index] = ENTITY_TYPE_PLAYER;
system->callbacks[index].dispose = &playerDispose;
system->callbacks[index].render = &playerRender;
system->positions[index].x = 0;
system->positions[index].y = 0;
system->positions[index].z = 0;
system->primitives[index] = quadCreate(0,
0, 0, 0, 0,
1, 1, 1, 1
);
}
void playerDispose(entitysystem_t *system, int32_t index) {
}
void playerRender(entitysystem_t *system, int32_t index,
shader_t *shader, camera_t *camera,
input_t *input
) {
shaderUsePosition(shader,
system->positions[index].x,
system->positions[index].y,
system->positions[index].z,
0, 0, 0
);
primitiveDraw(system->primitives[index],
0, system->primitives[index]->indiceCount
);
}

View File

@ -1,18 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include "entity.h"
#include "../../display/primitive.h"
#include "../../display/primitives/quad.h"
void playerCreate(entitysystem_t *system, int32_t index);
void playerDispose(entitysystem_t *system, int32_t index);
void playerRender(entitysystem_t *system, int32_t index,
shader_t *shader, camera_t *camera,
input_t *input
);

70
src/world/map/chunk.c Normal file
View File

@ -0,0 +1,70 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "chunk.h"
void chunkLoad(chunk_t *chunk, int32_t x, int32_t y, int32_t z) {
tileid_t tileId;
tiledef_t *tileDef;
int32_t i, indiceCount, verticeCount, tx, ty, tz;
// Start by loading the tiles and figuring out how big we need to make the
// primitive that the chunk uses.
indiceCount = 0, verticeCount = 0;
for(i = 0; i < CHUNK_TILE_COUNT; i++) {
//TODO: Actually load the tileId here
chunk->tiles[i] = x + y + z + 1;
tileId = chunk->tiles[i];
if(tileId == TILE_NULL) continue;
// Increment the primitive size.
tileDef = MAP_STATE.tileDefinitions + tileId;
verticeCount += tileDef->verticeCount;
indiceCount += tileDef->indiceCount;
}
// Do we even need to create a primitive?
if(indiceCount == 0) return;
chunk->primitive = primitiveCreate(verticeCount, indiceCount);
// Render each tile. The ZYX order is important for ordering.
i = 0;
verticeCount = 0, indiceCount = 0;
for(tz = 0; tz < CHUNK_DEPTH; tz++) {
for(ty = 0; ty < CHUNK_HEIGHT; ty++) {
for(tx = 0; tx < CHUNK_WIDTH; tx++) {
tileId = chunk->tiles[i];
if(tileId == TILE_NULL) {
i++;
continue;
}
tileDef = MAP_STATE.tileDefinitions + tileId;
tileRender(
chunk, tileId, tileDef,
i, tx, ty, tz,
verticeCount, indiceCount
);
// Prepare for the next render.
verticeCount += tileDef->verticeCount;
indiceCount += tileDef->indiceCount;
i++;
}
}
}
}
void chunkUnload(chunk_t *chunk) {
// Load chunks to zero. TODO: Necessary?
memset(chunk->tiles, TILE_NULL, CHUNK_TILE_COUNT);
// Unload the primitive. TODO: Can we salvage this and resize instead?
if(chunk->primitive == NULL) return;
primitiveDispose(chunk->primitive);
chunk->primitive = NULL;
}

28
src/world/map/chunk.h Normal file
View File

@ -0,0 +1,28 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <dawn/dawn.h>
#include "../../display/primitive.h"
#include "tile.h"
/**
* Loads a given chunk.
*
* @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(chunk_t *chunk, int32_t x, int32_t y, int32_t z);
/**
* Unload a given chunk.
*
* @param chunk Chunk to unload.
*/
void chunkUnload(chunk_t *chunk);

171
src/world/map/map.c Normal file
View File

@ -0,0 +1,171 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "map.h"
map_t MAP_STATE;
void mapInit() {
int32_t i, z, x, y;
chunk_t *chunk;
// Reset map
MAP_STATE.x = MAP_STATE.y = MAP_STATE.z = 0;
// Load the texture
MAP_STATE.texture = assetTextureLoad(MAP_ASSET_TEXTURE);
// Load the tileset
MAP_STATE.tileset = tilesetCreate(
MAP_STATE.texture->width/TILE_WIDTH, MAP_STATE.texture->height/TILE_HEIGHT,
MAP_STATE.texture->width, MAP_STATE.texture->height,
0, 0, 0, 0
);
// Prepare the tile definitions
MAP_STATE.tileDefinitions = calloc(
MAP_STATE.tileset->count,sizeof(tiledef_t)
);
// TODO: Load the tile definitions here.
for(i = 0; i < MAP_STATE.tileset->count; i++) {
(MAP_STATE.tileDefinitions+i)->verticeCount = 4;
(MAP_STATE.tileDefinitions+i)->indiceCount = 6;
}
// Load each of the chunks. The ZYX order is important for ordering.
i = 0;
for(z = 0; z < MAP_DEPTH; z++) {
for(y = 0; y < MAP_HEIGHT; y++) {
for(x = 0; x < MAP_WIDTH; x++) {
chunk = MAP_STATE.chunks + i;
MAP_STATE.chunkList[i] = chunk;
// Load initial chunk state.
chunk->x = x;
chunk->y = y;
chunk->z = z;
chunk->primitive = NULL;
// Load the chunk.
chunkLoad(chunk, x, y, z);
i++;
}
}
}
}
void mapRender() {
int32_t i;
float x, y, z;
chunk_t *chunk;
// Bind the texture
shaderUseTexture(GAME_STATE.shaderWorld, MAP_STATE.texture);
// Render each chunk.
// TODO: Do we need to render every chunk? (screen area)
for(i = 0; i < MAP_CHUNK_COUNT; i++) {
chunk = MAP_STATE.chunkList[i];
if(chunk->primitive == NULL) continue;
// Offset the primitive (into world space)
x = (chunk->x * CHUNK_WIDTH);
y = (chunk->y * CHUNK_HEIGHT);
z = (chunk->z * CHUNK_DEPTH);
shaderUsePosition(GAME_STATE.shaderWorld, x, y, z, 0, 0, 0);
primitiveDraw(chunk->primitive, 0, chunk->primitive->indiceCount);
}
}
void mapDispose() {
int32_t i;
chunk_t *chunk;
// Unload the chunks
for(i = 0; i < MAP_CHUNK_COUNT; i++) {
chunk = MAP_STATE.chunkList[i];
chunkUnload(chunk);
}
tilesetDispose(MAP_STATE.tileset);
textureDispose(MAP_STATE.texture);
}
void mapShift(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[MAP_CHUNK_COUNT];
// Calculate the new chunklist coordinates
lx = MAP_STATE.x + x;
ly = MAP_STATE.y + y;
lz = MAP_STATE.z + z;
// Precalc width * height.
wh = MAP_WIDTH * MAP_HEIGHT;
for(i = 0; i < MAP_CHUNK_COUNT; i++) {
chunk = MAP_STATE.chunkList[i];
// Calculate the new local positions for the chunk.
nx = mathMod(chunk->x - MAP_STATE.x - x, MAP_WIDTH);
ny = mathMod(chunk->y - MAP_STATE.y - y, MAP_HEIGHT);
nz = mathMod(chunk->z - MAP_STATE.z - z, MAP_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(chunk);
chunkLoad(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 * MAP_WIDTH) +
(nz * wh)
);
chunkList[ni] = chunk;
}
// Update Absolutes.
MAP_STATE.x = lx;
MAP_STATE.y = ly;
MAP_STATE.z = lz;
// Now copy that array over.
memcpy(MAP_STATE.chunkList, chunkList, sizeof(chunk_t *) * MAP_CHUNK_COUNT);
}
void mapAlign(int32_t x, int32_t y, int32_t z) {
mapShift(x - MAP_STATE.x, y - MAP_STATE.y, z - MAP_STATE.z);
}

46
src/world/map/map.h Normal file
View File

@ -0,0 +1,46 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <dawn/dawn.h>
#include "../../util/math.h"
#include "../../display/tileset.h"
#include "../../file/asset.h"
#include "chunk.h"
/**
* Initializes the world map.
*/
void mapInit();
/**
* Renders the map object to the graphics device.
*/
void mapRender();
/**
* Cleans the previously loaded world map.
*/
void mapDispose();
/**
* Shift the map chunk list along a set of axis (in absolute space).
*
* @param x X movement to shift chunks along.
* @param y Y movement to shift chunks along.
* @param z Z movement to shift chunks along.
*/
void mapShift(int32_t x, int32_t y, int32_t z);
/**
* Align the map chunk list (in absolute space).
*
* @param x X movement to shift chunks along.
* @param y Y movement to shift chunks along.
* @param z Z movement to shift chunks along.
*/
void mapAlign(int32_t x, int32_t y, int32_t z);

21
src/world/map/tile.c Normal file
View File

@ -0,0 +1,21 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "tile.h"
void tileRender(
chunk_t *chunk, tileid_t id, tiledef_t *tileDef,
int32_t i, int32_t x, int32_t y, int32_t z,
int32_t verticeStart, int32_t indiceStart
) {
tilesetdiv_t *div = (MAP_STATE.tileset->divisions + id);
quadBuffer(chunk->primitive, z,
x, y, div->x0, div->y0,
x+1, y+1, div->x1, div->y1,
verticeStart, indiceStart
);
}

16
src/world/map/tile.h Normal file
View File

@ -0,0 +1,16 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once
#include <dawn/dawn.h>
#include "../../display/primitives/quad.h"
void tileRender(
chunk_t *chunk, tileid_t id, tiledef_t *tileDef,
int32_t i, int32_t x, int32_t y, int32_t z,
int32_t verticeStart, int32_t indiceStart
);

View File

@ -1,54 +0,0 @@
/**
* Copyright (c) 2021 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "tile.h"
tilemap_t * tileMapCreate(texture_t *texture) {
tilemap_t *tilemap = malloc(sizeof(tilemap_t));
if(tilemap == NULL) return NULL;
tilemap->texture = texture;
// Create the tileset for the texture.
tilemap->tileset = tilesetCreate(
texture->width/TILE_WIDTH, texture->height/TILE_HEIGHT,
texture->width, texture->height,
0, 0, 0, 0
);
if(tilemap->tileset == NULL) {
free(tilemap);
return NULL;
}
// Setup the tile definitions for each tile within the tileset.
tilemap->tileDefinitions = calloc(tilemap->tileset->count, sizeof(tiledef_t));
if(!tilemap->tileDefinitions) {
tilesetDispose(tilemap->tileset);
free(tilemap);
return NULL;
}
return tilemap;
}
void tileMapDispose(tilemap_t *tilemap) {
free(tilemap->tileDefinitions);
tilesetDispose(tilemap->tileset);
free(tilemap);
}
void tileQuadRender(tileid_t id, tilemap_t *tilemap, tiledef_t *tileDef,
primitive_t *primitive, int32_t verticeStart, int32_t indiceStart,
int32_t x, int32_t y, int32_t z
) {
tilesetdiv_t *div = tilemap->tileset->divisions + id;
quadBuffer(primitive, z,
x, y, div->x0, div->y0,
x+1, y+1, div->x1, div->y1,
verticeStart, indiceStart
);
}

View File

@ -1,89 +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 "../display/tileset.h"
#include "../display/texture.h"
#include "../display/primitives/quad.h"
#include "../display/primitives/cube.h"
/** The tile id that represents a NULL tile */
#define TILE_NULL (tileid_t)0
/** Width of a tile (in pixels) */
#define TILE_WIDTH 16
/** Height of a tile (in pixels) */
#define TILE_HEIGHT 16
/** Bitwise Flags from tiles. */
typedef uint8_t tileflag_t;
/** Tile ID */
typedef uint8_t tileid_t;
// Forwarders
typedef struct tiledef_t tiledef_t;
typedef struct tilemap_t tilemap_t;
/** Representation of the information of a tile within a tilemap. */
typedef struct tiledef_t {
/** Flags of the tile */
tileflag_t flags;
/** How many indices and vertices a tile with this definition has. */
int32_t indiceCount, verticeCount;
/** Callback for the tile definition for rendering the tile */
void (*tileRender)(tileid_t id, tilemap_t *tilemap, tiledef_t *tileDef,
primitive_t *primitive, int32_t verticeStart, int32_t indiceStart,
int32_t x, int32_t y, int32_t z
);
} tiledef_t;
/** Representation of the tile definitions within a tilemap. */
typedef struct tilemap_t {
/** Tile definitions within the tilemap */
tiledef_t *tileDefinitions;
/** Tileset predivided */
tileset_t *tileset;
/** Texture of the tileset */
texture_t *texture;
} tilemap_t;
/**
* Creates a tilemap from a tileset.
* @param The texture to base the tilemap on.
* @returns The tilemap.
*/
tilemap_t * tileMapCreate(texture_t *texture);
/**
* Destroys a previously created tilemap.
*
* @param tilemap Tilemap to dispose.
*/
void tileMapDispose(tilemap_t *tilemap);
/**
* Renders a tile as a standard quad.
*
* @param id ID of the Tile.
* @param tilemap The tilemap that the tile belongs to.
* @param tileDef The tiledef of the tile.
* @param primitive The primitive to render to.
* @param verticeStart The start index of the vertice.
* @param indiceStart The start index of the indice.
* @param x Tile (local) X position coordinate.
* @param y Tile (local) Y position coordinate.
* @param z Tile (local) Z position coordinate.
*/
void tileQuadRender(tileid_t id, tilemap_t *tilemap, tiledef_t *tileDef,
primitive_t *primitive, int32_t verticeStart, int32_t indiceStart,
int32_t x, int32_t y, int32_t z
);

View File

@ -7,207 +7,15 @@
#include "world.h" #include "world.h"
world_t * worldLoad() { void worldInit() {
// Define our local variables mapInit();
char file [128]; entityStateInit();
char *reading, *version, *textureFilename, *temp;
world_t *world;
chunk_t *chunk;
tiledef_t *tileDef;
texture_t *texture;
int32_t i, x, y, z;
// Load the world file.
file[0] = '\0';
strcat(file, "world/world.txt");
char *worldData = assetStringLoad(file);
if(worldData == NULL) return NULL;
// Create the world
world = malloc(sizeof(world_t));
world->x = 0, world->y = 0, world->z = 0;
// Now begin parsing, first we need to know which version of the file format
// we are using.
reading = worldData;
version = strtok_r(reading, WORLD_LOAD_TOKEN, &reading);
// Now load the tileset texture filename
textureFilename = strtok_r(reading, WORLD_LOAD_TOKEN, &reading);
// Load tileset texture.
file[0] = '\0';
strcat(file, "world/");
strcat(file, textureFilename);
texture = assetTextureLoad(file);
// Create the Tilemap
world->tilemap = tileMapCreate(texture);
// Load Tilemap Definitions. Skip
for(i = 0; i < world->tilemap->tileset->count; i++) {
tileDef = world->tilemap->tileDefinitions + i;
temp = strtok_r(reading, WORLD_LOAD_TOKEN, &reading);
tileDef->verticeCount = atoi(temp);
temp = strtok_r(reading, WORLD_LOAD_TOKEN, &reading);
tileDef->indiceCount = atoi(temp);
temp = strtok_r(reading, WORLD_LOAD_TOKEN, &reading);
tileDef->flags = 0x00;
tileDef->tileRender = &tileQuadRender;
}
// Finished actual loading.
free(worldData);
// 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.
chunkLoad(chunk, world->tilemap, x, y, z);
i++;
}
}
}
// Prepare the entity system
entitySystemInit(&world->entities);
return world;
} }
void worldRender(world_t *world, void worldRender() {
shader_t *shader, camera_t *camera, mapRender();
input_t *input
) {
int32_t i, j, tx, ty, tz;
float x, y, z;
chunk_t *chunk;
// Bind tilemap texture
shaderUseTexture(shader, world->tilemap->texture);
// Render each chunk.
for(i = 0; i < WORLD_CHUNK_COUNT; i++) {
chunk = world->chunks + i;
if(chunk->primitive == NULL) continue;
// Offset the primitive (into world space)
x = (chunk->x * CHUNK_WIDTH);
y = (chunk->y * CHUNK_HEIGHT);
z = (chunk->z * CHUNK_DEPTH);
shaderUsePosition(shader, x, y, z, 0, 0, 0);
primitiveDraw(chunk->primitive, 0, chunk->primitive->indiceCount);
}
// Entity System tick
entitySystemUpdate(&world->entities, shader, camera, input);
} }
void worldDispose(world_t *world) { void worldDispose() {
int32_t i; mapDispose();
chunk_t *chunk;
// Unload the chunks
for(i = 0; i < WORLD_CHUNK_COUNT; i++) {
chunk = world->chunks + i;
chunkUnload(chunk);
}
textureDispose(world->tilemap->texture);
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[WORLD_CHUNK_COUNT];
// 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;
for(i = 0; i < WORLD_CHUNK_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(chunk);
chunkLoad(chunk, world->tilemap, 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_CHUNK_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);
} }

View File

@ -1,92 +1,15 @@
// Copyright (c) 2021 Dominic Masters /**
// * Copyright (c) 2021 Dominic Masters
// This software is released under the MIT License. *
// https://opensource.org/licenses/MIT * This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#pragma once #pragma once
#include <malloc.h> #include <dawn/dawn.h>
#include <stdint.h> #include "map/map.h"
#include "tile.h"
#include "chunk.h"
#include "entity/entity.h" #include "entity/entity.h"
#include "../display/shader.h"
#include "../display/camera.h"
#include "../display/primitive.h"
#include "../display/tileset.h"
#include "../display/texture.h"
#include "../file/asset.h"
#include "../input/input.h"
#include "../util/string.h"
#include "../util/math.h"
/** Token in the world data file to split on. */ void worldInit();
#define WORLD_LOAD_TOKEN ";" void worldRender();
/** Width of world (in chunks) */ void worldDispose();
#define WORLD_WIDTH 5
/** Height of world (in chunks) */
#define WORLD_HEIGHT WORLD_WIDTH
/** Depth of world (in chunks) */
#define WORLD_DEPTH 2
/** Count of chunks in the world */
#define WORLD_CHUNK_COUNT WORLD_WIDTH*WORLD_HEIGHT*WORLD_DEPTH
/** Representation of the world. */
typedef struct world_t {
// Chunks
/** Tilemap of the world */
tilemap_t *tilemap;
/** Current (chunk) coordinates of the first chunk in the chunk list */
int32_t x, y, z;
/** Current chunk list, ordered */
chunk_t *chunkList[WORLD_CHUNK_COUNT];
/** Chunk array (unordered) */
chunk_t chunks[WORLD_CHUNK_COUNT];
entitysystem_t entities;
} world_t;
/**
* Create a world object.
*
* @returns The newly created world.
*/
world_t * worldLoad();
/**
* 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, camera_t *camera,
input_t *input
);
/**
* 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);