From d87fb23a937783e20bb1ff1d09899edf6cae39de Mon Sep 17 00:00:00 2001 From: rodri Date: Thu, 26 Aug 2021 20:04:59 +0000 Subject: [PATCH] bring games/swar from 1ed sources. --- sys/src/games/mkfile | 1 + sys/src/games/swar/accel.h | 16 ++ sys/src/games/swar/boom.icon | 67 +++++ sys/src/games/swar/deathstar.icon | 16 ++ sys/src/games/swar/missile.icon | 35 +++ sys/src/games/swar/mkfile | 10 + sys/src/games/swar/player0.icon | 47 ++++ sys/src/games/swar/player1.icon | 47 ++++ sys/src/games/swar/swar.c | 430 ++++++++++++++++++++++++++++++ 9 files changed, 669 insertions(+) create mode 100644 sys/src/games/swar/accel.h create mode 100644 sys/src/games/swar/boom.icon create mode 100644 sys/src/games/swar/deathstar.icon create mode 100644 sys/src/games/swar/missile.icon create mode 100644 sys/src/games/swar/mkfile create mode 100644 sys/src/games/swar/player0.icon create mode 100644 sys/src/games/swar/player1.icon create mode 100644 sys/src/games/swar/swar.c diff --git a/sys/src/games/mkfile b/sys/src/games/mkfile index 89477b88f..066a792f8 100644 --- a/sys/src/games/mkfile +++ b/sys/src/games/mkfile @@ -46,6 +46,7 @@ DIRS=\ snes\ sokoban\ sudoku\ + swar\ timmy\ v8e\ diff --git a/sys/src/games/swar/accel.h b/sys/src/games/swar/accel.h new file mode 100644 index 000000000..6eab0923e --- /dev/null +++ b/sys/src/games/swar/accel.h @@ -0,0 +1,16 @@ +512, 0, +473, 196, +362, 362, +196, 473, +0, 512, +-196, 473, +-362, 362, +-473, 196, +-512, 0, +-473, -196, +-362, -362, +-196, -473, +0, -512, +196, -473, +362, -362, +473, -196, diff --git a/sys/src/games/swar/boom.icon b/sys/src/games/swar/boom.icon new file mode 100644 index 000000000..1432d9c38 --- /dev/null +++ b/sys/src/games/swar/boom.icon @@ -0,0 +1,67 @@ +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ .......x........", +"................ ................ ................ .....x.x........", +"................ ........x....... .......x.x...... .....x.x..x.....", +"........x....... ......x.x....... .......xxx...... .........xxx....", +"......xxx....... ......xxx....... ......xx........ ......xx........", +".......x........ ........xx...... .......xx....... .....xxxxx......", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", +"................ ................ ................ ................", + +"................ ................ ................ ................", +"................ ................ ................ x.x.......x....x", +"................ ........xx...... ....x.xx.x....x. ..x........x....", +"................ .........x...... ...xx..x....x... .x.x...xxx.x....", +"......x......... ....x.xxx....... ..x.xx......x... ..xxxx..xx..x...", +".....xxxxxx..... .....xxxx.x..... ..xx.xxxxx.x.x.. ..x.x..x.x..xx..", +".....x.x..xx.... ...........x.... ...x....x.x..x.. .x....x..xxxx...", +"...xxx.x.xx..... .....x.xx..x.... ...xxxxx..x.x... ....xx..xxxx..x.", +".....x.x.xx..... ....xx.xx....... ..xx.xx.x.xx.... ..xxx.xx.xx.....", +"......x.xx...... ....x..xx....... ..xx.xx.....x... ...x.xx...x.x...", +"....x.x..xx..... .....xx.x.x..... ....xxx......... ..xxxx..x...x...", +".....xx....x.... .........xx..... ...x....xxx..... ..x.x..xx.xxx...", +"................ ........xx...... ....x..xx.x.x... ....xx.xx.x.....", +"................ ................ ...x......x..... ...xxxxx.x...x..", +"................ ................ ................ ...xxxx..x...x..", +"................ ................ ................ ................", + +"................ ................ ................ ................", +".......x..x..... .......x..x..... .......x..x..... .......x..x.....", +"......x......... ......x......... ......x......... ................", +"....x.x...x.x.x. ....x.x...x.x.x. ....x.x...x.x.x. ....x.....x.x.x.", +"...xx.xx.xx.x.x. ...xx.xx.xx.x.x. ...xx.xx.xx.x.x. ...xx.xx.xx.x.x.", +"..x..xxxx.xx.x.x ..x..xx.x.x..x.x ......x.x.x..x.x ........x.x..x.x", +"...xx.x.x.x...x. ....x.x.x.....x. ....x.x.......x. ..............x.", +"..x.x.x.x.xx.xx. ..x.x...x.xx.xx. ..x.x.....xx.xx. ..x.......xx.xx.", +"...xx.xxxxx..x.. ...xx.x.xxx..x.. ...x..x......x.. ...x..x......x..", +"...xxx.xxx.xxxx. ...xx...x..xxxx. ...xx...x..xx.x. ...xx.......x.x.", +"x.x.xx.xx.x.x.x. x.x.xx.xx...x.x. x.x.x..xx...x.x. x...x.......x.x.", +"....xx.xx.xx.x.. ....xx..x.xx.x.. ....xx..x.x..x.. ....x...x.x..x..", +"...x...x...xx... ...x...x...xx... ...x...x....x... ...x...x....x...", +"....xx...x..x... ....xx...x..x... ....xx...x...... ....xx...x......", +"....x.x.x....... ....x.x.x....... ....x.x.x....... ....x.x.x.......", +"................ ................ ................ ................", + +"................ ................ ................ ................", +".......x..x..... .......x..x..... .......x..x..... .......x..x.....", +"................ ................ ................ ................", +"....x.....x.x.x. ....x.......x.x. ....x.......x.x. ....x.......x...", +"...xx..x.x..x... ...x...x.x...... ...x...x........ ...x............", +"........x.x..x.x ........x.x..x.x ........x.x....x ..........x....x", +"................ ................ ................ ................", +"..x.......x..xx. ..x..........xx. ..x..........xx. ..x...........x.", +"...x..x......x.. ...x..x......x.. ................ ................", +"...xx.........x. ...x..........x. ...x..........x. ...x..........x.", +"x.............x. x............... x............... ................", +"........x.x..x.. ........x.x..x.. ..........x..x.. ................", +"...x...x....x... ...x...x....x... ...x...x....x... ...x...x....x...", +"....x....x...... ....x....x...... .........x...... .........x......", +"....x.x.x....... ....x...x....... ....x...x....... ....x...x.......", +"................ ................ ................ ................", diff --git a/sys/src/games/swar/deathstar.icon b/sys/src/games/swar/deathstar.icon new file mode 100644 index 000000000..5e4034190 --- /dev/null +++ b/sys/src/games/swar/deathstar.icon @@ -0,0 +1,16 @@ +". . . . . x x x x x x . . . . .", +". . . x x x x x . . . . x . . .", +". . . . . . . . . . . . . . . .", +". x x x x x x x x x x x x x x .", +". . x x x x x x x x . . . . x .", +". . . . . . . . . . . . . . . .", +"x x x x x x x x x x x x x x x x", +". x x x x x x x x x . . . . . x", +". . . . . . . . . . . . . . . .", +"x x x x x x x x x x x x x x x x", +". . . x x x x x . . . . . . . x", +". . . . . . . . . . . . . . . .", +". x x x x x x x x x x x x x x .", +". . . . . . . . . . . . . . . .", +". . . x . . . . . . . . x . . .", +". . . . . x x x x x x . . . . .", diff --git a/sys/src/games/swar/missile.icon b/sys/src/games/swar/missile.icon new file mode 100644 index 000000000..8e8f3e4d7 --- /dev/null +++ b/sys/src/games/swar/missile.icon @@ -0,0 +1,35 @@ +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", +". x x x . x x . . x x x . x x . . x x x . x x . . x x . . x x .", +". x . . x . x . . x . . x . x . . x . . . x x . . x x . . . x .", +"x x . . . . x x x x . . . x x x x . . x x . . x x x . x . x . x", +"x x x x x . x x x x . x . x x x x . . . x x x x x x x . . . x x", +". x . . . . x . . x . . . . x . . x . x x . x . . x x . . . x .", +". x x . x x x . . x x . x x x . . x x x . x x . . x x x . x x .", +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", + +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", +". x x x . x x . . x x x x x x . . x x . x x x . . x x x x x x .", +". x x x x x x . . x x x . x x . . x x x x . x . . x . x x x x .", +"x . . x x x . x x . . . x . x x x . x x . x . x x x . . . . x x", +"x . . . . x x x x x . x . x . x x . x x x . . x x . . . x x . x", +". x . . . x x . . x . . . . x . . x . x x x x . . x . . x . x .", +". x x . x x x . . x x . . x x . . x x x . x x . . x x . . x x .", +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", + +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", +". x x . . x x . . x x . x x x . . x x x x x x . . x x x x x x .", +". x . x . . x . . x . . x x x . . x . . . x x . . x . x . x x .", +"x . x x . x x x x x . x x . . x x x x . . . x x x x . x . x x x", +"x . . x . x . x x . x x x x x x x x . x x . . x x . x . . . x x", +". x . . . . x . . x x . . . x . . x x x x x x . . x . x x . x .", +". x x . . x x . . x x . . x x . . x x . . x x . . x x . . x x .", +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", + +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", +". x x . . x x . . x x . . x x . . x x x . x x . . x x x . x x .", +". x . . x x x . . x x . . . x . . x x x . . x . . x x x . . x .", +"x x . x . . . x x x . x x . . x x x . x x . . x x . x x x . x x", +"x . x x x . . x x . x . x x . x x x x . . . . x x x x . . . . x", +". x . . x . x . . x . x . x x . . x . x . . x . . x x x x x x .", +". x x x . x x . . x x x . x x . . x x x x x x . . x x x . x x .", +". . . x x . . . . . . x x . . . . . . x x . . . . . . x x . . .", diff --git a/sys/src/games/swar/mkfile b/sys/src/games/swar/mkfile new file mode 100644 index 000000000..c13716510 --- /dev/null +++ b/sys/src/games/swar/mkfile @@ -0,0 +1,10 @@ + +#include +#include +#include +int xc, yc; +#define NOBJ (1+2+6*2) +#define MSPEED (V/32) /* speed of missile relative to ship */ +#define SZ 512 /* maximum scaled coordinate */ +#define V 256 /* velocity scale factor */ +#define G (V*11585) /* 11585 is SZ**(3./2.) */ +#define ALIVE 1 +#define DEAD 2 +#define SUN 3 +#define BOOM 4 +#define HYPER 5 +#define SLEEP 40 /* ms per iteration */ +#define TUBA (2000/SLEEP) /* iterations until born again */ +#define HYTIME ((600+rand()%600)/SLEEP) /* iterations in hyperspace */ +char *starbits[]={ +#include "deathstar.icon" +}; +Image *stardwg; +Rectangle starrect={0, 0, 16, 16}; +char *p0bits[]={ +#include "player0.icon" +}; +Image *p0dwg; +Rectangle p0rect={0, 0, 44, 44}; +char *p1bits[]={ +#include "player1.icon" +}; +Image *p1dwg; +Rectangle p1rect={0, 0, 44, 44}; +char *misbits[]={ +#include "missile.icon" +}; +Image *misdwg; +Rectangle misrect={0, 0, 32, 32}; +char *boombits[]={ +#include "boom.icon" +}; +Image *boomdwg; +Rectangle boomrect={0, 0, 64, 64}; +struct obj{ + int x, y; + int vx, vy; /* scaled by V */ + int orientation; + int state; + int diameter; + Image *bp; + int curdwg; +#define wrapped timer + int timer; +}obj[NOBJ], iobj[]={ + {0, 0, 0, 0, 0, SUN, 16}, + { 300, 0, 0, 5*V, 8, ALIVE, 11, 0, 0, TUBA}, + {-300, 0, 0, -5*V, 0, ALIVE, 11, 0, 0, TUBA}, + {0, 0, 0, 0, 0, ALIVE, 8}, +}; +#define ATT (&obj[0]) +#define P0 (&obj[1]) +#define P1 (&obj[2]) +int score[3]; +#define NORIENTATION 16 +struct dv{ + int x, y; +}dv[NORIENTATION]={ +#include "accel.h" +}; + +int xc, yc, size; +void kbdplayer(int c); +void hyper(struct obj *o); +void right(struct obj *o); +void left(struct obj *o); +void jerk(struct obj *o); +int isqrt(int x); +void fire(struct obj *o); +void initobj(struct obj *o); +void deathto(struct obj *o, int doboom); +void boom(struct obj *o); +void shards(struct obj *o); +void move(struct obj *o); +void blot(struct obj *o, int dwg); +void collide(struct obj *o, struct obj *p); +void newscore(struct obj *o, struct obj *p); +void drawscore(char *str, int sc, int where); +void doscore(void); +Image *initbitmap(char *bits[], Rectangle r); + +#define sq(x) ((x)*(x)) +#define muldiv(a, b, c) ((a)*(b)/(c)) + +int +min(int a, int b) +{ + return ar, display->black, nil, ZP); + blot(ATT, ATT->orientation); + doscore(); +} + +void +eresized(int) +{ + if(getwindow(display, Refnone) < 0) + sysfatal("resized"); + xc=(screen->r.min.x+screen->r.max.x)/2; + yc=(screen->r.min.y+screen->r.max.y)/2; + size=min(screen->r.max.x-screen->r.min.x, + screen->r.max.y-screen->r.min.y)/2; + redraw(); +} + +void +main(void) +{ + struct obj *o, *p; + + initdraw(nil,nil,nil); + einit(Ekeyboard|Emouse); + + iobj[0].bp = stardwg = initbitmap(starbits, starrect); + iobj[1].bp = p0dwg = initbitmap(p0bits, p0rect); + iobj[2].bp = p1dwg = initbitmap(p1bits, p1rect); + iobj[3].bp = misdwg = initbitmap(misbits, misrect); + boomdwg = initbitmap(boombits, boomrect); + + xc=(screen->r.min.x+screen->r.max.x)/2; + yc=(screen->r.min.y+screen->r.max.y)/2; + size=min(screen->r.max.x-screen->r.min.x, + screen->r.max.y-screen->r.min.y)/2; + + for(o=obj;o<=P1;o++) + initobj(o); + + for(;o!=&obj[NOBJ];o++) + o->state=DEAD; + + for(;;){ + redraw(); + for(o=obj;o!=&obj[NOBJ];o++){ + switch(o->state){ + case ALIVE: + case SUN: + for(p=o+1;p!=&obj[NOBJ];p++) + if(p->state!=DEAD) + collide(o, p); + if(o>P1) + left(o); + move(o); + break; + case HYPER: + if(--o->timer==0){ + blot(o, o->curdwg); + o->state=ALIVE; + if(rand()%4==0){ + deathto(o, 1); + newscore(ATT, o); + } + }else + move(o); + break; + case DEAD: + if((o==P0 || o==P1) && --o->timer==0) + initobj(o); + break; + case BOOM: + shards(o); + move(o); + break; + } + } + flushimage(display, 1); + while(ecanmouse()) emouse(); + if(ecankbd()) kbdplayer(ekbd()); + sleep(SLEEP); + } +} +void kbdplayer(int c){ + switch(c){ + case 'k': left(P0); break; + case 'o': jerk(P0); break; + case ';': right(P0); break; + case 'l': fire(P0); break; + case '.': + case ',': hyper(P0); break; + case 'a': left(P1); break; + case 'w': jerk(P1); break; + case 'd': right(P1); break; + case 's': fire(P1); break; + case 'z': + case 'x': hyper(P1); break; + case 'Q': exits(""); break; + } +} +void hyper(struct obj *o){ + if(o->state!=ALIVE) + return; + o->state=HYPER; + o->timer=HYTIME; + blot(o, o->curdwg); +} +void right(struct obj *o){ + if(++o->orientation==NORIENTATION) + o->orientation=0; +} +void left(struct obj *o){ + if(--o->orientation<0) + o->orientation=NORIENTATION-1; +} +void jerk(struct obj *o){ + o->vx+=dv[o->orientation].x/2; + o->vy+=dv[o->orientation].y/2; +} +int isqrt(int x){ + int s, u; + if(x<=0) + return(0); + if(x>=32768L*(32768L/4)) + return(2*isqrt(x/4)); /* avoid overflow */ + for(s=2, u=4;u>1)state!=ALIVE) + return; + for(m=o+2;m<&obj[NOBJ];m+=2) + if(m->state==DEAD){ + initobj(m); + m->state=ALIVE; + vl=isqrt(sq(o->vx)+sq(o->vy)); + if(vl==0) + vl=V; + vx=muldiv(vl, dv[o->orientation].x, V); + vy=muldiv(vl, dv[o->orientation].y, V); + m->x=o->x+muldiv(vx, (o->diameter+m->diameter), vl); + m->y=o->y+muldiv(vy, (o->diameter+m->diameter), vl); + m->vx=o->vx+MSPEED*dv[o->orientation].x; + m->vy=o->vy+MSPEED*dv[o->orientation].y; + blot(m, m->orientation); + return; + } +} +void initobj(struct obj *o){ + *o=(o>P1)?iobj[P1-obj+1]:iobj[o-obj]; + if(o<=P1) + blot(o, o->orientation); +} +void deathto(struct obj *o, int doboom){ + o->state=DEAD; + blot(o, o->curdwg); + if(doboom) + boom(o); +} +void boom(struct obj *o){ + o->state=BOOM; + o->bp=boomdwg; + o->diameter=boomdwg->r.max.x/4; + blot(o, o->orientation=0); +} +void shards(struct obj *o){ + if(++o->orientation==16){ + blot(o, o->curdwg); + o->state=DEAD; + o->timer=TUBA; + } +} +void move(struct obj *o){ + int r32; + int x, y; + if(o->state==DEAD || o->state==SUN) + return; + r32=o->x*o->x+o->y*o->y; + if(r32!=0){ + r32*=isqrt(r32); /* pow(r, 3./2.) */ + if(r32!=0){ + o->vx-=G*o->x/r32; + o->vy-=G*o->y/r32; + } + } + x=o->x+o->vx/V; + y=o->y+o->vy/V; + if(x<-SZ || SZP1 && o->wrapped){ + Death: + deathto(o, 0); + return; + } + if(x<-SZ) x+=2*SZ; else x-=2*SZ; + o->wrapped++; + } + if(y<-SZ || SZP1 && o->wrapped) + goto Death; + if(y<-SZ) y+=2*SZ; else y-=2*SZ; + o->wrapped++; + } + if(o->state!=HYPER) + blot(o, o->curdwg); + o->x=x, o->y=y; + if(o->state!=HYPER) + blot(o, o->orientation); +} + +#define BLOTSIZE 5 +#define rescale(x) muldiv(x, size, SZ) + +void +blot(struct obj *o, int dwg) +{ + Point p; + int dx = dwg % 4*o->diameter, dy = dwg / 4*o->diameter; + + p = Pt(rescale(o->x)+xc-o->diameter/2, rescale(o->y)+yc-o->diameter/2); + + draw(screen, rectaddpt(Rect(dx,dy,dx+o->diameter,dy+o->diameter),p), o->bp, nil, Pt(dx, dy)); + o->curdwg = dwg; +} + +void +collide(struct obj *o, struct obj *p) +{ + int doneboom; + /* o

