/***************************************************************************
* NAME: PLAY3DI.C
**
** Copyright (C) 1992,1993 by Focal Point 3D Audio and FORTE
** All Rights Reserved
**
** "This software is furnished under a license and may be used,
** copied, or disclosed only in accordance with the terms of such
** license and with the inclusion of the above copyright notice.
** This software or any other copies thereof may not be provided or
** otherwise made available to any other person. No title to and
** ownership of the software is hereby transfered."
****************************************************************************
* CREATION DATE: 11/18/92
*--------------------------------------------------------------------------*
* VERSION DATE NAME DESCRIPTION
*> 1.0 05/01/93 Original
***************************************************************************/
/*********************************************************************
*
* Example program for playing a 3D Sound track
*
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <alloc.h>
#include "forte.h"
#include "gf1proto.h"
#include "extern.h"
#include "ultraerr.h"
#include "threed.h"
#include "hdr3d.h"
/* Caution: Don't make BSIZE too small. It won't be able to feed */
/* data to the UltraSound fast enough .... */
#define BSIZE 30*1024
#define ULTRA_BSIZE (long)(128L*1024L)
/* Joystick stuff */
int center_x=0;
int right_x=0;
int left_x=1000;
int center_z=0;
int fwrd_z=1000;
int back_z=0;
void
usage()
{
printf("\nUsage: play3di filename\n");
}
/* This function will load DRAM with the next data in the file */
unsigned long
load_dram(fp,sound,dramloc,dramsize,pcsize,pcbuffer)
FILE *fp; /* File pointer */
SOUND_3D *sound; /* 3d sound handle */
unsigned long dramloc; /* Where to put it */
unsigned long dramsize; /* How much to read & transfer */
unsigned int pcsize; /* How big is the PC buffer for DMA */
void far *pcbuffer; /* pointer to pc DMA buffer */
{
int i;
unsigned int length;
unsigned long total=0L;
int num;
int remaining;
num = dramsize / (long)pcsize;
remaining = dramsize - (long)((long)pcsize*(long)num);
/* Send as many full buffers as possible */
for (i=0;i<num;i++)
{
length = fread(pcbuffer,1,pcsize,fp);
if (length == pcsize)
{
UltraDownload(pcbuffer,sound->dmode,dramloc,length,TRUE);
dramloc += length;
total += length;
}
else
break;
}
/* Send amount left over */
if (remaining != 0)
{
length = fread(pcbuffer,1,remaining,fp);
if (length == remaining)
{
UltraDownload(pcbuffer,sound->dmode,dramloc,length,TRUE);
dramloc += length;
total += length;
}
}
return(total);
}
void
main(argc,argv)
int argc;
char *argv[];
{
FILE *fp;
int i;
int key_char;
int done;
ULTRA_CFG config;
SOUND_3D sound_3d;
void far *buffer;
int val;
int new_xpos,new_zpos;
int last_x,last_z;
unsigned int temp_it;
char filename[80];
int x_pos,z_pos,x_pos2,z_pos2,buttons;
unsigned long memloc;
unsigned long middle;
unsigned long where;
unsigned long length;
int first_buff = TRUE;
int first_track;
if (argc < 2)
{
usage();
printf("\nYou need to specify a file to play.\n");
exit(-1);
}
strcpy(filename,argv[argc-1]);
fp = fopen(filename,"rb");
if (fp == NULL)
{
printf("Unable to open %s\n",filename);
exit(-1);
}
/* Get the ULTRASND environment string parameters */
UltraGetCfg(&config);
if (UltraProbe(config.base_port) == NO_ULTRA)
{
printf("No card found\n");
exit(-1);
}
if (UltraOpen(&config,28) == NO_ULTRA)
{
printf("No card found\n");
exit(-1);
}
/* allocate memory in PC AND UltraSound */
buffer = malloc((unsigned int)BSIZE);
if (buffer == NULL)
{
printf("Unable to get PC memory\n");
goto done1;
}
val = UltraSetup3dInterleave(&sound_3d,filename,(long)ULTRA_BSIZE);
if (val != ULTRA_OK)
{
printf("Couldn't load 3d interleaved sound file. Err code %d\n",val);
goto failure;
}
/* Now prime the buffer with data from file */
fseek(fp,(long)sizeof(FILEHDR_3D),0);
for (i=0;i<6;i++)
{
if (sound_3d.vdata[i].voicenum != -1)
{
first_track = sound_3d.vdata[i].voicenum;
memloc = sound_3d.vdata[i].start;
break;
}
}
middle = memloc + ULTRA_BSIZE/2L;
/* Prime the buffer with data */
length = load_dram(fp,&sound_3d,memloc,ULTRA_BSIZE,BSIZE,buffer);
if (length != ULTRA_BSIZE)
{
printf("Not enough data\n");
goto done1;
}
UltraEnableOutput();
read_joystick(&x_pos,&z_pos,&x_pos2,&z_pos2,&buttons);
last_x = left_x = right_x = center_x = x_pos;
last_z = fwrd_z = back_z = center_z = z_pos;
/* Start the sound */
UltraStart3d(&sound_3d);
where = memloc;
done = FALSE;
while (!done)
{
if( fast_kbhit() ) /* Exit when a key is hit */
{
key_char = getch(); /* read the character */
done = TRUE;
break;
}
read_joystick(&x_pos,&z_pos,&x_pos2,&z_pos2,&buttons);
if (x_pos < center_x )
{
if (x_pos < left_x)
left_x = x_pos;
}
else
{
if (x_pos > right_x)
right_x = x_pos;
}
if (z_pos < center_z )
{
if (z_pos < fwrd_z)
fwrd_z = z_pos;
}
else
{
if (z_pos > back_z)
back_z = z_pos;
}
new_xpos = 0;
new_zpos = 0;
temp_it = abs((x_pos - center_x))<<8;
if (x_pos > center_x)
{
new_xpos = temp_it/(right_x-center_x+1);
}
else
{
new_xpos = -1*(temp_it/(center_x-left_x+1));
}
temp_it = abs(z_pos - center_z)<<8;
if (z_pos > center_z)
{
new_zpos = -1*(temp_it/(back_z-center_z+1));
}
else
{
new_zpos = temp_it/(center_z-fwrd_z+1);
}
printf("%03d %03d \r",new_xpos,new_zpos);
if ((abs(new_xpos-last_x) > 3) || (abs(new_zpos-last_z) > 3))
UltraAbsPosition3d(&sound_3d,new_xpos,0,new_zpos);
last_x = new_xpos;
last_z = new_zpos;
if (!(buttons & 0x10))
{
UltraStart3d(&sound_3d);
}
/* See if we need more data */
where = UltraReadVoice(first_track);
/* Are we waiting for first half to finish playing ? */
if (first_buff) /* yes */
{
if (where > middle)
{
/* fill in first half */
length = load_dram(fp,&sound_3d,memloc,ULTRA_BSIZE/2L,BSIZE,buffer);
if (length != ULTRA_BSIZE/2L)
{
done = TRUE;
}
first_buff = FALSE; /* now looking at second buff */
}
}
else /* how about second */
{
if (where < middle) /* has it looped back to beginning? */
{
/* fill in second half ... */
length = load_dram(fp,&sound_3d,middle,ULTRA_BSIZE/2L,BSIZE,buffer);
if (length != ULTRA_BSIZE/2L)
{
done = TRUE;
}
first_buff = TRUE; /* now looking at second buff */
}
}
}
/* Stop the sound */
UltraStop3d(&sound_3d,FALSE);
/* Free up resources */
UltraRelease3dInterleave(&sound_3d);
failure:
free(buffer);
done1:
/* close 3D sound track */
fclose(fp);
/* Shut sound down & re-init hardware ... */
UltraClose();
}