beginning...

This commit is contained in:
2023-08-15 18:04:43 -04:00
parent b9395446a0
commit 5fde8cbb9f
188 changed files with 36209 additions and 21879 deletions

View File

@ -2,15 +2,15 @@
#include "state/STATE_COMMON.h"
#include "ecs/ECS_COMMON.h"
#include "input/INPUT_COMMON.h"
#include "../engine/renderer.h"
#include "../engine/tick.h"
#include "../engine/atlas.h"
#include "../engine/json.h"
#include "../engine/file.h"
#include "../engine/atlas.h"
#include "../engine/json.h"
#include "../engine/renderer.h"
#include "../engine/sdl.h"
#include "../engine/event.h"
#include "../engine/tick.h"
#include "../engine/fullscreen.h"
typedef struct Game
{
@ -18,7 +18,8 @@ typedef struct Game
Resources resources;
Renderer renderer;
Window window;
Event event;
Input input;
Tick tick;
ECS ecs;
bool isFullscreen;
} Game;

View File

@ -2,8 +2,16 @@
#include "../../../COMMON.h"
#define ECS_COMPONENT_COUNT ECS_COMPONENT_SPRITE + 1
#define ECS_COMPONENT_COUNT ECS_COMPONENT_LIFETIME + 1
typedef enum ECSComponentType
{
ECS_COMPONENT_SPRITE
ECS_COMPONENT_PHYSICS,
ECS_COMPONENT_SHOOT,
ECS_COMPONENT_CONTROL_MOVE,
ECS_COMPONENT_CONTROL_SHOOT,
ECS_COMPONENT_HEALTH,
ECS_COMPONENT_AMMO,
ECS_COMPONENT_SPRITE,
ECS_COMPONENT_GAME_OBJECT,
ECS_COMPONENT_LIFETIME
} ECSComponentType;

View File

@ -0,0 +1,17 @@
#include "component_ammo.h"
/* Sets ammo component info. */
void
component_ammo_init(ComponentAmmo* self, u32 ammo)
{
self->ammoMax = ammo;
self->ammo = self->ammoMax;
}
/* Ticks ammo component. If ammo is depleted, marks as out. */
void
component_ammo_tick(ComponentAmmo* self, ECS* ecs)
{
if (self->ammo <= 0)
self->isOut = true;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
typedef struct ComponentAmmo
{
u32 id;
u32 ammoMax;
u32 ammo;
bool isOut;
} ComponentAmmo;
void component_ammo_init(ComponentAmmo* self, u32 ammo);
void component_ammo_tick(ComponentAmmo* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_AMMO_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_ammo_tick,
NULL
}
},
.type = ECS_COMPONENT_AMMO,
.size = sizeof(ComponentAmmo)
};

View File

@ -0,0 +1,130 @@
#include "component_control_move.h"
/* DEPENDENCIES: Physics */
/* Ticks control_move component. */
void
component_control_move_init(ComponentControlMove* self, f32 speed)
{
self->speed = speed;
}
/* Ticks control_move component. */
void
component_control_move_tick(ComponentControlMove* self, ECS* ecs)
{
if
(
input_held(&ecs->game->input, INPUT_LEFT) ||
input_held(&ecs->game->input, INPUT_RIGHT) ||
input_held(&ecs->game->input, INPUT_UP) ||
input_held(&ecs->game->input, INPUT_DOWN)
)
{
ComponentPhysics* physics;
f32 angle;
vec2 velocity;
angle = 0.0f;
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->id);
glm_vec2_zero(velocity);
self->previousDirection = self->direction;
self->direction = DIRECTION_NONE;
velocity[0] = 1.0f;
velocity[1] = 0.0f;
glm_vec2_norm(velocity);
glm_vec2_scale(velocity, self->speed, velocity);
if
(
input_held(&ecs->game->input, INPUT_LEFT) &&
input_held(&ecs->game->input, INPUT_UP)
)
{
angle = PI + PI_FOURTH;
self->direction = DIRECTION_NORTH_WEST;
}
else if
(
input_held(&ecs->game->input, INPUT_RIGHT) &&
input_held(&ecs->game->input, INPUT_UP)
)
{
angle = TAU - PI_FOURTH;
self->direction = DIRECTION_NORTH_EAST;
}
else if
(
input_held(&ecs->game->input, INPUT_DOWN) &&
input_held(&ecs->game->input, INPUT_LEFT)
)
{
angle = PI - PI_FOURTH;
self->direction = DIRECTION_SOUTH_WEST;
}
else if
(
input_held(&ecs->game->input, INPUT_DOWN) &&
input_held(&ecs->game->input, INPUT_RIGHT)
)
{
angle = PI_FOURTH;
self->direction = DIRECTION_SOUTH_EAST;
}
else if
(
input_held(&ecs->game->input, INPUT_LEFT) &&
input_held(&ecs->game->input, INPUT_RIGHT)
)
{
if
(
self->direction =
self->previousDirection == INPUT_LEFT
)
{
self->direction = DIRECTION_
}
}
else if (input_held(&ecs->game->input, INPUT_LEFT))
{
angle = PI;
self->direction = DIRECTION_WEST;
}
else if (input_held(&ecs->game->input, INPUT_RIGHT))
{
angle = 0.0f;
self->direction = DIRECTION_EAST;
}
else if (input_held(&ecs->game->input, INPUT_UP))
{
angle = PI + PI_HALF;
self->direction = DIRECTION_NORTH;
}
else if (input_held(&ecs->game->input, INPUT_DOWN))
{
angle = PI - PI_HALF;
self->direction = DIRECTION_SOUTH;
}
if (self->direction == DIRECITON_NORTH)
{
}
else if (self->direction == DIRECTION
glm_vec2_rotate(velocity, angle, velocity);
physics->velocity[0] += velocity[0];
physics->velocity[1] += velocity[1];
}
}

