ref: f2fbb92be6b39f4150b6729814f41e91bb64266d
parent: 1184dc33223639c8f20dfead77b0e6411bc651f7
author: rodri <rgl@antares-labs.eu>
date: Tue Nov 12 11:17:53 EST 2024
bts: moderate cleanup and restructuring.
--- a/bts.c
+++ b/bts.c
@@ -139,6 +139,7 @@
Channel *reconnc;
Channel *ingress, *egress;
Mousectl *mctl; /* only used to update the cursor */
+Keyboardctl *kctl; /* only used to ignore key presses during specific interactions */
RFrame worldrf;
Image *pal[NCOLORS];
Image *screenb;
@@ -277,6 +278,7 @@
vstring(Image *dst, Point p, Image *src, Point sp, Font *f, char *s)
{
char buf[2];
+
buf[1] = 0;
while(*s){
buf[0] = *s++;
@@ -328,7 +330,7 @@
}
void
-drawships(Image *dst)
+drawarmada(Image *dst)
{
int i;
@@ -371,7 +373,7 @@
drawinfo(Image *dst)
{
Point p;
- char *s, aux[32], aux2[32];
+ char *s, aux[32];
int i;
s = "";
@@ -400,7 +402,6 @@
p = subpt(localboard.bbox.min, Pt(font->width+2+Borderwidth,0));
vstring(dst, p, pal[PCWhite], ZP, font, gamestate == Watching? match.pl[0].uid: uid);
- /* TODO make this an info panel and show errors from bad transactions. */
if(gamestate == Outlaying){
if(curship != nil){
snprint(aux, sizeof aux, "%s (%d)", shipname(curship-armada), curship->ncells);
@@ -410,19 +411,25 @@
s = "done with the layout?";
p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin);
string(dst, p, pal[PCYellow], ZP, font, s);
+ s = "LMB/MMB = No, RMB = Yes";
+ p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin+font->height);
+ string(dst, p, pal[PCYellow], ZP, font, s);
}
}else if(gamestate == Watching){
- snprint(aux, sizeof aux, "waiting for players to");
- snprint(aux2, sizeof aux2, "lay out their fleet");
for(i = 0; i < nelem(match.pl); i++)
if(match.pl[i].state == Playing){
snprint(aux, sizeof aux, "it's %s's turn", match.pl[i].uid);
- aux2[0] = 0;
+ p = Pt(SCRW/2 - stringwidth(font, aux)/2, SCRH-Boardmargin);
+ string(dst, p, pal[PCBlue], ZP, font, aux);
+ return;
}
- p = Pt(SCRW/2 - stringwidth(font, aux)/2, SCRH-Boardmargin);
- string(dst, p, pal[PCBlue], ZP, font, aux);
- p = Pt(SCRW/2 - stringwidth(font, aux2)/2, SCRH-Boardmargin+font->height);
- string(dst, p, pal[PCBlue], ZP, font, aux2);
+
+ s = "waiting for players to";
+ p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin);
+ string(dst, p, pal[PCBlue], ZP, font, s);
+ s = "lay out their fleet";
+ p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin+font->height);
+ string(dst, p, pal[PCBlue], ZP, font, s);
}
}
@@ -454,7 +461,7 @@
default:
drawboard(screenb, &alienboard);
drawboard(screenb, &localboard);
- drawships(screenb);
+ drawarmada(screenb);
drawinfo(screenb);
break;
}
@@ -642,25 +649,50 @@
0x86, 0x64, 0x8f, 0xc4, 0x80, 0x0c, 0xff, 0xf8,
},
};
+
csetcursor(mc, &anchor);
+ readmouse(mc);
while(mc->buttons == 0)
readmouse(mc);
if(mc->buttons != 4){
+ while(nbrecv(kctl->c, nil)) /* flush key presses */
csetcursor(mc, nil);
return 0;
}
while(mc->buttons){
if(mc->buttons != 4){
+ while(nbrecv(kctl->c, nil));
csetcursor(mc, nil);
return 0;
}
readmouse(mc);
}
+ while(nbrecv(kctl->c, nil));
csetcursor(mc, nil);
return 1;
}
void
+sendlayout(void)
+{
+ char buf[NSHIPS*(1+3+1)+1];
+ int i, n;
+
+ n = 0;
+ for(i = 0; i < nelem(armada); i++){
+ assert(sizeof(buf) - n > 1+3+1);
+ if(i != 0)
+ buf[n++] = ',';
+ n += cell2coords(buf+n, sizeof(buf) - n, armada[i].p);
+ buf[n++] = armada[i].orient == OH? 'h': 'v';
+ }
+ buf[n] = 0;
+
+ chanprint(egress, "layout %s\n", buf);
+ layoutdone++;
+}
+
+void
lmb(Mousectl *mc)
{
Point2 cell;
@@ -672,12 +704,11 @@
switch(gamestate){
case Waiting0:
- for(b = mainbtns; b < mainbtns+nelem(mainbtns); b++){
+ for(b = mainbtns; b < mainbtns+nelem(mainbtns); b++)
if(ptinrect(mc->xy, b->r)){
b->handler(b);
break;
}
- }
break;
case Outlaying:
if(!ptinrect(mc->xy, localboard.bbox))
@@ -684,9 +715,14 @@
break;
if(curship != nil && rectinrect(curship->bbox, localboard.bbox)){
- if(++curship-armada >= nelem(armada))
+ if(++curship >= armada+nelem(armada)){
curship = nil;
- else if(curship != &armada[0])
+ redraw();
+ if(confirmdone(mc))
+ sendlayout();
+ else
+ curship = &armada[0];
+ }else if(curship != &armada[0])
curship->orient = (curship-1)->orient;
nbsend(drawchan, nil);
}
@@ -745,55 +781,6 @@
}
void
-rmb(Mousectl *mc)
-{
- enum {
- PLACESHIP,
- DONE,
- };
- static char *items[] = {
- [PLACESHIP] "relocate ships",
- [DONE] "done",
- nil
- };
- static Menu menu = { .item = items };
- char buf[NSHIPS*(1+3+1)+1];
- int i, n;
-
- if(gamestate != Outlaying)
- return;
-
- mc->xy = addpt(mc->xy, screen->r.min);
- switch(menuhit(3, mc, &menu, _screen)){
- case PLACESHIP:
- if(!layoutdone)
- curship = &armada[0];
- break;
- case DONE:
- if(curship != nil || layoutdone)
- break;
-
- if(!confirmdone(mc))
- break;
-
- n = 0;
- for(i = 0; i < nelem(armada); i++){
- assert(sizeof buf - n > 1+3+1);
- if(i != 0)
- buf[n++] = ',';
- n += cell2coords(buf+n, sizeof buf - n, armada[i].p);
- buf[n++] = armada[i].orient == OH? 'h': 'v';
- }
- buf[n] = 0;
-
- chanprint(egress, "layout %s\n", buf);
- layoutdone++;
- break;
- }
- nbsend(drawchan, nil);
-}
-
-void
mouse(Mousectl *mc)
{
static Mouse oldm;
@@ -809,7 +796,9 @@
nbsend(drawchan, nil);
if((selmatch = matches->update(matches, mc, drawchan)) >= 0){
- if(debug) fprint(2, "selected match id %d title %s\n", matches->entries[selmatch].id, matches->entries[selmatch].title);
+ if(debug) fprint(2, "selected match id %d title %s\n",
+ matches->entries[selmatch].id,
+ matches->entries[selmatch].title);
chanprint(egress, "watch %d\n", matches->entries[selmatch].id);
}
}
@@ -843,9 +832,6 @@
case 2:
mmb(mc);
break;
- case 4:
- rmb(mc);
- break;
}
oldm = mc->Mouse;
@@ -863,6 +849,7 @@
switch(r){
case Kdel:
threadexitsall(nil);
+ case Kesc:
case 'q':
if(gamestate == Waiting0)
threadexitsall(nil);
@@ -1178,6 +1165,7 @@
resize();
mctl = mc;
+ kctl = kc;
if((user = getenv("user")) == nil)
user = getuser();
snprint(uid, sizeof uid, "%s", user);