Merged-in lua 5.2.2.
[AROS-Contrib.git] / Demo / FTunnel / ftunnel.c
blob1dbb2761a981852f79cfc668e997f13fb6def1b4
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>
11 #include <aros/macros.h>
13 #include <math.h>
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <memory.h>
20 /***********************************************************************************/
22 struct IntuitionBase *IntuitionBase;
23 struct GfxBase *GfxBase;
24 struct Library *CyberGfxBase;
25 struct Screen *scr;
26 struct Window *win;
27 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 static void cleanup(char *msg);
38 /***********************************************************************************/
40 #define W 256
41 #define H 256
43 #ifndef M_PI
44 #define M_PI 3.14159265358979323846 /* pi */
45 #endif
48 #define RADIUS 64
49 #define DIST 256
51 void do_precalc(float Xd, float Z, float dalpha,
52 float cx, float cy, float cz, /* vecteur de visee central */
53 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
54 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
56 void refresh ();
58 float alpha [H/8+1][W/8+1] ;
59 float zede [H/8+1][W/8+1] ;
61 unsigned char *texture;
62 unsigned char *buffer, *buffer_remapped;
64 /***********************************************************************************/
66 void initftunnel(void)
68 int x,y;
69 FILE * fichier;
70 char * c;
72 /* Chargement de la texture */
74 c = (char *) malloc ( 128*129 );
75 buffer = (char *)malloc (W*(H+1));
76 if (!c || !buffer)
77 cleanup("Out of memory!");
79 if (mustremap)
81 buffer_remapped = malloc(W * H);
82 if (!buffer_remapped) cleanup("Out of memory!");
85 fichier = fopen ( "pattern.data" , "rb" );
86 if (!fichier)
87 cleanup("Can't open pattern.data file!");
89 if (fread ( buffer , 1, 128*128 , fichier ) != 128 * 128)
90 cleanup("Error reading pattern.data file!");
91 fclose ( fichier );
93 /* Open palette */
95 fichier = fopen ( "pattern.pal" , "rb" );
96 if (!fichier)
98 fclose(fichier);
99 cleanup("Can't open pattern.pal file!");
102 if (fread ( cgfx_coltab , 1, 256 * 4 , fichier ) != 256 * 4)
104 fclose(fichier);
105 cleanup("Error reading pattern.pal file!");
108 fclose ( fichier );
110 /* Fix palette endianess */
112 #if !AROS_BIG_ENDIAN
114 int i;
116 for(i = 0; i < 256; i ++)
118 cgfx_coltab[i] = AROS_LONG2BE(cgfx_coltab[i]);
121 #endif
123 if (!truecolor)
125 WORD palindex;
127 for(palindex = 0; palindex < 256; palindex++)
129 ULONG red = (cgfx_coltab[palindex] >> 16) & 0xFF;
130 ULONG green = (cgfx_coltab[palindex] >> 8) & 0xFF;
131 ULONG blue = cgfx_coltab[palindex] & 0xFF;
133 if (mustremap)
135 red *= 0x01010101;
136 green *= 0x01010101;
137 blue *= 0x01010101;
139 remaptable[palindex] = ObtainBestPen(scr->ViewPort.ColorMap,
140 red,
141 green,
142 blue,
143 OBP_Precision, PRECISION_IMAGE,
144 OBP_FailIfBad, FALSE,
145 TAG_DONE);
146 remapped = TRUE;
149 else
151 red *= 0x01010101;
152 green *= 0x01010101;
153 blue *= 0x01010101;
155 SetRGB32(&scr->ViewPort, palindex, red, green, blue);
160 /* Rotate texture */
162 for(x = 0; x < 127; x++)
164 for(y = 0;y < 127; y++)
166 c[y * 128 + x] = buffer[x * 128 + (127 - y)];
170 texture = (unsigned char *) c;
176 void do_precalc(float Xd, float Z, float dalpha,
177 float cx, float cy, float cz, /* vecteur de visee central */
178 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
179 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
182 int i,j;
183 float t;
184 float prec1,prec2;
185 float prec3;
186 float x,y,z;
189 prec3 = (Xd*Xd -1);
190 vx1/=W/8.0;
191 vy1/=W/8.0;
192 vz1/=W/8.0;
195 for (j=0; j<=H/8; j++)
197 x = cx - vx1*4/W+
198 (j - H/16)*8*vx2/H;
199 y = cy -vy1*4/W+
200 (j - H/16)*8*vy2/H;
201 z = cz - vz1*4/W+
202 (j - H/16)*8*vz2/H;
209 for (i=0; i<=W/8; i++)
212 x+=vx1;
213 y+=vy1;
214 z+=vz1;
217 prec1 = x*Xd;
218 prec2 = (y*y + x*x);
219 if (prec2 >= 0.00001)
222 t= (-prec1 + sqrt( prec1*prec1 - prec3 * prec2))
223 / prec2;
224 /* remplacer sqrt par ident, sin, ... ca fait des
225 trucs marrants */
227 alpha[j][i]= (atan2(t*y , Xd+t*x) + dalpha) *128 / M_PI;
228 /* remplacer atan2 par "+" , "*" ou 1 des 2 termes...
229 trucs marrants... */
231 zede[j][i]= Z+ 8*t*z;
232 /* pkoi 8 ?
233 paceke sinon ca marche pas bien */
235 else /* trop dans l'alignement du tunnel ... ~div by 0 */
237 alpha[j][i]= 0;
238 zede[j][i]= 1000;
248 void refresh () {
249 int i,j; /* macro-bloc */
250 int ii,jj; /* dans bloc (interpolation) */
251 int a,ai, z,zi; /* 16-16 (fixed-point = lsb) (/pixel)*/
253 int a0,a0i, z0,z0i; /* (/ligne) (colone de gauche)*/
254 int a1,a1i, z1,z1i; /* (/ligne) (c de droite )*/
255 int a22;
256 float al0,al1,al2,al3;
258 unsigned char *tmp,*tmp1;
261 for (j=0; j<H/8; j++)
262 for (i=0; i<W/8; i++)
265 al0=alpha[j][i];
266 a0=( (int) 65536*al0);
267 z0=( (int) 65536*zede[j][i]) ;
269 al1=alpha[j+1][i];
270 if (abs(al1-al0) > 100) /* detecter la jonction entre les bords */
271 al1=al0; /* c'est du kludge pas efficace la...
272 il faudrait renormaliser tout ca et garder
273 la valeur modulo 1 par exemple, plutot que d'egaliser
274 (ce qui produit des marches d'escalier) */
276 a22=( (int) (65536*al1));
278 a0i=( a22 - a0) /8;
279 z0i=( ( (int) (65536*zede[j+1][i])) -z0) /8;
281 al2=alpha[j][i+1];
282 if (abs(al2-al0) > 100)
283 al2=al0;
284 a1=( (int) 65536*al2);
285 z1=( (int) 65536*zede[j][i+1]) ;
287 al3=alpha[j+1][i+1];
288 if (abs(al3-al2) > 100)
289 al3=al2;
292 a1i=( ( (int) (65536*al3)) - a1) /8;
293 z1i=( ( (int) (65536*zede[j+1][i+1])) -z1) /8;
298 tmp1= (unsigned char *)buffer + i*8 + (j*8)*W - W;
299 for (jj=8; jj; jj--)
301 tmp=tmp1+=W;
303 a=a0;
304 z=z0;
305 ai = (a1-a0) >>3;
306 zi = (z1-z0) >>3;
308 for (ii=8; ii; ii--)
310 * ( tmp++ ) = * ( texture
313 ((a>>17)&127)
315 ((z>>8) & (127<<7))
318 a+=ai;
319 z+=zi;
323 a0+=a0i;
324 z0+=z0i;
326 a1+=a1i;
327 z1+=z1i;
332 if (truecolor)
334 WriteLUTPixelArray(buffer,
339 cgfx_coltab,
340 win->BorderLeft,
341 win->BorderTop,
344 CTABFMT_XRGB8);
346 else if (mustremap)
348 LONG i;
349 UBYTE *src = buffer;
350 UBYTE *dest = buffer_remapped;
352 for(i = 0; i < W * H; i++)
354 *dest++ = remaptable[*src++];
356 WriteChunkyPixels(rp,
357 win->BorderLeft,
358 win->BorderTop,
359 win->BorderLeft + W - 1,
360 win->BorderTop + H - 1,
361 buffer_remapped,
365 else
367 WriteChunkyPixels(rp,
368 win->BorderLeft,
369 win->BorderTop,
370 win->BorderLeft + W - 1,
371 win->BorderTop + H - 1,
372 buffer,
377 /***********************************************************************************/
379 static void cleanup(char *msg)
382 if (msg)
384 printf("FTunnel: %s\n",msg);
387 if (win) CloseWindow(win);
389 if (remapped)
391 WORD i;
393 for(i = 0; i < 256; i++)
395 ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
399 if (scr)
401 if (wbscreen)
402 UnlockPubScreen(0, scr);
403 else
404 CloseScreen(scr);
407 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
408 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
409 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
411 exit(0);
414 /***********************************************************************************/
416 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
417 #define ARG_X 0
418 #define ARG_Y 1
419 #define ARG_SCR 2
420 #define ARG_WIN 3
421 #define NUM_ARGS 4
423 static IPTR args[NUM_ARGS];
425 static void getarguments(void)
427 struct RDArgs *myargs;
429 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
431 if (args[ARG_SCR])
432 forcescreen = TRUE;
433 else if (args[ARG_WIN])
434 forcewindow = TRUE;
436 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
437 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
439 FreeArgs(myargs);
443 /***********************************************************************************/
445 static void openlibs(void)
447 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
449 cleanup("Can't open intuition.library V39!");
452 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
454 cleanup("Can't open graphics.library V39!");
457 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
459 cleanup("Can't open cybergraphics.library!");
464 /***********************************************************************************/
466 static void getvisual(void)
468 if (!(scr = LockPubScreen(NULL)))
470 cleanup("Can't lock pub screen!");
473 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
475 if (!forcewindow)
477 wbscreen = FALSE;
479 else
481 mustremap = TRUE;
485 if (forcescreen) wbscreen = FALSE;
487 if (!wbscreen)
489 UnlockPubScreen(NULL, scr);
490 wbscreen = FALSE;
492 scr = OpenScreenTags(NULL, SA_Width , W ,
493 SA_Height , H ,
494 SA_Depth , 8 ,
495 TAG_DONE);
496 if (!scr) cleanup("Can't open screen!");
499 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
502 /***********************************************************************************/
504 static void makewin(void)
506 struct TagItem winonwbtags[] =
508 {WA_DragBar , TRUE },
509 {WA_DepthGadget , TRUE },
510 {WA_CloseGadget , TRUE },
511 {WA_Title , (IPTR)"FTunnel" },
512 {TAG_DONE }
515 struct TagItem winonscrtags[] =
517 {WA_Borderless, TRUE },
518 {TAG_DONE }
521 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
522 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
524 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
525 WA_Left , winx,
526 WA_Top , winy,
527 WA_InnerWidth , W,
528 WA_InnerHeight , H,
529 WA_AutoAdjust , TRUE,
530 WA_Activate , TRUE,
531 WA_IDCMP , IDCMP_CLOSEWINDOW |
532 IDCMP_RAWKEY,
533 TAG_MORE, wbscreen ? winonwbtags : winonscrtags);
535 if (!win) cleanup("Can't open window");
537 rp = win->RPort;
540 /***********************************************************************************/
542 #define KC_LEFT 0x4F
543 #define KC_RIGHT 0x4E
544 #define KC_UP 0x4C
545 #define KC_DOWN 0x4D
546 #define KC_ESC 0x45
548 /***********************************************************************************/
550 static void getevents(void)
552 struct IntuiMessage *msg;
554 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
556 switch(msg->Class)
558 case IDCMP_CLOSEWINDOW:
559 Keys[KC_ESC] = 1;
560 break;
562 case IDCMP_RAWKEY:
564 WORD code = msg->Code & ~IECODE_UP_PREFIX;
566 Keys[code] = (code == msg->Code) ? 1 : 0;
569 break;
572 ReplyMsg((struct Message *)msg);
577 /***********************************************************************************/
579 static void action(void)
581 float Xd,Z,dalpha=0;
582 float aa=0,thet=0; /*alpha theta de la visee en spherique */
584 float eaa=0; /* ecran alpha : rotation de l'ecran au bout du vecteur visee */
585 float exx,exy,exz; /* vecteur ex normal */
586 float eyx,eyy,eyz; /* ey */
588 initftunnel();
591 /* Init FPS */
593 //init_fps ();
595 /* Boucle */
597 while (!Keys[KC_ESC])
599 getevents();
601 /*** pfff trigo 3d en coord spherique = caca ***/
602 exx=-sin(aa); exy= cos(aa); exz=0;
603 eyx=-cos(aa)*sin(thet); eyy= -sin(aa)*sin(thet); eyz=cos(thet);
605 exx*=2; exy*=2; exz*=2;
606 eyx*=2; eyy*=2; eyz*=2;
608 Xd=sin(dalpha)*0.9;
609 Z=sin(aa*0.1-thet*0.2+dalpha*0.12001)*700;
611 aa+=0.004;
612 /*aa=0; */
613 thet+=0.006203;
614 /*thet = M_PI/2; */
615 eaa+=0.002;
616 dalpha+=0.01;
619 do_precalc(Xd,Z,dalpha,
620 4*cos(aa)*cos(thet), 4*sin(aa)*cos(thet),4* sin(thet),
622 cos(eaa)*exx + sin(eaa)*eyx,
623 cos(eaa)*exy + sin(eaa)*eyy,
624 cos(eaa)*exz + sin(eaa)*eyz,
626 -sin(eaa)*exx + cos(eaa)*eyx,
627 -sin(eaa)*exy + cos(eaa)*eyy,
628 -sin(eaa)*exz + cos(eaa)*eyz
631 refresh ();
633 WaitTOF();
634 //update_x ();
635 //next_fps ();
638 /* Aff FPS */
640 //aff_fps (NAME);
644 /***********************************************************************************/
646 int main(void)
648 getarguments();
649 openlibs();
650 getvisual();
651 makewin();
652 action();
653 cleanup(0);
655 return 0;
658 /***********************************************************************************/