View File

@ -0,0 +1,35 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
#include "../../input/input.h"
#include "component_physics.h"
typedef struct ComponentControlMove
{
u32 id;
f32 speed;
Direction direction;
Direction oldDirection;
} ComponentControlMove;
void component_control_move_init(ComponentControlMove* self, f32 speed);
void component_control_move_tick(ComponentControlMove* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_CONTROL_MOVE_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_control_move_tick,
NULL
}
},
.type = ECS_COMPONENT_CONTROL_MOVE,
.size = sizeof(ComponentControlMove)
};

View File

@ -0,0 +1,17 @@
#include "component_control_shoot.h"
/* DEPENDENCIES: Shoot */
/* Ticks control_shoot component. */
void
component_control_shoot_tick(ComponentControlShoot* self, ECS* ecs)
{
if (input_press(&ecs->game->input, INPUT_SHOOT))
{
ComponentShoot* shoot;
shoot = ecs_component_get(ecs, ECS_COMPONENT_SHOOT, self->id);
shoot->isFire = true;
}
}

View File

@ -0,0 +1,31 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
#include "../../input/input.h"
#include "component_shoot.h"
typedef struct ComponentControlShoot
{
u32 id;
} ComponentControlShoot;
void component_control_shoot_tick(ComponentControlShoot* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_CONTROL_SHOOT_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_control_shoot_tick,
NULL
}
},
.type = ECS_COMPONENT_CONTROL_SHOOT,
.size = sizeof(ComponentControlShoot)
};

View File

@ -0,0 +1,108 @@
#include "component_game_object.h"
/* DEPENDENCIES: Sprite, Physics */
/* Sets game_object component info. */
/* This assumes a one-frame sprite. */
void
component_game_object_init
(
ComponentGameObject* self,
ECS* ecs,
Texture texture,
ShaderType shader,
OriginType origin,
vec2 size,
vec3 position,
vec4 color,
f32 friction,
f32 velocityMax
)
{
ivec2 atlasSize;
ivec2 frameSize;
frameSize[0] = (s32)texture.size[0];
frameSize[1] = (s32)texture.size[1];
self->angle = 0.0f;
glm_ivec2_one(atlasSize);
component_game_object_atlas_init
(
self,
ecs,
texture,
shader,
origin,
frameSize,
atlasSize,
size,
position,
color,
friction,
velocityMax
);
}
/* Sets game_object component info, with an atlas. */
void
component_game_object_atlas_init
(
ComponentGameObject* self,
ECS* ecs,
Texture texture,
ShaderType shader,
OriginType origin,
ivec2 frameSize,
ivec2 atlasSize,
vec2 size,
vec3 position,
vec4 color,
f32 friction,
f32 velocityMax
)
{
ComponentSprite* sprite;
ComponentPhysics* physics;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->id);
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->id);
component_sprite_atlas_init(sprite, texture, shader, origin, frameSize, atlasSize, size, position, color);
component_physics_init(physics, position, velocityMax, friction);
}
/* Runs on game object add. */
void
component_game_object_add(ComponentGameObject* self, ECS* ecs)
{
ComponentSprite* sprite;
ecs_component_add(ecs, ECS_COMPONENT_PHYSICS, self->id);
sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, self->id);
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->id);
}
/* Runs on game object add. */
void
component_game_object_delete(ComponentGameObject* self, ECS* ecs)
{
ecs_component_delete(ecs, ECS_COMPONENT_SPRITE, self->id);
ecs_component_delete(ecs, ECS_COMPONENT_PHYSICS, self->id);
}
/* Ticks game_object component. */
void
component_game_object_tick(ComponentGameObject* self, ECS* ecs)
{
ComponentSprite* sprite;
ComponentPhysics* physics;
sprite = ecs_component_get(ecs, ECS_COMPONENT_SPRITE, self->id);
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->id);
glm_vec3_copy(physics->position, sprite->position);
}

View File

