/* * MAIN.C * * Bulging Bubbles Demo */ #include "bubbles.h" TA Ta = { (ubyte *)"topaz.font", 8 }; NS Ns = { 0, 0, 640, 200, 2, 0, 1, HIRES, CUSTOMSCREEN|SCREENQUIET, &Ta, (ubyte *)"", NULL, NULL }; NW Nw = { 0, 2, 64, 32, -1, -1, CLOSEWINDOW, WINDOWCLOSE|SIMPLE_REFRESH|BORDERLESS|NOCAREREFRESH|RMBTRAP, NULL,NULL,NULL,NULL,NULL,16,16,-1,-1,CUSTOMSCREEN }; OBJECT *Grid; OBJECT *Ball; WIN *Win; SCR *Scr; RP *Rp; long S_width, S_height, S_midwidth, S_dblheight; main(ac,av) char *av[]; { IMESS *imess; SCR Screen; if (ac <= 1) { init_grid(); init_ball(); } else { init_file(av[1]); } init_objectmodule(); init_bounce(); openlibs(INTUITION_LIB|GRAPHICS_LIB); GetScreenData(&Screen, sizeof(Screen), WBENCHSCREEN, NULL); Ns.Width = Screen.Width; Ns.Height= Screen.Height; if (Scr = OpenScreen(&Ns)) { S_width = Scr->Width; S_height= Scr->Height; S_midwidth = S_width >> 1; S_dblheight= S_height<< 1; SetRGB4(&Scr->ViewPort,0, 0, 0, 0); SetRGB4(&Scr->ViewPort,3, 5, 5, 15); Nw.Screen = Scr; if (Win = OpenWindow(&Nw)) { Rp = &Scr->RastPort; for (;;) { bounce_ball(); toggle_rport(); displayobj(Rp,Grid); displayobj(Rp,Ball); if (imess = GetMsg(Win->UserPort)) break; } ReplyMsg(imess); CloseWindow(Win); } CloseScreen(Scr); } closelibs(-1); } toggle_rport() { if (Rp->Mask & 1) { SetRGB4(&Scr->ViewPort,1, 5, 5, 15); SetRGB4(&Scr->ViewPort,2, 0, 0, 0); Rp->Mask = 0x02; SetAPen(Rp,2); } else { SetRGB4(&Scr->ViewPort,2, 5, 5, 15); SetRGB4(&Scr->ViewPort,1, 0, 0, 0); Rp->Mask = 0x01; SetAPen(Rp,1); } WaitTOF(); SetRast(Rp,0); } /* * Create two objects: * (1) A stationary grid Z=0, x/y -32768:65536/4 * (2) a ball (cube for now) */ init_grid() { static long points[][3] = { -PMAXX,-PMAXY,0, /* Border */ PMAXX,-PMAXY,0, PMAXX, PMAXY,0, -PMAXX, PMAXY,0, -0x0400,0x0700,0x0E00, -0x0280,0x0700,0x0E00, -0x0100,0x0700,0x0E00, -0x0D00,-0x0700,0, -0x0B80,-0x0700,0, -0x0A00,-0x0700,0, -0x1000,-0x0300,0x0400, -0x0E80,-0x0300,0x0400, -0x0D00,-0x0300,0x0400, -0x0C80,-0x05E0,0x0110, -0x0BC0,-0x0510,0x01F0, /* 14 */ -0x0900,-0x0700,0, -0x0400,0,0x700, -0x0300,-0x0700,0, -0x0610,-0x0300,0x0400, -0x0390,-0x0300,0x0400, -0x0200,-0x0700,0, -0x0100,0,0x0700, /* 21 */ 0x0100,-0x0300,0x0400, 0x0400,0,0x0700, 0x0300,-0x0700,0, 0x0500,-0x0700,0, /* 25.. I */ 0x0700,-0x0700,0, 0x0900,-0x0700,0, 0x0500,0,0x0700, 0x0700,0,0x0700, 0x0900,0,0x0700, 0x0D00,-0x0100,0x0600, 0x0C00,0,0x0700, 0x0A00,0,0x0700, 0x0980,-0x0400,0x0300, 0x0A00,-0x0700,0, 0x0D00,-0x0700,0, 0x0D00,-0x0500,0x0200, 0x0C00,-0x0500,0x0200, 0x0E00,-0x0700,0, 0x0F80,-0x0300,0x0400, 0x1100,0,0x0700, 0x1200,-0x0300,0x0400, 0x1300,-0x0700,0 }; static short connect[][2] = { 0,1, 1,2, 2,3, 3,0, 4,5, 5,6, 4,7, 5,8, 6,9, 9,8, 8,7, 7,10, 10,11, 11,13, 13,14, 14,12, 12,11, 15,18, 18,16, 16,19, 19,17, 18,19, /* A */ 20,21, 21,22, 22,23, 23,24, /* M */ 28,29, 29,30, 29,26, 25,26, 26,27, /* I */ 31,32, 32,33, 33,34, 34,35, 35,36, 36,37, 37,38, /* G */ 39,40, 40,41, 41,42, 42,43, 40,42 }; Grid = makeobject( points , sizeof(points)/sizeof(points[0]), connect, sizeof(connect)/sizeof(connect[0]), 0,0,0 ); } init_ball() { static long points[][3] = { -PSKIP/5 ,-PSKIP/5 , 0, PSKIP/5 ,-PSKIP/5 , 0, PSKIP/5 , PSKIP/5 , 0, -PSKIP/5 , PSKIP/5 , 0, -PSKIP/5 ,-PSKIP/5 , PSKIP*2/5, PSKIP/5 ,-PSKIP/5 , PSKIP*2/5, PSKIP/5 , PSKIP/5 , PSKIP*2/5, -PSKIP/5 , PSKIP/5 , PSKIP*2/5 }; static short connect[][2] = { 0,1,1,2,2,3,3,0, 4,5,5,6,6,7,7,4, 0,4,1,5,2,6,3,7, 0,6,1,7,2,4,3,5 }; Ball = makeobject( points , sizeof(points)/sizeof(points[0]), connect, sizeof(connect)/sizeof(connect[0]), 0,0,0 ); } /* * FILE FORMAT: * ignored * # comment -comment * DB numpoints numconnect -begin ball definition * DG numpoints numconnect -begin grid definition * P X Y Z -define points (index begins at 0) * C A B -define line segments * END -end of def. */ init_file(name) char *name; { FILE *fi = fopen(name,"r"); char buf[256]; if (fi == NULL) { puts("File not found"); exit(1); } while (fgets(buf,256,fi)) { if (buf[0] == 'D') { OBJECT **which; long *points; uword *connect; long npts, ncon, ip, ic, c1, c2; which = (buf[1] == 'B') ? &Ball : &Grid; if (sscanf(buf+2,"%ld %ld", &npts, &ncon) != 2) { puts("Illegal format"); exit(1); } points = (long *)malloc(sizeof(long) * 3 * npts); connect = (uword *)malloc(sizeof(short) * 2 * ncon); ip = ic = 0; while (fgets(buf,256,fi)) { switch(buf[0]) { case 'P': if (ip >= npts) { puts("Beyond specified parameters"); exit(1); } sscanf(buf+1,"%ld %ld %ld", &points[ip*3], &points[ip*3+1], &points[ip*3+2]); ++ip; break; case 'C': if (ic >= ncon) { puts("Beyond specified parameters"); exit(1); } sscanf(buf+1,"%ld %ld", &c1, &c2); connect[ic*2] = c1; connect[ic*2+1]=c2; ++ic; break; case 'E': *which = makeobject(points,ip,connect,ic,0,0,0); goto br2; } } br2: ; } } fclose(fi); if (!Ball) init_ball(); if (!Grid) init_grid(); } /* * Bounce the ball within the domain (-PMAX,-PMAX,0) to (PMAX,PMAX,PMAX) * -uniform Z deceleration * -Z < 0 bounce + random acceleration load * * -Camera attempts to match ball but is allowed only uniform * acceleration * * -My position attempts to match camera but is allow only uniform * acceleration which is less than that for camera * * Ball velocity clamped at 100 */ long Bx,By,Bz,BAx,BAy,BAz,BVx,BVy,BVz; /* The Ball */ long Cx,Cy,Cz,CAx,CAy,CAz,CVx,CVy,CVz; /* Camera center pt */ long Mx,My,Mz,MAx,MAy,MAz,MVx,MVy,MVz; /* My position */ init_bounce() { Mx = My = Mz = 16384; BVx = 123; BVy = -56; } bounce_ball() { BAz = -10; BVx += BAx; if (BVx > CLAMP) BVx = CLAMP; if (BVx < -CLAMP) BVx = -CLAMP; BVy += BAy; if (BVy > CLAMP) BVy = CLAMP; if (BVy < -CLAMP) BVy = -CLAMP; BVz += BAz; if (BVz > CLAMP) BVz = CLAMP; if (BVz < -CLAMP) BVz = -CLAMP; Bx += BVx; if (Bx < -PMAXX|| Bx > PMAXX) { BVx = -BVx; Bx += 2*BVx; } By += BVy; if (By < -PMAXY|| By > PMAXY) { BVy = -BVy; By += 2*BVy; } Bz += BVz; if (Bz > PMAXZ ) { BVz = -BVz; Bz += 2*BVz; } if (Bz < 0) { /* Elastic bounce plus boost */ BVz = -BVz + (ran()&0xFFFF)%200; if (BVz > 300) BVz = 250; } Ball->x = Bx; Ball->y = By; Ball->z = Bz; { uword theta,phi; short result; theta = ibearing(Bx-Cx,By-Cy); phi = ibearing(irange(Bx-Cx,By-Cy),Bz-Cz); result = ICOS(phi); CAx += (5 * ((ICOS(theta) * result)>>15)) >> 15; CAy += (5 * ((ISIN(theta) * result)>>15)) >> 15; CAz += (5 * ISIN(phi)) >> 15; } { uword theta,phi; short result; theta = ibearing(Cx-Mx,Cy-My); phi = ibearing(irange(Cx-Mx,Cy-My),Cz-Mz); result = ICOS(phi); MAx = (10 * ((ICOS(theta) * result)>>15)) >> 15; MAy = (10 * ((ISIN(theta) * result)>>15)) >> 15; MAz = (10 * ISIN(phi)) >> 15; } MVx += MAx; Mx += MVx; MVy += MAy; My += MVy; MVz += MAz; Mz += MVz; CVx += CAx; Cx += CVx; CVy += CAy; Cy += CVy; CVz += CAz; Cz += CVz; if (CAx > ACLAMP)CAx =ACLAMP; if (CAx < -ACLAMP)CAx = -ACLAMP; if (CAy > ACLAMP)CAy =ACLAMP; if (CAy < -ACLAMP)CAy = -ACLAMP; if (CAz > ACLAMP)CAz =ACLAMP; if (CAz < -ACLAMP)CAz = -ACLAMP; if (CVx > CCLAMP) CVx = CCLAMP; if (CVx < -CCLAMP) CVx = -CCLAMP; if (CVy > CCLAMP) CVy = CCLAMP; if (CVy < -CCLAMP) CVy = -CCLAMP; if (CVz > CCLAMP) CVz = CCLAMP; if (CVz < -CCLAMP) CVz = -CCLAMP; if (MAx > ACLAMP)MAx =ACLAMP; if (MAx < -ACLAMP)MAx = -ACLAMP; if (MAy > ACLAMP)MAy =ACLAMP; if (MAy < -ACLAMP)MAy = -ACLAMP; if (MAz > ACLAMP)MAz =ACLAMP; if (MAz < -ACLAMP)MAz = -ACLAMP; if (MVx > CCLAMP) MVx = CCLAMP; if (MVx < -CCLAMP) MVx = -CCLAMP; if (MVy > CCLAMP) MVy = CCLAMP; if (MVy < -CCLAMP) MVy = -CCLAMP; if (MVz > CCLAMP) MVz = CCLAMP; if (MVz < -CCLAMP) MVz = -CCLAMP; setcamera(Mx, My, Mz, Cx, Cy, Cz, 0); }