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>
18 #include "schedul_fx.h"
20 /***********************************************************************************/
22 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,NOBLUR/S,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
31 struct IntuitionBase
*IntuitionBase
;
32 struct GfxBase
*GfxBase
;
33 struct Library
*CyberGfxBase
;
37 struct RDArgs
*myargs
;
38 ULONG cgfx_coltab
[256];
39 UBYTE remaptable
[256];
42 WORD winx
= -1, winy
= -1;
44 BOOL forcescreen
, forcewindow
;
45 BOOL mustremap
, truecolor
, remapped
, wbscreen
= TRUE
;
47 static void cleanup(char *msg
);
49 /***********************************************************************************/
52 #define M_PI 3.14159265358979323846 /* pi */
55 #define W 320 /* if you change it: dont forget to also change the W
60 char *b8
; /* working 8bits buffer */
68 typedef float matrix
[3][3];
75 typedef unsigned short word
;
77 void memshset (char *dst
, int center_shade
,int fixed_shade
, int length_2
);
82 static inline float ocos(float a
){
83 return (precos
[(int)(a
*256/M_PI
)&511]);
86 static inline float osin(float a
){
87 return (presin
[(int)(a
*256/M_PI
)&511]);
98 void mulmat(matrix
*a
, matrix
*b
, matrix
*c
){
103 (*c
)[i
][j
] = (*a
)[i
][0] * (*b
)[0][j
]
104 +(*a
)[i
][1] * (*b
)[1][j
]
105 +(*a
)[i
][2] * (*b
)[2][j
];
108 static inline void mulvec(matrix
*a
, float *x
, float *y
, float *z
){
109 float nx
=*x
,ny
=*y
,nz
=*z
;
111 *x
= nx
*(*a
)[0][0] + ny
*(*a
)[0][1] + nz
*(*a
)[0][2];
112 *y
= nx
*(*a
)[1][0] + ny
*(*a
)[1][1] + nz
*(*a
)[1][2];
113 *z
= nx
*(*a
)[2][0] + ny
*(*a
)[2][1] + nz
*(*a
)[2][2];
118 void setrmat(float a
, float b
, float c
, matrix
*m
){
120 for (i
=0; i
<3; i
++) for (j
=0; j
<3; j
++) (*m
)[i
][j
]=(float)(i
==j
);
123 (*m
)[0][0] = cos(a
); (*m
)[0][1] = sin(a
);
124 (*m
)[1][0] = sin(a
); (*m
)[1][1] = -cos(a
);
128 (*m
)[0][0] = cos(b
); (*m
)[0][2] = sin(b
);
129 (*m
)[2][0] = sin(b
); (*m
)[2][2] = -cos(b
);
133 (*m
)[1][1] = cos(c
); (*m
)[1][2] = sin(c
);
134 (*m
)[2][1] = sin(c
); (*m
)[2][2] = -cos(c
);
138 void rotate3d(float *xr
, float *yr
, float *zr
, /* point to rotate */
139 float ax
, float ay
, float az
) /* the 3 angles (order ?..) */
144 xr2
= (*xr
*ocos(az
) + *yr
*osin(az
));
145 yr2
= (*xr
*osin(az
) - *yr
*ocos(az
));
149 xr2
= (*xr
*ocos(ay
) + *zr
*osin(ay
));
150 zr2
= (*xr
*osin(ay
) - *zr
*ocos(ay
));
154 zr2
= (*zr
*ocos(ax
) + *yr
*osin(ax
));
155 yr2
= (*zr
*osin(ax
) - *yr
*ocos(ax
));
164 WriteLUTPixelArray(b8
,
180 UBYTE
*dest
= b8_remapped
;
182 for(i
= 0; i
< W
* H
; i
++)
184 *dest
++ = remaptable
[*src
++];
186 WriteChunkyPixels(rp
,
189 win
->BorderLeft
+ W
- 1,
190 win
->BorderTop
+ H
- 1,
197 WriteChunkyPixels(rp
,
200 win
->BorderLeft
+ W
- 1,
201 win
->BorderTop
+ H
- 1,
211 b8
= (unsigned char *)malloc(W
*(H
+1)); /* +1 : I dont trust my range checkings... */
212 if (!b8
) cleanup("Out of memory!");
216 b8_remapped
= (unsigned char *)malloc(W
*H
);
217 if (!b8_remapped
) cleanup("Out of memory!");
220 for (i
=0; i
<256; i
++){
228 cgfx_coltab
[i
]=((r
<<16)|(g
<<8)|(b
));
232 ULONG red
= r
* 0x01010101;
233 ULONG green
= g
* 0x01010101;
234 ULONG blue
= b
* 0x01010101;
236 remaptable
[i
] = ObtainBestPen(scr
->ViewPort
.ColorMap
,
240 OBP_Precision
, PRECISION_IMAGE
,
241 OBP_FailIfBad
, FALSE
,
248 ULONG red
= r
* 0x01010101;
249 ULONG green
= g
* 0x01010101;
250 ULONG blue
= b
* 0x01010101;
252 SetRGB32(&scr
->ViewPort
, i
, red
, green
, blue
);
257 for (i
=0; i
<512; i
++){
258 precos
[i
]=cos(i
*M_PI
/256);
259 presin
[i
]=sin(i
*M_PI
/256);
265 for (i=0; i<GMAX; i++){
266 gal[i].x = 1*((rand()&1023) - 512);
267 gal[i].y = 1*((rand()&1023) - 512);
268 gal[i].z = 1*((rand()&1023) - 512);
269 gal[i].r = rand()&63;
273 for (i
=0; i
<GMAX
; i
++){
275 r
= rand()*1.0 / RAND_MAX
;
276 r
= (1-r
)*(1-r
)+0.05;
278 th
= rand()*M_PI
*2/RAND_MAX
;
280 th
= (rand()&3)*M_PI
/ 2+ r
*r
*2;
281 dth
= rand()*1.0/RAND_MAX
;
287 gal
[i
].x
= 512*r
*cos(th
);
288 gal
[i
].z
= 512*r
*sin(th
);
289 h
= (1+cos(r
*M_PI
))*150;
290 dth
= rand()*1.0/RAND_MAX
;
291 gal
[i
].y
=h
*(dth
-0.5);
292 gal
[i
].r
= (2-r
)*60+31;
294 gal
[0].x
= gal
[0].y
= gal
[0].z
= 0;
300 void starsh(char *, char);
302 void drawshdisk(int x0
, int y0
, int r
){
307 int c
; /* color at center */
314 /* range checking is already (more or less) done... */
315 starsh(&b8
[x0
+ W
*y0
],10+r
*5);
319 if (r
< SLIMIT
+SRANGE
)
320 r
= ((r
-SLIMIT
)*SLIMIT
)/SRANGE
+1;
322 y
=ly
=r
; /* AAaargh */
327 if (y
!=ly
){ /* dont overlap these lines */
332 if (y
==x
+1) /* this would overlap with the next x lines */
333 goto TOTO
; /* WHY NOT */
335 /* note : for "normal" numbers (not too big) :
336 (unsigned int)(x) < M <=> 0<=x<H
337 (because if x<0, then (unsigned)(x) = 2**32-|x| which is
340 This is clearly a stupid, unmaintanable, unreadable "optimization".
343 if ((unsigned int)(y0
-y
-1)<H
-3)
344 memshset(&b8
[x0
+ W
*(y0
-y
+1)] ,c
,d
, x
);
345 if ((unsigned int)(y0
+y
-1)<H
-3)
346 memshset(&b8
[x0
+ W
*(y0
+y
)] ,c
,d
, x
);
352 if ((unsigned int)(y0
-x
-1)<H
-3)
353 memshset(&b8
[x0
+ W
*(y0
-x
)] ,c
,d
, y
);
354 if ((unsigned int)(y0
+x
-1)<H
-3)
355 memshset(&b8
[x0
+ W
*(y0
+x
+1)] ,c
,d
, y
);
371 void mblur (char *src
, int nbpixels
);
385 /* t is the parametric coordinate for the animation;
386 change the scale value to change the speed of anim
387 (independant of processor speed)
389 t
=opti_scale_time(0.418, &demo_elapsed_time
);
409 mblur does something like that:
410 (or did, perhaps it's another version!..)
412 for (i=0; i<W*H; i++)
413 b8[i]= (b8[i]>>3) + (b8[i]>>1) ;
421 for (i
=0; i
<GMAX
; i
++){
427 mulvec(&mr
, &rx
, &ry
, &rz
);
435 x
= (int)(15*rx
/(rz
/5+1))+W
/2; /* tain jcomprend plus rien */
436 y
= (int)(15*ry
/(rz
/5+1))+H
/2; /* a ces formules de daube !! */
437 r
= (int)(3*gal
[i
].r
/ (rz
/4+3))+2;
440 if ((unsigned int)x
<W
-1
451 /***********************************************************************************/
453 static void cleanup(char *msg
)
458 printf("Galaxy: %s\n",msg
);
461 if (win
) CloseWindow(win
);
467 for(i
= 0; i
< 256; i
++)
469 ReleasePen(scr
->ViewPort
.ColorMap
, remaptable
[i
]);
476 UnlockPubScreen(0, scr
);
481 if (myargs
) FreeArgs(myargs
);
483 if (CyberGfxBase
) CloseLibrary(CyberGfxBase
);
484 if (GfxBase
) CloseLibrary((struct Library
*)GfxBase
);
485 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
490 /***********************************************************************************/
492 static void openlibs(void)
494 if (!(IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library", 39)))
496 cleanup("Can't open intuition.library V39!");
499 if (!(GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library", 39)))
501 cleanup("Can't open graphics.library V39!");
504 if (!(CyberGfxBase
= OpenLibrary("cybergraphics.library",0)))
506 cleanup("Can't open cybergraphics.library!");
510 /***********************************************************************************/
512 static void getargs(void)
514 if (!(myargs
= ReadArgs(ARG_TEMPLATE
, args
, 0)))
516 Fault(IoErr(), 0, s
, 255);
520 if (args
[ARG_NOBLUR
])
529 else if (args
[ARG_WIN
])
532 if (args
[ARG_X
]) winx
= *(IPTR
*)args
[ARG_X
];
533 if (args
[ARG_Y
]) winy
= *(IPTR
*)args
[ARG_Y
];
537 /***********************************************************************************/
539 static void getvisual(void)
541 if (!(scr
= LockPubScreen(NULL
)))
543 cleanup("Can't lock pub screen!");
546 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) <= 8)
558 if (forcescreen
) wbscreen
= FALSE
;
562 UnlockPubScreen(NULL
, scr
);
565 scr
= OpenScreenTags(NULL
, SA_Width
, W
,
569 if (!scr
) cleanup("Can't open screen!");
572 truecolor
= (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) >= 15) ? TRUE
: FALSE
;
575 /***********************************************************************************/
577 static void makewin(void)
579 struct TagItem winonwbtags
[] =
581 {WA_DragBar
, TRUE
},
582 {WA_DepthGadget
, TRUE
},
583 {WA_CloseGadget
, TRUE
},
584 {WA_Title
, (IPTR
)"Galaxy" },
588 struct TagItem winonscrtags
[] =
590 {WA_Borderless
, TRUE
},
594 if (winx
== -1) winx
= (scr
->Width
- W
- scr
->WBorLeft
- scr
->WBorRight
) / 2;
595 if (winy
== -1) winy
= (scr
->Height
- H
- scr
->WBorTop
- scr
->WBorTop
- scr
->Font
->ta_YSize
- 1) / 2;
597 win
= OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
)scr
,
602 WA_AutoAdjust
, TRUE
,
604 WA_IDCMP
, IDCMP_CLOSEWINDOW
|
606 TAG_MORE
, wbscreen
? winonwbtags
: winonscrtags
);
609 if (!win
) cleanup("Can't open window");
614 /***********************************************************************************/
617 #define KC_RIGHT 0x4E
622 /***********************************************************************************/
624 static void getevents(void)
626 struct IntuiMessage
*msg
;
628 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
632 case IDCMP_CLOSEWINDOW
:
638 WORD code
= msg
->Code
& ~IECODE_UP_PREFIX
;
640 Keys
[code
] = (code
== msg
->Code
) ? 1 : 0;
646 ReplyMsg((struct Message
*)msg
);
651 /***********************************************************************************/
653 static void action(void)
659 while (!Keys
[KC_ESC
])
667 opti_sched_nextframe();
676 /***********************************************************************************/
690 /***********************************************************************************/