Annotation of researchv9/jtools/src/demo/swar/swar.c, revision 1.1.1.1

1.1       root        1: /*% mcc -g % -o swar
                      2:  * swar -- jerq space war
                      3:  * td&rob 84.01.01
                      4:  */
                      5: #include <jerq.h>
                      6: #undef min
                      7: Bitmap ToBitmap();
                      8: 
                      9: int xc, yc;
                     10: #define        NOBJ    (1+2+6*2)
                     11: #define        MSPEED  (V/32)          /* speed of missile relative to ship */
                     12: #define        SZ      512             /* maximum scaled coordinate */
                     13: #define        V       256             /* velocity scale factor */
                     14: #define        G       ((long)V*11585) /* 11585 is SZ**(3./2.) */
                     15: #define        ALIVE   1
                     16: #define        DEAD    2
                     17: #define        SUN     3
                     18: #define        BOOM    4
                     19: #define        HYPER   5
                     20: #define        SLEEP   2               /* ticks per iteration */
                     21: #define        TUBA    (120/SLEEP)     /* ticks until born again */
                     22: #define        HYTIME  ((40+rand()%40)/SLEEP)
                     23: short starbits[]={
                     24: #include "deathstar.icon"
                     25: };
                     26: Bitmap stardwg;
                     27: short p0bits[]={
                     28: #include "player0.icon"
                     29: };
                     30: Bitmap p0dwg;
                     31: short p1bits[]={
                     32: #include "player1.icon"
                     33: };
                     34: Bitmap p1dwg;
                     35: short misbits[]={
                     36: #include "missile.icon"
                     37: };
                     38: Bitmap misdwg;
                     39: short boombits[]={
                     40: #include "boom.icon"
                     41: };
                     42: Bitmap boomdwg;
                     43: struct obj{
                     44:        int x, y;
                     45:        long vx, vy;            /* scaled by V */
                     46:        int orientation;
                     47:        int state;
                     48:        int diameter;
                     49:        Bitmap *bp;
                     50:        int curdwg;
                     51: #define        wrapped timer
                     52:        int timer;
                     53: }obj[NOBJ], iobj[]={
                     54:        {0, 0, 0, 0, 0, SUN, 16, &stardwg},
                     55:        { 300, 0, 0,  5*V, 8, ALIVE, 11, &p0dwg, 0, TUBA},
                     56:        {-300, 0, 0, -5*V, 0, ALIVE, 11, &p1dwg, 0, TUBA},
                     57:        {0, 0, 0, 0, 0, ALIVE, 8, &misdwg},
                     58: };
                     59: #define        ATT     (&obj[0])
                     60: #define        P0      (&obj[1])
                     61: #define        P1      (&obj[2])
                     62: int score[3];
                     63: #define        NORIENTATION    16
                     64: struct dv{
                     65:        long x, y;
                     66: }dv[NORIENTATION]={
                     67: #include "accel.h"
                     68: };
                     69: int xc, yc, size;
                     70: #define        sq(x)   ((long)(x)*(long)(x))
                     71: int min(a, b){return(a<b?a:b);}
                     72: long lmin(a, b)long a,b;{return(a<b?a:b);}
                     73: int abs(a){return(a<0?-a:a);}
                     74: main(argc,argv){
                     75:        register i;
                     76:        register struct obj *o, *p;
                     77:        request(KBD);
                     78:        initdisplay(argc,argv);
                     79:        stardwg=ToBitmap((char *)starbits, 4, 0, 0, 16, 16);
                     80:        p0dwg=ToBitmap((char *)p0bits, 8, 0, 0, 44, 44);
                     81:        p1dwg=ToBitmap((char *)p1bits, 8, 0, 0, 44, 44);
                     82:        misdwg=ToBitmap((char *)misbits, 4, 0, 0, 32, 32);
                     83:        boomdwg=ToBitmap((char *)boombits, 8, 0, 0, 64, 64);
                     84:        xc=(Drect.origin.x+Drect.corner.x)/2;
                     85:        yc=(Drect.origin.y+Drect.corner.y)/2;
                     86:        size=min(Drect.corner.x-Drect.origin.x,
                     87:                Drect.corner.y-Drect.origin.y)/2;
                     88:        rectf (&display, Drect, F_XOR);
                     89:        for(o=obj;o<=P1;o++)
                     90:                initobj(o);
                     91:        for(;o!=&obj[NOBJ];o++)
                     92:                o->state=DEAD;
                     93:        doscore();
                     94:        for(;;){
                     95:                for(o=obj;o!=&obj[NOBJ];o++){
                     96:                        switch(o->state){
                     97:                        case ALIVE:
                     98:                        case SUN:
                     99:                                for(p=o+1;p!=&obj[NOBJ];p++)
                    100:                                        if(p->state!=DEAD)
                    101:                                                collide(o, p);
                    102:                                if(o>P1)
                    103:                                        left(o);
                    104:                                move(o);
                    105:                                break;
                    106:                        case HYPER:
                    107:                                if(--o->timer==0){
                    108:                                        blot(o, o->curdwg);
                    109:                                        o->state=ALIVE;
                    110:                                        if(rand()%4==0){
                    111:                                                deathto(o, 1);
                    112:                                                newscore(ATT, o);
                    113:                                        }
                    114:                                }else
                    115:                                        move(o);
                    116:                                break;
                    117:                        case DEAD:
                    118:                                if((o==P0 || o==P1) && --o->timer==0)
                    119:                                        initobj(o);
                    120:                                break;
                    121:                        case BOOM:
                    122:                                shards(o);
                    123:                                move(o);
                    124:                                break;
                    125:                        }
                    126:                }
                    127:                if(own()&KBD)
                    128:                        kbdplayer(kbdchar());
                    129:                sleep(SLEEP);
                    130:        }
                    131: }
                    132: kbdplayer(c){
                    133:        switch(c){
                    134:        case ';': left(P0);     break;
                    135:        case 'o': jerk(P0);     break;
                    136:        case 'k': right(P0);    break;
                    137:        case 'l': fire(P0);     break;
                    138:        case '/':
                    139:        case '.': hyper(P0);    break;
                    140:        case 'a':  left(P1);    break;
                    141:        case 'w':  jerk(P1);    break;
                    142:        case 'd':  right(P1);   break;
                    143:        case 's':  fire(P1);    break;
                    144:        case 'z':
                    145:        case 'x':  hyper(P1);   break;
                    146:        case 'Q':  exit();      break;
                    147:        }
                    148: }
                    149: hyper(o)
                    150: register struct obj *o;
                    151: {
                    152:        if(o->state!=ALIVE)
                    153:                return;
                    154:        o->state=HYPER;
                    155:        o->timer=HYTIME;
                    156:        blot(o, o->curdwg);
                    157: }
                    158: right(o)
                    159: register struct obj *o;
                    160: {
                    161:        if(++o->orientation==NORIENTATION)
                    162:                o->orientation=0;
                    163: }
                    164: left(o)
                    165: register struct obj *o;
                    166: {
                    167:        if(--o->orientation<0)
                    168:                o->orientation=NORIENTATION-1;
                    169: }
                    170: jerk(o)
                    171: register struct obj *o;
                    172: {
                    173:        o->vx+=dv[o->orientation].x/2;
                    174:        o->vy+=dv[o->orientation].y/2;
                    175: }
                    176: long isqrt(x)
                    177: register long x;
                    178: {
                    179:        register long s, u;
                    180:        if(x<=0)
                    181:                return(0);
                    182:        if(x>=32768L*(32768L/4))
                    183:                return(2*isqrt(x/4));   /* avoid overflow */
                    184:        for(s=2, u=4;u<x;s+=s, u*=4);
                    185:        while((u=((x+s*s)/s)>>1)<s)
                    186:                s=u;
                    187:        return(s);
                    188: }
                    189: fire(o)
                    190: register struct obj *o;
                    191: {
                    192:        register struct obj *m;
                    193:        register vx, vy, vl;
                    194: 
                    195:        if(o->state!=ALIVE)
                    196:                return;
                    197:        for(m=o+2;m<&obj[NOBJ];m+=2)
                    198:                if(m->state==DEAD){
                    199:                        initobj(m);
                    200:                        m->state=ALIVE;
                    201:                        vl=isqrt(sq(o->vx)+sq(o->vy));
                    202:                        if(vl==0)
                    203:                                vl=V;
                    204:                        vx=muldiv(vl, dv[o->orientation].x, V);
                    205:                        vy=muldiv(vl, dv[o->orientation].y, V);
                    206:                        m->x=o->x+muldiv(vx, (o->diameter+m->diameter), vl);
                    207:                        m->y=o->y+muldiv(vy, (o->diameter+m->diameter), vl);
                    208:                        m->vx=o->vx+MSPEED*dv[o->orientation].x;
                    209:                        m->vy=o->vy+MSPEED*dv[o->orientation].y;
                    210:                        blot(m, m->orientation);
                    211:                        return;
                    212:                }
                    213: }
                    214: initobj(o)
                    215:        register struct obj *o;
                    216: {
                    217:        *o=(o>P1)?iobj[P1-obj+1]:iobj[o-obj];
                    218:        if(o<=P1)
                    219:                blot(o, o->orientation);
                    220: }
                    221: deathto(o, doboom)
                    222: register struct obj *o;
                    223: {
                    224:        o->state=DEAD;
                    225:        blot(o, o->curdwg);
                    226:        if(doboom)
                    227:                boom(o);
                    228: }
                    229: boom(o)
                    230: register struct obj *o;
                    231: {
                    232:        o->state=BOOM;
                    233:        o->bp= &boomdwg;
                    234:        o->diameter=boomdwg.rect.corner.x/4;
                    235:        blot(o, o->orientation=0);
                    236: }
                    237: shards(o)
                    238: register struct obj *o;
                    239: {
                    240:        if(++o->orientation==16){
                    241:                blot(o, o->curdwg);
                    242:                o->state=DEAD;
                    243:                o->timer=TUBA;
                    244:        }
                    245: }
                    246: move(o)
                    247: register struct obj *o;
                    248: {
                    249:        register long r32;
                    250:        register x, y;
                    251:        if(o->state==DEAD || o->state==SUN)
                    252:                return;
                    253:        r32=(long)o->x*o->x+(long)o->y*o->y;
                    254:        if(r32!=0){
                    255:                r32*=isqrt(r32);        /* pow(r, 3./2.) */
                    256:                if(r32!=0){
                    257:                        o->vx-=G*o->x/r32;
                    258:                        o->vy-=G*o->y/r32;
                    259:                }
                    260:        }
                    261:        x=o->x+o->vx/V;
                    262:        y=o->y+o->vy/V;
                    263:        if(x<-SZ || SZ<x){
                    264:                if(o>P1 && o->wrapped){
                    265:     Death:
                    266:                        deathto(o, 0);
                    267:                        return;
                    268:                }
                    269:                if(x<-SZ) x+=2*SZ; else x-=2*SZ;
                    270:                o->wrapped++;
                    271:        }
                    272:        if(y<-SZ || SZ<y){
                    273:                if(o>P1 && o->wrapped)
                    274:                        goto Death;
                    275:                if(y<-SZ) y+=2*SZ; else y-=2*SZ;
                    276:                o->wrapped++;
                    277:        }
                    278:        if(o->state!=HYPER)
                    279:                blot(o, o->curdwg);
                    280:        o->x=x, o->y=y;
                    281:        if(o->state!=HYPER)
                    282:                blot(o, o->orientation);
                    283: }
                    284: #define        BLOTSIZE        5
                    285: #define        rescale(x)      muldiv(x, size, SZ)
                    286: blot(o, dwg)
                    287: register struct obj *o;
                    288: {
                    289:        register dx=dwg%4*o->diameter, dy=dwg/4*o->diameter;
                    290:        bitblt(o->bp, Rect(dx, dy, dx+o->diameter, dy+o->diameter),
                    291:                &display, Pt(rescale(o->x)+xc-o->diameter/2,
                    292:                        rescale(o->y)+yc-o->diameter/2), F_XOR);
                    293:        o->curdwg=dwg;
                    294: }
                    295: collide(o, p)
                    296: register struct obj *o, *p;
                    297: {
                    298:        register doneboom;
                    299:        /* o<p always */
                    300:        if(o->state!=HYPER && p->state!=HYPER
                    301:        && sq(rescale(o->x-p->x))+sq(rescale(o->y-p->y))<
                    302:                sq(o->diameter+p->diameter)/4){
                    303:                newscore(o, p);
                    304:                if(doneboom=o->state==ALIVE)
                    305:                        deathto(o, 1);
                    306:                if(p->state==ALIVE)
                    307:                        deathto(p, !doneboom || (o==P0 && p==P1));
                    308:        }
                    309: }
                    310: newscore(o, p)
                    311: register struct obj *o, *p;
                    312: {
                    313:        doscore();
                    314:        /* o<p always */
                    315:        score[2]++;
                    316:        if(o==P0 || p==P0)
                    317:                score[1]++;
                    318:        if(o==P1 || p==P1)
                    319:                score[0]++;
                    320:        doscore();
                    321: }
                    322: drawscore(str, sc, where)
                    323:        char *str;
                    324: {
                    325:        static char buf[16];
                    326:        register char *p=buf+6;
                    327:        register s;
                    328:        do; while(*p++= *str++);
                    329:        p=buf+6;
                    330:        s=abs(sc);
                    331:        do{
                    332:                *--p=s%10+'0';
                    333:                s/=10;
                    334:        }while(s);      /*mcc bug */
                    335:        if(sc<0)
                    336:                *--p='-';
                    337:        if(where==2)
                    338:                s=Drect.origin.x;
                    339:        else if(where==1)
                    340:                s=(Drect.origin.x+Drect.corner.x-strwidth(&defont, p))/2;
                    341:        else
                    342:                s=Drect.corner.x-strwidth(&defont, p);
                    343:        string(&defont, p, &display, Pt(s, Drect.origin.y+5), F_XOR);
                    344: }
                    345: doscore()
                    346: {
                    347:        drawscore(" MCI", score[0], 0);
                    348:        drawscore(" AT&T", score[2], 1);
                    349:        drawscore(" SPRINT", score[1], 2);
                    350: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.