adjust to match the uname changes.
[AROS-Contrib.git] / Demo / Firework / firework.c
blob7675615c8bbd499d21a69ede2e60ad956eb53401
2 #include <dos/dos.h>
3 #include <intuition/intuition.h>
4 #include <graphics/gfx.h>
5 #include <cybergraphx/cybergraphics.h>
6 #include <proto/exec.h>
7 #include <proto/dos.h>
8 #include <proto/graphics.h>
9 #include <proto/cybergraphics.h>
10 #include <proto/intuition.h>
12 #include <math.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <memory.h>
19 /***********************************************************************************/
21 struct IntuitionBase *IntuitionBase;
22 struct GfxBase *GfxBase;
23 struct Library *CyberGfxBase;
24 struct Screen *scr;
25 struct Window *win;
26 struct RastPort *rp;
28 ULONG cgfx_coltab[256];
29 UBYTE remaptable[256];
30 UBYTE Keys[128];
31 char s[256];
32 WORD winx = -1, winy = -1;
33 BOOL forcescreen, forcewindow;
34 BOOL mustremap, truecolor, remapped, wbscreen = TRUE;
36 /***********************************************************************************/
38 #define RANDOM ((WORD)(rand() & 0xFFFF))
40 #define W 320
41 #define H 200
42 #define PARTICLES 4096
44 struct Particle
46 WORD speed;
47 WORD counter;
48 WORD ypos;
49 WORD xpos;
50 UBYTE particlecolor;
53 #define xspeed counter
54 #define yspeed speed
56 static UBYTE chunkybufferarray[W * (H + 2)];
57 static UBYTE *chunkybuffer = &chunkybufferarray[W];
59 static UBYTE chunkybuffer_remapped[W * H];
61 struct Particle particles[PARTICLES];
63 /***********************************************************************************/
65 static void refresh(void)
67 if (truecolor)
69 WriteLUTPixelArray(chunkybuffer,
73 rp,
74 cgfx_coltab,
75 win->BorderLeft,
76 win->BorderTop,
79 CTABFMT_XRGB8);
81 else if (mustremap)
83 LONG i;
84 UBYTE *src = chunkybuffer;
85 UBYTE *dest = chunkybuffer_remapped;
87 for(i = 0; i < W * H; i++)
89 *dest++ = remaptable[*src++];
91 WriteChunkyPixels(rp,
92 win->BorderLeft,
93 win->BorderTop,
94 win->BorderLeft + W - 1,
95 win->BorderTop + H - 1,
96 chunkybuffer_remapped,
97 W);
99 else
101 WriteChunkyPixels(rp,
102 win->BorderLeft,
103 win->BorderTop,
104 win->BorderLeft + W - 1,
105 win->BorderTop + H - 1,
106 chunkybuffer,
111 /***********************************************************************************/
113 static void initpalette(void)
115 static UBYTE pal[256*3];
117 ULONG ecx = 1024;
118 ULONG eax = 0xA000;
119 ULONG temp;
120 ULONG palindex = 0;
122 for(ecx = 1024; ecx; ecx--)
124 eax = (eax >> 8) | (eax & 0xFF) << 24;
125 if ((eax & 255) >= 63)
127 eax &= ~0xFF; eax |= 63;
128 temp = ((eax & 0xFF00) + 0x400) & 0xFF00;
129 eax &= ~0xFF00; eax |= temp;
132 if (ecx & 3)
134 pal[palindex++] = (UBYTE)eax;
138 for(palindex = 0; palindex < 256; palindex++)
140 ULONG red = pal[palindex*3] * 4;
141 ULONG green = pal[palindex*3+1] * 4;
142 ULONG blue = pal[palindex*3+2] * 4;
144 if (truecolor)
146 cgfx_coltab[palindex] = (red << 16) + (green << 8) + blue;
148 else if (mustremap)
150 red *= 0x01010101;
151 green *= 0x01010101;
152 blue *= 0x01010101;
154 remaptable[palindex] = ObtainBestPen(scr->ViewPort.ColorMap,
155 red,
156 green,
157 blue,
158 OBP_Precision, PRECISION_IMAGE,
159 OBP_FailIfBad, FALSE,
160 TAG_DONE);
161 remapped = TRUE;
164 else
166 red *= 0x01010101;
167 green *= 0x01010101;
168 blue *= 0x01010101;
170 SetRGB32(&scr->ViewPort, palindex, red, green, blue);
176 /***********************************************************************************/
178 static void ticker(void)
180 static ULONG tick;
181 static ULONG ebx;
182 static ULONG si = 0x100;
184 WORD x, y;
185 ULONG ecx;
187 tick++;
189 if (!(tick & 3))
191 /* New explosion */
193 x = RANDOM / 2;
194 y = RANDOM / 2;
196 for(ecx = 256; ecx; ecx--)
198 struct Particle *p;
199 float f;
201 WORD xspeed;
202 WORD yspeed;
204 p = &particles[ebx];
205 ebx = (ebx + 1) & (PARTICLES - 1);
207 p->speed = RANDOM >> 6;
208 p->counter = ecx;
210 //f= (float)(*(ULONG *)(&p->speed));
211 f = (float)((ULONG)p->speed + (ULONG)p->counter * 65536);
213 p->ypos = y;
215 xspeed = sin(f) * p->speed;
216 yspeed = cos(f) * p->speed;
218 p->xpos = x;
220 p->particlecolor = 58;
221 p->yspeed = ((UWORD)yspeed) * 2;
222 p->xspeed = xspeed;
227 /* Draw/move all particles */
229 for(ecx = PARTICLES; ecx; ecx--)
231 struct Particle *p = &particles[si];
232 WORD xp, yp;
234 p->yspeed += 16;
235 p->ypos += p->yspeed; p->yspeed -= (p->yspeed / 16);
236 p->xpos += p->xspeed; p->xspeed -= (p->xspeed / 16);
238 yp = p->ypos / 256;
239 xp = p->xpos / 128;
241 if ((yp >= -99) && (yp <= 99) && (xp >= -159) && (xp <= 159))
243 ULONG dest = (yp + 100) * W + xp + 160;
245 UBYTE col = p->particlecolor--;
247 if (col > chunkybuffer[dest])
249 chunkybuffer[dest] = col;
253 si = (si + 1) & (PARTICLES - 1);
256 /* blur */
258 for(ecx = 0; ecx < W * H; ecx++)
260 UBYTE col = chunkybuffer[ecx];
262 col += chunkybuffer[ecx + 1];
263 if (ecx >= W)
264 col += chunkybuffer[ecx - W];
265 col += chunkybuffer[ecx + W];
266 col /= 4;
268 if ((col > 0) && (tick & 1))
270 col--;
273 chunkybuffer[ecx] = col;
277 /***********************************************************************************/
279 static void cleanup(char *msg)
281 if (msg)
283 printf("Firework: %s\n",msg);
286 if (win) CloseWindow(win);
288 if (remapped)
290 WORD i;
292 for(i = 0; i < 256; i++)
294 ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
298 if (scr)
300 if (wbscreen)
301 UnlockPubScreen(0, scr);
302 else
303 CloseScreen(scr);
306 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
307 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
308 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
310 exit(0);
313 /***********************************************************************************/
315 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
316 #define ARG_X 0
317 #define ARG_Y 1
318 #define ARG_SCR 2
319 #define ARG_WIN 3
320 #define NUM_ARGS 4
322 static IPTR args[NUM_ARGS];
324 static void getarguments(void)
326 struct RDArgs *myargs;
328 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
330 if (args[ARG_SCR])
331 forcescreen = TRUE;
332 else if (args[ARG_WIN])
333 forcewindow = TRUE;
335 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
336 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
338 FreeArgs(myargs);
342 /***********************************************************************************/
344 static void openlibs(void)
346 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
348 cleanup("Can't open intuition.library V39!");
351 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
353 cleanup("Can't open graphics.library V39!");
356 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
358 cleanup("Can't open cybergraphics.library!");
362 /***********************************************************************************/
364 static void getvisual(void)
366 if (!(scr = LockPubScreen(NULL)))
368 cleanup("Can't lock pub screen!");
371 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
373 if (!forcewindow)
375 wbscreen = FALSE;
377 else
379 mustremap = TRUE;
383 if (forcescreen) wbscreen = FALSE;
385 if (!wbscreen)
387 UnlockPubScreen(NULL, scr);
388 wbscreen = FALSE;
390 scr = OpenScreenTags(NULL, SA_Width, W,
391 SA_Height, H,
392 SA_Depth, 8,
393 TAG_DONE);
395 if (!scr) cleanup("Can't open screen!");
398 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
401 /***********************************************************************************/
403 static void makewin(void)
405 struct TagItem winonwbtags[] =
407 {WA_DragBar, TRUE },
408 {WA_DepthGadget, TRUE },
409 {WA_CloseGadget, TRUE },
410 {WA_Title, (IPTR)"Firework" },
411 {TAG_DONE }
414 struct TagItem winonscrtags[] =
416 {WA_Borderless, TRUE },
417 {TAG_DONE }
420 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
421 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
423 win = OpenWindowTags(NULL, WA_CustomScreen, (IPTR)scr,
424 WA_Left, winx,
425 WA_Top, winy,
426 WA_InnerWidth, W,
427 WA_InnerHeight, H,
428 WA_AutoAdjust, TRUE,
429 WA_Activate, TRUE,
430 WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
431 TAG_MORE, wbscreen ? winonwbtags : winonscrtags);
433 if (!win) cleanup("Can't open window");
435 rp = win->RPort;
438 /***********************************************************************************/
440 #define KC_LEFT 0x4F
441 #define KC_RIGHT 0x4E
442 #define KC_UP 0x4C
443 #define KC_DOWN 0x4D
444 #define KC_ESC 0x45
446 /***********************************************************************************/
448 static void getevents(void)
450 struct IntuiMessage *msg;
452 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
454 switch(msg->Class)
456 case IDCMP_CLOSEWINDOW:
457 Keys[KC_ESC] = 1;
458 break;
460 case IDCMP_RAWKEY:
462 WORD code = msg->Code & ~IECODE_UP_PREFIX;
463 Keys[code] = (code == msg->Code) ? 1 : 0;
465 break;
467 ReplyMsg((struct Message *)msg);
472 /***********************************************************************************/
474 static void action(void)
476 initpalette();
478 while (!Keys[KC_ESC])
480 getevents();
482 ticker();
483 refresh();
484 WaitTOF();
488 /***********************************************************************************/
490 int main(void)
492 getarguments();
493 openlibs();
494 getvisual();
495 makewin();
496 action();
497 cleanup(0);
499 return 0;
502 /***********************************************************************************/