@ -0,0 +1,70 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
#include "../../input/input.h"
#include "component_sprite.h"
#include "component_physics.h"
typedef void (*EntityGameObjectInit)(ECS*, u32 id, vec3);
typedef struct ComponentGameObject
{
u32 id;
f32 angle;
} ComponentGameObject;
void
component_game_object_init
(
ComponentGameObject* self,
ECS* ecs,
Texture texture,
ShaderType shader,
OriginType origin,
vec2 size,
vec3 position,
vec4 color,
f32 friction,
f32 velocityMax
);
void
component_game_object_atlas_init
(
ComponentGameObject* self,
ECS* ecs,
Texture texture,
ShaderType shader,
OriginType origin,
ivec2 frameSize,
ivec2 atlasSize,
vec2 size,
vec3 position,
vec4 color,
f32 friction,
f32 velocityMax
);
void component_game_object_add(ComponentGameObject* self, ECS* ecs);
void component_game_object_delete(ComponentGameObject* self, ECS* ecs);
void component_game_object_tick(ComponentGameObject* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_GAME_OBJECT_INFO =
{
.system =
{
.functions =
{
(ECSFunction)component_game_object_add,
(ECSFunction)component_game_object_delete,
(ECSFunction)component_game_object_tick,
NULL
}
},
.type = ECS_COMPONENT_GAME_OBJECT,
.size = sizeof(ComponentGameObject)
};

View File

@ -0,0 +1,17 @@
#include "component_health.h"
/* Sets health component info. */
void
component_health_init(ComponentHealth* self, u32 health)
{
self->healthMax = health;
self->health = self->healthMax;
}
/* Ticks health component. If health is depleted, marked dead. */
void
component_health_tick(ComponentHealth* self, ECS* ecs)
{
if (self->health <= 0)
self->isDead = true;
}

View File

@ -0,0 +1,33 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
typedef struct ComponentHealth
{
u32 id;
u32 healthMax;
u32 health;
bool isDead;
} ComponentHealth;
void component_health_init(ComponentHealth* self, u32 health);
void component_health_tick(ComponentHealth* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_HEALTH_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_health_tick,
NULL
}
},
.type = ECS_COMPONENT_HEALTH,
.size = sizeof(ComponentHealth)
};

View File

@ -0,0 +1,19 @@
#include "component_lifetime.h"
/* Sets lifetime component info. */
void
component_lifetime_init(ComponentLifetime* self, u32 lifetime)
{
self->lifetimeMax = lifetime;
self->lifetime = self->lifetimeMax;
}
/* Ticks lifetime component; when it hits 0, poof. */
void
component_lifetime_tick(ComponentLifetime* self, ECS* ecs)
{
self->lifetime--;
if (self->lifetime <= 0)
ecs_entity_delete(ecs, self->id);
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
typedef struct ComponentLifetime
{
u32 id;
u32 lifetimeMax;
u32 lifetime;
} ComponentLifetime;
void component_lifetime_init(ComponentLifetime* self, u32 lifetime);
void component_lifetime_tick(ComponentLifetime* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_LIFETIME_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_lifetime_tick,
NULL
}
},
.type = ECS_COMPONENT_LIFETIME,
.size = sizeof(ComponentLifetime)
};

View File

@ -0,0 +1,30 @@
#include "component_physics.h"
/* Sets physics component info. */
void
component_physics_init
(
ComponentPhysics* self,
vec3 position,
f32 velocityMax,
f32 friction
)
{
glm_vec3_copy(position, self->position);
glm_vec3_zero(self->velocity);
self->friction = friction;
self->velocityMax = velocityMax;
}
/* Ticks physics component. */
void
component_physics_tick(ComponentPhysics* self, ECS* ecs)
{
self->velocity[0] = CLAMP(self->velocity[0], -self->velocityMax, self->velocityMax);
self->velocity[1] = CLAMP(self->velocity[1], -self->velocityMax, self->velocityMax);
self->velocity[2] = CLAMP(self->velocity[2], -self->velocityMax, self->velocityMax);
glm_vec3_add(self->velocity, self->position, self->position);
glm_vec3_scale(self->velocity, self->friction, self->velocity);
}

View File

@ -0,0 +1,40 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
typedef struct ComponentPhysics
{
u32 id;
f32 friction;
f32 velocityMax;
vec3 velocity;
vec3 position;
} ComponentPhysics;
void component_physics_init
(
ComponentPhysics* self,
vec3 position,
f32 velocityMax,
f32 friction
);
void component_physics_tick(ComponentPhysics* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_PHYSICS_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_physics_tick,
NULL
}
},
.type = ECS_COMPONENT_PHYSICS,
.size = sizeof(ComponentPhysics)
};

View File

@ -0,0 +1,43 @@
#include "component_shoot.h"
/* DEPENDENCIES: Physics */
/* Sets shoot component info. */
void
component_shoot_init
(
ComponentShoot* self,
EntityGameObjectInit projectileInit,
f32 speed,
f32 offset
)
{
self->projectileInit = projectileInit;
self->speed = speed;
self->offset = offset;
}
/* Ticks shoot component. */
void
component_shoot_tick(ComponentShoot* self, ECS* ecs)
{
if (self->isFire)
{
//ComponentGameObject* gameObject;
ComponentPhysics* physics;
u32 projectile;
vec3 position;
//vec3 velocity;
//gameObject = ecs_component_get(ecs, ECS_COMPONENT_GAME_OBJECT, self->id);
physics = ecs_component_get(ecs, ECS_COMPONENT_PHYSICS, self->id);
glm_vec3_copy(physics->position, position);
projectile = ecs_entity_add(ecs);
self->projectileInit(ecs, projectile, position);
self->isFire = false;
}
}

View File

