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 >
C/C++ Source or Header  |  1995-04-10  |  9KB  |  314 lines

  1. /****************************************************************************
  2. *
  3. *                   Digital Sound Interface Kit (DSIK)
  4. *                            Version 2.00
  5. *
  6. *                           by Carlos Hasan
  7. *
  8. * Filename:     example11.c
  9. * Version:      Revision 1.0
  10. *
  11. * Language:     WATCOM C
  12. * Environment:  IBM PC (DOS/4GW)
  13. *
  14. * Description:  Small VGA 320x200 graphics demo.
  15. *
  16. * Note:         This demo is VERY slow! I got only 38fps on my 486/66,
  17. *               and ET4000/W32p SVGA video card playing a 4-track module
  18. *               in my SB16 at 16-bit stereo 22kHz, because it was written
  19. *               in 100% C code and I have not done any optimization.
  20. *               Try disabling the interpolation and/or gouraud shading
  21. *               code to get higher FPS rates... or buy a Pentium! :-)
  22. ****************************************************************************/
  23.  
  24. #include <stdio.h>
  25. #include <stdlib.h>
  26. #include <string.h>
  27. #include <conio.h>
  28. #include <i86.h>
  29. #include "audio.h"
  30. #include "timer.h"
  31.  
  32. /* comment the following equates if you have a slow processor (80386) */
  33. #define INTERPOLE_HEIGHT
  34. #define INTERPOLE_COLOR
  35. #define USE_GOURAUD
  36.  
  37. #define DSMPATH     "SONG.DSM"
  38.  
  39. #define XDOTS       200
  40. #define YDOTS       100
  41. #define BPL         320
  42. #define MAXDEPTH    32
  43. #define K0          3
  44. #define K2          128
  45. #define VGAPTR      (char*)(0xa0000+((320-XDOTS)/2)+BPL*((200-YDOTS)/2))
  46.  
  47. int invtab[MAXDEPTH];
  48. unsigned char height[256][256],color[256][256];
  49. int oldy[XDOTS],oldc[XDOTS],lasty[XDOTS];
  50. int ix,iy,u,v,x,y,basey,col,adj,tmp,count,step;
  51. char *ptr;
  52.  
  53. volatile int retraces;
  54.  
  55. /* VGA routines */
  56. void setmode(int mode)
  57. {
  58.     union REGS r;
  59.     r.h.ah = 0x00;
  60.     r.h.al = mode;
  61.     int386(0x10,&r,&r);
  62. }
  63.  
  64. void setpal(char *pal)
  65. {
  66.     int i;
  67.     outp(0x3c8,0x00);
  68.     for (i = 0; i < 3*256; i++)
  69.         outp(0x3c9,pal[i]);
  70. }
  71.  
  72. /* plasma routines */
  73. int random(int n)
  74. {
  75.     static int seed = 0x1234;
  76.     seed = 0x00ab*seed + 0x4a37;
  77.     return (n*(seed & 0xffff))>>16;
  78. }
  79.  
  80. int val(int x1, int y1, int x2, int y2, int len)
  81. {
  82.     int n;
  83.     n = (((int)height[x1&0xff][y1&0xff] +
  84.         (int)height[x2&0xff][y2&0xff])>>1) + len*(random(4)-1);
  85.     return ((n<1) ? 1 : ((n>255) ? 255 : n));
  86. }
  87.  
  88. void makeplasma(int x1,int y1,int x2,int y2)
  89. {
  90.     int xc,yc,len;
  91.     if ((len = x2-x1) < 2) return;
  92.     xc = (x1+x2)>>1;
  93.     yc = (y1+y2)>>1;
  94.     if (!height[xc][y1&0xff]) height[xc][y1&0xff] = val(x1,y1,x2,y1,len);
  95.     if (!height[xc][y2&0xff]) height[xc][y2&0xff] = val(x1,y2,x2,y2,len);
  96.     if (!height[x1&0xff][yc]) height[x1&0xff][yc] = val(x1,y1,x1,y2,len);
  97.     if (!height[x2&0xff][yc]) height[x2&0xff][yc] = val(x2,y1,x2,y2,len);
  98.     height[xc][yc] = (val(xc,y1,xc,y2,len) + val(x1,yc,x2,yc,len))>>1;
  99.     makeplasma(x1,y1,xc,yc);
  100.     makeplasma(xc,y1,x2,yc);
  101.     makeplasma(x1,yc,xc,y2);
  102.     makeplasma(xc,yc,x2,y2);
  103. }
  104.  
  105.  
  106. /* voxel routines */
  107. void initdraw(void)
  108. {
  109.     int i,j,k;
  110.  
  111.     /* make inverse "1/x" table */
  112.     for (i = j = 0; i < MAXDEPTH; i++) {
  113.         invtab[i] = 256/(i+1);
  114.     }
  115.  
  116.     /* make surface height table */
  117.     memset(height,0,sizeof(height));
  118.     makeplasma(0,0,256,256);
  119.  
  120.     /* make surface color table */
  121.     for (i = 0; i < 256; i++) {
  122.         for (j = 0; j < 256; j++) {
  123.             k = (((int)(height[i][j] - height[(i+3)&0xff][(j+0)&0xff]))<<2)+128;
  124.             color[i][j] = ((k<0) ? 0 : ((k>255) ? 255 : k));
  125.         }
  126.     }
  127.  
  128.     /* remove noise in the surface height table */
  129.     for (i = 0; i < 256; i++) {
  130.         for (j = 0; j < 256; j++) {
  131.             height[i][j] = ((int)height[i][j] +
  132.                 (int)height[(i+1)&0xff][j] + (int)height[i][(j+1)&0xff] +
  133.                 (int)height[(i+1)&0xff][(j+1)&0xff])>>2;
  134.         }
  135.     }
  136.  
  137.     for (i = 0; i < XDOTS; i++)
  138.         lasty[i] = YDOTS-1;
  139. }
  140.  
  141. void draw(int posx, int posy, int posz)
  142. {
  143.     int du;
  144.     for (x = 0; x < XDOTS; x++) {
  145.         oldy[x] = YDOTS-1;
  146.         oldc[x] = 0;
  147.     }
  148.     for (v = 0; v < MAXDEPTH; v++, posy += 256) {
  149.         adj = invtab[v];
  150.         basey = (YDOTS/2) + ((posz*adj)>>16);
  151.         adj += K2;
  152.         u = (posx) - (XDOTS*K0/2)*v;
  153.         du = K0*v;
  154.         for (x = 0; x < XDOTS; x++) {
  155.             ix = (unsigned char)(u>>8);
  156.             iy = (unsigned char)(posy>>8);
  157.  
  158. #ifdef INTERPOLE_HEIGHT
  159.             y = height[ix][iy];
  160.             y += ((height[(unsigned char)(ix+1)][iy]-y)*((unsigned char)u))>>8;
  161.             y = basey - ((y*adj)>>8);
  162. #else
  163.             y = basey - ((height[ix][iy]*adj)>>8);
  164. #endif
  165.             if (y < 0) y = 0;
  166.  
  167. #ifdef INTERPOLE_COLOR
  168.             col = color[ix][iy];
  169.             col += ((color[(unsigned char)(ix+1)][iy]-col)*((unsigned char)u))>>8;
  170. #else
  171.             col = color[ix][iy];
  172. #endif
  173.  
  174.             if (oldy[x] > y) {
  175.                 tmp = oldy[x];
  176.                 oldy[x] = y;
  177.                 y = tmp;
  178.                 tmp = oldc[x];
  179.                 oldc[x] = col;
  180.                 col = tmp;
  181.                 count = y-oldy[x];
  182. #ifdef USE_GOURAUD
  183.                 step = ((oldc[x]-col)<<8)/count;
  184.                 col <<= 8;
  185.                 ptr = VGAPTR + x + BPL*y;
  186.                 if (count & 7) {
  187.                     register int c = count&7;
  188.                     for ( ; c-- > 0; ptr -= BPL) {
  189.                         *ptr = col>>8;
  190.                         col += step;
  191.                     }
  192.                 }
  193.                 count >>= 3;
  194.                 for (; count-- > 0; ) {
  195.                     ptr -= 8*BPL;
  196.                     ptr[8*BPL] = col>>8;
  197.                     col += step;
  198.                     ptr[7*BPL] = col>>8;
  199.                     col += step;
  200.                     ptr[6*BPL] = col>>8;
  201.                     col += step;
  202.                     ptr[5*BPL] = col>>8;
  203.                     col += step;
  204.                     ptr[4*BPL] = col>>8;
  205.                     col += step;
  206.                     ptr[3*BPL] = col>>8;
  207.                     col += step;
  208.                     ptr[2*BPL] = col>>8;
  209.                     col += step;
  210.                     ptr[1*BPL] = col>>8;
  211.                     col += step;
  212.                 }
  213. #else
  214.                 ptr = VGAPTR + x + BPL*y;
  215.                 if (count&7) {
  216.                     register int c = count&7;
  217.                     for (;c-->0; ptr -= BPL)
  218.                         *ptr = col;
  219.                 }
  220.                 count>>=3;
  221.                 for (;count-->0; ) {
  222.                     ptr -= 8*BPL;
  223.                     ptr[8*BPL] = col;
  224.                     ptr[7*BPL] = col;
  225.                     ptr[6*BPL] = col;
  226.                     ptr[5*BPL] = col;
  227.                     ptr[4*BPL] = col;
  228.                     ptr[3*BPL] = col;
  229.                     ptr[2*BPL] = col;
  230.                     ptr[1*BPL] = col;
  231.                 }
  232. #endif
  233.             }
  234.             else {
  235.                 oldc[x] = col;
  236.             }
  237.             u += du;
  238.         }
  239.     }
  240.  
  241.     for (x = 0; x < XDOTS; x++) {
  242.         y = oldy[x];
  243.         count = y - lasty[x];
  244.         lasty[x] = y;
  245.         ptr = VGAPTR + x + BPL*y;
  246.         for ( ; count-- > 0; ptr -= BPL)
  247.             *ptr = 0;
  248.     }
  249. }
  250.  
  251. void timer(void)
  252. {
  253.     dPoll();
  254.     retraces++;
  255. }
  256.  
  257. int main(int argc, char *argv[])
  258. {
  259.     char pal[3*256];
  260.     int i,j;
  261.     FILE *f;
  262.     SoundCard SC;
  263.     DSM *M;
  264.     long frames;
  265.  
  266.     dRegisterDrivers();
  267.     if (dAutoDetect(&SC))
  268.         printf("No soundcard detected.\n");
  269.     else {
  270.         printf("%s at Port %03Xh using IRQ %d on DMA channel %d.\n",
  271.             dGetDriverStruc(SC.ID)->Name, SC.Port, SC.IrqLine, SC.DmaChannel);
  272.     }
  273.     if (dInit(&SC)) {
  274.         printf("Error initializing the sound system.\n");
  275.         exit(EXIT_FAILURE);
  276.     }
  277.     atexit((void(*)(void))dDone);
  278.     dInitTimer();
  279.     atexit((void(*)(void))dDoneTimer);
  280.     dStartTimer(timer,TICKS(70));
  281.     if (!(M = dLoadModule(DSMPATH))) {
  282.         printf("Error (%03d) loading %s module file: %s.\n",
  283.             dError, DSMPATH, dErrorMsg[dError]);
  284.         exit(EXIT_FAILURE);
  285.     }
  286.     dSetupVoices(M->Header.NumTracks,M->Header.MasterVolume);
  287.     dPlayMusic(M);
  288.  
  289.     printf("Building landscape...\n");
  290.     initdraw();
  291.     for (i = 0; i < 256; i++) {
  292.         pal[3*i+0] = i/6;
  293.         pal[3*i+1] = i/12;
  294.         pal[3*i+2] = i/8;
  295.     }
  296.  
  297.     setmode(0x13);
  298.     setpal(pal);
  299.      for (frames = retraces = 0; !kbhit(); frames++) {
  300.         /* this demo will run at the same speed on any machine,
  301.            but will look much more smooth in fast computers. */
  302.         i = 3*retraces;
  303.         j = 64*retraces;
  304.         draw(i,j,(400+height[(i>>8)&0xff][(j>>8)&0xff])<<8);
  305.     }
  306.     setmode(0x03);
  307.     dStopMusic();
  308.     dFreeModule(M);
  309.  
  310.     printf("%ld retraces, %ld frames, %5.2f fps.\n",
  311.         retraces, frames, (70.1*frames)/retraces);
  312.     return 0;
  313. }
  314.