diff options
-rw-r--r-- | audio/fmopl.cpp | 21 | ||||
-rw-r--r-- | audio/module.mk | 5 | ||||
-rw-r--r-- | audio/opl2lpt.cpp | 154 | ||||
-rw-r--r-- | base/commandLine.cpp | 4 | ||||
-rwxr-xr-x | configure | 32 |
5 files changed, 215 insertions, 1 deletions
diff --git a/audio/fmopl.cpp b/audio/fmopl.cpp index 3756d98123..3a003c80d9 100644 --- a/audio/fmopl.cpp +++ b/audio/fmopl.cpp @@ -43,6 +43,12 @@ namespace ALSA { } // End of namespace ALSA #endif // USE_ALSA +#ifdef ENABLE_OPL2LPT +namespace OPL2LPT { + OPL *create(); +} // End of namespace OPL2LPT +#endif // ENABLE_OPL2LPT + // Config implementation enum OplEmulator { @@ -50,7 +56,8 @@ enum OplEmulator { kMame = 1, kDOSBox = 2, kALSA = 3, - kNuked = 4 + kNuked = 4, + kOPL2LPT = 5 }; OPL::OPL() { @@ -71,6 +78,9 @@ const Config::EmulatorDescription Config::_drivers[] = { #ifdef USE_ALSA { "alsa", _s("ALSA Direct FM"), kALSA, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 }, #endif +#ifdef ENABLE_OPL2LPT + { "opl2lpt", _s("OPL2LPT"), kOPL2LPT, kFlagOpl2 }, +#endif { 0, 0, 0, 0 } }; @@ -193,6 +203,15 @@ OPL *Config::create(DriverId driver, OplType type) { return ALSA::create(type); #endif +#ifdef ENABLE_OPL2LPT + case kOPL2LPT: + if (type == kOpl2) + return OPL2LPT::create(); + else + warning("OPL2LPT only supports OPL2"); + return 0; +#endif + default: warning("Unsupported OPL emulator %d", driver); // TODO: Maybe we should add some dummy emulator too, which just outputs diff --git a/audio/module.mk b/audio/module.mk index 4f296ba0e1..49584aba90 100644 --- a/audio/module.mk +++ b/audio/module.mk @@ -72,6 +72,11 @@ MODULE_OBJS += \ alsa_opl.o endif +ifdef ENABLE_OPL2LPT +MODULE_OBJS += \ + opl2lpt.o +endif + ifndef USE_ARM_SOUND_ASM MODULE_OBJS += \ rate.o diff --git a/audio/opl2lpt.cpp b/audio/opl2lpt.cpp new file mode 100644 index 0000000000..fc5a4ef465 --- /dev/null +++ b/audio/opl2lpt.cpp @@ -0,0 +1,154 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + */ + +/* OPL implementation for OPL2LPT through libieee1284. + */ + +#define FORBIDDEN_SYMBOL_ALLOW_ALL +#include "common/scummsys.h" + +#include "common/config-manager.h" +#include "common/debug.h" +#include "common/str.h" +#include "common/textconsole.h" +#include "audio/fmopl.h" + +#include <unistd.h> +#include <ieee1284.h> + +namespace OPL { +namespace OPL2LPT { + +class OPL : public ::OPL::RealOPL { +private: + struct parport *_pport; + int index; + static const uint8 ctrlBytes[]; + +public: + OPL(); + ~OPL(); + + bool init(); + void reset(); + + void write(int a, int v); + byte read(int a); + + void writeReg(int r, int v); +}; + +const uint8 OPL::ctrlBytes[] = { + (C1284_NSELECTIN | C1284_NSTROBE | C1284_NINIT) ^ C1284_INVERTED, + (C1284_NSELECTIN | C1284_NSTROBE) ^ C1284_INVERTED, + (C1284_NSELECTIN | C1284_NSTROBE | C1284_NINIT) ^ C1284_INVERTED, + + (C1284_NSELECTIN | C1284_NINIT) ^ C1284_INVERTED, + C1284_NSELECTIN ^ C1284_INVERTED, + (C1284_NSELECTIN | C1284_NINIT) ^ C1284_INVERTED +}; + +OPL::OPL() : _pport(nullptr) { +} + +OPL::~OPL() { + if (_pport) { + stop(); + reset(); + ieee1284_close(_pport); + } +} + +bool OPL::init() { + struct parport_list parports = {}; + const Common::String parportName = ConfMan.get("opl2lpt_parport"); + + // Look for available parallel ports + if (ieee1284_find_ports(&parports, 0) != E1284_OK) { + return false; + } + for (int i = 0; i < parports.portc; i++) { + if (parportName == "null" || + parportName == parports.portv[i]->name) { + int caps = CAP1284_RAW; + _pport = parports.portv[i]; + if (ieee1284_open(_pport, F1284_EXCL, &caps) != E1284_OK) { + warning("cannot open parallel port %s", _pport->name); + } + if (ieee1284_claim(_pport) != E1284_OK) { + warning("cannot claim parallel port %s", _pport->name); + ieee1284_close(_pport); + continue; + } + reset(); + // Safe to free ports here, opened ports are refcounted. + ieee1284_free_ports(&parports); + return true; + } + } + _pport = nullptr; + ieee1284_free_ports(&parports); + return false; +} + +void OPL::reset() { + for(int i = 0; i < 256; i ++) { + writeReg(i, 0); + } + index = 0; +} + +void OPL::write(int port, int val) { + if (port & 1) { + writeReg(index, val); + } else { + index = val; + } +} + +byte OPL::read(int port) { + // No read support for the OPL2LPT + return 0; +} + +void OPL::writeReg(int r, int v) { + r &= 0xff; + v &= 0xff; + ieee1284_write_data(_pport, r); + ieee1284_write_control(_pport, ctrlBytes[0]); + ieee1284_write_control(_pport, ctrlBytes[1]); + ieee1284_write_control(_pport, ctrlBytes[2]); + usleep(4); // 3.3 us + + ieee1284_write_data(_pport, v); + ieee1284_write_control(_pport, ctrlBytes[3]); + ieee1284_write_control(_pport, ctrlBytes[4]); + ieee1284_write_control(_pport, ctrlBytes[5]); + usleep(23); +} + +OPL *create() { + return new OPL(); +} + +} // End of namespace OPL2LPT +} // End of namespace OPL diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 10ded95a51..9e62443d30 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -135,6 +135,9 @@ static const char HELP_STRING[] = #ifndef DISABLE_NUKED_OPL ", nuked" #endif +#ifdef ENABLE_OPL2LPT + ", opl2lpt" +#endif ")\n" " --aspect-ratio Enable aspect ratio correction\n" " --render-mode=MODE Enable additional render modes (hercGreen, hercAmber,\n" @@ -224,6 +227,7 @@ void registerDefaults() { ConfMan.registerDefault("music_driver", "auto"); ConfMan.registerDefault("mt32_device", "null"); ConfMan.registerDefault("gm_device", "null"); + ConfMan.registerDefault("opl2lpt_parport", "null"); ConfMan.registerDefault("cdrom", 0); @@ -134,6 +134,7 @@ _tremor=auto _tremolo=no _flac=auto _mad=auto +_opl2lpt=no _alsa=auto _seq_midi=auto _sndio=auto @@ -1049,6 +1050,9 @@ Optional Libraries: installed (optional) --disable-fluidsynth disable fluidsynth MIDI driver [autodetect] + --with-ieee1284-prefix=DIR prefix where libieee1284 is installed (optional) + --enable-opl2lpt enable OPL2LPT support + --with-sparkle-prefix=DIR prefix where sparkle is installed (OS X/Windows only - optional) --disable-sparkle disable sparkle automatic update support @@ -1134,6 +1138,8 @@ for ac_option in $@; do --disable-vorbis) _vorbis=no ;; --enable-tremor) _tremor=yes ;; --disable-tremor) _tremor=no ;; + --enable-opl2lpt) _opl2lpt=yes ;; + --disable-opl2lpt) _opl2lpt=no ;; --enable-flac) _flac=yes ;; --disable-flac) _flac=no ;; --enable-mad) _mad=yes ;; @@ -1230,6 +1236,11 @@ for ac_option in $@; do TREMOR_CFLAGS="-I$arg/include" TREMOR_LIBS="-L$arg/lib" ;; + --with-ieee1284-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + IEEE1284_CFLAGS="-I$arg/include" + IEEE1284_LIBS="-L$arg/lib" + ;; --with-flac-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` FLAC_CFLAGS="-I$arg/include" @@ -4023,6 +4034,27 @@ add_to_config_mk_if_yes "$_tremor" 'USE_TREMOR = 1' echo "$_tremor" # +# Check for IEEE1284 for OPL2lPT +# +echocheck "OPL2LPT" +if test "$_opl2lpt" = yes ; then + _opl2lpt=no + cat > $TMPC << EOF +#include <ieee1284.h> +struct parport_list parports; +int main(void) { ieee1284_find_ports(&parports, 0); return 0; } +EOF + cc_check $IEEE1284_CFLAGS $IEEE1284_LIBS -lieee1284 && \ + _opl2lpt=yes +fi +if test "$_opl2lpt" = yes; then + append_var LIBS "$IEEE1284_LIBS -lieee1284" + append_var INCLUDES "$IEEE1284_CFLAGS" +fi +define_in_config_if_yes "$_opl2lpt" 'ENABLE_OPL2LPT' +echo "$_opl2lpt" + +# # Check for FLAC # echocheck "FLAC >= 1.0.1" |