|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.