cMatrixStack::cMatrixStack(uintf MaxLevels, char *StackName, byte *buf)
{	if (buf==NULL)
	{	char reason[256];
		uintf memneeded = sizeof(sMatrixStackLevel) * MaxLevels + txtlen(StackName)+1;
		tprintf(reason,sizeof(reason),"Matrix Stack: %s",StackName);
		buf = fcalloc(memneeded,reason);
		flags = 1;
	}	else
	{	flags = 0;
	}
	level	= (sMatrixStackLevel *)buf;		buf += sizeof(sMatrixStackLevel) * MaxLevels;
	name	= (char *)buf;		buf += txtlen(StackName)+1;
	levels = MaxLevels;
	txtcpy(name,StackName,txtlen(StackName)+1);
	for (uintf i=0; i<levels; i++)
	{	level[i].parent = 0;
		level[i].pivot.x = 0;
		level[i].pivot.y = 0;
		level[i].pivot.z = 0;
		level[i].rotx = 0;
		level[i].roty = 0;
		level[i].rotz = 0;
		makeidentity(level[i].mtx);
		level[i].current = 1;
	}
	level[0].current = 1;
}
Esempio n. 2
0
fchandle *
fcopen(void)
{
    fchandle fctemp, *fcp;	/* It takes a handle to allocate a handle */

    fctemp.FreeChain = NULL;			/* Nothing to free (yet) */
    fcp = fcalloc(&fctemp, sizeof(fchandle));	/* Allocate new handle */
    fcp->FreeChain = fctemp.FreeChain;		/* Free self last */
    return fcp;
}
Esempio n. 3
0
/** @brief creates a new string_list
 * @return 0 if the creation was a success
 **/
int string_list_new(string_list** servers)
{
    if(((*servers) = (string_list*) fmalloc(sizeof(string_list))) == NULL)
        return 1;
    (*servers)->max_size = SERVER_LIST_DEFAULT_MAX_SIZE;
    (*servers)->size = 0;
    if(((*servers)->array = fcalloc((*servers)->max_size, sizeof(char*)))
            == NULL)
        return 2;
    return 0;
}
Esempio n. 4
0
/**
 * @brief adds a string to the servers list
 * @return 0 if adding was successfull
 **/
int string_list_add(string_list** servers, char* string)
{
    char* str;
    if((*servers) == NULL && string_list_new(servers))
        return 1;
    if((*servers)->size >= (*servers)->max_size &&
            string_list_resize(servers))
        return 2;
    if((str = (char*) fcalloc(strlen(string) + 1, sizeof(char))) == NULL)
        return 3;
    (*servers)->array[(*servers)->size] = str;
    strcpy((*servers)->array[(*servers)->size], string);
    (*servers)->size++;
    return 0;
}
char *ferite_function_generate_sig_string( FeriteScript *script, FeriteFunction *f )
{
	int argcount = 0, i = 0;
	char *str = NULL;
	
	FE_ENTER_FUNCTION;
	
	if( f != NULL )
	{
		argcount = f->arg_count;
		str = fcalloc( argcount+1, sizeof(char) );
		for( i = 0; i < argcount; i++ )
		{
			if( f->signature[i]->is_dots ) {
				str[i] = 'E';
			} else {
				switch( F_VAR_TYPE(f->signature[i]->variable) )
				{
				  case F_VAR_LONG:
				  case F_VAR_DOUBLE:
					str[i] = 'n';
					break;
				  case F_VAR_STR:
					str[i] = 's';
					break;
				  case F_VAR_OBJ:
					str[i] = 'o';
					break;
				  case F_VAR_UARRAY:
					str[i] = 'a';
					break;
				  case F_VAR_VOID:
					str[i] = 'v';
					break;
				  case F_VAR_BOOL:
					str[i] = 'b';
					break;
				}
			}
		}
		str[i++] = '\0'; 
	}
	FE_LEAVE_FUNCTION( str );
}
Esempio n. 6
0
/**
 * @function ferite_str_new
 * @declaration FeriteString *ferite_str_new( char *str, int length, int encoding )
 * @brief Create a new string with exisitng data and encoding
 * @param FeriteScript *script The script context
 * @param char *str The data to use
 * @param int length The length of the data, if it is 0, strlen() is called on the data.
 * @param int encoding The encoding to use, if you are not sure use FE_CHARSET_DEFAULT
 * @return A FeriteString containing the data
 */
