Archival snapshot of the Virtual World Entertainment Tesla cockpit software, 1994-1996: MUNGA engine and L4 pod layer source (Borland C++ 5.0), BT/RP game code, and game content (models, audio, maps, gauges, Division renderer data). Includes third-party libraries: Division dVS/DPL graphics, HMI SOS audio, WATTCP networking. Files are preserved byte-for-byte (.gitattributes disables all line-ending conversion). README.md documents the layout, target hardware, and toolchain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
459 lines
12 KiB
C++
459 lines
12 KiB
C++
/****************************************************************************
|
|
|
|
File : sosmawe.c
|
|
|
|
Purpose : Module to handle AWE32 .SBK file uploads
|
|
|
|
Date : 1-20-95
|
|
|
|
Programmer(s) : Don Fowler
|
|
|
|
Last Updated : 1-29-95
|
|
|
|
****************************************************************************
|
|
Copyright(c) 1992,1995 Human Machine Interfaces
|
|
All Rights Reserved
|
|
****************************************************************************/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <dos.h>
|
|
#include <fcntl.h>
|
|
#include <bios.h>
|
|
#include <io.h>
|
|
#include <malloc.h>
|
|
#include <conio.h>
|
|
#include <ctype.h>
|
|
#include "sosm.h"
|
|
#include "sosmawe.h"
|
|
|
|
// maximum number of .SBK files that can be set on the chip
|
|
#define _MAX_SBKS 0x10
|
|
|
|
// offset into slot list for .SBK files to start
|
|
#define _SBK_SLOT_OFFSET 0x01
|
|
|
|
// size of buffer needed to read in a chunk of .SBK file
|
|
#define _READ_BUFFER_SIZE 0x2000
|
|
|
|
// pointer to preset data for awe32
|
|
#ifdef __BORLANDC__
|
|
PSTR _lpSOSMIDIAwe32PresetBuffer[ _SOS_MIDI_MAX_DRIVERS ][ _MAX_SBKS ] = {
|
|
#else
|
|
LPSTR _lpSOSMIDIAwe32PresetBuffer[ _SOS_MIDI_MAX_DRIVERS ][ _MAX_SBKS ] = {
|
|
#endif
|
|
|
|
{ _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL,
|
|
_NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL },
|
|
{ _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL,
|
|
_NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL },
|
|
{ _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL,
|
|
_NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL },
|
|
{ _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL,
|
|
_NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL },
|
|
{ _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL,
|
|
_NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL, _NULL }
|
|
|
|
};
|
|
|
|
// index into list of presets to the currently available slot,
|
|
// start the index at 0 to leave slot 0 open for general midi
|
|
// rom on the AWE32
|
|
WORD _wSOSMIDIAwe32PresetIndex[ _SOS_MIDI_MAX_DRIVERS ] = {
|
|
|
|
_SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET,
|
|
_SBK_SLOT_OFFSET, _SBK_SLOT_OFFSET
|
|
};
|
|
|
|
/***************************************************************************
|
|
|
|
Function : WORD sosMIDIAWE32SetSBKFile
|
|
|
|
Parameters : WORD hDriver
|
|
Handle of SOS driver to set SBK file on.
|
|
PSTR szFileName
|
|
Name of .SBK file to set.
|
|
|
|
Returns : -1 if error; otherwise, slot that the .SBK file was
|
|
assigned to on the AWE32.
|
|
|
|
Description : Stream a .SBK file onto the awe32 and return the slot
|
|
streamed to.
|
|
|
|
****************************************************************************/
|
|
|
|
#pragma warn -def
|
|
#pragma warn -sus
|
|
#pragma warn -pia
|
|
|
|
WORD sosMIDIAWE32SetSBKFile( WORD hDriver, const char *szFileName )
|
|
{
|
|
WORD wIndex;
|
|
WORD hFile;
|
|
WORD wReadSize;
|
|
PSTR pDataPtr;
|
|
#ifdef __BORLANDC__
|
|
SFAR lpTemp;
|
|
#endif
|
|
|
|
// attempt to find a slot to use for the .SBK file
|
|
if( _wSOSMIDIAwe32PresetIndex[ hDriver ] == ( _MAX_SBKS - 1 ) )
|
|
return( -1 );
|
|
|
|
// attempt to open the sbk file
|
|
if( ( hFile = open( ( const char * )szFileName, O_RDONLY | O_BINARY ) ) == -1 )
|
|
return( -2 );
|
|
|
|
// attempt to allocate a buffer to use for transfer
|
|
if( ( pDataPtr = ( PSTR )malloc( _READ_BUFFER_SIZE ) ) == NULL )
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// return an error
|
|
return( -3 );
|
|
}
|
|
|
|
// open the awe32 stream
|
|
#ifdef __BORLANDC__
|
|
if( ( wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 5 ],
|
|
lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#else
|
|
if( ( wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 5 ]( _NULL,
|
|
_wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#endif
|
|
{
|
|
// free the previously allocated memory
|
|
free( pDataPtr );
|
|
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// return error
|
|
return( -4 );
|
|
}
|
|
|
|
// read in a chunk of data from the file
|
|
if( read( hFile, pDataPtr, wReadSize ) == -1 )
|
|
return( -5 );
|
|
|
|
// get the sample data seek location
|
|
#ifdef __BORLANDC__
|
|
lpTemp.sel = getDS();
|
|
lpTemp.off = pDataPtr;
|
|
if( ( wIndex = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 8 ],
|
|
lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#else
|
|
if( ( wIndex = _lpSOSMIDIDrvFunction[ hDriver ][ 8 ]( ( LPSTR )pDataPtr,
|
|
_wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#endif
|
|
{
|
|
// free the previously allocated memory
|
|
free( pDataPtr );
|
|
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// return error
|
|
return( -6 );
|
|
}
|
|
|
|
// seek the file to the sample location
|
|
if( lseek( hFile, wIndex, SEEK_SET ) == -1 )
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// free the preset memory
|
|
free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] );
|
|
|
|
// return an error
|
|
return( -7 );
|
|
}
|
|
|
|
// send chunks of data to the driver
|
|
do
|
|
{
|
|
// read in a chunk of data from the file
|
|
if( read( hFile, pDataPtr, wReadSize ) == -1 )
|
|
return( -8 );
|
|
|
|
// send the data to the driver
|
|
#ifdef __BORLANDC__
|
|
lpTemp.sel = getDS();
|
|
lpTemp.off = pDataPtr;
|
|
if( ( wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ]
|
|
[ 6 ], lpTemp, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#else
|
|
if( ( wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 6 ](
|
|
( LPSTR )pDataPtr, _wSOSMIDIAwe32PresetIndex[ hDriver ], 0x00 ) ) == -1 )
|
|
#endif
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// free the memory
|
|
free( pDataPtr );
|
|
|
|
// return an error
|
|
return( -9 );
|
|
}
|
|
} while( wReadSize );
|
|
|
|
// free the temporary memory buffer
|
|
free( pDataPtr );
|
|
|
|
// get the preset data size
|
|
#ifdef __BORLANDC__
|
|
wReadSize = sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 7 ],
|
|
lpTemp, 0x00, 0x00 );
|
|
#else
|
|
wReadSize = _lpSOSMIDIDrvFunction[ hDriver ][ 7 ]( _NULL, 0x00, 0x00 );
|
|
#endif
|
|
|
|
// get the preset location in the file
|
|
#ifdef __BORLANDC__
|
|
lpTemp.sel = getDS();
|
|
lpTemp.off = &wIndex;
|
|
sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ], lpTemp,
|
|
0x00, 0x00 );
|
|
#else
|
|
_lpSOSMIDIDrvFunction[ hDriver ][ 9 ]( ( LPSTR )&wIndex, 0x00, 0x00 );
|
|
#endif
|
|
|
|
// allocate the memory for the preset information
|
|
#ifdef __BORLANDC__
|
|
if( !( _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] =
|
|
( PSTR )malloc( wReadSize ) ) )
|
|
#else
|
|
if( !( _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] =
|
|
( LPSTR )malloc( wReadSize ) ) )
|
|
#endif
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// return an error
|
|
return( -10 );
|
|
}
|
|
|
|
// seek the file to the preset location
|
|
if( lseek( hFile, wIndex, SEEK_SET ) == -1 )
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// free the preset memory
|
|
free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] );
|
|
|
|
// return an error
|
|
return( -11 );
|
|
}
|
|
|
|
// read in the preset information
|
|
if( read( hFile, ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][
|
|
_wSOSMIDIAwe32PresetIndex[ hDriver ] ], wReadSize ) == -1 )
|
|
{
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// free the preset memory
|
|
free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] );
|
|
|
|
// return an error
|
|
return( -12 );
|
|
}
|
|
|
|
// send the preset information to the driver
|
|
#ifdef __BORLANDC__
|
|
lpTemp.sel = getDS();
|
|
lpTemp.off = _lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ];
|
|
if( ( sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 10 ],
|
|
lpTemp, 0x00, 0x00 ) ) == -1 )
|
|
#else
|
|
if( ( _lpSOSMIDIDrvFunction[ hDriver ][ 10 ]( ( LPSTR )
|
|
_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ], 0x00, 0x00 ) ) == -1 )
|
|
#endif
|
|
{
|
|
// free the preset memory
|
|
free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ _wSOSMIDIAwe32PresetIndex[ hDriver ] ] );
|
|
|
|
// close the file
|
|
close( hFile );
|
|
|
|
// return an error
|
|
return( -13 );
|
|
}
|
|
|
|
// close the SBK file
|
|
close( hFile );
|
|
|
|
// increment the preset buffer index to the next available slot
|
|
_wSOSMIDIAwe32PresetIndex[ hDriver ]++;
|
|
|
|
// return no error
|
|
return( _wSOSMIDIAwe32PresetIndex[ hDriver ] );
|
|
}
|
|
|
|
#pragma warn .def
|
|
#pragma warn .sus
|
|
#pragma warn .pia
|
|
|
|
/***************************************************************************
|
|
|
|
Function : WORD sosMIDIAWE32ReleaseAllSBKFiles
|
|
|
|
Parameters : WORD hDriver
|
|
Handle of SOS driver to release .SBK files from
|
|
|
|
Returns : -1 if error; otherwise, _ERR_NO_ERROR
|
|
|
|
Description : Release all of the memory associated to the .SBK files
|
|
uploaded to the awe32.
|
|
|
|
****************************************************************************/
|
|
|
|
#pragma warn -def
|
|
|
|
WORD sosMIDIAWE32ReleaseSBKFiles( WORD hDriver )
|
|
{
|
|
WORD wIndex;
|
|
#ifdef __BORLANDC__
|
|
SFAR lpTemp;
|
|
#endif
|
|
|
|
// call the driver to release all of the .SBK files
|
|
#ifdef __BORLANDC__
|
|
if( sosMIDIDRVCall32Func( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ], lpTemp,
|
|
0x01, 0x00 ) == -1 )
|
|
#else
|
|
if( _lpSOSMIDIDrvFunction[ hDriver ][ 9 ]( ( LPSTR )_NULL, 0x01, 0x00 )
|
|
== -1 )
|
|
#endif
|
|
return( -1 );
|
|
|
|
// free the memory allocated for the awe32 preset information
|
|
for( wIndex = _SBK_SLOT_OFFSET; wIndex < _wSOSMIDIAwe32PresetIndex[ hDriver ];
|
|
wIndex++ )
|
|
free( ( PSTR )_lpSOSMIDIAwe32PresetBuffer[ hDriver ][ wIndex ] );
|
|
|
|
// reset the available slot index
|
|
_wSOSMIDIAwe32PresetIndex[ hDriver ] = _SBK_SLOT_OFFSET;
|
|
|
|
// return no error
|
|
return( _ERR_NO_ERROR );
|
|
}
|
|
|
|
#pragma warn .def
|
|
|
|
/***************************************************************************
|
|
|
|
Function : WORD sosMIDIAWE32NoteOn
|
|
|
|
Parameters : WORD hDriver
|
|
Handle of SOS driver
|
|
WORD wSlot
|
|
.SBK file slot to associate patch to
|
|
WORD wChannel
|
|
Channel to use
|
|
WORD wPatch
|
|
Patch to use
|
|
WORD wNote
|
|
MIDI relative pitch to use
|
|
WORD wVelocity
|
|
Velocity to use
|
|
|
|
Returns : -1 if error; otherwise, _ERR_NO_ERROR
|
|
|
|
Description : Turn a note on
|
|
|
|
****************************************************************************/
|
|
|
|
#pragma warn -sig
|
|
|
|
WORD sosMIDIAWE32NoteOn( WORD hDriver, WORD wSlot, WORD wChannel,
|
|
WORD wPatch, WORD wNote, WORD wVelocity )
|
|
{
|
|
BYTE szMIDIData[ 0x10 ];
|
|
|
|
// setup the midi data structure to associate a slot to a channel
|
|
szMIDIData[ 0 ] = 0xb0 | wChannel;
|
|
szMIDIData[ 1 ] = 0x00;
|
|
szMIDIData[ 2 ] = wSlot;
|
|
#ifdef __BORLANDC__
|
|
sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x03 );
|
|
#else
|
|
sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x03 );
|
|
#endif
|
|
|
|
// select the patch for the channel
|
|
szMIDIData[ 0 ] = 0xc0 | wChannel;
|
|
szMIDIData[ 1 ] = wPatch;
|
|
#ifdef __BORLANDC__
|
|
sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x02 );
|
|
#else
|
|
sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x02 );
|
|
#endif
|
|
|
|
// turn the note on with the correct pitch and attack
|
|
szMIDIData[ 0 ] = 0x90 | wChannel;
|
|
szMIDIData[ 1 ] = wNote;
|
|
szMIDIData[ 2 ] = wVelocity;
|
|
#ifdef __BORLANDC__
|
|
sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x02 );
|
|
#else
|
|
sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x02 );
|
|
#endif
|
|
|
|
// return no error
|
|
return( _ERR_NO_ERROR );
|
|
}
|
|
|
|
#pragma warn .sig
|
|
|
|
/***************************************************************************
|
|
|
|
Function : WORD sosMIDIAWE32NoteOff
|
|
|
|
Parameters : WORD hDriver
|
|
Handle of SOS driver
|
|
WORD wChannel
|
|
Channel to use
|
|
WORD wNote
|
|
MIDI relative pitch to use
|
|
|
|
Returns : -1 if error; otherwise, _ERR_NO_ERROR
|
|
|
|
Description : Turn a note on
|
|
|
|
****************************************************************************/
|
|
|
|
#pragma warn -sig
|
|
|
|
WORD sosMIDIAWE32NoteOff( WORD hDriver, WORD wChannel, WORD wNote )
|
|
{
|
|
BYTE szMIDIData[ 0x10 ];
|
|
|
|
// turn the note off
|
|
szMIDIData[ 0 ] = 0x90 | wChannel;
|
|
szMIDIData[ 1 ] = wNote;
|
|
szMIDIData[ 2 ] = 0x00;
|
|
#ifdef __BORLANDC__
|
|
sosMIDISendMIDIData( hDriver, ( PSTR )szMIDIData, 0x03 );
|
|
#else
|
|
sosMIDISendMIDIData( hDriver, ( LPSTR )szMIDIData, 0x03 );
|
|
#endif
|
|
|
|
// return no error
|
|
return( _ERR_NO_ERROR );
|
|
}
|
|
|
|
#pragma warn .sig
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|