home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 24
/
CD_ASCQ_24_0995.iso
/
dos
/
prg
/
dsik205
/
dsik.dat
/
EXAMPLES
/
EXAMP11.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-04-10
|
9KB
|
314 lines
/****************************************************************************
*
* Digital Sound Interface Kit (DSIK)
* Version 2.00
*
* by Carlos Hasan
*
* Filename: example11.c
* Version: Revision 1.0
*
* Language: WATCOM C
* Environment: IBM PC (DOS/4GW)
*
* Description: Small VGA 320x200 graphics demo.
*
* Note: This demo is VERY slow! I got only 38fps on my 486/66,
* and ET4000/W32p SVGA video card playing a 4-track module
* in my SB16 at 16-bit stereo 22kHz, because it was written
* in 100% C code and I have not done any optimization.
* Try disabling the interpolation and/or gouraud shading
* code to get higher FPS rates... or buy a Pentium! :-)
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <i86.h>
#include "audio.h"
#include "timer.h"
/* comment the following equates if you have a slow processor (80386) */
#define INTERPOLE_HEIGHT
#define INTERPOLE_COLOR
#define USE_GOURAUD
#define DSMPATH "SONG.DSM"
#define XDOTS 200
#define YDOTS 100
#define BPL 320
#define MAXDEPTH 32
#define K0 3
#define K2 128
#define VGAPTR (char*)(0xa0000+((320-XDOTS)/2)+BPL*((200-YDOTS)/2))
int invtab[MAXDEPTH];
unsigned char height[256][256],color[256][256];
int oldy[XDOTS],oldc[XDOTS],lasty[XDOTS];
int ix,iy,u,v,x,y,basey,col,adj,tmp,count,step;
char *ptr;
volatile int retraces;
/* VGA routines */
void setmode(int mode)
{
union REGS r;
r.h.ah = 0x00;
r.h.al = mode;
int386(0x10,&r,&r);
}
void setpal(char *pal)
{
int i;
outp(0x3c8,0x00);
for (i = 0; i < 3*256; i++)
outp(0x3c9,pal[i]);
}
/* plasma routines */
int random(int n)
{
static int seed = 0x1234;
seed = 0x00ab*seed + 0x4a37;
return (n*(seed & 0xffff))>>16;
}
int val(int x1, int y1, int x2, int y2, int len)
{
int n;
n = (((int)height[x1&0xff][y1&0xff] +
(int)height[x2&0xff][y2&0xff])>>1) + len*(random(4)-1);
return ((n<1) ? 1 : ((n>255) ? 255 : n));
}
void makeplasma(int x1,int y1,int x2,int y2)
{
int xc,yc,len;
if ((len = x2-x1) < 2) return;
xc = (x1+x2)>>1;
yc = (y1+y2)>>1;
if (!height[xc][y1&0xff]) height[xc][y1&0xff] = val(x1,y1,x2,y1,len);
if (!height[xc][y2&0xff]) height[xc][y2&0xff] = val(x1,y2,x2,y2,len);
if (!height[x1&0xff][yc]) height[x1&0xff][yc] = val(x1,y1,x1,y2,len);
if (!height[x2&0xff][yc]) height[x2&0xff][yc] = val(x2,y1,x2,y2,len);
height[xc][yc] = (val(xc,y1,xc,y2,len) + val(x1,yc,x2,yc,len))>>1;
makeplasma(x1,y1,xc,yc);
makeplasma(xc,y1,x2,yc);
makeplasma(x1,yc,xc,y2);
makeplasma(xc,yc,x2,y2);
}
/* voxel routines */
void initdraw(void)
{
int i,j,k;
/* make inverse "1/x" table */
for (i = j = 0; i < MAXDEPTH; i++) {
invtab[i] = 256/(i+1);
}
/* make surface height table */
memset(height,0,sizeof(height));
makeplasma(0,0,256,256);
/* make surface color table */
for (i = 0; i < 256; i++) {
for (j = 0; j < 256; j++) {
k = (((int)(height[i][j] - height[(i+3)&0xff][(j+0)&0xff]))<<2)+128;
color[i][j] = ((k<0) ? 0 : ((k>255) ? 255 : k));
}
}
/* remove noise in the surface height table */
for (i = 0; i < 256; i++) {
for (j = 0; j < 256; j++) {
height[i][j] = ((int)height[i][j] +
(int)height[(i+1)&0xff][j] + (int)height[i][(j+1)&0xff] +
(int)height[(i+1)&0xff][(j+1)&0xff])>>2;
}
}
for (i = 0; i < XDOTS; i++)
lasty[i] = YDOTS-1;
}
void draw(int posx, int posy, int posz)
{
int du;
for (x = 0; x < XDOTS; x++) {
oldy[x] = YDOTS-1;
oldc[x] = 0;
}
for (v = 0; v < MAXDEPTH; v++, posy += 256) {
adj = invtab[v];
basey = (YDOTS/2) + ((posz*adj)>>16);
adj += K2;
u = (posx) - (XDOTS*K0/2)*v;
du = K0*v;
for (x = 0; x < XDOTS; x++) {
ix = (unsigned char)(u>>8);
iy = (unsigned char)(posy>>8);
#ifdef INTERPOLE_HEIGHT
y = height[ix][iy];
y += ((height[(unsigned char)(ix+1)][iy]-y)*((unsigned char)u))>>8;
y = basey - ((y*adj)>>8);
#else
y = basey - ((height[ix][iy]*adj)>>8);
#endif
if (y < 0) y = 0;
#ifdef INTERPOLE_COLOR
col = color[ix][iy];
col += ((color[(unsigned char)(ix+1)][iy]-col)*((unsigned char)u))>>8;
#else
col = color[ix][iy];
#endif
if (oldy[x] > y) {
tmp = oldy[x];
oldy[x] = y;
y = tmp;
tmp = oldc[x];
oldc[x] = col;
col = tmp;
count = y-oldy[x];
#ifdef USE_GOURAUD
step = ((oldc[x]-col)<<8)/count;
col <<= 8;
ptr = VGAPTR + x + BPL*y;
if (count & 7) {
register int c = count&7;
for ( ; c-- > 0; ptr -= BPL) {
*ptr = col>>8;
col += step;
}
}
count >>= 3;
for (; count-- > 0; ) {
ptr -= 8*BPL;
ptr[8*BPL] = col>>8;
col += step;
ptr[7*BPL] = col>>8;
col += step;
ptr[6*BPL] = col>>8;
col += step;
ptr[5*BPL] = col>>8;
col += step;
ptr[4*BPL] = col>>8;
col += step;
ptr[3*BPL] = col>>8;
col += step;
ptr[2*BPL] = col>>8;
col += step;
ptr[1*BPL] = col>>8;
col += step;
}
#else
ptr = VGAPTR + x + BPL*y;
if (count&7) {
register int c = count&7;
for (;c-->0; ptr -= BPL)
*ptr = col;
}
count>>=3;
for (;count-->0; ) {
ptr -= 8*BPL;
ptr[8*BPL] = col;
ptr[7*BPL] = col;
ptr[6*BPL] = col;
ptr[5*BPL] = col;
ptr[4*BPL] = col;
ptr[3*BPL] = col;
ptr[2*BPL] = col;
ptr[1*BPL] = col;
}
#endif
}
else {
oldc[x] = col;
}
u += du;
}
}
for (x = 0; x < XDOTS; x++) {
y = oldy[x];
count = y - lasty[x];
lasty[x] = y;
ptr = VGAPTR + x + BPL*y;
for ( ; count-- > 0; ptr -= BPL)
*ptr = 0;
}
}
void timer(void)
{
dPoll();
retraces++;
}
int main(int argc, char *argv[])
{
char pal[3*256];
int i,j;
FILE *f;
SoundCard SC;
DSM *M;
long frames;
dRegisterDrivers();
if (dAutoDetect(&SC))
printf("No soundcard detected.\n");
else {
printf("%s at Port %03Xh using IRQ %d on DMA channel %d.\n",
dGetDriverStruc(SC.ID)->Name, SC.Port, SC.IrqLine, SC.DmaChannel);
}
if (dInit(&SC)) {
printf("Error initializing the sound system.\n");
exit(EXIT_FAILURE);
}
atexit((void(*)(void))dDone);
dInitTimer();
atexit((void(*)(void))dDoneTimer);
dStartTimer(timer,TICKS(70));
if (!(M = dLoadModule(DSMPATH))) {
printf("Error (%03d) loading %s module file: %s.\n",
dError, DSMPATH, dErrorMsg[dError]);
exit(EXIT_FAILURE);
}
dSetupVoices(M->Header.NumTracks,M->Header.MasterVolume);
dPlayMusic(M);
printf("Building landscape...\n");
initdraw();
for (i = 0; i < 256; i++) {
pal[3*i+0] = i/6;
pal[3*i+1] = i/12;
pal[3*i+2] = i/8;
}
setmode(0x13);
setpal(pal);
for (frames = retraces = 0; !kbhit(); frames++) {
/* this demo will run at the same speed on any machine,
but will look much more smooth in fast computers. */
i = 3*retraces;
j = 64*retraces;
draw(i,j,(400+height[(i>>8)&0xff][(j>>8)&0xff])<<8);
}
setmode(0x03);
dStopMusic();
dFreeModule(M);
printf("%ld retraces, %ld frames, %5.2f fps.\n",
retraces, frames, (70.1*frames)/retraces);
return 0;
}