~ubuntu-branches/debian/jessie/scummvm/jessie

« back to all changes in this revision

Viewing changes to engines/scumm/sound.cpp

  • Committer: Package Import Robot
  • Author(s): Moritz Muehlenhoff
  • Date: 2011-11-05 10:29:43 UTC
  • mto: This revision was merged to the branch mainline in revision 25.
  • Revision ID: package-import@ubuntu.com-20111105102943-zfm3dhlvy5b01u7v
Tags: upstream-1.4.0
ImportĀ upstreamĀ versionĀ 1.4.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
18
18
 * along with this program; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
20
 *
21
 
 * $URL$
22
 
 * $Id$
23
 
 *
24
21
 */
25
22
 
26
23
#include "common/config-manager.h"
32
29
#include "scumm/imuse/imuse.h"
33
30
#include "scumm/imuse_digi/dimuse.h"
34
31
#include "scumm/player_towns.h"
 
32
#include "scumm/resource.h"
35
33
#include "scumm/scumm.h"
36
34
#include "scumm/sound.h"
37
35
#include "scumm/util.h"
86
84
        memset(_soundQue, 0, sizeof(_soundQue));
87
85
        memset(_soundQue2, 0, sizeof(_soundQue2));
88
86
        memset(_mouthSyncTimes, 0, sizeof(_mouthSyncTimes));
 
87
 
 
88
        _musicType = MDT_NONE;
89
89
}
90
90
 
91
91
Sound::~Sound() {
314
314
                sound = (byte *)malloc(size);
315
315
                memcpy(sound, ptr + 6, size);
316
316
                stream = Audio::makeRawStream(sound, size, rate, Audio::FLAG_UNSIGNED);
317
 
                _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);                 
 
317
                _mixer->playStream(Audio::Mixer::kSFXSoundType, NULL, stream, soundID);
318
318
        }
319
319
        else if (_vm->_game.platform != Common::kPlatformFMTowns && READ_BE_UINT32(ptr) == MKTAG('S','O','U','N')) {
320
320
                if (_vm->_game.version != 3)
1018
1018
        // appears.
1019
1019
 
1020
1020
        _vm->getTimerManager()->removeTimerProc(&cd_timer_handler);
1021
 
        _vm->getTimerManager()->installTimerProc(&cd_timer_handler, 100700, _vm);
 
1021
        _vm->getTimerManager()->installTimerProc(&cd_timer_handler, 100700, _vm, "scummCDtimer");
1022
1022
}
1023
1023
 
1024
1024
void Sound::stopCDTimer() {
1066
1066
#pragma mark --- Sound resource handling ---
1067
1067
#pragma mark -
1068
1068
 
1069
 
static void convertMac0Resource(ResourceManager *res, int idx, byte *src_ptr, int size);
 
1069
static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size);
1070
1070
 
1071
1071
 
1072
1072
/*
1076
1076
 * could stand a thorough cleanup!
1077
1077
 */
1078
1078
 
1079
 
