fix remapping behavior. Remapping is only necessary if we are rendering on the workbe...
[AROS-Contrib.git] / Demo / InfPlane / infplane.c
blobeac5bb87bf361fe63993473c29e4cbf99dc4e089
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 (forcescreen)
448 wbscreen = FALSE;
450 if (!wbscreen)
452 scr = OpenScreenTags(NULL, SA_Width , W ,
453 SA_Height , H ,
454 SA_Depth , 8 ,
455 TAG_DONE);
456 if (!scr) cleanup("Failed to open specified screen!");
458 else if (!(scr = LockPubScreen(NULL)))
460 cleanup("Failed to lock pub screen (workbench)!");
463 truecolor = (GetBitMapAttr(scr->RastPort.BitMap, BMA_DEPTH) >= 15) ? TRUE : FALSE;
465 if ((!truecolor) && (wbscreen))
466 mustremap = TRUE;
469 /***********************************************************************************/
471 static void makewin(void)
473 struct TagItem winonwbtags[] =
475 {WA_DragBar , TRUE },
476 {WA_DepthGadget , TRUE },
477 {WA_CloseGadget , TRUE },
478 {WA_Title , (IPTR)"InfPlane" },
479 {TAG_DONE }
482 struct TagItem winonscrtags[] =
484 {WA_Borderless, TRUE },
485 {TAG_DONE }
488 if (winx == -1) winx = (scr->Width - W - scr->WBorLeft - scr->WBorRight) / 2;
489 if (winy == -1) winy = (scr->Height - H - scr->WBorTop - scr->WBorTop - scr->Font->ta_YSize - 1) / 2;
491 win = OpenWindowTags(NULL, WA_CustomScreen , (IPTR)scr,
492 WA_Left , winx,
493 WA_Top , winy,
494 WA_InnerWidth , W,
495 WA_InnerHeight , H,
496 WA_AutoAdjust , TRUE,
497 WA_Activate , TRUE,
498 WA_IDCMP , IDCMP_CLOSEWINDOW |
499 IDCMP_RAWKEY,
500 TAG_MORE , wbscreen ? winonwbtags : winonscrtags);
503 if (!win) cleanup("Can't open window");
505 rp = win->RPort;
508 /***********************************************************************************/
510 #define KC_LEFT 0x4F
511 #define KC_RIGHT 0x4E
512 #define KC_UP 0x4C
513 #define KC_DOWN 0x4D
514 #define KC_ESC 0x45
516 /***********************************************************************************/
518 static void getevents(void)
520 struct IntuiMessage *msg;
522 while ((msg = (struct IntuiMessage *)GetMsg(win->UserPort)))
524 switch(msg->Class)
526 case IDCMP_CLOSEWINDOW:
527 Keys[KC_ESC] = 1;
528 break;
530 case IDCMP_RAWKEY:
532 WORD code = msg->Code & ~IECODE_UP_PREFIX;
534 Keys[code] = (code == msg->Code) ? 1 : 0;
537 break;
540 ReplyMsg((struct Message *)msg);
545 /***********************************************************************************/
547 static void action(void)
549 float Xd,Yd,Zd;
550 float dzz=0;
551 float aa=0,thet=0;
555 float ax,ay,az;
557 float cx,cy,cz; /* vecteur visee */
558 float exx,exy,exz; /* vecteur ex normal */
559 float eyx,eyy,eyz; /* ey */
561 initinfplane();
563 /* Boucle */
565 Xd=Yd=0;
566 ax=ay=az=0;
568 /* Init FPS */
570 //init_fps ();
572 /* Boucle */
574 while (!Keys[KC_ESC])
576 getevents();
578 aa+=0.006;
579 thet+=0.008203;
582 if (aa>1){ /* this is the "keyframing" code :)) */
583 if (aa<2.45)
584 ax+=0.0261;
585 else
587 ax+=0.0061;
588 ay+=0.0033;
589 az+=0.0018;
593 /* rotate view */
594 cx=0.3; cy=0; cz=0;
595 exx=0; exy=1; exz=0;
596 eyx=0; eyy=0; eyz=1;
598 rotate3d(&cx, &cy, &cz,
599 ax,ay,az);
600 rotate3d(&exx, &exy, &exz,
601 ax,ay,az);
602 rotate3d(&eyx, &eyy, &eyz,
603 ax,ay,az);
607 Zd=10*sin(dzz/70)*0.9+30;
608 Yd=dzz+sin(aa*0.1-thet*0.2)*700;
609 dzz+=1.5;
610 Xd=dzz*2;
613 /*Xd=Yd=0;
614 //Zd=10; */
615 do_precalc(240,
616 Xd,Yd,Zd,
617 cx,cy,cz,
618 exx,exy,exz,
619 eyx,eyy,eyz
623 #ifdef C_FUNCTION
624 refresh1 (); /* la routine en C */
625 #else
626 refresh_prout (); /* ma routine asm */
627 #endif
629 if (truecolor)
631 WriteLUTPixelArray(buffer,
636 cgfx_coltab,
637 win->BorderLeft,
638 win->BorderTop,
641 CTABFMT_XRGB8);
643 else if (mustremap)
645 LONG i;
646 UBYTE *src = buffer;
647 UBYTE *dest = buffer_remapped;
649 for(i = 0; i < W * H; i++)
651 *dest++ = remaptable[*src++];
653 WriteChunkyPixels(rp,
654 win->BorderLeft,
655 win->BorderTop,
656 win->BorderLeft + W - 1,
657 win->BorderTop + H - 1,
658 buffer_remapped,
662 else
664 WriteChunkyPixels(rp,
665 win->BorderLeft,
666 win->BorderTop,
667 win->BorderLeft + W - 1,
668 win->BorderTop + H - 1,
669 buffer,
673 WaitTOF();
675 //update_x ();
676 //next_fps();
680 /* Aff FPS */
682 //aff_fps (NAME);
686 /***********************************************************************************/
688 int main(void)
690 getarguments();
691 openlibs();
692 getvisual();
693 makewin();
694 action();
695 cleanup(0);
697 return 0;
700 /***********************************************************************************/