background.c}ϳ;= background.cyTEXTCWIEX}ϳ;=h#include #include #include #include "background.h" #include "message.h" #define no_anims 6 #define rnd (rand() & 255) // Structure used for points for the graded lines. typedef struct { u_char type; u_char r,g,b; long x,y; long var1, var2; } colorpt; // Structure used for bouncy points. typedef struct { long x,y; long spx,spy; long accx,accy; } bouncypt; // Structure for bezier curve control pts. typedef struct { long pts[4][2]; } bezier; static u_char backanim; static long timer = 0; void Blob(GsOT *OT); // A wobbly line that consists of a number of bezier segments all joined together. void Bezier(GsOT *OT, bezier *B); // Plots a bezier curve. void Morph(GsOT *OT); // Morphs between different line drawings. void BouncyLine(GsOT *OT); // Like those screen savers you always get. void WireFrame(GsOT *OT); void WireFrame2(GsOT *OT); // Two different wire frame models. void GradedLines(GsOT *OT); // A number of points all joined together using graded lines. void SetupBouncy(bouncypt* p); // Initialise a bouncy point. void MoveBouncy(bouncypt* p); // Move a bouncy point. void ChangeBG() { static u_char onebeforelast = 255; // To prevent animations coming up too soon. static lastchange = 0; u_char newanim; if (backanim<128) { /* Find a new animation that isn't the same as the current one * or the one before last. */ do { newanim = rand() % no_anims; } while (newanim==backanim || newanim==onebeforelast); onebeforelast = backanim; backanim = newanim; if (timer>lastchange+128) { lastchange = timer; // Display message about new animation. switch (newanim) { case 0: NewMessage("Coloured lines"); break; case 1: NewMessage("Truncated cube"); break; case 2: NewMessage("Little house on the backdrop"); break; case 3: NewMessage("One of those line things you always see"); break; case 4: NewMessage("Morphing lines"); break; case 5: NewMessage("Bouncy squiggle"); break; } } } } void ToggleBG() {backanim = 255 - backanim;} static long bgrcolour = 0; static long bggcolour = 0; static long bgbcolour = 80<<16; void PlotBackground(GsOT *OT) { GsBOXF BG; static u_char threeDmess = 0; static u_char startup = 1; if (startup) { startup = 0; backanim = rand() % no_anims; } timer++; // Call appropriate procedure for current animation. switch (backanim) { case 0: GradedLines(OT); break; case 1: if (rand() == 128 && !threeDmess) { threeDmess = 1; NewMessage("For those people that can stereo view the image at the back can be seen in 3D. The inner column is the left image and the outer columns are the right image."); } WireFrame(OT); break; case 2: if (rand() == 128 && !threeDmess) { threeDmess = 1; NewMessage("For those people that can stereo view the image at the back can be seen in 3D. The inner column is the left image and the outer columns are the right image."); } WireFrame2(OT); break; case 3: BouncyLine(OT); break; case 4: Morph(OT); break; case 5: Blob(OT); break; } BG.attribute = 0; BG.x = BG.y = 0; BG.w = 320; BG.h = 256; /* Tend background colour towards blue. * So that it returns to normal after a white flash. */ if (bgrcolour>0 || bgbcolour>80<<16) { bgrcolour-=bgrcolour>>3; bggcolour-=bggcolour>>3; bgbcolour-=(bgbcolour-(80<<16))>>3; } BG.r = bgrcolour>>16; BG.g = bggcolour>>16; BG.b = bgbcolour>>16; GsSortBoxFill(&BG, OT, 15); } void FlashBG() {bgrcolour = bggcolour = bgbcolour = 255<<16;} #define nocontrolpts 8 void Blob(GsOT *OT) { /* There are a number of control points given by nocontrolpts that form * the beginnings and endings of bezier curves. Eg. If there are 3 control * points then there are 3 bezier curves pt1->pt2, pt2->pt3 & pt3->pt0. * Each control point has an angle associated with it and 2 distances. * These are used to determine the 2 inner points of each curve. */ static bouncypt pts[nocontrolpts]; static long vars[nocontrolpts][3]; static long varsp[nocontrolpts][3]; static long varacc[nocontrolpts][3]; static u_char startup = 1; bezier segment; short invangle; int i,i2; if (startup) { startup = 0; // Set up each control point. for (i=0;i32<<8) varsp[i][0] = 32<<8; if (varsp[i][0]<-(32<<8)) varsp[i][0] = -(32<<8); vars[i][0]+=varsp[i][0]; if (vars[i][0]<0) vars[i][0]+=4096<<8; if (vars[i][0]>4096<<8) vars[i][0]-=4096<<8; if (rnd<2) varacc[i][0] = (rand() & 511) - 256; // Change length of tangents for (i2=1;i2<3;i2++) { varsp[i][i2]+=varacc[i][i2]; if (varsp[i][i2]>512) varsp[i][i2] = 512; if (varsp[i][i2]<-512) varsp[i][i2] = -512; vars[i][i2]+=varsp[i][i2]; if ((vars[i][i2]<16<<8 && vars[i][i2]>0) || (vars[i][i2]>-16<<8 && vars[i][i2]<0) || vars[i][i2]>512 || vars[i][i2]<-512) { vars[i][i2]-=varsp[i][i2]; varsp[i][i2]=-varsp[i][i2]; } if (rnd<2) varacc[i][i2] = (rand() & 127) - 64; } } for (i=0;i>8; segment.pts[0][1] = pts[i].y>>8; segment.pts[1][0] = ((pts[i].x<<4) + (vars[i][1]>>8)*DJsin(vars[i][0]>>8))>>12; segment.pts[1][1] = ((pts[i].y<<4) + (vars[i][1]>>8)*DJcos(vars[i][0]>>8))>>12; invangle = 2048 + (vars[i2][0]>>8); if (invangle>=4096) invangle-=4096; segment.pts[2][0] = ((pts[i2].x<<4) + (vars[i2][2]>>8)*DJsin(invangle))>>12; segment.pts[2][1] = ((pts[i2].y<<4) + (vars[i2][2]>>8)*DJcos(invangle))>>12; segment.pts[3][0] = pts[i2].x>>8; segment.pts[3][1] = pts[i2].y>>8; Bezier(OT, &segment); } } #define splinesegments 32 // No of segments each bezier is made up of. void Bezier(GsOT *OT, bezier *B) { /* This is just a straigtforward implementation of a bezier curve plotter. * Read a book about computer graphics if you wan't to know it works. */ long i; long squ,cub; GsLINE line; long x,y,x0,y0,x1,y1,x2,y2,x3,y3; line.attribute = 0; line.r = line.g = line.b = 64; x0 = -B->pts[0][0] + 3*B->pts[1][0] - 3*B->pts[2][0] + B->pts[3][0]; x1 = 3*B->pts[0][0] - 6*B->pts[1][0] + 3*B->pts[2][0]; x2 = -3*B->pts[0][0] + 3*B->pts[1][0]; x3 = B->pts[0][0]; y0 = -B->pts[0][1] + 3*B->pts[1][1] - 3*B->pts[2][1] + B->pts[3][1]; y1 = 3*B->pts[0][1] - 6*B->pts[1][1] + 3*B->pts[2][1]; y2 = -3*B->pts[0][1] + 3*B->pts[1][1]; y3 = B->pts[0][1]; for (i=0;i<=4096;i+=4096/splinesegments) { squ = (i*i)>>12; cub = (squ*i)>>12; line.x1 = line.x0; line.y1 = line.y0; x = cub * x0; y = cub * y0; x += squ * x1; y += squ * y1; x += i * x2; y += i * y2; x += x3<<12; y += y3<<12; line.x0 = x>>12; line.y0 = y>>12; if (i!=0) GsSortLine(&line, OT, 14); } } #define no_shapes 10 // Points of each shape that can be morphed to. static short shapes[no_shapes][24][2] = { {{50,96},{82,64},{198,64},{198,56},{198,48},{190,48},{190,56},{190,64}, {238,64},{270,96},{160,96},{50,96},{50,160},{50,224}, {180,224},{180,194},{180,164},{160,164},{140,164},{140,194},{140,224}, {270,224},{270,96},{270,96}}, {{80,100},{100,80},{120,60},{120,110},{120,160},{100,180},{80,200},{80,150},{80,100}, {180,100},{200,80},{220,60},{120,60},{220,60},{220,110},{220,160},{120,160},{220,160}, {200,180},{180,200},{80,200},{180,200},{180,150},{180,100}}, {{64,80},{64,176},{112,176},{112,224},{160,224},{160,176},{112,176},{112,80}, {64,80},{64,32},{112,32},{112,80},{208,80},{208,32}, {256,32},{256,80},{208,80},{208,128},{160,128},{160,176}, {208,176},{208,128},{256,128},{256,80}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{160,40},{140,60},{160,40},{180,60},{160,40}, {160,80},{130,110},{160,80},{190,110},{160,80}, {160,120},{120,160},{160,120},{200,160},{160,120}, {160,160},{110,210},{160,160},{210,210},{160,160}, {160,220},{190,220},{130,220},{160,220}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}}, {{100,32},{110,32},{120,32},{140,32},{160,32},{180,32},{190,32},{200,32},{220,32}, {190,80},{160,128},{130,176}, {100,224},{120,224},{140,224},{160,224},{170,224},{180,224},{200,224},{220,224}, {190,176},{160,128},{130,80},{100,32}}, {{40,192},{60,192},{60,64},{80,64},{80,192},{100,192},{100,64}, {120,64},{120,192},{140,192},{140,64},{160,64},{160,192},{180,192},{180,64}, {200,64},{200,192},{220,192},{220,64},{240,64},{240,192}, {260,192},{260,64},{280,64}}, {{64,32},{80,32},{120,72},{160,112},{200,72},{240,32},{256,32},{256,48}, {216,88},{176,128},{216,168},{256,208},{256,224},{240,224},{200,184}, {160,144},{120,184},{80,224},{64,224},{64,208},{104,168}, {144,128},{64,48},{64,32}}, {{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}, {0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0},{0,0}} }; void Morph(GsOT *OT) { static long pts[24][2]; // Coordinates of each point on screen. static long step[24][2]; // Amount each point moves by each frame. static u_char startup = 1; static short angle = 0; static int delay = 128; static int lastshape; int shape,i,xdis,ydis; short temp1, temp2; GsLINE line; if (startup) { startup = 0; // Create circle for (i=0;i<23;i++) { shapes[3][i][0] = 160+((96*DJsin(i*178))/4096); shapes[3][i][1] = 128+((96*DJcos(i*178))/4096); } shapes[3][23][0] = 160+((96*DJsin(0))/4096); shapes[3][23][1] = 128+((96*DJcos(0))/4096); // Create figure of 8 for (i=0;i<11;i++) { shapes[5][i][0] = 160+((48*DJsin(i*372))/4096); shapes[5][i][1] = 80+((48*DJcos(i*372))/4096); shapes[5][12+i][0] = 160+((48*DJsin(i*372))/4096); shapes[5][12+i][1] = 176-((48*DJcos(i*372))/4096); } shapes[5][11][0] = 160+((48*DJsin(0))/4096); shapes[5][11][1] = 80+((48*DJcos(0))/4096); shapes[5][23][0] = 160+((48*DJsin(0))/4096); shapes[5][23][1] = 176-((48*DJcos(0))/4096); // Create flowery thing for (i=0;i<24;i++) { if ((temp1 = (i*178))>=4096) temp1-=4096; temp2 = 1500-(i*712); while (temp2<0) temp2+=4096; shapes[9][i][0] = 160+((64*DJsin(temp1))/4096 + (32*DJsin(temp2))/4096); shapes[9][i][1] = 128+((64*DJcos(temp1))/4096 + (32*DJcos(temp2))/4096); } shape = rand() % no_shapes; for (i=0;i<24;i++) { pts[i][0] = shapes[shape][i][0]<<8; pts[i][1] = shapes[shape][i][1]<<8; } lastshape = shape; } if (delay>0) { delay--; if (delay==0) { // Find new shape to morph to. do { shape = rand() % no_shapes; } while (shape==lastshape); lastshape = shape; /* Calculate the steps for each point in order to move them to * form the new shape. */ for (i=0;i<24;i++) { step[i][0] = ((shapes[shape][i][0]<<8)-pts[i][0])/64; step[i][1] = ((shapes[shape][i][1]<<8)-pts[i][1])/64; } } } else { // Move each point for (i=0;i<24;i++) { pts[i][0]+=step[i][0]; pts[i][1]+=step[i][1]; } if ((--delay) == -64) delay = 128; } // Move it around (otherwise you can't really see it right). if ((angle+=32) >= 4096) angle-=4096; xdis = (24*DJsin(angle))>>12; ydis = (24*DJcos(angle))>>12; line.attribute; line.r = line.b = line.g = 64; // Join together all the lines. for (i=0;i<23;i++) { line.x0 = xdis+(pts[i][0]>>8); line.y0 = ydis+(pts[i][1]>>8); line.x1 = xdis+(pts[i+1][0]>>8); line.y1 = ydis+(pts[i+1][1]>>8); GsSortLine(&line, OT, 14); } } void BouncyLine(GsOT *OT) { static bouncypt pt0,pt1; static long r0,g0,b0,r1,g1,b1; static long r0sp,g0sp,b0sp,r1sp,g1sp,b1sp; static u_char curpos; static short pastxy[32][2][2]; static u_char pastrgb[32][2][3]; static u_char startup = 1; GsGLINE line; int i; if (startup) { startup = 0; curpos = 0; for (i=0;i<32;i++) { pastxy[i][0][0] = -1; pastxy[i][0][1] = -1; pastxy[i][1][0] = -1; pastxy[i][1][1] = -1; } SetupBouncy(&pt0); SetupBouncy(&pt1); r0=rnd<<7; g0=rnd<<7; b0=rnd<<7; r1=rnd<<7; g1=rnd<<7; b1=rnd<<7; r0sp=rnd<<1; g0sp=rnd<<1; b0sp=rnd<<1; r1sp=rnd<<1; g1sp=rnd<<1; b1sp=rnd<<1; } MoveBouncy(&pt0); MoveBouncy(&pt1); r0+=r0sp; g0+=g0sp; b0+=b0sp; r1+=r1sp; g1+=g1sp; b1+=b1sp; if (r0<0 || r0>(127<<8)) {r0-=r0sp; r0sp=-r0sp;} if (g0<0 || g0>(127<<8)) {g0-=g0sp; g0sp=-g0sp;} if (b0<0 || b0>(127<<8)) {b0-=b0sp; b0sp=-b0sp;} if (r1<0 || r1>(127<<8)) {r1-=r1sp; r1sp=-r1sp;} if (g1<0 || g1>(127<<8)) {g1-=g1sp; g1sp=-g1sp;} if (b1<0 || b1>(127<<8)) {b1-=b1sp; b1sp=-b1sp;} if ((rand() & 63) == 0) {r0sp=rnd<<1; g0sp=rnd<<1; b0sp=rnd<<1;} if ((rand() & 63) == 0) {r1sp=rnd<<1; g1sp=rnd<<1; b1sp=rnd<<1;} pastxy[curpos][0][0] = pt0.x>>8; pastxy[curpos][0][1] = pt0.y>>8; pastxy[curpos][1][0] = pt1.x>>8; pastxy[curpos][1][1] = pt1.y>>8; pastrgb[curpos][0][0] = r0>>8; pastrgb[curpos][1][0] = r1>>8; pastrgb[curpos][0][1] = g0>>8; pastrgb[curpos][1][1] = g1>>8; pastrgb[curpos][0][2] = b0>>8; pastrgb[curpos][1][2] = b1>>8; if ((++curpos)==32) curpos = 0; line.attribute = 0; for (i=0;i<32;i++) { line.x0 = pastxy[i][0][0]; line.y0 = pastxy[i][0][1]; line.x1 = pastxy[i][1][0]; line.y1 = pastxy[i][1][1]; line.r0 = pastrgb[i][0][0]; line.r1 = pastrgb[i][1][0]; line.g0 = pastrgb[i][0][1]; line.g1 = pastrgb[i][1][1]; line.b0 = pastrgb[i][0][2]; line.b1 = pastrgb[i][1][2]; GsSortGLine(&line, OT, 14); } } #define tcs 30 void WireFrame(GsOT *OT) { // The 3D vertice locations. static long vertices[24][3] = { {-100,100,-tcs},{-tcs,100,-100},{-100,tcs,-100}, {100,100,-tcs},{tcs,100,-100},{100,tcs,-100}, {-100,-100,-tcs},{-tcs,-100,-100},{-100,-tcs,-100}, {100,-100,-tcs},{tcs,-100,-100},{100,-tcs,-100}, {-100,100,tcs},{-tcs,100,100},{-100,tcs,100}, {100,100,tcs},{tcs,100,100},{100,tcs,100}, {-100,-100,tcs},{-tcs,-100,100},{-100,-tcs,100}, {100,-100,tcs},{tcs,-100,100},{100,-tcs,100} }; // What vertices form lines. static u_char lines[36][2] = { {0,1},{1,2},{2,0}, {3,4},{4,5},{5,3}, {6,7},{7,8},{8,6}, {9,10},{10,11},{11,9}, {12,13},{13,14},{14,12}, {15,16},{16,17},{17,15}, {18,19},{19,20},{20,18}, {21,22},{22,23},{23,21}, {1,4},{7,10},{2,8},{5,11}, {13,16},{19,22},{14,20},{17,23}, {0,12},{3,15},{6,18},{9,21} }; static short xrot=0; static short yrot=0; static short zrot=0; long pts[24][3]; GsLINE line; int i; MATRIX m; VECTOR pt, pt2; int x,y; line.attribute = 0; line.r = line.g = line.b = 64; // Spin shape around. if ((xrot+=21) >= 4096) xrot-=4096; if ((yrot+=13) >= 4096) yrot-=4096; if ((zrot+=24) >= 4096) zrot-=4096; // Create identity matrix and apply matrix rotations. for (y=0;y<3;y++) { m.t[y] = 0; for (x=0;x<3;x++) m.m[x][y] = 4096*(x==y); } RotMatrixX(xrot, &m); RotMatrixY(yrot, &m); RotMatrixZ(zrot, &m); for (i=0;i<24;i++) { // Rotate each vertex. pt.vx = vertices[i][0]; pt.vy = vertices[i][1]; pt.vz = vertices[i][2]; ApplyMatrixLV(&m, &pt, &pt2); // Project each point onto a 2D plane. pts[i][0] = 160+(((pt2.vx)*256)/(400+pt2.vz)); pts[i][1] = 128+(((pt2.vy)*256)/(400+pt2.vz)); pts[i][2] = pt2.vz; } // Plot lines for wireframe model. for (i=0;i<36;i++) { for (y=0;y<4;y++) { for (x=0;x<2;x++) { line.x0 = x*213+(pts[lines[i][0]][0]>>2); line.y0 = y*64+(pts[lines[i][0]][1]>>2); line.x1 = x*213+(pts[lines[i][1]][0]>>2); line.y1 = y*64+(pts[lines[i][1]][1]>>2); GsSortLine(&line, OT, 14); } } } // Same as above but slightly to the right to give a 3D view. for (i=0;i<24;i++) { pt.vx = vertices[i][0]; pt.vy = vertices[i][1]; pt.vz = vertices[i][2]; ApplyMatrixLV(&m, &pt, &pt2); pt2.vx+=32; pts[i][0] = 160+(((pt2.vx)*256)/(400+pt2.vz)); pts[i][1] = 128+(((pt2.vy)*256)/(400+pt2.vz)); pts[i][2] = pt2.vz; } for (i=0;i<36;i++) { for (y=0;y<4;y++) { line.x0 = 107+(pts[lines[i][0]][0]>>2); line.y0 = y*64+(pts[lines[i][0]][1]>>2); line.x1 = 107+(pts[lines[i][1]][0]>>2); line.y1 = y*64+(pts[lines[i][1]][1]>>2); GsSortLine(&line, OT, 14); } } } void WireFrame2(GsOT *OT) { // See comments for WireFrame. static long vertices[22][3] = { {-100,-80,60},{100,-80,60},{-100,-80,-60},{100,-80,-60}, {-100,40,60},{100,40,60},{-100,40,-60},{100,40,-60}, {-80,100,0},{80,100,0}, {-15,-40,-60},{15,-40,-60},{-15,-80,-60},{15,-80,-60}, {-70,-30,-60},{-40,-30,-60},{-70,-60,-60},{-40,-60,-60}, {40,-30,-60},{70,-30,-60},{40,-60,-60},{70,-60,-60} }; static u_char lines[28][2] = { {0,1},{1,3},{3,2},{2,0}, {4,5},{5,7},{7,6},{6,4}, {0,4},{1,5},{2,6},{3,7}, {4,8},{6,8},{5,9},{7,9},{8,9}, {12,10},{10,11},{11,13}, {14,15},{15,17},{17,16},{16,14}, {18,19},{19,21},{21,20},{20,18} }; static short xrot=0; static short yrot=0; static short zrot=0; long pts[22][3]; GsLINE line; int i; MATRIX m; VECTOR pt, pt2; int x,y; line.attribute = 0; line.r = line.g = line.b = 64; if ((xrot+=21) >= 4096) xrot-=4096; if ((yrot+=13) >= 4096) yrot-=4096; if ((zrot+=24) >= 4096) zrot-=4096; for (y=0;y<3;y++) { m.t[y] = 0; for (x=0;x<3;x++) m.m[x][y] = 4096*(x==y); } RotMatrixX(xrot, &m); RotMatrixY(yrot, &m); RotMatrixZ(zrot, &m); for (i=0;i<22;i++) { pt.vx = vertices[i][0]; pt.vy = vertices[i][1]; pt.vz = vertices[i][2]; ApplyMatrixLV(&m, &pt, &pt2); pts[i][0] = 160+(((pt2.vx)*256)/(400+pt2.vz)); pts[i][1] = 128+(((pt2.vy)*256)/(400+pt2.vz)); pts[i][2] = pt2.vz; } for (i=0;i<28;i++) { for (y=0;y<4;y++) { for (x=0;x<2;x++) { line.x0 = x*213+(pts[lines[i][0]][0]>>2); line.y0 = y*64+(pts[lines[i][0]][1]>>2); line.x1 = x*213+(pts[lines[i][1]][0]>>2); line.y1 = y*64+(pts[lines[i][1]][1]>>2); GsSortLine(&line, OT, 14); } } } for (i=0;i<22;i++) { pt.vx = vertices[i][0]; pt.vy = vertices[i][1]; pt.vz = vertices[i][2]; ApplyMatrixLV(&m, &pt, &pt2); pt2.vx+=32; pts[i][0] = 160+(((pt2.vx)*256)/(400+pt2.vz)); pts[i][1] = 128+(((pt2.vy)*256)/(400+pt2.vz)); pts[i][2] = pt2.vz; } for (i=0;i<28;i++) { for (y=0;y<4;y++) { line.x0 = 107+(pts[lines[i][0]][0]>>2); line.y0 = y*64+(pts[lines[i][0]][1]>>2); line.x1 = 107+(pts[lines[i][1]][0]>>2); line.y1 = y*64+(pts[lines[i][1]][1]>>2); GsSortLine(&line, OT, 14); } } } #define no_pts 16 void GradedLines(GsOT *OT) { /* Each vertex is allocated an rgb colour and moved around by either bouncing * it under the effect of gravity, letting it bounce "Pong" style or using a * bouncy point. * Lines are drawn between every vertex using a graded line with the rgb * colour for each end given by the vertex colour. */ static u_char startup = 1; static colorpt pts[no_pts]; static bouncypt bpts[no_pts]; GsGLINE line; int i,i2; if (startup) { startup = 0; for (i=0;i>8; line.y0 = (pts[i].y)>>8; line.r0 = pts[i].r; line.g0 = pts[i].g; line.b0 = pts[i].b; line.x1 = (pts[i2].x)>>8; line.y1 = (pts[i2].y)>>8; line.r1 = pts[i2].r; line.g1 = pts[i2].g; line.b1 = pts[i2].b; GsSortGLine(&line, OT, 14); } } for (i=0;i 255<<8) pts[i].var2=-(32+pts[i].var2); break; case 2: MoveBouncy(&bpts[i]); pts[i].x = bpts[i].x; pts[i].y = bpts[i].y; } } } /* Bouncy points have an x,y position, speed and acceleration. * Every frame the speed alters by the amount of acceleration and the position * alters by the amount of speed. * Every now and then a new acceleration is chosen. */ void SetupBouncy(bouncypt* p) { p->x = (rand() % 320)<<8; p->y = (rand() & 255)<<8; p->spx = (rand() & 1023)-512; p->spy = (rand() & 1023)-512; p->accx = (rand() & 31)-16; p->accy = (rand() & 31)-16; } void MoveBouncy(bouncypt* p) { p->spx+=p->accx; if (p->spx>512) p->spx=512; if (p->spx<-512) p->spx=-512; p->x+=p->spx; if (p->x>=(320<<8) || p->x<0) { p->x-=p->spx; p->spx=-p->spx; p->accx=-p->accx; } if (rnd==0) p->accx = (rand() & 63)-32; p->spy+=p->accy; if (p->spy>512) p->spy=512; if (p->spy<-512) p->spy=-512; p->y+=p->spy; if (p->y>=(256<<8) || p->y<0) { p->y-=p->spy; p->spy=-p->spy; p->accy=-p->accy; } if (rnd==0) p->accy = (rand() & 63)-32; }ZZR @dfpap n%rJ@_/.? background.cIDE 2.0.3atantallerTEXTCWIE}X1n!n0J.o0.=@a(-PAp`=@Jf0p1@p `k0.k @\p `-h00(a\=APjNuNT