ref: 786f41cb2f7787933a0f939a221728b844776702
parent: e06ad3c9310136ded262e1e0370dadd83db0b066
author: rodri <rgl@antares-labs.eu>
date: Thu Sep 28 12:13:43 EDT 2023
got rid of static Image pointers in favor of a global color palette.
--- a/bts.c
+++ b/bts.c
@@ -10,6 +10,20 @@
#include "fns.h"
enum {
+ PCBlack,
+ PCWhite,
+ PCRed,
+ PCGreen,
+ PCShip,
+ PCYellow,
+ PCBlue,
+ PCWater,
+ PCWaves,
+ PCShadow,
+ NCOLORS
+};
+
+enum {
CMid,
CMqueued,
CMlayout,
@@ -119,6 +133,7 @@
Channel *ingress, *egress;
Mousectl *mctl; /* only used to update the cursor */
RFrame worldrf;
+Image *pal[NCOLORS];
Image *screenb;
Image *tiletab[NTILES];
Board alienboard;
@@ -303,7 +318,7 @@
{
static char s[] = "BATTLESHIP";
- string(dst, Pt(SCRW/2 - stringwidth(titlefont, s)/2, 0), display->white, ZP, titlefont, s);
+ string(dst, Pt(SCRW/2 - stringwidth(titlefont, s)/2, 0), pal[PCWhite], ZP, titlefont, s);
}
void
@@ -311,13 +326,12 @@
{
static char s[] = "press p to play, w to watch";
- string(dst, Pt(SCRW/2 - stringwidth(font, s)/2, 10*font->height+5), display->white, ZP, font, s);
+ string(dst, Pt(SCRW/2 - stringwidth(font, s)/2, 10*font->height+5), pal[PCWhite], ZP, font, s);
}
void
drawinfo(Image *dst)
{
- static Image *c;
Point p;
char *s, aux[32], aux2[32];
int i;
@@ -334,35 +348,32 @@
case Playing: s = "your turn"; break;
}
p = Pt(SCRW/2 - stringwidth(font, s)/2, 0);
- string(dst, p, display->white, ZP, font, s);
+ string(dst, p, pal[PCWhite], ZP, font, s);
s = "TARGET";
p = subpt(alienboard.bbox.min, Pt(font->width+2,0));
- vstring(dst, p, display->white, ZP, font, s);
+ vstring(dst, p, pal[PCWhite], ZP, font, s);
s = "LOCAL";
p = Pt(localboard.bbox.max.x+2, localboard.bbox.min.y);
- vstring(dst, p, display->white, ZP, font, s);
+ vstring(dst, p, pal[PCWhite], ZP, font, s);
p = Pt(alienboard.bbox.max.x+2, alienboard.bbox.min.y);
- vstring(dst, p, display->white, ZP, font, game.state == Watching? match.pl[1].uid: oid);
+ vstring(dst, p, pal[PCWhite], ZP, font, game.state == Watching? match.pl[1].uid: oid);
p = subpt(localboard.bbox.min, Pt(font->width+2,0));
- vstring(dst, p, display->white, ZP, font, game.state == Watching? match.pl[0].uid: uid);
+ vstring(dst, p, pal[PCWhite], ZP, font, game.state == Watching? match.pl[0].uid: uid);
+ /* TODO make this an info panel and show errors from bad transactions. */
if(game.state == Outlaying){
- if(c == nil)
- c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellow);
if(curship != nil){
snprint(aux, sizeof aux, "%s (%d)", shipname(curship-armada), curship->ncells);
p = Pt(SCRW/2 - stringwidth(font, aux)/2, SCRH-Boardmargin);
- string(dst, p, c, ZP, font, aux);
+ string(dst, p, pal[PCYellow], ZP, font, aux);
}else{
s = "done with the layout?";
p = Pt(SCRW/2 - stringwidth(font, s)/2, SCRH-Boardmargin);
- string(dst, p, c, ZP, font, s);
+ string(dst, p, pal[PCYellow], ZP, font, s);
}
}else if(game.state == Watching){
- if(c == nil)
- c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DYellow);
snprint(aux, sizeof aux, "waiting for players to");
snprint(aux2, sizeof aux2, "lay out their fleet");
for(i = 0; i < nelem(match.pl); i++)
@@ -371,9 +382,9 @@
aux2[0] = 0;
}
p = Pt(SCRW/2 - stringwidth(font, aux)/2, SCRH-Boardmargin);
- string(dst, p, c, ZP, font, aux);
+ string(dst, p, pal[PCBlue], ZP, font, aux);
p = Pt(SCRW/2 - stringwidth(font, aux2)/2, SCRH-Boardmargin+font->height);
- string(dst, p, c, ZP, font, aux2);
+ string(dst, p, pal[PCBlue], ZP, font, aux2);
}
}
@@ -380,17 +391,14 @@
void
drawconclusion(Image *dst)
{
- static Image *shadow;
static char s[] = "press any key to continue";
if(conclusion.s == nil)
return;
- if(shadow == nil)
- shadow = eallocimage(display, Rect(0,0,1,1), RGBA32, 1, 0x0000007f);
- draw(dst, dst->r, shadow, nil, ZP);
+ draw(dst, dst->r, pal[PCShadow], nil, ZP);
string(dst, Pt(SCRW/2 - stringwidth(font, conclusion.s)/2, font->height+5), conclusion.c, ZP, font, conclusion.s);
- string(dst, Pt(SCRW/2 - stringwidth(font, s)/2, 10*font->height+5), display->white, ZP, font, s);
+ string(dst, Pt(SCRW/2 - stringwidth(font, s)/2, 10*font->height+5), pal[PCWhite], ZP, font, s);
}
void
@@ -398,7 +406,7 @@
{
lockdisplay(display);
- draw(screenb, screenb->r, display->black, nil, ZP);
+ draw(screenb, screenb->r, pal[PCBlack], nil, ZP);
switch(game.state){
case Waiting0:
drawtitle(screenb);
@@ -443,9 +451,23 @@
}
void
+initpalette(void)
+{
+ pal[PCBlack] = display->black;
+ pal[PCWhite] = display->white;
+ pal[PCRed] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
+ pal[PCGreen] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
+ pal[PCShip] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAAAAAAFF);
+ pal[PCYellow] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DDarkyellow);
+ pal[PCWater] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreyblue);
+ pal[PCWaves] = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalebluegreen);
+ pal[PCBlue] = pal[PCWaves];
+ pal[PCShadow] = eallocimage(display, Rect(0,0,1,1), RGBA32, 1, 0x0000007f);
+}
+
+void
inittiles(void)
{
- Image *brush;
int i, x, y;
Point pts[2];
@@ -453,44 +475,30 @@
tiletab[i] = eallocimage(display, Rect(0,0,TW,TH), screen->chan, 0, DNofill);
switch(i){
case Twater:
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalegreyblue);
- draw(tiletab[i], tiletab[i]->r, brush, nil, ZP);
- freeimage(brush);
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DPalebluegreen);
+ draw(tiletab[i], tiletab[i]->r, pal[PCWater], nil, ZP);
for(pts[0] = ZP, x = 0; x < TW; x++){
y = sin(x)*TH/2;
pts[1] = Pt(x,y+TH/2);
- line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 0, brush, ZP);
+ line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 0, pal[PCWaves], ZP);
pts[0] = pts[1];
}
- freeimage(brush);
break;
case Tship:
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAAAAAAFF);
- draw(tiletab[i], tiletab[i]->r, brush, nil, ZP);
- freeimage(brush);
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DBlack);
- fillellipse(tiletab[i], Pt(TW/2,TH/2), 2, 2, brush, ZP);
- freeimage(brush);
+ draw(tiletab[i], tiletab[i]->r, pal[PCShip], nil, ZP);
+ fillellipse(tiletab[i], Pt(TW/2,TH/2), 2, 2, pal[PCBlack], ZP);
break;
case Thit:
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
- draw(tiletab[i], tiletab[i]->r, brush, nil, ZP);
- freeimage(brush);
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DBlack);
+ draw(tiletab[i], tiletab[i]->r, pal[PCRed], nil, ZP);
pts[0] = Pt(TW/2-TW/4,TH/2-TH/4);
pts[1] = Pt(TW/2+TW/4,TH/2+TH/4);
- line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 1, brush, ZP);
+ line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 1, pal[PCBlack], ZP);
pts[0].y += TH/2;
pts[1].y -= TH/2;
- line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 1, brush, ZP);
- freeimage(brush);
+ line(tiletab[i], pts[0], pts[1], Endsquare, Endsquare, 1, pal[PCBlack], ZP);
break;
case Tmiss:
draw(tiletab[i], tiletab[i]->r, tiletab[Twater], nil, ZP);
- brush = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DWhite);
- ellipse(tiletab[i], Pt(TW/2,TH/2), 6, 6, 1, brush, ZP);
- freeimage(brush);
+ ellipse(tiletab[i], Pt(TW/2,TH/2), 6, 6, 1, pal[PCWhite], ZP);
break;
}
}
@@ -759,12 +767,9 @@
void
celebrate(void)
{
- static Image *c;
static char s[] = "YOU WON!";
- if(c == nil)
- c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
- conclusion.c = c;
+ conclusion.c = pal[PCGreen];
conclusion.s = s;
}
@@ -771,12 +776,9 @@
void
keelhaul(void)
{
- static Image *c;
static char s[] = "…YOU LOST";
- if(c == nil)
- c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DRed);
- conclusion.c = c;
+ conclusion.c = pal[PCRed];
conclusion.s = s;
}
@@ -783,18 +785,13 @@
void
announcewinner(char *winner)
{
- static Image *c;
static char s[16];
if(winner == nil)
return;
- /* TODO build a global color palette. this static color referencing is BS. */
- if(c == nil)
- c = eallocimage(display, Rect(0,0,1,1), screen->chan, 1, DGreen);
-
snprint(s, sizeof s, "%s WON", winner);
- conclusion.c = c;
+ conclusion.c = pal[PCGreen];
conclusion.s = s;
}
@@ -1025,11 +1022,14 @@
if(titlefont == nil)
sysfatal("openfont: %r");
+ initpalette();
inittiles();
initboards();
initarmada();
matches = newmenulist(14*font->height, "ongoing matches");
game.state = Waiting0;
+
+ /* TODO add sfx */
drawchan = chancreate(sizeof(void*), 1);
ingress = chancreate(sizeof(char*), 1);