first commit
This commit is contained in:
21
src/game/GAME_COMMON.h
Normal file
21
src/game/GAME_COMMON.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "state/state.h"
|
||||
|
||||
#include "../engine/tick.h"
|
||||
#include "../engine/sdl.h"
|
||||
|
||||
#include "render/buffer.h"
|
||||
|
||||
typedef struct Game
|
||||
{
|
||||
ECS ecs;
|
||||
Input input;
|
||||
Renderer renderer;
|
||||
Resources resources;
|
||||
State state;
|
||||
Tick tick;
|
||||
Window window;
|
||||
Postprocessing postprocessing[RENDERER_BUFFER_COUNT];
|
||||
bool isPaused;
|
||||
} Game;
|
62
src/game/ecs/ECS_COMMON.h
Normal file
62
src/game/ecs/ECS_COMMON.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
|
||||
#include "component/COMPONENT_COMMON.h"
|
||||
|
||||
#include "../../engine/vector.h"
|
||||
|
||||
#define ECS_FUNCTION_COUNT ECS_FUNCTION_DRAW + 1
|
||||
typedef enum ECSFunctionType
|
||||
{
|
||||
ECS_FUNCTION_ADD,
|
||||
ECS_FUNCTION_DELETE,
|
||||
ECS_FUNCTION_TICK,
|
||||
ECS_FUNCTION_UPDATE,
|
||||
ECS_FUNCTION_DRAW
|
||||
} ECSFunctionType;
|
||||
|
||||
typedef struct ECS ECS;
|
||||
typedef struct Input Input;
|
||||
typedef struct Renderer Renderer;
|
||||
typedef struct Postprocessing Postprocessing;
|
||||
typedef struct Resources Resources;
|
||||
typedef u32 EntityID;
|
||||
|
||||
typedef void (*ECSFunction)(void*, ECS*);
|
||||
|
||||
typedef struct ECSComponent
|
||||
{
|
||||
EntityID id;
|
||||
bool isDisabled;
|
||||
bool isFunctionDisabled[ECS_FUNCTION_COUNT];
|
||||
} ECSComponent;
|
||||
|
||||
typedef struct ECSSystem
|
||||
{
|
||||
ECSFunction functions[ECS_FUNCTION_COUNT];
|
||||
} ECSSystem;
|
||||
|
||||
typedef struct ECSComponentInfo
|
||||
{
|
||||
ECSSystem system;
|
||||
ECSComponentType type;
|
||||
size_t size;
|
||||
} ECSComponentInfo;
|
||||
|
||||
typedef struct ECSComponentList
|
||||
{
|
||||
ECS* ecs;
|
||||
ECSSystem system;
|
||||
ECSComponentType type;
|
||||
Vector components;
|
||||
} ECSComponentList;
|
||||
|
||||
typedef struct ECS
|
||||
{
|
||||
Input* input;
|
||||
Renderer* renderer;
|
||||
Resources* resources;
|
||||
Postprocessing* postprocessing;
|
||||
ECSComponentList lists[ECS_COMPONENT_COUNT];
|
||||
EntityID nextID;
|
||||
} ECS;
|
||||
|
19
src/game/ecs/component/COMPONENT_COMMON.h
Normal file
19
src/game/ecs/component/COMPONENT_COMMON.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../../COMMON.h"
|
||||
|
||||
#include "../../../engine/debug.h"
|
||||
|
||||
#define ECS_COMPONENT_COUNT ECS_COMPONENT_COPY_MOUSE_POSITION + 1
|
||||
typedef enum ECSComponentType
|
||||
{
|
||||
ECS_COMPONENT_GAME_OBJECT,
|
||||
ECS_COMPONENT_COUNTER,
|
||||
ECS_COMPONENT_TIMER,
|
||||
ECS_COMPONENT_TEXTURE_QUAD,
|
||||
ECS_COMPONENT_TEXT,
|
||||
ECS_COMPONENT_OUTLINE,
|
||||
ECS_COMPONENT_ATLAS,
|
||||
ECS_COMPONENT_PHYSICS,
|
||||
ECS_COMPONENT_COPY_MOUSE_POSITION
|
||||
} ECSComponentType;
|
58
src/game/ecs/component/game/component_game_object.c
Normal file
58
src/game/ecs/component/game/component_game_object.c
Normal file
@@ -0,0 +1,58 @@
|
||||
#include "component_game_object.h"
|
||||
|
||||
void
|
||||
component_game_object_init
|
||||
(
|
||||
ComponentGameObject* self,
|
||||
ECS* ecs,
|
||||
Texture* texture,
|
||||
RendererBuffer buffer,
|
||||
vec2 size,
|
||||
vec3 position
|
||||
)
|
||||
{
|
||||
ComponentTextureQuad* textureQuad;
|
||||
ComponentPhysics* physics;
|
||||
|
||||
textureQuad = ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, self->component.id);
|
||||
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
|
||||
|
||||
component_texture_quad_init
|
||||
(
|
||||
textureQuad,
|
||||
ecs,
|
||||
texture,
|
||||
&ecs->resources->shaders[SHADER_TEXTURE_QUAD],
|
||||
COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT,
|
||||
ORIGIN_CENTER,
|
||||
buffer,
|
||||
COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT,
|
||||
size,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
position,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT
|
||||
);
|
||||
|
||||
glm_vec3_copy(position, physics->position);
|
||||
}
|
||||
|
||||
void
|
||||
component_game_object_add(ComponentGameObject* self, ECS* ecs)
|
||||
{
|
||||
ecs_components_add(ecs, COMPONENT_GAME_OBJECT_DEPENDENCIES, COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT, self->component.id);
|
||||
}
|
||||
|
||||
void
|
||||
component_game_object_tick(ComponentGameObject* self, ECS* ecs)
|
||||
{
|
||||
ComponentTextureQuad* textureQuad;
|
||||
ComponentPhysics* physics;
|
||||
|
||||
textureQuad = ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, self->component.id);
|
||||
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
|
||||
|
||||
glm_vec3_copy(physics->position, textureQuad->position);
|
||||
}
|
47
src/game/ecs/component/game/component_game_object.h
Normal file
47
src/game/ecs/component/game/component_game_object.h
Normal file
@@ -0,0 +1,47 @@
|
||||
#pragma once
|
||||
|
||||
#include "../visual/component_texture_quad.h"
|
||||
#include "../physics/component_physics.h"
|
||||
|
||||
typedef struct ComponentGameObject
|
||||
{
|
||||
ECSComponent component;
|
||||
} ComponentGameObject;
|
||||
|
||||
void
|
||||
component_game_object_init
|
||||
(
|
||||
ComponentGameObject* self,
|
||||
ECS* ecs,
|
||||
Texture* texture,
|
||||
RendererBuffer buffer,
|
||||
vec2 size,
|
||||
vec3 position
|
||||
);
|
||||
|
||||
void component_game_object_add(ComponentGameObject* self, ECS* ecs);
|
||||
void component_game_object_tick(ComponentGameObject* self, ECS* ecs);
|
||||
|
||||
#define COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT 2
|
||||
static const ECSComponentType COMPONENT_GAME_OBJECT_DEPENDENCIES[COMPONENT_GAME_OBJECT_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_TEXTURE_QUAD,
|
||||
ECS_COMPONENT_PHYSICS
|
||||
};
|
||||
|
||||
static const ECSComponentInfo COMPONENT_GAME_OBJECT_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
(ECSFunction)component_game_object_add,
|
||||
NULL,
|
||||
(ECSFunction)component_game_object_tick,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_GAME_OBJECT,
|
||||
.size = sizeof(ComponentGameObject)
|
||||
};
|
@@ -0,0 +1,15 @@
|
||||
#include "component_copy_mouse_position.h"
|
||||
|
||||
void
|
||||
component_copy_mouse_position_tick(ComponentCopyMousePosition* self, ECS* ecs)
|
||||
{
|
||||
ComponentPhysics* physics;
|
||||
vec2 mousePosition;
|
||||
|
||||
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->component.id);
|
||||
|
||||
mouse_world_position_get(&ecs->input->mouse, ecs->renderer, mousePosition);
|
||||
|
||||
physics->position[0] = mousePosition[0];
|
||||
physics->position[1] = mousePosition[1];
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
|
||||
#include "component_physics.h"
|
||||
|
||||
#include "../../../input/input.h"
|
||||
|
||||
typedef struct ComponentCopyMousePosition
|
||||
{
|
||||
ECSComponent component;
|
||||
} ComponentCopyMousePosition;
|
||||
|
||||
void component_copy_mouse_position_tick(ComponentCopyMousePosition* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_COPY_MOUSE_POSITION_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_copy_mouse_position_tick,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_COPY_MOUSE_POSITION,
|
||||
.size = sizeof(ComponentCopyMousePosition)
|
||||
};
|
10
src/game/ecs/component/physics/component_physics.c
Normal file
10
src/game/ecs/component/physics/component_physics.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "component_physics.h"
|
||||
|
||||
void
|
||||
component_physics_tick(ComponentPhysics* self, ECS* ecs)
|
||||
{
|
||||
glm_vec3_add(self->velocity, self->position, self->position);
|
||||
|
||||
if (keyboard_held(&ecs->input->keyboard, KEYBOARD_KEY_D))
|
||||
self->position[0] += 1.0f;
|
||||
}
|
31
src/game/ecs/component/physics/component_physics.h
Normal file
31
src/game/ecs/component/physics/component_physics.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs_entity.h"
|
||||
|
||||
#include "../../../input/input.h"
|
||||
|
||||
typedef struct ComponentPhysics
|
||||
{
|
||||
ECSComponent component;
|
||||
vec3 position;
|
||||
vec3 velocity;
|
||||
} ComponentPhysics;
|
||||
|
||||
void component_physics_tick(ComponentPhysics* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_PHYSICS_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_physics_tick,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_PHYSICS,
|
||||
.size = sizeof(ComponentPhysics)
|
||||
};
|
29
src/game/ecs/component/utility/component_counter.c
Normal file
29
src/game/ecs/component/utility/component_counter.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "component_counter.h"
|
||||
|
||||
void
|
||||
component_counter_init(ComponentCounter* self, ECS* ecs, s32 value, s32 max)
|
||||
{
|
||||
self->value = value;
|
||||
self->min = self->value;
|
||||
self->max = self->max;
|
||||
}
|
||||
|
||||
void
|
||||
component_counter_add(ComponentCounter* self, ECS* ecs)
|
||||
{
|
||||
self->value = 0;
|
||||
self->min = 0;
|
||||
self->max = COMPONENT_COUNTER_MAX;
|
||||
}
|
||||
|
||||
void
|
||||
component_counter_tick(ComponentCounter* self, ECS* ecs)
|
||||
{
|
||||
if (self->value >= self->max)
|
||||
{
|
||||
self->value = self->min;
|
||||
return;
|
||||
}
|
||||
|
||||
self->value++;
|
||||
}
|
34
src/game/ecs/component/utility/component_counter.h
Normal file
34
src/game/ecs/component/utility/component_counter.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs_entity.h"
|
||||
|
||||
#define COMPONENT_COUNTER_MAX INT_MAX
|
||||
|
||||
typedef struct ComponentCounter
|
||||
{
|
||||
ECSComponent component;
|
||||
s32 value;
|
||||
s32 max;
|
||||
s32 min;
|
||||
} ComponentCounter;
|
||||
|
||||
void component_counter_init(ComponentCounter* self, ECS* ecs, s32 value, s32 max);
|
||||
void component_counter_add(ComponentCounter* self, ECS* ecs);
|
||||
void component_counter_tick(ComponentCounter* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_COUNTER_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
(ECSFunction)component_counter_add,
|
||||
NULL,
|
||||
(ECSFunction)component_counter_tick,
|
||||
NULL,
|
||||
NULL,
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_COUNTER,
|
||||
.size = sizeof(ComponentCounter)
|
||||
};
|
23
src/game/ecs/component/utility/component_timer.c
Normal file
23
src/game/ecs/component/utility/component_timer.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "component_timer.h"
|
||||
|
||||
void
|
||||
component_timer_init(ComponentTimer* self, ECS* ecs, s32 value)
|
||||
{
|
||||
self->value = value;
|
||||
}
|
||||
|
||||
void
|
||||
component_timer_tick(ComponentTimer* self, ECS* ecs)
|
||||
{
|
||||
if (self->isFinished)
|
||||
return;
|
||||
|
||||
if (self->value <= 0)
|
||||
{
|
||||
self->isFinished = true;
|
||||
self->value = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
self->value--;
|
||||
}
|
30
src/game/ecs/component/utility/component_timer.h
Normal file
30
src/game/ecs/component/utility/component_timer.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs_entity.h"
|
||||
|
||||
typedef struct ComponentTimer
|
||||
{
|
||||
ECSComponent component;
|
||||
s32 value;
|
||||
bool isFinished;
|
||||
} ComponentTimer;
|
||||
|
||||
void component_timer_init(ComponentTimer* self, ECS* ecs, s32 value);
|
||||
void component_timer_tick(ComponentTimer* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_TIMER_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_timer_tick,
|
||||
NULL,
|
||||
NULL,
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_TIMER,
|
||||
.size = sizeof(ComponentTimer)
|
||||
};
|
35
src/game/ecs/component/visual/component_atlas.c
Normal file
35
src/game/ecs/component/visual/component_atlas.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include "component_atlas.h"
|
||||
|
||||
void
|
||||
component_atlas_uv_get(ComponentAtlas* self, Texture* texture, vec2 uvMin, vec2 uvMax)
|
||||
{
|
||||
vec2 position;
|
||||
s32 col;
|
||||
s32 row;
|
||||
|
||||
position[0] = (self->index % self->size[1]) * self->frameSize[1];
|
||||
position[1] = (s32)((f32)self->index / self->size[1]) * self->frameSize[1];
|
||||
|
||||
uvMin[0] = (f32)position[0] / texture->size[0];
|
||||
uvMin[1] = (f32)position[1] / texture->size[1];
|
||||
uvMax[0] = (f32)(position[0] + self->frameSize[0]) / texture->size[0];
|
||||
uvMax[1] = (f32)(position[1] + self->frameSize[1]) / texture->size[1];
|
||||
}
|
||||
|
||||
void
|
||||
component_atlas_init(ComponentAtlas* self, ECS* ecs, ivec2 frameSize, ivec2 size, u32 index)
|
||||
{
|
||||
glm_ivec2_copy(frameSize, self->frameSize);
|
||||
glm_ivec2_copy(size, self->size);
|
||||
self->index = index;
|
||||
}
|
||||
|
||||
void
|
||||
component_atlas_tick(ComponentAtlas* self, ECS* ecs)
|
||||
{
|
||||
ComponentTextureQuad* textureQuad;
|
||||
|
||||
textureQuad = ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, self->component.id);
|
||||
|
||||
component_atlas_uv_get(self, textureQuad->texture, textureQuad->uvMin, textureQuad->uvMax);
|
||||
}
|
32
src/game/ecs/component/visual/component_atlas.h
Normal file
32
src/game/ecs/component/visual/component_atlas.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include "component_texture_quad.h"
|
||||
|
||||
typedef struct ComponentAtlas
|
||||
{
|
||||
ECSComponent component;
|
||||
ivec2 frameSize;
|
||||
ivec2 size;
|
||||
u32 index;
|
||||
} ComponentAtlas;
|
||||
|
||||
void component_atlas_init(ComponentAtlas* self, ECS* ecs, ivec2 frameSize, ivec2 size, u32 index);
|
||||
void component_atlas_tick(ComponentAtlas* self, ECS* ecs);
|
||||
void component_atlas_uv_get(ComponentAtlas* self, Texture* texture, vec2 uvMin, vec2 uvMax);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_ATLAS_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_atlas_tick,
|
||||
NULL,
|
||||
NULL,
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_ATLAS,
|
||||
.size = sizeof(ComponentAtlas)
|
||||
};
|
61
src/game/ecs/component/visual/component_outline.c
Normal file
61
src/game/ecs/component/visual/component_outline.c
Normal file
@@ -0,0 +1,61 @@
|
||||
#include "component_outline.h"
|
||||
|
||||
static void _component_outline_texture_quad_set(ComponentOutline* self, ECS* ecs);
|
||||
|
||||
static void
|
||||
_component_outline_texture_quad_set(ComponentOutline* self, ECS* ecs)
|
||||
{
|
||||
ComponentTextureQuad* textureQuadOutline;
|
||||
ComponentTextureQuad* textureQuad;
|
||||
|
||||
textureQuad = ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, self->component.id);
|
||||
|
||||
if (!self->isSpriteInit)
|
||||
{
|
||||
self->spriteID = entity_sprite_add
|
||||
(
|
||||
ecs,
|
||||
textureQuad->texture,
|
||||
textureQuad->buffer,
|
||||
textureQuad->size,
|
||||
textureQuad->position
|
||||
);
|
||||
|
||||
self->isSpriteInit = true;
|
||||
}
|
||||
|
||||
textureQuadOutline = ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, self->spriteID);
|
||||
|
||||
memcpy(textureQuadOutline, textureQuad, sizeof(ComponentTextureQuad));
|
||||
|
||||
textureQuadOutline->component.id = self->spriteID;
|
||||
textureQuadOutline->position[2] += COMPONENT_OUTLINE_Z_OFFSET;
|
||||
glm_vec4_copy(self->color, textureQuadOutline->color);
|
||||
glm_vec2_adds(textureQuadOutline->size, self->size, textureQuadOutline->size);
|
||||
textureQuadOutline->shader = &ecs->resources->shaders[SHADER_COLORED_TEXTURE_QUAD];
|
||||
}
|
||||
|
||||
void
|
||||
component_outline_init(ComponentOutline* self, ECS* ecs, vec4 color, f32 size)
|
||||
{
|
||||
glm_vec4_copy(color, self->color);
|
||||
self->size = size;
|
||||
}
|
||||
|
||||
void
|
||||
component_outline_add(ComponentOutline* self, ECS* ecs)
|
||||
{
|
||||
component_outline_init(self, ecs, (f32*)COMPONENT_OUTLINE_COLOR, COMPONENT_OUTLINE_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
component_outline_delete(ComponentOutline* self, ECS* ecs)
|
||||
{
|
||||
ecs_entity_delete(ecs, self->spriteID);
|
||||
}
|
||||
|
||||
void
|
||||
component_outline_tick(ComponentOutline* self, ECS* ecs)
|
||||
{
|
||||
_component_outline_texture_quad_set(self, ecs);
|
||||
}
|
40
src/game/ecs/component/visual/component_outline.h
Normal file
40
src/game/ecs/component/visual/component_outline.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../entity/visual/entity_sprite.h"
|
||||
|
||||
#include "component_texture_quad.h"
|
||||
|
||||
#define COMPONENT_OUTLINE_SIZE 8
|
||||
#define COMPONENT_OUTLINE_Z_OFFSET 0.001
|
||||
|
||||
static const vec4 COMPONENT_OUTLINE_COLOR = {1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
typedef struct ComponentOutline
|
||||
{
|
||||
ECSComponent component;
|
||||
vec4 color;
|
||||
f32 size;
|
||||
EntityID spriteID;
|
||||
bool isSpriteInit;
|
||||
} ComponentOutline;
|
||||
|
||||
void component_outline_init(ComponentOutline* self, ECS* ecs, vec4 color, f32 size);
|
||||
void component_outline_tick(ComponentOutline* self, ECS* ecs);
|
||||
void component_outline_add(ComponentOutline* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_OUTLINE_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
(ECSFunction)component_outline_add,
|
||||
NULL,
|
||||
(ECSFunction)component_outline_tick,
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_OUTLINE,
|
||||
.size = sizeof(ComponentOutline)
|
||||
};
|
225
src/game/ecs/component/visual/component_text.c
Normal file
225
src/game/ecs/component/visual/component_text.c
Normal file
@@ -0,0 +1,225 @@
|
||||
#include "component_text.h"
|
||||
|
||||
void
|
||||
component_text_glyph_size_get(ComponentText* self, Texture* texture, vec2 size)
|
||||
{
|
||||
size[0] = texture->size[0] * self->scale[0];
|
||||
size[1] = texture->size[1] * self->scale[1];
|
||||
}
|
||||
|
||||
void
|
||||
component_text_glyph_draw(ComponentText* self, ECS* ecs, Texture* texture, vec3 position)
|
||||
{
|
||||
mat4 model;
|
||||
vec2 size;
|
||||
|
||||
component_text_glyph_size_get(self, texture, size);
|
||||
|
||||
glm_mat4_identity(model);
|
||||
glm_translate(model, position);
|
||||
|
||||
texture_quad_draw
|
||||
(
|
||||
texture,
|
||||
ecs->renderer,
|
||||
self->shader,
|
||||
(f32*)TEXTURE_QUAD_UV_MIN_DEFAULT,
|
||||
(f32*)TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
model,
|
||||
size,
|
||||
self->color,
|
||||
FLIP_NONE
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
component_text_rectangle_get(ComponentText* self, Rectangle* rectangle)
|
||||
{
|
||||
char glyph;
|
||||
char nextGlyph;
|
||||
f32 lineW;
|
||||
f32 offsetX;
|
||||
f32 prevY;
|
||||
GlyphMetrics glyphMetrics;
|
||||
vec2 origin;
|
||||
vec2 size;
|
||||
f32 lineSkip;
|
||||
f32 kerning;
|
||||
f32 advance;
|
||||
|
||||
lineSkip = font_line_skip_get(self->font) * self->scale[1];
|
||||
|
||||
font_glyph_metrics_init(self->font, &glyphMetrics, self->string[0]);
|
||||
|
||||
lineW = 0.0f;
|
||||
|
||||
size[0] = 0.0f;
|
||||
size[1] = (f32)glyphMetrics.maxY - glyphMetrics.minY;
|
||||
|
||||
for (s32 i = 0; i < (s32)self->length; i++)
|
||||
{
|
||||
glyph = self->string[i];
|
||||
|
||||
if
|
||||
(
|
||||
glyph == '\n' ||
|
||||
(glyph == ' ' && (lineW > self->wrap) && self->wrap != -1)
|
||||
)
|
||||
{
|
||||
size[1] += lineSkip;
|
||||
lineW = 0.0f;
|
||||
|
||||
if (glyph == '\n')
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < (s32)self->length)
|
||||
{
|
||||
nextGlyph = self->string[i + 1];
|
||||
kerning = (f32)font_glyph_kerning_get(self->font, glyph, nextGlyph);
|
||||
}
|
||||
else
|
||||
kerning = 0.0;
|
||||
|
||||
font_glyph_metrics_init(self->font, &glyphMetrics, glyph);
|
||||
|
||||
advance = glyphMetrics.advance;
|
||||
|
||||
offsetX = advance + kerning;
|
||||
offsetX *= self->scale[0];
|
||||
|
||||
lineW += offsetX;
|
||||
|
||||
if (lineW > size[0])
|
||||
size[0] = lineW;
|
||||
}
|
||||
|
||||
rectangle->w = size[0];
|
||||
rectangle->h = size[1];
|
||||
rectangle->x = self->position[0] + self->offset[0];
|
||||
rectangle->y = self->position[1] + self->offset[1];
|
||||
}
|
||||
|
||||
void
|
||||
component_text_string_set(ComponentText* self, const char* string, u32 length)
|
||||
{
|
||||
if (length > COMPONENT_TEXT_STRING_MAX)
|
||||
return;
|
||||
|
||||
self->length = length;
|
||||
|
||||
memset(self->string, '\0', sizeof(char) * COMPONENT_TEXT_STRING_MAX);
|
||||
memcpy(self->string, string, sizeof(char) * self->length);
|
||||
}
|
||||
|
||||
void
|
||||
component_text_add(ComponentText* self, ECS* ecs)
|
||||
{
|
||||
glm_vec4_copy(COMPONENT_TEXT_COLOR_DEFAULT, self->color);
|
||||
glm_vec2_copy((f32*)COMPONENT_TEXT_SCALE_DEFAULT, self->scale);
|
||||
}
|
||||
|
||||
void
|
||||
component_text_draw(ComponentText* self, ECS* ecs)
|
||||
{
|
||||
char glyph;
|
||||
char nextGlyph;
|
||||
f32 advance;
|
||||
f32 lineW;
|
||||
f32 offsetX;
|
||||
f32 kerning;
|
||||
GlyphMetrics glyphMetrics;
|
||||
Rectangle rectangle;
|
||||
vec2 origin;
|
||||
vec3 position;
|
||||
f32 lineSkip;
|
||||
f32 lineBegin;
|
||||
|
||||
component_text_rectangle_get(self, &rectangle);
|
||||
|
||||
lineSkip = font_line_skip_get(self->font) * self->scale[1];
|
||||
|
||||
glm_vec3_zero(position);
|
||||
|
||||
position[0] = rectangle.x;
|
||||
position[1] = rectangle.y;
|
||||
|
||||
position[0] += self->offset[0];
|
||||
position[1] += self->offset[1];
|
||||
position[2] = self->position[2] + self->offset[2];
|
||||
|
||||
offsetX = 0.0f;
|
||||
lineW = 0.0f;
|
||||
|
||||
lineBegin = position[0];
|
||||
|
||||
for (s32 i = 0; i < (s32)self->length; i++)
|
||||
{
|
||||
glyph = self->string[i];
|
||||
|
||||
if
|
||||
(
|
||||
glyph == '\n' ||
|
||||
(glyph == ' ' && (lineW > self->wrap) && self->wrap != -1)
|
||||
)
|
||||
{
|
||||
position[0] = lineBegin;
|
||||
position[1] += lineSkip;
|
||||
|
||||
lineW = 0.0f;
|
||||
|
||||
if (glyph == '\n')
|
||||
continue;
|
||||
}
|
||||
|
||||
if (i < (s32)self->length)
|
||||
{
|
||||
nextGlyph = self->string[i + 1];
|
||||
kerning = (f32)font_glyph_kerning_get(self->font, glyph, nextGlyph);
|
||||
}
|
||||
else
|
||||
kerning = 0.0;
|
||||
|
||||
font_glyph_metrics_init(self->font, &glyphMetrics, glyph);
|
||||
|
||||
component_text_glyph_draw(self, ecs, &self->font->glyphTextures[(s32)glyph], position);
|
||||
|
||||
advance = glyphMetrics.advance;
|
||||
|
||||
offsetX = advance + kerning;
|
||||
offsetX *= self->scale[0];
|
||||
|
||||
position[0] += offsetX;
|
||||
lineW += offsetX;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
component_text_init
|
||||
(
|
||||
ComponentText* self,
|
||||
ECS* ecs,
|
||||
Font* font,
|
||||
Shader* shader,
|
||||
RendererBuffer buffer,
|
||||
const char* string,
|
||||
const vec2 scale,
|
||||
const vec3 position,
|
||||
const vec3 offset,
|
||||
const vec4 color,
|
||||
u32 length,
|
||||
s32 wrap
|
||||
)
|
||||
{
|
||||
self->font = font;
|
||||
self->wrap = wrap;
|
||||
self->shader = shader;
|
||||
self->buffer = buffer;
|
||||
|
||||
glm_vec2_copy((f32*)scale, self->scale);
|
||||
glm_vec3_copy((f32*)position, self->position);
|
||||
glm_vec3_copy((f32*)offset, self->offset);
|
||||
glm_vec4_copy((f32*)color, self->color);
|
||||
|
||||
component_text_string_set(self, string, length);
|
||||
}
|
72
src/game/ecs/component/visual/component_text.h
Normal file
72
src/game/ecs/component/visual/component_text.h
Normal file
@@ -0,0 +1,72 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs_entity.h"
|
||||
|
||||
#include "../../../../engine/rectangle.h"
|
||||
#include "../../../../engine/font.h"
|
||||
#include "../../../render/texture_quad.h"
|
||||
#include "../../../resource/resource_shader.h"
|
||||
|
||||
#define COMPONENT_TEXT_LIMIT 1024
|
||||
#define COMPONENT_TEXT_STRING_MAX 1024
|
||||
|
||||
#define COMPONENT_TEXT_COLOR_DEFAULT (f32*)OPAQUE
|
||||
|
||||
static const vec2 COMPONENT_TEXT_SCALE_DEFAULT = {1.0f, 1.0f};
|
||||
static const vec3 COMPONENT_TEXT_OFFSET_DEFAULT = {0.0f, 0.0f, 0.0f};
|
||||
|
||||
typedef struct ComponentText
|
||||
{
|
||||
ECSComponent component;
|
||||
Shader* shader;
|
||||
RendererBuffer buffer;
|
||||
vec3 position;
|
||||
vec4 color;
|
||||
vec2 scale;
|
||||
vec3 offset;
|
||||
Font* font;
|
||||
char string[COMPONENT_TEXT_STRING_MAX];
|
||||
u32 length;
|
||||
s32 wrap;
|
||||
} ComponentText;
|
||||
|
||||
void component_text_glyph_size_get(ComponentText* self, Texture* texture, vec2 size);
|
||||
void component_text_glyph_draw(ComponentText* self, ECS* ecs, Texture* texture, vec3 position);
|
||||
void component_text_rectangle_get(ComponentText* self, Rectangle* rectangle);
|
||||
void component_text_string_set(ComponentText* self, const char* string, u32 length);
|
||||
void component_text_add(ComponentText* self, ECS* ecs);
|
||||
void component_text_draw(ComponentText* self, ECS* ecs);
|
||||
|
||||
void
|
||||
component_text_init
|
||||
(
|
||||
ComponentText* self,
|
||||
ECS* ecs,
|
||||
Font* font,
|
||||
Shader* shader,
|
||||
RendererBuffer buffer,
|
||||
const char* string,
|
||||
const vec2 scale,
|
||||
const vec3 position,
|
||||
const vec3 offset,
|
||||
const vec4 color,
|
||||
u32 length,
|
||||
s32 wrap
|
||||
);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_TEXT_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
(ECSFunction)component_text_add,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_text_draw
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_TEXT,
|
||||
.size = sizeof(ComponentText)
|
||||
};
|
166
src/game/ecs/component/visual/component_texture_quad.c
Normal file
166
src/game/ecs/component/visual/component_texture_quad.c
Normal file
@@ -0,0 +1,166 @@
|
||||
#include "component_texture_quad.h"
|
||||
|
||||
void
|
||||
component_texture_quad_size_get(ComponentTextureQuad* self, vec2 size)
|
||||
{
|
||||
glm_vec2_copy(self->size, size);
|
||||
glm_vec2_mul(self->size, self->scale, self->size);
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_position_get(ComponentTextureQuad* self, vec3 position)
|
||||
{
|
||||
vec2 size;
|
||||
|
||||
glm_vec3_copy(self->position, position);
|
||||
glm_vec3_add(self->position, self->offset, position);
|
||||
|
||||
switch (self->origin)
|
||||
{
|
||||
case ORIGIN_CENTER:
|
||||
component_texture_quad_size_get(self, size);
|
||||
position[0] -= size[0] / 2;
|
||||
position[1] -= size[1] / 2;
|
||||
case ORIGIN_TOP_LEFT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_origin_point_get(ComponentTextureQuad* self, vec3 originPoint)
|
||||
{
|
||||
vec2 size;
|
||||
|
||||
glm_vec3_zero(originPoint);
|
||||
|
||||
switch (self->origin)
|
||||
{
|
||||
case ORIGIN_CENTER:
|
||||
component_texture_quad_size_get(self, size);
|
||||
originPoint[0] = size[0] / 2;
|
||||
originPoint[1] = size[1] / 2;
|
||||
case ORIGIN_TOP_LEFT:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_model_get(ComponentTextureQuad* self, mat4 model)
|
||||
{
|
||||
vec3 position;
|
||||
vec3 originPoint;
|
||||
|
||||
component_texture_quad_position_get(self, position);
|
||||
component_texture_quad_origin_point_get(self, originPoint);
|
||||
|
||||
glm_mat4_identity(model);
|
||||
glm_translate(model, position);
|
||||
glm_rotate_at(model, originPoint, self->rotation, (f32*)COMPONENT_TEXTURE_QUAD_ROTATION_AXIS);
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_rectangle_get(ComponentTextureQuad* self, Rectangle* rectangle)
|
||||
{
|
||||
vec2 size;
|
||||
vec2 difference;
|
||||
|
||||
component_texture_quad_size_get(self, size);
|
||||
|
||||
rectangle->x = (self->position[0] - (size[0] / 2)) + self->offset[0];
|
||||
rectangle->y = (self->position[1] - (size[1] / 2)) + self->offset[1];
|
||||
rectangle->w = size[0];
|
||||
rectangle->h = size[1];
|
||||
}
|
||||
|
||||
s32
|
||||
component_texture_quad_sort(ComponentTextureQuad* a, ComponentTextureQuad* b)
|
||||
{
|
||||
return a->position[2] > b->position[2] ? -1 : 1;
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_init
|
||||
(
|
||||
ComponentTextureQuad* self,
|
||||
ECS* ecs,
|
||||
Texture* texture,
|
||||
Shader* shader,
|
||||
Flip flip,
|
||||
Origin origin,
|
||||
RendererBuffer buffer,
|
||||
f32 rotation,
|
||||
vec2 size,
|
||||
vec2 scale,
|
||||
vec2 uvMin,
|
||||
vec2 uvMax,
|
||||
vec3 offset,
|
||||
vec3 position,
|
||||
vec4 color
|
||||
)
|
||||
{
|
||||
self->texture = texture;
|
||||
self->shader = shader;
|
||||
self->flip = flip;
|
||||
self->origin = origin;
|
||||
self->buffer = buffer;
|
||||
self->rotation = rotation;
|
||||
glm_vec2_copy(size, self->size);
|
||||
glm_vec2_copy(scale, self->scale);
|
||||
glm_vec2_copy(uvMin, self->uvMin);
|
||||
glm_vec2_copy(uvMax, self->uvMax);
|
||||
glm_vec3_copy(offset, self->offset);
|
||||
glm_vec3_copy(position, self->position);
|
||||
glm_vec4_copy(color, self->color);
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_add(ComponentTextureQuad* self, ECS* ecs)
|
||||
{
|
||||
component_texture_quad_init
|
||||
(
|
||||
self,
|
||||
ecs,
|
||||
&ecs->resources->textures[COMPONENT_TEXTURE_QUAD_TEXTURE_DEFAULT],
|
||||
&ecs->resources->shaders[COMPONENT_TEXTURE_QUAD_SHADER_DEFAULT],
|
||||
COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT,
|
||||
COMPONENT_TEXTURE_QUAD_ORIGIN_DEFAULT,
|
||||
COMPONENT_TEXTURE_QUAD_BUFFER_DEFAULT,
|
||||
COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_SIZE_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_POSITION_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
component_texture_quad_draw(ComponentTextureQuad* self, ECS* ecs)
|
||||
{
|
||||
mat4 model;
|
||||
vec2 size;
|
||||
|
||||
component_texture_quad_model_get(self, model);
|
||||
component_texture_quad_size_get(self, size);
|
||||
|
||||
renderer_buffer_use(ecs->renderer, self->buffer);
|
||||
|
||||
texture_quad_draw
|
||||
(
|
||||
self->texture,
|
||||
ecs->renderer,
|
||||
self->shader,
|
||||
self->uvMin,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
model,
|
||||
size,
|
||||
self->color,
|
||||
self->flip
|
||||
);
|
||||
|
||||
renderer_buffer_unbind();
|
||||
}
|
85
src/game/ecs/component/visual/component_texture_quad.h
Normal file
85
src/game/ecs/component/visual/component_texture_quad.h
Normal file
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs_entity.h"
|
||||
|
||||
#include "../../../../engine/rectangle.h"
|
||||
#include "../../../render/texture_quad.h"
|
||||
#include "../../../resource/resource_shader.h"
|
||||
|
||||
typedef struct ComponentTextureQuad
|
||||
{
|
||||
ECSComponent component;
|
||||
Texture* texture;
|
||||
Shader* shader;
|
||||
Flip flip;
|
||||
Origin origin;
|
||||
RendererBuffer buffer;
|
||||
f32 rotation;
|
||||
vec2 scale;
|
||||
vec2 size;
|
||||
vec2 uvMax;
|
||||
vec2 uvMin;
|
||||
vec3 offset;
|
||||
vec3 position;
|
||||
vec4 color;
|
||||
} ComponentTextureQuad;
|
||||
|
||||
void component_texture_quad_init
|
||||
(
|
||||
ComponentTextureQuad* self,
|
||||
ECS* ecs,
|
||||
Texture* texture,
|
||||
Shader* shader,
|
||||
Flip flip,
|
||||
Origin origin,
|
||||
RendererBuffer buffer,
|
||||
f32 rotation,
|
||||
vec2 size,
|
||||
vec2 scale,
|
||||
vec2 uvMin,
|
||||
vec2 uvMax,
|
||||
vec3 position,
|
||||
vec3 offset,
|
||||
vec4 color
|
||||
);
|
||||
|
||||
void component_texture_quad_size_get(ComponentTextureQuad* self, vec2 size);
|
||||
void component_texture_quad_position_get(ComponentTextureQuad* self, vec3 position);
|
||||
void component_texture_quad_origin_point_get(ComponentTextureQuad* self, vec3 originPoint);
|
||||
void component_texture_quad_model_get(ComponentTextureQuad* self, mat4 model);
|
||||
void component_texture_quad_rectangle_get(ComponentTextureQuad* self, Rectangle* rectangle);
|
||||
s32 component_texture_quad_sort(ComponentTextureQuad* a, ComponentTextureQuad* b);
|
||||
void component_texture_quad_draw(ComponentTextureQuad* self, ECS* ecs);
|
||||
|
||||
static const ECSComponentInfo COMPONENT_TEXTURE_QUAD_INFO =
|
||||
{
|
||||
.system =
|
||||
{
|
||||
.functions =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
(ECSFunction)component_texture_quad_draw
|
||||
}
|
||||
},
|
||||
.type = ECS_COMPONENT_TEXTURE_QUAD,
|
||||
.size = sizeof(ComponentTextureQuad)
|
||||
};
|
||||
|
||||
#define COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT TEXTURE_QUAD_UV_MIN_DEFAULT
|
||||
#define COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT TEXTURE_QUAD_UV_MAX_DEFAULT
|
||||
#define COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT TEXTURE_QUAD_COLOR_DEFAULT
|
||||
#define COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT TEXTURE_QUAD_FLIP_DEFAULT
|
||||
#define COMPONENT_TEXTURE_QUAD_ORIGIN_DEFAULT TEXTURE_QUAD_ORIGIN_DEFAULT
|
||||
|
||||
static const vec3 COMPONENT_TEXTURE_QUAD_ROTATION_AXIS = {0.0f, 0.0f, 1.0f};
|
||||
static const TextureType COMPONENT_TEXTURE_QUAD_TEXTURE_DEFAULT = TEXTURE_TEST;
|
||||
static const ShaderType COMPONENT_TEXTURE_QUAD_SHADER_DEFAULT = SHADER_TEXTURE_QUAD;
|
||||
static const RendererBuffer COMPONENT_TEXTURE_QUAD_BUFFER_DEFAULT = RENDERER_BUFFER_WORLD;
|
||||
static const f32 COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT = 0.0f;
|
||||
static const vec2 COMPONENT_TEXTURE_QUAD_SIZE_DEFAULT = {32.0f, 32.0f};
|
||||
static const vec2 COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT = {1.0f, 1.0f};
|
||||
static const vec3 COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT = {0.0f, 0.0f, 0.0f};
|
||||
static const vec3 COMPONENT_TEXTURE_QUAD_POSITION_DEFAULT = {0.0f, 0.0f, 0.0f};
|
66
src/game/ecs/ecs.c
Normal file
66
src/game/ecs/ecs.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "ecs.h"
|
||||
|
||||
static void _ecs_function(ECS* self, ECSFunctionType type);
|
||||
|
||||
static void
|
||||
_ecs_function(ECS* self, ECSFunctionType type)
|
||||
{
|
||||
for (s32 i = 0; i < ECS_COMPONENT_COUNT; i++)
|
||||
{
|
||||
ECSComponentList* list;
|
||||
|
||||
list = &self->lists[i];
|
||||
|
||||
ecs_component_list_function(list, type);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ecs_tick(ECS* self)
|
||||
{
|
||||
_ecs_function(self, ECS_FUNCTION_TICK);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_update(ECS* self)
|
||||
{
|
||||
_ecs_function(self, ECS_FUNCTION_UPDATE);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_draw(ECS* self)
|
||||
{
|
||||
vector_sort(&self->lists[ECS_COMPONENT_TEXTURE_QUAD].components, (SortCompareFunction)component_texture_quad_sort);
|
||||
|
||||
_ecs_function(self, ECS_FUNCTION_DRAW);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_init(ECS* self, Renderer* renderer, Input* input, Resources* resources, Postprocessing* postprocessing)
|
||||
{
|
||||
self->renderer = renderer;
|
||||
self->input = input;
|
||||
self->resources = resources;
|
||||
self->postprocessing = postprocessing;
|
||||
|
||||
for (s32 i = 0 ; i < ECS_COMPONENT_COUNT; i++)
|
||||
ecs_component_list_init(&self->lists[i], self, ECS_COMPONENT_INFO[i]);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_clear(ECS* self)
|
||||
{
|
||||
for (s32 i = 0 ; i < ECS_COMPONENT_COUNT; i++)
|
||||
ecs_component_list_clear(&self->lists[i]);
|
||||
|
||||
self->nextID = 0;
|
||||
}
|
||||
|
||||
void
|
||||
ecs_free(ECS* self)
|
||||
{
|
||||
for (s32 i = 0 ; i < ECS_COMPONENT_COUNT; i++)
|
||||
ecs_component_list_free(&self->lists[i]);
|
||||
|
||||
memset(self, '\0', sizeof(ECS));
|
||||
}
|
37
src/game/ecs/ecs.h
Normal file
37
src/game/ecs/ecs.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
|
||||
#include "component/game/component_game_object.h"
|
||||
#include "component/physics/component_copy_mouse_position.h"
|
||||
#include "component/physics/component_physics.h"
|
||||
#include "component/utility/component_counter.h"
|
||||
#include "component/utility/component_timer.h"
|
||||
#include "component/visual/component_atlas.h"
|
||||
#include "component/visual/component_outline.h"
|
||||
#include "component/visual/component_texture_quad.h"
|
||||
#include "component/visual/component_text.h"
|
||||
|
||||
#include "../input/input.h"
|
||||
#include "../../engine/renderer.h"
|
||||
#include "../resource/resource_font.h"
|
||||
#include "../resource/resource_music.h"
|
||||
#include "../resource/resource_sound.h"
|
||||
|
||||
static const struct ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] =
|
||||
{
|
||||
COMPONENT_GAME_OBJECT_INFO,
|
||||
COMPONENT_COUNTER_INFO,
|
||||
COMPONENT_TIMER_INFO,
|
||||
COMPONENT_TEXTURE_QUAD_INFO,
|
||||
COMPONENT_TEXT_INFO,
|
||||
COMPONENT_OUTLINE_INFO,
|
||||
COMPONENT_ATLAS_INFO,
|
||||
COMPONENT_PHYSICS_INFO,
|
||||
COMPONENT_COPY_MOUSE_POSITION_INFO
|
||||
};
|
||||
|
||||
void ecs_tick(ECS* self);
|
||||
void ecs_update(ECS* self);
|
||||
void ecs_draw(ECS* self);
|
||||
void ecs_init(ECS* self, Renderer* renderer, Input* input, Resources* resources, Postprocessing* postprocessing);
|
||||
void ecs_clear(ECS* self);
|
||||
void ecs_free(ECS* self);
|
76
src/game/ecs/ecs_component.c
Normal file
76
src/game/ecs/ecs_component.c
Normal file
@@ -0,0 +1,76 @@
|
||||
#include "ecs_component.h"
|
||||
|
||||
void*
|
||||
ecs_component_get(ECS* self, ECSComponentType type, EntityID id)
|
||||
{
|
||||
return ecs_component_list_get(&self->lists[type], id);
|
||||
}
|
||||
|
||||
void*
|
||||
ecs_component_from_index_get(ECS* self, ECSComponentType type, u32 index)
|
||||
{
|
||||
return vector_get(&self->lists[type].components, index);
|
||||
}
|
||||
|
||||
void*
|
||||
ecs_component_add(ECS* self, ECSComponentType type, EntityID id)
|
||||
{
|
||||
void* component;
|
||||
ECSFunction add;
|
||||
|
||||
component = ecs_component_get(self, type, id);
|
||||
|
||||
if (component)
|
||||
return component;
|
||||
|
||||
component = vector_push(&self->lists[type].components, NULL);
|
||||
|
||||
memcpy(component, (void*)&id, sizeof(EntityID));
|
||||
|
||||
add = self->lists[type].system.functions[ECS_FUNCTION_ADD];
|
||||
|
||||
if (add)
|
||||
add(component, self);
|
||||
|
||||
return component;
|
||||
}
|
||||
|
||||
void
|
||||
ecs_component_delete(ECS* self, ECSComponentType type, EntityID id)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)self->lists[type].components.count; i++)
|
||||
{
|
||||
EntityID checkID;
|
||||
void* component;
|
||||
|
||||
component = vector_get(&self->lists[type].components, i);
|
||||
|
||||
memcpy(&checkID, component, sizeof(EntityID));
|
||||
|
||||
if (checkID == id)
|
||||
{
|
||||
ECSFunction delete;
|
||||
|
||||
delete = self->lists[type].system.functions[ECS_FUNCTION_DELETE];
|
||||
|
||||
if (delete)
|
||||
delete(component, self);
|
||||
|
||||
vector_remove(&self->lists[type].components, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ecs_components_add(ECS* self, const ECSComponentType* types, u32 count, EntityID id)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
ecs_component_add(self, types[i], id);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_components_delete(ECS* self, const ECSComponentType* types, u32 count, EntityID id)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
ecs_component_delete(self, types[i], id);
|
||||
}
|
10
src/game/ecs/ecs_component.h
Normal file
10
src/game/ecs/ecs_component.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_component_list.h"
|
||||
|
||||
void ecs_component_delete(ECS* self, ECSComponentType type, EntityID id);
|
||||
void* ecs_component_add(ECS* self, ECSComponentType type, EntityID id);
|
||||
void* ecs_component_get(ECS* self, ECSComponentType type, EntityID id);
|
||||
void* ecs_component_from_index_get(ECS* self, ECSComponentType type, u32 index);
|
||||
void ecs_components_add(ECS* self, const ECSComponentType* types, u32 count, EntityID id);
|
||||
void ecs_components_delete(ECS* self, const ECSComponentType* types, u32 count, EntityID id);
|
73
src/game/ecs/ecs_component_list.c
Normal file
73
src/game/ecs/ecs_component_list.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "ecs_component_list.h"
|
||||
|
||||
void
|
||||
ecs_component_list_init(ECSComponentList* self, ECS* ecs, ECSComponentInfo info)
|
||||
{
|
||||
self->ecs = ecs;
|
||||
self->type = info.type;
|
||||
self->system = info.system;
|
||||
|
||||
vector_init(&self->components, info.size);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_component_list_function(ECSComponentList* self, ECSFunctionType type)
|
||||
{
|
||||
ECSFunction function;
|
||||
|
||||
function = self->system.functions[type];
|
||||
|
||||
if (!function)
|
||||
return;
|
||||
|
||||
for (s32 i = 0; i < (s32)self->components.count; i++)
|
||||
{
|
||||
void* component;
|
||||
ECSComponent ecsComponent;
|
||||
|
||||
component = vector_get(&self->components, i);
|
||||
|
||||
memcpy(&ecsComponent, component, sizeof(ECSComponent));
|
||||
|
||||
if
|
||||
(
|
||||
ecsComponent.isDisabled ||
|
||||
ecsComponent.isFunctionDisabled[type]
|
||||
)
|
||||
continue;
|
||||
|
||||
function(component, self->ecs);
|
||||
}
|
||||
}
|
||||
|
||||
void*
|
||||
ecs_component_list_get(ECSComponentList* self, EntityID id)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)self->components.count; i++)
|
||||
{
|
||||
u32 checkID;
|
||||
void* component;
|
||||
|
||||
component = vector_get(&self->components, i);
|
||||
|
||||
memcpy(&checkID, component, sizeof(u32));
|
||||
|
||||
if (checkID == id)
|
||||
return component;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
ecs_component_list_clear(ECSComponentList* self)
|
||||
{
|
||||
vector_clear(&self->components);
|
||||
}
|
||||
|
||||
void
|
||||
ecs_component_list_free(ECSComponentList* self)
|
||||
{
|
||||
vector_free(&self->components);
|
||||
memset(self, '\0', sizeof(ECSComponentList));
|
||||
}
|
9
src/game/ecs/ecs_component_list.h
Normal file
9
src/game/ecs/ecs_component_list.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "ECS_COMMON.h"
|
||||
|
||||
void* ecs_component_list_get(ECSComponentList* self, EntityID id);
|
||||
void ecs_component_list_init(ECSComponentList* self, ECS* ecs, ECSComponentInfo info);
|
||||
void ecs_component_list_function(ECSComponentList* self, ECSFunctionType type);
|
||||
void ecs_component_list_clear(ECSComponentList* self);
|
||||
void ecs_component_list_free(ECSComponentList* self);
|
20
src/game/ecs/ecs_entity.c
Normal file
20
src/game/ecs/ecs_entity.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "ecs_entity.h"
|
||||
|
||||
EntityID
|
||||
ecs_entity_add(ECS* self)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = self->nextID;
|
||||
|
||||
self->nextID++;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
void
|
||||
ecs_entity_delete(ECS* self, EntityID id)
|
||||
{
|
||||
for (s32 i = 0; i < ECS_COMPONENT_COUNT; i++)
|
||||
ecs_component_delete(self, (ECSComponentType)i, id);
|
||||
}
|
6
src/game/ecs/ecs_entity.h
Normal file
6
src/game/ecs/ecs_entity.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "ecs_component.h"
|
||||
|
||||
u32 ecs_entity_add(ECS* ecs);
|
||||
void ecs_entity_delete(ECS* ecs, EntityID id);
|
23
src/game/ecs/entity/ui/entity_cursor.c
Normal file
23
src/game/ecs/entity/ui/entity_cursor.c
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "entity_cursor.h"
|
||||
|
||||
EntityID
|
||||
entity_cursor_add(ECS* ecs)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = ecs_entity_add(ecs);
|
||||
|
||||
ecs_components_add(ecs, ENTITY_CURSOR_DEPENDENCIES, ENTITY_CURSOR_DEPENDENCY_COUNT, id);
|
||||
|
||||
component_game_object_init
|
||||
(
|
||||
ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, id),
|
||||
ecs,
|
||||
&ecs->resources->textures[TEXTURE_CURSOR],
|
||||
ENTITY_CURSOR_BUFFER,
|
||||
(f32*)ENTITY_CURSOR_SIZE,
|
||||
(f32*)ENTITY_CURSOR_POSITION
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
19
src/game/ecs/entity/ui/entity_cursor.h
Normal file
19
src/game/ecs/entity/ui/entity_cursor.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../component/game/component_game_object.h"
|
||||
#include "../../component/physics/component_copy_mouse_position.h"
|
||||
|
||||
EntityID entity_cursor_add(ECS* ecs);
|
||||
|
||||
#define ENTITY_CURSOR_DEPENDENCY_COUNT 3
|
||||
static const ECSComponentType ENTITY_CURSOR_DEPENDENCIES[ENTITY_CURSOR_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_GAME_OBJECT,
|
||||
ECS_COMPONENT_OUTLINE,
|
||||
ECS_COMPONENT_COPY_MOUSE_POSITION
|
||||
};
|
||||
|
||||
static const RendererBuffer ENTITY_CURSOR_BUFFER = RENDERER_BUFFER_UI;
|
||||
static const vec2 ENTITY_CURSOR_SIZE = {32.0f, 32.0f};
|
||||
static const vec3 ENTITY_CURSOR_POSITION = {0.0f, 0.0f, 0.0f};
|
||||
|
15
src/game/ecs/entity/utility/entity_counter.c
Normal file
15
src/game/ecs/entity/utility/entity_counter.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "entity_counter.h"
|
||||
|
||||
EntityID
|
||||
entity_counter_add(ECS* ecs, s32 value, s32 max)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = ecs_entity_add(ecs);
|
||||
|
||||
ecs_components_add(ecs, ENTITY_COUNTER_DEPENDENCIES, ENTITY_COUNTER_DEPENDENCY_COUNT, id);
|
||||
|
||||
component_counter_init(ecs_component_get(ecs, ECS_COMPONENT_COUNTER, id), ecs, value, max);
|
||||
|
||||
return id;
|
||||
}
|
11
src/game/ecs/entity/utility/entity_counter.h
Normal file
11
src/game/ecs/entity/utility/entity_counter.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../component/utility/component_counter.h"
|
||||
|
||||
#define ENTITY_COUNTER_DEPENDENCY_COUNT 1
|
||||
static const ECSComponentType ENTITY_COUNTER_DEPENDENCIES[ENTITY_COUNTER_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_COUNTER
|
||||
};
|
||||
|
||||
EntityID entity_counter_add(ECS* ecs, s32 value, s32 max);
|
15
src/game/ecs/entity/utility/entity_timer.c
Normal file
15
src/game/ecs/entity/utility/entity_timer.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "entity_timer.h"
|
||||
|
||||
EntityID
|
||||
entity_timer_add(ECS* ecs, u32 value)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = ecs_entity_add(ecs);
|
||||
|
||||
ecs_components_add(ecs, ENTITY_TIMER_DEPENDENCIES, ENTITY_TIMER_DEPENDENCY_COUNT, id);
|
||||
|
||||
component_timer_init(ecs_component_get(ecs, ECS_COMPONENT_TIMER, id), ecs, value);
|
||||
|
||||
return id;
|
||||
}
|
11
src/game/ecs/entity/utility/entity_timer.h
Normal file
11
src/game/ecs/entity/utility/entity_timer.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../component/utility/component_timer.h"
|
||||
|
||||
#define ENTITY_TIMER_DEPENDENCY_COUNT 1
|
||||
static const ECSComponentType ENTITY_TIMER_DEPENDENCIES[ENTITY_TIMER_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_TIMER
|
||||
};
|
||||
|
||||
EntityID entity_timer_add(ECS* ecs, u32 value);
|
32
src/game/ecs/entity/visual/entity_sprite.c
Normal file
32
src/game/ecs/entity/visual/entity_sprite.c
Normal file
@@ -0,0 +1,32 @@
|
||||
#include "entity_sprite.h"
|
||||
|
||||
EntityID
|
||||
entity_sprite_add(ECS* ecs, Texture* texture, RendererBuffer buffer, const vec2 size, const vec3 position)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = ecs_entity_add(ecs);
|
||||
|
||||
ecs_components_add(ecs, ENTITY_SPRITE_DEPENDENCIES, ENTITY_SPRITE_DEPENDENCY_COUNT, id);
|
||||
|
||||
component_texture_quad_init
|
||||
(
|
||||
ecs_component_get(ecs, ECS_COMPONENT_TEXTURE_QUAD, id),
|
||||
ecs,
|
||||
texture,
|
||||
&ecs->resources->shaders[SHADER_TEXTURE_QUAD],
|
||||
COMPONENT_TEXTURE_QUAD_FLIP_DEFAULT,
|
||||
COMPONENT_TEXTURE_QUAD_ORIGIN_DEFAULT,
|
||||
buffer,
|
||||
COMPONENT_TEXTURE_QUAD_ROTATION_DEFAULT,
|
||||
(f32*)size,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_SCALE_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MIN_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_OFFSET_DEFAULT,
|
||||
(f32*)position,
|
||||
(f32*)COMPONENT_TEXTURE_QUAD_COLOR_DEFAULT
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
11
src/game/ecs/entity/visual/entity_sprite.h
Normal file
11
src/game/ecs/entity/visual/entity_sprite.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../component/visual/component_texture_quad.h"
|
||||
|
||||
#define ENTITY_SPRITE_DEPENDENCY_COUNT 1
|
||||
static const ECSComponentType ENTITY_SPRITE_DEPENDENCIES[ENTITY_SPRITE_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_TEXTURE_QUAD
|
||||
};
|
||||
|
||||
EntityID entity_sprite_add(ECS* ecs, Texture* texture, RendererBuffer buffer, const vec2 size, const vec3 position);
|
39
src/game/ecs/entity/visual/entity_text.c
Normal file
39
src/game/ecs/entity/visual/entity_text.c
Normal file
@@ -0,0 +1,39 @@
|
||||
#include "entity_text.h"
|
||||
|
||||
EntityID
|
||||
entity_text_add
|
||||
(
|
||||
ECS* ecs,
|
||||
Font* font,
|
||||
RendererBuffer buffer,
|
||||
const char* string,
|
||||
const vec3 position,
|
||||
const vec4 color,
|
||||
u32 length,
|
||||
u32 wrap
|
||||
)
|
||||
{
|
||||
EntityID id;
|
||||
|
||||
id = ecs_entity_add(ecs);
|
||||
|
||||
ecs_components_add(ecs, ENTITY_TEXT_DEPENDENCIES, ENTITY_TEXT_DEPENDENCY_COUNT, id);
|
||||
|
||||
component_text_init
|
||||
(
|
||||
ecs_component_get(ecs, ECS_COMPONENT_TEXT, id),
|
||||
ecs,
|
||||
font,
|
||||
&ecs->resources->shaders[SHADER_TEXTURE_QUAD],
|
||||
buffer,
|
||||
string,
|
||||
(f32*)ENTITY_TEXT_SCALE_DEFAULT,
|
||||
position,
|
||||
(f32*)ENTITY_TEXT_OFFSET_DEFAULT,
|
||||
color,
|
||||
length,
|
||||
wrap
|
||||
);
|
||||
|
||||
return id;
|
||||
}
|
26
src/game/ecs/entity/visual/entity_text.h
Normal file
26
src/game/ecs/entity/visual/entity_text.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../component/visual/component_text.h"
|
||||
|
||||
#define ENTITY_TEXT_SCALE_DEFAULT COMPONENT_TEXT_SCALE_DEFAULT
|
||||
#define ENTITY_TEXT_OFFSET_DEFAULT COMPONENT_TEXT_OFFSET_DEFAULT
|
||||
|
||||
#define ENTITY_TEXT_DEPENDENCY_COUNT 1
|
||||
static const ECSComponentType ENTITY_TEXT_DEPENDENCIES[ENTITY_TEXT_DEPENDENCY_COUNT] =
|
||||
{
|
||||
ECS_COMPONENT_TEXT
|
||||
};
|
||||
|
||||
|
||||
EntityID
|
||||
entity_text_add
|
||||
(
|
||||
ECS* ecs,
|
||||
Font* font,
|
||||
RendererBuffer buffer,
|
||||
const char* string,
|
||||
const vec3 position,
|
||||
const vec4 color,
|
||||
u32 length,
|
||||
u32 wrap
|
||||
);
|
116
src/game/game.c
Normal file
116
src/game/game.c
Normal file
@@ -0,0 +1,116 @@
|
||||
#include "game.h"
|
||||
|
||||
Game game;
|
||||
|
||||
static void _game_tick(Game* self);
|
||||
static void _game_update(Game* self);
|
||||
static void _game_draw(Game* self);
|
||||
static void _game_quit(Game* self);
|
||||
|
||||
static void
|
||||
_game_quit(Game* self)
|
||||
{
|
||||
state_free(&self->state);
|
||||
|
||||
ecs_free(&self->ecs);
|
||||
|
||||
window_free(&self->window);
|
||||
|
||||
sdl_quit();
|
||||
|
||||
memset(self, '\0', sizeof(Game));
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static void
|
||||
_game_tick(Game* self)
|
||||
{
|
||||
input_tick(&self->input);
|
||||
|
||||
state_tick(&self->state);
|
||||
|
||||
ecs_tick(&self->ecs);
|
||||
|
||||
if (event_press(&self->input.event, EVENT_QUIT))
|
||||
_game_quit(self);
|
||||
}
|
||||
|
||||
static void
|
||||
_game_update(Game* self)
|
||||
{
|
||||
renderer_update(&self->renderer);
|
||||
ecs_update(&self->ecs);
|
||||
}
|
||||
|
||||
static void
|
||||
_game_draw(Game* self)
|
||||
{
|
||||
renderer_clear_color_set(&self->renderer, (f32*)RENDERER_CLEAR_COLOR);
|
||||
|
||||
renderer_clear(&self->renderer);
|
||||
|
||||
for (s32 i = 0; i < RENDERER_BUFFER_COUNT; i++)
|
||||
{
|
||||
renderer_buffer_init(&self->renderer, (RendererBuffer)i);
|
||||
renderer_buffer_use(&self->renderer, (RendererBuffer)i);
|
||||
renderer_clear_color_set(&self->renderer, (f32*)TRANSPARENT);
|
||||
renderer_clear(&self->renderer);
|
||||
renderer_buffer_unbind();
|
||||
}
|
||||
|
||||
ecs_draw(&self->ecs);
|
||||
|
||||
for (s32 i = 0; i < RENDERER_BUFFER_COUNT; i++)
|
||||
{
|
||||
buffer_draw
|
||||
(
|
||||
&self->renderer,
|
||||
&self->resources.shaders[SHADER_POSTPROCESS_TEXTURE_QUAD],
|
||||
&self->postprocessing[i],
|
||||
(RendererBuffer)i
|
||||
);
|
||||
|
||||
renderer_buffer_free(&self->renderer, (RendererBuffer)i);
|
||||
}
|
||||
|
||||
renderer_present(&self->renderer);
|
||||
}
|
||||
|
||||
void
|
||||
game_init(Game* self)
|
||||
{
|
||||
memset(self, '\0', sizeof(Game));
|
||||
|
||||
RANDOM_SEED_SET(time(NULL));
|
||||
|
||||
resource_shader_read(&self->resources);
|
||||
|
||||
sdl_init();
|
||||
|
||||
window_init(&self->window, STRING_WINDOW_TITLE, (s32*)WINDOW_SIZE, WINDOW_FLAGS);
|
||||
|
||||
renderer_init(&self->renderer, &self->window, CAMERA_ORTHOGRAPHIC, (s32*)WORLD_SIZE);
|
||||
|
||||
renderer_clear_color_set(&self->renderer, (f32*)RENDERER_CLEAR_COLOR);
|
||||
|
||||
ecs_init(&self->ecs, &self->renderer, &self->input, &self->resources, self->postprocessing);
|
||||
|
||||
state_init(&self->state, &self->ecs, STATE_GAMEPLAY);
|
||||
}
|
||||
|
||||
void
|
||||
game_loop(Game* self)
|
||||
{
|
||||
tick_update(&self->tick);
|
||||
|
||||
while (self->tick.cumulative > TICK_DELAY)
|
||||
{
|
||||
_game_tick(self);
|
||||
|
||||
self->tick.cumulative -= TICK_DELAY;
|
||||
}
|
||||
|
||||
_game_update(self);
|
||||
_game_draw(self);
|
||||
}
|
16
src/game/game.h
Normal file
16
src/game/game.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "GAME_COMMON.h"
|
||||
|
||||
#define WINDOW_FLAGS SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
|
||||
#define STRING_WINDOW_TITLE "Game Engine"
|
||||
#define TICK_DELAY 15
|
||||
|
||||
static const ivec2 WINDOW_SIZE = {1280, 720};
|
||||
static const ivec2 WORLD_SIZE = {1280, 720};
|
||||
static const vec4 RENDERER_CLEAR_COLOR = {0.700f, 0.700f, 0.700f, 1.0f};
|
||||
|
||||
void game_init(Game* game);
|
||||
void game_loop(Game* game);
|
||||
|
||||
extern Game game;
|
9
src/game/input/input.c
Normal file
9
src/game/input/input.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "input.h"
|
||||
|
||||
void
|
||||
input_tick(Input* self)
|
||||
{
|
||||
keyboard_update(&self->keyboard);
|
||||
mouse_update(&self->mouse);
|
||||
event_update(&self->event);
|
||||
}
|
14
src/game/input/input.h
Normal file
14
src/game/input/input.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../engine/event.h"
|
||||
#include "../../engine/keyboard.h"
|
||||
#include "../../engine/mouse.h"
|
||||
|
||||
typedef struct Input
|
||||
{
|
||||
Keyboard keyboard;
|
||||
Mouse mouse;
|
||||
Event event;
|
||||
} Input;
|
||||
|
||||
void input_tick(Input* self);
|
26
src/game/render/RENDER_COMMON.h
Normal file
26
src/game/render/RENDER_COMMON.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../engine/renderer.h"
|
||||
#include "../../engine/texture.h"
|
||||
|
||||
typedef enum Flip
|
||||
{
|
||||
FLIP_NONE,
|
||||
FLIP_HORIZONTAL,
|
||||
FLIP_VERTICAL,
|
||||
FLIP_HORIZONTAL_VERTICAL
|
||||
} Flip;
|
||||
|
||||
typedef enum Origin
|
||||
{
|
||||
ORIGIN_CENTER,
|
||||
ORIGIN_TOP_LEFT
|
||||
} Origin;
|
||||
|
||||
typedef struct Postprocessing
|
||||
{
|
||||
vec4 color;
|
||||
f32 screenShakeIntensity;
|
||||
u32 screenShakeTimer;
|
||||
bool isScreenShake;
|
||||
} Postprocessing;
|
44
src/game/render/buffer.c
Normal file
44
src/game/render/buffer.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "buffer.h"
|
||||
|
||||
void
|
||||
buffer_draw(Renderer* renderer, Shader* shader, Postprocessing* postprocessing, RendererBuffer buffer)
|
||||
{
|
||||
mat4 model;
|
||||
vec2 size;
|
||||
vec3 position;
|
||||
|
||||
glm_vec2_zero(size);
|
||||
glm_vec3_zero(position);
|
||||
glm_mat4_identity(model);
|
||||
|
||||
size[0] = renderer->size[0];
|
||||
size[1] = renderer->size[1];
|
||||
|
||||
glm_translate(model, position);
|
||||
|
||||
renderer_shader_use(renderer, shader);
|
||||
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
||||
/*
|
||||
postprocessing->color[0] = 0.9f;
|
||||
postprocessing->color[1] = 0.25f;
|
||||
postprocessing->color[2] = 0.25f;
|
||||
postprocessing->color[3] = 1.0f;
|
||||
*/
|
||||
|
||||
texture_quad_draw
|
||||
(
|
||||
&renderer->fboTextures[buffer],
|
||||
renderer,
|
||||
shader,
|
||||
(f32*)TEXTURE_QUAD_UV_MIN_DEFAULT,
|
||||
(f32*)TEXTURE_QUAD_UV_MAX_DEFAULT,
|
||||
model,
|
||||
size,
|
||||
postprocessing->color,
|
||||
FLIP_HORIZONTAL_VERTICAL
|
||||
);
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
}
|
5
src/game/render/buffer.h
Normal file
5
src/game/render/buffer.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "texture_quad.h"
|
||||
|
||||
void buffer_draw(Renderer* renderer, Shader* shader, Postprocessing* postprocessing, RendererBuffer buffer);
|
97
src/game/render/texture_quad.c
Normal file
97
src/game/render/texture_quad.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#include "texture_quad.h"
|
||||
|
||||
void
|
||||
texture_quad_draw
|
||||
(
|
||||
Texture* texture,
|
||||
Renderer* renderer,
|
||||
Shader* shader,
|
||||
vec2 uvMin,
|
||||
vec2 uvMax,
|
||||
mat4 model,
|
||||
vec2 size,
|
||||
vec4 color,
|
||||
Flip flip
|
||||
)
|
||||
{
|
||||
mat4 view;
|
||||
mat4 projection;
|
||||
f32 vertices[4][5];
|
||||
|
||||
u32 indices[2][3] = {{1, 2, 3}, {0, 1, 3}};
|
||||
f32 verticiesFlipNone[4][5] =
|
||||
{
|
||||
{0.0f, 0.0f, 0.0f, uvMin[0], uvMin[1]},
|
||||
{0.0f, size[1], 0.0f, uvMin[0], uvMax[1]},
|
||||
{size[0], size[1], 0.0f, uvMax[0], uvMax[1]},
|
||||
{size[0], 0.0f, 0.0f, uvMax[0], uvMin[1]}
|
||||
};
|
||||
|
||||
f32 verticiesFlipHorizontal[4][5] =
|
||||
{
|
||||
{size[0], 0.0f, 0.0f, uvMin[0], uvMin[1]},
|
||||
{size[0], size[1], 0.0f, uvMin[0], uvMax[1]},
|
||||
{0.0f, size[1], 0.0f, uvMax[0], uvMax[1]},
|
||||
{0.0f, 0.0f, 0.0f, uvMax[0], uvMin[1]}
|
||||
};
|
||||
|
||||
f32 verticiesFlipVertical[4][5] =
|
||||
{
|
||||
{size[0], size[1], 0.0f, uvMin[0], uvMin[1]},
|
||||
{size[0], 0.0f, 0.0f, uvMin[0], uvMax[1]},
|
||||
{0.0f, 0.0f, 0.0f, uvMax[0], uvMax[1]},
|
||||
{0.0f, size[1], 0.0f, uvMax[0], uvMin[1]}
|
||||
};
|
||||
|
||||
f32 verticiesFlipHorizontalVertical[4][5] =
|
||||
{
|
||||
{0.0f, size[1], 0.0f, uvMin[0], uvMin[1]},
|
||||
{0.0f, 0.0f, 0.0f, uvMin[0], uvMax[1]},
|
||||
{size[0], 0.0f, 0.0f, uvMax[0], uvMax[1]},
|
||||
{size[0], size[1], 0.0f, uvMax[0], uvMin[1]}
|
||||
};
|
||||
|
||||
switch (flip)
|
||||
{
|
||||
case FLIP_HORIZONTAL:
|
||||
memcpy(vertices, verticiesFlipHorizontal, sizeof(vertices));
|
||||
break;
|
||||
case FLIP_VERTICAL:
|
||||
memcpy(vertices, verticiesFlipVertical, sizeof(vertices));
|
||||
break;
|
||||
case FLIP_HORIZONTAL_VERTICAL:
|
||||
memcpy(vertices, verticiesFlipHorizontalVertical, sizeof(vertices));
|
||||
break;
|
||||
case FLIP_NONE:
|
||||
default:
|
||||
memcpy(vertices, verticiesFlipNone, sizeof(vertices));
|
||||
break;
|
||||
}
|
||||
|
||||
camera_view_get(&renderer->camera, view);
|
||||
camera_projection_get(&renderer->camera, projection);
|
||||
|
||||
vao_bind(&renderer->vao);
|
||||
|
||||
vbo_bind(&renderer->vbo);
|
||||
vbo_buffer(&renderer->vbo, sizeof(vertices), vertices);
|
||||
|
||||
vbo_bind(&renderer->ebo);
|
||||
vbo_buffer(&renderer->ebo, sizeof(indices), indices);
|
||||
|
||||
vertex_attribute_set(0, 3, GL_FLOAT, 5 * sizeof(f32), 0);
|
||||
vertex_attribute_set(1, 2, GL_FLOAT, 5 * sizeof(f32), 3 * sizeof(f32));
|
||||
|
||||
renderer_shader_use(renderer, shader);
|
||||
|
||||
shader_uniform_mat4_set(shader, TEXTURE_QUAD_UNIFORM_VIEW, view);
|
||||
shader_uniform_mat4_set(shader, TEXTURE_QUAD_UNIFORM_PROJECTION, projection);
|
||||
shader_uniform_mat4_set(shader, TEXTURE_QUAD_UNIFORM_MODEL, model);
|
||||
shader_uniform_vec2_set(shader, TEXTURE_QUAD_UNIFORM_SIZE, size);
|
||||
shader_uniform_vec4_set(shader, TEXTURE_QUAD_UNIFORM_COLOR, color);
|
||||
shader_uniform_texture_set(shader, TEXTURE_QUAD_UNIFORM_TEXTURE, texture, 0);
|
||||
|
||||
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);
|
||||
|
||||
vao_unbind();
|
||||
}
|
30
src/game/render/texture_quad.h
Normal file
30
src/game/render/texture_quad.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include "RENDER_COMMON.h"
|
||||
|
||||
#define TEXTURE_QUAD_UNIFORM_COLOR "color"
|
||||
#define TEXTURE_QUAD_UNIFORM_MODEL "model"
|
||||
#define TEXTURE_QUAD_UNIFORM_PROJECTION "projection"
|
||||
#define TEXTURE_QUAD_UNIFORM_SIZE "size"
|
||||
#define TEXTURE_QUAD_UNIFORM_TEXTURE "tex"
|
||||
#define TEXTURE_QUAD_UNIFORM_VIEW "view"
|
||||
|
||||
void texture_quad_draw
|
||||
(
|
||||
Texture* texture,
|
||||
Renderer* renderer,
|
||||
Shader* shader,
|
||||
vec2 uvMin,
|
||||
vec2 uvMax,
|
||||
mat4 model,
|
||||
vec2 size,
|
||||
vec4 color,
|
||||
Flip flip
|
||||
);
|
||||
|
||||
#define TEXTURE_QUAD_COLOR_DEFAULT (f32*)OPAQUE
|
||||
|
||||
static const vec2 TEXTURE_QUAD_UV_MIN_DEFAULT = {0.0f, 0.0f};
|
||||
static const vec2 TEXTURE_QUAD_UV_MAX_DEFAULT = {1.0f, 1.0f};
|
||||
static const Flip TEXTURE_QUAD_FLIP_DEFAULT = FLIP_NONE;
|
||||
static const Origin TEXTURE_QUAD_ORIGIN_DEFAULT = ORIGIN_CENTER;
|
101
src/game/resource/RESOURCE_COMMON.h
Normal file
101
src/game/resource/RESOURCE_COMMON.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../engine/file.h"
|
||||
#include "../../engine/shader.h"
|
||||
#include "../../engine/font.h"
|
||||
#include "../../engine/texture.h"
|
||||
#include "../../engine/sound.h"
|
||||
#include "../../engine/music.h"
|
||||
|
||||
#define SHADER_COUNT SHADER_POSTPROCESS_TEXTURE_QUAD + 1
|
||||
typedef enum ShaderType
|
||||
{
|
||||
SHADER_TEXTURE_QUAD,
|
||||
SHADER_COLORED_TEXTURE_QUAD,
|
||||
SHADER_POSTPROCESS_TEXTURE_QUAD
|
||||
} ShaderType;
|
||||
|
||||
typedef struct ShaderPaths
|
||||
{
|
||||
const char* vertex;
|
||||
const char* fragment;
|
||||
} ShaderPaths;
|
||||
|
||||
static const ShaderPaths SHADER_PATHS[SHADER_COUNT] =
|
||||
{
|
||||
{
|
||||
.vertex = "res/shader/texture_quad.vs",
|
||||
.fragment = "res/shader/texture_quad.fs"
|
||||
},
|
||||
{
|
||||
.vertex = "res/shader/texture_quad.vs",
|
||||
.fragment = "res/shader/colored_texture_quad.fs"
|
||||
},
|
||||
|
||||
{
|
||||
.vertex = "res/shader/texture_quad.vs",
|
||||
.fragment = "res/shader/postprocess_texture_quad.fs"
|
||||
},
|
||||
};
|
||||
|
||||
#define TEXTURE_COUNT TEXTURE_CURSOR + 1
|
||||
typedef enum TextureType
|
||||
{
|
||||
TEXTURE_TEST,
|
||||
TEXTURE_TEST2,
|
||||
TEXTURE_CURSOR,
|
||||
} TextureType;
|
||||
|
||||
static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
|
||||
{
|
||||
"res/gfx/test.png",
|
||||
"res/gfx/test2.png",
|
||||
"res/gfx/cursor.png"
|
||||
};
|
||||
|
||||
#define FONT_COUNT FONT_TEST + 1
|
||||
typedef enum FontType
|
||||
{
|
||||
FONT_TEST
|
||||
} FontType;
|
||||
|
||||
static const char* FONT_PATHS[FONT_COUNT] =
|
||||
{
|
||||
"res/font/test.ttf"
|
||||
};
|
||||
|
||||
static const u32 FONT_SIZES[FONT_COUNT] =
|
||||
{
|
||||
32
|
||||
};
|
||||
|
||||
#define SOUND_COUNT SOUND_TEST + 1
|
||||
typedef enum SoundType
|
||||
{
|
||||
SOUND_TEST
|
||||
} SoundType;
|
||||
|
||||
static const char* SOUND_PATHS[SOUND_COUNT] =
|
||||
{
|
||||
"res/sound/test.ogg"
|
||||
};
|
||||
|
||||
#define MUSIC_COUNT MUSIC_TEST + 1
|
||||
typedef enum MusicType
|
||||
{
|
||||
MUSIC_TEST
|
||||
} MusicType;
|
||||
|
||||
static const char* MUSIC_PATHS[MUSIC_COUNT] =
|
||||
{
|
||||
"res/music/test.ogg"
|
||||
};
|
||||
|
||||
typedef struct Resources
|
||||
{
|
||||
Shader shaders[SHADER_COUNT];
|
||||
Texture textures[TEXTURE_COUNT];
|
||||
Music music[MUSIC_COUNT];
|
||||
Sound sounds[SOUND_COUNT];
|
||||
Font fonts[FONT_COUNT];
|
||||
} Resources;
|
44
src/game/resource/resource_font.c
Normal file
44
src/game/resource/resource_font.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "resource_font.h"
|
||||
|
||||
/* Initializes font resource. */
|
||||
bool
|
||||
resource_font_init(Resources* self, FontType type)
|
||||
{
|
||||
if (!font_init(&self->fonts[type], FONT_PATHS[type], FONT_SIZES[type]))
|
||||
{
|
||||
printf(STRING_RESOURCE_FONT_ERROR, FONT_PATHS[type]);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(STRING_RESOURCE_FONT_INIT, FONT_PATHS[type]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Frees font resources. */
|
||||
void
|
||||
resource_font_free(Resources* self, FontType type)
|
||||
{
|
||||
if (self->fonts[type].isInit)
|
||||
{
|
||||
font_free(&self->fonts[type]);
|
||||
|
||||
printf(STRING_RESOURCE_FONT_FREE, FONT_PATHS[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an array, initializes font resources. */
|
||||
void
|
||||
resource_font_state_init(Resources* self, const FontType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_font_init(self, types[i]);
|
||||
}
|
||||
|
||||
/* Frees font resources. */
|
||||
void
|
||||
resource_font_state_free(Resources* self, const FontType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_font_free(self, types[i]);
|
||||
}
|
14
src/game/resource/resource_font.h
Normal file
14
src/game/resource/resource_font.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCE_COMMON.h"
|
||||
|
||||
#define STRING_RESOURCE_FONT_ERROR "[ERROR] Unable to initialize font resource: %s\n"
|
||||
#define STRING_RESOURCE_FONT_FREE "[INFO] Freed font resource: %s\n"
|
||||
#define STRING_RESOURCE_FONT_INIT "[INFO] Initialized font resource: %s\n"
|
||||
|
||||
|
||||
|
||||
void resource_font_state_free(Resources* self, const FontType* types, u32 count);
|
||||
void resource_font_state_init(Resources* self, const FontType* types, u32 count);
|
||||
void resource_font_free(Resources* self, FontType type);
|
||||
bool resource_font_init(Resources* self, FontType type);
|
44
src/game/resource/resource_music.c
Normal file
44
src/game/resource/resource_music.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "resource_music.h"
|
||||
|
||||
/* Initializes music resource. */
|
||||
bool
|
||||
resource_music_init(Resources* self, MusicType type)
|
||||
{
|
||||
if (!music_init(&self->music[type], MUSIC_PATHS[type]))
|
||||
{
|
||||
printf(STRING_RESOURCE_MUSIC_ERROR, MUSIC_PATHS[type]);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(STRING_RESOURCE_MUSIC_INIT, MUSIC_PATHS[type]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Frees music resources. */
|
||||
void
|
||||
resource_music_free(Resources* self, MusicType type)
|
||||
{
|
||||
if (self->music[type].isInit)
|
||||
{
|
||||
music_free(&self->music[type]);
|
||||
|
||||
printf(STRING_RESOURCE_MUSIC_FREE, MUSIC_PATHS[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an array, initializes music resources. */
|
||||
void
|
||||
resource_music_state_init(Resources* self, const MusicType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_music_init(self, types[i]);
|
||||
}
|
||||
|
||||
/* Frees music resources. */
|
||||
void
|
||||
resource_music_state_free(Resources* self, const MusicType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_music_free(self, types[i]);
|
||||
}
|
12
src/game/resource/resource_music.h
Normal file
12
src/game/resource/resource_music.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCE_COMMON.h"
|
||||
|
||||
#define STRING_RESOURCE_MUSIC_ERROR "[ERROR] Unable to initialize music resource: %s\n"
|
||||
#define STRING_RESOURCE_MUSIC_FREE "[INFO] Freed music resource: %s\n"
|
||||
#define STRING_RESOURCE_MUSIC_INIT "[INFO] Initialized music resource: %s\n"
|
||||
|
||||
void resource_music_state_free(Resources* self, const MusicType* types, u32 count);
|
||||
void resource_music_state_init(Resources* self, const MusicType* types, u32 count);
|
||||
void resource_music_free(Resources* self, MusicType type);
|
||||
bool resource_music_init(Resources* self, MusicType type);
|
77
src/game/resource/resource_shader.c
Normal file
77
src/game/resource/resource_shader.c
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "resource_shader.h"
|
||||
|
||||
typedef struct ShaderData
|
||||
{
|
||||
char vertex[SHADER_BUFFER_SIZE];
|
||||
char fragment[SHADER_BUFFER_SIZE];
|
||||
} ShaderData;
|
||||
|
||||
static ShaderData shaderData[SHADER_COUNT];
|
||||
|
||||
void
|
||||
resource_shader_read(Resources* self)
|
||||
{
|
||||
for (s32 i = 0; i < SHADER_COUNT; i++)
|
||||
{
|
||||
file_read
|
||||
(
|
||||
SHADER_PATHS[i].vertex,
|
||||
(void*)shaderData[i].vertex,
|
||||
SHADER_BUFFER_SIZE,
|
||||
"r"
|
||||
);
|
||||
|
||||
file_read
|
||||
(
|
||||
SHADER_PATHS[i].fragment,
|
||||
(void*)shaderData[i].fragment,
|
||||
SHADER_BUFFER_SIZE,
|
||||
"r"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
resource_shader_init(Resources* self, ShaderType type)
|
||||
{
|
||||
if
|
||||
(
|
||||
!shader_init
|
||||
(
|
||||
&self->shaders[type],
|
||||
shaderData[type].vertex,
|
||||
shaderData[type].fragment
|
||||
)
|
||||
)
|
||||
{
|
||||
printf(STRING_RESOURCE_SHADER_ERROR, SHADER_PATHS[type].vertex, SHADER_PATHS[type].fragment);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(STRING_RESOURCE_SHADER_INIT, SHADER_PATHS[type].vertex, SHADER_PATHS[type].fragment);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
resource_shader_free(Resources* self, ShaderType type)
|
||||
{
|
||||
if (self->shaders[type].isInit)
|
||||
{
|
||||
shader_free(&self->shaders[type]);
|
||||
printf(STRING_RESOURCE_SHADER_FREE, SHADER_PATHS[type].vertex, SHADER_PATHS[type].fragment);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
resource_shader_state_init(Resources* self, const ShaderType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_shader_init(self, types[i]);
|
||||
}
|
||||
|
||||
void
|
||||
resource_shader_state_free(Resources* self, const ShaderType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_shader_free(self, types[i]);
|
||||
}
|
15
src/game/resource/resource_shader.h
Normal file
15
src/game/resource/resource_shader.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCE_COMMON.h"
|
||||
|
||||
#define SHADER_BUFFER_SIZE 2048
|
||||
|
||||
#define STRING_RESOURCE_SHADER_ERROR "[ERROR] Unable to initialize shader resource: %s & %s\n"
|
||||
#define STRING_RESOURCE_SHADER_FREE "[INFO] Freed shader resource: %s & %s\n"
|
||||
#define STRING_RESOURCE_SHADER_INIT "[INFO] Initialized shader resource: %s & %s\n"
|
||||
|
||||
void resource_shader_free(Resources* self, ShaderType type);
|
||||
bool resource_shader_init(Resources* self, ShaderType type);
|
||||
void resource_shader_read(Resources* self);
|
||||
void resource_shader_state_free(Resources* self, const ShaderType* types, u32 count);
|
||||
void resource_shader_state_init(Resources* self, const ShaderType* types, u32 count);
|
44
src/game/resource/resource_sound.c
Normal file
44
src/game/resource/resource_sound.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "resource_sound.h"
|
||||
|
||||
/* Initializes sound resource. */
|
||||
bool
|
||||
resource_sound_init(Resources* self, SoundType type)
|
||||
{
|
||||
if (!sound_init(&self->sounds[type], SOUND_PATHS[type]))
|
||||
{
|
||||
printf(STRING_RESOURCE_SOUND_ERROR, SOUND_PATHS[type]);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(STRING_RESOURCE_SOUND_INIT, SOUND_PATHS[type]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Frees sound resources. */
|
||||
void
|
||||
resource_sound_free(Resources* self, SoundType type)
|
||||
{
|
||||
if (self->sounds[type].isInit)
|
||||
{
|
||||
sound_free(&self->sounds[type]);
|
||||
|
||||
printf(STRING_RESOURCE_SOUND_FREE, SOUND_PATHS[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an array, initializes sound resources. */
|
||||
void
|
||||
resource_sound_state_init(Resources* self, const SoundType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_sound_init(self, types[i]);
|
||||
}
|
||||
|
||||
/* Frees sound resources. */
|
||||
void
|
||||
resource_sound_state_free(Resources* self, const SoundType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_sound_free(self, types[i]);
|
||||
}
|
12
src/game/resource/resource_sound.h
Normal file
12
src/game/resource/resource_sound.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCE_COMMON.h"
|
||||
|
||||
#define STRING_RESOURCE_SOUND_ERROR "[ERROR] Unable to initialize sound resource: %s\n"
|
||||
#define STRING_RESOURCE_SOUND_FREE "[INFO] Freed sound resource: %s\n"
|
||||
#define STRING_RESOURCE_SOUND_INIT "[INFO] Initialized sound resource: %s\n"
|
||||
|
||||
void resource_sound_state_free(Resources* self, const SoundType* types, u32 count);
|
||||
void resource_sound_state_init(Resources* self, const SoundType* types, u32 count);
|
||||
void resource_sound_free(Resources* self, SoundType type);
|
||||
bool resource_sound_init(Resources* self, SoundType type);
|
44
src/game/resource/resource_texture.c
Normal file
44
src/game/resource/resource_texture.c
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "resource_texture.h"
|
||||
|
||||
/* Initializes texture resource. */
|
||||
bool
|
||||
resource_texture_init(Resources* self, TextureType type)
|
||||
{
|
||||
if (!texture_from_path_init(&self->textures[type], TEXTURE_PATHS[type]))
|
||||
{
|
||||
printf(STRING_RESOURCE_TEXTURE_ERROR, TEXTURE_PATHS[type]);
|
||||
return false;
|
||||
}
|
||||
|
||||
printf(STRING_RESOURCE_TEXTURE_INIT, TEXTURE_PATHS[type]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Frees texture resources. */
|
||||
void
|
||||
resource_texture_free(Resources* self, TextureType type)
|
||||
{
|
||||
if (self->textures[type].isInit)
|
||||
{
|
||||
texture_free(&self->textures[type]);
|
||||
|
||||
printf(STRING_RESOURCE_TEXTURE_FREE, TEXTURE_PATHS[type]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Given an array, initializes texture resources. */
|
||||
void
|
||||
resource_texture_state_init(Resources* self, const TextureType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_texture_init(self, types[i]);
|
||||
}
|
||||
|
||||
/* Frees texture resources. */
|
||||
void
|
||||
resource_texture_state_free(Resources* self, const TextureType* types, u32 count)
|
||||
{
|
||||
for (s32 i = 0; i < (s32)count; i++)
|
||||
resource_texture_free(self, types[i]);
|
||||
}
|
12
src/game/resource/resource_texture.h
Normal file
12
src/game/resource/resource_texture.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include "RESOURCE_COMMON.h"
|
||||
|
||||
#define STRING_RESOURCE_TEXTURE_ERROR "[ERROR] Unable to initialize texture resource: %s\n"
|
||||
#define STRING_RESOURCE_TEXTURE_FREE "[INFO] Freed texture resource: %s\n"
|
||||
#define STRING_RESOURCE_TEXTURE_INIT "[INFO] Initialized texture resource: %s\n"
|
||||
|
||||
void resource_texture_state_free(Resources* self, const TextureType* types, u32 count);
|
||||
void resource_texture_state_init(Resources* self, const TextureType* types, u32 count);
|
||||
void resource_texture_free(Resources* self, TextureType type);
|
||||
bool resource_texture_init(Resources* self, TextureType type);
|
26
src/game/state/STATE_COMMON.h
Normal file
26
src/game/state/STATE_COMMON.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include "gameplay/gameplay.h"
|
||||
#include "title/title.h"
|
||||
|
||||
#include "../resource/resource_texture.h"
|
||||
|
||||
#define STATE_COUNT STATE_TITLE + 1
|
||||
typedef enum StateType
|
||||
{
|
||||
STATE_GAMEPLAY,
|
||||
STATE_TITLE
|
||||
} StateType;
|
||||
|
||||
typedef struct State
|
||||
{
|
||||
ECS* ecs;
|
||||
StateType type;
|
||||
StateType setType;
|
||||
bool isChanging;
|
||||
union
|
||||
{
|
||||
Gameplay gameplay;
|
||||
Title title;
|
||||
} states;
|
||||
} State;
|
11
src/game/state/gameplay/GAMEPLAY_COMMON.h
Normal file
11
src/game/state/gameplay/GAMEPLAY_COMMON.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs/entity/ui/entity_cursor.h"
|
||||
#include "../../ecs/entity/visual/entity_sprite.h"
|
||||
#include "../../ecs/entity/visual/entity_text.h"
|
||||
|
||||
typedef struct Gameplay
|
||||
{
|
||||
ECS* ecs;
|
||||
EntityID sprite;
|
||||
} Gameplay;
|
41
src/game/state/gameplay/gameplay.c
Normal file
41
src/game/state/gameplay/gameplay.c
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "gameplay.h"
|
||||
|
||||
const vec2 TEST_SIZE = {128.0f, 128.0f};
|
||||
const vec3 TEST_POSITION = {64.0f, 64.0f, 0.1f};
|
||||
const vec3 TEXT_POSITION = {300.0f, 300.0f, 0.0f};
|
||||
|
||||
static void _gameplay_entity_init(Gameplay* self);
|
||||
|
||||
static void
|
||||
_gameplay_entity_init(Gameplay* self)
|
||||
{
|
||||
entity_cursor_add(self->ecs);
|
||||
|
||||
entity_text_add
|
||||
(
|
||||
self->ecs,
|
||||
&self->ecs->resources->fonts[FONT_TEST],
|
||||
RENDERER_BUFFER_UI,
|
||||
"Gaming",
|
||||
TEXT_POSITION,
|
||||
OPAQUE,
|
||||
strlen("Gaming"),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
gameplay_init(Gameplay* self, ECS* ecs)
|
||||
{
|
||||
memset(self, '\0', sizeof(Gameplay));
|
||||
|
||||
self->ecs = ecs;
|
||||
|
||||
_gameplay_entity_init(self);
|
||||
}
|
||||
|
||||
void
|
||||
gameplay_tick(Gameplay* self)
|
||||
{
|
||||
|
||||
}
|
40
src/game/state/gameplay/gameplay.h
Normal file
40
src/game/state/gameplay/gameplay.h
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "GAMEPLAY_COMMON.h"
|
||||
|
||||
#define GAMEPLAY_TEXTURE_COUNT 3
|
||||
static const TextureType GAMEPLAY_TEXTURES[GAMEPLAY_TEXTURE_COUNT] =
|
||||
{
|
||||
TEXTURE_TEST,
|
||||
TEXTURE_TEST2,
|
||||
TEXTURE_CURSOR
|
||||
};
|
||||
|
||||
#define GAMEPLAY_FONT_COUNT 1
|
||||
static const FontType GAMEPLAY_FONTS[GAMEPLAY_FONT_COUNT] =
|
||||
{
|
||||
FONT_TEST
|
||||
};
|
||||
|
||||
#define GAMEPLAY_SOUND_COUNT 1
|
||||
static const SoundType GAMEPLAY_SOUNDS[GAMEPLAY_SOUND_COUNT] =
|
||||
{
|
||||
SOUND_TEST
|
||||
};
|
||||
|
||||
#define GAMEPLAY_MUSIC_COUNT 1
|
||||
static const MusicType GAMEPLAY_MUSIC[GAMEPLAY_MUSIC_COUNT] =
|
||||
{
|
||||
MUSIC_TEST
|
||||
};
|
||||
|
||||
#define GAMEPLAY_SHADER_COUNT 3
|
||||
static const ShaderType GAMEPLAY_SHADERS[GAMEPLAY_SHADER_COUNT] =
|
||||
{
|
||||
SHADER_TEXTURE_QUAD,
|
||||
SHADER_COLORED_TEXTURE_QUAD,
|
||||
SHADER_POSTPROCESS_TEXTURE_QUAD
|
||||
};
|
||||
|
||||
void gameplay_init(Gameplay* self, ECS* ecs);
|
||||
void gameplay_tick(Gameplay* self);
|
151
src/game/state/state.c
Normal file
151
src/game/state/state.c
Normal file
@@ -0,0 +1,151 @@
|
||||
#include "state.h"
|
||||
|
||||
static void _state_set(State* self, StateType type);
|
||||
|
||||
static void
|
||||
_state_set(State* self, StateType type)
|
||||
{
|
||||
self->type = type;
|
||||
|
||||
resource_shader_state_init
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_SHADERS[self->type],
|
||||
STATE_SHADER_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_texture_state_init
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_TEXTURES[self->type],
|
||||
STATE_TEXTURE_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_font_state_init
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_FONTS[self->type],
|
||||
STATE_FONT_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_sound_state_init
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_SOUNDS[self->type],
|
||||
STATE_SOUND_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_music_state_init
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_MUSIC[self->type],
|
||||
STATE_MUSIC_COUNT[self->type]
|
||||
);
|
||||
|
||||
switch (self->type)
|
||||
{
|
||||
case STATE_GAMEPLAY:
|
||||
gameplay_init(&self->states.gameplay, self->ecs);
|
||||
break;
|
||||
case STATE_TITLE:
|
||||
title_init(&self->states.title, self->ecs);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
state_init(State* self, ECS* ecs, StateType type)
|
||||
{
|
||||
memset(self, '\0', sizeof(State));
|
||||
|
||||
self->ecs = ecs;
|
||||
|
||||
_state_set(self, type);
|
||||
}
|
||||
|
||||
void
|
||||
state_free(State* self)
|
||||
{
|
||||
ecs_clear(self->ecs);
|
||||
|
||||
resource_shader_state_free
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_SHADERS[self->type],
|
||||
STATE_SHADER_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_texture_state_free
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_TEXTURES[self->type],
|
||||
STATE_TEXTURE_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_font_state_free
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_FONTS[self->type],
|
||||
STATE_FONT_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_sound_state_free
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_SOUNDS[self->type],
|
||||
STATE_SOUND_COUNT[self->type]
|
||||
);
|
||||
|
||||
resource_music_state_free
|
||||
(
|
||||
self->ecs->resources,
|
||||
STATE_MUSIC[self->type],
|
||||
STATE_MUSIC_COUNT[self->type]
|
||||
);
|
||||
}
|
||||
|
||||
void
|
||||
state_change(State* self, StateType type)
|
||||
{
|
||||
self->setType = type;
|
||||
|
||||
self->isChanging = true;
|
||||
}
|
||||
|
||||
void
|
||||
state_tick(State* self)
|
||||
{
|
||||
if (self->isChanging)
|
||||
{
|
||||
/*
|
||||
ComponentAnimationColorChange* animationColorChange;
|
||||
animationColorChange = ecs_component_get(&self->game->ecs, ECS_COMPONENT_ANIMATION_COLOR_CHANGE, self->fade);
|
||||
|
||||
if (animationColorChange->isDone)
|
||||
{
|
||||
*/
|
||||
self->isChanging = false;
|
||||
state_free(self);
|
||||
|
||||
memset(&self->states, '\0', sizeof(self->states));
|
||||
|
||||
_state_set(self, self->setType);
|
||||
//}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (self->type)
|
||||
{
|
||||
case STATE_GAMEPLAY:
|
||||
gameplay_tick(&self->states.gameplay);
|
||||
break;
|
||||
case STATE_TITLE:
|
||||
title_tick(&self->states.title);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
68
src/game/state/state.h
Normal file
68
src/game/state/state.h
Normal file
@@ -0,0 +1,68 @@
|
||||
#pragma once
|
||||
|
||||
#include "STATE_COMMON.h"
|
||||
|
||||
static const ShaderType* STATE_SHADERS[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_SHADERS,
|
||||
TITLE_SHADERS
|
||||
};
|
||||
|
||||
static const u32 STATE_SHADER_COUNT[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_SHADER_COUNT,
|
||||
TITLE_SHADER_COUNT
|
||||
};
|
||||
|
||||
static const TextureType* STATE_TEXTURES[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_TEXTURES,
|
||||
TITLE_TEXTURES
|
||||
};
|
||||
|
||||
static const u32 STATE_TEXTURE_COUNT[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_TEXTURE_COUNT,
|
||||
TITLE_TEXTURE_COUNT
|
||||
};
|
||||
|
||||
static const FontType* STATE_FONTS[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_FONTS,
|
||||
TITLE_FONTS
|
||||
};
|
||||
|
||||
static const u32 STATE_FONT_COUNT[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_FONT_COUNT,
|
||||
TITLE_FONT_COUNT
|
||||
};
|
||||
|
||||
static const SoundType* STATE_SOUNDS[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_SOUNDS,
|
||||
TITLE_SOUNDS
|
||||
};
|
||||
|
||||
static const u32 STATE_SOUND_COUNT[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_SOUND_COUNT,
|
||||
TITLE_SOUND_COUNT
|
||||
};
|
||||
|
||||
static const MusicType* STATE_MUSIC[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_MUSIC,
|
||||
TITLE_MUSIC
|
||||
};
|
||||
|
||||
static const u32 STATE_MUSIC_COUNT[STATE_COUNT] =
|
||||
{
|
||||
GAMEPLAY_MUSIC_COUNT,
|
||||
TITLE_MUSIC_COUNT
|
||||
};
|
||||
|
||||
void state_change(State* self, StateType type);
|
||||
void state_init(State* self, ECS* ecs, StateType type);
|
||||
void state_free(State* self);
|
||||
void state_tick(State* self);
|
8
src/game/state/title/TITLE_COMMON.h
Normal file
8
src/game/state/title/TITLE_COMMON.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../../ecs/ecs.h"
|
||||
|
||||
typedef struct Title
|
||||
{
|
||||
ECS* ecs;
|
||||
} Title;
|
15
src/game/state/title/title.c
Normal file
15
src/game/state/title/title.c
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "title.h"
|
||||
|
||||
void
|
||||
title_init(Title* self, ECS* ecs)
|
||||
{
|
||||
memset(self, '\0', sizeof(Title));
|
||||
|
||||
self->ecs = ecs;
|
||||
}
|
||||
|
||||
void
|
||||
title_tick(Title* self)
|
||||
{
|
||||
|
||||
}
|
36
src/game/state/title/title.h
Normal file
36
src/game/state/title/title.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#pragma once
|
||||
|
||||
#include "TITLE_COMMON.h"
|
||||
|
||||
#define TITLE_TEXTURE_COUNT 1
|
||||
static const TextureType TITLE_TEXTURES[TITLE_TEXTURE_COUNT] =
|
||||
{
|
||||
TEXTURE_TEST
|
||||
};
|
||||
|
||||
#define TITLE_FONT_COUNT 1
|
||||
static const FontType TITLE_FONTS[TITLE_FONT_COUNT] =
|
||||
{
|
||||
FONT_TEST
|
||||
};
|
||||
|
||||
#define TITLE_SOUND_COUNT 1
|
||||
static const SoundType TITLE_SOUNDS[TITLE_SOUND_COUNT] =
|
||||
{
|
||||
SOUND_TEST
|
||||
};
|
||||
|
||||
#define TITLE_MUSIC_COUNT 1
|
||||
static const MusicType TITLE_MUSIC[TITLE_MUSIC_COUNT] =
|
||||
{
|
||||
MUSIC_TEST
|
||||
};
|
||||
|
||||
#define TITLE_SHADER_COUNT 1
|
||||
static const ShaderType TITLE_SHADERS[TITLE_SHADER_COUNT] =
|
||||
{
|
||||
SHADER_TEXTURE_QUAD
|
||||
};
|
||||
|
||||
void title_init(Title* self, ECS* ecs);
|
||||
void title_tick(Title* self);
|
Reference in New Issue
Block a user