[Scummvm-cvs-logs] CVS: scummvm/scumm player_mod.cpp,NONE,2.1 player_mod.h,NONE,2.1 player_v2a.cpp,NONE,2.1 player_v2a.h,NONE,2.1 debugger.cpp,1.89,1.90 module.mk,1.25,1.26 player_v3a.cpp,1.11,1.12 player_v3a.h,1.8,1.9 scumm.h,1.303,1.304 scummvm.cpp,2.400,2.401 sound.cpp,1.254,1.255
Travis Howell
kirben at users.sourceforge.net
Tue Sep 23 23:58:02 CEST 2003
Update of /cvsroot/scummvm/scummvm/scumm
In directory sc8-pr-cvs1:/tmp/cvs-serv13731/scumm
Modified Files:
debugger.cpp module.mk player_v3a.cpp player_v3a.h scumm.h
scummvm.cpp sound.cpp
Added Files:
player_mod.cpp player_mod.h player_v2a.cpp player_v2a.h
Log Message:
More Amiga V2/V3 sound updates from _Q_:
1. A Player_MOD class, basically acts as a simplified mixer that mixes at 60Hz intervals (or whatever interval you specify), this gives smooth music playback in player_v3a
2. Some changes to player_v3a as a result of #1, including reduced music volume
3. player_v2a, and the necessary additions to scummvm.cpp/scumm.h
--- NEW FILE: player_mod.cpp ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/scumm/player_mod.cpp,v 2.1 2003/09/24 06:56:30 kirben Exp $
*
*/
#include "player_mod.h"
////////////////////////////////////////
//
// Generic Amiga MOD mixer - provides a 60Hz 'update' routine.
//
////////////////////////////////////////
Player_MOD::Player_MOD(Scumm *scumm) {
int i;
_mixer = scumm->_mixer;
_samplerate = scumm->_system->property(OSystem::PROP_GET_SAMPLE_RATE, 0);
_mixamt = 0;
_mixpos = 0;
for (i = 0; i < MOD_MAXCHANS; i++) {
_channels[i].id = 0;
_channels[i].vol = 0;
_channels[i].freq = 0;
_channels[i].ptr = NULL;
_channels[i].converter = NULL;
_channels[i].input = NULL;
}
_playproc = NULL;
_playparam = NULL;
_mixer->setupPremix(premix_proc, this);
}
Player_MOD::~Player_MOD() {
// Detach the premix callback handler
_mixer->setupPremix(0, 0);
for (int i = 0; i < MOD_MAXCHANS; i++) {
if (!_channels[i].id)
continue;
delete _channels[i].ptr;
delete _channels[i].converter;
delete _channels[i].input;
}
}
void Player_MOD::setMasterVolume (int vol) {
_maxvol = vol;
}
void Player_MOD::setUpdateProc(ModUpdateProc *proc, void *param, int freq) {
_playproc = proc;
_playparam = param;
_mixamt = _samplerate / freq;
}
void Player_MOD::clearUpdateProc() {
_playproc = NULL;
_playparam = NULL;
_mixamt = 0;
}
void Player_MOD::startChannel (int id, const char *data, int size, int rate, uint8 vol, int loopStart, int loopEnd, int8 pan) {
int i;
if (id == 0)
error("player_mod - attempted to start channel id 0");
for (i = 0; i < MOD_MAXCHANS; i++) {
if (!_channels[i].id)
break;
}
if (i == MOD_MAXCHANS) {
warning("player_mod - too many music channels playing (%i max)",MOD_MAXCHANS);
return;
}
_channels[i].id = id;
_channels[i].vol = vol;
_channels[i].pan = pan;
_channels[i].ptr = (byte *)data;
_channels[i].freq = rate;
_channels[i].input = makeLinearInputStream(SoundMixer::FLAG_AUTOFREE | (loopStart != loopEnd ? SoundMixer::FLAG_LOOP : 0), (byte *)data, size, loopStart, loopEnd - loopStart);
_channels[i].converter = makeRateConverter(rate, _mixer->getOutputRate(), false, false);
}
void Player_MOD::stopChannel(int id) {
if (id == 0)
error("player_mod - attempted to stop channel id 0");
for (int i = 0; i < MOD_MAXCHANS; i++) {
if (_channels[i].id == id) {
delete _channels[i].ptr;
_channels[i].ptr = NULL;
delete _channels[i].converter;
_channels[i].converter = NULL;
delete _channels[i].input;
_channels[i].input = NULL;
_channels[i].id = 0;
_channels[i].vol = 0;
_channels[i].freq = 0;
}
}
}
void Player_MOD::setChannelVol(int id, uint8 vol) {
if (id == 0)
error("player_mod - attempted to set volume for channel id 0");
for (int i = 0; i < MOD_MAXCHANS; i++) {
if (_channels[i].id == id) {
_channels[i].vol = vol;
break;
}
}
}
void Player_MOD::setChannelPan(int id, int8 pan) {
if (id == 0)
error("player_mod - attempted to set pan for channel id 0");
for (int i = 0; i < MOD_MAXCHANS; i++) {
if (_channels[i].id == id) {
_channels[i].pan = pan;
break;
}
}
}
void Player_MOD::setChannelFreq(int id, int freq) {
if (id == 0)
error("player_mod - attempted to set frequency for channel id 0");
for (int i = 0; i < MOD_MAXCHANS; i++) {
if (_channels[i].id == id) {
_channels[i].freq = freq;
delete _channels[i].converter;
_channels[i].converter = makeRateConverter(freq, _mixer->getOutputRate(), false, false);
break;
}
}
}
void Player_MOD::premix_proc(void *param, int16 *buf, uint len) {
((Player_MOD *) param)->do_mix(buf, len);
}
void Player_MOD::do_mix (int16 *data, uint len) {
int i;
int dpos = 0;
uint dlen = 0;
memset(data, 0, 2 * len * sizeof(int16));
while (len) {
if (_playproc) {
dlen = _mixamt - _mixpos;
if (!_mixpos)
_playproc(_playparam);
if (dlen <= len) {
_mixpos = 0;
len -= dlen;
} else {
_mixpos = _mixamt - len;
dlen = len;
len = 0;
}
} else {
dlen = len;
len = 0;
}
for (i = 0; i < MOD_MAXCHANS; i++)
if (_channels[i].id) {
st_volume_t vol_l = (127 - _channels[i].pan) * _channels[i].vol / 127;
st_volume_t vol_r = (127 + _channels[i].pan) * _channels[i].vol / 127;
_channels[i].converter->flow(*_channels[i].input, &data[dpos*2], dlen, vol_l, vol_r);
}
dpos += dlen;
}
}
--- NEW FILE: player_mod.h ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/scumm/player_mod.h,v 2.1 2003/09/24 06:56:30 kirben Exp $
*
*/
#ifndef PLAYER_MOD_H
#define PLAYER_MOD_H
#include "scumm.h"
#include "sound/mixer.h"
#include "sound/audiostream.h"
#include "sound/rate.h"
#define MOD_MAXCHANS 16
class Player_MOD {
public:
Player_MOD(Scumm *scumm);
virtual ~Player_MOD();
virtual void setMasterVolume(int vol);
virtual void startChannel(int id, const char *data, int size, int rate, uint8 vol, int loopStart = 0, int loopEnd = 0, int8 pan = 0);
virtual void stopChannel(int id);
virtual void setChannelVol(int id, uint8 vol);
virtual void setChannelPan(int id, int8 pan);
virtual void setChannelFreq(int id, int freq);
typedef void ModUpdateProc(void *param);
virtual void setUpdateProc(ModUpdateProc *proc, void *param, int freq);
virtual void clearUpdateProc();
private:
SoundMixer *_mixer;
uint32 _mixamt;
uint32 _mixpos;
int _samplerate;
struct soundChan
{
int id;
uint8 vol;
int8 pan;
uint16 freq;
byte *ptr;
RateConverter *converter;
AudioInputStream *input;
} _channels[MOD_MAXCHANS];
uint8 _maxvol;
static void premix_proc(void *param, int16 *buf, uint len);
virtual void do_mix(int16 *buf, uint len);
ModUpdateProc *_playproc;
void *_playparam;
};
#endif
--- NEW FILE: player_v2a.cpp ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/scumm/player_v2a.cpp,v 2.1 2003/09/24 06:56:30 kirben Exp $
[...1268 lines suppressed...]
for (i = 0; i < V2A_MAXSLOTS; i++) {
if ((_slot[i].id) && (!_slot[i].sound->update())) {
_slot[i].sound->stop();
_slot[i].sound = NULL;
_slot[i].id = 0;
}
}
}
int Player_V2A::getMusicTimer() const {
return 0; // FIXME - need to keep track of playing music resources
}
int Player_V2A::getSoundStatus(int nr) const {
for (int i = 0; i < V2A_MAXSLOTS; i++) {
if (_slot[i].id == nr)
return 1;
}
return 0;
}
--- NEW FILE: player_v2a.h ---
/* ScummVM - Scumm Interpreter
* Copyright (C) 2001 Ludvig Strigeus
* Copyright (C) 2001-2003 The ScummVM project
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* $Header: /cvsroot/scummvm/scummvm/scumm/player_v2a.h,v 2.1 2003/09/24 06:56:30 kirben Exp $
*
*/
#ifndef PLAYER_V2A_H
#define PLAYER_V2A_H
#include "common/scummsys.h"
#include "common/system.h"
#include "scumm/music.h"
#include "scumm/player_mod.h"
#define V2A_MAXSLOTS 8
class Scumm;
class SoundMixer;
class V2A_Sound;
class Player_V2A : public MusicEngine {
public:
Player_V2A(Scumm *scumm);
virtual ~Player_V2A();
virtual void setMasterVolume(int vol);
virtual void startSound(int nr);
virtual void stopSound(int nr);
virtual void stopAllSounds();
virtual int getMusicTimer() const;
virtual int getSoundStatus(int nr) const;
private:
OSystem *_system;
Scumm *_scumm;
Player_MOD *_mod;
struct soundSlot
{
int id;
V2A_Sound *sound;
} _slot[V2A_MAXSLOTS];
int getSoundSlot (int id = 0) const;
static void update_proc(void *param);
void updateSound();
};
#endif
Index: debugger.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/debugger.cpp,v
retrieving revision 1.89
retrieving revision 1.90
diff -u -d -r1.89 -r1.90
--- debugger.cpp 24 Sep 2003 06:33:58 -0000 1.89
+++ debugger.cpp 24 Sep 2003 06:56:30 -0000 1.90
@@ -361,7 +361,7 @@
}
bool ScummDebugger::Cmd_IMuse(int argc, const char **argv) {
- if (!_s->_imuse && !_s->_playerV2) {
+ if (!_s->_imuse && !_s->_musicEngine) {
Debug_Printf("No iMuse engine is active.\n");
return true;
}
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/module.mk,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- module.mk 18 Sep 2003 13:03:56 -0000 1.25
+++ module.mk 24 Sep 2003 06:56:30 -0000 1.26
@@ -22,9 +22,11 @@
scumm/midiparser_eup.o \
scumm/nut_renderer.o \
scumm/object.o \
- scumm/player_v1.o\
- scumm/player_v2.o\
- scumm/player_v3a.o\
+ scumm/player_mod.o \
+ scumm/player_v1.o \
+ scumm/player_v2.o \
+ scumm/player_v2a.o \
+ scumm/player_v3a.o \
scumm/resource.o \
scumm/resource_v2.o \
scumm/resource_v3.o \
Index: player_v3a.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v3a.cpp,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- player_v3a.cpp 18 Sep 2003 19:56:38 -0000 1.11
+++ player_v3a.cpp 24 Sep 2003 06:56:30 -0000 1.12
@@ -24,8 +24,6 @@
#include "base/engine.h"
#include "player_v3a.h"
#include "scumm.h"
-#include "sound/mixer.h"
-#include "common/timer.h"
static const uint16 note_freqs[4][12] = {
{0x06B0,0x0650,0x05F4,0x05A0,0x054C,0x0500,0x04B8,0x0474,0x0434,0x03F8,0x03C0,0x0388},
@@ -44,13 +42,14 @@
int i;
_scumm = scumm;
_system = scumm->_system;
- _mixer = scumm->_mixer;
-
- for (i = 0; i < V3A_MAXSFX; i++)
- _sfx[i].id = _sfx[i].dur = 0;
-
- for (i = 0; i < V3A_MAXMUS; i++)
- _mus[i].id = _mus[i].dur = 0;
+ for (i = 0; i < V3A_MAXMUS; i++) {
+ _mus[i].id = 0;
+ _mus[i].dur = 0;
+ }
+ for (i = 0; i < V3A_MAXSFX; i++) {
+ _sfx[i].id = 0;
+ _sfx[i].dur = 0;
+ }
_curSong = 0;
_songData = NULL;
@@ -59,36 +58,63 @@
_music_timer = 0;
- _maxvol = 255;
-
- scumm->_timer->installProcedure(timerHandler, 16666, this);
-
_isinit = false;
+
+ _mod = new Player_MOD(scumm);
+ _mod->setUpdateProc(update_proc, this, 60);
}
Player_V3A::~Player_V3A() {
- _scumm->_timer->releaseProcedure(timerHandler);
- if (!_isinit)
- return;
- for (int i = 0; _wavetable[i] != NULL; i++) {
- for (int j = 0; j < 6; j++) {
- free(_wavetable[i]->_idat[j]);
- free(_wavetable[i]->_ldat[j]);
+ int i;
+ delete _mod;
+ if (_isinit) {
+ for (i = 0; _wavetable[i] != NULL; i++) {
+ for (int j = 0; j < 6; j++) {
+ free(_wavetable[i]->_idat[j]);
+ free(_wavetable[i]->_ldat[j]);
+ }
+ free(_wavetable[i]);
}
- free(_wavetable[i]);
+ free(_wavetable);
}
- free(_wavetable);
}
void Player_V3A::setMasterVolume (int vol) {
- _maxvol = vol;
+ _mod->setMasterVolume(vol);
+}
+
+int Player_V3A::getMusChan (int id) const {
+ int i;
+ for (i = 0; i < V3A_MAXMUS; i++) {
+ if (_mus[i].id == id)
+ break;
+ }
+ if (i == V3A_MAXMUS) {
+ if (id == 0)
+ warning("player_v3a - out of music channels");
+ return -1;
+ }
+ return i;
+}
+int Player_V3A::getSfxChan (int id) const {
+ int i;
+ for (i = 0; i < V3A_MAXSFX; i++) {
+ if (_sfx[i].id == id)
+ break;
+ }
+ if (i == V3A_MAXSFX) {
+ if (id == 0)
+ warning("player_v3a - out of sfx channels");
+ return -1;
+ }
+ return i;
}
void Player_V3A::stopAllSounds() {
int i;
for (i = 0; i < V3A_MAXMUS; i++) {
if (_mus[i].id)
- _mixer->stopID(V3A_MUS_BASEID + i);
+ _mod->stopChannel(_mus[i].id);
_mus[i].id = 0;
_mus[i].dur = 0;
}
@@ -98,7 +124,7 @@
_songData = NULL;
for (i = 0; i < V3A_MAXSFX; i++) {
if (_sfx[i].id)
- _mixer->stopID(V3A_SFX_BASEID + i);
+ _mod->stopChannel(_sfx[i].id | 0x100);
_sfx[i].id = 0;
_sfx[i].dur = 0;
}
@@ -106,10 +132,14 @@
void Player_V3A::stopSound(int nr) {
int i;
+ if (nr == 0) { // Amiga Loom does this near the end, when Chaos casts SILENCE on Hetchel
+ stopAllSounds();
+ return;
+ }
if (nr == _curSong) {
for (i = 0; i < V3A_MAXMUS; i++) {
if (_mus[i].id)
- _mixer->stopID(V3A_MUS_BASEID + i);
+ _mod->stopChannel(_mus[i].id);
_mus[i].id = 0;
_mus[i].dur = 0;
}
@@ -118,59 +148,21 @@
_songDelay = 0;
_songData = NULL;
} else {
- for (i = 0; i < V3A_MAXSFX; i++) {
- if (_sfx[i].id == nr) {
- _mixer->stopID(V3A_SFX_BASEID + i);
- _sfx[i].id = 0;
- _sfx[i].dur = 0;
- break;
- }
+ i = getSfxChan(nr);
+ if (i != -1) {
+ _mod->stopChannel(nr | 0x100);
+ _sfx[i].id = 0;
+ _sfx[i].dur = 0;
}
}
}
-void Player_V3A::playSoundSFX (int nr, char *data, int size, int rate, int vol, int tl, bool looped, int loopStart, int loopEnd) {
- int i;
- for (i = 0; i < V3A_MAXSFX; i++) {
- if (!_sfx[i].id)
- break;
- }
- if (i == V3A_MAXSFX) {
- warning("player_v3a - too many sound effects playing (%i max)",V3A_MAXSFX);
- return;
- }
- _sfx[i].id = nr;
- _sfx[i].dur = tl;
-
- vol = (vol * _maxvol) / 255;
- _mixer->playRaw(NULL, data, size, rate, SoundMixer::FLAG_AUTOFREE | (looped ? SoundMixer::FLAG_LOOP : 0),
- V3A_SFX_BASEID + i, vol, 0, loopStart, loopEnd);
-}
-
-void Player_V3A::playSoundMUS (char *data, int size, int rate, int vol, int tl, bool looped, int loopStart, int loopEnd) {
- int i;
- for (i = 0; i < V3A_MAXMUS; i++) {
- if (!_mus[i].id)
- break;
- }
- if (i == V3A_MAXMUS) {
- warning("player_v3a - too many music channels playing (%i max)",V3A_MAXMUS);
- return;
- }
- _mus[i].id = i + 1;
- _mus[i].dur = tl;
-
- vol = (vol * _maxvol) / 255;
- _mixer->playRaw(NULL, data, size, rate, SoundMixer::FLAG_AUTOFREE | (looped ? SoundMixer::FLAG_LOOP : 0),
- V3A_MUS_BASEID + i, vol, 0, loopStart, loopEnd);
-}
-
void Player_V3A::startSound(int nr) {
assert(_scumm);
byte *data = _scumm->getResourceAddress(rtSound, nr);
assert(data);
- if (_scumm->_gameId != GID_INDY3 && _scumm->_gameId != GID_LOOM)
+ if ((_scumm->_gameId != GID_INDY3) && (_scumm->_gameId != GID_LOOM))
error("player_v3a - unknown game!");
if (!_isinit) {
@@ -223,6 +215,8 @@
stopSound(nr); // if a sound is playing, restart it
if (data[26]) {
+ if (_curSong)
+ stopSound(_curSong);
_curSong = nr;
_songData = data;
_songPtr = 0x1C;
@@ -232,43 +226,49 @@
int size = READ_BE_UINT16(data + 12);
int rate = 3579545 / READ_BE_UINT16(data + 20);
char *sound = (char *)malloc(size);
- int vol = (data[24] << 2) | (data[24] >> 4);
+ int vol = (data[24] << 1) | (data[24] >> 5); // if I boost this to 0-255, it gets too loud and starts to clip
memcpy(sound,data + READ_BE_UINT16(data + 8),size);
+ int loopStart = 0, loopEnd = 0;
+ bool looped = false;
if ((READ_BE_UINT16(data + 16) || READ_BE_UINT16(data + 6))) {
- // the first check is for complex (pitch-bending) looped sounds
- // the second check is for simple looped sounds
- int loopStart = READ_BE_UINT16(data + 10) - READ_BE_UINT16(data + 8);
- int loopEnd = READ_BE_UINT16(data + 14);
- int tl = -1;
- if ((_scumm->_gameId == GID_INDY3) && (nr == 60))
- tl = 240; // the "airplane dive" sound needs to end on its own - the game won't stop it
- playSoundSFX(nr, sound, size, rate, vol, tl, true, loopStart, loopEnd);
- } else {
- int tl = 1 + 60 * size / rate;
- playSoundSFX(nr, sound, size, rate, vol, tl, false);
+ loopStart = READ_BE_UINT16(data + 10) - READ_BE_UINT16(data + 8);
+ loopEnd = READ_BE_UINT16(data + 14);
+ looped = true;
}
+ int i = getSfxChan();
+ _sfx[i].id = nr;
+ _sfx[i].dur = looped ? -1 : (1 + 60 * size / rate);
+ if ((_scumm->_gameId == GID_INDY3) && (nr == 60))
+ _sfx[i].dur = 240;
+ _mod->startChannel(nr | 0x100, sound, size, rate, vol, loopStart, loopEnd);
}
}
-void Player_V3A::timerHandler(void *refCon) {
- Player_V3A *player = (Player_V3A *)refCon;
- assert(player);
- player->playMusic();
+void Player_V3A::update_proc(void *param) {
+ ((Player_V3A *)param)->playMusic();
}
void Player_V3A::playMusic() {
int i;
- for (i = 0; i < V3A_MAXSFX; i++) {
- if ((_sfx[i].dur) && (!--_sfx[i].dur))
- stopSound(_sfx[i].id);
- }
for (i = 0; i < V3A_MAXMUS; i++) {
- if ((_mus[i].dur) && (!--_mus[i].dur)) {
- _scumm->_mixer->stopID(V3A_MUS_BASEID + i);
+ if (_mus[i].id) {
+ _mus[i].dur--;
+ if (_mus[i].dur)
+ continue;
+ _mod->stopChannel(_mus[i].id);
_mus[i].id = 0;
- _mus[i].dur = 0;
}
}
+ for (i = 0; i < V3A_MAXSFX; i++) {
+ if (_sfx[i].id) {
+ _sfx[i].dur--;
+ if (_sfx[i].dur)
+ continue;
+ _mod->stopChannel(_sfx[i].id | 0x100);
+ _sfx[i].id = 0;
+ }
+ }
+
_music_timer++;
if (!_curSong)
return;
@@ -295,8 +295,7 @@
}
inst &= 0xF;
pit = _songData[_songPtr++];
- vol = _songData[_songPtr++] & 0x7F;
- vol = (vol << 1) | (vol >> 7); // 7-bit volume (Amiga drops the bottom bit), convert to 8-bit
+ vol = _songData[_songPtr++] & 0x7F; // if I boost this to 0-255, it gets too loud and starts to clip
dur = _songData[_songPtr++];
if (pit == 0) {
_songDelay = dur;
@@ -309,13 +308,18 @@
oct = 0;
if (oct > 5)
oct = 5;
+ int rate = 3579545 / note_freqs[_wavetable[inst]->_oct[oct]][pit];
char *data = (char *)malloc(_wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]);
if (_wavetable[inst]->_idat[oct])
memcpy(data, _wavetable[inst]->_idat[oct], _wavetable[inst]->_ilen[oct]);
if (_wavetable[inst]->_ldat[oct])
memcpy(data + _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ldat[oct], _wavetable[inst]->_llen[oct]);
- playSoundMUS(data, _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct], 3579545 / note_freqs[_wavetable[inst]->_oct[oct]][pit], vol, dur,
- (_wavetable[inst]->_ldat[oct] != NULL), _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]);
+
+ i = getMusChan();
+ _mus[i].id = i + 1;
+ _mus[i].dur = dur;
+ _mod->startChannel(_mus[i].id, data, _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct], rate, vol,
+ _wavetable[inst]->_ilen[oct], _wavetable[inst]->_ilen[oct] + _wavetable[inst]->_llen[oct]);
}
}
@@ -326,8 +330,7 @@
int Player_V3A::getSoundStatus(int nr) const {
if (nr == _curSong)
return 1;
- for (int i = 0; i < V3A_MAXSFX; i++)
- if (_sfx[i].id == nr)
- return 1;
+ if (getSfxChan(nr) != -1)
+ return 1;
return 0;
}
Index: player_v3a.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/player_v3a.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- player_v3a.h 18 Sep 2003 19:56:38 -0000 1.8
+++ player_v3a.h 24 Sep 2003 06:56:30 -0000 1.9
@@ -26,12 +26,10 @@
#include "common/scummsys.h"
#include "common/system.h"
#include "scumm/music.h"
+#include "scumm/player_mod.h"
-#define V3A_MAXMUS 8
-#define V3A_MAXSFX 8
-
-#define V3A_MUS_BASEID (1)
-#define V3A_SFX_BASEID (V3A_MUS_BASEID + V3A_MAXMUS)
+#define V3A_MAXMUS 8
+#define V3A_MAXSFX 8
class Scumm;
class SoundMixer;
@@ -42,26 +40,31 @@
virtual ~Player_V3A();
virtual void setMasterVolume(int vol);
-
virtual void startSound(int nr);
virtual void stopSound(int nr);
virtual void stopAllSounds();
virtual int getMusicTimer() const;
-
virtual int getSoundStatus(int nr) const;
-protected:
- SoundMixer *_mixer;
+private:
OSystem *_system;
Scumm *_scumm;
+ Player_MOD *_mod;
- struct soundChan
+ struct musChan
{
- uint16 id;
- uint16 dur;
- } _mus[V3A_MAXMUS], _sfx[V3A_MAXSFX];
-
- uint8 _maxvol;
+ int id;
+ int dur;
+ } _mus[V3A_MAXMUS];
+ int getMusChan (int id = 0) const;
+
+ struct sfxChan
+ {
+ int id;
+ int dur;
+ // SFX will eventually have pitch bends
+ } _sfx[V3A_MAXSFX];
+ int getSfxChan (int id = 0) const;
int _curSong;
uint8 *_songData;
@@ -80,11 +83,8 @@
int16 _pitadjust;
} **_wavetable;
- void playSoundSFX (int nr, char *data, int size, int rate, int vol, int tl, bool looped, int loopStart = 0, int loopEnd = 0);
- void playSoundMUS (char *data, int size, int rate, int vol, int tl, bool looped, int loopStart = 0, int loopEnd = 0);
-
+ static void update_proc(void *param);
void playMusic();
- static void timerHandler(void *engine);
};
#endif
Index: scumm.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scumm.h,v
retrieving revision 1.303
retrieving revision 1.304
diff -u -d -r1.303 -r1.304
--- scumm.h 18 Sep 2003 02:07:17 -0000 1.303
+++ scumm.h 24 Sep 2003 06:56:30 -0000 1.304
@@ -43,6 +43,7 @@
class MusicEngine;
class NewGui;
class Player_V2;
+class Player_V2A;
class Player_V3A;
class Scumm;
class ScummDebugger;
@@ -260,6 +261,7 @@
IMuse *_imuse;
IMuseDigital *_imuseDigital;
Player_V2 *_playerV2;
+ Player_V2A *_playerV2A;
Player_V3A *_playerV3A;
MusicEngine *_musicEngine;
Sound *_sound;
Index: scummvm.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/scummvm.cpp,v
retrieving revision 2.400
retrieving revision 2.401
diff -u -d -r2.400 -r2.401
--- scummvm.cpp 24 Sep 2003 05:59:32 -0000 2.400
+++ scummvm.cpp 24 Sep 2003 06:56:30 -0000 2.401
@@ -44,6 +44,7 @@
#include "scumm/object.h"
#include "scumm/player_v1.h"
#include "scumm/player_v2.h"
+#include "scumm/player_v2a.h"
#include "scumm/player_v3a.h"
#include "scumm/resource.h"
#include "scumm/scumm.h"
@@ -719,10 +720,13 @@
_imuse = NULL;
_imuseDigital = NULL;
_playerV2 = NULL;
+ _playerV2A = NULL;
_playerV3A = NULL;
_musicEngine = NULL;
if (_features & GF_DIGI_IMUSE) {
_musicEngine = _imuseDigital = new IMuseDigital(this);
+ } else if ((_features & GF_AMIGA) && (_version == 2)) {
+ _musicEngine = _playerV2A = new Player_V2A(this);
} else if ((_features & GF_AMIGA) && (_version == 3)) {
_musicEngine = _playerV3A = new Player_V3A(this);
} else if ((_features & GF_AMIGA) && (_version < 5)) {
@@ -1329,6 +1333,8 @@
// Covered automatically by the Sound class
} else if (_playerV2) {
VAR(VAR_MUSIC_TIMER) = _playerV2->getMusicTimer();
+ } else if (_playerV2A) {
+ VAR(VAR_MUSIC_TIMER) = _playerV2A->getMusicTimer();
} else if (_playerV3A) {
VAR(VAR_MUSIC_TIMER) = _playerV3A->getMusicTimer();
} else if (_imuse) {
Index: sound.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/scumm/sound.cpp,v
retrieving revision 1.254
retrieving revision 1.255
diff -u -d -r1.254 -r1.255
--- sound.cpp 24 Sep 2003 06:33:59 -0000 1.254
+++ sound.cpp 24 Sep 2003 06:56:30 -0000 1.255
@@ -25,8 +25,6 @@
#include "bundle.h"
#include "imuse.h"
#include "imuse_digi.h"
-#include "player_v2.h"
-#include "player_v3a.h"
#include "scumm.h"
#include "sound.h"
@@ -437,28 +435,6 @@
sound = (char *)malloc(size);
int vol = ptr[24] * 4;
memcpy(sound,ptr + READ_BE_UINT16(ptr + 8), size);
- _scumm->_mixer->playRaw(NULL, sound, size, rate, SoundMixer::FLAG_AUTOFREE, soundID, vol, 0);
- }
- else if ((_scumm->_features & GF_AMIGA) && (_scumm->_version <= 2) && READ_BE_UINT16(ptr + 14) == 0x0880) {
- size = READ_BE_UINT16(ptr + 6);
- int start = READ_BE_UINT16(ptr + 8);
- start += 10;
- rate = 11000;
- int vol = 255;
- int i = 0;
-
- while (i < start) {
- if ((READ_BE_UINT16(ptr) == 0x357c) && (READ_BE_UINT16(ptr + 4) == 6))
- rate = 3579545 / READ_BE_UINT16(ptr + 2);
-
- if ((READ_BE_UINT16(ptr) == 0x357c) && (READ_BE_UINT16(ptr + 4) == 8))
- vol = READ_BE_UINT16(ptr + 2) * 4;
- ptr += 2;
- i += 2;
- }
-
- sound = (char *)malloc(size);
- memcpy(sound, ptr, size);
_scumm->_mixer->playRaw(NULL, sound, size, rate, SoundMixer::FLAG_AUTOFREE, soundID, vol, 0);
}
else {
More information about the Scummvm-git-logs
mailing list