From b545537c9a6c7d32976b863cbb14792980d31e3d Mon Sep 17 00:00:00 2001 From: rodri Date: Wed, 8 Mar 2023 20:59:10 +0000 Subject: implemented states to represent game scene stages. added an intro as well. --- assets/spr/intro.pic | Bin 0 -> 74729 bytes dat.h | 11 +++---- musw.c | 84 ++++++++++++++++++++++++++++++++++++++++++++------- todo | 13 +++++--- 4 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 assets/spr/intro.pic diff --git a/assets/spr/intro.pic b/assets/spr/intro.pic new file mode 100644 index 0000000..fba25c8 Binary files /dev/null and b/assets/spr/intro.pic differ diff --git a/dat.h b/dat.h index 67fcf3b..2b3929d 100644 --- a/dat.h +++ b/dat.h @@ -58,7 +58,7 @@ enum { typedef struct VModel VModel; typedef struct Sprite Sprite; typedef struct Keymap Keymap; -typedef struct Scene Scene; +typedef struct State State; typedef struct Particle Particle; typedef struct Bullet Bullet; typedef struct Ship Ship; @@ -107,14 +107,11 @@ struct Keymap KeyOp op; }; -struct Scene +struct State { - char *title; - int state; + char *name; - Scene *(*δ)(Scene*); - void (*step)(Scene*); - void (*draw)(Scene*); + State *(*δ)(State*, void*); /* transition fn */ }; struct Particle diff --git a/musw.c b/musw.c index ea3803a..026ed9c 100644 --- a/musw.c +++ b/musw.c @@ -12,6 +12,14 @@ #include "dat.h" #include "fns.h" +enum { + GSIntro, + GSConnecting, + GSMatching, + GSPlaying, + NGAMESTATES +}; + Keymap kmap[] = { {.key = Kup, .op = K↑}, {.key = Kleft, .op = K↺}, @@ -31,12 +39,15 @@ Universe *universe; VModel *needlemdl, *wedgemdl; Image *screenb; Image *skymap; -Scene *curscene; +Sprite *intro; +State gamestates[NGAMESTATES]; +State *gamestate; Channel *ingress; Channel *egress; NetConn netconn; char deffont[] = "/lib/font/bit/pelm/unicode.9.font"; char winspec[32]; +int weplaying; int doghosting; int debug; @@ -365,6 +376,8 @@ threadnetppu(void *) switch(frame->type){ case NSsimstate: + weplaying = 1; + bufp = frame->data; bufp += unpack(bufp, frame->len, "PdPdP", &universe->ships[0].p, &universe->ships[0].θ, @@ -385,6 +398,7 @@ threadnetppu(void *) break; case NSbuhbye: + weplaying = 0; netconn.state = NCSDisconnected; break; } @@ -499,13 +513,20 @@ redraw(void) else draw(screenb, screenb->r, skymap, nil, ZP); - if(netconn.state == NCSConnecting) + switch(gamestate-gamestates){ + case GSIntro: + intro->draw(intro, screenb, subpt(divpt(screenb->r.max, 2), divpt(intro->r.max, 2))); + break; + case GSConnecting: drawconnecting(); - - if(netconn.state == NCSConnected){ + break; + case GSMatching: + break; + case GSPlaying: drawship(&universe->ships[0], screenb); drawship(&universe->ships[1], screenb); universe->star.spr->draw(universe->star.spr, screenb, subpt(toscreen(universe->star.p), Pt(16,16))); + break; } draw(screen, screen->r, screenb, nil, ZP); @@ -541,6 +562,37 @@ resize(void) redraw(); } +State *intro_δ(State *s, void *arg) +{ + double ∆t; + static ulong elapsed; + + ∆t = *(double*)arg; + elapsed += ∆t/1e6; + if(elapsed > 5000) + return &gamestates[GSConnecting]; + return s; +} + +State *connecting_δ(State *s, void*) +{ + if(netconn.state != NCSConnecting) + return &gamestates[GSMatching]; + return s; +} + +State *matching_δ(State *s, void*) +{ + if(netconn.state == NCSConnected && weplaying) + return &gamestates[GSPlaying]; + return s; +} + +State *playing_δ(State *s, void*) +{ + return s; +} + void usage(void) { @@ -595,7 +647,6 @@ threadmain(int argc, char *argv[]) proccreate(kbdproc, nil, mainstacksize); - /* TODO: implement this properly with screens and iodial(2) */ fd = dial(server, nil, nil, nil); if(fd < 0) sysfatal("dial: %r"); @@ -611,6 +662,14 @@ threadmain(int argc, char *argv[]) universe->ships[1].mdl = wedgemdl; universe->star.spr = readsprite("assets/spr/earth.pic", ZP, Rect(0,0,32,32), 5, 20e3); + intro = readsprite("assets/spr/intro.pic", ZP, Rect(0,0,640,480), 1, 0); + + gamestates[GSIntro].δ = intro_δ; + gamestates[GSConnecting].δ = connecting_δ; + gamestates[GSMatching].δ = matching_δ; + gamestates[GSPlaying].δ = playing_δ; + gamestate = &gamestates[GSIntro]; + ingress = chancreate(sizeof(Frame*), 8); egress = chancreate(sizeof(Frame*), 8); threadcreate(threadnetrecv, &fd, mainstacksize); @@ -626,15 +685,18 @@ threadmain(int argc, char *argv[]) frametime = now - then; then = now; - if(netconn.state != NCSConnected) - lastpktsent += frametime/1e6; + if(gamestate != &gamestates[GSIntro]){ + if(netconn.state == NCSConnecting) + lastpktsent += frametime/1e6; - if(netconn.state == NCSDisconnected || - (netconn.state == NCSConnecting && lastpktsent >= 1000)){ - initconn(); - lastpktsent = 0; + if(netconn.state == NCSDisconnected || + (netconn.state == NCSConnecting && lastpktsent >= 1000)){ + initconn(); + lastpktsent = 0; + } } + gamestate = gamestate->δ(gamestate, &frametime); universe->star.spr->step(universe->star.spr, frametime/1e6); redraw(); diff --git a/todo b/todo index 6827ae2..bccfa18 100644 --- a/todo +++ b/todo @@ -7,11 +7,14 @@ [ ] hyperjump [ ] minskytron effect [ ] engine damage on every jump -[ ] different screens for each game state - [ ] intro - [ ] connecting to server - [ ] waiting for a player - [ ] main game +[✓] different screens for each game state + [✓] intro + [✓] connecting to server + [✓] waiting for a player + [✓] main game [ ] reduce the amount of data sent on every NSsimstate packet [?] the client must try to connect continously > there's an error in the udp stack that doesn't allow the client to receive packets if run before the server is up. +[ ] more realistic DEC Type 30 CRT emulation + [ ] the right colors (fg: 0x3daaf7, fgblur: 0x0063eb, bg0: 0x79cc3e, bg1: 0x7eba1e) + [ ] the right decay function -- cgit v1.2.3