[RELEASE] u22-v04

This version is submitted for U22 final presentation. (squashed 158 commits)
This commit is contained in:
2020-10-09 00:00:00 +00:00
parent 84c3a02b9a
commit 80b3b82332
277 changed files with 12154 additions and 13836 deletions

View File

@@ -1,10 +1,14 @@
add_library(lobullet
base.c
bomb.c
linear.c
misc.c
pool.c
)
target_benum_sources(lobullet
type.h
)
target_crial_sources(lobullet
base.crial
)
target_link_libraries(lobullet
msgpackc

View File

@@ -12,6 +12,7 @@
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
#include "core/locommon/msgpack.h"
#include "core/locommon/position.h"
#include "core/locommon/ticker.h"
#include "core/loentity/bullet.h"
@@ -20,10 +21,20 @@
#include "core/loentity/store.h"
#include "core/loresource/set.h"
#include "core/loshader/bullet.h"
#include "core/loshader/set.h"
#include "./bomb.h"
#include "./linear.h"
#include "./misc.h"
#include "./type.h"
/* generated serializer */
#include "core/lobullet/crial/base.h"
static bool
(*const update_function_vtable_[LOBULLET_TYPE_COUNT])(lobullet_base_t* base) = {
[LOBULLET_TYPE_LINEAR_CIRCLE] = lobullet_linear_circle_update,
[LOBULLET_TYPE_LINEAR_TRIANGLE] = lobullet_linear_triangle_update,
[LOBULLET_TYPE_LINEAR_SQUARE] = lobullet_linear_square_update,
};
static void lobullet_base_delete_(loentity_t* entity) {
assert(entity != NULL);
@@ -32,18 +43,6 @@ static void lobullet_base_delete_(loentity_t* entity) {
if (!base->used) return;
base->used = false;
# define each_(NAME, name) do { \
if (base->type == LOBULLET_TYPE_##NAME) { \
lobullet_##name##_tear_down(base); \
return; \
} \
} while (0)
LOBULLET_TYPE_EACH_(each_);
assert(false);
# undef each_
}
static void lobullet_base_die_(loentity_t* entity) {
@@ -55,18 +54,22 @@ static bool lobullet_base_update_(loentity_t* entity) {
assert(entity != NULL);
lobullet_base_t* base = (typeof(base)) entity;
base->cache = (typeof(base->cache)) {0};
base->super.owner = base->param.owner;
base->super.velocity = vec2(0, 0);
# define each_(NAME, name) do { \
if (base->type == LOBULLET_TYPE_##NAME) { \
return lobullet_##name##_update(base); \
} \
} while (0)
const locommon_position_t oldpos = base->super.super.pos;
LOBULLET_TYPE_EACH_(each_);
return false;
# undef each_
assert(update_function_vtable_[base->param.type] != NULL);
if (!update_function_vtable_[base->param.type](base)) {
return false;
}
if (base->cache.velocity_calc) {
locommon_position_sub(
&base->super.velocity, &base->super.super.pos, &oldpos);
}
return true;
}
static void lobullet_base_draw_(
@@ -80,7 +83,8 @@ static void lobullet_base_draw_(
locommon_position_sub(&p, &base->super.super.pos, basepos);
vec2_addeq(&base->cache.instance.pos, &p);
loshader_bullet_drawer_add_instance(base->drawer, &base->cache.instance);
loshader_bullet_drawer_add_instance(
&base->shaders->drawer.bullet, &base->cache.instance);
}
static void lobullet_base_pack_(
@@ -90,29 +94,8 @@ static void lobullet_base_pack_(
const lobullet_base_t* base = (typeof(base)) entity;
msgpack_pack_map(packer, 4);
mpkutil_pack_str(packer, "subclass");
mpkutil_pack_str(packer, "bullet");
mpkutil_pack_str(packer, "type");
mpkutil_pack_str(packer, lobullet_type_stringify(base->type));
mpkutil_pack_str(packer, "id");
msgpack_pack_uint64(packer, base->super.super.id);
mpkutil_pack_str(packer, "data");
# define each_(NAME, name) do { \
if (base->type == LOBULLET_TYPE_##NAME) { \
lobullet_##name##_pack_data(base, packer); \
return; \
} \
} while (0)
LOBULLET_TYPE_EACH_(each_);
assert(false);
# undef each_
msgpack_pack_map(packer, CRIAL_PROPERTY_COUNT_);
CRIAL_SERIALIZER_;
}
static bool lobullet_base_affect_(
@@ -122,57 +105,31 @@ static bool lobullet_base_affect_(
lobullet_base_t* base = (typeof(base)) bullet;
vec2_t v = vec2(0, 0);
switch (base->cache.knockback.algorithm) {
case LOBULLET_BASE_KNOCKBACK_ALGORITHM_VELOCITY:
v = base->super.velocity;
break;
case LOBULLET_BASE_KNOCKBACK_ALGORITHM_POSITION:
locommon_position_sub(&v, &chara->super.pos, &base->super.super.pos);
break;
}
const float plen = vec2_pow_length(&v);
if (plen != 0) {
vec2_diveq(&v, sqrtf(plen));
vec2_muleq(&v, base->cache.knockback.acceleration);
loentity_character_knockback(chara, &v);
}
locommon_position_sub(&v, &chara->super.pos, &base->super.super.pos);
vec2_muleq(&v, base->cache.knockback);
loentity_character_knockback(chara, &v);
if (base->cache.toxic) {
loentity_character_apply_effect(chara, &base->cache.effect);
loentity_character_apply_effect(chara, &base->param.effect);
}
return base->cache.toxic;
}
void lobullet_base_initialize(
lobullet_base_t* base,
loresource_set_t* res,
loshader_bullet_drawer_t* drawer,
const locommon_ticker_t* ticker,
loentity_store_t* entities) {
lobullet_base_t* base,
loresource_set_t* res,
loshader_set_t* shaders,
const locommon_ticker_t* ticker,
loentity_store_t* entities) {
assert(base != NULL);
assert(res != NULL);
assert(drawer != NULL);
assert(shaders != NULL);
assert(ticker != NULL);
assert(entities != NULL);
*base = (typeof(*base)) {
.super = {
.super = {
.vtable = {
.delete = lobullet_base_delete_,
.die = lobullet_base_die_,
.update = lobullet_base_update_,
.draw = lobullet_base_draw_,
.pack = lobullet_base_pack_,
},
.subclass = LOENTITY_SUBCLASS_BULLET,
},
.vtable = {
.affect = lobullet_base_affect_,
},
},
.res = res,
.drawer = drawer,
.shaders = shaders,
.ticker = ticker,
.entities = entities,
};
@@ -180,12 +137,31 @@ void lobullet_base_initialize(
void lobullet_base_reinitialize(lobullet_base_t* base, loentity_id_t id) {
assert(base != NULL);
assert(!base->used);
base->super.super.id = id;
base->super = (typeof(base->super)) {
.super = {
.vtable = {
.delete = lobullet_base_delete_,
.die = lobullet_base_die_,
.update = lobullet_base_update_,
.draw = lobullet_base_draw_,
.pack = lobullet_base_pack_,
},
.id = id,
.subclass = LOENTITY_SUBCLASS_BULLET,
},
.vtable = {
.affect = lobullet_base_affect_,
},
};
base->param = (typeof(base->param)) {0};
}
void lobullet_base_deinitialize(lobullet_base_t* base) {
assert(base != NULL);
assert(!base->used);
lobullet_base_delete_(&base->super.super);
}
@@ -195,41 +171,13 @@ bool lobullet_base_unpack(lobullet_base_t* base, const msgpack_object* obj) {
lobullet_base_reinitialize(base, 0);
const char* v;
size_t vlen;
const msgpack_object_map* root = mpkutil_get_map(obj);
if (root == NULL) goto FAIL;
# define item_(v) mpkutil_get_map_item_by_str(root, v)
# define streq_(v1, len, v2) \
(strncmp(v1, v2, len) == 0 && v2[len] == 0)
if (!mpkutil_get_str(item_("subclass"), &v, &vlen) ||
!streq_(v, vlen, "bullet")) {
return false;
}
# undef streq_
if (!mpkutil_get_str(item_("type"), &v, &vlen) ||
!lobullet_type_unstringify(&base->type, v, vlen)) {
return false;
}
if (!mpkutil_get_uint64(item_("id"), &base->super.super.id)) {
return false;
}
const msgpack_object* data = item_("data");
# define each_(NAME, name) do { \
if (base->type == LOBULLET_TYPE_##NAME) { \
if (!lobullet_##name##_unpack_data(base, data)) return false; \
} \
} while (0)
LOBULLET_TYPE_EACH_(each_);
# undef each_
# undef item_
CRIAL_DESERIALIZER_;
return true;
FAIL:
lobullet_base_delete_(&base->super.super);
return false;
}

44
core/lobullet/base.crial Normal file
View File

@@ -0,0 +1,44 @@
/* CRIAL
SERIALIZER_BEGIN
mpkutil_pack_str(packer, "$name");
mpkutil_pack_str(packer, $code);
END
DESERIALIZER_BEGIN
const char* v;
size_t vlen;
if (!mpkutil_get_str(
mpkutil_get_map_item_by_str(root, "$name"), &v, &vlen) ||
strncmp(v, $code, vlen) != 0 || $code[vlen] != 0) {
goto FAIL;
}
END
PROPERTY subclass = "bullet"
SERIALIZER_BEGIN
mpkutil_pack_str(packer, "$name");
LOCOMMON_MSGPACK_PACK_ANY(packer, &base->$code);
END
DESERIALIZER_BEGIN
if (!LOCOMMON_MSGPACK_UNPACK_ANY(
mpkutil_get_map_item_by_str(root, "$name"), &base->$code)) {
goto FAIL;
}
END
PROPERTY id = super.super.id
PROPERTY pos = super.super.pos
PROPERTY owner = param.owner
PROPERTY type = param.type
PROPERTY target = param.target
PROPERTY basepos = param.basepos
PROPERTY size = param.size
PROPERTY color = param.color
PROPERTY velocity = param.velocity
PROPERTY acceleration = param.acceleration
PROPERTY angle = param.angle
PROPERTY angular_velocity = param.angular_velocity
PROPERTY quiet = param.quiet
PROPERTY knockback = param.knockback
PROPERTY effect = param.effect
PROPERTY since = param.since
PROPERTY duration = param.duration
*/

View File

@@ -13,54 +13,61 @@
#include "core/loentity/store.h"
#include "core/loresource/set.h"
#include "core/loshader/bullet.h"
#include "core/loshader/set.h"
#include "./misc.h"
#include "./type.h"
typedef enum {
LOBULLET_BASE_KNOCKBACK_ALGORITHM_VELOCITY,
LOBULLET_BASE_KNOCKBACK_ALGORITHM_POSITION,
} lobullet_base_knockback_algorithm_t;
typedef struct {
lobullet_type_t type;
loentity_id_t owner;
loentity_id_t target;
locommon_position_t basepos;
vec2_t size;
vec4_t color;
vec2_t velocity;
vec2_t acceleration;
float angle;
float angular_velocity;
bool quiet;
float knockback;
loeffect_t effect;
uint64_t since;
uint64_t duration;
} lobullet_base_param_t;
typedef struct {
loentity_bullet_t super;
bool used;
/* injected deps */
loresource_set_t* res;
loshader_bullet_drawer_t* drawer;
const locommon_ticker_t* ticker;
loentity_store_t* entities;
loresource_set_t* res;
loshader_set_t* shaders;
const locommon_ticker_t* ticker;
loentity_store_t* entities;
lobullet_base_param_t param;
/* params not to be packed */
struct {
bool toxic;
loeffect_t effect;
/* When toxic is true, apply this effect to characters hit. */
struct {
float acceleration;
lobullet_base_knockback_algorithm_t algorithm;
} knockback;
bool toxic;
float knockback;
bool velocity_calc;
loshader_bullet_drawer_instance_t instance;
/* instance pos is added to draw pos */
} cache;
/* params to be packed (includes id) */
lobullet_type_t type;
# define LOBULLET_BASE_DATA_MAX_SIZE 256
uint8_t data[LOBULLET_BASE_DATA_MAX_SIZE];
/* pack function for the type is used */
} lobullet_base_t;
void
lobullet_base_initialize(
lobullet_base_t* base,
loresource_set_t* res,
loshader_bullet_drawer_t* drawer,
const locommon_ticker_t* ticker,
loentity_store_t* entities
lobullet_base_t* base,
loresource_set_t* res,
loshader_set_t* shaders,
const locommon_ticker_t* ticker,
loentity_store_t* entities
);
void

View File

@@ -1,205 +0,0 @@
#include "./bomb.h"
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "util/coly2d/shape.h"
#include "util/math/algorithm.h"
#include "util/math/constant.h"
#include "util/math/vector.h"
#include "util/mpkutil/pack.h"
#include "core/locommon/msgpack.h"
#include "core/locommon/position.h"
#include "core/locommon/ticker.h"
#include "core/loentity/entity.h"
#include "core/loresource/sound.h"
#include "core/loshader/bullet.h"
#include "./base.h"
#include "./misc.h"
#define LOBULLET_BOMB_PARAM_TO_PACK_EACH_(PROC) do { \
PROC("owner", owner); \
PROC("pos", pos); \
PROC("size", size); \
PROC("angle", angle); \
PROC("color", color); \
PROC("silent", silent); \
PROC("beat", beat); \
PROC("step", step); \
PROC("knockback", knockback); \
PROC("effect", effect); \
PROC("since", since); \
} while (0)
#define LOBULLET_BOMB_PARAM_TO_PACK_COUNT 11
_Static_assert(sizeof(lobullet_bomb_param_t) <= LOBULLET_BASE_DATA_MAX_SIZE);
static bool lobullet_bomb_update_(lobullet_base_t* base) {
assert(base != NULL);
const lobullet_bomb_param_t* p = (typeof(p)) base->data;
base->super.super.pos = p->pos;
base->super.owner = p->owner;
base->super.velocity = vec2(0, 0);
base->super.shape.size = p->size;
base->super.shape.angle = p->angle;
const uint64_t st = (p->step-1) * p->beat;
const uint64_t ed = st + 100;
const uint64_t t = base->ticker->time - p->since;
const uint64_t pt =
(int64_t) t >= base->ticker->delta? t - base->ticker->delta: 0;
if (!p->silent && pt < st && t >= st) {
loresource_sound_play(base->res->sound, "bomb");
}
base->cache.toxic = st <= t && t < ed;
base->cache.effect = p->effect;
return t < p->step*p->beat;
}
bool lobullet_bomb_param_valid(const lobullet_bomb_param_t* param) {
return
param != NULL &&
locommon_position_valid(&param->pos) &&
vec2_valid(&param->size) &&
MATH_FLOAT_VALID(param->angle) &&
vec4_valid(&param->color) &&
MATH_FLOAT_VALID(param->beat) &&
param->step > 0 &&
MATH_FLOAT_VALID(param->knockback);
}
void lobullet_bomb_param_pack(
const lobullet_bomb_param_t* p, msgpack_packer* packer) {
assert(lobullet_bomb_param_valid(p));
assert(packer != NULL);
msgpack_pack_map(packer, LOBULLET_BOMB_PARAM_TO_PACK_COUNT);
# define pack_(name, var) do { \
mpkutil_pack_str(packer, name); \
LOCOMMON_MSGPACK_PACK_ANY(packer, &p->var); \
} while (0)
LOBULLET_BOMB_PARAM_TO_PACK_EACH_(pack_);
# undef pack_
}
bool lobullet_bomb_param_unpack(
lobullet_bomb_param_t* p, const msgpack_object* obj) {
assert(p != NULL);
const msgpack_object_map* root = mpkutil_get_map(obj);
# define item_(v) mpkutil_get_map_item_by_str(root, v)
# define unpack_(name, var) do { \
if (!LOCOMMON_MSGPACK_UNPACK_ANY(item_(name), &p->var)) { \
return false; \
} \
} while (0)
LOBULLET_BOMB_PARAM_TO_PACK_EACH_(unpack_);
return lobullet_bomb_param_valid(p);
# undef unpack_
# undef item_
}
void lobullet_bomb_build(
lobullet_base_t* base,
lobullet_type_t type,
const lobullet_bomb_param_t* param) {
assert(base != NULL);
assert(lobullet_bomb_param_valid(param));
base->type = type;
lobullet_bomb_param_t* p = (typeof(p)) base->data;
*p = *param;
p->since = base->ticker->time;
}
bool lobullet_bomb_square_update(lobullet_base_t* base) {
assert(base != NULL);
if (!lobullet_bomb_update_(base)) return false;
const lobullet_bomb_param_t* p = (typeof(p)) base->data;
/* ---- calculate motion ---- */
const float beats = (base->ticker->time - p->since) / p->beat;
float time = 0;
float angle = p->angle;
float alpha = 1;
if (beats < p->step-1) {
time = beats - (int64_t) beats;
alpha = 1-time;
time = time*time;
time = (1-time)*.05f;
} else {
time = 1 - powf(1-(beats - (int64_t) beats), 2);
angle += time * MATH_PI/4;
time = 1-time;
}
/* ---- apply motion ---- */
base->super.shape.type = COLY2D_SHAPE_TYPE_RECT;
base->super.shape.angle = angle;
base->cache.instance = (loshader_bullet_drawer_instance_t) {
.bullet_id = LOSHADER_BULLET_ID_SQUARE,
.size = p->size,
.theta = angle,
.color = p->color,
.time = time,
};
base->cache.instance.color.w *= alpha;
return true;
}
bool lobullet_bomb_triangle_update(lobullet_base_t* base) {
assert(base != NULL);
if (!lobullet_bomb_update_(base)) return false;
const lobullet_bomb_param_t* p = (typeof(p)) base->data;
/* ---- calculate motion ---- */
const float beats = (base->ticker->time - p->since) / p->beat;
float time = 0;
float alpha = 1;
if (beats < p->step-1) {
time = beats - (int64_t) beats;
alpha = 1-time;
time = time*time;
time = (1-time)*.05f;
} else {
time = 1 - powf(1-(beats - (int64_t) beats), 2);
time = 1-time;
}
/* ---- apply motion ---- */
base->super.shape.type = COLY2D_SHAPE_TYPE_TRIANGLE;
base->cache.instance = (loshader_bullet_drawer_instance_t) {
.bullet_id = LOSHADER_BULLET_ID_TRIANGLE,
.size = p->size,
.theta = base->super.shape.angle,
.color = p->color,
.time = time,
};
base->cache.instance.color.w *= alpha;
return true;
}

View File

@@ -1,82 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
#include "util/math/vector.h"
#include "core/locommon/position.h"
#include "core/loeffect/effect.h"
#include "core/loentity/entity.h"
#include "./base.h"
#include "./misc.h"
typedef struct {
loentity_id_t owner;
locommon_position_t pos;
vec2_t size;
float angle;
vec4_t color;
bool silent;
float beat;
int32_t step;
float knockback;
loeffect_t effect;
uint64_t since; /* set by build function */
} lobullet_bomb_param_t;
bool
lobullet_bomb_param_valid(
const lobullet_bomb_param_t* param /* NULLABLE */
);
void
lobullet_bomb_param_pack(
const lobullet_bomb_param_t* param,
msgpack_packer* packer
);
bool
lobullet_bomb_param_unpack(
lobullet_bomb_param_t* param,
const msgpack_object* obj /* NULLABLE */
);
void
lobullet_bomb_build(
lobullet_base_t* base,
lobullet_type_t type,
const lobullet_bomb_param_t* param
);
bool
lobullet_bomb_square_update(
lobullet_base_t* base
);
#define lobullet_bomb_square_build(base, param) \
lobullet_bomb_build(base, LOBULLET_TYPE_BOMB_SQUARE, param)
#define lobullet_bomb_square_tear_down(base)
#define lobullet_bomb_square_pack_data(base, packer) \
lobullet_bomb_param_pack( \
(const lobullet_bomb_param_t*) base->data, packer)
#define lobullet_bomb_square_unpack_data(base, obj) \
lobullet_bomb_param_unpack( \
(lobullet_bomb_param_t*) base->data, obj)
bool
lobullet_bomb_triangle_update(
lobullet_base_t* base
);
#define lobullet_bomb_triangle_build(base, param) \
lobullet_bomb_build(base, LOBULLET_TYPE_BOMB_TRIANGLE, param)
#define lobullet_bomb_triangle_tear_down(base)
#define lobullet_bomb_triangle_pack_data(base, packer) \
lobullet_bomb_param_pack( \
(const lobullet_bomb_param_t*) base->data, packer)
#define lobullet_bomb_triangle_unpack_data(base, obj) \
lobullet_bomb_param_unpack( \
(lobullet_bomb_param_t*) base->data, obj)

View File

@@ -1,197 +1,100 @@
#include "./linear.h"
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
#include "util/coly2d/shape.h"
#include "util/math/constant.h"
#include "util/math/algorithm.h"
#include "util/math/vector.h"
#include "util/mpkutil/get.h"
#include "util/mpkutil/pack.h"
#include "core/locommon/msgpack.h"
#include "core/locommon/position.h"
#include "core/loeffect/effect.h"
#include "core/loentity/entity.h"
#include "core/loshader/bullet.h"
#include "./base.h"
#include "./misc.h"
#define LOBULLET_LINEAR_PARAM_TO_PACK_EACH_(PROC) do { \
PROC("owner", owner); \
PROC("pos", pos); \
PROC("size", size); \
PROC("velocity", velocity); \
PROC("acceleration", acceleration); \
PROC("color", color); \
PROC("duration", duration); \
PROC("knockback", knockback); \
PROC("effect", effect); \
PROC("since", since); \
} while (0)
#define LOBULLET_LINEAR_PARAM_TO_PACK_COUNT 10
_Static_assert(sizeof(lobullet_linear_param_t) <= LOBULLET_BASE_DATA_MAX_SIZE);
#define FADE_DURATION_ 200
static bool lobullet_linear_update_(lobullet_base_t* base) {
assert(base != NULL);
const lobullet_linear_param_t* p = (typeof(p)) base->data;
const uint64_t t = base->ticker->time - base->param.since;
const float tf = t/1000.f;
const float t = (base->ticker->time - p->since)/1000.f;
base->super.owner = p->owner;
if (t >= base->param.duration) {
return false;
}
const uint64_t rt = base->param.duration - t;
const float alpha = rt < FADE_DURATION_? rt*1.f/FADE_DURATION_: 1;
/* ---- movement ---- */
vec2_t v1;
vec2_mul(&v1, &p->velocity, t);
vec2_mul(&v1, &base->param.velocity, tf);
vec2_t v2;
vec2_mul(&v2, &p->acceleration, t*t/2);
vec2_mul(&v2, &base->param.acceleration, tf*tf/2);
base->super.super.pos = p->pos;
base->super.super.pos = base->param.basepos;
vec2_addeq(&base->super.super.pos.fract, &v1);
vec2_addeq(&base->super.super.pos.fract, &v2);
locommon_position_reduce(&base->super.super.pos);
/* ---- velocity ---- */
vec2_mul(&base->super.velocity, &p->acceleration, t);
vec2_addeq(&base->super.velocity, &p->velocity);
vec2_mul(&base->super.velocity, &base->param.acceleration, tf);
vec2_addeq(&base->super.velocity, &base->param.velocity);
/* ---- angle ---- */
const float theta = vec2_pow_length(&base->super.velocity) != 0?
atan2f(base->super.velocity.y, base->super.velocity.x): 0;
base->super.shape.size = p->size;
base->super.shape.angle = theta;
/* ---- parameters ---- */
const float angle = base->param.angle + base->param.angular_velocity*tf;
base->cache = (typeof(base->cache)) {
.toxic = true,
.knockback = base->param.knockback,
/* ---- parameter update ---- */
base->cache.toxic = true;
base->cache.effect = p->effect;
base->cache.knockback = (typeof(base->cache.knockback)) {
.acceleration = p->knockback,
.algorithm = LOBULLET_BASE_KNOCKBACK_ALGORITHM_VELOCITY,
.instance = {
.size = base->param.size,
.theta = angle,
.color = base->param.color,
.time = alpha,
},
};
return p->since + p->duration > base->ticker->time;
}
bool lobullet_linear_param_valid(const lobullet_linear_param_t* param) {
return
param != NULL &&
locommon_position_valid(&param->pos) &&
vec2_valid(&param->size) &&
vec2_valid(&param->velocity) &&
vec2_valid(&param->acceleration) &&
param->duration > 0;
}
void lobullet_linear_param_pack(
const lobullet_linear_param_t* p, msgpack_packer* packer) {
assert(lobullet_linear_param_valid(p));
assert(packer != NULL);
msgpack_pack_map(packer, LOBULLET_LINEAR_PARAM_TO_PACK_COUNT);
# define pack_(name, var) do { \
mpkutil_pack_str(packer, name); \
LOCOMMON_MSGPACK_PACK_ANY(packer, &p->var); \
} while (0)
LOBULLET_LINEAR_PARAM_TO_PACK_EACH_(pack_);
# undef pack_
}
bool lobullet_linear_param_unpack(
lobullet_linear_param_t* p, const msgpack_object* obj) {
assert(p != NULL);
const msgpack_object_map* root = mpkutil_get_map(obj);
# define item_(v) mpkutil_get_map_item_by_str(root, v)
# define unpack_(name, var) do { \
if (!LOCOMMON_MSGPACK_UNPACK_ANY(item_(name), &p->var)) { \
return false; \
} \
} while (0)
LOBULLET_LINEAR_PARAM_TO_PACK_EACH_(unpack_);
return lobullet_linear_param_valid(p);
# undef unpack_
# undef item_
}
void lobullet_linear_build(
lobullet_base_t* base,
lobullet_type_t type,
const lobullet_linear_param_t* param) {
assert(base != NULL);
assert(lobullet_linear_param_valid(param));
base->type = type;
lobullet_linear_param_t* p = (typeof(p)) base->data;
*p = *param;
p->since = base->ticker->time;
}
bool lobullet_linear_light_update(lobullet_base_t* base) {
assert(base != NULL);
static const uint64_t fadedur = 500;
if (!lobullet_linear_update_(base)) return false;
const lobullet_linear_param_t* p = (typeof(p)) base->data;
/* ---- calculation ---- */
vec2_t size = p->size;
vec2_muleq(&size, 1.2f);
float alpha = 1;
const uint64_t remain = p->duration - (base->ticker->time - p->since);
if (remain <= fadedur) alpha = remain*1.f / fadedur;
/* ---- apply result ---- */
base->super.shape.type = COLY2D_SHAPE_TYPE_ELLIPSE;
base->cache.instance = (loshader_bullet_drawer_instance_t) {
.bullet_id = LOSHADER_BULLET_ID_LIGHT,
.size = size,
.theta = base->super.shape.angle,
.color = p->color,
base->super.shape = (coly2d_shape_t) {
.size = base->param.size,
.angle = angle,
};
base->cache.instance.color.w = alpha;
return true;
}
bool lobullet_linear_circle_update(lobullet_base_t* base) {
assert(base != NULL);
if (!lobullet_linear_update_(base)) return false;
base->cache.instance.bullet_id = LOSHADER_BULLET_ID_LIGHT;
base->super.shape.type = COLY2D_SHAPE_TYPE_ELLIPSE;
return true;
}
bool lobullet_linear_triangle_update(lobullet_base_t* base) {
assert(base != NULL);
if (!lobullet_linear_update_(base)) return false;
base->cache.instance.bullet_id = LOSHADER_BULLET_ID_TRIANGLE;
base->super.shape.type = COLY2D_SHAPE_TYPE_TRIANGLE;
const lobullet_linear_param_t* p = (typeof(p)) base->data;
/* ---- calculation ---- */
vec2_t size = p->size;
size.x *= 1-(1-cos(MATH_PI/3))/2;
size.y *= 1-(1-sin(MATH_PI/3))/2;
/* ---- apply result ---- */
base->super.shape.type = COLY2D_SHAPE_TYPE_TRIANGLE;
base->cache.instance = (loshader_bullet_drawer_instance_t) {
.bullet_id = LOSHADER_BULLET_ID_TRIANGLE,
.size = size,
.theta = base->super.shape.angle,
.color = p->color,
.time = 1,
};
return true;
}
bool lobullet_linear_square_update(lobullet_base_t* base) {
assert(base != NULL);
if (!lobullet_linear_update_(base)) return false;
base->cache.instance.bullet_id = LOSHADER_BULLET_ID_SQUARE;
base->super.shape.type = COLY2D_SHAPE_TYPE_RECT;
return true;
}
void lobullet_linear_build_(
lobullet_base_t* base,
const lobullet_base_param_t* param) {
assert(base != NULL);
assert(param != NULL);
base->super.super.pos = param->basepos;
base->param = *param;
base->param.since = base->ticker->time;
}

View File

@@ -1,81 +1,51 @@
#pragma once
#include <stdbool.h>
#include <stdint.h>
#include <msgpack.h>
#include "util/math/vector.h"
#include "core/locommon/position.h"
#include "core/loeffect/effect.h"
#include "core/loentity/entity.h"
#include "./base.h"
typedef struct {
loentity_id_t owner;
locommon_position_t pos;
vec2_t size;
vec2_t velocity;
vec2_t acceleration;
vec4_t color;
uint64_t duration;
float knockback;
loeffect_t effect;
uint64_t since; /* set by build function */
} lobullet_linear_param_t;
bool
lobullet_linear_param_valid(
const lobullet_linear_param_t* param
);
void
lobullet_linear_param_pack(
const lobullet_linear_param_t* param,
msgpack_packer* packer
);
bool
lobullet_linear_param_unpack(
lobullet_linear_param_t* param,
const msgpack_object* obj /* NULLABLE */
);
void
lobullet_linear_build(
lobullet_base_t* base,
lobullet_type_t type,
const lobullet_linear_param_t* param
);
bool
lobullet_linear_light_update(
lobullet_linear_circle_update(
lobullet_base_t* base
);
#define lobullet_linear_light_build(base, param) \
lobullet_linear_build(base, LOBULLET_TYPE_LINEAR_LIGHT, param)
#define lobullet_linear_light_tear_down(base)
#define lobullet_linear_light_pack_data(base, packer) \
lobullet_linear_param_pack( \
(const lobullet_linear_param_t*) base->data, packer)
#define lobullet_linear_light_unpack_data(base, obj) \
lobullet_linear_param_unpack( \
(lobullet_linear_param_t*) base->data, obj)
bool
lobullet_linear_triangle_update(
lobullet_base_t* base
);
#define lobullet_linear_triangle_build(base, param) \
lobullet_linear_build(base, LOBULLET_TYPE_LINEAR_TRIANGLE, param)
#define lobullet_linear_triangle_tear_down(base)
#define lobullet_linear_triangle_pack_data(base, packer) \
lobullet_linear_param_pack( \
(const lobullet_linear_param_t*) base->data, packer)
#define lobullet_linear_triangle_unpack_data(base, obj) \
lobullet_linear_param_unpack( \
(lobullet_linear_param_t*) base->data, obj)
bool
lobullet_linear_square_update(
lobullet_base_t* base
);
void
lobullet_linear_build_(
lobullet_base_t* base,
const lobullet_base_param_t* param
);
#define lobullet_linear_circle_build(base, ...) \
lobullet_linear_build_( \
base, \
&(lobullet_base_param_t) { \
.type = LOBULLET_TYPE_LINEAR_CIRCLE, \
__VA_ARGS__ \
})
#define lobullet_linear_triangle_build(base, ...) \
lobullet_linear_build_( \
base, \
&(lobullet_base_param_t) { \
.type = LOBULLET_TYPE_LINEAR_TRIANGLE, \
__VA_ARGS__ \
})
#define lobullet_linear_square_build(base, ...) \
lobullet_linear_build_( \
base, \
&(lobullet_base_param_t) { \
.type = LOBULLET_TYPE_LINEAR_SQUARE, \
__VA_ARGS__ \
})

View File

@@ -1,37 +0,0 @@
#include "./misc.h"
#include <assert.h>
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
const char* lobullet_type_stringify(lobullet_type_t type) {
# define each_(NAME, name) do { \
if (type == LOBULLET_TYPE_##NAME) return #name; \
} while (0)
LOBULLET_TYPE_EACH_(each_);
assert(false);
return NULL;
# undef each_
}
bool lobullet_type_unstringify(
lobullet_type_t* type, const char* v, size_t len) {
assert(type != NULL);
assert(v != NULL || len == 0);
# define each_(NAME, name) do { \
if (strncmp(v, #name, len) == 0 && #name[len] == 0) { \
*type = LOBULLET_TYPE_##NAME; \
return true; \
} \
} while (0)
LOBULLET_TYPE_EACH_(each_);
return false;
# undef each_
}

View File

@@ -1,31 +0,0 @@
#pragma once
#include <stdbool.h>
#include <stddef.h>
/* dont forget to update EACH macro */
typedef enum {
LOBULLET_TYPE_LINEAR_LIGHT,
LOBULLET_TYPE_LINEAR_TRIANGLE,
LOBULLET_TYPE_BOMB_SQUARE,
LOBULLET_TYPE_BOMB_TRIANGLE,
} lobullet_type_t;
#define LOBULLET_TYPE_EACH_(PROC) do { \
PROC(LINEAR_LIGHT, linear_light); \
PROC(LINEAR_TRIANGLE, linear_triangle); \
PROC(BOMB_SQUARE, bomb_square); \
PROC(BOMB_TRIANGLE, bomb_triangle); \
} while (0)
const char*
lobullet_type_stringify(
lobullet_type_t type
);
bool
lobullet_type_unstringify(
lobullet_type_t* type,
const char* v,
size_t len
);

View File

@@ -8,43 +8,24 @@
#include "core/locommon/counter.h"
#include "core/locommon/ticker.h"
#include "core/loentity/pool.h"
#include "core/loentity/store.h"
#include "core/loresource/set.h"
#include "core/loshader/bullet.h"
#include "core/loshader/set.h"
#include "./base.h"
struct lobullet_pool_t {
loresource_set_t* res;
loshader_bullet_drawer_t* drawer;
locommon_counter_t* idgen;
const locommon_ticker_t* ticker;
loentity_store_t* entities;
size_t length;
lobullet_base_t items[1];
};
static size_t lobullet_pool_find_unused_item_index_(
const lobullet_pool_t* pool) {
assert(pool != NULL);
for (size_t i = 0; i < pool->length; ++i) {
if (!pool->items[i].used) return i;
}
fprintf(stderr, "bullet pool overflow\n");
abort();
}
LOENTITY_POOL_SOURCE_TEMPLATE(lobullet)
lobullet_pool_t* lobullet_pool_new(
loresource_set_t* res,
loshader_bullet_drawer_t* drawer,
locommon_counter_t* idgen,
const locommon_ticker_t* ticker,
loentity_store_t* entities,
size_t length) {
loresource_set_t* res,
loshader_set_t* shaders,
locommon_counter_t* idgen,
const locommon_ticker_t* ticker,
loentity_store_t* entities,
size_t length) {
assert(res != NULL);
assert(drawer != NULL);
assert(shaders != NULL);
assert(idgen != NULL);
assert(ticker != NULL);
assert(entities != NULL);
@@ -53,52 +34,16 @@ lobullet_pool_t* lobullet_pool_new(
lobullet_pool_t* pool =
memory_new(sizeof(*pool) + (length-1)*sizeof(pool->items[0]));
*pool = (typeof(*pool)) {
.res = res,
.drawer = drawer,
.idgen = idgen,
.ticker = ticker,
.entities = entities,
.length = length,
.idgen = idgen,
.length = length,
};
for (size_t i = 0; i < pool->length; ++i) {
lobullet_base_initialize(
&pool->items[i],
res,
drawer,
shaders,
ticker,
entities);
}
return pool;
}
void lobullet_pool_delete(lobullet_pool_t* pool) {
if (pool == NULL) return;
for (size_t i = 0; i < pool->length; ++i) {
lobullet_base_deinitialize(&pool->items[i]);
}
memory_delete(pool);
}
lobullet_base_t* lobullet_pool_create(lobullet_pool_t* pool) {
assert(pool != NULL);
const size_t i = lobullet_pool_find_unused_item_index_(pool);
pool->items[i].used = true;
lobullet_base_reinitialize(
&pool->items[i], locommon_counter_count(pool->idgen));
return &pool->items[i];
}
lobullet_base_t* lobullet_pool_unpack_item(
lobullet_pool_t* pool, const msgpack_object* obj) {
assert(pool != NULL);
const size_t i = lobullet_pool_find_unused_item_index_(pool);
if (!lobullet_base_unpack(&pool->items[i], obj)) return NULL;
pool->items[i].used = true;
return &pool->items[i];
}

View File

@@ -8,7 +8,7 @@
#include "core/locommon/ticker.h"
#include "core/loentity/store.h"
#include "core/loresource/set.h"
#include "core/loshader/bullet.h"
#include "core/loshader/set.h"
#include "./base.h"
@@ -17,12 +17,12 @@ typedef struct lobullet_pool_t lobullet_pool_t;
lobullet_pool_t* /* OWNERSHIP */
lobullet_pool_new(
loresource_set_t* res,
loshader_bullet_drawer_t* drawer,
locommon_counter_t* idgen,
const locommon_ticker_t* ticker,
loentity_store_t* entities,
size_t length
loresource_set_t* res,
loshader_set_t* shaders,
locommon_counter_t* idgen,
const locommon_ticker_t* ticker,
loentity_store_t* entities,
size_t length
);
void

11
core/lobullet/type.h Normal file
View File

@@ -0,0 +1,11 @@
#pragma once
typedef enum {
/* BENUM BEGIN lobullet_type */
LOBULLET_TYPE_LINEAR_CIRCLE,
LOBULLET_TYPE_LINEAR_TRIANGLE,
LOBULLET_TYPE_LINEAR_SQUARE,
/* BENUM END */
} lobullet_type_t;
#include "core/lobullet/benum/type.h"