@ -0,0 +1,36 @@
#pragma once
#include "../../GAME_COMMON.h"
#include "../ecs_entity.h"
#include "component_game_object.h"
typedef struct ComponentShoot
{
u32 id;
EntityGameObjectInit projectileInit;
f32 offset;
f32 speed;
bool isFire;
} ComponentShoot;
void component_shoot_init(ComponentShoot* self, EntityGameObjectInit projectileInit, f32 speed, f32 offset);
void component_shoot_tick(ComponentShoot* self, ECS* ecs);
static const ECSComponentInfo COMPONENT_SHOOT_INFO =
{
.system =
{
.functions =
{
NULL,
NULL,
(ECSFunction)component_shoot_tick,
NULL
}
},
.type = ECS_COMPONENT_SHOOT,
.size = sizeof(ComponentShoot)
};

View File

@ -16,7 +16,6 @@ component_sprite_rectangle_get(ComponentSprite* self, vec4 rectangle)
rectangle[3] = self->position[1] + size[1];
}
/* Sets sprite component info, additionally given atlas rows/columns. */
void
component_sprite_atlas_init
@ -25,11 +24,11 @@ component_sprite_atlas_init
Texture texture,
ShaderType shader,
OriginType origin,
const ivec2 frameSize,
const ivec2 atlasSize,
const vec2 size,
const vec4 color,
const vec3 position
ivec2 frameSize,
ivec2 atlasSize,
vec2 size,
vec3 position,
vec4 color
)
{
self->shader = shader;
@ -50,9 +49,9 @@ component_sprite_init
Texture texture,
ShaderType shader,
OriginType origin,
const vec2 size,
const vec4 color,
const vec3 position
vec2 size,
vec3 position,
vec4 color
)
{
ivec2 atlasSize;
@ -68,8 +67,8 @@ component_sprite_init
texture.size,
atlasSize,
size,
color,
position
position,
color
);
}
@ -85,8 +84,6 @@ component_sprite_size_get(ComponentSprite* self, vec2 size)
void
component_sprite_add(ComponentSprite* self, ECS* ecs)
{
memset(self, '\0', sizeof(ComponentSprite));
self->scale = COMPONENT_SPRITE_SCALE_DEFAULT;
}

View File

@ -30,11 +30,11 @@ void component_sprite_atlas_init
Texture texture,
ShaderType shader,
OriginType origin,
const ivec2 frameSize,
const ivec2 atlasSize,
const vec2 size,
const vec4 color,
const vec3 position
ivec2 frameSize,
ivec2 atlasSize,
vec2 size,
vec3 position,
vec4 color
);
void
@ -44,9 +44,9 @@ component_sprite_init
Texture texture,
ShaderType shader,
OriginType origin,
const vec2 size,
const vec4 color,
const vec3 position
vec2 size,
vec3 position,
vec4 color
);
void component_sprite_size_get(ComponentSprite* self, vec2 size);

View File

@ -1,14 +1,28 @@
#pragma once
#include "component/component_ammo.h"
#include "component/component_shoot.h"
#include "component/component_control_shoot.h"
#include "component/component_control_move.h"
#include "component/component_game_object.h"
#include "component/component_health.h"
#include "component/component_lifetime.h"
#include "component/component_physics.h"
#include "component/component_sprite.h"
#include "entity/entity_test.h"
#include "ecs_component_list.h"
#include "ecs_component.h"
static const ECSComponentInfo ECS_COMPONENT_INFO[ECS_COMPONENT_COUNT] =
{
COMPONENT_SPRITE_INFO
COMPONENT_PHYSICS_INFO,
COMPONENT_SHOOT_INFO,
COMPONENT_CONTROL_MOVE_INFO,
COMPONENT_CONTROL_SHOOT_INFO,
COMPONENT_HEALTH_INFO,
COMPONENT_AMMO_INFO,
COMPONENT_SPRITE_INFO,
COMPONENT_GAME_OBJECT_INFO,
COMPONENT_LIFETIME_INFO
};
void ecs_tick(ECS* self);

View File

@ -1,5 +1,12 @@
#include "ecs_component.h"
/* Returns a component of type. */
void*
ecs_component_get(ECS* ecs, ECSComponentType type, u32 id)
{
return ecs_component_list_get(&ecs->lists[type], id);
}
/* Adds and returns a new component, executing system's add function. */
void*
ecs_component_add(ECS* ecs, ECSComponentType type, u32 id)
@ -9,14 +16,13 @@ ecs_component_add(ECS* ecs, ECSComponentType type, u32 id)
component = vector_push(&ecs->lists[type].components, NULL);
memcpy(component, (void*)&id, sizeof(u32));
add = ecs->lists[type].system.functions[ECS_FUNCTION_ADD];
if (add)
add(component, ecs);
/* all components have id as their first member so this is ok */
memcpy(component, (void*)&id, sizeof(u32));
return component;
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "ECS_COMMON.h"
#include "ecs_component_list.h"
void* ecs_component_add(ECS* ecs, ECSComponentType type, u32 id);
void ecs_component_delete(ECS* ecs, ECSComponentType type, u32 id);
void* ecs_component_add(ECS* ecs, ECSComponentType type, u32 id);
void* ecs_component_get(ECS* ecs, ECSComponentType type, u32 id);

View File

