Annotation of src/teksnd.c, revision 1.1

1.1     ! root        1: 
        !             2: /***************************************************************************
        !             3:  *   TEKSND.C  - HMI library replaces Kens sound stuff                     *
        !             4:  *               Also timer routine and keytimerstuff is here              *
        !             5:  *                                                                         *
        !             6:  ***************************************************************************/
        !             7: 
        !             8: #include <sys\types.h>
        !             9: #include <sys\stat.h>
        !            10: #include <stdlib.h>
        !            11: #include <dos.h>
        !            12: #include "io.h"
        !            13: #include "fcntl.h"
        !            14: #include "string.h"
        !            15: #include "malloc.h"
        !            16: #include "build.h"
        !            17: #include "names.h"
        !            18: 
        !            19: #include "tekwar.h"
        !            20: 
        !            21: //#define   SNDDEBUG
        !            22: //#define     MUSICDEBUG
        !            23: 
        !            24: 
        !            25: #pragma pack(4)               // HMI structures must be packed !!
        !            26: 
        !            27: #define  AMBUPDATEDIST  4000L
        !            28: 
        !            29: #define  _NULL          0
        !            30: #define  VOID           void
        !            31: 
        !            32: typedef  int            BOOL;
        !            33: typedef  unsigned int   UINT;
        !            34: typedef  unsigned char  BYTE;
        !            35: typedef  unsigned       WORD;
        !            36: typedef  signed long    LONG;
        !            37: typedef  unsigned long  DWORD;
        !            38: 
        !            39: typedef  BYTE  *        PBYTE;
        !            40: typedef  char near *    PSTR;
        !            41: typedef  WORD  *        PWORD;
        !            42: typedef  LONG  *        PLONG;
        !            43: typedef  VOID  *        PVOID;
        !            44: 
        !            45: typedef  BYTE  far   *  LPBYTE;
        !            46: typedef  BYTE  far   *  LPSTR;
        !            47: typedef  WORD  far   *  LPWORD;
        !            48: typedef  LONG  far   *  LPLONG;
        !            49: typedef  VOID  far   *  LPVOID;
        !            50: 
        !            51: typedef  BYTE  huge  *  HPBYTE;
        !            52: typedef  BYTE  huge  *  HPSTR;
        !            53: typedef  WORD  huge  *  HPWORD;
        !            54: typedef  LONG  huge  *  HPLONG;
        !            55: typedef  VOID  huge  *  HPVOID;
        !            56: 
        !            57: #define  _TIMER_DOS_RATE   0xff00
        !            58: 
        !            59: #define  _SOS_DEBUG_NORMAL       0x0000
        !            60: #define  _SOS_DEBUG_NO_TIMER     0x0001
        !            61: #define  _SOS_TIMER_DPMI         0x0002
        !            62: 
        !            63: #define  _ACTIVE           0x8000
        !            64: #define  _LOOPING          0x4000
        !            65: #define  _FIRST_TIME       0x2000
        !            66: #define  _PENDING_RELEASE  0x1000
        !            67: #define  _CONTINUE_BLOCK   0x0800
        !            68: #define  _PITCH_SHIFT      0x0400
        !            69: #define  _PANNING          0x0200
        !            70: #define  _VOLUME           0x0100
        !            71: #define  _TRANSLATE16TO8   0x0080
        !            72: #define  _STAGE_LOOP       0x0040
        !            73: #define  _TRANSLATE8TO16   0x0020
        !            74: #define  _STEREOTOMONO     0x0010
        !            75: 
        !            76: #define  _HMI_INI_MANAGER
        !            77: 
        !            78: #define   SM_NOHARDWARE       0
        !            79: #define   SM_STANDARD         1
        !            80: 
        !            81: #define   MM_NOHARDWARE       0
        !            82: #define   MM_MIDIFM           1
        !            83: #define   MM_MIDIDIGI         2
        !            84: #define   MM_MIDIGEN          3
        !            85: #define   MM_MIDIAWE32        4
        !            86: 
        !            87: char      soundmode=SM_NOHARDWARE;
        !            88: char      musicmode=MM_NOHARDWARE;
        !            89: 
        !            90: //JSA_NEW
        !            91: #define         MAX_LOOP_LENGTH                60000L
        !            92: #define   MAX_SND_LOOPS        14
        !            93: 
        !            94: typedef  struct   _tagINIInstance {
        !            95:             WORD  wFlags;           
        !            96:             BYTE  szName[ 128 ];    
        !            97:             PSTR  pData;            
        !            98:             WORD  wSize;            
        !            99:             WORD  wMaxSize;         
        !           100:             PSTR  pCurrent;         
        !           101:             WORD  wCurrent;         
        !           102:             PSTR  pSection;         
        !           103:             PSTR  pItemPtr;         
        !           104:             PSTR  pItem;            
        !           105:             PSTR  pList;            
        !           106:             PSTR  pListPtr;         
        !           107: } _INI_INSTANCE;
        !           108: 
        !           109: #define  _INI_SECTION_START   '['
        !           110: #define  _INI_SECTION_END     ']'
        !           111: #define  _INI_EQUATE          '='
        !           112: #define  _INI_SPACE           ' '
        !           113: #define  _INI_TAB             0x9
        !           114: #define  _INI_STRING_START    '"'
        !           115: #define  _INI_STRING_END      '"'
        !           116: #define  _INI_EOL             0x0d
        !           117: #define  _INI_CR              0x0d
        !           118: #define  _INI_LF              0x0a
        !           119: #define  _INI_HEX_INDICATOR   'x'
        !           120: #define  _INI_LIST_SEPERATOR  ','
        !           121: #define  _INI_EXTRA_MEMORY    1024
        !           122: #define  _INI_MODIFIED        0x8000
        !           123: 
        !           124: #define  _ERR_NO_SLOTS ( WORD )-1
        !           125: enum {
        !           126:    _ERR_NO_ERROR,
        !           127:    _ERR_DRIVER_NOT_LOADED,
        !           128:    _ERR_INVALID_POINTER,
        !           129:    _ERR_DETECT_INITIALIZED,
        !           130:    _ERR_FAIL_ON_FILE_OPEN,
        !           131:    _ERR_MEMORY_FAIL,
        !           132:    _ERR_INVALID_DRIVER_ID,
        !           133:    _ERR_NO_DRIVER_FOUND,
        !           134:    _ERR_DETECTION_FAILURE,
        !           135:    _ERR_DRIVER_LOADED,
        !           136:    _ERR_INVALID_HANDLE,
        !           137:    _ERR_NO_HANDLES,
        !           138:    _ERR_PAUSED,   
        !           139:    _ERR_NOT_PAUSED,
        !           140:    _ERR_INVALID_DATA,
        !           141:    _ERR_DRV_FILE_FAIL,
        !           142:    _ERR_INVALID_PORT,
        !           143:    _ERR_INVALID_IRQ,
        !           144:    _ERR_INVALID_DMA,
        !           145:    _ERR_INVALID_DMA_IRQ
        !           146: };   
        !           147: enum {
        !           148:          _FALSE, 
        !           149:          _TRUE 
        !           150: };
        !           151: 
        !           152: typedef struct {
        !           153:    BYTE  szDeviceName[ 32 ];  
        !           154:    WORD  wDeviceVersion;      
        !           155:    WORD  wBitsPerSample;      
        !           156:    WORD  wChannels;           
        !           157:    WORD  wMinRate;            
        !           158:    WORD  wMaxRate;            
        !           159:    WORD  wMixerOnBoard;       
        !           160:    WORD  wMixerFlags;         
        !           161:    WORD  wFlags;              
        !           162:    short far * lpPortList;    
        !           163:    short far * lpDMAList;     
        !           164:    short far * lpIRQList;     
        !           165:    short far * lpRateList;    
        !           166:    WORD  fBackground;         
        !           167:    WORD  wDeviceID;           
        !           168:    WORD  wTimerID;            
        !           169: } _SOS_CAPABILITIES; 
        !           170: _SOS_CAPABILITIES digicap;
        !           171: _SOS_CAPABILITIES _far *digicapptr=( _SOS_CAPABILITIES _far *)&digicap;
        !           172: 
        !           173: typedef struct {
        !           174:    WORD  wPort;
        !           175:    WORD  wIRQ;
        !           176:    WORD  wDMA; 
        !           177:    WORD  wParam;
        !           178: } _SOS_HARDWARE;
        !           179: _SOS_HARDWARE  digihardware;
        !           180: _SOS_HARDWARE  _far *digihardwareptr=( _SOS_HARDWARE _far *)&digihardware;
        !           181: 
        !           182: #define  _SOS_DMA_BUFFERSIZE     0x2000
        !           183: #define  _SOS_SAMPLE_RATE        11025
        !           184: #define  _SOS_FILL_TIMER_RATE    40
        !           185: #define  _SOS_NORMAL_TIMER       0x00
        !           186: #define  _CALLBACK_TIMER_RATE    40
        !           187: 
        !           188: typedef struct {
        !           189:    WORD  wBufferSize;
        !           190:    LPSTR lpBuffer;
        !           191:    BOOL  wAllocateBuffer;
        !           192:    WORD  wSampleRate;
        !           193:    WORD  wParam;
        !           194:    LONG  dwParam;
        !           195:    VOID ( far *lpFillHandler )( VOID );
        !           196:    LPSTR lpDriverMemory;
        !           197:    LPSTR lpDriverMemoryCS;
        !           198:    LPSTR lpTimerMemory;
        !           199:    LPSTR lpTimerMemoryCS;
        !           200:    WORD  wTimerID;
        !           201:    WORD  wPhysical;
        !           202: } _SOS_INIT_DRIVER;
        !           203: _SOS_INIT_DRIVER    digiinitdriver = {
        !           204:      _SOS_DMA_BUFFERSIZE,
        !           205:        _NULL,
        !           206:        _TRUE,
        !           207:        _SOS_SAMPLE_RATE,
        !           208:        19,
        !           209:        0L,
        !           210:        _NULL,
        !           211:        _NULL,
        !           212:        _NULL,
        !           213:        _SOS_NORMAL_TIMER
        !           214: };
        !           215: _SOS_INIT_DRIVER  _far *digiinitdriverptr=( _SOS_INIT_DRIVER _far *)&digiinitdriver;
        !           216: 
        !           217: enum {
        !           218:    _SAMPLE_PROCESSED,
        !           219:    _SAMPLE_LOOPING,
        !           220:    _SAMPLE_DONE
        !           221: };
        !           222: 
        !           223: enum
        !           224: {
        !           225:    _LEFT_CHANNEL,
        !           226:    _RIGHT_CHANNEL,
        !           227:    _CENTER_CHANNEL,
        !           228:    _INTERLEAVED
        !           229: };
        !           230: 
        !           231: typedef struct {
        !           232:    LPSTR lpSamplePtr;
        !           233:    WORD  dwSampleSize;
        !           234:    WORD  wLoopCount;
        !           235:    WORD  wChannel;
        !           236:    WORD  wVolume;
        !           237:    WORD  wSampleID;
        !           238:    VOID  ( far cdecl *lpCallback )( WORD, WORD, WORD );
        !           239:    WORD  wSamplePort; 
        !           240:    WORD  wSampleFlags;
        !           241:    WORD  dwSampleByteLength;
        !           242:    WORD  dwSampleLoopPoint;
        !           243:    WORD  dwSampleLoopLength;
        !           244:    WORD  dwSamplePitchAdd;
        !           245:    WORD  wSamplePitchFraction;
        !           246:    WORD  wSamplePanLocation;
        !           247:    WORD  wSamplePanSpeed;
        !           248:    WORD  wSamplePanDirection;
        !           249:    WORD  wSamplePanStart;
        !           250:    WORD  wSamplePanEnd;
        !           251:    WORD  wSampleDelayBytes;
        !           252:    WORD  wSampleDelayRepeat;
        !           253:    WORD  dwSampleADPCMPredicted;
        !           254:    WORD  wSampleADPCMIndex;
        !           255:    WORD  wSampleRootNoteMIDI;   
        !           256:    WORD  dwSampleTemp1;   
        !           257:    WORD  dwSampleTemp2;   
        !           258:    WORD  dwSampleTemp3;   
        !           259: } _SOS_START_SAMPLE;
        !           260: _SOS_START_SAMPLE   sample[MAXSOUNDS];
        !           261: _SOS_START_SAMPLE   _far *sampleptr[MAXSOUNDS];
        !           262: 
        !           263: #define   NULL_HANDLE    -1
        !           264: #define   MAXLOOPS        2
        !           265: 
        !           266: //defines for looping sound variables
        !           267: extern    int       loopinsound;
        !           268: extern    int       baydoorloop;
        !           269: extern    int       ambsubloop;
        !           270: 
        !           271: 
        !           272: // a 1-1 map from sounds in sound file to this array
        !           273: struct    soundbuffertype {
        !           274:      int       users;
        !           275:      long      offset;
        !           276:      long      cache_ptr;
        !           277:      long      cache_length;
        !           278:      char      cache_lock;
        !           279: };
        !           280: struct    soundbuffertype    sbuf[TOTALSOUNDS];
        !           281: struct    soundbuffertype    *sbufptr[TOTALSOUNDS];
        !           282: struct    soundbuffertype    loopbuf[MAXLOOPS];
        !           283: struct    soundbuffertype    *loopbufptr[MAXLOOPS];
        !           284: 
        !           285: struct    soundtype {
        !           286:      int       handle;
        !           287:      int       sndnum;
        !           288:      int       plevel;
        !           289:      long      x,y;
        !           290:      short     type;
        !           291: };
        !           292: struct    soundtype     dsound[MAXSOUNDS];
        !           293: struct    soundtype     *dsoundptr[MAXSOUNDS];
        !           294: struct    soundtype     lsound[MAXLOOPS];
        !           295: struct    soundtype     *lsoundptr[MAXLOOPS];
        !           296: DWORD    *LoopList;
        !           297: 
        !           298: VOID      _far cdecl digiloopcallback(  WORD, WORD, WORD  );
        !           299: 
        !           300: _SOS_START_SAMPLE loopsampledata[MAXLOOPS] =
        !           301:        {  
        !           302:           {_NULL, 0L, -1, _CENTER_CHANNEL, 0x3fff,
        !           303:                 0x1000, digiloopcallback, 0, _LOOPING | _VOLUME, 
        !           304:                 0L, 0L, 0L, 0L, 0, 0, 0, 0x8000, 0, 0, 0, 0, 
        !           305:                 0L, 0, 0, 0L, 0L, 0L},
        !           306: 
        !           307:       {_NULL, 0L, -1, _CENTER_CHANNEL, 0x3fff,
        !           308:                 0x2000, digiloopcallback, 0, _LOOPING | _VOLUME, 
        !           309:                 0L, 0L, 0L, 0L, 0, 0, 0, 0x8000, 0, 0, 0, 0, 
        !           310:                 0L, 0, 0, 0L, 0L, 0L},
        !           311:        };
        !           312: _SOS_START_SAMPLE   _far *loopsampleptr[MAXLOOPS];
        !           313: 
        !           314: WORD     LoopIndex=0,looptoggle=0,loopmusepauseflag=0;
        !           315: WORD     hLoopFile     =  -1;       // Handle for Loop file
        !           316: 
        !           317: 
        !           318: volatile       int LoopPending=0;
        !           319: 
        !           320: WORD      digiport;
        !           321: WORD _far *digiportptr=( WORD _far *)&digiport;
        !           322: WORD      fhdigifill;
        !           323: WORD _far *fhdigifillptr=( WORD _far *)&fhdigifill;
        !           324: WORD      fhdigidriver;
        !           325: WORD _far *fhdigidriverptr=( WORD _far *)&fhdigidriver;
        !           326: 
        !           327: int       fhsounds;
        !           328: int       fhsongs;
        !           329: 
        !           330: 
        !           331: 
        !           332: #define   BASESONG            0
        !           333: #define   MAXBASESONGLENGTH   44136
        !           334: #define   AVAILMODES          3
        !           335: #define   SONGSPERLEVEL       3 
        !           336: #define        NUMLEVELS                7
        !           337: 
        !           338: int       totalsongsperlevel;
        !           339: char      basesongdata[MAXBASESONGLENGTH];
        !           340: char      secondsongdata[MAXBASESONGLENGTH];
        !           341: char      thirdsongdata[MAXBASESONGLENGTH];
        !           342: 
        !           343: struct    songtype  {
        !           344:      int       handle;
        !           345:      int       offset;
        !           346:      int       playing;
        !           347:      int       pending;
        !           348:      char     *buffer;
        !           349:      long      length;
        !           350: };
        !           351: struct    songtype  song[SONGSPERLEVEL];
        !           352: struct    songtype  *songptr[SONGSPERLEVEL];
        !           353: 
        !           354: #define  _SOS_MIDI_MAX_DRIVERS  5
        !           355: #define  _SOS_MIDI_MAX_CHANNELS    0x10
        !           356: 
        !           357: #define  _SOS_MIDI_FADE_IN          0x01  
        !           358: #define  _SOS_MIDI_FADE_OUT         0x02  
        !           359: #define  _SOS_MIDI_FADE_OUT_STOP    0x04  
        !           360: 
        !           361: 
        !           362: #define  _MIDI_SOUND_MASTER_II      0xa000
        !           363: #define  _MIDI_MPU_401              0xa001
        !           364: #define  _MIDI_FM                   0xa002
        !           365: #define  _MIDI_OPL2                 0xa002
        !           366: #define  _MIDI_CALLBACK             0xa003
        !           367: #define  _MIDI_MT_32                0xa004
        !           368: #define  _MIDI_DIGI                 0xa005  
        !           369: #define  _MIDI_INTERNAL_SPEAKER     0xa006
        !           370: #define  _MIDI_WAVE_TABLE_SYNTH     0xa007  
        !           371: #define  _MIDI_AWE32                0xa008  
        !           372: #define  _MIDI_OPL3                 0xa009  
        !           373: #define  _MIDI_GUS                  0xa00a  
        !           374: 
        !           375: typedef struct {
        !           376:    BYTE     szDeviceName[ 32 ];  
        !           377:    WORD     wDeviceVersion;      
        !           378:    WORD     wFlags;              
        !           379:    WORD     wProcessData;        
        !           380:    short far *   lpPortList;     
        !           381:    short far *   lpIRQList;      
        !           382:    WORD     wDeviceID;           
        !           383: } _SOS_MIDI_CAPABILITIES; 
        !           384: _SOS_MIDI_CAPABILITIES midicap;
        !           385: _SOS_MIDI_CAPABILITIES _far *midicapptr=( _SOS_MIDI_CAPABILITIES _far *)&midicap;
        !           386: 
        !           387: typedef struct {
        !           388:    WORD  wDriverID;
        !           389:    WORD  wTimerRate;
        !           390:    WORD  wTimerCallbackRate;
        !           391:    WORD  wMaxVoices;
        !           392:    WORD  wVelocitySensing;
        !           393:    _SOS_INIT_DRIVER far * sDIGIDriverInfo;
        !           394:    _SOS_HARDWARE far *  sDIGIHardwareInfo;    
        !           395: } _SOS_MIDI_DIGI_INIT_DRIVER;
        !           396: _SOS_MIDI_DIGI_INIT_DRIVER    mididigiinitdriver;
        !           397: _SOS_MIDI_DIGI_INIT_DRIVER    _far *mididigiinitdriverptr=(_SOS_MIDI_DIGI_INIT_DRIVER _far *)&mididigiinitdriver;
        !           398: 
        !           399: typedef struct {
        !           400:    WORD        wDIGIDriverID;
        !           401:    VOID far * lpDriverMemory;
        !           402:    VOID far * lpDriverMemoryCS;
        !           403:    _SOS_MIDI_DIGI_INIT_DRIVER far * sDIGIInitInfo;
        !           404:    WORD  wParam;
        !           405:    DWORD dwParam;
        !           406: } _SOS_MIDI_INIT_DRIVER;
        !           407: _SOS_MIDI_INIT_DRIVER    midiinitdriver;
        !           408: _SOS_MIDI_INIT_DRIVER    _far *midiinitdriverptr=( _SOS_MIDI_INIT_DRIVER _far *)&midiinitdriver;
        !           409: 
        !           410: typedef struct {
        !           411:    BYTE _huge * lpSongData;
        !           412:    VOID ( far * lpSongCallback )( WORD );
        !           413: } _SOS_MIDI_INIT_SONG;
        !           414: _SOS_MIDI_INIT_SONG songdatastatic;
        !           415: _SOS_MIDI_INIT_SONG _far *songdataptr=(_SOS_MIDI_INIT_SONG _far *)&songdatastatic;
        !           416: 
        !           417: enum
        !           418: { 
        !           419:    _DRV_MIDI_GET_CAPS,
        !           420:    _DRV_MIDI_GET_CALL_TABLE,
        !           421:    _DRV_MIDI_SPECIAL1
        !           422: };
        !           423: 
        !           424: typedef struct {
        !           425:    BYTE  szName[ 32 ];
        !           426:    WORD  wDrivers;
        !           427:    WORD  lOffset;
        !           428:    WORD  lFileSize;
        !           429: } _MIDIFILEHEADER;
        !           430: 
        !           431: typedef struct {
        !           432:    BYTE  szName[ 32 ];
        !           433:    WORD  lNextDriver;
        !           434:    WORD  wSize;
        !           435:    WORD  wDeviceID;
        !           436:    WORD  wExtenderType;
        !           437: } _MIDIDRIVERHEADER;
        !           438: 
        !           439: typedef struct {
        !           440:    WORD  wPort;
        !           441:    WORD  wIRQ;
        !           442:    WORD  wParam;
        !           443: } _SOS_MIDI_HARDWARE;
        !           444: _SOS_MIDI_HARDWARE  midihardware;
        !           445: _SOS_MIDI_HARDWARE  _far *midihardwareptr=( _SOS_MIDI_HARDWARE _far *)&midihardware;
        !           446: 
        !           447: WORD      fhmididriver;
        !           448: WORD _far *fhmididriverptr=( WORD _far *)&fhmididriver;
        !           449: WORD      fhmididigidriver;
        !           450: WORD _far *fhmididigidriverptr=( WORD _far *)&fhmididigidriver;
        !           451: 
        !           452: int       songlist[4096];
        !           453: 
        !           454: #define   MELODICBANKLENGTH   0x152C
        !           455: #define   DRUMBANKLENGTH      0x152C
        !           456: LPSTR     melodicbankptr;
        !           457: LPSTR     drumbankptr;
        !           458: LPSTR     digitalbankptr;
        !           459: 
        !           460: #define  _MIDI_MAP_TRACK   0xff
        !           461: 
        !           462: typedef struct {
        !           463:    WORD wTrackDevice[ 32 ];
        !           464: } _SOS_MIDI_TRACK_DEVICE;
        !           465: 
        !           466: _SOS_MIDI_TRACK_DEVICE   songtrackmap = { 
        !           467:    _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, 
        !           468:    _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, 
        !           469:    _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, 
        !           470:    _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK, _MIDI_MAP_TRACK 
        !           471: };
        !           472: _SOS_MIDI_TRACK_DEVICE   _far *trackmapptr=(_SOS_MIDI_TRACK_DEVICE _far *)&songtrackmap;
        !           473: 
        !           474: UINT  PanArray[] = {
        !           475:                //REAR to HARD LEFT (angle = 0->512)   
        !           476:        0x8000,0x7000,0x6000,0x5000,0x4000,0x3000,0x2000,0x1000,0x0000,
        !           477:                //HARD LEFT to CENTER (angle = 513-1024)
        !           478:        0x1000,0x20f0,0x2000,0x3000,0x4000,0x5000,0x6000,0x7000,0x8000, 
        !           479:                //CENTER to HARD RIGHT (angle = 1025-1536)
        !           480:        0x70f0,0x8000,0x9000,0xa000,0xb000,0xc000,0xd000,0xe000,0xf000,   
        !           481:                //HARD RIGHT to REAR (angle = 1537-2047)
        !           482:        0xffff,0xf000,0xe000,0xd000,0xc000,0xb000,0xa000,0x9000,0x8000
        !           483: };
        !           484: 
        !           485: extern    void smkinit(WORD fhptr);
        !           486: extern    void smkuninit(WORD fhptr);
        !           487: extern    int  cyberenabled;
        !           488: extern    int  musicv,soundv;
        !           489: 
        !           490: VOID      _far cdecl soundcallback(  WORD, WORD, WORD  );
        !           491: void      _far      timerhandler(void);
        !           492: unsigned  _far      timerhandle1;
        !           493: volatile  int  quarterseconds=0;
        !           494: volatile  int  seconds=0;
        !           495: volatile  int  minutes=0;
        !           496: volatile  int  hours=0;
        !           497: volatile  int  messageon=0;
        !           498: int         digiloopflag=0;
        !           499: long        SeekIndex,SampleSize;
        !           500: 
        !           501: inittimer()
        !           502: {
        !           503:      sosTIMERInitSystem(_TIMER_DOS_RATE, _SOS_DEBUG_NORMAL);   
        !           504:        if( _ERR_NO_ERROR != sosTIMERRegisterEvent(CLKIPS, timerhandler, &timerhandle1) ) {
        !           505:           crash("inittimer: no handles");
        !           506:      }
        !           507: }
        !           508: 
        !           509: uninittimer()
        !           510: {
        !           511:      if (cyberenabled) {
        !           512:           ctm_deinit();
        !           513:      }
        !           514: 
        !           515:        sosTIMERRemoveEvent(timerhandle1);
        !           516:      sosTIMERUnInitSystem(0);
        !           517: }
        !           518: 
        !           519: void _far 
        !           520: timerhandler()
        !           521: {
        !           522:        totalclock++;
        !           523:        outp(0x20,0x20);
        !           524: }
        !           525: 
        !           526: initaudioptrs()
        !           527: {
        !           528:      int         i;
        !           529: 
        !           530:      for( i=0; i<TOTALSOUNDS; i++ ) {
        !           531:           sbufptr[i]=&sbuf[i];
        !           532:           sbufptr[i]->users=0;
        !           533:           sbufptr[i]->offset=0;
        !           534:           sbufptr[i]->cache_ptr=0L;
        !           535:           sbufptr[i]->cache_length=0;
        !           536:           sbufptr[i]->cache_lock=0x00;
        !           537:      }
        !           538:      for( i=0; i<MAXSOUNDS; i++ ) {
        !           539:           dsoundptr[i]=&dsound[i];
        !           540:           dsoundptr[i]->handle=NULL_HANDLE;
        !           541:           dsoundptr[i]->sndnum=0;
        !           542:           dsoundptr[i]->plevel=0;
        !           543:           dsoundptr[i]->x=0L;
        !           544:           dsoundptr[i]->y=0L;
        !           545:           dsoundptr[i]->type=ST_UPDATE;
        !           546:           dsoundptr[i]->sndnum=-1;
        !           547:           sampleptr[i]=(_SOS_START_SAMPLE   _far *)&sample[i];
        !           548:           sampleptr[i]->wSamplePitchFraction=0;
        !           549:           sampleptr[i]->wSamplePanDirection=0;
        !           550:           sampleptr[i]->wSamplePanStart=0;
        !           551:           sampleptr[i]->wSamplePanEnd=0;
        !           552:           sampleptr[i]->wSampleDelayBytes=0;
        !           553:           sampleptr[i]->wSampleDelayRepeat=0;
        !           554:           sampleptr[i]->dwSampleADPCMPredicted=0;
        !           555:           sampleptr[i]->wSampleADPCMIndex=0;
        !           556:           sampleptr[i]->wSampleRootNoteMIDI=0;
        !           557:           sampleptr[i]->dwSampleTemp1=0;
        !           558:           sampleptr[i]->dwSampleTemp2=0;
        !           559:           sampleptr[i]->dwSampleTemp3=0;
        !           560:      }
        !           561: //jsa venom
        !           562:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !           563:           songptr[i]=&song[i];
        !           564:           songptr[i]->handle=NULL_HANDLE;
        !           565:           songptr[i]->offset=0;
        !           566:           songptr[i]->playing= 0;
        !           567:           songptr[i]->pending=0;
        !           568:           songptr[i]->length=0L;
        !           569:      }
        !           570:      songptr[0]->buffer=&basesongdata;
        !           571:      songptr[1]->buffer=&secondsongdata;
        !           572:      songptr[2]->buffer=&thirdsongdata;
        !           573: 
        !           574: 
        !           575:      for( i=0; i<MAXLOOPS; i++ ) {
        !           576:           loopbufptr[i]=&loopbuf[i];
        !           577:           loopbufptr[i]->users=0;
        !           578:           loopbufptr[i]->offset=0;
        !           579:           loopbufptr[i]->cache_ptr=0L;
        !           580:           loopbufptr[i]->cache_length=0;
        !           581:           loopbufptr[i]->cache_lock=0x00;
        !           582:           lsoundptr[i]=&lsound[i];
        !           583:           lsoundptr[i]->handle=NULL_HANDLE;
        !           584:           lsoundptr[i]->sndnum=0;
        !           585:           lsoundptr[i]->plevel=0;
        !           586:           lsoundptr[i]->x=0L;
        !           587:           lsoundptr[i]->y=0L;
        !           588:           lsoundptr[i]->type=ST_UPDATE;
        !           589:           lsoundptr[i]->sndnum=-1;
        !           590:           loopsampleptr[i]=(_SOS_START_SAMPLE   _far *)&loopsampledata[i];
        !           591:      }
        !           592: }
        !           593: 
        !           594: setupdigi()
        !           595: {
        !           596:      int       i;
        !           597:      DWORD     *digilist;
        !           598: 
        !           599:      if( soundmode == SM_NOHARDWARE ) {
        !           600:           return;
        !           601:      }
        !           602: 
        !           603:      digilist=( DWORD *)malloc(( size_t)4096);
        !           604:      if( digilist == ( DWORD *)NULL ) {
        !           605:           crash("setupdigi: digilist malloc failed");
        !           606:      }
        !           607: 
        !           608:        fhsounds=open("sounds",O_RDONLY|O_BINARY);
        !           609:        if( fhsounds == -1 ) {
        !           610:             crash("setupdigi: cant open sounds");
        !           611:        }
        !           612:      memset(digilist,0, 4096);
        !           613:        lseek(fhsounds,-4096L,SEEK_END);
        !           614:        i=read(fhsounds,( void *)digilist, 4096);
        !           615:      if( i != 4096 ) {
        !           616:           crash("setupdigi: bad read of digilist");
        !           617:      }
        !           618: 
        !           619:      for( i=0; i<TOTALSOUNDS; i++ ) {
        !           620:           sbufptr[i]=&sbuf[i];
        !           621:           sbufptr[i]->users=0;
        !           622:           sbufptr[i]->offset=(digilist[i*3]*4096L);
        !           623:           sbufptr[i]->cache_ptr=0L;
        !           624:           sbufptr[i]->cache_length=( WORD)(digilist[i*3+1]);
        !           625:           sbufptr[i]->cache_lock=0x00;
        !           626:      }
        !           627:      for( i=0; i<MAXSOUNDS; i++ ) {
        !           628:           dsoundptr[i]=&dsound[i];
        !           629:           dsoundptr[i]->handle=NULL_HANDLE;
        !           630:           dsoundptr[i]->sndnum=0;
        !           631:           dsoundptr[i]->plevel=0;
        !           632:           dsoundptr[i]->x=0L;
        !           633:           dsoundptr[i]->y=0L;
        !           634:           dsoundptr[i]->type=ST_UPDATE;
        !           635:           dsoundptr[i]->sndnum=-1;
        !           636:           sampleptr[i]=(_SOS_START_SAMPLE   _far *)&sample[i];
        !           637:           sampleptr[i]->wSamplePitchFraction=0;
        !           638:           sampleptr[i]->wSamplePanDirection=0;
        !           639:           sampleptr[i]->wSamplePanStart=0;
        !           640:           sampleptr[i]->wSamplePanEnd=0;
        !           641:           sampleptr[i]->wSampleDelayBytes=0;
        !           642:           sampleptr[i]->wSampleDelayRepeat=0;
        !           643:           sampleptr[i]->dwSampleADPCMPredicted=0;
        !           644:           sampleptr[i]->wSampleADPCMIndex=0;
        !           645:           sampleptr[i]->wSampleRootNoteMIDI=0;
        !           646:           sampleptr[i]->dwSampleTemp1=0;
        !           647:           sampleptr[i]->dwSampleTemp2=0;
        !           648:           sampleptr[i]->dwSampleTemp3=0;
        !           649:      }
        !           650: 
        !           651:      free(digilist);
        !           652: }
        !           653: 
        !           654: setupmidi()
        !           655: {
        !           656:      int       fh,dl,rv,i;
        !           657: 
        !           658:      if( musicmode == MM_NOHARDWARE ) {
        !           659:           return;
        !           660:      }
        !           661: 
        !           662:      melodicbankptr=( LPSTR)0;
        !           663:      drumbankptr=( LPSTR)0;
        !           664:        digitalbankptr=( LPSTR)0;
        !           665: 
        !           666:      if( (musicmode != MM_MIDIFM) && (musicmode != MM_MIDIDIGI) )
        !           667:           goto nobanks;
        !           668: 
        !           669:      melodicbankptr=( LPSTR)malloc(( size_t)MELODICBANKLENGTH);
        !           670:      drumbankptr=( LPSTR)malloc(( size_t)DRUMBANKLENGTH);
        !           671:      if( (melodicbankptr == ( LPSTR)NULL) || (drumbankptr == ( LPSTR)NULL) ) {
        !           672:           crash("setupmidi: failed malloc");
        !           673:      }
        !           674:        if( (fh=open("melodic.bnk",O_RDONLY)) == -1 ) {
        !           675:           crash("setupmidi: cant open melodic.bnk");
        !           676:      }
        !           677:        read(fh, ( void * )melodicbankptr, MELODICBANKLENGTH);
        !           678:        close(fh);
        !           679:        rv=sosMIDISetInsData(*fhmididriverptr, melodicbankptr, 1);
        !           680:      if( rv != _ERR_NO_ERROR ) {
        !           681:           crash("setupmidi: bad SetInsData");
        !           682:      }
        !           683:        if( (fh=open("drum.bnk",O_RDONLY)) == -1 ) {
        !           684:           crash("setupmidi: cant open drum.bnk");
        !           685:      }
        !           686:        read(fh, ( void * )drumbankptr, DRUMBANKLENGTH);
        !           687:        close(fh);
        !           688:        rv=sosMIDISetInsData(*fhmididriverptr, drumbankptr, 1);
        !           689:      if( rv != _ERR_NO_ERROR ) {
        !           690:           crash("setupmidi: bad SetInsData");
        !           691:      }
        !           692: 
        !           693:        if( (musicmode == MM_MIDIDIGI) && (midihardwareptr->wPort == 0x388) ) {
        !           694:                if( (fh=open("test.dig",O_BINARY|O_RDWR)) == -1 ) {
        !           695:                crash("setupmidi: cant open test.dig");
        !           696:           }
        !           697:             dl=lseek(fh, 0L, SEEK_END);
        !           698:             lseek(fh, 0L, SEEK_SET);
        !           699:                digitalbankptr=( LPSTR)malloc(( size_t)dl);
        !           700:           if( digitalbankptr == ( LPSTR)NULL ) {
        !           701:                crash("setupmidi: failed malloc digbnkptr");
        !           702:           }
        !           703:                rv=read(fh, ( void * )digitalbankptr, dl);
        !           704:           if( rv != dl ) {
        !           705:                crash("setupmidi: bad .dig read");
        !           706:           }
        !           707:                close(fh);
        !           708:                rv=sosMIDISetInsData(*fhmididigidriverptr, digitalbankptr, 1);
        !           709:           if( rv != _ERR_NO_ERROR ) {
        !           710:                crash("setupmidi: bad SetInsData");
        !           711:           }
        !           712:        }       
        !           713: 
        !           714: nobanks:
        !           715: 
        !           716:      if( musicmode != MM_NOHARDWARE ) {
        !           717:                if( (fhsongs=open("SONGS",O_RDONLY | O_BINARY)) == -1 ) {
        !           718:                crash("setupmidi: cant open songs");
        !           719:           }
        !           720:           lseek(fhsongs, 0, SEEK_SET);
        !           721:                lseek(fhsongs, -4096, SEEK_END);
        !           722:                read(fhsongs, ( void *)songlist, 4096);
        !           723:        }
        !           724: 
        !           725: //jsa venom
        !           726:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !           727:           songptr[i]=&song[i];
        !           728:           songptr[i]->handle=NULL_HANDLE;
        !           729:           songptr[i]->offset=0;
        !           730:           songptr[i]->playing= 0;
        !           731:           songptr[i]->pending=0;
        !           732:           songptr[i]->length=0L;
        !           733:      }
        !           734:      songptr[0]->buffer=&basesongdata;
        !           735:      songptr[1]->buffer=&secondsongdata;
        !           736:      songptr[2]->buffer=&thirdsongdata;
        !           737: 
        !           738:         totalsongsperlevel=SONGSPERLEVEL*AVAILMODES;
        !           739: 
        !           740: 
        !           741: }
        !           742: 
        !           743: #define   lm(_str_) printf(" %s...\n", _str_);
        !           744: 
        !           745: initsb(char option1,char option2,long digihz,char option7a,char option7b,int val,char option7c)
        !           746: {
        !           747:      int  fh;
        !           748:      WORD rv;
        !           749:      int  vol;
        !           750: 
        !           751:      initaudioptrs();
        !           752: 
        !           753:      if( readhmicfg() == _FALSE ) {
        !           754:           musicmode=MM_NOHARDWARE;
        !           755:           soundmode=SM_NOHARDWARE;
        !           756:           return;
        !           757:      }
        !           758:  
        !           759:      switch( digicapptr->wDeviceID ) {
        !           760:      case 0x00000000:
        !           761:      case 0xFFFFFFFF:
        !           762:           soundmode=SM_NOHARDWARE;
        !           763:           break;
        !           764:      default:
        !           765:           soundmode=SM_STANDARD;
        !           766:           break;
        !           767:      }
        !           768: 
        !           769:      switch( soundmode ) {
        !           770:      case SM_NOHARDWARE:
        !           771:           lm("no sound fx");
        !           772:           break;
        !           773:      default:
        !           774:           lm("standard sound fx");
        !           775:           break;
        !           776:      }
        !           777: 
        !           778:      switch( midicapptr->wDeviceID ) {
        !           779:      case _MIDI_SOUND_MASTER_II    :    //   0xa000
        !           780:      case _MIDI_MPU_401            :    //   0xa001
        !           781:           musicmode=MM_MIDIGEN;
        !           782:           break;
        !           783:      case _MIDI_OPL2               :    //   0xa002
        !           784:           musicmode=MM_MIDIFM;
        !           785:           break;
        !           786:      case _MIDI_MT_32              :    //   0xa004
        !           787:           musicmode=MM_NOHARDWARE;
        !           788:           break;
        !           789:      case _MIDI_INTERNAL_SPEAKER   :    //   0xa006
        !           790:           musicmode=MM_NOHARDWARE;
        !           791:           break;
        !           792:      case _MIDI_WAVE_TABLE_SYNTH   :    //   0xa007  
        !           793:           musicmode=MM_NOHARDWARE;
        !           794:           break;
        !           795:      case _MIDI_AWE32              :    //   0xa008  
        !           796:           musicmode=MM_MIDIAWE32;
        !           797:           break;
        !           798:      case _MIDI_OPL3               :    //   0xa009  
        !           799:           musicmode=MM_MIDIFM;
        !           800:           break;
        !           801:      case _MIDI_GUS                :    //   0xa00a  
        !           802:           musicmode=MM_NOHARDWARE;
        !           803:           break;
        !           804:      case 0x00000000:
        !           805:      case 0xFFFFFFFF:
        !           806:           musicmode=MM_NOHARDWARE;
        !           807:           break;
        !           808:      default:
        !           809:           musicmode=MM_MIDIFM;
        !           810:           break;
        !           811:      }
        !           812: 
        !           813:     #ifdef DIGILOOPSACTIVE
        !           814:      if( (digiloopflag != 0) && (soundmode != SM_NOHARDWARE) ) {
        !           815:                 musicmode=MM_NOHARDWARE;       
        !           816:      }
        !           817:      else {
        !           818:            digiloopflag=0;
        !           819:      }
        !           820:     #else
        !           821:      digiloopflag=0;
        !           822:     #endif
        !           823: 
        !           824:      switch( musicmode ) {
        !           825:      default:
        !           826:      case MM_NOHARDWARE:
        !           827:            if( digiloopflag == 0 ) {                  
        !           828:                lm("no music");               
        !           829:            }
        !           830:            else {
        !           831:                lm("music is looped samples");
        !           832:            }
        !           833:            break;
        !           834:      case MM_MIDIFM:
        !           835:           lm("music is midi fm");
        !           836:            break;
        !           837:      case MM_MIDIDIGI:
        !           838:           lm("music is midi digi");
        !           839:            break;
        !           840:      case MM_MIDIGEN:
        !           841:           lm("music is general midi");
        !           842:            break;
        !           843:      case MM_MIDIAWE32:
        !           844:           lm("music is awe32");
        !           845:            break;
        !           846:      }
        !           847: 
        !           848:      if( soundmode != SM_NOHARDWARE ) {
        !           849:             if( sosDIGIInitSystem(_NULL,_SOS_DEBUG_NORMAL) != _ERR_NO_ERROR ) {
        !           850:                     crash("initsb: DIGIInit failed");
        !           851:                }
        !           852:             rv=sosDIGIInitDriver(digicapptr->wDeviceID,digihardwareptr,digiinitdriverptr,fhdigidriverptr);  
        !           853:           if( rv != _ERR_NO_ERROR ) {
        !           854:                crash("initsb: failed DIGIInitDriver");
        !           855:                }
        !           856:           rv=sosTIMERRegisterEvent(_SOS_FILL_TIMER_RATE,digiinitdriverptr->lpFillHandler,fhdigifillptr);
        !           857:           if( rv != _ERR_NO_ERROR ) {
        !           858:                crash("intsb: failed register lpFillHandler" );
        !           859:                }
        !           860:           vol=(soundv<<11);
        !           861:           if( (vol < 0) || (vol > 0x7fff) )
        !           862:                vol=0x7fff;
        !           863:           sosDIGISetMasterVolume(*fhdigidriverptr,vol);
        !           864:             setupdigi();
        !           865: 
        !           866:           smkinit(*fhdigidriverptr);
        !           867:        }
        !           868:      else {
        !           869:           smkinit(-1);
        !           870:      }
        !           871: 
        !           872: 
        !           873:      if( digiloopflag != 0 ) {    
        !           874:            initlooptable();
        !           875:      }
        !           876: 
        !           877:      if( musicmode != MM_NOHARDWARE ) {
        !           878:           if( sosMIDIInitSystem(_NULL,_SOS_DEBUG_NORMAL) != _ERR_NO_ERROR ) {
        !           879:                crash("initsb: MIDIInit failed");
        !           880:           }
        !           881:           midiinitdriverptr->lpDriverMemory=( VOID _far *)_NULL;
        !           882:           midiinitdriverptr->sDIGIInitInfo=( _SOS_MIDI_DIGI_INIT_DRIVER _far *)NULL;
        !           883:           rv=sosMIDIInitDriver(midicapptr->wDeviceID,midihardwareptr,midiinitdriverptr,fhmididriverptr);
        !           884:           if( rv != _ERR_NO_ERROR ) {
        !           885:                crash("initsb: MIDIInitDriver failed");
        !           886:           }
        !           887:           if( (musicmode == MM_MIDIDIGI) && (soundmode != SM_NOHARDWARE) ) {
        !           888:                mididigiinitdriverptr->wDriverID=digicapptr->wDeviceID;
        !           889:                mididigiinitdriverptr->wTimerRate=_SOS_FILL_TIMER_RATE; 
        !           890:                mididigiinitdriverptr->wMaxVoices=0x08;
        !           891:                mididigiinitdriverptr->wVelocitySensing=_FALSE;
        !           892:                mididigiinitdriverptr->sDIGIDriverInfo=digiinitdriverptr;
        !           893:                mididigiinitdriverptr->sDIGIHardwareInfo=digihardwareptr;
        !           894:                midiinitdriverptr->lpDriverMemory=( VOID _far *)_NULL;
        !           895:                midiinitdriverptr->sDIGIInitInfo=mididigiinitdriverptr;
        !           896:                rv=sosMIDIInitDriver(_MIDI_DIGI,midihardwareptr,midiinitdriverptr,fhmididigidriverptr);
        !           897:                if( rv != _ERR_NO_ERROR ) {
        !           898:                     crash("initsb: MIDIInitDriver failed");
        !           899:                }
        !           900:           }
        !           901:           vol=(musicv<<3);
        !           902:           if( (vol < 0) || (vol > 127) )
        !           903:                vol=127;
        !           904:           sosMIDISetMasterVolume(vol);
        !           905:             sosMIDIEnableChannelStealing(_FALSE);
        !           906:           setupmidi();
        !           907:      }
        !           908: }
        !           909: 
        !           910: VOID _far cdecl 
        !           911: soundcallback(WORD fhdriver, WORD action, WORD fhsample)
        !           912: {
        !           913:      int  i;
        !           914: 
        !           915:      switch( action ) {
        !           916:      case _SAMPLE_PROCESSED:
        !           917:           return;
        !           918:      case _SAMPLE_LOOPING:
        !           919:           return;
        !           920:      case _SAMPLE_DONE:
        !           921:           for( i=0; i<MAXSOUNDS; i++ ) {
        !           922:                if( dsoundptr[i]->handle == fhsample ) {
        !           923:                     sbufptr[dsoundptr[i]->sndnum]->users--;
        !           924:                     if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
        !           925:                          sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;                              
        !           926:                     }
        !           927:                     dsoundptr[i]->handle=NULL_HANDLE;
        !           928:                     dsoundptr[i]->plevel=0;
        !           929:                     dsoundptr[i]->sndnum=-1;
        !           930:                     break;
        !           931:                }
        !           932:           }
        !           933:           break;
        !           934:      }
        !           935:      return;
        !           936: }
        !           937: 
        !           938: VOID _far cdecl 
        !           939: digiloopcallback(WORD fhdriver, WORD action, WORD fhsample)
        !           940: {
        !           941:      if ( action == _SAMPLE_LOOPING ) {
        !           942:                        if(LoopPending) {
        !           943:                                SND_SwapLoops();
        !           944:                                LoopPending = 0;
        !           945:                        }
        !           946:      }
        !           947: } 
        !           948: 
        !           949: int
        !           950: playsound(int sn, long sndx,long sndy, int loop, short type)
        !           951: {
        !           952:      int       i,nr=0;
        !           953:      long      dist=0L,vol=0L,pan=0L;
        !           954: 
        !           955:      if( (toggles[TOGGLE_SOUND] == 0) || (soundmode == SM_NOHARDWARE) || (sn < 0) || (sn >= TOTALSOUNDS) )
        !           956:           return(-1);
        !           957: 
        !           958:      if( type&(ST_UNIQUE|ST_AMBUPDATE|ST_TOGGLE) ) {
        !           959:           for( i=0; i<MAXSOUNDS; i++ ) {
        !           960:                if( dsoundptr[i]->handle == NULL_HANDLE ) {
        !           961:                     continue;
        !           962:                }
        !           963:                else if( dsoundptr[i]->sndnum == sn ) {
        !           964:                     if( (type&ST_TOGGLE) != 0 ) {
        !           965:                          stopsound(i);
        !           966:                     }
        !           967:                     return(-1);
        !           968:                }
        !           969:           }
        !           970:      }
        !           971: 
        !           972:      for( i=0; i<MAXSOUNDS; i++ ) {
        !           973:           if( dsoundptr[i]->handle == NULL_HANDLE ) 
        !           974:                break;
        !           975:      }
        !           976:      if( i == MAXSOUNDS ) {
        !           977:           // add plevel and multiple occurrence replacement
        !           978:           return(-1);
        !           979:      }
        !           980: 
        !           981:      dsoundptr[i]->type=type;
        !           982:      dsoundptr[i]->x=sndx; dsoundptr[i]->y=sndy;
        !           983: 
        !           984:      sbufptr[sn]->cache_lock=1;
        !           985: 
        !           986:      if( sbufptr[sn]->cache_ptr == 0L ) {   // no longer in cache
        !           987:           allocache(&(sbufptr[sn]->cache_ptr), sbufptr[sn]->cache_length, &(sbufptr[sn]->cache_lock));
        !           988:           if( sbufptr[sn]->cache_ptr == 0L ) {
        !           989:                sbufptr[sn]->cache_lock=0x00;
        !           990:                return(-1);
        !           991:           }
        !           992:             lseek(fhsounds, sbufptr[sn]->offset, SEEK_SET);
        !           993:             nr=read(fhsounds,( void *)(sbufptr[sn]->cache_ptr),sbufptr[sn]->cache_length);
        !           994:           if( nr != sbufptr[sn]->cache_length ) {
        !           995:                sbufptr[sn]->cache_ptr=0L;
        !           996:                sbufptr[sn]->cache_lock=0x00;
        !           997:                return(-1);
        !           998:           }
        !           999:      }
        !          1000:      else {
        !          1001:      }
        !          1002: 
        !          1003:      if( (type&ST_IMMEDIATE) ) {
        !          1004:           vol=0x7fff;
        !          1005:           pan=13;
        !          1006:      }
        !          1007:      else {
        !          1008:           dist=labs(posx[screenpeek]-sndx)+labs(posy[screenpeek]-sndy);
        !          1009:                 if( (type&ST_AMBUPDATE) || (type&ST_VEHUPDATE) ) {
        !          1010:                     if( dist < AMBUPDATEDIST ) {
        !          1011:                    vol = (AMBUPDATEDIST<<3)-(dist<<3);
        !          1012:                }
        !          1013:                else {
        !          1014:                    vol=0;                   
        !          1015:                }
        !          1016:                 }
        !          1017:                 else { 
        !          1018:                     if(dist < 1500L)
        !          1019:                             vol = 0x7fff;
        !          1020:                        else if(dist > 8500L) {
        !          1021:                     if(sn >= S_MALE_COMEONYOU)
        !          1022:                                  vol = 0x0000;
        !          1023:                     else
        !          1024:                          vol = 0x1f00;
        !          1025:                }
        !          1026:                        else
        !          1027:                             vol = 39000L-(dist<<2);
        !          1028:            }
        !          1029:              pan=((getangle(posx[screenpeek]-dsoundptr[i]->x,posy[screenpeek]-dsoundptr[i]->y)+(2047-ang[screenpeek]))&2047) >> 6;
        !          1030:                 if( (pan < 0) || (pan > 35) ) 
        !          1031:             pan=13;
        !          1032:      }
        !          1033:      if( (vol < 0) )
        !          1034:          vol=0;
        !          1035:      if( (vol > 0x7fff) )
        !          1036:          vol=0x7fff;
        !          1037: 
        !          1038:      sampleptr[i]->lpSamplePtr=( LPSTR)sbufptr[sn]->cache_ptr;
        !          1039:      sampleptr[i]->dwSampleSize=sbufptr[sn]->cache_length;
        !          1040:      sampleptr[i]->wLoopCount=loop;
        !          1041:      sampleptr[i]->wChannel=_CENTER_CHANNEL;
        !          1042:      sampleptr[i]->wVolume=vol;
        !          1043:      sampleptr[i]->wSampleID=sn;
        !          1044:      sampleptr[i]->lpCallback=soundcallback;
        !          1045:      sampleptr[i]->wSamplePort=0;
        !          1046:      sampleptr[i]->wSampleFlags=_LOOPING|_VOLUME|_PANNING;
        !          1047:      sampleptr[i]->dwSampleLoopPoint=0;
        !          1048:      sampleptr[i]->dwSampleLoopLength=0;
        !          1049:      sampleptr[i]->dwSamplePitchAdd=0;
        !          1050:      sampleptr[i]->dwSampleByteLength=sbufptr[sn]->cache_length;
        !          1051:      sampleptr[i]->wSamplePanLocation=PanArray[pan];
        !          1052:      if( sampleptr[i]->wSamplePanLocation > 0xffff ) 
        !          1053:           sampleptr[i]->wSamplePanLocation=0x8000;
        !          1054:      sampleptr[i]->wSamplePanSpeed=0;
        !          1055: 
        !          1056:        dsoundptr[i]->handle=sosDIGIStartSample(*fhdigidriverptr,sampleptr[i]);
        !          1057:      if( dsoundptr[i]->handle == _ERR_NO_SLOTS ) {
        !          1058:           dsoundptr[i]->handle=NULL_HANDLE;
        !          1059:           dsoundptr[i]->plevel=0;
        !          1060:           dsoundptr[i]->sndnum=-1;
        !          1061:           if( sbufptr[sn]->users == 0 ) {
        !          1062:                sbufptr[sn]->cache_lock=0;
        !          1063:           }
        !          1064:           return(-1);
        !          1065:      }
        !          1066:      else {
        !          1067:             sbufptr[sn]->users++;
        !          1068:          #ifdef SNDDEBUG
        !          1069:           showmessage("SND %03d ADDR %08ld USRS %02d", sn, sbufptr[sn]->cache_ptr, sbufptr[sn]->users);
        !          1070:          #endif
        !          1071:          dsoundptr[i]->sndnum=sn;
        !          1072:      }
        !          1073: 
        !          1074:      return(i);    
        !          1075: }
        !          1076: 
        !          1077: stopsound(int i)
        !          1078: {
        !          1079:      if( soundmode == SM_NOHARDWARE )
        !          1080:           return;
        !          1081:      if( (i < 0) || (i >= MAXSOUNDS) ) {
        !          1082:           return;
        !          1083:      }
        !          1084:      if( dsoundptr[i]->handle == NULL_HANDLE )
        !          1085:           return;
        !          1086:      
        !          1087:      sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
        !          1088:      sbufptr[dsoundptr[i]->sndnum]->users--;
        !          1089:      if( sbufptr[dsoundptr[i]->sndnum]->users < 0 )
        !          1090:               sbufptr[dsoundptr[i]->sndnum]->users=0;
        !          1091:      if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
        !          1092:          sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;                              
        !          1093:      }
        !          1094:      dsoundptr[i]->handle=NULL_HANDLE;
        !          1095:      dsoundptr[i]->plevel=0;
        !          1096:      dsoundptr[i]->sndnum=-1;
        !          1097: }
        !          1098: 
        !          1099: void
        !          1100: updatesounds(int    snum)
        !          1101: {
        !          1102:      long      dist=0L,vol=0L,pan=0L;
        !          1103:      int       i,bufnum,panindx;
        !          1104: 
        !          1105:      if( (toggles[TOGGLE_SOUND] == 0) || (soundmode == SM_NOHARDWARE) ) 
        !          1106:           return;
        !          1107: 
        !          1108:      for( i=0; i<MAXSOUNDS; i++ ) {
        !          1109:           if( dsoundptr[i]->handle == NULL_HANDLE ) {
        !          1110:                continue;
        !          1111:           }
        !          1112:           if( (dsoundptr[i]->type&(ST_IMMEDIATE|ST_NOUPDATE|ST_VEHUPDATE)) != 0 ) {
        !          1113:                continue;
        !          1114:           }
        !          1115:           dist=labs(posx[snum]-dsoundptr[i]->x)+labs(posy[snum]-dsoundptr[i]->y);
        !          1116: 
        !          1117:           if(dsoundptr[i]->type==ST_AMBUPDATE) {
        !          1118:                     if( dist < AMBUPDATEDIST ) {
        !          1119:                     vol = (AMBUPDATEDIST<<3)-(dist<<3);
        !          1120:                }
        !          1121:                else {
        !          1122:                     vol=0;                   
        !          1123:                }
        !          1124:           }
        !          1125:                else {
        !          1126:                     if(dist < 1500L)
        !          1127:                                vol = 0x7fff;
        !          1128:                        else if(dist > 8500L)
        !          1129:                                vol = 0x1f00;
        !          1130:                        else
        !          1131:                                vol = 39000L-(dist<<2);
        !          1132:                }
        !          1133: 
        !          1134:           if( (vol < 0) )
        !          1135:               vol=0;
        !          1136:           if( (vol > 0x7fff) )
        !          1137:               vol=0x7fff;
        !          1138: 
        !          1139:           if( dsoundptr[i]->handle != NULL_HANDLE ) {   // safeguard on int level
        !          1140:                sosDIGISetSampleVolume(*fhdigidriverptr, dsoundptr[i]->handle, vol);
        !          1141:           }
        !          1142:          #ifdef DYNAMICPANPERFECT
        !          1143:           panindx=((getangle(posx[snum]-dsoundptr[i]->x,posy[snum]-dsoundptr[i]->y)+(2047-ang[snum]))&2047) >> 6;
        !          1144:           if( (panindx < 0) || (panindx > 35) ) 
        !          1145:                panindx=13;
        !          1146:           pan=PanArray[panindx];
        !          1147:           if( pan > 0xffff )
        !          1148:                pan=0xffff;
        !          1149:           if( dsoundptr[i]->handle != NULL_HANDLE ) {   // safeguard on int level
        !          1150:                sosDIGISetPanLocation(*fhdigidriverptr, dsoundptr[i]->handle, pan);
        !          1151:           }
        !          1152:          #endif
        !          1153:      }
        !          1154: }
        !          1155: 
        !          1156: void
        !          1157: updatevehiclesnds(int i, long sndx, long sndy)
        !          1158: {
        !          1159:      long      dist=0L,vol=0L,pan=0L;
        !          1160: 
        !          1161:        if( soundmode == SM_NOHARDWARE ) {
        !          1162:             return;
        !          1163:      }
        !          1164:      if( (i < 0) || (i > MAXSOUNDS) ) {
        !          1165:           return;
        !          1166:      }
        !          1167: 
        !          1168:        dsoundptr[i]->x=sndx;
        !          1169:        dsoundptr[i]->y=sndy;
        !          1170: 
        !          1171:      dist=labs(posx[screenpeek]-sndx)+labs(posy[screenpeek]-sndy);
        !          1172: 
        !          1173: 
        !          1174:        if( dist < 1000L ) {
        !          1175:                vol = 0x7fff;
        !          1176:      }
        !          1177:        else if( dist > 9000L ) {
        !          1178:                vol = 0x0000;
        !          1179:      }
        !          1180:        else {
        !          1181:                vol = 36000L-(dist<<2);
        !          1182:      }
        !          1183:      if( (vol < 0) || (vol > 0x7FFF) ) {
        !          1184:           vol=0x7fff;
        !          1185:      }
        !          1186: 
        !          1187:      if( dsoundptr[i]->handle != NULL_HANDLE ) 
        !          1188:             sosDIGISetSampleVolume(*fhdigidriverptr, dsoundptr[i]->handle, vol);
        !          1189: 
        !          1190:      pan=((getangle(posx[screenpeek]-dsoundptr[i]->x,posy[screenpeek]-dsoundptr[i]->y)+(2047-ang[screenpeek]))&2047) >> 6;
        !          1191:      if( (pan < 0) || (pan > 35) ) 
        !          1192:           pan=13;
        !          1193: 
        !          1194:      if( dsoundptr[i]->handle != NULL_HANDLE ) 
        !          1195:             sosDIGISetPanLocation(*fhdigidriverptr, dsoundptr[i]->handle, PanArray[pan]);
        !          1196: }
        !          1197: 
        !          1198: 
        !          1199: VOID _far cdecl 
        !          1200: songcallback(WORD shandle)
        !          1201: {
        !          1202: }
        !          1203: 
        !          1204: VOID _far cdecl 
        !          1205: triggercallback(WORD shandle, BYTE track, BYTE id)
        !          1206: {
        !          1207: }
        !          1208: 
        !          1209: stopsong(int sn)
        !          1210: {
        !          1211:      if( musicmode == MM_NOHARDWARE )
        !          1212:           return;
        !          1213: 
        !          1214:      if( songptr[sn]->playing == 0 ) {
        !          1215:           return;     
        !          1216:      }
        !          1217:      if( songptr[sn]->pending != 0 ) {    // cant stop a pending song
        !          1218:           return;                         // since may be interrupted
        !          1219:      }                                    // by trigger function
        !          1220: 
        !          1221:      sosMIDIStopSong(songptr[sn]->handle);
        !          1222:      songptr[sn]->playing=0;
        !          1223: }
        !          1224: 
        !          1225: removesong(int sn)
        !          1226: {
        !          1227:      if( musicmode == MM_NOHARDWARE )
        !          1228:           return;
        !          1229: 
        !          1230:      if( songptr[sn]->handle != NULL_HANDLE ) {
        !          1231:           songptr[sn]->pending=0;
        !          1232:           sosMIDIStopSong(songptr[sn]->handle);
        !          1233:           sosMIDIUnInitSong(songptr[sn]->handle);
        !          1234:           songptr[sn]->handle=NULL_HANDLE;
        !          1235:           songptr[sn]->playing=0;
        !          1236:      }
        !          1237: }
        !          1238: 
        !          1239: int
        !          1240: playsong(int sn)
        !          1241: {
        !          1242:      int       rv;
        !          1243:      int       fpos;
        !          1244: 
        !          1245:      if( (musicmode == MM_NOHARDWARE) || (toggles[TOGGLE_MUSIC] == 0) ) {
        !          1246:           return(0);
        !          1247:      }
        !          1248:      if( (sn < 0) || (sn >= SONGSPERLEVEL) || (songptr[sn]->playing != 0) || (songptr[sn]->pending != 0) ) {
        !          1249:           return(0);
        !          1250:      }
        !          1251:      
        !          1252:      if( songptr[sn]->handle != NULL_HANDLE ) {
        !          1253:           removesong(sn);
        !          1254:      }
        !          1255:      if( songptr[sn]->length == 0 )
        !          1256:          return(0);
        !          1257: 
        !          1258:      songdataptr->lpSongData=( LPSTR)songptr[sn]->buffer;
        !          1259:      songdataptr->lpSongCallback=( VOID _far *)NULL; //songcallback;
        !          1260: 
        !          1261:      fpos=flushall();
        !          1262:      if( songptr[sn]->handle == NULL_HANDLE ) {
        !          1263:           lseek(fhsongs,0,SEEK_SET);
        !          1264:           fpos=filelength(fhsongs);
        !          1265:           lseek(fhsongs, songptr[sn]->offset, SEEK_SET);
        !          1266:           fpos=tell(fhsongs);
        !          1267:           rv=read(fhsongs, ( void *)songptr[sn]->buffer, songptr[sn]->length);
        !          1268:           if( rv != songptr[sn]->length ) {
        !          1269:               crash("playsong: bad read");
        !          1270:           }
        !          1271:           rv=sosMIDIInitSong(songdataptr, trackmapptr, ( WORD _far *)&(songptr[sn]->handle));
        !          1272:           if( rv != _ERR_NO_ERROR ) {
        !          1273:                songptr[sn]->handle=NULL_HANDLE;
        !          1274:                return(0);
        !          1275:           }
        !          1276:      }
        !          1277:      else {
        !          1278:           rv=sosMIDIResetSong(songptr[sn]->handle, songdataptr); 
        !          1279:           if( rv != _ERR_NO_ERROR ) {
        !          1280:                songptr[sn]->handle=NULL_HANDLE;
        !          1281:               #ifdef MUSICDEBUG
        !          1282:                showmessage("CANT RESET SONG %2d", sn);
        !          1283:               #endif
        !          1284:           }
        !          1285:      }
        !          1286: 
        !          1287:      rv=sosMIDIStartSong(songptr[sn]->handle);
        !          1288:      if( rv != _ERR_NO_ERROR ) {
        !          1289:           songptr[sn]->handle=NULL_HANDLE;
        !          1290:           return(0);
        !          1291:      }
        !          1292: 
        !          1293:      if( (musicv<<3) > 0 ) {
        !          1294:           sosMIDIFadeSong(songptr[sn]->handle,_SOS_MIDI_FADE_IN,250,
        !          1295:                           0,(musicv<<3), 50);
        !          1296:      }
        !          1297: 
        !          1298:     #ifdef MUSICDEBUG
        !          1299:      showmessage("PLAYING SONG %2d", sn);
        !          1300:     #endif
        !          1301:      songptr[sn]->playing=1;
        !          1302:      songptr[sn]->pending=0;
        !          1303: 
        !          1304:      return(1);
        !          1305: }
        !          1306: 
        !          1307: 
        !          1308: void menusong(int insubway)
        !          1309: {
        !          1310: int i,index;
        !          1311: 
        !          1312:        if( musicmode == MM_NOHARDWARE )
        !          1313:        return;
        !          1314:        
        !          1315:     for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1316:          removesong(i);
        !          1317:     }
        !          1318: 
        !          1319:      if(insubway)
        !          1320:             index=(NUMLEVELS*(AVAILMODES*SONGSPERLEVEL)+3);
        !          1321: 
        !          1322:      else                
        !          1323:        index=NUMLEVELS*(AVAILMODES*SONGSPERLEVEL);
        !          1324: 
        !          1325:      switch( musicmode ) {
        !          1326:      case MM_MIDIFM:
        !          1327:           break;
        !          1328:      case MM_MIDIAWE32:
        !          1329:                 index++;        
        !          1330:           break;
        !          1331:      case MM_MIDIGEN:
        !          1332:                 index+=2;
        !          1333:           break;
        !          1334:      }
        !          1335: 
        !          1336:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1337:           songptr[0]->handle=NULL_HANDLE;
        !          1338:           songptr[0]->offset=songlist[index*3]*4096;
        !          1339:           songptr[0]->playing=0;
        !          1340:           songptr[0]->pending=0;
        !          1341:           songptr[0]->length=( WORD)songlist[(index*3)+1];
        !          1342:           if( songptr[0]->length >= MAXBASESONGLENGTH ) {
        !          1343:                crash("prepsongs: basesong exceeded max length");
        !          1344:           }
        !          1345:      }
        !          1346:      songptr[0]->buffer=&basesongdata;
        !          1347: 
        !          1348:      playsong(BASESONG);
        !          1349:        
        !          1350: 
        !          1351: }
        !          1352: 
        !          1353: startmusic(int level)
        !          1354: {
        !          1355:      int       i,index;
        !          1356: 
        !          1357:      if( musicmode == MM_NOHARDWARE ) {
        !          1358:           return;
        !          1359:      }
        !          1360: 
        !          1361:      if( level > 6 ) {
        !          1362:           return;
        !          1363:      }
        !          1364:      
        !          1365:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1366:           removesong(i);
        !          1367:      }
        !          1368: 
        !          1369:        index=totalsongsperlevel*(level);                 
        !          1370: 
        !          1371:      switch( musicmode ) {
        !          1372:      case MM_MIDIFM:
        !          1373:           break;
        !          1374:      case MM_MIDIAWE32:
        !          1375:                 index+=SONGSPERLEVEL;        
        !          1376:           break;
        !          1377:      case MM_MIDIGEN:
        !          1378:                 index+=SONGSPERLEVEL*2;
        !          1379:           break;
        !          1380:      }
        !          1381: 
        !          1382:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1383:           songptr[i]->handle=NULL_HANDLE;
        !          1384:           songptr[i]->offset=songlist[(index*3)+(i*3)]*4096;
        !          1385:           songptr[i]->playing=0;
        !          1386:           songptr[i]->pending=0;
        !          1387:           songptr[i]->length=( WORD)songlist[((index*3)+(i*3))+1];
        !          1388:           if( songptr[i]->length >= MAXBASESONGLENGTH ) {
        !          1389:                crash("prepsongs: basesong exceeded max length");
        !          1390:           }
        !          1391:      }
        !          1392:      songptr[0]->buffer=&basesongdata;
        !          1393:      songptr[1]->buffer=&secondsongdata;
        !          1394:      songptr[2]->buffer=&thirdsongdata;
        !          1395: 
        !          1396:      playsong(BASESONG);
        !          1397: }
        !          1398: 
        !          1399: songmastervolume(int vol)
        !          1400: {
        !          1401:      if( musicmode == MM_NOHARDWARE )
        !          1402:           return;
        !          1403: 
        !          1404:      if( (vol < 0) || (vol > 127) )
        !          1405:           vol=127;
        !          1406:      sosMIDISetMasterVolume(vol);
        !          1407: }
        !          1408: 
        !          1409: soundmastervolume(int vol)
        !          1410: {
        !          1411:      if( soundmode == SM_NOHARDWARE )
        !          1412:           return;
        !          1413: 
        !          1414:      if( (vol < 0) || (vol > 0x7FFF) )
        !          1415:           vol=0x7fff;
        !          1416:      sosDIGISetMasterVolume(*fhdigidriverptr, vol);
        !          1417: }
        !          1418: 
        !          1419: musicfade(int  dir)
        !          1420: {
        !          1421:      int i;
        !          1422: 
        !          1423:      if( musicmode == MM_NOHARDWARE ) {
        !          1424:           return;
        !          1425:      }
        !          1426:      for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1427:           if( (songptr[i]->handle != NULL_HANDLE) ) {
        !          1428:                if( ((musicv<<3) > 0) && (sosMIDISongDone(songptr[i]->handle) == _FALSE) ) {
        !          1429:                     sosMIDIFadeSong(songptr[i]->handle,_SOS_MIDI_FADE_OUT_STOP, 700,
        !          1430:                                     (musicv<<3),0,50);
        !          1431:                     while( (sosMIDISongDone(songptr[i]->handle)==_FALSE) ) {
        !          1432:                     }
        !          1433:                }
        !          1434:                removesong(i);
        !          1435:           }
        !          1436:      }
        !          1437: }
        !          1438: 
        !          1439: musicoff(void)
        !          1440: {
        !          1441:      int  i;
        !          1442: 
        !          1443:      if( musicmode != MM_NOHARDWARE )  {
        !          1444:           for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1445:                if( songptr[i]->handle == NULL_HANDLE )
        !          1446:                     continue;
        !          1447:                sosMIDIStopSong(songptr[i]->handle);
        !          1448:                sosMIDIUnInitSong(songptr[i]->handle);
        !          1449:           }
        !          1450:     }
        !          1451: }
        !          1452: 
        !          1453: stopallsounds()
        !          1454: {
        !          1455:      int       i;
        !          1456: 
        !          1457:      if( soundmode == SM_NOHARDWARE )
        !          1458:           return;
        !          1459: 
        !          1460:      for( i=0; i< MAXSOUNDS; i++ ) {
        !          1461:           if( dsoundptr[i]->handle == NULL_HANDLE )
        !          1462:                continue;
        !          1463:           sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
        !          1464:           sbufptr[dsoundptr[i]->sndnum]->users--;
        !          1465:           if( sbufptr[dsoundptr[i]->sndnum]->users < 0 )
        !          1466:               sbufptr[dsoundptr[i]->sndnum]->users=0;
        !          1467:           if( sbufptr[dsoundptr[i]->sndnum]->users == 0 ) {
        !          1468:                sbufptr[dsoundptr[i]->sndnum]->cache_lock=0x00;                              
        !          1469:           }
        !          1470:           dsoundptr[i]->handle=NULL_HANDLE;
        !          1471:           dsoundptr[i]->plevel=0;
        !          1472:           dsoundptr[i]->sndnum=-1;
        !          1473:      }
        !          1474: 
        !          1475: //clear variables that track looping sounds
        !          1476:      loopinsound=-1;
        !          1477:      baydoorloop=-1;
        !          1478:      ambsubloop=-1;
        !          1479: 
        !          1480: }
        !          1481: 
        !          1482: uninitsb(void)
        !          1483: {
        !          1484:      int       i;
        !          1485: 
        !          1486:      if( musicmode != MM_NOHARDWARE )  {
        !          1487:           for( i=0; i<SONGSPERLEVEL; i++ ) {
        !          1488:                if( songptr[i]->handle == NULL_HANDLE )
        !          1489:                     continue;
        !          1490:                sosMIDIStopSong(songptr[i]->handle);
        !          1491:                sosMIDIUnInitSong(songptr[i]->handle);
        !          1492:           }
        !          1493:                sosMIDIUnInitDriver(*fhmididriverptr, _TRUE );
        !          1494:          sosMIDIUnInitSystem();
        !          1495:     }
        !          1496: 
        !          1497:     if( digiloopflag != 0 ) {
        !          1498:           for( i=0; i<MAXLOOPS; i++ ) {
        !          1499:                if( lsoundptr[i]->handle == NULL_HANDLE )
        !          1500:                     continue;
        !          1501:                sosDIGIStopSample(*fhdigidriverptr, lsoundptr[i]->handle);
        !          1502:           }
        !          1503:     }
        !          1504: 
        !          1505:        if( soundmode != SM_NOHARDWARE ) {
        !          1506:           for( i=0; i<MAXSOUNDS; i++ ) {
        !          1507:                if( dsoundptr[i]->handle == NULL_HANDLE )
        !          1508:                     continue;
        !          1509:                sosDIGIStopSample(*fhdigidriverptr, dsoundptr[i]->handle);
        !          1510:           }
        !          1511:             if( soundmode != SM_NOHARDWARE ) {
        !          1512:                  sosTIMERRemoveEvent(*fhdigifillptr);
        !          1513:                     sosDIGIUnInitDriver(*fhdigidriverptr, _TRUE,_TRUE);
        !          1514:                     sosDIGIUnInitSystem();
        !          1515:           }
        !          1516:      }
        !          1517: 
        !          1518:      if( fhsounds >= 0 )
        !          1519:           close(fhsounds);
        !          1520:      if( fhsongs >= 0 )
        !          1521:           close(fhsongs);
        !          1522: 
        !          1523:      if( hLoopFile != -1 )
        !          1524:              close( hLoopFile );
        !          1525:      if( LoopList != ( DWORD *)NULL )
        !          1526:              free( LoopList );
        !          1527: 
        !          1528:      if( melodicbankptr )
        !          1529:           free( ( void *)melodicbankptr);
        !          1530:      if( drumbankptr )
        !          1531:           free( ( void *)drumbankptr);
        !          1532:      if( digitalbankptr )
        !          1533:           free( ( void *)digitalbankptr);
        !          1534: 
        !          1535:      smkuninit(*fhdigidriverptr);
        !          1536: }
        !          1537: 
        !          1538: void
        !          1539: initlooptable(void)
        !          1540: {
        !          1541:        if(!digiloopflag) 
        !          1542:                return;
        !          1543:        
        !          1544:        hLoopFile = open("LOOPS",O_RDONLY | O_BINARY);
        !          1545:        if( hLoopFile == -1 ) {
        !          1546:                crash("initlooptable: cant open loops");
        !          1547:        }
        !          1548:        LoopList = ( DWORD    *)malloc(0x1000); 
        !          1549:     if( LoopList == ( DWORD *)NULL )
        !          1550:          crash("initlooptable: cant get mem for LoopList");
        !          1551:        lseek(hLoopFile,-4096L,SEEK_END);
        !          1552:        read(hLoopFile,(void *)FP_OFF(LoopList),4096);
        !          1553: }
        !          1554: 
        !          1555: void
        !          1556: tekprepdigiloops(void)
        !          1557: {
        !          1558:        if( !digiloopflag )
        !          1559:                return;
        !          1560: 
        !          1561:        loopbufptr[0]->cache_lock=1;
        !          1562:        allocache(&(loopbufptr[0]->cache_ptr), MAX_LOOP_LENGTH, &(loopbufptr[0]->cache_lock));
        !          1563:        if( loopbufptr[0]->cache_ptr == 0L ) {
        !          1564:                loopbufptr[0]->cache_lock=0x00;
        !          1565:                digiloopflag=0;
        !          1566:        }
        !          1567: 
        !          1568:        loopbufptr[1]->cache_lock=1;
        !          1569:        allocache(&(loopbufptr[1]->cache_ptr), MAX_LOOP_LENGTH, &(loopbufptr[1]->cache_lock));
        !          1570:        if( loopbufptr[1]->cache_ptr == 0L ) {
        !          1571:                loopbufptr[1]->cache_lock=0x00;
        !          1572:                digiloopflag=0;
        !          1573:        }
        !          1574: }
        !          1575: 
        !          1576: void 
        !          1577: SND_LoadLoop(int load_start)
        !          1578: {
        !          1579:      int       nr=0;
        !          1580:        SeekIndex = ( LoopList[(LoopIndex * 3)+0] * 4096 );
        !          1581:        SampleSize= (WORD)LoopList[(LoopIndex * 3) + 1];
        !          1582:      lseek(hLoopFile, SeekIndex, SEEK_SET);
        !          1583: 
        !          1584:      if(!load_start) {
        !          1585:             nr=read(hLoopFile,( void *)(loopbufptr[looptoggle]->cache_ptr),SampleSize);
        !          1586:             if( nr != SampleSize ) {
        !          1587:                     loopbufptr[looptoggle]->cache_ptr=0L;
        !          1588:                     loopbufptr[looptoggle]->cache_lock=0x00;
        !          1589:                     crash("read problem with loops");
        !          1590:                }
        !          1591:           loopsampleptr[looptoggle]->lpSamplePtr=( LPSTR)loopbufptr[looptoggle]->cache_ptr;
        !          1592:             loopsampleptr[looptoggle]->dwSampleSize= SampleSize;
        !          1593:             loopsampleptr[looptoggle]->dwSampleByteLength= SampleSize;
        !          1594:        }
        !          1595:        else {
        !          1596:             nr=read(hLoopFile,( void *)(loopbufptr[looptoggle]->cache_ptr),SampleSize);
        !          1597:             if( nr != SampleSize ) {
        !          1598:                     loopbufptr[looptoggle]->cache_ptr=0L;
        !          1599:                     loopbufptr[looptoggle]->cache_lock=0x00;
        !          1600:                     crash("read problem with loops");
        !          1601:                }
        !          1602:          loopsampleptr[looptoggle]->lpSamplePtr=( LPSTR)loopbufptr[looptoggle]->cache_ptr;
        !          1603:             loopsampleptr[looptoggle]->dwSampleSize= SampleSize;
        !          1604:             loopsampleptr[looptoggle]->dwSampleByteLength= SampleSize;
        !          1605:             lsoundptr[looptoggle]->handle=sosDIGIStartSample(*fhdigidriverptr,loopsampleptr[looptoggle]);
        !          1606:             looptoggle^=1;
        !          1607:        }
        !          1608: 
        !          1609:        LoopIndex++;
        !          1610:        if(LoopIndex>MAX_SND_LOOPS-1)
        !          1611:             LoopIndex=0;
        !          1612: }
        !          1613: 
        !          1614: VOID 
        !          1615: SND_SwapLoops(VOID)
        !          1616: {
        !          1617:      int temp,i;
        !          1618: 
        !          1619:        temp=looptoggle^1;
        !          1620: 
        !          1621:        if( !sosDIGISampleDone(*fhdigidriverptr,lsoundptr[temp]->handle) )
        !          1622:        {
        !          1623:                sosDIGIStopSample(*fhdigidriverptr,lsoundptr[temp]->handle);
        !          1624:                lsoundptr[looptoggle]->handle = sosDIGIStartSample(*fhdigidriverptr,loopsampleptr[looptoggle] );
        !          1625:        }
        !          1626:          
        !          1627:        looptoggle^=1;
        !          1628: 
        !          1629: }
        !          1630: 
        !          1631: BOOL   cdecl 
        !          1632: hmiINIOpen( _INI_INSTANCE * sInstance, PSTR szName )
        !          1633: {
        !          1634:      WORD  hFile;
        !          1635: 
        !          1636:      strcpy( sInstance->szName, szName );
        !          1637: 
        !          1638:      if( ( hFile = open(szName, O_RDONLY | O_BINARY )) == -1 )
        !          1639:           return( _FALSE );
        !          1640: 
        !          1641:      sInstance->wSize=lseek( hFile, 0, SEEK_END );
        !          1642:      sInstance->wMaxSize=sInstance->wSize + _INI_EXTRA_MEMORY;
        !          1643:      lseek( hFile, 0, SEEK_SET );
        !          1644:      if( (sInstance->pData=( PSTR)malloc( sInstance->wMaxSize) ) == _NULL ) {
        !          1645:           close( hFile );
        !          1646:           return( _FALSE );
        !          1647:      }
        !          1648: 
        !          1649:      if( read( hFile, sInstance->pData, sInstance->wSize ) != sInstance->wSize ) {
        !          1650:           close( hFile );
        !          1651:           free( sInstance->pData );
        !          1652:           return( _FALSE );
        !          1653:      }
        !          1654: 
        !          1655:      close( hFile );
        !          1656: 
        !          1657:      sInstance->pCurrent  =  sInstance->pData;
        !          1658:      sInstance->wCurrent  =  0;
        !          1659: 
        !          1660:      sInstance->pItem     =  _NULL;
        !          1661:      sInstance->pList     =  _NULL;
        !          1662:      sInstance->pItemPtr  =  _NULL;
        !          1663:      sInstance->pListPtr  =  _NULL;
        !          1664: 
        !          1665:      sInstance->wFlags    &= ~_INI_MODIFIED;
        !          1666: 
        !          1667:      return( _TRUE );
        !          1668: }
        !          1669: 
        !          1670: BOOL   cdecl 
        !          1671: hmiINIClose( _INI_INSTANCE * sInstance )
        !          1672: {
        !          1673:      WORD  hFile;
        !          1674: 
        !          1675:      if( sInstance->wFlags & _INI_MODIFIED ) {
        !          1676:           if ( ( hFile =  open( (const char * )sInstance->szName, O_CREAT | O_TRUNC | O_RDWR | O_BINARY, 0 ) ) == -1 ) {
        !          1677:                free( sInstance->pData );
        !          1678:                return( _FALSE );
        !          1679:           }
        !          1680:           write( hFile, sInstance->pData, sInstance->wSize );
        !          1681:           close( hFile );
        !          1682:      }
        !          1683: 
        !          1684:      free( sInstance->pData );
        !          1685: 
        !          1686:      return( _TRUE );
        !          1687: }
        !          1688: 
        !          1689: static   PSTR  szHexNumbers="0123456789ABCDEF";
        !          1690: 
        !          1691: WORD   
        !          1692: hmiINIGetHexIndex( BYTE bValue )
        !          1693: {
        !          1694:      WORD      wIndex;
        !          1695: 
        !          1696:      for( wIndex = 0; wIndex < 16; wIndex++ )
        !          1697:           if( szHexNumbers[ wIndex ] == toupper( bValue ) )
        !          1698:                return( wIndex );
        !          1699: 
        !          1700:      return( -1 );
        !          1701: }
        !          1702: 
        !          1703: static   WORD  wMultiplier[]={ 1, 16, 256, 4096, 65536, 1048576, 16777216, 268435456 };
        !          1704: 
        !          1705: WORD   
        !          1706: hmiINIHex2Decimal( PSTR szHexValue )
        !          1707: {
        !          1708:      WORD  wDecimal=0;
        !          1709:      WORD       wPlaces=strlen( szHexValue );
        !          1710:      WORD       wMultIndex;
        !          1711:      WORD       wIndex=0;
        !          1712: 
        !          1713:      do {
        !          1714:           wDecimal+=wMultiplier[ wPlaces - 1 ] * hmiINIGetHexIndex( (BYTE)szHexValue[ wIndex++ ] );
        !          1715:           wPlaces--;
        !          1716:      } while( wPlaces > 0 );
        !          1717: 
        !          1718:      return( wDecimal );
        !          1719: }
        !          1720: 
        !          1721: BOOL  cdecl 
        !          1722: hmiINILocateSection( _INI_INSTANCE * sInstance, PSTR szName )
        !          1723: {
        !          1724:      PSTR  pDataPtr;
        !          1725:      PSTR       pSectionPtr;
        !          1726:      PSTR  szSection;
        !          1727:      WORD  wIndex;
        !          1728:      WORD  wFoundFlag  =  _FALSE;
        !          1729: 
        !          1730:      pDataPtr    =  sInstance->pData;
        !          1731:      wIndex      =  0;
        !          1732: 
        !          1733:      do {
        !          1734:           if( *pDataPtr == _INI_SECTION_START ) {
        !          1735:                pSectionPtr =  pDataPtr;
        !          1736:                pDataPtr++;
        !          1737:                szSection   =  szName;
        !          1738:                while( *pDataPtr == *szSection && wIndex < sInstance->wSize ) {
        !          1739:                   szSection++;
        !          1740:                   pDataPtr++;
        !          1741:                   wIndex++;
        !          1742:                }
        !          1743:                if( *pDataPtr == _INI_SECTION_END && *szSection == _NULL ) {
        !          1744:                   wFoundFlag  =  _TRUE;
        !          1745:                   while( *pDataPtr != _INI_LF )
        !          1746:                     pDataPtr++;
        !          1747:                   pDataPtr++;
        !          1748:                   sInstance->pListPtr  =  pDataPtr;
        !          1749:                   sInstance->pCurrent  =  pDataPtr;
        !          1750:                   sInstance->wCurrent  =  wIndex;
        !          1751:                   sInstance->pSection  =  pSectionPtr;
        !          1752:                }
        !          1753:           }
        !          1754:           pDataPtr++;
        !          1755:           wIndex++;
        !          1756:      } while( !wFoundFlag && wIndex < sInstance->wSize );
        !          1757: 
        !          1758:      return( ( BOOL )wFoundFlag );
        !          1759: }
        !          1760: 
        !          1761: BOOL   cdecl 
        !          1762: hmiINIGetDecimal( _INI_INSTANCE * sInstance, WORD * wValue )
        !          1763: {
        !          1764:      PSTR  pDataPtr;
        !          1765:        WORD  wDValue;
        !          1766:      BYTE  bBuffer[ 32 ];
        !          1767:      WORD  wIndex;
        !          1768: 
        !          1769:      if( sInstance->pList )
        !          1770:           pDataPtr=sInstance->pList;
        !          1771:      else
        !          1772:           pDataPtr=sInstance->pItem;
        !          1773:      if( pDataPtr == _NULL )
        !          1774:           return( _FALSE );
        !          1775: 
        !          1776:      while( *pDataPtr == _INI_SPACE )
        !          1777:           pDataPtr++;
        !          1778: 
        !          1779:      if( *pDataPtr == _INI_EOL )
        !          1780:           return( _FALSE );
        !          1781: 
        !          1782:      wIndex   =  0;
        !          1783:      while( *pDataPtr != _INI_EOL && *pDataPtr != _INI_LIST_SEPERATOR && *pDataPtr != _INI_SPACE ) {
        !          1784:           bBuffer[ wIndex++ ]  =  *pDataPtr++;
        !          1785:      }
        !          1786:      bBuffer[ wIndex ]='\0';
        !          1787:      if( wIndex == 0 )
        !          1788:           return( _FALSE );
        !          1789: 
        !          1790:      while( *pDataPtr == _INI_SPACE )
        !          1791:           pDataPtr++;
        !          1792:      if( *pDataPtr == _INI_LIST_SEPERATOR ) {
        !          1793:           sInstance->pList  =  ++pDataPtr;
        !          1794:      }
        !          1795:      else
        !          1796:           sInstance->pList  =  pDataPtr;
        !          1797: 
        !          1798:      if( bBuffer[ 1 ] == _INI_HEX_INDICATOR ) {
        !          1799:           wDValue  =  hmiINIHex2Decimal( &bBuffer[ 2 ] );
        !          1800:      }
        !          1801:      else {
        !          1802:           wDValue  =  (WORD)atoi( bBuffer );
        !          1803:      }
        !          1804: 
        !          1805:      *wValue  =  wDValue;
        !          1806: 
        !          1807:      return( _TRUE );
        !          1808: }
        !          1809: 
        !          1810: BOOL   cdecl 
        !          1811: hmiINILocateItem( _INI_INSTANCE * sInstance, PSTR szItem )
        !          1812: {
        !          1813:      PSTR  pDataPtr;
        !          1814:      PSTR  pItemPtr;
        !          1815:      PSTR  szSearch;
        !          1816:      WORD  wIndex;
        !          1817:      WORD  wFoundFlag=_FALSE;
        !          1818: 
        !          1819:      pDataPtr =  sInstance->pCurrent;
        !          1820:      wIndex   =  sInstance->wCurrent;
        !          1821: 
        !          1822:      do {
        !          1823: 
        !          1824:           szSearch =  szItem;
        !          1825:           if( *pDataPtr == *szSearch ) {
        !          1826:                pItemPtr    =  pDataPtr;
        !          1827:                pDataPtr++;
        !          1828:                szSearch++;
        !          1829:                wIndex++;
        !          1830:                while( *pDataPtr == *szSearch && wIndex < sInstance->wSize ) {
        !          1831:                     pDataPtr++;
        !          1832:                     szSearch++;
        !          1833:                     wIndex++;
        !          1834:                }
        !          1835:                if( *szSearch == _NULL ) {
        !          1836:                     while( *pDataPtr != _INI_EQUATE && *pDataPtr != _INI_EOL ) {
        !          1837:                          pDataPtr++;
        !          1838:                          wIndex++;
        !          1839:                     }
        !          1840:                     if( *pDataPtr == _INI_EQUATE ) {
        !          1841:                          pDataPtr++;
        !          1842:                          wIndex++;
        !          1843:                          sInstance->pItem     =  pDataPtr;
        !          1844:                     }
        !          1845:                     else {
        !          1846:                          sInstance->pItem     =  _NULL;
        !          1847:                     }
        !          1848:                     sInstance->pItemPtr  =  pItemPtr;
        !          1849:                     sInstance->pList  =  _NULL;
        !          1850:                     wFoundFlag  =  _TRUE;
        !          1851:                }
        !          1852:           }
        !          1853:           pDataPtr++;
        !          1854:           wIndex++;
        !          1855: 
        !          1856:      } while( !wFoundFlag && wIndex < sInstance->wSize && *pDataPtr != _INI_SECTION_START );
        !          1857: 
        !          1858:      return( ( BOOL )wFoundFlag );
        !          1859: }
        !          1860: 
        !          1861: BOOL   cdecl 
        !          1862: hmiINIGetItemDecimal( _INI_INSTANCE * sInstance, PSTR szItem, WORD * wValue )
        !          1863: {
        !          1864:      if( !hmiINILocateItem( sInstance, szItem ) )
        !          1865:           return( _FALSE );
        !          1866: 
        !          1867:      if( !hmiINIGetDecimal( sInstance, wValue ) )
        !          1868:           return( _FALSE );
        !          1869: 
        !          1870:      return( _TRUE );
        !          1871: }
        !          1872: 
        !          1873: readhmicfg()
        !          1874: {
        !          1875:      _INI_INSTANCE  sInstance;
        !          1876:      BOOL           wError;
        !          1877: 
        !          1878:       if( !hmiINIOpen(&sInstance, "hmiset.cfg") )
        !          1879:           return( _FALSE );
        !          1880: 
        !          1881:       if( !hmiINILocateSection(&sInstance, "DIGITAL") ) {
        !          1882:           hmiINIClose( &sInstance );
        !          1883:           return( _FALSE );
        !          1884:       }
        !          1885:       wError=hmiINIGetItemDecimal( &sInstance, "DeviceID",  ( WORD *)&(digicapptr->wDeviceID)  );
        !          1886:       wError=hmiINIGetItemDecimal( &sInstance, "DevicePort",( WORD *)&(digihardwareptr->wPort) );
        !          1887:       wError=hmiINIGetItemDecimal( &sInstance, "DeviceDMA", ( WORD *)&(digihardwareptr->wDMA)  );
        !          1888:       wError=hmiINIGetItemDecimal( &sInstance, "DeviceIRQ", ( WORD *)&(digihardwareptr->wIRQ)  );
        !          1889:       if( !wError ) {
        !          1890:           hmiINIClose( &sInstance );
        !          1891:           return( _FALSE );
        !          1892:       }
        !          1893: 
        !          1894:       if( !hmiINILocateSection(&sInstance, "MIDI") ) {
        !          1895:           hmiINIClose( &sInstance );
        !          1896:           return( _FALSE );
        !          1897:       }
        !          1898:       wError=hmiINIGetItemDecimal( &sInstance, "DeviceID",   ( WORD *)&(midicapptr->wDeviceID)  );
        !          1899:       wError=hmiINIGetItemDecimal( &sInstance, "DevicePort", ( WORD *)&(midihardwareptr->wPort) );
        !          1900:       if( !wError ) {
        !          1901:           hmiINIClose( &sInstance );
        !          1902:           return( _FALSE );
        !          1903:       }
        !          1904: 
        !          1905:       hmiINIClose( &sInstance );
        !          1906:       return( _TRUE );
        !          1907: }
        !          1908: 

unix.superglobalmegacorp.com