fix remapping behavior. Remapping is only necessary if we are rendering on the workbe...
[AROS-Contrib.git] / Demo / RubberStrings / rubberstrings.c
blobd34b64c35a00c69e5a3ae34c1da7ecb497c8976b
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;
27 ULONG cgfx_coltab[256];
28 UBYTE remaptable[256];
29 UBYTE Keys[128];
30 char s[256];
31 WORD winx = -1, winy = -1;
32 BOOL forcescreen, forcewindow;
33 BOOL mustremap, truecolor, remapped, wbscreen = TRUE;
35 static void cleanup(char *msg);
37 /***********************************************************************************/
39 #define balls 2
40 #define radius 5
41 #define speed 3
43 static WORD x, i;
45 static struct
47 APTR p;
48 WORD dia;
49 BYTE rand;
50 } ball[balls];
52 #define W 256 // Full width
53 #define hW 128 // Half width
54 #define qW 64 // Quarter width
55 #define eW 32 // 1/8 width
56 #define H 256 // Full height
57 #define hH 128 // Half height
58 #define qH 64 // Quarter height
59 #define eH 32 // 1/8 height
61 static UBYTE chunkybuffer[W * H];
62 static UBYTE chunkybuffer_remapped[W * H];
64 /***********************************************************************************/
66 static void refresh(void)
68 if (truecolor)
70 WriteLUTPixelArray(chunkybuffer,
74 rp,
75 cgfx_coltab,
76 win->BorderLeft,
77 win->BorderTop,
80 CTABFMT_XRGB8);
82 else if (mustremap)
84 LONG i;
85 UBYTE *src = chunkybuffer;
86 UBYTE *dest = chunkybuffer_remapped;
88 for(i = 0; i < W * H; i++)
90 *dest++ = remaptable[*src++];
92 WriteChunkyPixels(rp,
93 win->BorderLeft,
94 win->BorderTop,
95 win->BorderLeft + W - 1,
96 win->BorderTop + H - 1,
97 chunkybuffer_remapped,
98 W);
101 else
103 WriteChunkyPixels(rp,
104 win->BorderLeft,
105 win->BorderTop,
106 win->BorderLeft + W - 1,
107 win->BorderTop + H - 1,
108 chunkybuffer,
113 /***********************************************************************************/
115 #define SQR(x) ((x) * (x))
116 #define pi 3.14159265
117 #define deg 0.017453
119 static void Calc_Ball(WORD hohe, WORD breite, APTR po)
121 WORD x, y, col;
122 float e;
124 for(y = 0; y < hohe; y++)
126 for(x = 0; x < breite; x++)
128 e = sqrt(SQR(x-(breite+1)/2) + 1.5*SQR(y-(breite+1)/2));
130 col = 128 + 128*cos(radius*e*(1+(1.2*W-e)/(W))*deg);
132 if (col > 255) col=255;
133 ((UBYTE *)po)[breite * y + x] = col;
140 /***********************************************************************************/
142 static void Do_Ball(UWORD x, UWORD y, WORD h, WORD b, APTR po)
144 UWORD loopy, loopx;
145 ULONG destoffset = 0; // (y * W) + x;
146 ULONG srcoffset = 0;
147 UWORD col,col2;
148 UWORD dx = 0, dy = 0;
149 UWORD bW = b;
150 UWORD bH = h;
151 UWORD sx = x+W, sy = y+H;
153 if(sx>bW) sx=bW;
154 if(sy>bH) sy=bH;
156 #define src ((UBYTE *)po)
158 for(loopy = y; loopy < sy; loopy ++)
160 dx=0;
161 for(loopx = x; loopx < sx; loopx ++)
163 destoffset = (W*dy ) + dx;
164 srcoffset = (bW*loopy) + loopx;
166 col = src[srcoffset];
167 col2 = chunkybuffer[destoffset];
169 //if(col2>col) col = col2; // eggplant
171 //col += col2; // metaball
173 col = (col+col2)>>1; // Glassy
175 //col+=ctr; // colorcycle (add ctr++ below);
177 //col = col & 0xff; // Xor-effect
178 //if (col > 255) col = 255; // metaball max color
179 chunkybuffer[destoffset] = col;
180 dx++;
182 dy++;
185 // ctr++;
189 /***********************************************************************************/
191 static void initpalette(void)
193 WORD palindex = 0;
195 for(palindex = 0; palindex < 128; palindex++)
197 ULONG re = palindex;
198 ULONG gr = palindex;
199 ULONG bl = palindex*2;
200 cgfx_coltab[palindex] = (re << 16) + (gr << 8) + bl;
202 re = 128-palindex;
203 gr = 128-palindex;
204 bl = 255-palindex*2;
205 cgfx_coltab[palindex+128] = (re << 16) + (gr << 8) + bl;
208 if (!truecolor)
210 WORD i;
212 for(i = 0; i < 256; i++)
214 ULONG r = (cgfx_coltab[i] >> 16) & 0xFF;
215 ULONG g = (cgfx_coltab[i] >> 8) & 0xFF;
216 ULONG b = cgfx_coltab[i] & 0xFF;
218 if (mustremap)
220 ULONG red = r * 0x01010101;
221 ULONG green = g * 0x01010101;
222 ULONG blue = b * 0x01010101;
224 remaptable[i] = ObtainBestPen(scr->ViewPort.ColorMap,
225 red,
226 green,
227 blue,
228 OBP_Precision, PRECISION_IMAGE,
229 OBP_FailIfBad, FALSE,
230 TAG_DONE);
231 remapped = TRUE;
233 else
236 ULONG red = r * 0x01010101;
237 ULONG green = g * 0x01010101;
238 ULONG blue = b * 0x01010101;
240 SetRGB32(&scr->ViewPort, i, red, green, blue);
246 /***********************************************************************************/
248 static void initstuff(void)
250 for(i = 1; i <= balls; i++)
252 ball[i - 1].dia = 2*W;
253 ball[i - 1].rand = (BYTE)(20.0+20.0*sin(i*pi/balls*13));
254 ball[i - 1].p = malloc(SQR(ball[i - 1].dia));
255 if (ball[i].p) cleanup("out of memory!");
256 Calc_Ball(ball[i-1].dia, ball[i-1].dia, ball[i-1].p);
260 /***********************************************************************************/
262 static void ticker(void)
264 // Movement parameters
265 // The chain consists of four sin/cos waves per axis
266 // *dis* represents distance between blobs in the chain
267 // *add* represents the movement speed of the chain/waves
269 // Implemented by using local floats to make it easier
270 // to later implement CLI parameter values.
272 float xdis1 = 394 /balls;
273 float xdis2 = -363 /balls;
274 float xdis3 = 336 /balls;
275 float xdis4 = -344 /balls;
277 float ydis1 = 354 /balls;
278 float ydis2 = -324 /balls;
279 float ydis3 = 373 /balls;
280 float ydis4 = 382 /balls;
282 float xadd1 = 2.10 *speed;
283 float xadd2 = -1.25 *speed;
284 float xadd3 = -0.55 *speed;
285 float xadd4 = 0.93 *speed;
287 float yadd1 = 1.55 *speed;
288 float yadd2 = 0.63 *speed;
289 float yadd3 = -0.23 *speed;
290 float yadd4 = -0.94 *speed;
292 float xpos1, ypos1;
293 float xpos2, ypos2;
294 float xpos3, ypos3;
295 float xpos4, ypos4;
297 float xnew = 0, ynew = 0;
299 memset(chunkybuffer, 0, sizeof(chunkybuffer));
301 // Precalculating position of each wave
302 xpos1 = x * xadd1;
303 xpos2 = x * xadd2;
304 xpos3 = x * xadd3;
305 xpos4 = x * xadd4;
307 ypos1 = x * yadd1;
308 ypos2 = x * yadd2;
309 ypos3 = x * yadd3;
310 ypos4 = x * yadd4;
312 for(i = 0; i < balls; i++)
315 xnew = hW + // - ball[i].dia/2 +
316 eW * sin ((xdis1 * i + xpos1) * deg)+
317 eW * sin ((xdis2 * i + xpos2) * deg)+
318 eW * sin ((xdis3 * i + xpos3) * deg)+
319 eW * sin ((xdis4 * i + xpos4) * deg);
321 ynew = hW + // - ball[i].dia/2 +
322 eH * cos ((ydis1 * i + ypos1) * deg)+
323 eH * cos ((ydis2 * i + ypos2) * deg)+
324 eH * cos ((ydis3 * i + ypos3) * deg)+
325 eH * cos ((ydis4 * i + ypos4) * deg);
327 Do_Ball((WORD)xnew,(WORD)ynew,
328 ball[i].dia, ball[i].dia, ball[i].p);
331 x++;
334 /***********************************************************************************/
336 static void cleanup(char *msg)
339 if (msg)
341 printf("rubberstrings: %s\n",msg);
344 if (win) CloseWindow(win);
346 if (remapped)
348 WORD i;
350 for(i = 0; i < 256; i++)
352 ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
356 if (scr)
358 if (wbscreen)
359 UnlockPubScreen(0, scr);
360 else
361 CloseScreen(scr);
364 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
365 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
366 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
368 exit(0);
371 /***********************************************************************************/
373 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
374 #define ARG_X 0
375 #define ARG_Y 1
376 #define ARG_SCR 2
377 #define ARG_WIN 3
378 #define NUM_ARGS 4
380 static IPTR args[NUM_ARGS];
382 static void getarguments(void)
384 struct RDArgs *myargs;
386 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
388 if (args[ARG_SCR])
389 forcescreen = TRUE;
390 else if (args[ARG_WIN])
391 forcewindow = TRUE;
393 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
394 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
396 FreeArgs(myargs);
400 /***********************************************************************************/
402 static void openlibs(void)
404 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
406 cleanup("Can't open intuition.library V39!");
409 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
411 cleanup("Can't open graphics.library V39!");
414 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
416 cleanup("Can't open cybergraphics.library!");
421 /***********************************************************************************/
423 static void getvisual(void)
425 if (forcescreen)
426 wbscreen = FALSE;
428 if (!wbscreen)
430 scr = OpenScreenTags(NULL, SA_Width , W ,
431 SA_Height , H ,
432 SA_Depth , 8 ,
433 TAG_DONE);
434 if (!scr) cleanup("Failed to open specified screen!");
436 else if (!(scr = LockPubScreen(NULL)))
438 cleanup("Failed to lock pub screen (workbench)!");
441 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
443 if ((!truecolor) && (wbscreen))
444 mustremap = TRUE;
447 /***********************************************************************************/
449 static void makewin(void)
451 struct TagItem winonwbtags[] =
453 {WA_DragBar , TRUE },
454 {WA_DepthGadget , TRUE },
455 {WA_CloseGadget , TRUE },
456 {WA_Title , (IPTR)"Rubberstrings 1.0 - by Orgin" },
457 {TAG_DONE }
460 struct TagItem winonscrtags[] =
462 {WA_Borderless, TRUE },
463 {TAG_DONE }
466 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
467 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
469 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
470 WA_Left , winx,
471 WA_Top , winy,
472 WA_InnerWidth , W,
473 WA_InnerHeight , H,
474 WA_AutoAdjust , TRUE,
475 WA_Activate , TRUE,
476 WA_IDCMP , IDCMP_CLOSEWINDOW |
477 IDCMP_RAWKEY,
478 TAG_MORE , wbscreen ? winonwbtags : winonscrtags);
480 if (!win) cleanup("Can't open window");
482 rp = win->RPort;
485 /***********************************************************************************/
487 #define KC_LEFT 0x4F
488 #define KC_RIGHT 0x4E
489 #define KC_UP 0x4C
490 #define KC_DOWN 0x4D
491 #define KC_ESC 0x45
493 /***********************************************************************************/
495 static void getevents(void)
497 struct IntuiMessage *msg;
499 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
501 switch(msg->Class)
503 case IDCMP_CLOSEWINDOW:
504 Keys[KC_ESC] = 1;
505 break;
507 case IDCMP_RAWKEY:
509 WORD code = msg->Code & ~IECODE_UP_PREFIX;
511 Keys[code] = (code == msg->Code) ? 1 : 0;
514 break;
517 ReplyMsg((struct Message *)msg);
522 /***********************************************************************************/
524 static void action(void)
526 initpalette();
527 initstuff();
529 while (!Keys[KC_ESC])
531 getevents();
533 ticker();
534 refresh();
535 WaitTOF();
540 /***********************************************************************************/
542 int main(void)
544 getarguments();
545 openlibs();
546 getvisual();
547 makewin();
548 action();
549 cleanup(0);
551 return 0;
554 /***********************************************************************************/