3 #include <intuition/intuition.h>
4 #include <graphics/gfx.h>
5 #include <cybergraphx/cybergraphics.h>
6 #include <proto/exec.h>
8 #include <proto/graphics.h>
9 #include <proto/cybergraphics.h>
10 #include <proto/intuition.h>
19 /***********************************************************************************/
21 struct IntuitionBase
*IntuitionBase
;
22 struct GfxBase
*GfxBase
;
23 struct Library
*CyberGfxBase
;
27 ULONG cgfx_coltab
[256];
28 UBYTE remaptable
[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 /***********************************************************************************/
50 #define W 320 // Full width
51 #define hW 160 // Half width
52 #define qW 80 // Quarter width
53 #define eW 40 // 1/8 width
54 #define H 200 // Full height
55 #define hH 100 // Half height
56 #define qH 50 // Quarter height
57 #define eH 25 // 1/8 height
59 static UBYTE chunkybuffer
[W
* H
];
60 static UBYTE chunkybuffer_remapped
[W
* H
];
62 /***********************************************************************************/
64 static void refresh(void)
68 WriteLUTPixelArray(chunkybuffer
,
83 UBYTE
*src
= chunkybuffer
;
84 UBYTE
*dest
= chunkybuffer_remapped
;
86 for(i
= 0; i
< W
* H
; i
++)
88 *dest
++ = remaptable
[*src
++];
93 win
->BorderLeft
+ W
- 1,
94 win
->BorderTop
+ H
- 1,
95 chunkybuffer_remapped
,
101 WriteChunkyPixels(rp
,
104 win
->BorderLeft
+ W
- 1,
105 win
->BorderTop
+ H
- 1,
111 /***********************************************************************************/
113 #define SQR(x) ((x) * (x))
114 #define pi 3.14159265
117 static void Calc_Ball(WORD hohe
, WORD breite
, APTR po
)
122 for(y
= 0; y
< hohe
; y
++)
124 for(x
= 0; x
< breite
; x
++)
126 e
= sqrt(SQR(x
-(breite
+1)/2) + 1.5*SQR(y
-(breite
+1)/2));
127 col
= (WORD
)(130.0+130.0*cos(e
*pi
/(hohe
/2)));
128 if (col
> 255) col
=255;
131 ((UBYTE
*)po
)[breite
* y
+ x
] = col
;
135 ((UBYTE
*)po
)[breite
* y
+ x
] = 0;
142 /***********************************************************************************/
144 static void Do_Ball(WORD x
, WORD y
, WORD h
, WORD b
, APTR po
)
147 UWORD destoffset
= (y
* W
) + x
;
149 UBYTE
*src
= (UBYTE
*)po
;
151 for(loopy
= 0; loopy
< h
; loopy
++)
153 for(loopx
= 0; loopx
< b
; loopx
++)
156 col
+= chunkybuffer
[destoffset
];
157 if (col
> 255) col
= 255;
158 chunkybuffer
[destoffset
++] = col
;
160 destoffset
+= (W
- b
);
164 /***********************************************************************************/
166 static void initpalette(void)
170 for(palindex
= 0; palindex
< 64; palindex
++)
174 ULONG blue
= palindex
* 4;
176 cgfx_coltab
[palindex
] = (red
<< 16) + (green
<< 8) + blue
;
179 green
= palindex
* 4;
182 cgfx_coltab
[palindex
+ 64] = (red
<< 16) + (green
<< 8) + blue
;
184 red
= 0xFF - palindex
* 4;
185 green
= 0xFF - palindex
* 4;
186 blue
= 0xFF - palindex
* 4;
188 cgfx_coltab
[palindex
+ 128] = (red
<< 16) + (green
<< 8) + blue
;
191 green
= palindex
* 4;
194 cgfx_coltab
[palindex
+ 192] = (red
<< 16) + (green
<< 8) + blue
;
197 cgfx_coltab
[255] = 0xFFFFFF;
203 for(i
= 0; i
< 256; i
++)
205 ULONG r
= (cgfx_coltab
[i
] >> 16) & 0xFF;
206 ULONG g
= (cgfx_coltab
[i
] >> 8) & 0xFF;
207 ULONG b
= cgfx_coltab
[i
] & 0xFF;
211 ULONG red
= r
* 0x01010101;
212 ULONG green
= g
* 0x01010101;
213 ULONG blue
= b
* 0x01010101;
215 remaptable
[i
] = ObtainBestPen(scr
->ViewPort
.ColorMap
,
219 OBP_Precision
, PRECISION_IMAGE
,
220 OBP_FailIfBad
, FALSE
,
227 ULONG red
= r
* 0x01010101;
228 ULONG green
= g
* 0x01010101;
229 ULONG blue
= b
* 0x01010101;
231 SetRGB32(&scr
->ViewPort
, i
, red
, green
, blue
);
237 /***********************************************************************************/
239 static void initstuff(void)
243 for(i
= 1; i
<= balls
; i
++)
250 ball
[i
- 1].dia
= 30 + abs(5 * (j
-1));
251 ball
[i
- 1].rand
= (BYTE
)(20.0+20.0*sin(i
*pi
/balls
*13));
252 ball
[i
- 1].p
= malloc(SQR(ball
[i
- 1].dia
));
253 if (ball
[i
].p
) cleanup("out of memory!");
254 Calc_Ball(ball
[i
-1].dia
, ball
[i
-1].dia
, ball
[i
-1].p
);
258 /***********************************************************************************/
260 static void ticker(void)
262 // Movement parameters
263 // The chain consists of four sin/cos waves per axis
264 // *dis* represents distance between blobs in the chain
265 // *add* represents the movement speed of the chain/waves
267 // Implemented by using local floats to make it easier
268 // to later implement CLI parameter values.
295 float xnew
= 0, ynew
= 0;
297 memset(chunkybuffer
, 0, sizeof(chunkybuffer
));
299 // Precalculating position of each wave
310 for(i
= 0; i
< balls
; i
++)
313 xnew
= hW
- ball
[i
].dia
/2 +
314 qW
* sin ((xdis1
* i
+ xpos1
) * deg
)+
315 qW
* sin ((xdis2
* i
+ xpos2
) * deg
)+
316 qW
* sin ((xdis3
* i
+ xpos3
) * deg
)+
317 qW
* sin ((xdis4
* i
+ xpos4
) * deg
);
319 ynew
= hW
- ball
[i
].dia
/2 +
320 qH
* cos ((ydis1
* i
+ ypos1
) * deg
)+
321 qH
* cos ((ydis2
* i
+ ypos2
) * deg
)+
322 qH
* cos ((ydis3
* i
+ ypos3
) * deg
)+
323 qH
* cos ((ydis4
* i
+ ypos4
) * deg
);
325 // replace qW/qH with eW/eH if you wish to keep
326 // the blobs from moving entirely over the edges.
328 Do_Ball((WORD
)xnew
,(WORD
)ynew
,
329 ball
[i
].dia
, ball
[i
].dia
, ball
[i
].p
);
335 /***********************************************************************************/
337 static void cleanup(char *msg
)
342 printf("metaballs: %s\n",msg
);
345 if (win
) CloseWindow(win
);
351 for(i
= 0; i
< 256; i
++)
353 ReleasePen(scr
->ViewPort
.ColorMap
, remaptable
[i
]);
360 UnlockPubScreen(0, scr
);
365 if (CyberGfxBase
) CloseLibrary(CyberGfxBase
);
366 if (GfxBase
) CloseLibrary((struct Library
*)GfxBase
);
367 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
372 /***********************************************************************************/
374 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
381 static IPTR args
[NUM_ARGS
];
383 static void getarguments(void)
385 struct RDArgs
*myargs
;
387 if ((myargs
= ReadArgs(ARG_TEMPLATE
, args
, NULL
)))
391 else if (args
[ARG_WIN
])
394 if (args
[ARG_X
]) winx
= *(IPTR
*)args
[ARG_X
];
395 if (args
[ARG_Y
]) winy
= *(IPTR
*)args
[ARG_Y
];
401 /***********************************************************************************/
403 static void openlibs(void)
405 if (!(IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library", 39)))
407 cleanup("Can't open intuition.library V39!");
410 if (!(GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library", 39)))
412 cleanup("Can't open graphics.library V39!");
415 if (!(CyberGfxBase
= OpenLibrary("cybergraphics.library",0)))
417 cleanup("Can't open cybergraphics.library!");
422 /***********************************************************************************/
424 static void getvisual(void)
431 scr
= OpenScreenTags(NULL
, SA_Width
, W
,
435 if (!scr
) cleanup("Failed to open specified screen!");
437 else if (!(scr
= LockPubScreen(NULL
)))
439 cleanup("Failed to lock pub screen (workbench)!");
442 truecolor
= (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15) ? TRUE
: FALSE
;
444 if ((!truecolor
) && (wbscreen
))
448 /***********************************************************************************/
450 static void makewin(void)
452 struct TagItem winonwbtags
[] =
454 {WA_DragBar
, TRUE
},
455 {WA_DepthGadget
, TRUE
},
456 {WA_CloseGadget
, TRUE
},
457 {WA_Title
, (IPTR
)"Metaballs" },
461 struct TagItem winonscrtags
[] =
463 {WA_Borderless
, TRUE
},
467 if (winx
== -1) winx
= (scr
->Width
- W
- scr
->WBorLeft
- scr
->WBorRight
) / 2;
468 if (winy
== -1) winy
= (scr
->Height
- H
- scr
->WBorTop
- scr
->WBorTop
- scr
->Font
->ta_YSize
- 1) / 2;
470 win
= OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
)scr
,
475 WA_AutoAdjust
, TRUE
,
477 WA_IDCMP
, IDCMP_CLOSEWINDOW
|
479 TAG_MORE
, wbscreen
? winonwbtags
: winonscrtags
);
481 if (!win
) cleanup("Can't open window");
486 /***********************************************************************************/
489 #define KC_RIGHT 0x4E
494 /***********************************************************************************/
496 static void getevents(void)
498 struct IntuiMessage
*msg
;
500 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
504 case IDCMP_CLOSEWINDOW
:
510 WORD code
= msg
->Code
& ~IECODE_UP_PREFIX
;
512 Keys
[code
] = (code
== msg
->Code
) ? 1 : 0;
518 ReplyMsg((struct Message
*)msg
);
523 /***********************************************************************************/
525 static void action(void)
530 while (!Keys
[KC_ESC
])
541 /***********************************************************************************/
555 /***********************************************************************************/