Only set interface palette when painting backdrop. (This fixes movie palette.)
[scummvm-innocent.git] / sound / fmopl.cpp
blob9fc57ff027b79be2618b5abe1486c5c04d10c043
1 /* ScummVM - Graphic Adventure Engine
3 * ScummVM is the legal property of its developers, whose names
4 * are too numerous to list here. Please refer to the COPYRIGHT
5 * file distributed with this source distribution.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * $URL$
22 * $Id$
25 #include "sound/fmopl.h"
27 #include "sound/softsynth/opl/dosbox.h"
28 #include "sound/softsynth/opl/mame.h"
30 #include "common/config-manager.h"
32 namespace OPL {
34 // Config implementation
36 enum OplEmulator {
37 kAuto = 0,
38 kMame = 1,
39 kDOSBox = 2
42 const Config::EmulatorDescription Config::_drivers[] = {
43 { "auto", "<default>", kAuto, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
44 { "mame", "MAME OPL emulator", kMame, kFlagOpl2 },
45 #ifndef DISABLE_DOSBOX_OPL
46 { "db", "DOSBox OPL emulator (experimental)", kDOSBox, kFlagOpl2 | kFlagDualOpl2 | kFlagOpl3 },
47 #endif
48 { 0, 0, 0, 0 }
51 Config::DriverId Config::parse(const Common::String &name) {
52 for (int i = 0; _drivers[i].name; ++i) {
53 if (name.equalsIgnoreCase(_drivers[i].name))
54 return _drivers[i].id;
57 return -1;
60 Config::DriverId Config::detect(OplType type) {
61 uint32 flags = 0;
62 switch (type) {
63 case kOpl2:
64 flags = kFlagOpl2;
65 break;
67 case kDualOpl2:
68 flags = kFlagDualOpl2;
69 break;
71 case kOpl3:
72 flags = kFlagOpl3;
73 break;
76 DriverId drv = parse(ConfMan.get("opl_driver"));
78 // When a valid driver is selected, check whether it supports
79 // the requested OPL chip.
80 if (drv != -1 && drv != kAuto) {
81 // If the chip is supported, just use the driver.
82 if ((flags & _drivers[drv].flags))
83 return drv;
84 // When it doesn't support the flags fall back to auto detection
85 else
86 drv = -1;
89 // Detect the first matching emulator
90 for (int i = 1; _drivers[i].name; ++i) {
91 if (_drivers[i].flags & flags) {
92 drv = _drivers[i].id;
93 break;
97 return drv;
100 OPL *Config::create(DriverId driver, OplType type) {
101 // On invalid driver selection, we try to do some fallback detection
102 if (driver == -1) {
103 warning("Invalid OPL driver selected, trying to detect a fallback emulator");
104 driver = kAuto;
107 // If autodetection is selected, we search for a matching
108 // driver.
109 if (driver == kAuto) {
110 driver = detect(type);
112 // No emulator for the specified OPL chip could
113 // be found, thus stop here.
114 if (driver == -1) {
115 warning("No OPL emulator available for type %d", type);
116 return 0;
120 switch (driver) {
121 case kMame:
122 if (type == kOpl2)
123 return new MAME::OPL();
124 else
125 warning("MAME OPL emulator only supports OPL2 emulation.");
126 return 0;
128 #ifndef DISABLE_DOSBOX_OPL
129 case kDOSBox:
130 return new DOSBox::OPL(type);
131 #endif
133 default:
134 warning("Unsupported OPL emulator %d", driver);
135 // TODO: Maybe we should add some dummy emulator too, which just outputs
136 // silence as sound?
137 return 0;
141 bool OPL::_hasInstance = false;
143 } // end of namespace OPL
145 void OPLDestroy(FM_OPL *OPL) {
146 delete OPL;
149 void OPLResetChip(FM_OPL *OPL) {
150 OPL->reset();
153 void OPLWrite(FM_OPL *OPL, int a, int v) {
154 OPL->write(a, v);
157 unsigned char OPLRead(FM_OPL *OPL, int a) {
158 return OPL->read(a);
161 void OPLWriteReg(FM_OPL *OPL, int r, int v) {
162 OPL->writeReg(r, v);
165 void YM3812UpdateOne(FM_OPL *OPL, int16 *buffer, int length) {
166 OPL->readBuffer(buffer, length);
169 FM_OPL *makeAdlibOPL(int rate) {
170 FM_OPL *opl = OPL::Config::create();
172 if (opl) {
173 if (!opl->init(rate)) {
174 delete opl;
175 opl = 0;
179 return opl;