int ScummEngine::readSoundResource(int idx) {
 
1079
int ScummEngine::readSoundResource(ResId idx) {
1080
1080
        uint32 pos, total_size, size, tag, basetag, max_total_size;
1081
1081
        int pri, best_pri;
1082
1082
        uint32 best_size = 0, best_offs = 0;
1096
1096
        switch (basetag) {
1097
1097
        case MKTAG('M','I','D','I'):
1098
1098
        case MKTAG('i','M','U','S'):
1099
 
                if (_musicType != MDT_PCSPK && _musicType != MDT_PCJR) {
 
1099
                if (_sound->_musicType != MDT_PCSPK && _sound->_musicType != MDT_PCJR) {
1100
1100
                        _fileHandle->seek(-8, SEEK_CUR);
1101
1101
                        _fileHandle->read(_res->createResource(rtSound, idx, total_size + 8), total_size + 8);
1102
1102
                        return 1;
1120
1120
                                break;
1121
1121
                        case MKTAG('A','D','L',' '):
1122
1122
                                pri = 1;
1123
 
                                if (_musicType == MDT_ADLIB)
 
1123
                                if (_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS)
1124
1124
                                        pri = 10;
1125
1125
                                break;
1126
1126
                        case MKTAG('A','M','I',' '):
1139
1139
                                break;
1140
1140
                        case MKTAG('S','P','K',' '):
1141
1141
                                pri = -1;
1142
 
//                              if (_musicType == MDT_PCSPK || _musicType == MDT_PCJR)
1143
 
//                                      pri = 11;
 
1142
                                if (_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR)
 
1143
                                        pri = 11;
1144
1144
                                break;
1145
1145
                        }
1146
1146
 
1147
 
                        if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR || _musicType == MDT_CMS) && pri != 11)
 
1147
                        // We only allow SPK resources for PC Speaker and PCJr here
 
1148
                        // since other resource would sound horribly with their output
 
1149
                        // drivers.
 
1150
                        if ((_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR) && pri != 11)
 
1151
                                pri = -1;
 
1152
 
 
1153
                        // We only allow ADL, SBL and TOWS resources when AdLib
 
1154
                        // or FM-Towns is used as primary audio output. This fixes some
 
1155
                        // odd sounds when Indy and Sophia leave Atlantis with the
 
1156
                        // submarine in Indy4. (Easy to check with bootparam 4061 in
 
1157
                        // the CD version). It seems the game only contains a ROL resource
 
1158
                        // for sound id 60. Formerly we tried to play that via the AdLib
 
1159
                        // or FM-Towns audio driver resulting in strange noises. Now we
 
1160
                        // behave like the original did.
 
1161
                        // We make an exception for Macintosh, which uses priority 2 for
 
1162
                        // its sound resources, and Amiga games, which feature only ROL
 
1163
                        // resources, since we are a doing Midi -> AdLib conversion for
 
1164
                        // these.
 
1165
                        if ((_sound->_musicType == MDT_ADLIB || _sound->_musicType == MDT_TOWNS) && pri != 16 
 
1166
                                && pri != 15 && pri != 10 && pri != 2 && _game.platform != Common::kPlatformAmiga)
1148
1167
                                pri = -1;
1149
1168
 
1150
1169
                        debugC(DEBUG_RESOURCE, "    tag: %s, total_size=%d, pri=%d", tag2str(tag), size, pri);
1151
1170
 
1152
 
 
1153
1171
                        if (pri > best_pri) {
1154
1172
                                best_pri = pri;
1155
1173
                                best_size = size;
1226
1244
 
1227
1245
                if (!dmuFile.open(buffer)) {
1228
1246
                        error("Can't open music file %s", buffer);
1229
 
                        _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET;
 
1247
                        _res->_types[rtSound][idx]._roomoffs = RES_INVALID_OFFSET;
1230
1248
                        return 0;
1231
1249
                }
1232
1250
                dmuFile.seek(4, SEEK_SET);
1250
1268
                }
1251
1269
                error("Unrecognized base tag 0x%08x in sound %d", basetag, idx);
1252
1270
        }
1253
 
        _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET;
 
1271
        _res->_types[rtSound][idx]._roomoffs = RES_INVALID_OFFSET;
1254
1272
        return 0;
1255
1273
}
1256
1274
 
1429
1447
        }
1430
1448
}
1431
1449
 
1432
 
