diff options
-rw-r--r-- | assets/mdl/needle.vmdl | 14 | ||||
-rw-r--r-- | dat.h | 94 | ||||
-rw-r--r-- | fns.h | 2 | ||||
-rw-r--r-- | lobby.c | 1 | ||||
-rw-r--r-- | mkfile | 19 | ||||
-rw-r--r-- | musw.c | 43 | ||||
-rw-r--r-- | musw.man | 0 | ||||
-rw-r--r-- | muswd.c | 88 | ||||
-rw-r--r-- | pack.c | 1 | ||||
-rw-r--r-- | party.c | 1 | ||||
-rw-r--r-- | physics.c | 11 | ||||
-rw-r--r-- | sprite.c | 72 |
12 files changed, 269 insertions, 77 deletions
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 @@ -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; @@ -30,7 +30,7 @@ Lobby *newlobby(void); void dellobby(Lobby*); /* - * lobby + * party */ void inittheparty(void); Party *newparty(Player[2]); @@ -1,5 +1,6 @@ #include <u.h> #include <libc.h> +#include <draw.h> /* because of dat.h */ #include "dat.h" #include "fns.h" @@ -1,5 +1,6 @@ </$objtype/mkfile +MAN=/sys/man/1 BIN=/$objtype/bin/games TARG=\ musw\ @@ -17,4 +18,22 @@ HFILES=\ dat.h\ fns.h\ +LIB=\ + libgeometry/libgeometry.a$O\ + </sys/src/cmd/mkmany + +libgeometry/libgeometry.a$O: pulldeps + cd libgeometry + mk install + +pulldeps:V: + ! test -d libgeometry && git/clone https://github.com/sametsisartenep/libgeometry || echo >/dev/null + +install:V: man + +uninstall:V: + for(i in $TARG){ + rm -f $BIN/$i + rm -f $MAN/$i + } @@ -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 --- /dev/null +++ b/musw.man @@ -1,14 +1,12 @@ #include <u.h> #include <libc.h> #include <thread.h> +#include <draw.h> /* 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()); @@ -1,5 +1,6 @@ #include <u.h> #include <libc.h> +#include <draw.h> /* because of dat.h */ #include "dat.h" #include "fns.h" @@ -1,5 +1,6 @@ #include <u.h> #include <libc.h> +#include <draw.h> /* because of dat.h */ #include "dat.h" #include "fns.h" @@ -1,24 +1,17 @@ #include <u.h> #include <libc.h> -#include <draw.h> +#include <draw.h> /* 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 <u.h> +#include <libc.h> +#include <draw.h> +#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); +} |