@ -22,8 +22,35 @@ ecs_component_list_function(ECSComponentList* self, ECSFunctionType type)
if (!function)
return;
for (s32 i = 0; i < (s32)self->components.count; i++)
function(vector_get(&self->components, i), self->ecs);
{
void* component;
component = vector_get(&self->components, i);
function(component, self->ecs);
}
}
/* Returns a component within the component list, given an id. */
void*
ecs_component_list_get(ECSComponentList* self, u32 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;
}
/* Clears all elements in a component list. */

View File

@ -2,6 +2,7 @@
#include "ECS_COMMON.h"
void* ecs_component_list_get(ECSComponentList* self, u32 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);

View File

@ -4,9 +4,13 @@
u32
ecs_entity_add(ECS* self)
{
u32 id;
id = self->nextID;
self->nextID++;
return self->nextID;
return id;
}
/* Removes all components associated with an entity. */

View File

@ -1,21 +0,0 @@
#include "entity_test.h"
/* Initializes a test entity. */
void
entity_test_init(ECS* ecs, u32 id)
{
ComponentSprite* sprite;
sprite = ecs_component_add(ecs, ECS_COMPONENT_SPRITE, id);
component_sprite_init
(
sprite,
ecs->game->resources.textures[TEXTURE_TEST],
SHADER_TEXTURE_QUAD,
ORIGIN_CENTER,
(f32*)TEST_SIZE,
COLOR_OPAQUE,
(f32*)TEST_POSITION
);
}

View File

@ -1,9 +0,0 @@
#pragma once
#include "../ecs_component.h"
#include "../component/component_sprite.h"
static const vec2 TEST_SIZE = {50.0f, 50.0f};
static const vec3 TEST_POSITION = {50.0f, 50.0f, 0.0f};
void entity_test_init(ECS* ecs, u32 id);

View File

