build infplane for all targets .. only use the asm where supported.
[AROS-Contrib.git] / Demo / InfPlane / infplane.c
blob6660dafe869669d4ce5f18148ed933f648301fbe
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>
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 W 320
40 #define H 240
42 #ifndef M_PI
43 #define M_PI 3.14159265358979323846 /* pi */
44 #endif
46 #define RADIUS 64
47 #define DIST 256
49 void do_precalc(float Hp2, /* altitude du 2eme plan (1er = 0) (positif...) */
50 float Xd, float Yd, float Zd,
51 float cx, float cy, float cz, /* vecteur de visee central */
52 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
53 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
55 #ifdef C_FUNCTION
56 void refresh1 ();
57 #else
58 extern void refresh_prout(); /* eh eh */
59 #endif
61 float alpha [H/8+1][W/8+1] ;
62 float zede [H/8+1][W/8+1] ;
64 unsigned char *texture1, *buffer, *buffer_remapped;
66 int ikse [H/8+1][W/8+1] ;
67 int igrek [H/8+1][W/8+1] ;
69 /***********************************************************************************/
71 void rotate3d(float *xr, float *yr, float *zr, /* le point a faire tourner */
72 float ax, float ay, float az) /* les 3 angles (ordre ?..) */
74 float xr2,yr2,zr2;
77 xr2= (*xr*cos(az) + *yr*sin(az));
78 yr2= (*xr*sin(az) - *yr*cos(az));
79 *xr=xr2;
80 *yr=yr2;
82 xr2= (*xr*cos(ay) + *zr*sin(ay));
83 zr2= (*xr*sin(ay) - *zr*cos(ay));
84 *xr=xr2;
85 *zr=zr2;
87 zr2= (*zr*cos(ax) + *yr*sin(ax));
88 yr2= (*zr*sin(ax) - *yr*cos(ax));
89 *zr=zr2;
90 *yr=yr2;
93 void initinfplane(void)
95 FILE * fichier;
96 char * c;
98 /* Chargement de la texture */
100 c = (char *) malloc ( 256*257 );
101 buffer = (char *)malloc (W*(H+1));
102 if (!c || !buffer)
103 cleanup("Out of memory!");
105 if (mustremap)
107 buffer_remapped = malloc(W*H);
108 if (!buffer_remapped)
109 cleanup("Out of memory!");
112 fichier = fopen ( "pattern.data" , "rb" );
113 if (!fichier)
114 cleanup("Can't open pattern.data file!");
116 if (fread ( c , 1, 256*256 , fichier ) != 256*256)
117 cleanup("Error reading pattern.data file!");
118 fclose ( fichier );
120 /* Open palette */
122 fichier = fopen ( "pattern.pal" , "rb" );
123 if (!fichier)
125 fclose(fichier);
126 cleanup("Can't open pattern.pal file!");
129 if (fread ( cgfx_coltab , 1, 256 * 4 , fichier ) != 256 * 4)
131 fclose(fichier);
132 cleanup("Error reading pattern.pal file!");
135 fclose ( fichier );
137 /* Fix palette endianess */
139 #if !AROS_BIG_ENDIAN
141 int i;
143 for(i = 0; i < 256; i ++)
145 cgfx_coltab[i] = AROS_LONG2BE(cgfx_coltab[i]);
148 #endif
150 if (!truecolor)
152 WORD i;
154 for(i = 0; i < 256; i++)
156 ULONG r = (cgfx_coltab[i] >> 16) & 0xFF;
157 ULONG g = (cgfx_coltab[i] >> 8) & 0xFF;
158 ULONG b = cgfx_coltab[i] & 0xFF;
160 if (mustremap)
162 ULONG red = r * 0x01010101;
163 ULONG green = g * 0x01010101;
164 ULONG blue = b * 0x01010101;
166 remaptable[i] = ObtainBestPen(scr->ViewPort.ColorMap,
167 red,
168 green,
169 blue,
170 OBP_Precision, PRECISION_IMAGE,
171 OBP_FailIfBad, FALSE,
172 TAG_DONE);
173 remapped = TRUE;
175 else
178 ULONG red = r * 0x01010101;
179 ULONG green = g * 0x01010101;
180 ULONG blue = b * 0x01010101;
182 SetRGB32(&scr->ViewPort, i, red, green, blue);
187 texture1 = (unsigned char *) c;
191 void do_precalc(float Hp2,
192 float Xd, float Yd, float Zd,
193 float cx, float cy, float cz, /* vecteur de visee central */
194 float vx1, float vy1, float vz1, /* vecteur selon X ecran */
195 float vx2, float vy2, float vz2 /* vecteur selon Y ecran */
198 int i,j;
199 float t;
200 float x,y,z;
203 /* euh hem, tjours le meme probleme qd X ou Y arrivent a 65536... */
206 vx1/=W/8.0;
207 vy1/=W/8.0;
208 vz1/=W/8.0;
210 vx2/=H/8.0;
211 vy2/=H/8.0;
212 vz2/=H/8.0;
215 for (j=0; j<=H/8; j++)
217 x = cx - vx1*W/16 + (j - H/16)*vx2;
218 y = cy - vy1*W/16 + (j - H/16)*vy2;
219 z = cz - vz1*W/16 + (j - H/16)*vz2;
221 for (i=0; i<=W/8; i++)
224 x+=vx1;
225 y+=vy1;
226 z+=vz1;
229 if (z <=0.001) /* look downward ? */
232 t= -Zd/z;
234 ikse [j][i]= (int)256*(Xd+x*t);
235 igrek[j][i]= (int)256*(Yd+y*t);
238 else if (z >=0.001) /* look at the sky => 2nd plane */
240 t= (Hp2-Zd)/z;
242 ikse [j][i]= (int)256*(Xd+x*t);
243 igrek[j][i]= (int)256*(Yd+y*t);
246 else /* look infinite */
248 ikse [j][i]= -1; /* C'est une valeur completement idiote */
249 igrek[j][i]= -1;
257 #ifdef C_FUNCTION
258 void refresh1 () {
259 int i,j; /* macro-bloc */
260 int ii,jj; /* dans bloc (interpolation) */
261 int a,ai, z,zi; /* 8-8 (fixed-point = lsb) (/pixel)*/
263 int a0,a0i, z0,z0i;
264 int a1,a1i, z1,z1i;
265 int a2,a3,z2,z3;
267 unsigned char *tmp,*tmp1;
270 for (j=0; j<H/8; j++)
271 for (i=0; i<W/8; i++)
273 a0=ikse[j][i];
274 a1=ikse[j][i+1];
275 a2=ikse[j+1][i];
276 a3=ikse[j+1][i+1];
278 z0=igrek[j][i] ;
279 z1=igrek[j][i+1] ;
280 z2=igrek[j+1][i] ;
281 z3=igrek[j+1][i+1] ;
283 a0i=( a2 - a0) /8;
284 z0i=( z2 - z0) /8;
287 a1i=( a3 - a1) /8;
288 z1i=( z3 - z1) /8;
293 tmp1= (unsigned char *)buffer + i*8 + (j*8)*W-W;
294 for (jj=8; jj; jj--)
296 tmp=tmp1+=W;
298 a=a0;
299 z=z0;
300 ai = (a1-a0) >>3;
301 zi = (z1-z0) >>3;
303 for (ii=8; ii; ii--)
305 * ( tmp++ ) = * ( texture1 +
306 ( ((a>>8)&255) |
307 ((z) & (255<<8))
310 a+=ai;
311 z+=zi;
313 /* unrolling loop... just to see if it improves things
314 (it does a bit) */
317 * ( tmp++ ) = * ( texture1 +
318 ((((a+=ai)>>8)&255)
319 | (((z+=zi)) & (255<<8)) )) ;
320 * ( tmp++ ) = * ( texture1 +
321 ((((a+=ai)>>8)&255)
322 | (((z+=zi)) & (255<<8)) )) ;
323 * ( tmp++ ) = * ( texture1 +
324 ((((a+=ai)>>8)&255)
325 | (((z+=zi)) & (255<<8)) )) ;
326 * ( tmp++ ) = * ( texture1 +
327 ((((a+=ai)>>8)&255)
328 | (((z+=zi)) & (255<<8)) )) ;
329 * ( tmp++ ) = * ( texture1 +
330 ((((a+=ai)>>8)&255)
331 | (((z+=zi)) & (255<<8)) )) ;
332 * ( tmp++ ) = * ( texture1 +
333 ((((a+=ai)>>8)&255)
334 | (((z+=zi)) & (255<<8)) )) ;
335 * ( tmp++ ) = * ( texture1 +
336 ((((a+=ai)>>8)&255)
337 | (((z+=zi)) & (255<<8)) )) ;
338 * ( tmp++ ) = * ( texture1 +
339 ((((a+=ai)>>8)&255)
340 | (((z+=zi)) & (255<<8)) )) ;
343 a0+=a0i;
344 z0+=z0i;
346 a1+=a1i;
347 z1+=z1i;
353 #endif
355 /***********************************************************************************/
357 static void cleanup(char *msg)
360 if (msg)
362 printf("InfPlane: %s\n",msg);
365 if (win) CloseWindow(win);
367 if (remapped)
369 WORD i;
371 for(i = 0; i < 256; i++)
373 ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
377 if (scr)
379 if (wbscreen)
380 UnlockPubScreen(0, scr);
381 else
382 CloseScreen(scr);
385 if (CyberGfxBase) CloseLibrary(CyberGfxBase);
386 if (GfxBase) CloseLibrary((struct Library *)GfxBase);
387 if (IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
389 exit(0);
392 /***********************************************************************************/
394 #define ARG_TEMPLATE "WINPOSX=X/N/K,WINPOSY=Y/N/K,FORCESCREEN=SCR/S,FORCEWINDOW=WIN/S"
395 #define ARG_X 0
396 #define ARG_Y 1
397 #define ARG_SCR 2
398 #define ARG_WIN 3
399 #define NUM_ARGS 4
401 static IPTR args[NUM_ARGS];
403 static void getarguments(void)
405 struct RDArgs *myargs;
407 if ((myargs = ReadArgs(ARG_TEMPLATE, args, NULL)))
409 if (args[ARG_SCR])
410 forcescreen = TRUE;
411 else if (args[ARG_WIN])
412 forcewindow = TRUE;
414 if (args[ARG_X]) winx = *(IPTR *)args[ARG_X];
415 if (args[ARG_Y]) winy = *(IPTR *)args[ARG_Y];
417 FreeArgs(myargs);
421 /***********************************************************************************/
423 static void openlibs(void)
425 if (!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 39)))
427 cleanup("Can't open intuition.library V39!");
430 if (!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 39)))
432 cleanup("Can't open graphics.library V39!");
435 if (!(CyberGfxBase = OpenLibrary("cybergraphics.library",0)))
437 cleanup("Can't open cybergraphics.library!");
442 /***********************************************************************************/
444 static void getvisual(void)
446 if (forcescreen)
447 wbscreen = FALSE;
449 if (!wbscreen)
451 scr = OpenScreenTags(NULL, SA_Width , W ,
452 SA_Height , H ,
453 SA_Depth , 8 ,
454 TAG_DONE);
455 if (!scr) cleanup("Failed to open specified screen!");
457 else if (!(scr = LockPubScreen(NULL)))
459 cleanup("Failed to lock pub screen (workbench)!");
462 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
464 if ((!truecolor) && (wbscreen))
465 mustremap = TRUE;
468 /***********************************************************************************/
470 static void makewin(void)
472 struct TagItem winonwbtags[] =
474 {WA_DragBar , TRUE },
475 {WA_DepthGadget , TRUE },
476 {WA_CloseGadget , TRUE },
477 {WA_Title , (IPTR)"InfPlane" },
478 {TAG_DONE }
481 struct TagItem winonscrtags[] =
483 {WA_Borderless, TRUE },
484 {TAG_DONE }
487 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
488 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
490 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
491 WA_Left , winx,
492 WA_Top , winy,
493 WA_InnerWidth , W,
494 WA_InnerHeight , H,
495 WA_AutoAdjust , TRUE,
496 WA_Activate , TRUE,
497 WA_IDCMP , IDCMP_CLOSEWINDOW |
498 IDCMP_RAWKEY,
499 TAG_MORE , wbscreen ? winonwbtags : winonscrtags);
502 if (!win) cleanup("Can't open window");
504 rp = win->RPort;
507 /***********************************************************************************/
509 #define KC_LEFT 0x4F
510 #define KC_RIGHT 0x4E
511 #define KC_UP 0x4C
512 #define KC_DOWN 0x4D
513 #define KC_ESC 0x45
515 /***********************************************************************************/
517 static void getevents(void)
519 struct IntuiMessage *msg;
521 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
523 switch(msg->Class)
525 case IDCMP_CLOSEWINDOW:
526 Keys[KC_ESC] = 1;
527 break;
529 case IDCMP_RAWKEY:
531 WORD code = msg->Code & ~IECODE_UP_PREFIX;
533 Keys[code] = (code == msg->Code) ? 1 : 0;
536 break;
539 ReplyMsg((struct Message *)msg);
544 /***********************************************************************************/
546 static void action(void)
548 float Xd,Yd,Zd;
549 float dzz=0;
550 float aa=0,thet=0;
554 float ax,ay,az;
556 float cx,cy,cz; /* vecteur visee */
557 float exx,exy,exz; /* vecteur ex normal */
558 float eyx,eyy,eyz; /* ey */
560 initinfplane();
562 /* Boucle */
564 Xd=Yd=0;
565 ax=ay=az=0;
567 /* Init FPS */
569 //init_fps ();
571 /* Boucle */
573 while (!Keys[KC_ESC])
575 getevents();
577 aa+=0.006;
578 thet+=0.008203;
581 if (aa>1){ /* this is the "keyframing" code :)) */
582 if (aa<2.45)
583 ax+=0.0261;
584 else
586 ax+=0.0061;
587 ay+=0.0033;
588 az+=0.0018;
592 /* rotate view */
593 cx=0.3; cy=0; cz=0;
594 exx=0; exy=1; exz=0;
595 eyx=0; eyy=0; eyz=1;
597 rotate3d(&cx, &cy, &cz,
598 ax,ay,az);
599 rotate3d(&exx, &exy, &exz,
600 ax,ay,az);
601 rotate3d(&eyx, &eyy, &eyz,
602 ax,ay,az);
606 Zd=10*sin(dzz/70)*0.9+30;
607 Yd=dzz+sin(aa*0.1-thet*0.2)*700;
608 dzz+=1.5;
609 Xd=dzz*2;
612 /*Xd=Yd=0;
613 //Zd=10; */
614 do_precalc(240,
615 Xd,Yd,Zd,
616 cx,cy,cz,
617 exx,exy,exz,
618 eyx,eyy,eyz
622 #ifdef C_FUNCTION
623 refresh1 (); /* la routine en C */
624 #else
625 refresh_prout (); /* ma routine asm */
626 #endif
628 if (truecolor)
630 WriteLUTPixelArray(buffer,
635 cgfx_coltab,
636 win->BorderLeft,
637 win->BorderTop,
640 CTABFMT_XRGB8);
642 else if (mustremap)
644 LONG i;
645 UBYTE *src = buffer;
646 UBYTE *dest = buffer_remapped;
648 for(i = 0; i < W * H; i++)
650 *dest++ = remaptable[*src++];
652 WriteChunkyPixels(rp,
653 win->BorderLeft,
654 win->BorderTop,
655 win->BorderLeft + W - 1,
656 win->BorderTop + H - 1,
657 buffer_remapped,
661 else
663 WriteChunkyPixels(rp,
664 win->BorderLeft,
665 win->BorderTop,
666 win->BorderLeft + W - 1,
667 win->BorderTop + H - 1,
668 buffer,
672 WaitTOF();
674 //update_x ();
675 //next_fps();
679 /* Aff FPS */
681 //aff_fps (NAME);
685 /***********************************************************************************/
687 int main(void)
689 getarguments();
690 openlibs();
691 getvisual();
692 makewin();
693 action();
694 cleanup(0);
696 return 0;
699 /***********************************************************************************/