FeriteString *ferite_str_new( FeriteScript *script, char *str, size_t length, int encoding )
{
    FeriteString *ptr;

    FE_ENTER_FUNCTION;
    ptr = fmalloc( sizeof( FeriteString ) );
    ptr->pos = -1;
    ptr->encoding = encoding;

    if( str == NULL || *str == '\0' )
    {
        ptr->data = fcalloc( length + 1, sizeof(char) );
    }
    else
    {
        if(length == 0)
          length = strlen( str );
        ptr->data = fmalloc( length + 1 );
        memcpy( ptr->data, str, length );
        ptr->data[length] = '\0';
    }
    ptr->length = length;
    FE_LEAVE_FUNCTION( ptr );
}
sRenderTarget3D *new3DRenderTarget(intf width, intf height, uintf flags)	// Creates the texture and fills in the rt pointer with valid data to make the render target usable.  Flags - set to 0 for now, in the future, you will be able to enable/disable Z buffer, stencil, etc.  Setting to 0 enables a basic Z buffer and no stencil.
{	sRenderTarget3D *result;
	result = (sRenderTarget3D *)fcalloc(sizeof(sRenderTarget3D),"3D Render Target");
	vd_create3DRenderTarget(result,width,height,flags);
	return result;
}
Esempio n. 8
0
/* ===========================================================================
 * Initialize the "longest match" routines for a new file
 *
 * IN assertion: deflate_window_size is > 0 if the input file is already read or
 *    mmap'ed in the window[] array, 0 otherwise. In the first case,
 *    deflate_window_size is sufficient to contain the whole input file plus
 *    MIN_LOOKAHEAD bytes (to avoid referencing memory beyond the end
 *    of window[] when looking for matches towards the end).
 */