state!=HYPER && p->state!=HYPER + && sq(rescale(o->x-p->x))+sq(rescale(o->y-p->y))< + sq(o->diameter+p->diameter)/4){ + newscore(o, p); + if(doneboom=o->state==ALIVE) + deathto(o, 1); + if(p->state==ALIVE) + deathto(p, !doneboom || (o==P0 && p==P1)); + } +} + +void +newscore(struct obj *o, struct obj *p) +{ + doscore(); + /* o

r.min.x + 20; + else if(where == 1) + s = (screen->r.min.x + screen->r.max.x - stringwidth(font, p))/2; + else + s = screen->r.max.x - stringwidth(font, p) - 20; + + draw(screen, Rpt(Pt(s, screen->r.min.y+5),Pt(s+stringwidth(font, p), screen->r.min.y+5+font->height)), display->black, nil, ZP); + string(screen, Pt(s, screen->r.min.y+5), display->white, ZP, font, p); +} + +void +doscore(void) +{ + drawscore(" MCI", score[0], 0); + drawscore(" AT&T", score[2], 1); + drawscore(" SPRINT", score[1], 2); +} + +Image * +initbitmap(char *bits[], Rectangle r) +{ + Point p; + char *bit; + Image *b=allocimage(display, r, screen->chan, 0, DTransparent); + + if(b==0) + sysfatal("allocimage: %r"); + + for(p.y = r.min.y; p.y != r.max.y; p.y++){ + bit = bits[p.y-r.min.y]; + for(p.x = r.min.x; p.x != r.max.x; p.x++){ + while(*bit==' ') + bit++; + if(*bit++=='x') + draw(b, Rpt(p,addpt(p,Pt(1,1))), display->white, nil, ZP); + } + } + return b; +}