From 3ec387ac320f5f938c2a7ef763654a72e12f4e12 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 8 Nov 2012 05:45:58 +0000 Subject: [PATCH] - Renamed opl_stereo to opl_fullpan, since DOSBox's core is emulating an OPL3, which is stereo but only supports three pan positions and not the full 127 MIDI pan positions. - Added opl_core cvar to select emulator core. 0 is MAME and 1 is DOSBox. - Added DOSBox's LGPL OPL core, distantly related to one adlibemu.c written by Ken Silverman (not to be confused with the ancient MAME-derived and GPL-licensed core also found in DOSBox). I believe this corresponds to their "compat" emulator, but I'm not sure. SVN r3946 (trunk) --- src/CMakeLists.txt | 6 +-- src/oplsynth/fmopl.cpp | 16 ++----- src/oplsynth/fmopl.h | 11 ----- src/oplsynth/mlopl_io.cpp | 49 ++++++++++++++------- src/oplsynth/music_opl_mididevice.cpp | 10 ++--- src/oplsynth/music_opldumper_mididevice.cpp | 4 +- src/oplsynth/muslib.h | 5 ++- src/oplsynth/opl.h | 5 ++- src/oplsynth/opl_mus_player.cpp | 15 ++++--- src/oplsynth/opl_mus_player.h | 2 +- src/sound/music_mus_opl.cpp | 4 +- wadsrc/static/menudef.txt | 9 +++- zdoom.vcproj | 44 ++++++++++++++++-- zlib/CMakeLists.txt | 2 +- 14 files changed, 114 insertions(+), 68 deletions(-) delete mode 100644 src/oplsynth/fmopl.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f1b0e0603..b6dd26f28 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -566,11 +566,6 @@ else( NO_ASM ) ADD_ASM_FILE( asm_ia32 tmap2 ) ADD_ASM_FILE( asm_ia32 tmap3 ) endif( X64 ) - if( WIN32 ) - if( NOT X64 ) - ADD_ASM_FILE( win32 wrappers ) - endif( NOT X64 ) - endif( WIN32 ) endif( NO_ASM ) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.c ${CMAKE_CURRENT_BINARY_DIR}/xlat_parser.h @@ -817,6 +812,7 @@ add_executable( zdoom WIN32 oplsynth/music_opldumper_mididevice.cpp oplsynth/music_opl_mididevice.cpp oplsynth/opl_mus_player.cpp + oplsynth/dosbox/opl.cpp resourcefiles/ancientzip.cpp resourcefiles/file_7z.cpp resourcefiles/file_grp.cpp diff --git a/src/oplsynth/fmopl.cpp b/src/oplsynth/fmopl.cpp index e1ade9e43..c4fe1a282 100644 --- a/src/oplsynth/fmopl.cpp +++ b/src/oplsynth/fmopl.cpp @@ -100,7 +100,7 @@ Revision History: #include #include //#include "driver.h" /* use M.A.M.E. */ -#include "fmopl.h" +#include "opl.h" /* compiler dependence */ #ifndef OSD_CPU_H @@ -1576,17 +1576,9 @@ public: } /* YM3812 I/O interface */ - int Write(int a, int v) + void WriteReg(int reg, int v) { - if( !(a&1) ) - { /* address port */ - Chip.address = v & 0xff; - } - else - { /* data port */ - OPLWriteReg(&Chip, Chip.address, v); - } - return Chip.status>>7; + OPLWriteReg(&Chip, reg & 0xff, v); } void Reset() @@ -1676,7 +1668,7 @@ public: } }; -OPLEmul *YM3812Init(bool stereo) +OPLEmul *YM3812Create(bool stereo) { /* emulator create */ return new YM3812(stereo); diff --git a/src/oplsynth/fmopl.h b/src/oplsynth/fmopl.h deleted file mode 100644 index 6a5f65256..000000000 --- a/src/oplsynth/fmopl.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __FMOPL_H_ -#define __FMOPL_H_ - -#include "opl.h" - -// Multiplying OPL_SAMPLE_RATE by ADLIB_CLOCK_MUL gives the number -// Adlib clocks per second, as used by the RAWADATA file format. - -OPLEmul *YM3812Init(bool stereo); - -#endif diff --git a/src/oplsynth/mlopl_io.cpp b/src/oplsynth/mlopl_io.cpp index 6f33fa7f7..cfc29f7c9 100644 --- a/src/oplsynth/mlopl_io.cpp +++ b/src/oplsynth/mlopl_io.cpp @@ -42,7 +42,10 @@ #include #endif #include "muslib.h" -#include "fmopl.h" +#include "opl.h" +#include "c_cvars.h" + +EXTERN_CVAR(Int, opl_core) OPLio::~OPLio() { @@ -58,8 +61,12 @@ void OPLio::WriteDelay(int ticks) void OPLio::OPLwriteReg(int which, uint reg, uchar data) { - chips[which]->Write(0, reg); - chips[which]->Write(1, data); + if (IsOPL3) + { + reg |= (which & 1) << 8; + which >>= 1; + } + chips[which]->WriteReg(reg, data); } /* @@ -249,10 +256,11 @@ void OPLio::OPLwritePan(uint channel, struct OPL2instrument *instr, int pan) OPLwriteValue(0xC0, channel, instr->feedback | bits); // Set real panning if we're using emulated chips. - int which = channel / OPL2CHANNELS; + int chanper = IsOPL3 ? OPL3CHANNELS : OPL2CHANNELS; + int which = channel / chanper; if (chips[which] != NULL) { - chips[which]->SetPanning(channel % OPL2CHANNELS, pan + 64); + chips[which]->SetPanning(channel % chanper, pan + 64); } } } @@ -300,15 +308,20 @@ void OPLio::OPLshutup(void) /* * Initialize hardware upon startup */ -int OPLio::OPLinit(uint numchips, bool stereo) +int OPLio::OPLinit(uint numchips, bool stereo, bool initopl3) { assert(numchips >= 1 && numchips <= countof(chips)); uint i; + IsOPL3 = (opl_core == 1); + memset(chips, 0, sizeof(chips)); + if (IsOPL3) + { + numchips = (numchips + 1) >> 1; + } for (i = 0; i < numchips; ++i) { - OPLEmul *chip = YM3812Init(stereo); - + OPLEmul *chip = IsOPL3 ? DBOPLCreate(stereo) : YM3812Create(stereo); if (chip == NULL) { break; @@ -316,18 +329,24 @@ int OPLio::OPLinit(uint numchips, bool stereo) chips[i] = chip; } NumChips = i; - OPLchannels = OPL2CHANNELS * i; - OPLwriteInitState(); + OPLchannels = i * (IsOPL3 ? OPL3CHANNELS : OPL2CHANNELS); + OPLwriteInitState(initopl3); return i; } -void OPLio::OPLwriteInitState() +void OPLio::OPLwriteInitState(bool initopl3) { - for (uint i = 0; i < OPLchannels / OPL2CHANNELS; ++i) + for (uint i = 0; i < NumChips; ++i) { - OPLwriteReg (i, 0x01, 0x20); // enable Waveform Select - OPLwriteReg (i, 0x0B, 0x40); // turn off CSW mode - OPLwriteReg (i, 0xBD, 0x00); // set vibrato/tremolo depth to low, set melodic mode + int chip = i << (int)IsOPL3; + if (IsOPL3 && initopl3) + { + OPLwriteReg(chip, 0x105, 0x01); // enable YMF262/OPL3 mode + OPLwriteReg(chip, 0x104, 0x00); // disable 4-operator mode + } + OPLwriteReg(chip, 0x01, 0x20); // enable Waveform Select + OPLwriteReg(chip, 0x0B, 0x40); // turn off CSW mode + OPLwriteReg(chip, 0xBD, 0x00); // set vibrato/tremolo depth to low, set melodic mode } OPLshutup(); } diff --git a/src/oplsynth/music_opl_mididevice.cpp b/src/oplsynth/music_opl_mididevice.cpp index f9c28d0cc..79bb10226 100644 --- a/src/oplsynth/music_opl_mididevice.cpp +++ b/src/oplsynth/music_opl_mididevice.cpp @@ -41,7 +41,7 @@ #include "m_swap.h" #include "w_wad.h" #include "v_text.h" -#include "fmopl.h" +#include "opl.h" // MACROS ------------------------------------------------------------------ @@ -66,7 +66,7 @@ EXTERN_CVAR(Int, opl_numchips) // PUBLIC DATA DEFINITIONS ------------------------------------------------- -CVAR(Bool, opl_stereo, true, CVAR_ARCHIVE); +CVAR(Bool, opl_fullpan, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG); // CODE -------------------------------------------------------------------- @@ -78,7 +78,7 @@ CVAR(Bool, opl_stereo, true, CVAR_ARCHIVE); OPLMIDIDevice::OPLMIDIDevice() { - IsStereo = opl_stereo; + FullPan = opl_fullpan; FWadLump data = Wads.OpenLumpName("GENMIDI"); OPLloadBank(data); SampleRate = (int)OPL_SAMPLE_RATE; @@ -94,11 +94,11 @@ OPLMIDIDevice::OPLMIDIDevice() int OPLMIDIDevice::Open(void (*callback)(unsigned int, void *, DWORD, DWORD), void *userdata) { - if (io == NULL || 0 == (NumChips = io->OPLinit(opl_numchips, IsStereo))) + if (io == NULL || 0 == (NumChips = io->OPLinit(opl_numchips, FullPan, true))) { return 1; } - int ret = OpenStream(14, IsStereo ? 0 : SoundStream::Mono, callback, userdata); + int ret = OpenStream(14, (FullPan || io->IsOPL3) ? 0 : SoundStream::Mono, callback, userdata); if (ret == 0) { OPLstopMusic(); diff --git a/src/oplsynth/music_opldumper_mididevice.cpp b/src/oplsynth/music_opldumper_mididevice.cpp index f8fe6089f..0bb9ac14d 100644 --- a/src/oplsynth/music_opldumper_mididevice.cpp +++ b/src/oplsynth/music_opldumper_mididevice.cpp @@ -39,7 +39,7 @@ #include "doomdef.h" #include "m_swap.h" #include "w_wad.h" -#include "fmopl.h" +#include "opl.h" // MACROS ------------------------------------------------------------------ @@ -188,7 +188,7 @@ int DiskWriterIO::OPLinit(uint numchips, bool dontcare) CurIntTime = 0; CurChip = 0; OPLchannels = OPL2CHANNELS * numchips; - OPLwriteInitState(); + OPLwriteInitState(false); return numchips; } diff --git a/src/oplsynth/muslib.h b/src/oplsynth/muslib.h index 4c4bd6e88..1746ea02b 100644 --- a/src/oplsynth/muslib.h +++ b/src/oplsynth/muslib.h @@ -176,9 +176,9 @@ struct OPLio { void OPLwritePan(uint channel, struct OPL2instrument *instr, int pan); void OPLwriteInstrument(uint channel, struct OPL2instrument *instr); void OPLshutup(void); - void OPLwriteInitState(); + void OPLwriteInitState(bool initopl3); - virtual int OPLinit(uint numchips, bool stereo=false); + virtual int OPLinit(uint numchips, bool stereo=false, bool initopl3=false); virtual void OPLdeinit(void); virtual void OPLwriteReg(int which, uint reg, uchar data); virtual void SetClockRate(double samples_per_tick); @@ -187,6 +187,7 @@ struct OPLio { class OPLEmul *chips[MAXOPL2CHIPS]; uint OPLchannels; uint NumChips; + bool IsOPL3; }; struct DiskWriterIO : public OPLio diff --git a/src/oplsynth/opl.h b/src/oplsynth/opl.h index fbb7c412c..6a8e42e27 100644 --- a/src/oplsynth/opl.h +++ b/src/oplsynth/opl.h @@ -12,10 +12,13 @@ public: virtual ~OPLEmul() {} virtual void Reset() = 0; - virtual int Write(int a, int v) = 0; + virtual void WriteReg(int reg, int v) = 0; virtual void Update(float *buffer, int length) = 0; virtual void SetPanning(int c, int pan) = 0; virtual FString GetVoiceString() { return FString(); } }; +OPLEmul *YM3812Create(bool stereo); +OPLEmul *DBOPLCreate(bool stereo); + #endif \ No newline at end of file diff --git a/src/oplsynth/opl_mus_player.cpp b/src/oplsynth/opl_mus_player.cpp index 6140d327e..df4b3c88e 100644 --- a/src/oplsynth/opl_mus_player.cpp +++ b/src/oplsynth/opl_mus_player.cpp @@ -7,7 +7,7 @@ #include "opl_mus_player.h" #include "doomtype.h" -#include "fmopl.h" +#include "opl.h" #include "w_wad.h" #include "templates.h" #include "c_cvars.h" @@ -25,7 +25,7 @@ OPLmusicBlock::OPLmusicBlock() LastOffset = 0; NumChips = MIN(*opl_numchips, 2); Looping = false; - IsStereo = false; + FullPan = false; io = NULL; io = new OPLio; } @@ -39,7 +39,7 @@ void OPLmusicBlock::ResetChips () { ChipAccess.Enter(); io->OPLdeinit (); - NumChips = io->OPLinit(MIN(*opl_numchips, 2), IsStereo); + NumChips = io->OPLinit(MIN(*opl_numchips, 2), FullPan); ChipAccess.Leave(); } @@ -223,7 +223,8 @@ void OPLmusicFile::Restart () bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { float *samples1 = (float *)buff; - int numsamples = numbytes / (sizeof(float) << int(IsStereo)); + int stereoshift = (int)(FullPan | io->IsOPL3); + int numsamples = numbytes / (sizeof(float) << stereoshift); bool prevEnded = false; bool res = true; @@ -243,12 +244,12 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { io->chips[i]->Update(samples1, samplesleft); } - OffsetSamples(samples1, samplesleft << int(IsStereo)); + OffsetSamples(samples1, samplesleft << stereoshift); assert(NextTickIn == ticky); NextTickIn -= samplesleft; assert (NextTickIn >= 0); numsamples -= samplesleft; - samples1 += samplesleft << int(IsStereo); + samples1 += samplesleft << stereoshift; } if (NextTickIn < 1) @@ -265,7 +266,7 @@ bool OPLmusicBlock::ServiceStream (void *buff, int numbytes) { io->chips[i]->Update(samples1, samplesleft); } - OffsetSamples(samples1, numsamples << int(IsStereo)); + OffsetSamples(samples1, numsamples << stereoshift); } res = false; break; diff --git a/src/oplsynth/opl_mus_player.h b/src/oplsynth/opl_mus_player.h index 03765c10a..b0eb4b6c8 100644 --- a/src/oplsynth/opl_mus_player.h +++ b/src/oplsynth/opl_mus_player.h @@ -21,7 +21,7 @@ protected: int NumChips; bool Looping; double LastOffset; - bool IsStereo; + bool FullPan; FCriticalSection ChipAccess; }; diff --git a/src/sound/music_mus_opl.cpp b/src/sound/music_mus_opl.cpp index 0d9c35bb2..fe3463386 100644 --- a/src/sound/music_mus_opl.cpp +++ b/src/sound/music_mus_opl.cpp @@ -19,6 +19,8 @@ CUSTOM_CVAR (Int, opl_numchips, 2, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) } } +CVAR(Int, opl_core, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) + OPLMUSSong::OPLMUSSong (FILE *file, BYTE *musiccache, int len) { int samples = int(OPL_SAMPLE_RATE / 14); @@ -26,7 +28,7 @@ OPLMUSSong::OPLMUSSong (FILE *file, BYTE *musiccache, int len) Music = new OPLmusicFile (file, musiccache, len); m_Stream = GSnd->CreateStream (FillStream, samples*4, - SoundStream::Mono | SoundStream::Float, int(OPL_SAMPLE_RATE), this); + (opl_core != 1 ? SoundStream::Mono : 0) | SoundStream::Float, int(OPL_SAMPLE_RATE), this); if (m_Stream == NULL) { Printf (PRINT_BOLD, "Could not create music stream.\n"); diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index 80e4ad0e0..49bbfd91c 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1400,6 +1400,12 @@ OptionValue GusMemory 4, "1024K" } +OptionValue OplCores +{ + 0, "MAME" + 1, "DOSBox" +} + OptionMenu AdvSoundOptions { Title "ADVANCED SOUND OPTIONS" @@ -1409,7 +1415,8 @@ OptionMenu AdvSoundOptions StaticText " " StaticText "OPL Synthesis", 1 Slider "Number of emulated OPL chips", "opl_numchips", 1, 8, 1, 0 - Option "Support MIDI stero panning", "opl_stereo", "OnOff" + Option "Full MIDI stereo panning", "opl_fullpan", "OnOff" + Option "OPL Emulator Core", "opl_core", "OplCores" StaticText " " StaticText "GUS Emulation", 1 Slider "MIDI voices", "midi_voices", 16, 256, 4, 0 diff --git a/zdoom.vcproj b/zdoom.vcproj index 0b144ce26..fb5e5b1f5 100644 --- a/zdoom.vcproj +++ b/zdoom.vcproj @@ -2602,10 +2602,6 @@ /> - - @@ -2630,6 +2626,46 @@ RelativePath=".\src\oplsynth\opl_mus_player.h" > + + + + + + + + + + + + + + + + + +