//\r
// ID Engine\r
// ID_SD.c - Sound Manager for Wolfenstein 3D\r
-// v1.2\r
+// v1.2w\r
// By Jason Blochowiak\r
+// Open Watcom port by sparky4\r
//\r
\r
//\r
// (Use SM_SetSoundMode() to set)\r
// MusicMode - What device is used for music\r
// (Use SM_SetMusicMode() to set)\r
-// DigiMode - What device is used for digitized sound effects\r
-// (Use SM_SetDigiDevice() to set)\r
-//\r
// For Cache Mgr:\r
// NeedsDigitized - load digitized sounds?\r
// NeedsMusic - load music?\r
\r
#pragma hdrstop // Wierdo thing with MUSE\r
\r
-\r
+#include <dos.h>\r
\r
//#ifdef _MUSE_ // Will be defined in ID_Types.h\r
#include "src/lib/id_sd.h"\r
#pragma hdrstop\r
#pragma warn -pia\r
\r
-#ifdef nil\r
-#undef nil\r
-#endif\r
-#define nil 0\r
-\r
#define SDL_SoundFinished() {SoundNumber = SoundPriority = 0;}\r
\r
-// Macros for SoundBlaster stuff\r
-#define sbOut(n,b) outportb((n) + sbLocation,b)\r
-#define sbIn(n) inportb((n) + sbLocation)\r
-#define sbWriteDelay() while (sbIn(sbWriteStat) & 0x80);\r
-#define sbReadDelay() while (sbIn(sbDataAvail) & 0x80);\r
-\r
// Macros for AdLib stuff\r
#define selreg(n) outportb(alFMAddr,n)\r
#define writereg(n) outportb(alFMData,n)\r
}\r
}\r
\r
-#if 0\r
-//\r
-// SoundBlaster code\r
-//\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBStopSample() - Stops any active sampled sound and causes DMA\r
-// requests from the SoundBlaster to cease\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_SBStopSample(void)\r
-{\r
- byte is;\r
-\r
-asm pushf\r
-asm cli\r
-\r
- if (sbSamplePlaying)\r
- {\r
- sbSamplePlaying = false;\r
-\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0xd0); // Turn off DSP DMA\r
-\r
- is = inportb(0x21); // Restore interrupt mask bit\r
- if (sbOldIntMask & (1 << sbInterrupt))\r
- is |= (1 << sbInterrupt);\r
- else\r
- is &= ~(1 << sbInterrupt);\r
- outportb(0x21,is);\r
- }\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBPlaySeg() - Plays a chunk of sampled sound on the SoundBlaster\r
-// Insures that the chunk doesn't cross a bank boundary, programs the DMA\r
-// controller, and tells the SB to start doing DMA requests for DAC\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static dword\r
-SDL_SBPlaySeg(volatile byte huge *data,dword length)\r
-{\r
- unsigned datapage;\r
- dword dataofs,uselen;\r
-\r
- uselen = length;\r
- datapage = FP_SEG(data) >> 12;\r
- dataofs = ((FP_SEG(data) & 0xfff) << 4) + FP_OFF(data);\r
- if (dataofs >= 0x10000)\r
- {\r
- datapage++;\r
- dataofs -= 0x10000;\r
- }\r
-\r
- if (dataofs + uselen > 0x10000)\r
- uselen = 0x10000 - dataofs;\r
-\r
- uselen--;\r
-\r
- // Program the DMA controller\r
-asm pushf\r
-asm cli\r
- outportb(0x0a,sbDMA | 4); // Mask off DMA on channel sbDMA\r
- outportb(0x0c,0); // Clear byte ptr flip-flop to lower byte\r
- outportb(0x0b,0x49); // Set transfer mode for D/A conv\r
- outportb(sbDMAa2,(byte)dataofs); // Give LSB of address\r
- outportb(sbDMAa2,(byte)(dataofs >> 8)); // Give MSB of address\r
- outportb(sbDMAa1,(byte)datapage); // Give page of address\r
- outportb(sbDMAa3,(byte)uselen); // Give LSB of length\r
- outportb(sbDMAa3,(byte)(uselen >> 8)); // Give MSB of length\r
- outportb(0x0a,sbDMA); // Re-enable DMA on channel sbDMA\r
-\r
- // Start playing the thing\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0x14);\r
- sbWriteDelay();\r
- sbOut(sbWriteData,(byte)uselen);\r
- sbWriteDelay();\r
- sbOut(sbWriteData,(byte)(uselen >> 8));\r
-asm popf\r
-\r
- return(uselen + 1);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBService() - Services the SoundBlaster DMA interrupt\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-/*static*/ void interrupt\r
-SDL_SBService(void)\r
-{\r
- dword used;\r
-\r
- sbIn(sbDataAvail); // Ack interrupt to SB\r
-\r
- if (sbNextSegPtr)\r
- {\r
- used = SDL_SBPlaySeg(sbNextSegPtr,sbNextSegLen);\r
- if (sbNextSegLen <= used)\r
- sbNextSegPtr = nil;\r
- else\r
- {\r
- sbNextSegPtr += used;\r
- sbNextSegLen -= used;\r
- }\r
- }\r
- else\r
- {\r
- SDL_SBStopSample();\r
- SDL_DigitizedDone();\r
- }\r
-\r
- outportb(0x20,0x20); // Ack interrupt\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBPlaySample() - Plays a sampled sound on the SoundBlaster. Sets up\r
-// DMA to play the sound\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-#ifdef _MUSE_\r
-void\r
-#else\r
-static void\r
-#endif\r
-SDL_SBPlaySample(byte huge *data,dword len)\r
-{\r
- dword used;\r
-\r
- SDL_SBStopSample();\r
-\r
-asm pushf\r
-asm cli\r
-\r
- used = SDL_SBPlaySeg(data,len);\r
- if (len <= used)\r
- sbNextSegPtr = nil;\r
- else\r
- {\r
- sbNextSegPtr = data + used;\r
- sbNextSegLen = len - used;\r
- }\r
-\r
- // Save old interrupt status and unmask ours\r
- sbOldIntMask = inportb(0x21);\r
- outportb(0x21,sbOldIntMask & ~(1 << sbInterrupt));\r
-\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0xd4); // Make sure DSP DMA is enabled\r
-\r
- sbSamplePlaying = true;\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_PositionSBP() - Sets the attenuation levels for the left and right\r
-// channels by using the mixer chip on the SB Pro. This hits a hole in\r
-// the address map for normal SBs.\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_PositionSBP(int leftpos,int rightpos)\r
-{\r
- byte v;\r
-\r
- if (!SBProPresent)\r
- return;\r
-\r
- leftpos = 15 - leftpos;\r
- rightpos = 15 - rightpos;\r
- v = ((leftpos & 0x0f) << 4) | (rightpos & 0x0f);\r
-\r
-asm pushf\r
-asm cli\r
-\r
- sbOut(sbpMixerAddr,sbpmVoiceVol);\r
- sbOut(sbpMixerData,v);\r
-\r
-asm popf\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_CheckSB() - Checks to see if a SoundBlaster resides at a\r
-// particular I/O location\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-SDL_CheckSB(int port)\r
-{\r
- int i;\r
-\r
- sbLocation = port << 4; // Initialize stuff for later use\r
-\r
- sbOut(sbReset,true); // Reset the SoundBlaster DSP\r
-asm mov dx,0x388 // Wait >4usec\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-asm in al, dx\r
-\r
- sbOut(sbReset,false); // Turn off sb DSP reset\r
-asm mov dx,0x388 // Wait >100usec\r
-asm mov cx,100\r
-#ifdef __WATCOMC__\r
- __asm {\r
-#endif\r
-usecloop:\r
-asm in al,dx\r
-asm loop usecloop\r
-#ifdef __WATCOMC__\r
- }\r
-#endif\r
-\r
- for (i = 0;i < 100;i++)\r
- {\r
- if (sbIn(sbDataAvail) & 0x80) // If data is available...\r
- {\r
- if (sbIn(sbReadData) == 0xaa) // If it matches correct value\r
- return(true);\r
- else\r
- {\r
- sbLocation = -1; // Otherwise not a SoundBlaster\r
- return(false);\r
- }\r
- }\r
- }\r
- sbLocation = -1; // Retry count exceeded - fail\r
- return(false);\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// Checks to see if a SoundBlaster is in the system. If the port passed is\r
-// -1, then it scans through all possible I/O locations. If the port\r
-// passed is 0, then it uses the default (2). If the port is >0, then\r
-// it just passes it directly to SDL_CheckSB()\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static boolean\r
-SDL_DetectSoundBlaster(int port)\r
-{\r
- int i;\r
-\r
- if (port == 0) // If user specifies default, use 2\r
- port = 2;\r
- if (port == -1)\r
- {\r
- if (SDL_CheckSB(2)) // Check default before scanning\r
- return(true);\r
-\r
- if (SDL_CheckSB(4)) // Check other SB Pro location before scan\r
- return(true);\r
-\r
- for (i = 1;i <= 6;i++) // Scan through possible SB locations\r
- {\r
- if ((i == 2) || (i == 4))\r
- continue;\r
-\r
- if (SDL_CheckSB(i)) // If found at this address,\r
- return(true); // return success\r
- }\r
- return(false); // All addresses failed, return failure\r
- }\r
- else\r
- return(SDL_CheckSB(port)); // User specified address or default\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_SBSetDMA() - Sets the DMA channel to be used by the SoundBlaster\r
-// code. Sets up sbDMA, and sbDMAa1-sbDMAa3 (used by SDL_SBPlaySeg()).\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-void\r
-SDL_SBSetDMA(byte channel)\r
-{\r
- if (channel > 3)\r
- Quit("SDL_SBSetDMA() - invalid SoundBlaster DMA channel");\r
-\r
- sbDMA = channel;\r
- sbDMAa1 = sba1Vals[channel];\r
- sbDMAa2 = sba2Vals[channel];\r
- sbDMAa3 = sba3Vals[channel];\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_StartSB() - Turns on the SoundBlaster\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_StartSB(void)\r
-{\r
- byte timevalue,test;\r
-\r
- sbIntVec = sbIntVectors[sbInterrupt];\r
- if (sbIntVec < 0)\r
- Quit("SDL_StartSB: Illegal or unsupported interrupt number for SoundBlaster");\r
-\r
- sbOldIntHand = getvect(sbIntVec); // Get old interrupt handler\r
- setvect(sbIntVec,SDL_SBService); // Set mine\r
\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0xd1); // Turn on DSP speaker\r
-\r
- // Set the SoundBlaster DAC time constant for 7KHz\r
- timevalue = 256 - (1000000 / 7000);\r
- sbWriteDelay();\r
- sbOut(sbWriteCmd,0x40);\r
- sbWriteDelay();\r
- sbOut(sbWriteData,timevalue);\r
-\r
- SBProPresent = false;\r
- if (sbNoProCheck)\r
- return;\r
-\r
- // Check to see if this is a SB Pro\r
- sbOut(sbpMixerAddr,sbpmFMVol);\r
- sbpOldFMMix = sbIn(sbpMixerData);\r
- sbOut(sbpMixerData,0xbb);\r
- test = sbIn(sbpMixerData);\r
- if (test == 0xbb)\r
- {\r
- // Boost FM output levels to be equivilent with digitized output\r
- sbOut(sbpMixerData,0xff);\r
- test = sbIn(sbpMixerData);\r
- if (test == 0xff)\r
- {\r
- SBProPresent = true;\r
-\r
- // Save old Voice output levels (SB Pro)\r
- sbOut(sbpMixerAddr,sbpmVoiceVol);\r
- sbpOldVOCMix = sbIn(sbpMixerData);\r
-\r
- // Turn SB Pro stereo DAC off\r
- sbOut(sbpMixerAddr,sbpmControl);\r
- sbOut(sbpMixerData,0); // 0=off,2=on\r
- }\r
- }\r
-}\r
-\r
-///////////////////////////////////////////////////////////////////////////\r
-//\r
-// SDL_ShutSB() - Turns off the SoundBlaster\r
-//\r
-///////////////////////////////////////////////////////////////////////////\r
-static void\r
-SDL_ShutSB(void)\r
-{\r
- SDL_SBStopSample();\r
-\r
- if (SBProPresent)\r
- {\r
- // Restore FM output levels (SB Pro)\r
- sbOut(sbpMixerAddr,sbpmFMVol);\r
- sbOut(sbpMixerData,sbpOldFMMix);\r
-\r
- // Restore Voice output levels (SB Pro)\r
- sbOut(sbpMixerAddr,sbpmVoiceVol);\r
- sbOut(sbpMixerData,sbpOldVOCMix);\r
- }\r
-\r
- setvect(sbIntVec,sbOldIntHand); // Set vector back\r
-}\r
-#endif\r
\r
// Sound Source Code\r
\r
asm pushf\r
asm cli\r
\r
- (long)ssSample = 0;\r
+ /*(long)*/ssSample = 0;\r
\r
asm popf\r
}\r
v = *ssSample++;\r
if (!(--ssLengthLeft))\r
{\r
- (long)ssSample = 0;\r
+ /*(long)*/ssSample = 0;\r
SDL_DigitizedDone();\r
}\r
\r
asm pushf\r
asm cli\r
\r
- (long)pcSound = 0;\r
+ /*(long)*/pcSound = 0;\r
\r
SDL_IndicatePC(false);\r
\r
asm pushf\r
asm cli\r
\r
- (long)pcSound = 0;\r
+ /*(long)*/pcSound = 0;\r
\r
asm in al,0x61 // Turn the speaker off\r
asm and al,0xfd // ~2\r
asm popf\r
}\r
\r
-#if 0\r
///////////////////////////////////////////////////////////////////////////\r
//\r
// SDL_PCService() - Handles playing the next sample in a PC sound\r
}\r
}\r
}\r
-#endif\r
\r
///////////////////////////////////////////////////////////////////////////\r
//\r
// Stuff for digitized sounds\r
//\r
memptr\r
-SDL_LoadDigiSegment(word page)\r
+SDL_LoadDigiSegment(word page, global_game_variables_t *gvar)\r
{\r
memptr addr;\r
\r
asm out dx,al\r
#endif\r
\r
- addr = PM_GetSoundPage(page, gvar);\r
- PM_SetPageLock(PMSoundStart + page,pml_Locked);\r
+ addr = PM_GetSoundPage(page);\r
+ PM_SetPageLock(gvar->pm.fi.PMSoundStart + page,pml_Locked, gvar);\r
\r
#if 0 // for debugging\r
asm mov dx,STATUS_REGISTER_1\r
}\r
\r
void\r
-SD_StopDigitized(void)\r
+SD_StopDigitized(global_game_variables_t *gvar)\r
{\r
int i;\r
\r
asm popf\r
\r
for (i = DigiLastStart;i < DigiLastEnd;i++)\r
- PM_SetPageLock(i + PMSoundStart,pml_Unlocked);\r
+ PM_SetPageLock(i + gvar->pm.fi.PMSoundStart,pml_Unlocked, gvar);\r
DigiLastStart = 1;\r
DigiLastEnd = 0;\r
}\r
}\r
\r
void\r
-SD_SetPosition(int leftpos,int rightpos)\r
+SD_SetPosition(int leftpos,int rightpos, global_game_variables_t *gvar)\r
{\r
if\r
(\r
|| (rightpos > 15)\r
|| ((leftpos == 15) && (rightpos == 15))\r
)\r
- Quit("SD_SetPosition: Illegal position");\r
+ Quit(gvar, "SD_SetPosition: Illegal position");\r
\r
switch (DigiMode)\r
{\r
}\r
\r
void\r
-SD_PlayDigitized(word which,int leftpos,int rightpos)\r
+SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar)\r
{\r
word len;\r
memptr addr;\r
\r
SD_StopDigitized();\r
if (which >= NumDigi)\r
- Quit("SD_PlayDigitized: bad sound number");\r
+ Quit(gvar, "SD_PlayDigitized: bad sound number");\r
\r
SD_SetPosition(leftpos,rightpos);\r
\r
}\r
\r
void\r
-SDL_SetupDigi(void)\r
+SDL_SetupDigi(global_game_variables_t *gvar)\r
{\r
memptr list;\r
word far *p,\r
pg;\r
int i;\r
\r
- PM_UnlockMainMem();\r
- MM_GetPtr(&list,PMPageSize);\r
- PM_CheckMainMem();\r
- p = (word far *)MK_FP(PM_GetPage(ChunksInFile - 1),0);\r
+ PM_UnlockMainMem(gvar);\r
+ MM_GetPtr(&list,PMPageSize, gvar);\r
+ PM_CheckMainMem(gvar);\r
+ p = (word far *)MK_FP(PM_GetPage(gvar->pm.fi.ChunksInFile - 1),0,gvar);\r
_fmemcpy((void far *)list,(void far *)p,PMPageSize);\r
- pg = PMSoundStart;\r
+ pg = gvar->pm.fi.PMSoundStart;\r
for (i = 0;i < PMPageSize / (sizeof(word) * 2);i++,p += 2)\r
{\r
if (pg >= ChunksInFile - 1)\r
asm pushf\r
asm cli\r
\r
- (long)alSound = 0;\r
+ /*(long)*/alSound = 0;\r
alOut(alFreqH + 0,0);\r
\r
asm popf\r
#else\r
static void\r
#endif\r
-SDL_ALPlaySound(AdLibSound far *sound)\r
+SDL_ALPlaySound(AdLibSound far *sound, global_game_variables_t *gvar)\r
{\r
Instrument far *inst;\r
byte huge *data;\r
if (!(inst->mSus | inst->cSus))\r
{\r
asm popf\r
- Quit("SDL_ALPlaySound() - Bad instrument");\r
+ Quit(gvar, "SDL_ALPlaySound() - Bad instrument");\r
}\r
\r
SDL_AlSetFXInst(&alZeroInst); // DEBUG\r
//\r
///////////////////////////////////////////////////////////////////////////\r
void\r
-SD_Startup(void)\r
+SD_Startup(global_game_variables_t *gvar)\r
{\r
int i;\r
\r
)\r
port = (temp - 0x200) >> 4;\r
else\r
- Quit("SD_Startup: Unsupported address value in BLASTER");\r
+ Quit(gvar, "SD_Startup: Unsupported address value in BLASTER");\r
break;\r
case 'I':\r
temp = strtol(env + 1,&env,10);\r
sbIntVec = sbIntVectors[sbInterrupt];\r
}\r
else\r
- Quit("SD_Startup: Unsupported interrupt value in BLASTER");\r
+ Quit(gvar, "SD_Startup: Unsupported interrupt value in BLASTER");\r
break;\r
case 'D':\r
temp = strtol(env + 1,&env,10);\r
if ((temp == 0) || (temp == 1) || (temp == 3))\r
SDL_SBSetDMA(temp);\r
else\r
- Quit("SD_Startup: Unsupported DMA value in BLASTER");\r
+ Quit(gvar, "SD_Startup: Unsupported DMA value in BLASTER");\r
break;\r
default:\r
while (isspace(*env))\r
//\r
///////////////////////////////////////////////////////////////////////////\r
boolean\r
-SD_PlaySound(soundnames sound)\r
+SD_PlaySound(soundnames sound, global_game_variables_t *gvar)\r
{\r
boolean ispos;\r
SoundCommon far *s;\r
\r
s = MK_FP(SoundTable[sound],0);\r
if ((SoundMode != sdm_Off) && !s)\r
- Quit("SD_PlaySound() - Uncached sound");\r
+ Quit(gvar, "SD_PlaySound() - Uncached sound");\r
\r
if ((DigiMode != sds_Off) && (DigiMap[sound] != -1))\r
{\r
if (DigiPriority && !DigiNumber)\r
{\r
asm popf\r
- Quit("SD_PlaySound: Priority without a sound");\r
+ Quit(gvar, "SD_PlaySound: Priority without a sound");\r
}\r
asm popf\r
\r
if (SoundMode == sdm_Off)\r
return(false);\r
if (!s->length)\r
- Quit("SD_PlaySound() - Zero length sound");\r
+ Quit(gvar, "SD_PlaySound() - Zero length sound");\r
if (s->priority < SoundPriority)\r
return(false);\r
\r