aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2023-03-08 20:59:10 +0000
committerrodri <rgl@antares-labs.eu>2023-03-08 20:59:10 +0000
commitb545537c9a6c7d32976b863cbb14792980d31e3d (patch)
tree71cb8c74c6be18ab80dbfb0c92fccdc580788439
parent941d146cea7d0c2ce872e599622a5c9e01d37fe2 (diff)
downloadmusw-b545537c9a6c7d32976b863cbb14792980d31e3d.tar.gz
musw-b545537c9a6c7d32976b863cbb14792980d31e3d.tar.bz2
musw-b545537c9a6c7d32976b863cbb14792980d31e3d.zip
implemented states to represent game scene stages.
added an intro as well.
-rw-r--r--assets/spr/intro.picbin0 -> 74729 bytes
-rw-r--r--dat.h11
-rw-r--r--musw.c84
-rw-r--r--todo13
4 files changed, 85 insertions, 23 deletions
diff --git a/assets/spr/intro.pic b/assets/spr/intro.pic
new file mode 100644
index 0000000..fba25c8
--- /dev/null
+++ b/assets/spr/intro.pic
Binary files 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