1 /***********************************************************
2 *                      K O U L E S                         *
3 *----------------------------------------------------------*
4 *  C1995 JAHUSOFT                                          *
5 *        Jan Hubicka                                       *
6 *        Dukelskych Bojovniku 1944                         *
7 *        390 03 Tabor                                      *
8 *        Czech Republic                                    *
9 *        Phone: 0041-361-32613                             *
10 *        eMail: hubicka@limax.paru.cas.cz                  *
11 *----------------------------------------------------------*
12 *   Copyright(c)1995,1996 by Jan Hubicka.See README for    *
13 *                    licence details.                      *
14 *----------------------------------------------------------*
15 *  framebuffer.c fast 8 bit framebuffer bitmap creation    *
16 *                routines                                  *
17 ***********************************************************/
18 #include "koules.h"
19 
20 
21 #define NCOLORS 32
22 
23 #define HOLE_XCENTER (2*HOLE_RADIUS-3*HOLE_RADIUS/4)
24 #define HOLE_YCENTER (2*HOLE_RADIUS-HOLE_RADIUS/4)
25 #define HOLE_MAX_RADIUS (HOLE_RADIUS/DIV+0.5*HOLE_RADIUS/DIV)
26 #define HOLE_SIZE_MAX (radius*radius)
27 #ifndef NODIRECT
28 /*
29  * hardcoded bitmap drawing routines
30  */
31 static char    *
draw_ball_bitmap(int radius,CONST int color)32 draw_ball_bitmap (int radius, CONST int color)
33 {
34   char           *bitmap = NULL, *point;
35   int             x, y, r;
36   radius /= DIV;
37   if ((bitmap = alloca ((radius * 2) * (radius * 2) + 2)) == NULL)
38     perror ("create_ball_bitmap"), exit (-1);
39   point = bitmap;
40   for (y = 0; y < radius * 2; y++)
41     for (x = 0; x < radius * 2; x++, point++)
42       {
43 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
44 	    < (radius - 0.5) * (radius - 0.5))
45 	  {
46 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
47 	      (y - radius / 4) * (y - radius / 4);
48 	    r = r * 32 / (1.5 * radius) / (1.5 * radius);
49 	    if (r > 31)
50 	      r = 31;
51 	    *point = color + r;
52 	  }
53 	else
54 	  *point = 0;
55       }
56   return (CompileBitmap (radius * 2, radius * 2, (char *) bitmap));
57 }
58 static char    *
draw_reversed_ball_bitmap(int radius,CONST int color)59 draw_reversed_ball_bitmap (int radius, CONST int color)
60 {
61   char           *bitmap = NULL, *point;
62   int             x, y, r;
63   radius /= DIV;
64   if ((bitmap = alloca ((radius * 2) * (radius * 2) + 2)) == NULL)
65     perror ("create_ball_bitmap"), exit (-1);
66   point = bitmap;
67   for (y = 0; y < radius * 2; y++)
68     for (x = 0; x < radius * 2; x++, point++)
69       {
70 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
71 	    < (radius - 0.5) * (radius - 0.5))
72 	  {
73 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
74 	      (y - radius / 4) * (y - radius / 4);
75 	    r = r * 32 / (1.5 * radius) / (1.5 * radius);
76 	    if (r > 31)
77 	      r = 31;
78 	    *point = color + 16 + r / 2;
79 	  }
80 	else
81 	  *point = 0;
82       }
83   return (CompileBitmap (radius * 2, radius * 2, (char *) bitmap));
84 }
85 static char    *
draw_apple_bitmap(int radius,CONST int color)86 draw_apple_bitmap (int radius, CONST int color)
87 {
88   char           *bitmap = NULL, *point;
89   int             x, y, r;
90   int             radius1;
91   radius /= DIV;
92   if ((bitmap = alloca ((radius * 2) * (radius * 2) + 2)) == NULL)
93     perror ("create_ball_bitmap"), exit (-1);
94   point = bitmap;
95   for (y = 0; y < radius * 2; y++)
96     for (x = 0; x < radius * 2; x++, point++)
97       {
98 	if (DIV == 2)
99 	  radius1 = radius * (abs (x - radius) / 2 + 25) / 30;
100 	else
101 	  radius1 = radius * (abs (x - radius) / 2 + 50) / 60;
102 	if (radius1 > radius)
103 	  radius1 = radius;
104 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
105 	    < ((radius1) * (radius1)))
106 	  {
107 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
108 	      (y - radius / 4) * (y - radius / 4);
109 	    r = 3 + r * 22 / (1.5 * radius1) / (1.5 * radius1);
110 	    if (r > 31)
111 	      r = 31;
112 	    *point = color + r;
113 	  }
114 	else
115 	  *point = 0;
116       }
117   return (CompileBitmap (radius * 2, radius * 2, (char *) bitmap));
118 }
119 #else
120 static float    err = 0.0;
121 #ifdef XSUPPORT
122 static INLINE int
errdist(int c)123 errdist (int c)
124 {
125   float           sat, merr;
126   int             i;
127   int             p;
128   c &= 0xff;
129   sat = opixels[c] + err;
130   merr = sat - spixels[c];
131   p = c;
132   if (sat < spixels[c])
133     {
134       int             max = c / 32;
135       max = (max + 1) * 32;
136       for (i = c; i < max && i < 255; i++)
137 	{
138 	  if (fabs (merr) > fabs (spixels[i] - sat))
139 	    {
140 	      p = i;
141 	      merr = sat - spixels[i];
142 	    }
143 	}
144     }
145   if (sat > spixels[c])
146     {
147       int             min = c / 32;
148       min *= 32;
149       for (i = c; i > min && i > 0; i--)
150 	{
151 	  if (fabs (merr) > fabs (spixels[i] - sat))
152 	    {
153 	      p = i;
154 	      merr = sat - spixels[i];
155 	    }
156 	}
157     }
158   if (fabs (merr) > fabs (64 - sat))
159     {
160       p = 255;
161       merr = sat - 64;
162     }
163   if (fabs (merr) > fabs (sat))
164     {
165       p = 32;
166       merr = sat;
167     }
168   err = merr;
169   return (p);
170 }
171 #else
172 #define errdist(c) c
173 #endif
174 static          BitmapType
draw_ball_bitmap(int radius,CONST int color)175 draw_ball_bitmap (int radius, CONST int color)
176 {
177   RawBitmapType   bbitmap;
178   int             x, y, r, c;
179   radius /= DIV;
180   err = 0.0;
181   bbitmap = CreateBitmap ((radius * 2), (radius * 2));
182   for (y = 0; y < radius * 2; y++)
183     for (x = 0; x < radius * 2; x++)
184       {
185 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
186 	    < (radius - 0.5) * (radius - 0.5))
187 	  {
188 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
189 	      (y - radius / 4) * (y - radius / 4);
190 	    r = r * 32 / (1.5 * radius) / (1.5 * radius);
191 	    if (r > 31)
192 	      r = 31;
193 	    c = errdist (color + r);
194 	    BSetPixel (bbitmap, x, y, c);
195 	  }
196 	else
197 	  {
198 	    err = 0.0;
199 	    BSetPixel (bbitmap, x, y, 0);
200 	  }
201       }
202   return (CompileBitmap (radius * 2, radius * 2, bbitmap));
203 }
204 static          BitmapType
draw_reversed_ball_bitmap(int radius,CONST int color)205 draw_reversed_ball_bitmap (int radius, CONST int color)
206 {
207   RawBitmapType   bbitmap;
208   int             x, y, r, c;
209   radius /= DIV;
210   err = 0.0;
211   bbitmap = CreateBitmap ((radius * 2), (radius * 2));
212   for (y = 0; y < radius * 2; y++)
213     for (x = 0; x < radius * 2; x++)
214       {
215 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
216 	    < (radius - 0.5) * (radius - 0.5))
217 	  {
218 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
219 	      (y - radius / 4) * (y - radius / 4);
220 	    r = r * 32 / (1.5 * radius) / (1.5 * radius);
221 	    if (r > 31)
222 	      r = 31;
223 	    c = errdist (color + 16 + r / 2);
224 	    BSetPixel (bbitmap, x, y, c);
225 	  }
226 	else
227 	  {
228 	    err = 0.0;
229 	    BSetPixel (bbitmap, x, y, 0);
230 	  }
231       }
232   return (CompileBitmap (radius * 2, radius * 2, bbitmap));
233 }
234 static          BitmapType
draw_apple_bitmap(int radius,CONST int color)235 draw_apple_bitmap (int radius, CONST int color)
236 {
237   RawBitmapType   bitmap;
238   int             x, y, r, c;
239   int             radius1;
240   radius /= DIV;
241   bitmap = CreateBitmap ((radius * 2), (radius * 2));
242   err = 0;
243   for (y = 0; y < radius * 2; y++)
244     for (x = 0; x < radius * 2; x++)
245       {
246 	if (DIV == 2)
247 	  radius1 = radius * (abs (x - radius) / 2 + 25) / 30;
248 	else
249 	  radius1 = radius * (abs (x - radius) / 2 + 50) / 60;
250 	if (radius1 > radius)
251 	  radius1 = radius;
252 	if ((x - radius) * (x - radius) + (y - radius) * (y - radius)
253 	    < ((radius1) * (radius1)))
254 	  {
255 	    r = (x - 3 * radius / 4) * (x - 3 * radius / 4) +
256 	      (y - radius / 4) * (y - radius / 4);
257 	    r = 3 + r * 22 / (1.5 * radius1) / (1.5 * radius1);
258 	    if (r > 31)
259 	      r = 31;
260 	    c = errdist (color + r);
261 	    BSetPixel (bitmap, x, y, c);
262 	  }
263 	else
264 	  {
265 	    BSetPixel (bitmap, x, y, 0);
266 	  }
267       }
268   return (CompileBitmap (radius * 2, radius * 2, bitmap));
269 }
270 #endif
271 void
create_bitmap()272 create_bitmap ()
273 {
274   int             x, y, r, po, radius;
275 #ifndef NODIRECT
276   char            hole_data[HOLE_RADIUS * 2][HOLE_RADIUS * 2];
277   char            ehole_data[HOLE_RADIUS * 2][HOLE_RADIUS * 2];
278 #else
279   int             c;
280   RawBitmapType   hole_data, ehole_data;
281 #endif
282   printf ("creating bitmaps...\n");
283 #ifndef NODIRECT
284   for (x = 0; x < HOLE_RADIUS * 2; x++)
285     for (y = 0; y < HOLE_RADIUS * 2; y++)
286       {
287 	if (DIV == 1)
288 	  radius = HOLE_RADIUS / 2 + (int) (atan (fabs (x - HOLE_RADIUS + 0.5) / fabs (y - HOLE_RADIUS + 0.5)) * HOLE_RADIUS / 2) % (HOLE_RADIUS / 2);
289 	else
290 	  radius = HOLE_RADIUS / 4;
291 	if ((x - HOLE_RADIUS / DIV) * (x - HOLE_RADIUS / DIV) + (y - HOLE_RADIUS / DIV) * (y - HOLE_RADIUS / DIV)
292 	    < radius * radius)
293 	  {
294 	    r = (x - HOLE_RADIUS / DIV) * (x - HOLE_RADIUS / DIV) +
295 	      (y - HOLE_RADIUS / DIV) * (y - HOLE_RADIUS / DIV);
296 	    r = r * 24 / HOLE_SIZE_MAX;
297 	    if (r > 23)
298 	      r = 23;
299 	    hole_data[x][y] = 64 + r + 1;
300 	    ehole_data[x][y] = 128 + r + 1;
301 	  }
302 	else
303 	  hole_data[x][y] = 0,
304 	    ehole_data[x][y] = 0;
305       }
306   hole_bitmap = (CompileBitmap (HOLE_RADIUS * 2, HOLE_RADIUS * 2, (char *) hole_data));
307   ehole_bitmap = (CompileBitmap (HOLE_RADIUS * 2, HOLE_RADIUS * 2, (char *) ehole_data));
308 #else
309   ehole_data = CreateBitmap ((HOLE_RADIUS * 2), (HOLE_RADIUS * 2));
310   hole_data = CreateBitmap ((HOLE_RADIUS * 2), (HOLE_RADIUS * 2));
311   err = 0;
312   for (x = 0; x < HOLE_RADIUS * 2; x++)
313     for (y = 0; y < HOLE_RADIUS * 2; y++)
314       {
315 	if (DIV == 1)
316 	  radius = HOLE_RADIUS / 2 + (int) (atan (fabs (x - HOLE_RADIUS + 0.5) / fabs (y - HOLE_RADIUS + 0.5)) * HOLE_RADIUS / 2) % (HOLE_RADIUS / 2);
317 	else
318 	  radius = HOLE_RADIUS / 4;
319 	if ((x - HOLE_RADIUS / DIV) * (x - HOLE_RADIUS / DIV) + (y - HOLE_RADIUS / DIV) * (y - HOLE_RADIUS / DIV)
320 	    < radius * radius)
321 	  {
322 	    r = (x - HOLE_RADIUS / DIV) * (x - HOLE_RADIUS / DIV) +
323 	      (y - HOLE_RADIUS / DIV) * (y - HOLE_RADIUS / DIV);
324 	    r = r * 24 / HOLE_SIZE_MAX;
325 	    if (r > 23)
326 	      r = 23;
327 	    c = errdist (64 + r + 1);
328 	    BSetPixel (hole_data, x, y, c);
329 	    c = errdist (128 + r + 1);
330 	    BSetPixel (ehole_data, x, y, c);
331 	  }
332 	else
333 	  {
334 	    BSetPixel (hole_data, x, y, 0);
335 	    BSetPixel (ehole_data, x, y, 0);
336 	  }
337       }
338   ehole_bitmap = (CompileBitmap ((HOLE_RADIUS * 2), (HOLE_RADIUS * 2), ehole_data));
339   hole_bitmap = (CompileBitmap (HOLE_RADIUS * 2, HOLE_RADIUS * 2, hole_data));
340 #endif
341 
342   for (po = 0; po < MAXROCKETS; po++)
343     {
344       eye_bitmap[po] = draw_ball_bitmap (EYE_RADIUS, 32 + 32 * po);
345     }
346   ball_bitmap = draw_ball_bitmap (BALL_RADIUS, ball (0));
347   mouse_bitmap = draw_ball_bitmap (MOUSE_RADIUS * DIV, 32 + 32 * 2);
348   bball_bitmap = draw_ball_bitmap (BBALL_RADIUS, 4 * 32);
349   apple_bitmap = draw_apple_bitmap (APPLE_RADIUS, ball (0));
350   inspector_bitmap = draw_ball_bitmap (INSPECTOR_RADIUS, 160);
351   lunatic_bitmap = draw_reversed_ball_bitmap (LUNATIC_RADIUS, 192);
352   lball_bitmap[0] = draw_ball_bitmap (BALL_RADIUS, 4 * 32);
353   lball_bitmap[1] = draw_ball_bitmap (BALL_RADIUS, 5 * 32);
354   lball_bitmap[2] = draw_reversed_ball_bitmap (BALL_RADIUS, 192);
355   lball_bitmap[3] = draw_reversed_ball_bitmap (BALL_RADIUS, 0);
356   lball_bitmap[4] = draw_reversed_ball_bitmap (BALL_RADIUS, 3 * 32 - 5);
357  /* lball_bitmap[5] = draw_reversed_ball_bitmap (BALL_RADIUS, 4 * 32 - 5);*/
358 
359   for (x = 0; x < 5; x++)
360     rocket_bitmap[x] = draw_ball_bitmap (ROCKET_RADIUS, rocketcolor[x]);
361 
362 
363 
364 }
365 
366 
367 
368 
369 
370 
371 
372 
373 
374 #ifndef XSUPPORT
375 static void
createbackground()376 createbackground ()
377 {
378 /* Create fancy dark red background */
379   int             x, y;
380 #ifndef NODIRECT
381   char           *pixel = background->vbuf;
382 #endif
383   for (y = 0; y < MAPHEIGHT + 20; y++)
384     for (x = 0; x < MAPWIDTH; x++)
385       {
386 	int             i = 0;
387 	int             n = 0;
388 	int             c;
389 	if (x > 0)
390 	  {
391 #ifndef NODIRECT
392 	    i += *(pixel - 1) - back (0);
393 #else
394 	    i += SGetPixel (x - 1, y);
395 #endif
396 	    n++;
397 	  }
398 	if (y > 0)
399 	  {
400 #ifndef NODIRECT
401 	    i += *(pixel - MAPWIDTH) - back (0);
402 #else
403 	    i += SGetPixel (x, y - 1);
404 #endif
405 	    n++;
406 	  }
407 	c = (i + (rand () % 16)) / (n + 1);
408 	if (c > 9)
409 	  c = 9;
410 #ifndef NODIRECT
411 	*pixel = back (0) + c;
412 	pixel++;
413 #else
414 	SPutPixel (x, y, back (0) + c);
415 #endif
416       }
417 }
418 #else
419 #ifdef MITSHM
420 static void
Shmcreatebackground()421 Shmcreatebackground ()
422 {
423 /* Create fancy dark red background */
424   int             x, y;
425   unsigned char  *pixel = (unsigned char *) background.vbuff;
426   for (y = 0; y < MAPHEIGHT + 20; y++)
427     for (x = 0; x < MAPWIDTH; x++)
428       {
429 	int             i = 0;
430 	int             n = 0;
431 	int             c;
432 	if (x > 0)
433 	  {
434 	    i += *(pixel - 1) - back (0);
435 	    n++;
436 	  }
437 	if (y > 0)
438 	  {
439 	    i += *(pixel - MAPWIDTH) - back (0);
440 	    n++;
441 	  }
442 	c = (i + (rand () % 16)) / (n + 1);
443 	if (c > 9)
444 	  c = 9;
445 	*pixel = back (0) + c;
446 	pixel++;
447       }
448   pixel = (unsigned char *) background.vbuff;
449   for (y = 0; y < MAPHEIGHT + 20; y++)
450     for (x = 0; x < MAPWIDTH; x++)
451       *pixel = (unsigned char) pixels[*pixel],
452 	pixel++;
453 }
454 #endif
455 static void
createbackground()456 createbackground ()
457 {
458 /* Create fancy dark red background */
459   int             x, y;
460   XImage         *img;
461   char           *data;
462 #ifdef MITSHM
463   if (shm)
464     {
465       Shmcreatebackground ();
466       return;
467     }
468 #endif
469   if ((data = (char *) calloc ((MAPWIDTH + BitmapPad (dp)) * (MAPHEIGHT + 20) * 4, 1)) == NULL)
470     perror ("Memory Error"), exit (2);
471   img = XCreateImage (dp, DefaultVisual (dp, screen), DefaultDepth (dp, screen),
472 		      ZPixmap, 0, data, MAPWIDTH, MAPHEIGHT + 20,
473 		      BitmapPad (dp), 0);
474   for (y = 0; y < MAPHEIGHT + 20; y++)
475     for (x = 0; x < MAPWIDTH; x++)
476       {
477 	int             i = 0;
478 	int             n = 0;
479 	int             c;
480 	if (x > 0)
481 	  {
482 	    i += XGetPixel (img, x - 1, y);
483 	    n++;
484 	  }
485 	if (y > 0)
486 	  {
487 	    i += XGetPixel (img, x, y - 1);
488 	    n++;
489 	  }
490 	c = (i + (rand () % 16)) / (n + 1);
491 	if (c > 9)
492 	  c = 9;
493 	/*gl_setpixel (x, y, back (0) + c); */
494 	XPutPixel (img, x, y, c & 0xff);
495       }
496   for (y = 0; y < MAPHEIGHT + 20; y++)
497     for (x = 0; x < MAPWIDTH; x++)
498       XPutPixel (img, x, y, pixels[back (0) + XGetPixel (img, x, y)]);
499   XPutImage (dp, current.pixmap, gc, img, 0, 0, 0, 0, MAPWIDTH, MAPHEIGHT + 20);
500   XSync (dp, 1);
501   XDestroyImage (img);
502 }
503 #endif
504 void
drawstarbackground()505 drawstarbackground ()
506 {
507 /* Create fancy dark red background */
508   int             x;
509   int             x1, y1, c1;
510   SetScreen (starbackground);
511   ClearScreen ();
512   for (x = 0; x < 700 / DIV / DIV; x++)
513     {
514       x1 = rand () % MAPWIDTH;
515       y1 = rand () % (MAPHEIGHT + 20);
516       c1 = rand () % 32 + 192;
517       SSetPixel (x1, y1, c1);
518     }
519 }
520 
521 
522 
523 
524 void
drawbackground()525 drawbackground ()
526 {				/*int i; */
527 /* Build up background from map data */
528   SetScreen (background);
529   ClearScreen ();
530   createbackground ();
531   EnableClipping ();
532 #ifdef MITSHM
533   if (shm)
534     HLine (0, MAPHEIGHT, MAPWIDTH - 1, back (16));
535   else
536 #endif
537     Line (0, MAPHEIGHT, MAPWIDTH - 1, MAPHEIGHT, back (16));
538   DisableClipping ();
539 }
540