diff options
Diffstat (limited to 'src/unit')
| -rw-r--r-- | src/unit/inc/unit.h | 21 | ||||
| -rw-r--r-- | src/unit/inc/unit_type.h | 9 | ||||
| -rw-r--r-- | src/unit/src/unit.c | 459 |
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]; -} |
