2 #include <intuition/intuition.h>
3 #include <graphics/gfx.h>
4 #include <cybergraphx/cybergraphics.h>
5 #include <proto/exec.h>
7 #include <proto/graphics.h>
8 #include <proto/cybergraphics.h>
9 #include <proto/intuition.h>
17 #define PI 3.141592654
18 #define SCREENWIDTH 640
19 #define SCREENHEIGHT 400
22 #define CLOUDWIDTH 640
23 #define CLOUDHEIGHT 400
25 #define MAPSHIFT 9 /* 2^9==512==MAPWIDTH */
26 #define voxel_dist 3000
30 #define CHECKMAPRANGE 1
32 #define MAXVIEWLENGTH SCREENWIDTH
35 /*************************************************************/
37 struct IntuitionBase
*IntuitionBase
;
38 struct GfxBase
*GfxBase
;
39 struct Library
*CyberGfxBase
;
44 ULONG cgfx_coltab
[256];
46 int screenwidth
= SCREENWIDTH
;
47 int screenheight
= SCREENHEIGHT
- 1;
48 int resizescale
= 1 << 16;
50 /**************************VARS*******************************/
51 float sintab
[360],costab
[360];
52 char *buffer
, /* Offscreen Buffer */
53 *map
; /* Height Map */
54 unsigned char *color
, /* Color Map */
55 *clouds
; /* Cloud Bitmap */
60 void (__interrupt __far
*old09h
)();
61 void __interrupt __far
new09h();
63 int hoehe
,richt
,xc
,yc
,direction
,voxel_stretch
=50;
65 view_length
,view_size
,flyheight
= 100,
66 y_old
,offtab
[SCREENHEIGHT
],
67 xtab
[SCREENWIDTH
][MAXVIEWLENGTH
],voxtab
[SCREENWIDTH
];
69 /************************************************************/
72 /**************************PCX-STRUCTS***********************/
78 unsigned char id
,version
,encoding
,bpp
;
79 short x1
,y1
,x2
,y2
,hres
,vres
;
80 unsigned char colors
[48];
81 unsigned char vmode
,planes
;
83 unsigned char fillbytes
[58];
86 /************************************************************/
89 /*****************BUILD TABLES*******************************/
94 maxy
=(screenheight
-1),
95 view_length
=(screenwidth
/5),
96 view_size
=(screenwidth
/PIXELWIDTH
)-1;
98 resizescale
= (screenheight
<< 16) / SCREENHEIGHT
;
105 for(i
=0;i
<=359;i
++)sintab
[(int)i
]=sin(i
/(180)*PI
);
106 for(i
=0;i
<=359;i
++)costab
[(int)i
]=cos(i
/(180)*PI
);
114 for(j
=1;j
<=view_length
;j
++)voxtab
[j
]=horizon
+voxel_dist
/j
;
115 for(j
=0;j
<screenheight
;j
++)offtab
[j
]=j
*SCREENWIDTH
;
116 for(i
=0;i
<=view_size
;i
++)
117 for(j
=1;j
<=view_length
;j
++)
118 xtab
[i
][j
]=i
*j
/view_size
-(j
>>1);
127 return sintab
[(int)a
];
134 return costab
[(int)a
];
138 /************************PCX LOADER**************************/
140 Tpcxsize
getpcxsize(char *d
)
144 FILE *f
=fopen(d
,"rb");
145 memset(&pc
,0,sizeof(pc
));
146 fread(&pc
,sizeof(pc
),1,f
);
153 long filesize(FILE *n
)
155 long org
=ftell(n
), size
;
156 fseek(n
,-0L,SEEK_END
);
158 fseek(n
,org
,SEEK_SET
);
162 void loadpcx(char *name
,char *po
)
166 unsigned char *cimage
;
167 unsigned char header
[128];
169 Tpcxsize sz
=getpcxsize(name
);
171 cimage
=(char *)malloc(filesize(f
));
172 fread(&header
,128,1,f
);
174 fread(&*cimage
,filesize(f
)-896,1,f
);
179 if(cimage
[z
]<192) po
[g
]=cimage
[z
];
180 if(cimage
[z
]>=192){m
=cimage
[z
]-192;
182 for(i
=1;i
<=m
;i
++) po
[g
+i
-1]=cimage
[z
];
192 void loadpcxpal(char *name
,unsigned char pal
[768])
198 fseek(f
,filesize(f
)-768,SEEK_SET
);
200 for(i
=0;i
<768;i
++) pal
[i
]/=4;
203 /***********************************************************/
206 void setpal(unsigned char palp
[])
209 for(pcount
=0;pcount
<256;pcount
++){
210 cgfx_coltab
[pcount
] = (palp
[pcount
* 3] << 18) +
211 (palp
[pcount
* 3 + 1] << 10) +
212 (palp
[pcount
* 3 + 2] << 2);
220 for(y
=0;y
<MAPHEIGHT
;y
++)
221 for(x
=0;x
<MAPWIDTH
;x
++){
222 f
=b
[(x
-1)+y
*MAPWIDTH
]+\
223 b
[(x
-2)+y
*MAPWIDTH
]+\
224 b
[(x
+1)+y
*MAPWIDTH
]+\
225 b
[(x
+2)+y
*MAPWIDTH
]+\
226 b
[x
+(y
-1)*MAPWIDTH
]+\
227 b
[x
+(y
-2)*MAPWIDTH
]+\
228 b
[x
+(y
+1)*MAPWIDTH
]+\
230 if(f
!=0)b
[x
+y
*MAPWIDTH
]=f
>>3;}
235 /*****************MAIN VOXEL PROCS**************************/
239 static inline void innerloop(int x
, int start
,int col
)
241 UBYTE
*dest
= buffer
+ x
+ start
* SCREENWIDTH
;
242 int count
= y_old
+ 1 - start
;
245 #define PIXELTYPE int
246 col
+= (col
<< 24) + (col
<< 16) + (col
<< 8);
248 #define PIXELTYPE short
251 #define PIXELTYPE char
253 #error "PIXELWIDTH must be 1,2 or 4"
258 *(PIXELTYPE
*)dest
= col
;
265 void innerloop(int x
,int start
,int col
); /* draws 4pix vline */
266 #pragma aux innerloop= \
287 void draw_voxel(int x
,int e
,int f
,int c
)
291 h
=f
*voxel_stretch
/e
;
293 y
=((voxtab
[e
]-h
) * resizescale
) >> 16;
304 void voxel_spacing(int xp
,int yp
,int r
)
306 int i
,j
=0,offset
,x
,co
,si
,nx
,ny
;
313 hoehe
=map
[xp
+yp
*MAPWIDTH
]+flyheight
;
315 for(i
=0;i
<=view_size
;i
++){
316 y_old
=screenheight
-1;
317 for(j
=1;j
<=view_length
;j
++){
319 nx
=(x
*co
>> 10)-(j
*si
>> 10);
320 ny
=(x
*si
>> 10)+(j
*co
>> 10);
322 offset
=((nx
+xp
) & (MAPWIDTH
- 1)) + (((ny
+yp
) & (MAPHEIGHT
- 1))<<MAPSHIFT
);
324 offset
=(nx
+xp
)+((ny
+yp
)<<MAPSHIFT
);
328 draw_voxel(i
*PIXELWIDTH
,j
,f
,c
);
333 /***********************************************************/
336 #define KC_RIGHT 0x4E
339 #define KC_NUMPAD8 0x3E
340 #define KC_NUMPAD2 0x1E
341 #define KC_NUMPADPLUS 0x5E
342 #define KC_NUMPADMINUS 0x4A
343 #define KC_NUMPADMINUS2 0x5D
345 #define KC_RETURN 0x44
350 xc
-=cosinus(richt
)*4;
354 xc
+=cosinus(richt
)*4;
357 if(Keys
[KC_RIGHT
]){richt
-=4;direction
-=4;if(richt
<0)richt
+=360;if(direction
<0) direction
+=SCREENWIDTH
;}
358 if(Keys
[KC_LEFT
]){richt
+=4;direction
+=4;if(richt
>=360)richt
-=360;if(direction
>=SCREENWIDTH
)direction
-=SCREENWIDTH
;}
359 if(Keys
[KC_NUMPAD2
])flyheight
--;
360 if(Keys
[KC_NUMPAD8
])flyheight
++;
361 if(Keys
[KC_RETURN
])adjust(map
);
362 if(Keys
[KC_NUMPADMINUS
] || Keys
[KC_NUMPADMINUS2
])voxel_stretch
++;
363 if(Keys
[KC_NUMPADPLUS
])voxel_stretch
--;
364 if(Keys
[KC_ESC
]) ende
=1;
367 /***********************************************************/
369 void cleanup(char *msg
)
373 printf("voxel: %s\n",msg
);
376 if (win
) CloseWindow(win
);
378 if (scr
) UnlockPubScreen(0, scr
);
380 if (CyberGfxBase
) CloseLibrary(CyberGfxBase
);
381 if (GfxBase
) CloseLibrary((struct Library
*)GfxBase
);
382 if (IntuitionBase
) CloseLibrary((struct Library
*)IntuitionBase
);
389 if (!(IntuitionBase
= (struct IntuitionBase
*)OpenLibrary("intuition.library", 39)))
391 cleanup("Can't open intuition.library V39!");
394 if (!(GfxBase
= (struct GfxBase
*)OpenLibrary("graphics.library", 39)))
396 cleanup("Can't open graphics.library V39!");
399 if (!(CyberGfxBase
= OpenLibrary("cybergraphics.library",0)))
401 cleanup("Can't open cybergraphics.library!");
407 if (!(scr
= LockPubScreen(NULL
)))
409 cleanup("Can't lock pub screen!");
412 if (GetBitMapAttr(scr
->RastPort
.BitMap
, BMA_DEPTH
) <= 8)
414 cleanup("Need hi or true color screen!");
420 win
= OpenWindowTags(NULL
, WA_CustomScreen
, (IPTR
)scr
,
421 WA_InnerWidth
, SCREENWIDTH
,
422 WA_InnerHeight
, SCREENHEIGHT
- 1,
423 WA_Title
, (IPTR
)"Voxel",
425 WA_DepthGadget
, TRUE
,
426 WA_CloseGadget
, TRUE
,
434 WA_IDCMP
, IDCMP_CLOSEWINDOW
|
435 (RESIZEABLE
* IDCMP_NEWSIZE
) |
439 if (!win
) cleanup("Can't open window");
442 WindowLimits(win
, 320 + win
->BorderLeft
+ win
->BorderRight
,
443 200 + win
->BorderTop
+ win
->BorderBottom
,
444 SCREENWIDTH
+ win
->BorderLeft
+ win
->BorderRight
,
445 SCREENHEIGHT
- 1 + win
->BorderTop
+ win
->BorderBottom
);
454 struct IntuiMessage
*msg
;
456 while ((msg
= (struct IntuiMessage
*)GetMsg(win
->UserPort
)))
460 case IDCMP_CLOSEWINDOW
:
466 WORD code
= msg
->Code
& ~IECODE_UP_PREFIX
;
468 Keys
[code
] = (code
== msg
->Code
) ? 1 : 0;
477 screenwidth
= win
->Width
- win
->BorderLeft
- win
->BorderRight
;
478 screenheight
= win
->Height
- win
->BorderTop
- win
->BorderBottom
;
485 ReplyMsg((struct Message
*)msg
);
488 /********************MAIN PROC******************************/
490 int main(int argc
, char **argv
)
493 unsigned char pal
[768];
500 buffer
=(char*)malloc(SCREENWIDTH
*(SCREENHEIGHT
+ 1));
501 map
=(char*)malloc(MAPWIDTH
*MAPHEIGHT
);
502 color
=(char*)malloc(MAPWIDTH
*MAPHEIGHT
);
503 clouds
=(char*)malloc(CLOUDWIDTH
*CLOUDHEIGHT
);
504 if(color
==0||buffer
==0||map
==0||clouds
==0){
505 printf("no mem... -sorry!\n");exit(0);
507 loadpcx("demoh.pcx",map
);
508 loadpcx("democ.pcx",color
);
509 loadpcx("clouds.pcx",clouds
);
510 loadpcxpal("democ.pcx",pal
);
511 for(u
=0;u
<7;u
++)adjust(map
);
513 xc
=160,yc
=100,direction
=0;
520 memcpy(buffer
,clouds
+ CLOUDWIDTH
- direction
,SCREENWIDTH
*screenheight
);
521 voxel_spacing(xc
,yc
,richt
);
523 WriteLUTPixelArray(buffer
,