@ -0,0 +1,40 @@
#include "entity_player.h"
/* Initializes a player entity. */
void
entity_player_init(ECS* ecs, u32 id, vec3 position)
{
ComponentGameObject* gameObject;
ComponentControlMove* controlMove;
ComponentShoot* shoot;
gameObject = ecs_component_add(ecs, ECS_COMPONENT_GAME_OBJECT, id);
controlMove = ecs_component_add(ecs, ECS_COMPONENT_CONTROL_MOVE, id);
shoot = ecs_component_add(ecs, ECS_COMPONENT_SHOOT, id);
ecs_component_add(ecs, ECS_COMPONENT_CONTROL_SHOOT, id);
component_game_object_init
(
gameObject,
ecs,
ecs->game->resources.textures[TEXTURE_PLAYER],
SHADER_TEXTURE_QUAD,
ORIGIN_CENTER,
(f32*)PLAYER_SIZE,
position,
(f32*)COLOR_OPAQUE,
PLAYER_FRICTION,
PLAYER_VELOCITY_MAX
);
component_control_move_init(controlMove, PLAYER_SPEED);
component_shoot_init
(
shoot,
(EntityGameObjectInit)entity_snake_init,
PLAYER_SHOOT_SPEED,
PLAYER_SHOOT_OFFSET
);
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "../../ecs_component.h"
#include "../../component/component_game_object.h"
#include "../../component/component_control_move.h"
#include "../../component/component_control_shoot.h"
#include "../../component/component_shoot.h"
#include "../../component/component_lifetime.h"
#include "entity_snake.h"
#define PLAYER_SPEED 0.85
#define PLAYER_FRICTION 0.9
#define PLAYER_VELOCITY_MAX 6
#define PLAYER_SHOOT_SPEED 5
#define PLAYER_SHOOT_OFFSET 32
static const vec2 PLAYER_SIZE = {50.0f, 100.0f};
void entity_player_init(ECS* ecs, u32 id, vec3 position);

View File

@ -0,0 +1,24 @@
#include "entity_snake.h"
/* Initializes a snake entity. */
void
entity_snake_init(ECS* ecs, u32 id, vec3 position)
{
ComponentGameObject* gameObject;
gameObject = ecs_component_add(ecs, ECS_COMPONENT_GAME_OBJECT, id);
component_game_object_init
(
gameObject,
ecs,
ecs->game->resources.textures[TEXTURE_SNAKE],
SHADER_TEXTURE_QUAD,
ORIGIN_CENTER,
(f32*)SNAKE_SIZE,
position,
(f32*)COLOR_OPAQUE,
SNAKE_FRICTION,
SNAKE_VELOCITY_MAX
);
}

View File

@ -0,0 +1,11 @@
#pragma once
#include "../../ecs_component.h"
#include "../../component/component_game_object.h"
#define SNAKE_SPEED 1
#define SNAKE_FRICTION 1
#define SNAKE_VELOCITY_MAX 50
static const vec2 SNAKE_SIZE = {25.0f, 25.0f};
void entity_snake_init(ECS* ecs, u32 id, vec3 position);

View File

@ -29,10 +29,30 @@ _game_tick(Game* self)
{
ecs_tick(&self->ecs);
event_update(&self->event);
input_update(&self->input);
if (event_press(&self->event, EVENT_QUIT))
if (event_press(&self->input.event, EVENT_QUIT))
_game_quit(self);
if (self->isFullscreen)
{
if (keyboard_press(&self->input.keyboard, KEYBOARD_KEY_F))
fullscreen_exit(&self->window, &self->renderer);
}
else
{
if (keyboard_press(&self->input.keyboard, KEYBOARD_KEY_F))
fullscreen_set(&self->window, &self->renderer);
}
vec2 position;
vec2 mousePosition;
mousePosition[0] = (f32)self->input.mouse.position[0];
mousePosition[1] = (f32)self->input.mouse.position[1];
renderer_world_position_from_window_position(&self->renderer, mousePosition, position);
}
/* Main game draw function. */
@ -61,12 +81,12 @@ game_init(Game* self)
window_init
(
&self->window,
WINDOW_TITLE,
STRING_WINDOW_TITLE,
(s32*)WINDOW_SIZE,
WINDOW_FLAGS
);
renderer_init(&self->renderer, &self->window, CAMERA_ORTHOGRAPHIC);
renderer_init(&self->renderer, &self->window, CAMERA_ORTHOGRAPHIC, WORLD_SIZE);
renderer_clear_color_set(&self->renderer, (f32*)RENDERER_CLEAR_COLOR);
ecs_init(&self->ecs, self);

View File

@ -2,10 +2,10 @@
#include "state/state.h"
#define WINDOW_TITLE "Calamity Cobra in 'A Sweeter Reprise'"
#define WINDOW_FLAGS SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE
static const ivec2 WINDOW_SIZE = {1280, 720};
static const vec2 WORLD_SIZE = {1980.0f, 1080.0f};
static const vec4 RENDERER_CLEAR_COLOR = {0.0f, 0.0f, 0.0f, 1.0f};
void game_init(Game* game);

View File

@ -0,0 +1,40 @@
#pragma once
#include "../../engine/event.h"
#include "../../engine/keyboard.h"
#include "../../engine/mouse.h"
#define INPUT_COUNT INPUT_RECALL + 1
typedef enum InputType
{
INPUT_LEFT,
INPUT_RIGHT,
INPUT_UP,
INPUT_DOWN,
INPUT_SHOOT,
INPUT_SWING,
INPUT_REDIRECT,
INPUT_LOCK,
INPUT_RECALL,
} InputType;
typedef struct KeyboardInputEntry
{
KeyboardKeyType* types;
u32 count;
} KeyboardInputEntry;
typedef struct MouseInputEntry
{
MouseButtonType* types;
u32 count;
} MouseInputEntry;
typedef struct Input
{
Keyboard keyboard;
Mouse mouse;
Event event;
bool current[INPUT_COUNT];
bool previous[INPUT_COUNT];
} Input;

70
src/game/input/input.c Normal file
View File

@ -0,0 +1,70 @@
#include "input.h"
/* Initializes input. */
void
input_init(Input* self)
{
memset(self, '\0', sizeof(Input));
}
/* Updates input struct. */
void
input_update(Input* self)
{
memcpy(&self->previous, &self->current, sizeof(bool) * INPUT_COUNT);
memset(&self->current, '\0', sizeof(bool) * INPUT_COUNT);
keyboard_update(&self->keyboard);
mouse_update(&self->mouse);
event_update(&self->event);
for (s32 i = 0; i < INPUT_COUNT; i++)
{
KeyboardInputEntry keyboardEntry;
MouseInputEntry mouseEntry;
keyboardEntry = INPUT_KEYBOARD_ENTRIES[i];
mouseEntry = INPUT_MOUSE_ENTRIES[i];
for (s32 j = 0; j < (s32)keyboardEntry.count; j++)
{
KeyboardKeyType keyboardKey;
keyboardKey = keyboardEntry.types[j];
if (self->keyboard.current[keyboardKey])
self->current[i] = true;
}
for (s32 j = 0; j < (s32)mouseEntry.count; j++)
{
MouseButtonType mouseButton;
mouseButton = mouseEntry.types[j];
if (self->mouse.current[mouseButton])
self->current[i] = true;
}
}
}
/* Is the given key pressed? */
bool
input_press(Input* self, InputType type)
{
return (self->current[type] && !self->previous[type]);
}
/* Is the given key held? */
bool
input_held(Input* self, InputType type)
{
return (self->current[type] && self->previous[type]);
}
/* Is the given key released? */
bool
input_release(Input* self, InputType type)
{
return (!self->current[type] && self->previous[type]);
}

222
src/game/input/input.h Normal file
View File

@ -0,0 +1,222 @@
#pragma once
#include "INPUT_COMMON.h"
/* TODO: button remapping */
#define INPUT_LEFT_KEY_COUNT 2
static const KeyboardKeyType INPUT_LEFT_KEYS[INPUT_LEFT_KEY_COUNT] =
{
KEYBOARD_KEY_LEFT,
KEYBOARD_KEY_A
};
static const KeyboardInputEntry INPUT_KEYBOARD_LEFT_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_LEFT_KEYS,
.count = INPUT_LEFT_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_LEFT_ENTRY =
{
.types = NULL,
.count = 0
};
#define INPUT_RIGHT_KEY_COUNT 2
static const KeyboardKeyType INPUT_RIGHT_KEYS[INPUT_RIGHT_KEY_COUNT] =
{
KEYBOARD_KEY_RIGHT,
KEYBOARD_KEY_D
};
static const KeyboardInputEntry INPUT_KEYBOARD_RIGHT_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_RIGHT_KEYS,
.count = INPUT_RIGHT_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_RIGHT_ENTRY =
{
.types = NULL,
.count = 0
};
#define INPUT_UP_KEY_COUNT 2
static const KeyboardKeyType INPUT_UP_KEYS[INPUT_UP_KEY_COUNT] =
{
KEYBOARD_KEY_UP,
KEYBOARD_KEY_W
};
static const KeyboardInputEntry INPUT_KEYBOARD_UP_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_UP_KEYS,
.count = INPUT_UP_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_UP_ENTRY =
{
.types = NULL,
.count = 0
};
#define INPUT_DOWN_KEY_COUNT 2
static const KeyboardKeyType INPUT_DOWN_KEYS[INPUT_DOWN_KEY_COUNT] =
{
KEYBOARD_KEY_DOWN,
KEYBOARD_KEY_S
};
static const KeyboardInputEntry INPUT_KEYBOARD_DOWN_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_DOWN_KEYS,
.count = INPUT_DOWN_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_DOWN_ENTRY =
{
.types = NULL,
.count = 0
};
#define INPUT_SHOOT_KEY_COUNT 1
#define INPUT_SHOOT_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_SHOOT_KEYS[INPUT_SHOOT_KEY_COUNT] =
{
KEYBOARD_KEY_SPACE,
};
static const KeyboardInputEntry INPUT_KEYBOARD_SHOOT_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_SHOOT_KEYS,
.count = INPUT_SHOOT_KEY_COUNT
};
static const MouseButtonType INPUT_SHOOT_MOUSE_BUTTONS[INPUT_SHOOT_MOUSE_BUTTON_COUNT] =
{
MOUSE_BUTTON_LEFT
};
static const MouseInputEntry INPUT_MOUSE_SHOOT_ENTRY =
{
.types = (MouseButtonType*)INPUT_SHOOT_MOUSE_BUTTONS,
.count = INPUT_SHOOT_MOUSE_BUTTON_COUNT
};
#define INPUT_SWING_KEY_COUNT 1
static const KeyboardKeyType INPUT_SWING_KEYS[INPUT_SWING_KEY_COUNT] =
{
KEYBOARD_KEY_E,
};
static const KeyboardInputEntry INPUT_KEYBOARD_SWING_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_SWING_KEYS,
.count = INPUT_SWING_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_SWING_ENTRY =
{
.types = NULL,
.count = 0
};
#define INPUT_REDIRECT_KEY_COUNT 1
#define INPUT_REDIRECT_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_REDIRECT_KEYS[INPUT_REDIRECT_KEY_COUNT] =
{
KEYBOARD_KEY_R,
};
static const KeyboardInputEntry INPUT_KEYBOARD_REDIRECT_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_REDIRECT_KEYS,
.count = INPUT_REDIRECT_KEY_COUNT
};
static const MouseButtonType INPUT_REDIRECT_MOUSE_BUTTONS[INPUT_REDIRECT_MOUSE_BUTTON_COUNT] =
{
MOUSE_BUTTON_RIGHT
};
static const MouseInputEntry INPUT_MOUSE_REDIRECT_ENTRY =
{
.types = (MouseButtonType*)INPUT_REDIRECT_MOUSE_BUTTONS,
.count = INPUT_REDIRECT_MOUSE_BUTTON_COUNT
};
#define INPUT_LOCK_KEY_COUNT 1
#define INPUT_LOCK_MOUSE_BUTTON_COUNT 1
static const KeyboardKeyType INPUT_LOCK_KEYS[INPUT_LOCK_KEY_COUNT] =
{
KEYBOARD_KEY_Q,
};
static const KeyboardInputEntry INPUT_KEYBOARD_LOCK_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_LOCK_KEYS,
.count = INPUT_LOCK_KEY_COUNT
};
static const MouseButtonType INPUT_LOCK_MOUSE_BUTTONS[INPUT_LOCK_MOUSE_BUTTON_COUNT] =
{
MOUSE_BUTTON_MIDDLE
};
static const MouseInputEntry INPUT_MOUSE_LOCK_ENTRY =
{
.types = (MouseButtonType*)INPUT_LOCK_MOUSE_BUTTONS,
.count = INPUT_LOCK_MOUSE_BUTTON_COUNT
};
#define INPUT_RECALL_KEY_COUNT 2
static const KeyboardKeyType INPUT_RECALL_KEYS[INPUT_RECALL_KEY_COUNT] =
{
KEYBOARD_KEY_LSHIFT,
KEYBOARD_KEY_RSHIFT
};
static const KeyboardInputEntry INPUT_KEYBOARD_RECALL_ENTRY =
{
.types = (KeyboardKeyType*)INPUT_RECALL_KEYS,
.count = INPUT_RECALL_KEY_COUNT
};
static const MouseInputEntry INPUT_MOUSE_RECALL_ENTRY =
{
.types = NULL,
.count = 0
};
static const KeyboardInputEntry INPUT_KEYBOARD_ENTRIES[INPUT_COUNT] =
{
INPUT_KEYBOARD_LEFT_ENTRY,
INPUT_KEYBOARD_RIGHT_ENTRY,
INPUT_KEYBOARD_UP_ENTRY,
INPUT_KEYBOARD_DOWN_ENTRY,
INPUT_KEYBOARD_SHOOT_ENTRY,
INPUT_KEYBOARD_SWING_ENTRY,
INPUT_KEYBOARD_REDIRECT_ENTRY,
INPUT_KEYBOARD_LOCK_ENTRY,
INPUT_KEYBOARD_RECALL_ENTRY,
};
static const MouseInputEntry INPUT_MOUSE_ENTRIES[INPUT_COUNT] =
{
INPUT_MOUSE_LEFT_ENTRY,
INPUT_MOUSE_RIGHT_ENTRY,
INPUT_MOUSE_UP_ENTRY,
INPUT_MOUSE_DOWN_ENTRY,
INPUT_MOUSE_SHOOT_ENTRY,
INPUT_MOUSE_SWING_ENTRY,
INPUT_MOUSE_REDIRECT_ENTRY,
INPUT_MOUSE_LOCK_ENTRY,
INPUT_MOUSE_RECALL_ENTRY,
};
void input_init(Input* self);
void input_update(Input* self);
bool input_press(Input* self, InputType type);
bool input_held(Input* self, InputType type);
bool input_release(Input* self, InputType type);

