1 #include <stdio.h>
2 #include <string.h>
3 #include <stdlib.h>
4 #include <unistd.h>
5 #include <math.h>
6 #include <sys/types.h>
7 #include <fcntl.h>
8 #include <vga.h>
9 #include <vgagl.h>
10 #include <vgakeyboard.h>
11 #include <sys/soundcard.h>
12 #include "soundIt.h"
13 #define VGAMODE G640x480x256
14 #define back(x) (32 + x)
15 #define ball(x) (64 + x)
16 #define rocket(x) (96 + x)
17 #define PLAY_X1 0
18 #define PLAY_Y1 0
19 #define PLAY_X2 600
20 #define PLAY_Y2 400
21 #define MAPWIDTH (PLAY_X2-PLAY_X1)
22 #define MAPHEIGHT (PLAY_Y2-PLAY_Y1)
23 #define RAD(n)  ((float)(n)/180.0*M_PI)
24 #define ROTSTEP RAD(20)
25 #define ROCKET_SPEED 0.8
26 #define BALL_SPEED 0.3
27 #define SLOWDOWN 0.9
28 #define GUMM 5
29 #define BALLM 3
30 #define LBALLM 4
31 #define ROCKETM 5
32 #define BALL_RADIUS 8
33 #define ROCKET_RADIUS 10
34 #define EYE_RADIUS 4
35 #define EYE_RADIUS1 8
36 
37 #define ROCKET 1
38 #define BALL 2
39 #define LBALL 3
40 #define CREATOR 4
41 #define MAXOBJECT 50
42 #define MAXPOINT 1000
43 #define MAXROCKETS 4
44 typedef struct {
45         int type;
46 	int live;
47 	int time;
48         float x;
49         float y;
50 	float fx;	/*forces*/
51 	float fy;
52 	float rotation;	/*for rockets*/
53 	float M;
54 	int radius;
55 	float speed;
56 	float accel;
57 	char letter;
58 } Object;
59 typedef struct {
60 	int x,y,xp,yp,time,color;
61 	} Point;
62 
63 int nobjects=8;
64 int nrockets=2;
65 Object object[MAXOBJECT];
66 Point point[MAXPOINT];
67 
68 
69 GraphicsContext *physicalscreen;
70 GraphicsContext *backscreen;
71 GraphicsContext *background;
72 
73 char ball_data[BALL_RADIUS*2][BALL_RADIUS*2];
74 char *ball_bitmap;
75 char eye_data[MAXROCKETS][EYE_RADIUS*2][EYE_RADIUS*2];
76 char *eye_bitmap[MAXROCKETS];
77 char rocket_data[ROCKET_RADIUS*2][ROCKET_RADIUS*2];
78 char *rocket_bitmap;
79 int npoint=0;
80 #define BALL_XCENTER (3*BALL_RADIUS/4)
81 #define BALL_YCENTER (BALL_RADIUS/4)
82 #define BALL_MAX_RADIUS (BALL_RADIUS+0.5*BALL_RADIUS)
83 #define BALL_SIZE_MAX (MAX_RADIUS*MAX_RADIUS)
84 #define ROCKET_XCENTER (3*ROCKET_RADIUS/4)
85 #define ROCKET_YCENTER (ROCKET_RADIUS/4)
86 #define ROCKET_MAX_RADIUS (ROCKET_RADIUS+0.5*ROCKET_RADIUS)
87 #define ROCKET_SIZE_MAX (ROCKET_MAX_RADIUS*ROCKET_MAX_RADIUS)
88 #define EYE_XCENTER (3*EYE_RADIUS/4)
89 #define EYE_YCENTER (EYE_RADIUS/4)
90 #define EYE_MAX_RADIUS (EYE_RADIUS+0.5*EYE_RADIUS)
91 #define EYE_SIZE_MAX (EYE_MAX_RADIUS*EYE_MAX_RADIUS)
92 #define NCOLORS 32
93 
94 
95 #define L_ACCEL 'A'
96 #define L_SPEED 'S'
97 #define L_GUMM 'M'
98 #define L_MULT 1.2
99 #define LETTER 1024
100 
101 
102 
103 #define S_START 0
104 #define S_END 1
105 #define S_COLIZE 2
106 #define S_DESTROY_BALL 3
107 #define S_DESTROY_ROCKET 4
108 #define NSAMPLES 5
109 char *files[NSAMPLES]=
110  {
111     "start.raw",
112     "end.raw",
113     "colize.raw",
114     "destroy1.raw",
115     "destroy2.raw"
116  };
117 
addpoint(int x,int y,int xp,int yp,int color,int time)118 static void addpoint(int x,int y,int xp,int yp,int color,int time)
119 {
120   point[npoint].x=x;
121   point[npoint].y=y;
122   point[npoint].xp=xp;
123   point[npoint].yp=yp;
124   point[npoint].time=time;
125   point[npoint].color=color;
126   npoint++;
127   if(npoint>=MAXPOINT) npoint=0;
128 }
129 int cit=0;
130 #define NTRACKS 4
131 #define next ((++cit)>=NTRACKS?cit=0:cit)
create_bitmap()132 static void create_bitmap()
133 {int x,y,r,size,po;
134 	printf("creating bitmaps...\n");
135 	for(x=0;x<BALL_RADIUS*2;x++)
136 	  for(y=0;y<BALL_RADIUS*2;y++)
137 		{
138 		 if((x-BALL_RADIUS)*(x-BALL_RADIUS)+(y-BALL_RADIUS)*(y-BALL_RADIUS)
139 			<BALL_RADIUS*BALL_RADIUS)
140 		 {
141 		 r=(x-BALL_XCENTER)*(x-BALL_XCENTER)+
142 		   (y-BALL_XCENTER)*(y-BALL_XCENTER);
143 		 r=r*NCOLORS/ROCKET_SIZE_MAX;
144 		 ball_data[x][y]=ball(r);
145 		 } else ball_data[x][y]=0;
146 		}
147 	printf("compiling bitmaps...\n");
148 	size = gl_compiledboxmasksize( BALL_RADIUS*2,BALL_RADIUS*2, ball_data );
149 	if((ball_bitmap=malloc(size))==NULL) perror("balls"),exit(1);
150 	gl_compileboxmask( BALL_RADIUS*2,BALL_RADIUS*2, ball_data, ball_bitmap );
151 	for(x=0;x<ROCKET_RADIUS*2;x++)
152 	  for(y=0;y<ROCKET_RADIUS*2;y++)
153 		{
154 		 if((x-ROCKET_RADIUS)*(x-ROCKET_RADIUS)+(y-ROCKET_RADIUS)*(y-ROCKET_RADIUS)
155 			<ROCKET_RADIUS*ROCKET_RADIUS)
156 		 {
157 		 r=(x-ROCKET_XCENTER)*(x-ROCKET_XCENTER)+
158 		   (y-ROCKET_XCENTER)*(y-ROCKET_XCENTER);
159 		 r=r*NCOLORS/ROCKET_SIZE_MAX;
160 		 rocket_data[x][y]=rocket(r);
161 		 } else rocket_data[x][y]=0;
162 		}
163 	printf("compiling bitmaps...\n");
164 	size = gl_compiledboxmasksize( ROCKET_RADIUS*2,ROCKET_RADIUS*2, rocket_data );
165 	if((rocket_bitmap=malloc(size))==NULL) perror("rocket"),exit(1);
166 	gl_compileboxmask( ROCKET_RADIUS*2,ROCKET_RADIUS*2, rocket_data, rocket_bitmap );
167 	for(po=0;po<MAXROCKETS;po++) {
168 	for(x=0;x<EYE_RADIUS*2;x++)
169 	  for(y=0;y<EYE_RADIUS*2;y++)
170 		{
171 		 if((x-EYE_RADIUS)*(x-EYE_RADIUS)+(y-EYE_RADIUS)*(y-EYE_RADIUS)
172 			<EYE_RADIUS*EYE_RADIUS)
173 		 {
174 		 r=(x-EYE_XCENTER)*(x-EYE_XCENTER)+
175 		   (y-EYE_XCENTER)*(y-EYE_XCENTER);
176 		 r=r*NCOLORS/EYE_SIZE_MAX;
177 		 eye_data[po][x][y]=32+32*po+r;
178 		 } else eye_data[po][x][y]=0;
179 		}
180 	printf("compiling bitmaps...\n");
181 	size = gl_compiledboxmasksize( EYE_RADIUS*2,EYE_RADIUS*2, eye_data[po] );
182 	if((eye_bitmap[po]=malloc(size))==NULL) perror("eye"),exit(1);
183 	gl_compileboxmask( EYE_RADIUS*2,EYE_RADIUS*2, eye_data[po], eye_bitmap[po] );
184 	}
185 }
normalize(float * x,float * y,float size)186 static inline void normalize(float *x,float *y,float size)
187 {
188 	float length=sqrt((*x)*(*x)+(*y)*(*y));
189 	if(length==0) length=1;
190 	*x*=size/length;
191 	*y*=size/length;
192 }
193 
setcustompalette()194 static void setcustompalette() {
195     /* colors 0-31 are a RGB mix (bits 0 and 1 red, 2 green, 3 and 4 blue) */
196     /* 32-63    black to red */
197 	Palette pal;
198 	int i;
199 	for (i = 0; i < 64; i++) {
200 		int r, g, b;
201 		r = g = b = 0;
202 		if ((i & 32) > 0) b = (i & 31) << 1;
203 		if (i < 32) {
204 			r = (i & 3) << 4;   /* 2 bits */
205 			g = (i & 4) << 3;   /* 1 bit */
206 			b = (i & 24) << 1;  /* 2 bits */
207 		}
208 		pal.color[i].red = r;
209 		pal.color[i].green = g;
210 		pal.color[i].blue = b;
211 	}
212 	for (i = 64; i < 64+32; i++) {
213 		int r, g, b;
214 		r = g = b = 0;
215 		r = (32-(i - 63)) << 1;
216 		if(i<64+8) {
217 		 b=g=((32-(i - 63))) << 3;
218 		}
219 		pal.color[i].red = r;
220 		pal.color[i].green = g;
221 		pal.color[i].blue = b;
222 	}
223 	for (i = 96; i < 96+32; i++) {
224 		int r, g, b;
225 		r = g = b = 0;
226 		r = g = (32-(i - 95)) << 1;
227 		if(i<96+8) {
228 		 b=((32-(i - 95))) << 3;
229 		}
230 		pal.color[i].red = r;
231 		pal.color[i].green = g;
232 		pal.color[i].blue = b;
233 	}
234 	for (i = 128; i < 128+32; i++) {
235 		int r, g, b;
236 		r = g = b = 0;
237 		g = (32-(i - 127)) << 1;
238 		if(i<128+8) {
239 		 r = b=((32-(i - 127))) << 3;
240 		}
241 		pal.color[i].red = r;
242 		pal.color[i].green = g;
243 		pal.color[i].blue = b;
244 	}
245 	for (i = 160; i < 160+32; i++) {
246 		int r, g, b;
247 		r = g = b = 0;
248 		b = (32-(i - 159)) << 1;
249 		if(i<160+8) {
250 		 r = g=((32-(i - 159))) << 3;
251 		}
252 		pal.color[i].red = r;
253 		pal.color[i].green = g;
254 		pal.color[i].blue = b;
255 	}
256 	gl_setpalette(&pal);
257 }
258 
259 
260 Sample sa[NSAMPLES];
loadsamples()261 void loadsamples()
262 {
263  int index;
264     for (index=0; index<NSAMPLES; index++)
265 	{
266 		if(Snd_loadRawSample( files[index], &sa[index] ))
267 			perror(files[index]),exit(-1);
268         }
269 	Snd_init( NSAMPLES, sa,11000, NTRACKS, "/dev/dsp" );
270 }
271 
initialize()272 static void initialize(){
273 	void *font;
274 	loadsamples();
275 	vga_disabledriverreport();
276 	vga_init();
277 	vga_setmode(VGAMODE);
278 	gl_setcontextvga(VGAMODE);
279 	physicalscreen = gl_allocatecontext();
280 	gl_getcontext(physicalscreen);
281 	gl_setcontextvgavirtual(VGAMODE);
282 	backscreen = gl_allocatecontext();
283 	gl_getcontext(backscreen);
284 	gl_setcontextvgavirtual(VGAMODE);
285 	setcustompalette();
286 	background = gl_allocatecontext();
287 	gl_getcontext(background);
288 	font = malloc(256 * 8 * 8 );
289 	gl_expandfont(8, 8, back(3), gl_font8x8, font);
290 	gl_setfont(8, 8, font);
291 #ifdef USE_PAGEFLIPPING
292 	/* Try to enable page flipping. */
293 	gl_enablepageflipping(&physicalscreen);
294 #endif
295 	if (keyboard_init()) {
296 		printf("Could not initialize keyboard.\n");
297 		exit(-1);
298 	}
299         /*keyboard_translatekeys(TRANSLATE_CURSORKEYS | TRANSLATE_KEYPADENTER);*/
300         keyboard_translatekeys(0);
301 }
createbackground()302 static void createbackground() {
303 /* Create fancy dark red background */
304 	int x, y;
305 	for (y = 0; y < MAPHEIGHT; y++)
306 		for (x = 0; x < MAPWIDTH; x++) {
307 			int i = 0;
308 			int n = 0;
309 			int c;
310 			if (x > 0) {
311 				i += gl_getpixel(x - 1, y) - back(0);
312 				n++;
313 			}
314 			if (y > 0) {
315 				i += gl_getpixel(x, y - 1) - back(0);
316 				n++;
317 			}
318 			c = (i + (random()%16)) / (n + 1);
319 			if (c > 9)
320 				c = 9;
321 			gl_setpixel(x, y, back(0) + c);
322 		}
323 }
324 
drawbackground()325 static void drawbackground() {
326 /* Build up background from map data */
327 	gl_setcontext(background);
328 	gl_clearscreen(0);
329 	createbackground();
330 }
331 
332 
333 
uninitialise()334 static void uninitialise()
335 {
336 	vga_setmode(TEXT);
337 }
338 
init_objects()339 static void init_objects()
340 {	int i;
341 	for(i=0;i<nobjects;i++)
342 	{	object[i].live=(i<nrockets?5:1);
343 		object[i].x=rand()%MAPWIDTH;
344 		object[i].y=rand()%MAPHEIGHT;
345 		object[i].fx=(rand()%10)/10.0;
346 		object[i].fy=(rand()%10)/10.0;
347 		object[i].rotation=0;
348 		object[i].type=(i<nrockets?ROCKET:BALL);
349 		object[i].M=(i<nrockets?ROCKETM:BALLM);
350 		object[i].radius=BALL_RADIUS;
351 		object[i].speed=2;
352 		object[i].accel=ROCKET_SPEED;
353 		object[i].letter=' ';
354 	}
355 }
move_objects()356 static void move_objects()
357 {
358 	int i;
359 	for(i=0;i<nobjects;i++)
360 	  if(object[i].type==CREATOR){
361 		object[i].time--;
362 		if(!object[i].time) {
363 			object[i].live=1,
364 			object[i].type=BALL;
365 		}
366 	  } else
367 	  if(object[i].live){
368 		object[i].x+=object[i].fx;
369 		object[i].y+=object[i].fy;
370 	}
371 
372 }
373 
points()374 static void points()
375 {
376 	int i;
377 	for(i=0;i<MAXPOINT;i++)
378 	{
379 		if(point[i].time>0) {
380 			point[i].time--;
381 			point[i].x+=point[i].xp;
382 			point[i].y+=point[i].yp;
383 			if(point[i].x>0&&point[i].x>>8<MAPWIDTH&&
384 			   point[i].y>0&&point[i].y>>8<MAPHEIGHT)
385 				gl_setpixel( point[i].x>>8,point[i].y>>8,point[i].color);
386 			else point[i].time=0;
387 		}
388 	}
389 }
390 char str[2];
draw_objects()391 static void draw_objects()
392 {
393 	int i;
394         gl_setcontext(background);
395         gl_copyscreen(backscreen);
396 
397         /* Now draw the objects in backscreen. */
398         gl_setcontext(backscreen);
399 
400 	points();
401 	for(i=0;i<nobjects;i++)
402 	  if(object[i].live){
403 		if(object[i].type==BALL||object[i].type==LBALL) {
404 		  gl_putboxmaskcompiled( (int)object[i].x - BALL_RADIUS, (int)object[i].y - BALL_RADIUS,
405 		  BALL_RADIUS * 2 ,BALL_RADIUS * 2 , ball_bitmap );
406 		  gl_setwritemode(WRITEMODE_MASKED);
407 		  str[0]=object[i].letter;
408 		  gl_write((int)object[i].x-4,(int)object[i].y-4, str);
409 
410 		  }
411 		if(object[i].type==ROCKET)
412 		  {int x1,y1;
413 		  gl_putboxmaskcompiled( (int)object[i].x - ROCKET_RADIUS, (int)object[i].y - ROCKET_RADIUS,
414 		  ROCKET_RADIUS * 2 ,ROCKET_RADIUS * 2 , rocket_bitmap );
415 		  x1=object[i].x+sin(object[i].rotation-RAD(30))*EYE_RADIUS1-EYE_RADIUS;
416 		  y1=object[i].y+cos(object[i].rotation-RAD(30))*EYE_RADIUS1-EYE_RADIUS;
417 		  gl_putboxmaskcompiled(  x1 , y1 ,
418 		  EYE_RADIUS * 2  ,EYE_RADIUS * 2 , eye_bitmap[i] );
419 		  x1=object[i].x+sin(object[i].rotation+RAD(30))*EYE_RADIUS1-EYE_RADIUS;
420 		  y1=object[i].y+cos(object[i].rotation+RAD(30))*EYE_RADIUS1-EYE_RADIUS;
421 		  gl_putboxmaskcompiled(  x1 , y1 ,
422 		  EYE_RADIUS * 2 ,EYE_RADIUS * 2 , eye_bitmap[i] );
423 		  }
424 	}
425 
426         /* Copy backscreen to physical screen. */
427         gl_copyscreen(physicalscreen);
428 }
explosion(int x,int y,int type)429 void explosion(int x,int y,int type)
430 {float i;
431  int speed;
432  int color;
433 	for(i=0;i<RAD(360);i+=RAD(2))
434 	{
435 	speed=rand()%1024;
436 	switch(type)
437 	{
438 		case BALL:color=ball(rand()%32);break;
439 		case ROCKET:color=rocket(rand()%32);break;
440 	}
441 	addpoint(x*256,y*256,
442 		sin(i)*(speed),
443 		cos(i)*(speed),
444 		color,
445 		rand()%1000);
446 	}
447 }
check_limit()448 static void check_limit()
449 {
450 	int i;
451 	for(i=0;i<nobjects;i++)
452 	  if(object[i].live){
453 		if(object[i].x-object[i].radius<0||object[i].x+object[i].radius>MAPWIDTH||
454 		   object[i].y-object[i].radius<0||object[i].y+object[i].radius>MAPHEIGHT)
455 			{
456 			switch(object[i].type) {
457 			case LBALL:
458 				Snd_effect( S_DESTROY_BALL, next );
459 				object[i].live=0,explosion(object[i].x,object[i].y,object[i].type);break;
460 			case BALL:
461 				Snd_effect( S_DESTROY_BALL, next );
462 				if(rand()%2==0)
463 				{
464 					if(object[i].x-object[i].radius<0||object[i].x+object[i].radius>MAPWIDTH)
465 						object[i].fx*=-1; else
466 						object[i].fy*=-1;
467 				object[i].type=LBALL;
468 				object[i].M=LBALLM;
469 		  	   	switch(rand()%2) {
470 					case 0:object[i].letter=L_ACCEL;break;
471 					case 1:object[i].letter=L_GUMM;break;
472 		  		}
473 				} else
474 					object[i].live=0,explosion(object[i].x,object[i].y,object[i].type);break;
475 				break;
476 			case ROCKET:
477 				Snd_effect( S_DESTROY_ROCKET, next );
478 				object[i].live--,explosion(object[i].x,object[i].y,object[i].type);
479 				if(object[i].live) {
480 					object[i].x=rand()%MAPWIDTH;
481 					object[i].y=rand()%MAPHEIGHT;
482 					object[i].fx=0;
483 					object[i].fy=0;
484 					object[i].rotation=0;
485 					object[i].type=ROCKET;
486 					object[i].speed=2;
487 					object[i].accel=ROCKET_SPEED;
488 				}
489 				break;
490 			}
491 			}
492 	}
493 
494 }
495 
process_keys()496 static void process_keys()
497 {
498 
499                 keyboard_update();
500 
501                 /* Move. */
502                 if (keyboard_keypressed(SCANCODE_CURSORLEFT))
503                         {object[0].rotation+=ROTSTEP;}
504                 if (keyboard_keypressed(SCANCODE_CURSORRIGHT))
505                         object[0].rotation-=ROTSTEP;
506                 if (keyboard_keypressed(SCANCODE_CURSORUP)){
507 			float p;
508 			int i;
509                         object[0].fx+=sin(object[0].rotation)*object[0].accel,
510                         object[0].fy+=cos(object[0].rotation)*object[0].accel;
511 			for(i=0;i<5;i++) {
512 			p=RAD(rand()%45-22);
513 			addpoint(object[0].x*256,
514 			         object[0].y*256,
515 			         (object[0].fx-sin(object[0].rotation+p)*object[0].accel*10)*(rand()%512),
516 			         (object[0].fy-cos(object[0].rotation+p)*object[0].accel*10)*(rand()%512),
517 				 rocket(rand()%16),10);
518 			}
519 			}
520 
521 
522                 /* Move. */
523                 if (keyboard_keypressed(SCANCODE_CURSORBLOCKLEFT))
524                         {object[1].rotation+=ROTSTEP;}
525                 if (keyboard_keypressed(SCANCODE_CURSORBLOCKRIGHT))
526                         object[1].rotation-=ROTSTEP;
527                 if (keyboard_keypressed(SCANCODE_CURSORBLOCKUP)){
528 			float p;
529 			int i;
530                         object[1].fx+=sin(object[1].rotation)*object[1].accel,
531                         object[1].fy+=cos(object[1].rotation)*object[1].accel;
532 			for(i=0;i<5;i++) {
533 			p=RAD(rand()%45-22);
534 			addpoint(object[1].x*256,
535 			         object[1].y*256,
536 			         (object[1].fx-sin(object[1].rotation+p)*object[1].accel*10)*(rand()%512),
537 			         (object[1].fy-cos(object[1].rotation+p)*object[1].accel*10)*(rand()%512),
538 				 rocket(rand()%16),10);
539 			}
540 			}
541 
542 }
543 
creator()544 static void creator()
545 {
546  int time=rand()%50+1;
547  int i;
548  int z;
549  int x,y;
550 	for(i=nobjects;i<MAXOBJECT&&(object[i].live||
551 		object[i].type==CREATOR);
552 		i++);
553 	if(i==MAXOBJECT) return;
554 	if(i>=nobjects) nobjects=i+1;
555 	object[i].live=0;
556 	object[i].x=rand()%MAPWIDTH;
557 	object[i].y=rand()%MAPHEIGHT;
558 	object[i].fx=0.0;
559 	object[i].fy=0.0;
560 	object[i].time=time;
561 	object[i].rotation=0;
562 	object[i].type=CREATOR;
563 	object[i].M=(i<nrockets?ROCKETM:BALLM);
564 	object[i].radius=BALL_RADIUS;
565 	object[i].speed=2;
566 	object[i].accel=ROCKET_SPEED;
567 	object[i].letter=' ';
568 	for(z=0;z<360;z++)
569 	{
570 	x=rand()%MAPWIDTH;
571 	y=rand()%MAPHEIGHT;
572 	addpoint(x*256,y*256,
573 		(object[i].x-x)*256/(time),
574 		(object[i].y-y)*256/(time),
575 		ball(rand()%32),
576 		time);
577 	}
578 }
579 
update_forces()580 static void update_forces()
581 {
582 	int i;
583 	int rocket=0;
584 	int r;
585 	float d;
586 	float xp,yp;
587 	if(!(rand()%120)) creator();
588 	for(i=0;i<nobjects;i++)
589 	{
590 	  if(object[i].live){
591 	  	if(object[i].type==BALL||object[i].type==LBALL){
592 			d=640*640;
593 			if(object[i].type==BALL&&!rand()%2048) {
594 				object[i].type=LBALL;
595 		  	   	switch(rand()%2) {
596 					case 0:object[i].letter=L_ACCEL;break;
597 					case 1:object[i].letter=L_GUMM;break;
598 		  		}
599 			}
600 			for(r=0;r<nrockets;r++)
601 			{
602 				if(object[r].live) {
603 				xp=object[r].x-object[i].x;
604                         	yp=object[r].y-object[i].y;
605 				if(xp*xp+yp*yp<d) d=xp*xp+yp*yp,rocket=r;}
606 
607 			}
608 			xp=object[rocket].x-object[i].x;
609 			yp=object[rocket].y-object[i].y;
610 			normalize(&xp,&yp,BALL_SPEED);
611 			object[i].fx+=xp;
612 			object[i].fy+=yp;
613 		}
614 	  /*if(object[i].fx*object[i].fx+
615 	     object[i].fy*object[i].fy>object[i].speed*object[i].speed)*/
616 		object[i].fx*=SLOWDOWN,
617 		object[i].fy*=SLOWDOWN;
618 	}
619 	}
620 }
colisions()621 static void colisions()
622 {	int i,y;
623 	int colize=0;
624 	float xp,yp;
625 	for(i=0;i<nobjects;i++)
626 	  if(object[i].live)
627 	     for(y=i+1;y<nobjects;y++)
628 	       if(object[y].live)
629 		{
630 		  xp=object[y].x-object[i].x;
631 		  yp=object[y].y-object[i].y;
632 		  if(xp*xp+yp*yp<(object[y].radius+object[i].radius)*
633 				 (object[y].radius+object[i].radius))
634 			{colize=1;
635 			if(object[i].type==ROCKET) {
636 				if(object[y].letter==L_ACCEL)
637 					object[i].accel*=L_MULT;
638 				if(object[y].letter==L_GUMM)
639 					object[i].M*=L_MULT;
640 				object[y].letter=' ';
641 				if(object[y].type==LBALL) object[y].type=BALL;
642 				}
643 			normalize(&xp,&yp,object[i].M/object[y].M*GUMM);
644 			object[y].fx+=xp;
645 			object[y].fy+=yp;
646 			normalize(&xp,&yp,object[y].M/object[i].M*GUMM);
647 			object[i].fx-=xp;
648 			object[i].fy-=yp;
649 			}
650 		}
651 	if(colize)
652 	Snd_effect( S_COLIZE, next );
653 }
654 
game()655 static void game()
656 {
657 	Snd_effect( S_START, next );
658 	while(1) {
659 		process_keys();
660 		update_forces();
661 		colisions();
662 		move_objects();
663 		check_limit();
664 		draw_objects();
665 		usleep(5000);
666 	}
667 	Snd_effect( S_END, next );
668 }
main()669 int main()
670 {
671 	create_bitmap();
672 	printf("initializing vgalib\n");
673 	initialize();
674 	printf("initializing objects\n");
675 	init_objects();
676 	printf("creating bitmaps\n");
677 	drawbackground();
678 	printf("playing game\n");
679 	game();
680 	printf("uninitializing\n");
681 	uninitialise();
682 	return 0;
683 }
684