adjust to match the expanded name.
[AROS-Contrib.git] / Demo / InfPlane / infplane.c
blob61a2b910f3f68013f18b1d6265901e38e2187de7
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 C_FUNCTION
41 /* comment/undefine this define to use the asm routine */
43 #define W 320
44 #define H 240
46 #ifndef M_PI
47 #define M_PI 3.14159265358979323846 /* pi */
48 #endif
51 #define RADIUS 64
52 #define DIST 256
54 void do_precalc(float Hp2, /* altitude du 2eme plan (1er = 0) (positif...) */
55 float Xd, float Yd, float Zd,
56 float cx, float cy, float cz, /* vecteur de visee central */
57 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
58 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
60 void refresh1 ();
61 extern void refresh_prout(); /* eh eh */
63 float alpha [H/8+1][W/8+1] ;
64 float zede [H/8+1][W/8+1] ;
66 unsigned char *texture1, *buffer, *buffer_remapped;
68 int ikse [H/8+1][W/8+1] ;
69 int igrek [H/8+1][W/8+1] ;
71 /***********************************************************************************/
73 void rotate3d(float *xr, float *yr, float *zr, /* le point a faire tourner */
74 float ax, float ay, float az) /* les 3 angles (ordre ?..) */
76 float xr2,yr2,zr2;
79 xr2= (*xr*cos(az) + *yr*sin(az));
80 yr2= (*xr*sin(az) - *yr*cos(az));
81 *xr=xr2;
82 *yr=yr2;
84 xr2= (*xr*cos(ay) + *zr*sin(ay));
85 zr2= (*xr*sin(ay) - *zr*cos(ay));
86 *xr=xr2;
87 *zr=zr2;
89 zr2= (*zr*cos(ax) + *yr*sin(ax));
90 yr2= (*zr*sin(ax) - *yr*cos(ax));
91 *zr=zr2;
92 *yr=yr2;
95 void initinfplane(void)
97 FILE * fichier;
98 char * c;
100 /* Chargement de la texture */
102 c = (char *) malloc ( 256*257 );
103 buffer = (char *)malloc (W*(H+1));
104 if (!c || !buffer)
105 cleanup("Out of memory!");
107 if (mustremap)
109 buffer_remapped = malloc(W*H);
110 if (!buffer_remapped)
111 cleanup("Out of memory!");
114 fichier = fopen ( "pattern.data" , "rb" );
115 if (!fichier)
116 cleanup("Can't open pattern.data file!");
118 if (fread ( c , 1, 256*256 , fichier ) != 256*256)
119 cleanup("Error reading pattern.data file!");
120 fclose ( fichier );
122 /* Open palette */
124 fichier = fopen ( "pattern.pal" , "rb" );
125 if (!fichier)
127 fclose(fichier);
128 cleanup("Can't open pattern.pal file!");
131 if (fread ( cgfx_coltab , 1, 256 * 4 , fichier ) != 256 * 4)
133 fclose(fichier);
134 cleanup("Error reading pattern.pal file!");
137 fclose ( fichier );
139 /* Fix palette endianess */
141 #if !AROS_BIG_ENDIAN
143 int i;
145 for(i = 0; i < 256; i ++)
147 cgfx_coltab[i] = AROS_LONG2BE(cgfx_coltab[i]);
150 #endif
152 if (!truecolor)
154 WORD i;
156 for(i = 0; i < 256; i++)
158 ULONG r = (cgfx_coltab[i] >> 16) & 0xFF;
159 ULONG g = (cgfx_coltab[i] >> 8) & 0xFF;
160 ULONG b = cgfx_coltab[i] & 0xFF;
162 if (mustremap)
164 ULONG red = r * 0x01010101;
165 ULONG green = g * 0x01010101;
166 ULONG blue = b * 0x01010101;
168 remaptable[i] = ObtainBestPen(scr->ViewPort.ColorMap,
169 red,
170 green,
171 blue,
172 OBP_Precision, PRECISION_IMAGE,
173 OBP_FailIfBad, FALSE,
174 TAG_DONE);
175 remapped = TRUE;
177 else
180 ULONG red = r * 0x01010101;
181 ULONG green = g * 0x01010101;
182 ULONG blue = b * 0x01010101;
184 SetRGB32(&scr->ViewPort, i, red, green, blue);
189 texture1 = (unsigned char *) c;
193 void do_precalc(float Hp2,
194 float Xd, float Yd, float Zd,
195 float cx, float cy, float cz, /* vecteur de visee central */
196 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
197 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
200 int i,j;
201 float t;
202 float x,y,z;
205 /* euh hem, tjours le meme probleme qd X ou Y arrivent a 65536... */
208 vx1/=W/8.0;
209 vy1/=W/8.0;
210 vz1/=W/8.0;
212 vx2/=H/8.0;
213 vy2/=H/8.0;
214 vz2/=H/8.0;
217 for (j=0; j<=H/8; j++)
219 x = cx - vx1*W/16 + (j - H/16)*vx2;
220 y = cy - vy1*W/16 + (j - H/16)*vy2;
221 z = cz - vz1*W/16 + (j - H/16)*vz2;
223 for (i=0; i<=W/8; i++)
226 x+=vx1;
227 y+=vy1;
228 z+=vz1;
231 if (z <=0.001) /* look downward ? */
234 t= -Zd/z;
236 ikse [j][i]= (int)256*(Xd+x*t);
237 igrek[j][i]= (int)256*(Yd+y*t);
240 else if (z >=0.001) /* look at the sky => 2nd plane */
242 t= (Hp2-Zd)/z;
244 ikse [j][i]= (int)256*(Xd+x*t);
245 igrek[j][i]= (int)256*(Yd+y*t);
248 else /* look infinite */
250 ikse [j][i]= -1; /* C'est une valeur completement idiote */
251 igrek[j][i]= -1;
260 void refresh1 () {
261 int i,j; /* macro-bloc */
262 int ii,jj; /* dans bloc (interpolation) */
263 int a,ai, z,zi; /* 8-8 (fixed-point = lsb) (/pixel)*/
265 int a0,a0i, z0,z0i;
266 int a1,a1i, z1,z1i;
267 int a2,a3,z2,z3;
269 unsigned char *tmp,*tmp1;
272 for (j=0; j<H/8; j++)
273 for (i=0; i<W/8; i++)
275 a0=ikse[j][i];
276 a1=ikse[j][i+1];
277 a2=ikse[j+1][i];
278 a3=ikse[j+1][i+1];
280 z0=igrek[j][i] ;
281 z1=igrek[j][i+1] ;
282 z2=igrek[j+1][i] ;
283 z3=igrek[j+1][i+1] ;
285 a0i=( a2 - a0) /8;
286 z0i=( z2 - z0) /8;
289 a1i=( a3 - a1) /8;
290 z1i=( z3 - z1) /8;
295 tmp1= (unsigned char *)buffer + i*8 + (j*8)*W-W;
296 for (jj=8; jj; jj--)
298 tmp=tmp1+=W;
300 a=a0;
301 z=z0;
302 ai = (a1-a0) >>3;
303 zi = (z1-z0) >>3;
305 for (ii=8; ii; ii--)
307 * ( tmp++ ) = * ( texture1 +
308 ( ((a>>8)&255) |
309 ((z) & (255<<8))
312 a+=ai;
313 z+=zi;
315 /* unrolling loop... just to see if it improves things
316 (it does a bit) */
319 * ( tmp++ ) = * ( texture1 +
320 ((((a+=ai)>>8)&255)
321 | (((z+=zi)) & (255<<8)) )) ;
322 * ( tmp++ ) = * ( texture1 +
323 ((((a+=ai)>>8)&255)
324 | (((z+=zi)) & (255<<8)) )) ;
325 * ( tmp++ ) = * ( texture1 +
326 ((((a+=ai)>>8)&255)
327 | (((z+=zi)) & (255<<8)) )) ;
328 * ( tmp++ ) = * ( texture1 +
329 ((((a+=ai)>>8)&255)
330 | (((z+=zi)) & (255<<8)) )) ;
331 * ( tmp++ ) = * ( texture1 +
332 ((((a+=ai)>>8)&255)
333 | (((z+=zi)) & (255<<8)) )) ;
334 * ( tmp++ ) = * ( texture1 +
335 ((((a+=ai)>>8)&255)
336 | (((z+=zi)) & (255<<8)) )) ;
337 * ( tmp++ ) = * ( texture1 +
338 ((((a+=ai)>>8)&255)
339 | (((z+=zi)) & (255<<8)) )) ;
340 * ( tmp++ ) = * ( texture1 +
341 ((((a+=ai)>>8)&255)
342 | (((z+=zi)) & (255<<8)) )) ;
345 a0+=a0i;
346 z0+=z0i;
348 a1+=a1i;
349 z1+=z1i;
356 /***********************************************************************************/
358 static void cleanup(char *msg)
361 if (msg)
363 printf("InfPlane: %s\n",msg);
366 if (win) CloseWindow(win);
368 if (remapped)
370 WORD i;
372 for(i = 0; i < 256; i++)
374 ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
378 if (scr)
380 if (wbscreen)
381 UnlockPubScreen(0, scr);
382 else
383 CloseScreen(scr);
386 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
387 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
388 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
390 exit(0);
393 /***********************************************************************************/
395 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
396 #define ARG_X 0
397 #define ARG_Y 1
398 #define ARG_SCR 2
399 #define ARG_WIN 3
400 #define NUM_ARGS 4
402 static IPTR args[NUM_ARGS];
404 static void getarguments(void)
406 struct RDArgs *myargs;
408 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
410 if (args[ARG_SCR])
411 forcescreen = TRUE;
412 else if (args[ARG_WIN])
413 forcewindow = TRUE;
415 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
416 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
418 FreeArgs(myargs);
422 /***********************************************************************************/
424 static void openlibs(void)
426 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
428 cleanup("Can't open intuition.library V39!");
431 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
433 cleanup("Can't open graphics.library V39!");
436 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
438 cleanup("Can't open cybergraphics.library!");
443 /***********************************************************************************/
445 static void getvisual(void)
447 if (!(scr = LockPubScreen(NULL)))
449 cleanup("Can't lock pub screen!");
452 if (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) <= 8)
454 if (!forcewindow)
456 wbscreen = FALSE;
458 else
460 mustremap = TRUE;
464 if (forcescreen) wbscreen = FALSE;
466 if (!wbscreen)
468 UnlockPubScreen(NULL, scr);
469 wbscreen = FALSE;
471 scr = OpenScreenTags(NULL, SA_Width , W ,
472 SA_Height , H ,
473 SA_Depth , 8 ,
474 TAG_DONE);
475 if (!scr) cleanup("Can't open screen!");
478 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
481 /***********************************************************************************/
483 static void makewin(void)
485 struct TagItem winonwbtags[] =
487 {WA_DragBar , TRUE },
488 {WA_DepthGadget , TRUE },
489 {WA_CloseGadget , TRUE },
490 {WA_Title , (IPTR)"InfPlane" },
491 {TAG_DONE }
494 struct TagItem winonscrtags[] =
496 {WA_Borderless, TRUE },
497 {TAG_DONE }
500 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
501 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
503 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
504 WA_Left , winx,
505 WA_Top , winy,
506 WA_InnerWidth , W,
507 WA_InnerHeight , H,
508 WA_AutoAdjust , TRUE,
509 WA_Activate , TRUE,
510 WA_IDCMP , IDCMP_CLOSEWINDOW |
511 IDCMP_RAWKEY,
512 TAG_MORE , wbscreen ? winonwbtags : winonscrtags);
515 if (!win) cleanup("Can't open window");
517 rp = win->RPort;
520 /***********************************************************************************/
522 #define KC_LEFT 0x4F
523 #define KC_RIGHT 0x4E
524 #define KC_UP 0x4C
525 #define KC_DOWN 0x4D
526 #define KC_ESC 0x45
528 /***********************************************************************************/
530 static void getevents(void)
532 struct IntuiMessage *msg;
534 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
536 switch(msg->Class)
538 case IDCMP_CLOSEWINDOW:
539 Keys[KC_ESC] = 1;
540 break;
542 case IDCMP_RAWKEY:
544 WORD code = msg->Code & ~IECODE_UP_PREFIX;
546 Keys[code] = (code == msg->Code) ? 1 : 0;
549 break;
552 ReplyMsg((struct Message *)msg);
557 /***********************************************************************************/
559 static void action(void)
561 float Xd,Yd,Zd;
562 float dzz=0;
563 float aa=0,thet=0;
567 float ax,ay,az;
569 float cx,cy,cz; /* vecteur visee */
570 float exx,exy,exz; /* vecteur ex normal */
571 float eyx,eyy,eyz; /* ey */
573 initinfplane();
575 /* Boucle */
577 Xd=Yd=0;
578 ax=ay=az=0;
580 /* Init FPS */
582 //init_fps ();
584 /* Boucle */
586 while (!Keys[KC_ESC])
588 getevents();
590 aa+=0.006;
591 thet+=0.008203;
594 if (aa>1){ /* this is the "keyframing" code :)) */
595 if (aa<2.45)
596 ax+=0.0261;
597 else
599 ax+=0.0061;
600 ay+=0.0033;
601 az+=0.0018;
605 /* rotate view */
606 cx=0.3; cy=0; cz=0;
607 exx=0; exy=1; exz=0;
608 eyx=0; eyy=0; eyz=1;
610 rotate3d(&cx, &cy, &cz,
611 ax,ay,az);
612 rotate3d(&exx, &exy, &exz,
613 ax,ay,az);
614 rotate3d(&eyx, &eyy, &eyz,
615 ax,ay,az);
619 Zd=10*sin(dzz/70)*0.9+30;
620 Yd=dzz+sin(aa*0.1-thet*0.2)*700;
621 dzz+=1.5;
622 Xd=dzz*2;
625 /*Xd=Yd=0;
626 //Zd=10; */
627 do_precalc(240,
628 Xd,Yd,Zd,
629 cx,cy,cz,
630 exx,exy,exz,
631 eyx,eyy,eyz
635 #ifdef C_FUNCTION
636 refresh1 (); /* la routine en C */
637 #else
638 refresh_prout (); /* ma routine asm */
639 #endif
641 if (truecolor)
643 WriteLUTPixelArray(buffer,
648 cgfx_coltab,
649 win->BorderLeft,
650 win->BorderTop,
653 CTABFMT_XRGB8);
655 else if (mustremap)
657 LONG i;
658 UBYTE *src = buffer;
659 UBYTE *dest = buffer_remapped;
661 for(i = 0; i < W * H; i++)
663 *dest++ = remaptable[*src++];
665 WriteChunkyPixels(rp,
666 win->BorderLeft,
667 win->BorderTop,
668 win->BorderLeft + W - 1,
669 win->BorderTop + H - 1,
670 buffer_remapped,
674 else
676 WriteChunkyPixels(rp,
677 win->BorderLeft,
678 win->BorderTop,
679 win->BorderLeft + W - 1,
680 win->BorderTop + H - 1,
681 buffer,
685 WaitTOF();
687 //update_x ();
688 //next_fps();
692 /* Aff FPS */
694 //aff_fps (NAME);
698 /***********************************************************************************/
700 int main(void)
702 getarguments();
703 openlibs();
704 getvisual();
705 makewin();
706 action();
707 cleanup(0);
709 return 0;
712 /***********************************************************************************/