View File

@ -28,13 +28,9 @@ texture_quad_draw(Renderer* renderer, Atlas* atlas, Shader* shader, mat4 model,
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
camera_view_get(&renderer->camera, view);
camera_projection_get(&renderer->camera, projection);
model[3][0] = 25.0f;
model[3][1] = 25.0f;
vao_bind(&renderer->vao);
vbo_bind(&renderer->vbo);

View File

@ -1,26 +0,0 @@
#include "triangle.h"
/* Draws a triangle. */
void
triangle_draw(Renderer* renderer, Shader* shader)
{
f32 vertices[] = {
-0.5f, -0.5f, 0.0f,
0.5f, -0.5f, 0.0f,
0.0f, 0.5f, 0.0f
};
vao_bind(&renderer->vao);
vbo_bind(&renderer->vbo);
renderer->vbo.isDynamic = false;
vbo_buffer(&renderer->vbo, sizeof(vertices), vertices);
vertex_attribute_set(0, 3, GL_FLOAT, 3 * sizeof(f32), 0);
renderer_shader_use(renderer, shader);
glDrawArrays(GL_TRIANGLES, 0, 3);
vao_unbind();
}

View File

@ -1,5 +0,0 @@
#pragma once
#include "RENDER_COMMON.h"
void triangle_draw(Renderer* renderer, Shader* shader);

View File

@ -4,11 +4,10 @@
#include "../../engine/shader.h"
#include "../../engine/texture.h"
#define SHADER_COUNT SHADER_TRIANGLE + 1
#define SHADER_COUNT SHADER_TEXTURE_QUAD + 1
typedef enum ShaderType
{
SHADER_TEXTURE_QUAD,
SHADER_TRIANGLE
SHADER_TEXTURE_QUAD
} ShaderType;
typedef struct ShaderPaths
@ -22,23 +21,20 @@ static const ShaderPaths SHADER_PATHS[SHADER_COUNT] =
{
.vertex = "res/shader/texture_quad.vs",
.fragment = "res/shader/texture_quad.fs"
},
{
.vertex = "res/shader/triangle.vs",
.fragment = "res/shader/triangle.fs"
},
}
};
#define TEXTURE_COUNT TEXTURE_TEST + 1
#define TEXTURE_COUNT TEXTURE_SNAKE + 1
typedef enum TextureType
{
TEXTURE_TEST
TEXTURE_PLAYER,
TEXTURE_SNAKE
} TextureType;
static const char* TEXTURE_PATHS[TEXTURE_COUNT] =
{
"res/gfx/test.png"
"res/gfx/player.png",
"res/gfx/snake.png"
};
typedef struct Resources

