/* Project 16 Source Code~\r
- * Copyright (C) 2012-2017 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
+ * Copyright (C) 2012-2019 sparky4 & pngwen & andrius4669 & joncampbell123 & yakui-lover\r
*\r
* This file is part of Project 16.\r
*\r
*\r
*/\r
\r
-#ifndef __16_SD_H_\r
-#define __16_SD_H_\r
+//\r
+// ID Engine\r
+// ID_SD.h - Sound Manager Header\r
+// Version for Wolfenstein\r
+// By Jason Blochowiak\r
+// Open Watcom port by sparky4\r
+//\r
+\r
+#ifndef __16_SD__\r
+#define __16_SD__\r
\r
#include "src/lib/16_head.h"\r
-#include <hw/8254/8254.h> /* 8254 timer */\r
-#include <hw/adlib/adlib.h>\r
-#include <hw/vga/vga.h>\r
-#include <hw/dos/dos.h>\r
-#include <hw/8259/8259.h>\r
-\r
-#define MIN_REGISTER 0x01\r
-#define MAX_REGISTER 0xF5\r
-#define ADLIB_FM_ADDRESS 0x388 /* adlib address/status register */\r
-#define ADLIB_FM_DATA 0x389 /* adlib data register */\r
-\r
-/*\r
-* FM Instrument definition for .SBI files - SoundBlaster instrument\r
-* - these are the important parts - we will skip the header, but since\r
-* I am not sure where it starts and ends so I have had to guess.\r
-* However it SEEMS! to work. Each array has two values, one for\r
-* each operator.\r
-*/\r
-typedef struct{\r
- byte SoundCharacteristic[2]; /* modulator frequency multiple... */\r
- byte Level[2]; /* modulator frequency level... */\r
- byte AttackDecay[2]; /* modulator attack/decay... */\r
- byte SustainRelease[2]; /* modulator sustain/release... */\r
- byte WaveSelect[2]; /* output waveform distortion */\r
- byte Feedback; /* feedback algorithm and strength */\r
-} FMInstrument;\r
-\r
-extern void interrupt (*old_irq0)(void);\r
-\r
-void opl2out(word reg, word data);\r
-void opl3out(word reg, word data);\r
-void opl3exp(word data);\r
-\r
-void FMReset(void/*int percusiveMode*/);\r
-void FMKeyOff(int voice);\r
-void FMKeyOn(int voice, int freq, int octave);\r
-void FMSetVoice(int voiceNum, FMInstrument *ins);\r
-\r
-void SD_Initimf(global_game_variables_t *gvar);\r
-void SD_imf_free_music(global_game_variables_t *gvar);\r
-int SD_imf_load_music(const char *path, global_game_variables_t *gvar);\r
-void interrupt irq0(void);\r
-void SD_imf_tick(global_game_variables_t *gvar);\r
-void SD_adlib_shut_up();\r
-\r
-#endif /*__16_SND_H_*/\r
+#include "src/lib/16_pm.h"\r
+\r
+//#define SD_USECATA3DSETTIMERSPEED\r
+\r
+void alOut(byte n,byte b);\r
+\r
+#ifdef __DEBUG__\r
+#define __DEBUG_SoundMgr__\r
+#endif\r
+\r
+#define TickBase 70 // 70Hz per tick - used as a base for timer 0\r
+\r
+typedef enum {\r
+ sdm_Off,\r
+ sdm_PC,sdm_AdLib,\r
+ } SDMode;\r
+typedef enum {\r
+ smm_Off,smm_AdLib\r
+ } SMMode;\r
+typedef enum {\r
+ sds_Off,sds_PC,sds_SoundSource,sds_SoundBlaster\r
+ } SDSMode;\r
+typedef struct\r
+ {\r
+ dword length;\r
+ word priority;\r
+ } SoundCommon;\r
+\r
+// PC Sound stuff\r
+#define pcTimer 0x42\r
+#define pcTAccess 0x43\r
+#define pcSpeaker 0x61\r
+\r
+#define pcSpkBits 3\r
+\r
+typedef struct\r
+ {\r
+ SoundCommon common;\r
+ byte data[1];\r
+ } PCSound;\r
+\r
+// Registers for the Sound Blaster card - needs to be offset by n0 (0x10,0x20,0x30,0x40,0x50,0x60)\r
+#define sbReset 0x206 // W\r
+#define sbFMStatus 0x208 // R\r
+#define sbFMAddr 0x208 // W\r
+#define sbFMData 0x209 // W\r
+#define sbReadData 0x20a // R\r
+#define sbWriteCmd 0x20c // W\r
+#define sbWriteData 0x20c // W\r
+#define sbWriteStat 0x20c // R\r
+#define sbDataAvail 0x20e // R\r
+\r
+// Registers for the Sound Blaster Pro card - needs to be offset by n0 (0x20 or 0x40)\r
+#define sbpLFMStatus 0x200 // R\r
+#define sbpLFMAddr 0x200 // W\r
+#define sbpLFMData 0x201 // W\r
+#define sbpRFMStatus 0x202 // R\r
+#define sbpRFMAddr 0x202 // W\r
+#define sbpRFMData 0x203 // W\r
+#define sbpMixerAddr 0x204 // W\r
+#define sbpMixerData 0x205 // RW\r
+#define sbpCDData 0x210 // R\r
+#define sbpCDCommand 0x210 // W\r
+#define sbpCDStatus 0x211 // R\r
+#define sbpCDReset 0x212 // W\r
+\r
+// SBPro Mixer addresses\r
+#define sbpmReset 0x00\r
+#define sbpmVoiceVol 0x04\r
+#define sbpmMicMix 0x0a\r
+#define sbpmFilterADC 0x0c\r
+#define sbpmControl 0x0e\r
+#define sbpmMasterVol 0x22\r
+#define sbpmFMVol 0x26\r
+#define sbpmCDVol 0x28\r
+#define sbpmLineVol 0x2e\r
+\r
+typedef struct\r
+ {\r
+ SoundCommon common;\r
+ word hertz;\r
+ byte bits,\r
+ reference,\r
+ data[1];\r
+ } SampledSound;\r
+\r
+// Registers for the AdLib card\r
+#define alFMStatus 0x388 // R\r
+#define alFMAddr 0x388 // W\r
+#define alFMData 0x389 // W\r
+\r
+// Register addresses\r
+// Operator stuff\r
+#define alChar 0x20\r
+#define alScale 0x40\r
+#define alAttack 0x60\r
+#define alSus 0x80\r
+#define alWave 0xe0\r
+// Channel stuff\r
+#define alFreqL 0xa0\r
+#define alFreqH 0xb0\r
+#define alFeedCon 0xc0\r
+// Global stuff\r
+#define alEffects 0xbd\r
+\r
+typedef struct\r
+ {\r
+ byte mChar,cChar,\r
+ mScale,cScale,\r
+ mAttack,cAttack,\r
+ mSus,cSus,\r
+ mWave,cWave,\r
+ nConn,\r
+\r
+ // These are only for Muse - these bytes are really unused\r
+ voice,\r
+ mode,\r
+ unused[3];\r
+ } Instrument;\r
+\r
+typedef struct\r
+ {\r
+ SoundCommon common;\r
+ Instrument inst;\r
+ byte block,\r
+ data[1];\r
+ } AdLibSound;\r
+\r
+//\r
+// Sequencing stuff\r
+//\r
+#define sqMaxTracks 10\r
+#define sqMaxMoods 1 // DEBUG\r
+\r
+#define sev_Null 0 // Does nothing\r
+#define sev_NoteOff 1 // Turns a note off\r
+#define sev_NoteOn 2 // Turns a note on\r
+#define sev_NotePitch 3 // Sets the pitch of a currently playing note\r
+#define sev_NewInst 4 // Installs a new instrument\r
+#define sev_NewPerc 5 // Installs a new percussive instrument\r
+#define sev_PercOn 6 // Turns a percussive note on\r
+#define sev_PercOff 7 // Turns a percussive note off\r
+#define sev_SeqEnd -1 // Terminates a sequence\r
+\r
+// Flags for MusicGroup.flags\r
+#define sf_Melodic 0\r
+#define sf_Percussive 1\r
+\r
+#if 1\r
+typedef struct\r
+ {\r
+ word length,\r
+ values[1];\r
+ } MusicGroup;\r
+#else\r
+typedef struct\r
+ {\r
+ word flags,\r
+ count,\r
+ offsets[1];\r
+ } MusicGroup;\r
+#endif\r
+\r
+typedef struct\r
+ {\r
+ /* This part needs to be set up by the user */\r
+ word mood,far *moods[sqMaxMoods];\r
+\r
+ /* The rest is set up by the code */\r
+ Instrument inst;\r
+ boolean percussive;\r
+ word far *seq;\r
+ dword nextevent;\r
+ } ActiveTrack;\r
+\r
+#define sqmode_Normal 0\r
+#define sqmode_FadeIn 1\r
+#define sqmode_FadeOut 2\r
+\r
+#define sqMaxFade 64 // DEBUG\r
+\r
+\r
+// Global variables\r
+extern boolean AdLibPresent,\r
+ SoundSourcePresent,\r
+ SoundBlasterPresent,\r
+ NeedsMusic, // For Caching Mgr\r
+ SoundPositioned;\r
+extern SDMode SoundMode;\r
+extern SDSMode DigiMode;\r
+extern SMMode MusicMode;\r
+extern boolean DigiPlaying;\r
+extern int DigiMap[];\r
+extern dword TimeCount; // Global time in ticks\r
+\r
+// Function prototypes\r
+extern void SD_Startup(global_game_variables_t *gvar),\r
+ SD_Shutdown(global_game_variables_t *gvar),\r
+ SD_Default(boolean gotit,SDMode sd,SMMode sm, global_game_variables_t *gvar),\r
+\r
+ SD_PositionSound(int leftvol,int rightvol);\r
+extern boolean SD_PlaySound(soundnames sound, global_game_variables_t *gvar);\r
+extern void SD_SetPosition(int leftvol,int rightvol, global_game_variables_t *gvar),\r
+ SD_StopSound(global_game_variables_t *gvar),\r
+ SD_WaitSoundDone(void),\r
+\r
+ SD_StartMusic(MusicGroup far *music),\r
+ SD_MusicOn(void),\r
+ SD_MusicOff(void),\r
+ SD_FadeOutMusic(void),\r
+\r
+ SD_SetUserHook(void (*hook)(void));\r
+extern boolean SD_MusicPlaying(void),\r
+ SD_SetSoundMode(SDMode mode, global_game_variables_t *gvar),\r
+ SD_SetMusicMode(SMMode mode);\r
+extern word SD_SoundPlaying(void);\r
+\r
+extern void SD_SetDigiDevice(SDSMode, global_game_variables_t *gvar),\r
+ SD_PlayDigitized(word which,int leftpos,int rightpos, global_game_variables_t *gvar),\r
+ SD_StopDigitized(global_game_variables_t *gvar),\r
+ SD_Poll(global_game_variables_t *gvar);\r
+\r
+#ifdef _MUSE_ // MUSE Goes directly to the lower level routines\r
+extern void SDL_PCPlaySound(PCSound far *sound, global_game_variables_t *gvar),\r
+ SDL_PCStopSound(void),\r
+ SDL_ALPlaySound(AdLibSound far *sound),\r
+ SDL_ALStopSound(void);\r
+#endif\r
+\r
+#endif\r