home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
HOT Scene Stuff
/
hotscenestuffzyklop1996.iso
/
demos
/
sunknown
/
voxel.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1994-04-07
|
10KB
|
553 lines
// VOXEL.CPP ////////////////////////////////////////////////////////////////
// Thomas H.
// INCLUDES /////////////////////////////////////////////////////////////////
#include <stdio.h>
#include <math.h>
#include <dos.h>
#include <stdlib.h>
#include "template.h"
#include "voxel.h"
#include "timer.h"
#include "global.h"
#include "seg.h"
#include "xgraf.h"
// DEFINES //////////////////////////////////////////////////////////////////
#define VOXX 128
#define VOXY 96
#define BACK 0.5
#define HFAC 0.3
#define SENTERY 145
#define ZOOMFAC 1.5873
#define HITIT 125600
#define REALLY 1
#define RANFAC 127
#define RANDOMIZE 1
//#define CHEAT
//#define OVERVIEW
// EXTERNALS ////////////////////////////////////////////////////////////////
// FUNCTIONS
extern "C" void asmvox(void);
extern "C" void interpolate(void);
extern "C" void asmsky(void);
// VARS
extern timer_C timer;
extern long plustimer;
extern long far copper_32,
far leapright;
extern word far sseg,
far hseg,
far fseg,
far lseg,
far voxpos,
far voypos;
extern byte far alti,
far ofraction,
far interlimit,
*pressed,
rgb[];
extern ulong musicstart;
extern int relspeed;
// VARS /////////////////////////////////////////////////////////////////////
word *ra1,
*ra2,
*ra3,
*ra4;
float zoomfac=ZOOMFAC;
// RECURSE
void recurse(word *ra,word pos,word len)
{
long l=ra[pos];
long r=ra[pos+len];
long maxr=(long)len*RANFAC;
long ny=random(2l*maxr+1)-maxr;
if (len>=32)
ny*=4;
long her=(long)l+r+ny;
her>>=1;
if (her<0)
her=0;
if (her>16383)
her=16383l;
int plus=len>>1;
ra[pos+plus]=her;
if (plus==1)
return;
recurse(ra,pos,plus);
recurse(ra,pos+plus,plus);
}
// MAKERAND
void makerand(word *ra)
{
ra[0]=ra[256]=8192;
recurse(ra,0,256);
}
// DIST
float dist(int no)
{
float fac=no/96.0;
fac=pow(fac,1.05);
return fac*256.0;
}
// PRECALC
void precalc(byte *lookup, byte *copper)
{
byte *olookup=lookup;
byte *ocopper=copper;
FILE *fp=fopen(VOXPRE,"rb");
byte *leap=(byte*)leapright;
for (int o=0; o<64; o++)
{
float vekk=64.0-o;
float s=max((double)0,64-sqrt(4096.0-vekk*vekk));
leap[o]=leap[127-o]=2*s;
}
for (word cut=0; cut<128l*96l*3; cut++)
{
byte temp;
fread(&temp,1,1,fp);
ocopper[cut]=temp;
}
for (cut=0; cut<96l*256l; cut++)
{
byte temp;
fread(&temp,1,1,fp);
olookup[cut]=temp;
}
fclose(fp);
}
// VISVOX
void visvox(byte *page,float camv, word screenseg,int step)
{
#ifndef CHEAT
int tempdx,tempcx;
byte count;
float co=cos(camv);
float si=sin(camv);
float hx=co*256/zoomfac;
float hy=si*256/zoomfac;
int x0=32768-160*hx+120*hy;
int y0=32768-160*hy-120*hx;
int plx=hx;
int ply=hy;
int plx4=hx*4;
int ply4=hy*4;
asm pusha
asm push ds
asm lds si,page
int mapval=MAP_MASK-256+512*step;
for (byte plan=0; plan<4; plan+=step)
{
asm mov ax,screenseg
asm mov es,ax
asm mov ax,mapval
asm mov cl,plan
asm shl ah,cl
asm mov dx,SC_INDEX
asm out dx,ax
asm xor di,di
asm mov cx,x0
asm mov dx,y0
asm mov count,80
asm mov si,plx
next_right:
asm mov tempcx,cx
asm mov tempdx,dx
asm mov ah,60
next_down:
asm mov bl,ch
asm mov bh,dh
asm mov al,[bx]
asm mov [es:di],al
asm add di,80
asm sub cx,ply
asm add dx,si
asm mov bl,ch
asm mov bh,dh
asm mov al,[bx]
asm mov [es:di],al
asm add di,80
asm sub cx,ply
asm add dx,si
asm mov bl,ch
asm mov bh,dh
asm mov al,[bx]
asm mov [es:di],al
asm add di,80
asm sub cx,ply
asm add dx,si
asm mov bl,ch
asm mov bh,dh
asm mov al,[bx]
asm mov [es:di],al
asm add di,80
asm sub cx,ply
asm add dx,si
asm dec ah
asm jnz next_down
asm add di,1-240*80
asm mov cx,tempcx
asm mov dx,tempdx
asm add cx,plx4
asm add dx,ply4
asm dec count
asm jnz next_right
asm mov cx,plx
asm add x0,cx
asm mov cx,ply
asm add y0,cx
}
asm pop ds
asm popa
#else
asm pusha
asm push ds
asm lds si,page
asm mov ax,0xa000
asm mov es,ax
asm xor si,si
asm xor di,di
asm mov dx,200
l1:
asm mov cx,128
asm rep movsw
asm add di,320-256
asm dec dx
asm jnz l1
asm pop ds
asm popa
#endif
}
// LOADSKY
void loadsky(byte *sky)
{
FILE *infile=fopen(CLOUDFILE,"rb");
for (int qy=0; qy<256; qy++)
for (int qx=0; qx<256; qx++)
{
byte col;
fread(&col,1,1,infile);
sky[qx+(qy<<8)]=col;
}
fclose(infile);
}
// FIXSKY
void fixsky(byte *page, byte *sky, char skyx, byte skyy)
{
asm pusha
asm push ds
asm les di,page
asm lds bx,sky
asm add bh,skyx
asm add bl,skyy
asmsky();
asm pop ds
asm popa
}
// COLORSTRIP
void colorstrip(byte *height, byte *color, byte stripe)
{
for (int x=0; x<256; x++)
{
byte xx=x+2;
byte xxx=x-2;
int her=height[x+(stripe<<8)];
int der=height[xx+(stripe<<8)];
int tre=height[xxx+(stripe<<8)];
int diff=3*der-2*her-1*tre;
diff+=64;
fit(2,diff,127);
color[x+(stripe<<8)]=diff;
}
}
// MAKESTRIP
void makestrip(byte *ptr,int no,float pro)
{
int minus=384-no;
if (pro>0.65)
minus=(pro-0.65)*250;
fit(0,minus,127);
float f1=1+sin(no/23.0+2.5);
float f2=1+sin(no/21.0+1.5+f1/3);
float f3=1+sin(no/34.0+2.5);
float f4=1+sin(no/16.0+1.5+f3/2);
int pl1=f1*4+no/2.0;
int pl2=f2*8-no/1.5;
int pl3=f3*7+no/4;
int pl4=f4*3-no/3;
byte *optr=&ptr[no<<8];
for (int count=0; count<256; count++)
{
word v1=ra1[(count+pl1)&255];
word v2=ra2[(count+pl2)&255];
word v3=ra3[(count+pl3)&255];
word v4=ra4[(count+pl4)&255];
word vv=v1+v2+v3+v4;
long sumb=vv>>9;
sumb-=minus;
if (sumb<0)
sumb=random(2);
*(optr++)=128+sumb;
}
}
// VOXEL
void voxel(void)
{
#if RANDOMIZE
randomize();
#endif
zoomfac=ZOOMFAC;
#ifdef CHEAT
asm mov ax,0x13
asm int 0x10
#endif
setpalette(VOXELPAL);
seg_C height;
seg_C color;
seg_C lookup;
seg_C sky;
seg_C randata(4096);
ra1=(word*)&randata.ptr[0];
ra2=(word*)&randata.ptr[512];
ra3=(word*)&randata.ptr[1024];
ra4=(word*)&randata.ptr[1536];
hseg=(long)height.ptr>>16;
fseg=(long)color.ptr>>16;
lseg=(long)lookup.ptr>>16;
#ifndef OVERVIEW
loadsky(sky.ptr);
#endif
#ifndef OVERVIEW
precalc(lookup.ptr, (byte*)copper_32);
#endif
makerand(ra1);
makerand(ra2);
makerand(ra3);
makerand(ra4);
for (long e=0; e<65536l; e++)
{
height.ptr[e]=random(2)+128;
height.ptr[e]=128;
color.ptr[e]=59+random(10);
}
int s;
seg_C page;
sseg=(long)page.ptr>>16;
for (s=0; s<1280; s++)
{
height.ptr[s]=(s>=4*256)?138:128;
color.ptr[s]=0;
}
word screenseg=0xa000;
word xpos=0,ypos=0;
long dxpos=0,dypos=0;
float frames=0,dvin=0,vin=M_PI_2,alt=0;
int done=0,pixsize=1+(relspeed<300);
long estart=timer.readtimer();
long sofar=timer.elapsed(musicstart,estart);
long left=END_VOXEL-sofar-1100l;
int sretn=1-2*(random(100)>20);
do
{
long gaatt=timer.readtimer();
gaatt=timer.elapsed(estart,gaatt);
float pro=(float)gaatt/left;
if (pro>0.90)
{
float zfac=1+(pro-0.90)*150;
zoomfac=ZOOMFAC*zfac*zfac;
}
if (pressed[59])
pixsize=1;
if (pressed[60])
pixsize=2;
if (pressed[61])
interlimit++;
if (pressed[62])
interlimit--;
voypos=ypos>>8;
voxpos=xpos;
ofraction=voxpos;
frames++;
if (pro>0.80)
vin+=(pro-0.80)*4.6*sretn;
dvin+=(pressed[77]-pressed[75])*0.007;
vin+=dvin;
if (dypos>512)
dypos=512;
long hit=timer.elapsed(musicstart,timer.readtimer());
if (hit<HITIT)
dypos=0;
byte test1=xpos>>8;
byte test0=test1-15;
byte test2=test2+15;
byte testy=voypos+30;
word testypos=256*testy;
int der0=height.ptr[test0+testypos];
int der2=height.ptr[test2+testypos];
float vfacx=sin(vin);
float vkorr=cos(vin);
if (dypos)
dvin+=vkorr*0.01;
dvin*=0.975;
if (vfacx<0)
vfacx=0;
int hdiff=(der2-der0);
if (dypos)
dvin+=-hdiff*0.00009;
if (dypos)
xpos+=dxpos-1000*cos(vin);
ypos+=dypos;
static word voypos2;
makestrip(height.ptr,voypos2+254,pro);
makestrip(height.ptr,voypos2+255,pro);
colorstrip(height.ptr,color.ptr,(voypos2+252)&255);
colorstrip(height.ptr,color.ptr,(voypos2+253)&255);
alt+=2*(pressed[72]-pressed[80]);
voypos2+=dypos/256;
testy=voypos2;
byte xx=(xpos>>8);
xx+=4;
float inall=height.ptr[xx+256*testy];
float inall2=height.ptr[xx+256*testy+5120];
if (pro>0.8)
inall2=128+((pro-0.8)*1270);
if (inall2>inall)
inall=inall2;
inall-=110;
if (inall>127)
inall=127;
float qq=20;
if (inall>alt)
qq=3;
if (!dypos)
qq=3;
float diff=(inall-alt)/qq;
alt+=diff;
if (diff<0.5 && !dypos)
dypos=512;
fit((float)0,alt,(float)127);
alti=alt;
asmvox();
interpolate();
fixsky(page.ptr,sky.ptr,(xpos+50000000l)/256l,0);
#ifdef OVERVIEW
visvox(color.ptr,vin,screenseg,pixsize);
#else
visvox(page.ptr,vin,screenseg,pixsize);
#endif
#ifndef CHEAT
yoffset((screenseg-0xa000)/5);
screenseg+=240*5;
if (screenseg==240*5*3l+0xa000)
screenseg=0xa000;
#endif
done|=(pro>=1.0);
}while (!done);
byte col=getpixel(160,100);
float rr=rgb[col*3];
float rg=rgb[col*3+1];
float rb=rgb[col*3+2];
for (int count=0; count<70; count++)
{
float fac=1-count/69.0;
byte r=rr*fac;
byte g=rg*fac;
byte b=rb*fac;
frame();
setrgb(col,r,g,b);
}
}