View File

@ -8,6 +8,6 @@ typedef struct State State;
typedef struct Play
{
State* state;
u32 testID;
u32 player;
} Play;

View File

@ -8,7 +8,12 @@ play_init(Play* self, State* state)
self->state = state;
self->testID = ecs_entity_add(&self->state->game->ecs);
self->player = ecs_entity_add(&self->state->game->ecs);
entity_test_init(&self->state->game->ecs, self->testID);
entity_player_init
(
&self->state->game->ecs,
self->player,
(f32*)PLAY_PLAYER_POSITION
);
}

View File

@ -4,18 +4,21 @@
#include "../../ecs/ecs.h"
#define PLAY_SHADER_COUNT 2
#include "../../ecs/entity/play/entity_player.h"
static const vec3 PLAY_PLAYER_POSITION = {600.0f, 400.0f, 0.0f};
#define PLAY_SHADER_COUNT 1
static const ShaderType PLAY_SHADERS[PLAY_SHADER_COUNT] =
{
SHADER_TEXTURE_QUAD,
SHADER_TRIANGLE
};
#define PLAY_TEXTURE_COUNT 1
#define PLAY_TEXTURE_COUNT 2
static const TextureType PLAY_TEXTURES[PLAY_TEXTURE_COUNT] =
{
TEXTURE_TEST
TEXTURE_PLAYER,
TEXTURE_SNAKE
};
void play_init(Play* play, State* state);