From 9942eb201a657640cf244b261008b850352a29f3 Mon Sep 17 00:00:00 2001 From: rodri Date: Wed, 28 Jul 2021 22:15:15 +0000 Subject: brought the Sprite struct for future animations. implemented per-party game state and dynamics. now the state is broadcast after integration, not before. fixed a bug in the broadcast procedure where it would keep referencing an already freed Party and its players. implemented a proper Keymap the user will be able to configure. added mkfile rules to manage installation and dependencies. defined a ton of structs in dat.h for new game objects. started work on a general vector model abstraction to define ship `skins'. removed some debug clauses we no longer need. fixed some other ones. --- assets/mdl/needle.vmdl | 14 ++++++++ dat.h | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ fns.h | 2 +- lobby.c | 1 + mkfile | 19 ++++++++++ musw.c | 43 ++++++++++++----------- musw.man | 0 muswd.c | 88 ++++++++++++++++++++++------------------------ pack.c | 1 + party.c | 1 + physics.c | 11 ++---- sprite.c | 72 ++++++++++++++++++++++++++++++++++++++ 12 files changed, 269 insertions(+), 77 deletions(-) create mode 100644 assets/mdl/needle.vmdl create mode 100644 musw.man create mode 100644 sprite.c diff --git a/assets/mdl/needle.vmdl b/assets/mdl/needle.vmdl new file mode 100644 index 0000000..ba2fd44 --- /dev/null +++ b/assets/mdl/needle.vmdl @@ -0,0 +1,14 @@ +# The Needle vector model + +v 10 0 +v 8 -4 +v -10 -6 +v -12 0 +v -10 6 +v 8 4 + +l 1 2 +l 2 3 +c 3 4 5 +l 5 6 +l 6 1 diff --git a/dat.h b/dat.h index 643216e..33c4607 100644 --- a/dat.h +++ b/dat.h @@ -1,3 +1,28 @@ +typedef enum +{ + K↑, + K↺, + K↻, + Kfire, + Khyper, + Ksay, + Kquit, + NKEYOPS +} KeyOp; + +typedef enum +{ + NEEDLE, + WEDGE +} Kind; + +typedef struct Vector Vector; +typedef struct VModel VModel; +typedef struct Sprite Sprite; +typedef struct Particle Particle; +typedef struct Ship Ship; +typedef struct Star Star; +typedef struct Universe Universe; typedef struct GameState GameState; typedef struct Derivative Derivative; typedef struct Conn Conn; @@ -5,8 +30,72 @@ typedef struct Player Player; typedef struct Lobby Lobby; typedef struct Party Party; +struct Vector +{ + double x, y; +}; + +/* + * Vector model - made out of lines and curves + */ +struct VModel +{ + Vector *pts; + ulong npts; + /* WIP + * l(ine) → takes 2 points + * c(urve) → takes 3 points + */ +// char *strokefmt; +}; + +struct Sprite +{ + Image *sheet; + Point sp; + Rectangle r; + int nframes; + int curframe; + ulong period; + ulong elapsed; + + void (*step)(Sprite*, ulong); + void (*draw)(Sprite*, Image*, Point); +}; + +struct Particle +{ + Vector p, v; + double yaw; + double mass; +}; + +struct Ship +{ + Particle; + Kind kind; + uint ammo; + VModel *mdl; +// Matrix mdlxform; +}; + +struct Star +{ + Particle; + Sprite spr; +}; + +struct Universe +{ + Ship ships[2]; + Star star; + + int (*step)(Universe*); +}; + struct GameState { + double t, timeacc; double x, v; }; @@ -43,7 +132,12 @@ struct Lobby struct Party { Player players[2]; /* the needle and the wedge */ + Universe *u; Party *prev, *next; + + /* testing */ + GameState state; }; + extern Party theparty; diff --git a/fns.h b/fns.h index 38ce644..af78e5e 100644 --- a/fns.h +++ b/fns.h @@ -30,7 +30,7 @@ Lobby *newlobby(void); void dellobby(Lobby*); /* - * lobby + * party */ void inittheparty(void); Party *newparty(Player[2]); diff --git a/lobby.c b/lobby.c index 2007f2a..4211639 100644 --- a/lobby.c +++ b/lobby.c @@ -1,5 +1,6 @@ #include #include +#include /* because of dat.h */ #include "dat.h" #include "fns.h" diff --git a/mkfile b/mkfile index c9c09ff..7b27036 100644 --- a/mkfile +++ b/mkfile @@ -1,5 +1,6 @@ /dev/null + +install:V: man + +uninstall:V: + for(i in $TARG){ + rm -f $BIN/$i + rm -f $MAN/$i + } diff --git a/musw.c b/musw.c index feba719..39c707a 100644 --- a/musw.c +++ b/musw.c @@ -7,23 +7,24 @@ #include "dat.h" #include "fns.h" -enum { - K↑, - K←, - K→, - Kfire, - Khyper, - Kquit, - NKEYS +typedef struct Keymap Keymap; +struct Keymap +{ + Rune key; + KeyOp op; }; -Rune keys[NKEYS] = { - [K↑] Kup, - [K←] Kleft, - [K→] Kright, - [Kfire] ' ', - [Khyper] 'h', - [Kquit] 'q' +Keymap kmap[] = { + {.key = Kup, .op = K↑}, + {.key = Kleft, .op = K↺}, + {.key = Kright, .op = K↻}, + {.key = 'w', .op = K↑}, + {.key = 'a', .op = K↺}, + {.key = 'd', .op = K↻}, + {.key = ' ', .op = Kfire}, + {.key = 'h', .op = Khyper}, + {.key = 'y', .op = Ksay}, + {.key = 'q', .op = Kquit} }; ulong kup, kdown; @@ -40,7 +41,8 @@ int debug; void kbdproc(void *) { - Rune r, *k; + Rune r; + Keymap *k; char buf[128], *s; int fd, n; @@ -74,16 +76,17 @@ kbdproc(void *) kdown = 0; while(*s){ s += chartorune(&r, s); - for(k = keys; k < keys+NKEYS; k++) - if(r == *k){ - kdown |= 1 << k-keys; + for(k = kmap; k < kmap+nelem(kmap); k++) + if(r == k->key){ + kdown |= 1 << k->op; break; } } kup = ~kdown; if(debug) - fprint(2, "kup\t%lub\nkdown\t%lub\n", kup, kdown); + fprint(2, "kup %.*lub\nkdown %.*lub\n", + sizeof(kup)*8, kup, sizeof(kdown)*8, kdown); } } diff --git a/musw.man b/musw.man new file mode 100644 index 0000000..e69de29 diff --git a/muswd.c b/muswd.c index cf0009e..4c1c7ca 100644 --- a/muswd.c +++ b/muswd.c @@ -1,14 +1,12 @@ #include #include #include +#include /* because of dat.h */ #include "dat.h" #include "fns.h" int debug; -GameState state; -double t, Δt; - Lobby *lobby; @@ -68,86 +66,79 @@ broadcaststate(void) { int i, n; uchar buf[256]; - Party *p; + Player *player; + Party *p, *np; - if(debug) - fprint(2, "state: x=%g v=%g\n", state.x, state.v); + for(p = theparty.next; p != &theparty; p = p->next){ + n = pack(buf, sizeof buf, "dd", p->state.x, p->state.v); - for(p = theparty.next; p != &theparty; p = p->next) for(i = 0; i < nelem(p->players); i++){ - n = pack(buf, sizeof buf, "dd", state.x, state.v); if(write(p->players[i].conn.data, buf, n) != n){ - lobby->takeseat(lobby, p->players[i^1].conn.dir, p->players[i^1].conn.ctl, p->players[i^1].conn.data); + player = &p->players[i^1]; + lobby->takeseat(lobby, player->conn.dir, player->conn.ctl, player->conn.data); + np = p->prev; delparty(p); + p = np; + break; } } + } } void -resetsim(void) +resetsim(Party *p) { - t = 0; - memset(&state, 0, sizeof state); - state.x = 100; + memset(&p->state, 0, sizeof p->state); + p->state.x = 100; } void threadsim(void *) { uvlong then, now; - double frametime, timeacc; + double frametime, Δt; Ioproc *io; Player couple[2]; + Party *p; Δt = 0.01; then = nanosec(); - timeacc = 0; io = ioproc(); - resetsim(); - for(;;){ lobby->healthcheck(lobby); - if(debug){ - Party *p; - ulong nparties = 0; - - for(p = theparty.next; p != &theparty; p = p->next) - nparties++; - - fprint(2, "lobby status: %lud conns at %lud cap\n", - lobby->nseats, lobby->cap); - fprint(2, "party status: %lud parties going on\n", - nparties); - } - - if(lobby->getcouple(lobby, couple) != -1) + if(lobby->getcouple(lobby, couple) != -1){ newparty(couple); - - broadcaststate(); + resetsim(theparty.prev); /* reset the new party */ + } now = nanosec(); frametime = now - then; then = now; - timeacc += frametime/1e9; - while(timeacc >= Δt){ - integrate(&state, t, Δt); - timeacc -= Δt; - t += Δt; + for(p = theparty.next; p != &theparty; p = p->next){ + p->state.timeacc += frametime/1e9; + + while(p->state.timeacc >= Δt){ + integrate(&p->state, p->state.t, Δt); + p->state.timeacc -= Δt; + p->state.t += Δt; + } } - iosleep(io, FPS2MS(1)); + broadcaststate(); + + iosleep(io, FPS2MS(70)); } } void fprintstats(int fd) { - Party *p; ulong nparties = 0; + Party *p; for(p = theparty.next; p != &theparty; p = p->next) nparties++; @@ -162,11 +153,14 @@ fprintstats(int fd) } void -fprintstate(int fd) +fprintstates(int fd) { - fprint(fd, "x %g\n" - "v %g\n", - state.x, state.v); + ulong i = 0; + Party *p; + + for(p = theparty.next; p != &theparty; p = p->next, i++) + fprint(fd, "%lud [x %g v %g]\n", + i, p->state.x, p->state.v); } @@ -200,8 +194,8 @@ threadC2(void *) if(strcmp(cmdargs[0], "show") == 0){ if(strcmp(cmdargs[1], "stats") == 0) fprintstats(pfd[1]); - else if(strcmp(cmdargs[1], "state") == 0) - fprintstate(pfd[1]); + else if(strcmp(cmdargs[1], "states") == 0) + fprintstates(pfd[1]); } } } @@ -221,7 +215,7 @@ threadmain(int argc, char *argv[]) int acfd; char adir[40], *addr; - addr = "udp!*!112"; + addr = "tcp!*!112"; /* for testing. will work out udp soon */ ARGBEGIN{ case 'a': addr = EARGF(usage()); diff --git a/pack.c b/pack.c index d60800d..a1335c2 100644 --- a/pack.c +++ b/pack.c @@ -1,5 +1,6 @@ #include #include +#include /* because of dat.h */ #include "dat.h" #include "fns.h" diff --git a/party.c b/party.c index d6b0e52..050bd18 100644 --- a/party.c +++ b/party.c @@ -1,5 +1,6 @@ #include #include +#include /* because of dat.h */ #include "dat.h" #include "fns.h" diff --git a/physics.c b/physics.c index 5f45fd9..5bc2e5b 100644 --- a/physics.c +++ b/physics.c @@ -1,24 +1,17 @@ #include #include -#include +#include /* because of dat.h */ #include "dat.h" #include "fns.h" -//enum { DYNTIME, RENTIME, NSTATS }; -//Stats simstats[NSTATS]; - - /* * Dynamics stepper - * - * Currently set to a basic spring-damper system. */ static double -accel(GameState *s, double t) +accel(GameState *s, double) { static double k = 15, b = 0.1; - USED(t); return -k*s->x - b*s->v; } diff --git a/sprite.c b/sprite.c new file mode 100644 index 0000000..a2bf290 --- /dev/null +++ b/sprite.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include "dat.h" +#include "fns.h" + +static void +sprite_step(Sprite *spr, ulong Δt) +{ + if(spr->nframes < 2) + return; + + spr->elapsed += Δt; + + if(spr->elapsed >= spr->period){ + spr->elapsed -= spr->period; + spr->curframe = ++spr->curframe % spr->nframes; + } +} + +static void +sprite_draw(Sprite *spr, Image *dst, Point dp) +{ + Point sp = (Point){ + spr->curframe * Dx(spr->r), + 0 + }; + sp = addpt(spr->sp, sp); + + draw(dst, rectaddpt(spr->r, dp), spr->sheet, nil, sp); +} + +Sprite * +newsprite(Image *sheet, Point sp, Rectangle r, int nframes, ulong period) +{ + Sprite *spr; + + spr = emalloc(sizeof(Sprite)); + spr->sheet = sheet; + spr->sp = sp; + spr->r = r; + spr->nframes = nframes; + spr->curframe = 0; + spr->period = period; + spr->elapsed = 0; + spr->step = sprite_step; + spr->draw = sprite_draw; + + return spr; +} + +Sprite * +readsprite(char *sheetfile, Point sp, Rectangle r, int nframes, ulong period) +{ + Image *sheet; + int fd; + + fd = open(sheetfile, OREAD); + if(fd < 0) + sysfatal("readsprite: %r"); + sheet = readimage(display, fd, 1); + close(fd); + + return newsprite(sheet, sp, r, nframes, period); +} + +void +delsprite(Sprite *spr) +{ + freeimage(spr->sheet); + free(spr); +} -- cgit v1.2.3