static void convertMac0Resource(ResourceManager *res, int idx, byte *src_ptr, int size) {
 
1450
static void convertMac0Resource(ResourceManager *res, ResId idx, byte *src_ptr, int size) {
1433
1451
        /*
1434
1452
        From Markus Magnuson (superqult) we got this information:
1435
1453
        Mac0
1620
1638
#endif
1621
1639
}
1622
1640
 
1623
 
static void convertADResource(ResourceManager *res, const GameSettings& game, int idx, byte *src_ptr, int size) {
 
1641
static void convertADResource(ResourceManager *res, const GameSettings& game, ResId idx, byte *src_ptr, int size) {
1624
1642
        // We will ignore the PPQN in the original resource, because
1625
1643
        // it's invalid anyway. We use a constant PPQN of 480.
1626
1644
        const int ppqn = 480;
1986
2004
                                break;
1987
2005
 
1988
2006
                        case 0x80:
 
2007
                                // FIXME: This is incorrect. The original uses 0x80 for
 
2008
                                // looping a single channel. We currently interpret it as stop
 
2009
                                // thus we won't get looping for sound effects. It should
 
2010
                                // always jump to the start of the channel.
 
2011
                                //
 
2012
                                // Since we convert the data to MIDI and we cannot only loop a
 
2013
                                // single channel via MIDI fixing this will require some more
 
2014
                                // thought.
1989
2015
                                track_time[ch] = -1;
1990
2016
                                src_ptr ++;
1991
2017
                                break;
2003
2029
}
2004
2030
 
2005
2031
 
2006
 
int ScummEngine::readSoundResourceSmallHeader(int idx) {
 
2032
int ScummEngine::readSoundResourceSmallHeader(ResId idx) {
2007
2033
        uint32 pos, total_size, size, tag;
2008
2034
        uint32 ad_size = 0, ad_offs = 0;
2009
2035
        uint32 ro_size = 0, ro_offs = 0;
2076
2102
                }
2077
2103
        }
2078
2104
 
2079
 
        if ((_musicType == MDT_PCSPK || _musicType == MDT_PCJR) && wa_offs != 0) {
 
2105
        if ((_sound->_musicType == MDT_PCSPK || _sound->_musicType == MDT_PCJR) && wa_offs != 0) {
2080
2106
                if (_game.features & GF_OLD_BUNDLE) {
2081
2107
                        _fileHandle->seek(wa_offs, SEEK_SET);
2082
2108
                        _fileHandle->read(_res->createResource(rtSound, idx, wa_size), wa_size);
2085
2111
                        _fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6);
2086
2112
                }
2087
2113
                return 1;
2088
 
        } else if (_musicType == MDT_CMS && ad_offs != 0) {
 
2114
        } else if (_sound->_musicType == MDT_CMS) {
2089
2115
                if (_game.features & GF_OLD_BUNDLE) {
2090
 
                        _fileHandle->seek(wa_offs + wa_size + 6, SEEK_SET);
2091
 
                        byte musType = _fileHandle->readByte();
2092
 
 
2093
 
                        if (musType == 0x80) {
 
2116
                        bool hasAdLibMusicTrack = false;
 
2117
 
 
2118
                        if (ad_offs) {
 
2119
                                _fileHandle->seek(ad_offs + 4 + 2, SEEK_SET);
 
2120
                                hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80);
 
2121
                        }
 
2122
 
 
2123
                        if (hasAdLibMusicTrack) {
2094
2124
                                _fileHandle->seek(ad_offs, SEEK_SET);
2095
2125
                                _fileHandle->read(_res->createResource(rtSound, idx, ad_size), ad_size);
2096
2126
                        } else {
2097
2127
                                _fileHandle->seek(wa_offs, SEEK_SET);
2098
2128
                                _fileHandle->read(_res->createResource(rtSound, idx, wa_size), wa_size);
2099
2129
                        }
 
2130
                } else {
 
2131
                        bool hasAdLibMusicTrack = false;
 
2132
 
 
2133
                        if (ad_offs) {
 
2134
                                _fileHandle->seek(ad_offs + 2, SEEK_SET);
 
2135
                                hasAdLibMusicTrack = (_fileHandle->readByte() == 0x80);
 
2136
                        }
 
2137
 
 
2138
                        if (hasAdLibMusicTrack) {
 
2139
                                _fileHandle->seek(ad_offs - 4, SEEK_SET);
 
2140
                                _fileHandle->read(_res->createResource(rtSound, idx, ad_size + 4), ad_size + 4);
 
2141
                        } else {
 
2142
                                _fileHandle->seek(wa_offs - 6, SEEK_SET);
 
2143
                                _fileHandle->read(_res->createResource(rtSound, idx, wa_size + 6), wa_size + 6);
 
2144
                        }
2100
2145
                }
2101
2146
        } else if (ad_offs != 0) {
2102
2147
                // AD resources have a header, instrument definitions and one MIDI track.
2125
2170
                _fileHandle->read(_res->createResource(rtSound, idx, ro_size - 4), ro_size - 4);
2126
2171
                return 1;
2127
2172
        }
2128
 
        _res->roomoffs[rtSound][idx] = RES_INVALID_OFFSET;
 
2173
        _res->_types[rtSound][idx]._roomoffs = RES_INVALID_OFFSET;
2129
2174
        return 0;
2130
2175
}
2131
2176