aboutsummaryrefslogtreecommitdiff
path: root/src/unit
diff options
context:
space:
mode:
Diffstat (limited to 'src/unit')
-rw-r--r--src/unit/inc/unit.h21
-rw-r--r--src/unit/inc/unit_type.h9
-rw-r--r--src/unit/src/unit.c459
3 files changed, 263 insertions, 226 deletions
diff --git a/src/unit/inc/unit.h b/src/unit/inc/unit.h
index 8d3e1bf..c9abafe 100644
--- a/src/unit/inc/unit.h
+++ b/src/unit/inc/unit.h
@@ -33,17 +33,14 @@ struct unit
{
struct instance instance;
enum unit_type type;
+ const char *name;
enum unit_dir
{
- UNIT_DIR_N,
- UNIT_DIR_NE,
- UNIT_DIR_E,
- UNIT_DIR_SE,
- UNIT_DIR_S,
- UNIT_DIR_SW,
UNIT_DIR_W,
- UNIT_DIR_NW
+ UNIT_DIR_S,
+ UNIT_DIR_N,
+ UNIT_DIR_E
} dir;
enum unit_state state;
@@ -61,7 +58,12 @@ UTIL_STATIC_ASSERT(!offsetof(struct unit, instance), "must be at offset zero");
struct unit_cfg
{
- enum unit_type type;
+ enum
+ {
+ UNIT_CFG_TYPE_WALKER,
+ UNIT_CFG_TYPE_CAR
+ } type;
+
unsigned long x, y;
};
@@ -72,7 +74,6 @@ bool unit_target_valid(const struct unit *u, const struct unit_target *t);
void unit_set_target(struct unit *u, const struct unit_target *t);
void unit_move_to(struct unit *u, unsigned long x, unsigned long y);
void unit_update(struct unit *u);
-const char *unit_str(const struct unit *u);
enum
{
@@ -82,6 +83,8 @@ enum
UNIT_4_SPRITE,
UNIT_5_SPRITE,
UNIT_6_SPRITE,
+ UNIT_CAR_1_SPRITE,
+ UNIT_CAR_2_SPRITE,
MAX_UNIT_SPRITES
};
diff --git a/src/unit/inc/unit_type.h b/src/unit/inc/unit_type.h
index f023784..ea59856 100644
--- a/src/unit/inc/unit_type.h
+++ b/src/unit/inc/unit_type.h
@@ -3,6 +3,15 @@
enum unit_type
{
+ UNIT_TYPE_1,
+ UNIT_TYPE_2,
+ UNIT_TYPE_3,
+ UNIT_TYPE_4,
+ UNIT_TYPE_5,
+ UNIT_TYPE_6,
+ UNIT_TYPE_CAR_1,
+ UNIT_TYPE_CAR_2,
+
MAX_UNIT_TYPES
};
diff --git a/src/unit/src/unit.c b/src/unit/src/unit.c
index 1bb1e0f..43dcc86 100644
--- a/src/unit/src/unit.c
+++ b/src/unit/src/unit.c
@@ -11,7 +11,7 @@
struct sprite unit_sprites[MAX_UNIT_SPRITES];
struct sound unit_sounds[MAX_UNIT_SOUNDS];
-enum {N_FRAMES = 5};
+static const unsigned char anim[] = {0, 1, 0, 2};
static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy)
{
@@ -21,38 +21,18 @@ static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy)
u->ry -= sy;
break;
- case UNIT_DIR_NE:
- u->rx += sx;
- u->ry -= sy;
- break;
-
case UNIT_DIR_E:
u->rx += sx;
break;
- case UNIT_DIR_SE:
- u->rx += sx;
- u->ry += sy;
- break;
-
case UNIT_DIR_S:
u->ry += sy;
break;
- case UNIT_DIR_SW:
- u->rx -= sx;
- u->ry += sy;
- break;
-
case UNIT_DIR_W:
u->rx -= sx;
break;
- case UNIT_DIR_NW:
- u->rx -= sx;
- u->ry -= sy;
- break;
-
default:
break;
}
@@ -61,17 +41,51 @@ static void move_unit(struct unit *const u, const fix16_t sx, const fix16_t sy)
static void get_speed(const struct unit *const u, fix16_t *const x,
fix16_t *const y)
{
- static const struct speed
+ struct speed
{
fix16_t x, y;
- } speed[1];
+ } s;
+
+ switch (u->type)
+ {
+ case UNIT_TYPE_1:
+ case UNIT_TYPE_2:
+ case UNIT_TYPE_3:
+ case UNIT_TYPE_4:
+ case UNIT_TYPE_5:
+ case UNIT_TYPE_6:
+ {
+ static const struct speed ref =
+ {
+ .x = FIX16_C_FROM_FLOAT(0.4),
+ .y = FIX16_C_FROM_FLOAT(0.4)
+ };
+
+ s = ref;
+ }
+ break;
+
+ case UNIT_TYPE_CAR_1:
+ case UNIT_TYPE_CAR_2:
+ {
+ static const struct speed ref =
+ {
+ .x = FIX16_C_FROM_FLOAT(1.5),
+ .y = FIX16_C_FROM_FLOAT(1.5)
+ };
+
+ s = ref;
+ }
+
+ case MAX_UNIT_TYPES:
+ break;
+ }
- const struct speed *const s = &speed[u->type];
const int dx = abs(u->rx - u->tx);
const int dy = abs(u->ry - u->ty);
- *x = dx < s->x ? dx : s->x;
- *y = dy < s->y ? dy : s->y;
+ *x = dx < s.x ? dx : s.x;
+ *y = dy < s.y ? dy : s.y;
}
static enum unit_dir get_direction(const struct unit *const u)
@@ -79,18 +93,7 @@ static enum unit_dir get_direction(const struct unit *const u)
const fix16_t x = u->rx, y = u->ry, tx = u->tx, ty = u->ty;
enum unit_dir dir = 0;
- if (x != tx && y != ty)
- {
- if (x > tx && y > ty)
- dir = UNIT_DIR_NW;
- else if (x < tx && y > ty)
- dir = UNIT_DIR_NE;
- else if (x < tx && y < ty)
- dir = UNIT_DIR_SE;
- else
- dir = UNIT_DIR_SW;
- }
- else if (x != tx)
+ if (x != tx)
{
if (x > tx)
dir = UNIT_DIR_W;
@@ -155,7 +158,7 @@ static bool must_move(const struct unit *const u)
void unit_update(struct unit *const u)
{
- const struct instance *const i = &u->instance;
+ struct instance *const i = &u->instance;
if (!i->alive)
return;
@@ -170,13 +173,13 @@ void unit_update(struct unit *const u)
get_speed(u, &x_step, &y_step);
move_unit(u, x_step, y_step);
- enum {FRAME_RATE = 6};
+ enum {FRAME_RATE = 10};
if (++u->frame.t >= FRAME_RATE)
{
u->frame.t = 0;
- if (++u->frame.i >= N_FRAMES)
+ if (++u->frame.i >= sizeof anim / sizeof *anim)
u->frame.i = 0;
}
@@ -185,8 +188,8 @@ void unit_update(struct unit *const u)
else
u->frame.i = 0;
- u->instance.r.x = fix16_to_int(u->rx);
- u->instance.r.y = fix16_to_int(u->ry);
+ i->r.x = fix16_to_int(u->rx);
+ i->r.y = fix16_to_int(u->ry);
}
void unit_set_target(struct unit *const u, const struct unit_target *const t)
@@ -209,240 +212,262 @@ void unit_move_to(struct unit *const u, const unsigned long x, const unsigned lo
u->ty = y > y_off ? fix16_from_int(y - y_off) : 0;
}
-static int get_ux(const struct unit *const u)
+static void adjust_walker(const struct unit *const u, struct sprite *const s,
+ struct instance_render_off *const off)
+{
+ s->w = u->instance.r.w;
+ s->h = u->instance.r.h;
+ s->u += u->dir * s->w;
+ s->v += anim[u->frame.i] * s->h;
+ off->x = 0;
+ off->y = -2;
+}
+
+static void adjust_car(const struct unit *const u, struct sprite *const s,
+ struct instance_render_off *const off)
{
switch (u->dir)
{
- case UNIT_DIR_N:
- return 0;
-
- case UNIT_DIR_NE:
- /* Fall through. */
- case UNIT_DIR_NW:
- return 1;
-
- case UNIT_DIR_E:
- /* Fall through. */
case UNIT_DIR_W:
- return 2;
-
- case UNIT_DIR_SE:
- /* Fall through. */
- case UNIT_DIR_SW:
- return 3;
+ s->w = s->h = 32;
+ s->u += 32;
+ off->x = -5;
+ break;
case UNIT_DIR_S:
- return 4;
+ s->w = 16;
+ s->h = 32;
+ off->x = 2;
+ break;
- default:
+ case UNIT_DIR_N:
+ s->u += 16;
+ s->w = 16;
+ s->h = 32;
+ off->x = 2;
+ break;
+
+ case UNIT_DIR_E:
+ s->w = s->h = 32;
+ s->u += 64;
+ off->x = -5;
break;
}
- return -1;
+ off->y = -10;
}
-typedef const struct
-{
- const struct sprite *s;
- char xo, x[N_FRAMES], w[N_FRAMES];
- short y;
- short h;
-} anim_dim;
-
-static anim_dim *peasant_anim(const struct unit *const u)
+static void adjust_sprite(const struct unit *const u, struct sprite *const s,
+ struct instance_render_off *const off)
{
-#if 0
- static anim_dim t[] =
+ switch (u->type)
{
- {
- .s = &unit_sprites[UNIT_SPRITE_N],
- .xo = 5,
- .x = {0, 1, 1, 2, 1},
- .w = {25, 22, 24, 22, 24},
- .y = 2,
- .h = 31
- },
-
- {
- .s = &unit_sprites[UNIT_SPRITE_NE],
- .xo = 11,
- .x = {0, -4, -1, -4, -2},
- .w = {18, 26, 22, 23, 20},
- .y = 2,
- .h = 31
- },
-
- {
- .s = &unit_sprites[UNIT_SPRITE_E],
- .xo = 10,
- .x = {0, -6, -1, -6, -3},
- .w = {14, 26, 17, 24, 19},
- .y = 2,
- .h = 33
- },
-
- {
- .s = &unit_sprites[UNIT_SPRITE_SE],
- .xo = 6,
- .x = {0, 1, 2, 0, 0},
- .w = {20, 22, 18, 21, 21},
- .y = 2,
- .h = 31
- },
-
- {
- .s = &unit_sprites[UNIT_SPRITE_S],
- .xo = 7,
- .x = {0, 1, 0, 0, 0},
- .w = {24, 23, 24, 23, 24},
- .y = 2,
- .h = 33
- }
- };
-
- const int ux = get_ux(u);
+ case UNIT_TYPE_1:
+ case UNIT_TYPE_2:
+ case UNIT_TYPE_3:
+ case UNIT_TYPE_4:
+ case UNIT_TYPE_5:
+ case UNIT_TYPE_6:
+ adjust_walker(u, s, off);
+ break;
- if (ux < 0)
- return NULL;
+ case UNIT_TYPE_CAR_1:
+ case UNIT_TYPE_CAR_2:
+ adjust_car(u, s, off);
+ break;
- return &t[ux];
-#else
- return NULL;
-#endif
+ case MAX_UNIT_TYPES:
+ break;
+ }
}
-struct render_cfg
-{
- struct instance_render_off off;
- struct instance_render_quad qcfg;
-};
-
-static anim_dim *peasant_quad(const struct unit *const u)
+int unit_render(const struct unit *const u, const struct camera *const cam,
+ const bool sel)
{
- return peasant_anim(u);
-}
+ if (!u->instance.alive)
+ return 0;
-static void adjust_quad(const struct unit *const u, anim_dim *const dim,
- struct render_cfg *const rcfg)
-{
- const unsigned char n = u->frame.i;
- short u_off = 0;
+ sprite_get_or_ret(s, -1);
- for (unsigned char i = 0; i < n; i++)
- u_off += dim->w[i];
+ struct instance_render_off off;
- struct instance_render_quad *const qcfg = &rcfg->qcfg;
+ if (sprite_clone(&unit_sprites[u->type], s))
+ {
+ fprintf(stderr, "%s: sprite_clone failed\n", __func__);
+ return -1;
+ }
- qcfg->u = u_off;
- qcfg->w = dim->w[n];
- qcfg->h = dim->h;
+ adjust_sprite(u, s, &off);
- struct instance_render_off *const off = &rcfg->off;
+ const struct instance_render_cfg cfg =
+ {
+ .i = &u->instance,
+ .prim_type = INSTANCE_RENDER_CFG_SPRITE,
+ .prim.s = s,
+ .off = &off,
+ .cam = cam,
+ .sel = sel
+ };
- off->x = dim->xo;
- off->y = dim->y;
+ return instance_render(&cfg);
+}
- switch (u->dir)
+static void get_dimensions(const enum unit_type type, short *const w,
+ short *const h)
+{
+ switch (type)
{
- case UNIT_DIR_SW:
- /* Fall through. */
- case UNIT_DIR_W:
- /* Fall through. */
- case UNIT_DIR_NW:
- qcfg->xflip = true;
- off->x += dim->x[n];
+ case UNIT_TYPE_1:
+ case UNIT_TYPE_2:
+ case UNIT_TYPE_3:
+ case UNIT_TYPE_4:
+ case UNIT_TYPE_5:
+ case UNIT_TYPE_6:
+ *w = *h = 16;
break;
- default:
- qcfg->xflip = false;
- off->x += dim->x[n];
+ case UNIT_TYPE_CAR_1:
+ case UNIT_TYPE_CAR_2:
+ *w = *h = 22;
+ break;
+
+ case MAX_UNIT_TYPES:
break;
}
}
-static int unit_quad(const struct unit *const u, struct render_cfg *const rcfg)
+static const char *get_walker_name(const enum unit_type type)
{
- struct instance_render_quad *const qcfg = &rcfg->qcfg;
-
- static anim_dim *(*const f[1])(const struct unit *);
+ enum {FEMALE, MALE} gender = 0;
- anim_dim *const dim = f[u->type](u);
-
- if (!dim)
- return -1;
+ switch (type)
+ {
+ case UNIT_TYPE_2:
+ case UNIT_TYPE_5:
+ gender = FEMALE;
+ break;
- adjust_quad(u, dim, rcfg);
+ case UNIT_TYPE_1:
+ case UNIT_TYPE_3:
+ case UNIT_TYPE_4:
+ case UNIT_TYPE_6:
+ gender = MALE;
+ break;
- if (quad_from_sprite(dim->s, qcfg->q))
- return -1;
+ default:
+ return NULL;
+ }
- return 0;
-}
+ static const char *const female[] =
+ {
+ "Amelia",
+ "Asher",
+ "Aurora",
+ "Ava",
+ "Charlotte",
+ "Dana",
+ "Ellie",
+ "Emma",
+ "Ezra",
+ "Haley",
+ "Harper",
+ "Isabella",
+ "Luna",
+ "Mire",
+ "Olivia",
+ "Sophia",
+ };
-int unit_render(const struct unit *const u, const struct camera *const cam,
- const bool sel)
-{
- if (!u->instance.alive)
- return 0;
+ static const char *const male[] =
+ {
+ "Oliver",
+ "Xavi",
+ "Benjamin",
+ "Elijah",
+ "Ethan",
+ "Jack",
+ "James",
+ "Jan",
+ "Kyte",
+ "Leo",
+ "Levi",
+ "Liam",
+ "Luca",
+ "Lucas",
+ "Michael",
+ "Noah",
+ };
- struct render_cfg rcfg;
+ switch (gender)
+ {
+ case FEMALE:
+ {
+ const size_t i = rand() % (sizeof female / sizeof *female);
- quad_get_or_ret(q, -1);
- rcfg.qcfg.q = q;
+ return female[i];
+ }
- if (unit_quad(u, &rcfg))
- return -1;
+ case MALE:
+ {
+ const size_t i = rand() % (sizeof male / sizeof *male);
- const struct instance_render_cfg cfg =
- {
- .i = &u->instance,
- .prim_type = INSTANCE_RENDER_CFG_QUAD,
- .prim = {.quad = &rcfg.qcfg},
- .cam = cam,
- .sel = sel,
- .off = &rcfg.off
- };
+ return male[i];
+ }
+ }
- return instance_render(&cfg);
+ return NULL;
}
-static void get_dimensions(const enum unit_type type, short *const w,
- short *const h)
+static const char *get_name(const enum unit_type type)
{
- static const struct dim
+ switch (type)
{
- short w, h;
- } dim[1];
+ case UNIT_TYPE_1:
+ case UNIT_TYPE_2:
+ case UNIT_TYPE_3:
+ case UNIT_TYPE_4:
+ case UNIT_TYPE_5:
+ case UNIT_TYPE_6:
+ return get_walker_name(type);
+
+ case UNIT_TYPE_CAR_1:
+ case UNIT_TYPE_CAR_2:
+ return "Car";
+
+ case MAX_UNIT_TYPES:
+ break;
+ }
- const struct dim *const d = &dim[type];
- *w = d->w;
- *h = d->h;
+ return NULL;
}
void unit_create(const struct unit_cfg *const cfg, struct unit *const u)
{
struct instance *const i = &u->instance;
+ enum unit_type type = 0;
- *u = (const struct unit)
+ switch (cfg->type)
{
- .instance =
- {
- .alive = true,
- },
+ case UNIT_CFG_TYPE_WALKER:
+ type = UNIT_TYPE_1 + (rand() % (UNIT_TYPE_6 + 1));
+ break;
- .type = cfg->type,
+ case UNIT_CFG_TYPE_CAR:
+ type = UNIT_TYPE_CAR_1 + (rand()
+ % (UNIT_TYPE_CAR_2 - UNIT_TYPE_CAR_1 + 1));
+ break;
+ }
+
+ *u = (const struct unit)
+ {
+ .instance.alive = true,
.dir = UNIT_DIR_S,
.rx = fix16_from_int(cfg->x),
- .ry = fix16_from_int(cfg->y)
+ .ry = fix16_from_int(cfg->y),
+ .type = type,
+ .name = get_name(type)
};
- get_dimensions(cfg->type, &i->r.w, &i->r.h);
+ get_dimensions(u->type, &i->r.w, &i->r.h);
unit_stop(u);
}
-
-const char *unit_str(const struct unit *const u)
-{
- static const char *const str[1];
-
- return str[u->type];
-}