void lm_init (int pack_level, ush *flags)
                    /* 0: store, 1: best speed, 9: best compression */
                    /* general purpose bit flag */
{
    register unsigned j;

    if (pack_level < 1 || pack_level > 9) error("bad pack level");

    /* Do not slide the window if the whole input is already in memory
     * (deflate_window_size > 0)
     */
    sliding = 0;
    if (deflate_window_size == 0L) {
        sliding = 1;
        deflate_window_size = (ulg)2L*WSIZE;
    }

    /* Use dynamic allocation if compiler does not like big static arrays: */
#ifdef DYN_ALLOC
    if (window == NULL) {
        window = (uch*) fcalloc(WSIZE,   2*sizeof(uch));
        if (window == NULL) err(ZE_MEM, "window allocation");
    }
    if (prev == NULL) {
        prev   = (Pos*) fcalloc(WSIZE,     sizeof(Pos));
        head   = (Pos*) fcalloc(HASH_SIZE, sizeof(Pos));
        if (prev == NULL || head == NULL) {
            err(ZE_MEM, "hash table allocation");
        }
    }
#endif /* DYN_ALLOC */

    /* Initialize the hash table (avoiding 64K overflow for 16 bit systems).
     * prev[] will be initialized on the fly.
     */
    head[HASH_SIZE-1] = NIL;
    memset(head, NIL, (HASH_SIZE-1)*sizeof(*head));

    /* Set the default configuration parameters:
     */
    max_lazy_match   = configuration_table[pack_level].max_lazy;
    good_match       = configuration_table[pack_level].good_length;
#ifndef FULL_SEARCH
    nice_match       = configuration_table[pack_level].nice_length;
#endif
    max_chain_length = configuration_table[pack_level].max_chain;
    if (pack_level == 1) {
       *flags |= FAST;
    } else if (pack_level == 9) {
       *flags |= SLOW;
    }
    /* ??? reduce max_chain_length for binary files */

    deflate_strstart = 0;
    deflate_block_start = 0L;
#ifdef ASMV
    match_init(); /* initialize the asm code */
#endif

    j = WSIZE;
#ifndef MAXSEG_64K
    if (sizeof(int) > 2) j <<= 1; /* Can read 64K in one step */
#endif
    lookahead = (*bits_read_buf)(window, j);

    if (lookahead == 0 || lookahead == (unsigned) EOF) {
       eofile = 1, lookahead = 0;
       return;
    }
    eofile = 0;
    /* Make sure that we always have enough lookahead. This is important
     * if input comes from a device such as a tty.
     */
    while (lookahead < MIN_LOOKAHEAD && !eofile) fill_window();

    ins_h = 0;
    for (j=0; j<MIN_MATCH-1; j++) UPDATE_HASH(ins_h, window[j]);
    /* If lookahead < MIN_MATCH, ins_h is garbage, but this is
     * not important since only literal bytes will be emitted.
     */
}
Esempio n. 9
0
static Value* allocValue(VALTYPE type) {
	Value* ret = fcalloc(1, sizeof(*ret));
	ret->type = type;
	return ret;
}
bool netserver::listen(void)
{	long retval;
	if (connectionerror) return false;
	netserveroem *oem = (netserveroem *) oemdata; 
	oem->fromlen =sizeof(oem->from);
//	SOCKET msgsock;
	
	// accept() doesn't make sense on UDP, since we do not listen()
	if (oem->socket_type != SOCK_DGRAM) 
	{	oem->msgsock = accept(oem->listen_socket,(struct sockaddr*)&oem->from, &oem->fromlen);
		if (oem->msgsock == INVALID_SOCKET) 
		{	fprintf(stderr,"accept() error %d\n",WSAGetLastError());
			connectionerror = net_acceptfailed;
			return false;
		}
		//printf("accepted connection from %s, port %d\n", inet_ntoa(from.sin_addr), htons(from.sin_port)) ;
	}
	else
		oem->msgsock = oem->listen_socket;

	// In the case of SOCK_STREAM, the server can do recv() and 
	// send() on the accepted socket and then close it.
	// However, for SOCK_DGRAM (UDP), the server will do
	// recvfrom() and sendto()  in a loop.
	if (oem->socket_type != SOCK_DGRAM)
	{	// TCP
		retval = recv(oem->msgsock,(char *)oem->Buffer,sizeof(oem->Buffer),0 );
	}
	else 
	{	// UDP
		retval = recvfrom(oem->msgsock,(char *)oem->Buffer,sizeof(oem->Buffer),0,(struct sockaddr *)&oem->from,&oem->fromlen);
		//printf("Received datagram from %s\n",inet_ntoa(from.sin_addr));
	}

	if (retval == SOCKET_ERROR) 
	{	//fprintf(stderr,"recv() failed: error %d\n",WSAGetLastError());
		//closesocket(oem->msgsock);
		//con->add("recv() failed: error :%d",WSAGetLastError());
		return false;
	}

	if (retval == 0) 
	{	//printf("Client closed connection\n");
		//closesocket(oem->msgsock);
		return false;
	}
		
	char response[256];
	if (acceptconnections && (retval == requesttxtlen+9))
	{	if (strncmp((char *)oem->Buffer,requeststring,requesttxtlen)==0)
		//if (strncmp((char *)oem->Buffer,requeststring,requesttxtlen-9)==0)
		{	// We have a new net connection!
			netconnection *nc = oem->freeconnections;
			if (nc)
			{	oem->freeconnections = nc->next;
				if (oem->freeconnections) 
				{	oem->freeconnections->last = NULL;
				}
				nc->next = firstconnection;
				nc->last = NULL;				
				if (firstconnection)
				{	firstconnection->last = nc;
				}
				firstconnection = nc;
				numconnections++;
				netconnectionoem *conoem = (netconnectionoem *)fcalloc(sizeof(netconnectionoem),"Network Server Connection");
				firstconnection->oemdata = (void *)conoem;
				conoem->ClientIP = oem->from;
				// Calculate bandwidth
				char *bwptr = (char *)(oem->Buffer + requesttxtlen);
				long i=0;
				while (bwptr[i]!=0 && bwptr[i]==' ')
				{	i++;
				}
				bwptr += i;
				dword bw = 0;
				while (*bwptr)
				{	bw <<= 4;
					char tmp = (toupper)(*bwptr++);
					switch(tmp)
					{	case '0':	bw+=0; break;
						case '1':	bw+=1; break;
						case '2':	bw+=2; break;
						case '3':	bw+=3; break;
						case '4':	bw+=4; break;
						case '5':	bw+=5; break;
						case '6':	bw+=6; break;
						case '7':	bw+=7; break;
						case '8':	bw+=8; break;
						case '9':	bw+=9; break;
						case 'A':	bw+=10; break;
						case 'B':	bw+=11; break;
						case 'C':	bw+=12; break;
						case 'D':	bw+=13; break;
						case 'E':	bw+=14; break;
						case 'F':	bw+=15; break;
					}
				}
//				con->add("Bandwidth = %i",bw*8);
				if (nc->init(default_receiver,bw))
				{	if (new_connection)
						new_connection(nc);
					return true;
				}
				else
					strcpy(response,"ConnectionFailed");
			}
			else
				strcpy(response,"ServerFull");
			netsend(oem->msgsock,oem->from,(byte *)response,txtlen(response));
			return true;
		}
	}

	// It was not a new connection request - must be a data packet from an existing connection
	if (default_receiver)
	{	default_receiver(NULL,oem->Buffer,retval);
	}
	sprintf(response,"Error: %s",oem->Buffer);
	netsend(oem->msgsock,oem->from,(byte *)response,txtlen(response)+1);
	return true;
}
netserver::netserver(bool reliable, char *_requeststring, long _maxconnections, long portnumber,dword bandwidth,
					 void (*newconnection)(netconnection *), void (*defaultreceiver)(netconnection *,byte *,long))
{	reliable = false;
	if (_maxconnections<1)
	{	connectionerror = net_toofewconnections;
		return;
	}

	if (!serverok)
	{	connectionerror = net_tcpipna;
		return;
	}
	netserveroem *oem = (netserveroem *)fcalloc(sizeof(netserveroem),"Network Server Buffers");
	oemdata = (void *)oem;
	if (reliable) oem->socket_type = SOCK_STREAM;	// TCP
			else  oem->socket_type = SOCK_DGRAM;	// UDP
	requeststring = _requeststring;
	requesttxtlen = txtlen(requeststring);
	maxconnections = _maxconnections;
	oem->port = (word)portnumber;

	numconnections = 0;
	oem->freeconnections = NULL;
	firstconnection = NULL;

	oem->connectionlookup = (netconnection **)malloc(maxconnections * ptrsize);
	for (long i=0; i<maxconnections; i++)
	{	netconnection *nc = oem->freeconnections;
		oem->freeconnections = new netconnection();
		oem->freeconnections->connection_num = (word)i;
		oem->freeconnections->parent = this;
		oem->connectionlookup[i] = oem->freeconnections;
		oem->freeconnections->next = nc;
		oem->freeconnections->last = NULL;
		if (nc) nc->last = oem->freeconnections;
	}

	oem->listen_socket = socket(AF_INET, oem->socket_type,0); 
	if (oem->listen_socket == INVALID_SOCKET)
	{	//fprintf(stderr,"socket() failed with error %d\n",WSAGetLastError());
		connectionerror = net_opensocketerror;
		return;
	}

	// bind() associates a local address and port combination with the
	// socket just created. This is most useful when the application is a 
	// server that has a well-known port that clients know about in advance.
	oem->local.sin_family = AF_INET;
	oem->local.sin_addr.s_addr = INADDR_ANY;
	oem->local.sin_port = htons(oem->port);
	if (bind(oem->listen_socket,(struct sockaddr*)&oem->local,sizeof(oem->local) ) != 0) 
	{	//fprintf(stderr,"bind() failed with error %d\n",WSAGetLastError());
		connectionerror = net_bindfailed;
		return;
	}

	// So far, everything we did was applicable to TCP as well as UDP.
	// However, there are certain steps that do not work when the server is
	// using UDP.
	u_long argp = 1;
	if (ioctlsocket(oem->listen_socket,FIONBIO,&argp))
	{	connectionerror = net_ioctlfailed;
		return;
	}

	// We cannot listen() on a UDP socket.
	if (oem->socket_type != SOCK_DGRAM) 
	{	if (::listen(oem->listen_socket,5) == SOCKET_ERROR) 
		{	//fprintf(stderr,"listen() failed with error %d\n",WSAGetLastError());
			connectionerror = net_listenfailed;
			return;
		}
	}
	//printf("'Listening' on port %d, protocol %s\n",port,(socket_type == SOCK_STREAM)?"TCP":"UDP");
	default_receiver = defaultreceiver;
	new_connection = newconnection;
	connectionerror = 0;
	acceptconnections = true;
}
netclient::netclient(bool reliable,char *requeststring,char *host,word port,dword bandwidth,void (*_receiver)(netclient *client,byte packettype,byte *data,long size))
{	reliable = false;

	if (!clientok)
	{	connectionerror = net_tcpipna;
		return;
	}
	receiver = _receiver;
	netclientoem *oem = (netclientoem *)fcalloc(sizeof(netclientoem),"Network Client Connection");
	oemdata = oem;

	if (reliable) oem->socket_type = SOCK_STREAM;	// TCP
			else  oem->socket_type = SOCK_DGRAM;	// UDP

	// Attempt to detect if we should call gethostbyname() or gethostbyaddr()
	if (isalpha(host[0])) 
	{   // server address is a name
		oem->host = gethostbyname(host);
	}	else  
	{	// Convert nnn.nnn address to a usable one
		dword addr = inet_addr(host);
		oem->host = gethostbyaddr((char *)&addr,4,AF_INET);
	}
	if (oem->host == NULL ) 
	{	//con->add("Client: Cannot resolve address [%s]: Error %d\n",host,WSAGetLastError());
		connectionerror = net_cantresolveaddr;
		return;
	}

	oem->conn_socket = socket(AF_INET,oem->socket_type,0); // Open a socket
	if (oem->conn_socket <0 ) 
	{	//con->add("Client: Error Opening socket: Error %d\n",WSAGetLastError());
		connectionerror = net_opensocketerror;
		return;
	}

	u_long argp = 1;
	if (ioctlsocket(oem->conn_socket,FIONBIO,&argp))
	{	connectionerror = net_ioctlfailed;
		closesocket(oem->conn_socket);
		return;
	}

	//
	// Notice that nothing in this code is specific to whether we 
	// are using UDP or TCP.
	// We achieve this by using a simple trick.
	//    When connect() is called on a datagram socket, it does not 
	//    actually establish the connection as a stream (TCP) socket
	//    would. Instead, TCP/IP establishes the remote half of the
	//    ( LocalIPAddress, LocalPort, RemoteIP, RemotePort) mapping.
	//    This enables us to use send() and recv() on datagram sockets,
	//    instead of recvfrom() and sendto()

	//
	// Copy the resolved information into the sockaddr_in structure
	//
	sockaddr_in server;
	memfill(&server,0,sizeof(server));
	memcpy(&server.sin_addr,oem->host->h_addr,oem->host->h_length);
	server.sin_family = oem->host->h_addrtype;
	server.sin_port = htons(port);	// Port Number
//dword ip = *(dword *)oem->host->h_addr;
//con->add("server IP = %i.%i.%i.%i, Port %i",(ip)&0xff,(ip>>8)&0xff,(ip>>16)&0xff,(ip>>24)&0xff,port);

	long retval = WSAEWOULDBLOCK;
	while (retval==WSAEWOULDBLOCK)
	{	checkmsg();
		retval = connect(oem->conn_socket,(struct sockaddr*)&server,sizeof(server));
		if (retval == SOCKET_ERROR) 
		{	connectionerror = net_connectfailed;
			closesocket(oem->conn_socket);
			return;
		}
	}

	// Send initial request for a connection
	char *constring = buildstr("%s%8x",requeststring,bandwidth);
	retval = WSAEWOULDBLOCK;
	while (retval==WSAEWOULDBLOCK)
	{	checkmsg();
//con->add("Send '%s' on Socket %i",requeststring,oem->conn_socket);
//		retval = send(oem->conn_socket,requeststring,txtlen(requeststring)+1,0);
		retval = send(oem->conn_socket,constring,txtlen(constring)+1,0);
		if (retval == SOCKET_ERROR) 
		{	connectionerror = net_hostlogin;
			closesocket(oem->conn_socket);
			return;
		}
	}
		
	retval = WSAEWOULDBLOCK;
	dword timeouttime = globalTimer + currentTimerHz * 2;
	while ((globalTimer<timeouttime) && (retval == WSAEWOULDBLOCK))
	{	checkmsg();
		retval = recv(oem->conn_socket,(char *)&oem->Buffer[0],sizeof(oem->Buffer),0 );
		if (retval == SOCKET_ERROR) 
		{	retval = WSAEWOULDBLOCK;
			//connectionerror = net_hostresponse;
			//closesocket(oem->conn_socket);
			//return;
		}
		if (retval == 0) 
		{	retval = WSAEWOULDBLOCK;
		}
	}
	
	if (globalTimer>=timeouttime)
	{	connectionerror = net_timeout;
		closesocket(oem->conn_socket);
		return;
	}

	//con->add("Server says: %s\n",Buffer);
	long ofs = 0;
	char sep;
	char *token;
	token = gettoken((char *)oem->Buffer,&ofs,&sep);
	connectionerror = net_invalidresponse;
	if (txtcmp(token,"ServerFull")==0) connectionerror = net_serverfull;
	if (txtcmp(token,"ConnectionFailed")==0) connectionerror = net_servererror;
	if (txtcmp(token,"ConnectionGranted")==0) 
	{	port = (word)getuinttoken((char *)oem->Buffer,&ofs,&sep);
		oem->refnum = port;
		connectionerror = 0;
		return;
	}

//	con->add("%s",oem->Buffer);
//	con->add("Token = '%s', buffer = %s, length = %i",""/*token*/,oem->Buffer,retval);
//	con->add("Expected ConnectionGranted");
	closesocket(oem->conn_socket);	// ERROR ONLY! This line is not executed during normal execution
}
void initWinMM(void)
{   WAVEFORMATEX	wfe;		// Format of the mixing buffers we will be sending to the audio hardware to play
	MMRESULT		mmr;		// Temporary container to hold the result of Multimedia function calls

	audioLog->log("Initializing WinMM Sound System");
	int numDevs = waveOutGetNumDevs();	    // Retrieve the number of multimedia sound playing devices in the system
	audioLog->log("%i WaveOut devices detected\n",numDevs);
	if (numDevs==0) return;					// No audio devices detected, or an error occured
    audioNumSpeakers = 2;
	WinMM_mixFreq = 44100;
	uint16	sampleSize = 2 * audioNumSpeakers;	// 16 bit stereo  (16 bits * number of speakers)
	bufferSizeBytes = WinMM_mixFreq*sampleSize*BUFFERSIZE/1000;	// Calculate the size of the buffers in BYTES
	bufferSizeSamples = WinMM_mixFreq*BUFFERSIZE/1000;			// Calculate the size of the buffers in SAMPLES

    initSWAudioMixer(WinMM_mixFreq,bufferSizeSamples,16,audioNumSpeakers);

	wfe.wFormatTag = WAVE_FORMAT_PCM;		// We are genertating uncompressed Pulse-Code Modulation ...
	wfe.nChannels = audioNumSpeakers;		// In stereo (2 channels)
	wfe.nSamplesPerSec=WinMM_mixFreq;		// at 44 Khz
	wfe.nAvgBytesPerSec=WinMM_mixFreq * sampleSize;	// Consuming 44100 * 4 bytes per second
	wfe.nBlockAlign=sampleSize;				// 1 block = size of each sample * number of channels
	wfe.wBitsPerSample=16;					// 16 bit audio
	wfe.cbSize=0;							// size of extensible data ... plain PCM is fine, no extensible data needed

	// Open a handle to the WaveOut device (like files, we must open a device before accessing it)
	mmr=waveOutOpen( &WinMM_hwaveout,		// &hwaveout points to where we want to store the handle to the WaveOut device
					 WAVE_MAPPER,			// We want the system's DEFAULT playback device (you should ALWAYS use this device)
					 &wfe,					// Points to the format description of the sound we will be playing
					 (DWORD_PTR)WinMM_CallBack, // Points to the function to call when we finish playing a buffer
					 0,						// A number we send to the callback function, can be anything we like
					 CALLBACK_FUNCTION);	// What special features of playback do we require ... only one: call our callback function
	if (mmr!=MMSYSERR_NOERROR)
	{	audioError("waveOutOpen",mmr);	// Report any error that occured
		return;
	}

	byte *tmp = (byte *)fcalloc(bufferSizeBytes*2,"WinMM Audio Buffers");
	for (int i=0; i<2; i++)		// For each buffer (there will only ever be 2 buffers)
	{	WinMM_buffer[i] = tmp + bufferSizeBytes * i;						// Allocate memory for buffer
		memfill(WinMM_buffer[i], 0, bufferSizeBytes);						// Fill the buffer with silence
		WinMM_header[i].lpData = (LPSTR)WinMM_buffer[i];					// Tell the header where the buffer is located
		WinMM_header[i].dwBufferLength = bufferSizeBytes;					// Tell the header the size of the buffer
		mmr=waveOutPrepareHeader(WinMM_hwaveout,&WinMM_header[i],sizeof(WAVEHDR));	// Prepare the header (Make the sound system aware that it will need to play this type of sound)
		if (mmr!=MMSYSERR_NOERROR)
		{	audioError("waveOutOpen",mmr);						// Report any errors
			return;
		}
	}
	nextBuffer=0;														// The next buffer to process is buffer #0

	audioSemaphore = 0;									// Tell the system it's save to receive hardware interrupts

	// Force sound system to start playing sounds (Sound begins playing the moment the first buffer is written to the device)
	mmr=waveOutWrite(WinMM_hwaveout,&WinMM_header[0],sizeof(WAVEHDR));	// Write the first buffer (will be silent)
	if (mmr!=MMSYSERR_NOERROR)
	{	audioError("waveOutWrite",mmr);						// Report any errors
		return;
	}
	mmr=waveOutWrite(WinMM_hwaveout,&WinMM_header[1],sizeof(WAVEHDR));	// Write the second buffer (will be silent)
	if (mmr!=MMSYSERR_NOERROR)
	{	audioError("waveOutWrite",mmr);						// Report any errors
		return;
	}

}