mirror of
https://github.com/libretro/scummvm.git
synced 2025-02-21 19:51:49 +00:00
Added (early) midi player code.
Added "screen flash" effect. Implemented opcodes: - o1_PLAYMUS - o1_STOPMUS - o1_ISMUS - o1_FLASH - o1_LOADSND - o1_LOADMUS svn-id: r31682
This commit is contained in:
parent
6562a7cd8a
commit
efeb8a3193
@ -44,6 +44,7 @@
|
|||||||
#include "made/screen.h"
|
#include "made/screen.h"
|
||||||
#include "made/script.h"
|
#include "made/script.h"
|
||||||
#include "made/sound.h"
|
#include "made/sound.h"
|
||||||
|
#include "made/music.h"
|
||||||
#include "made/redreader.h"
|
#include "made/redreader.h"
|
||||||
|
|
||||||
namespace Made {
|
namespace Made {
|
||||||
@ -88,6 +89,24 @@ MadeEngine::MadeEngine(OSystem *syst, const MadeGameDescription *gameDesc) : Eng
|
|||||||
_dat = new GameDatabase();
|
_dat = new GameDatabase();
|
||||||
_script = new ScriptInterpreter(this);
|
_script = new ScriptInterpreter(this);
|
||||||
|
|
||||||
|
int midiDriver = MidiDriver::detectMusicDriver(MDT_MIDI | MDT_ADLIB | MDT_PREFER_MIDI);
|
||||||
|
bool native_mt32 = ((midiDriver == MD_MT32) || ConfMan.getBool("native_mt32"));
|
||||||
|
bool adlib = (midiDriver == MD_ADLIB);
|
||||||
|
|
||||||
|
MidiDriver *driver = MidiDriver::createMidi(midiDriver);
|
||||||
|
if (native_mt32)
|
||||||
|
driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
|
||||||
|
|
||||||
|
_music = new Music(driver, _musicVolume);
|
||||||
|
_music->setNativeMT32(native_mt32);
|
||||||
|
_music->setAdlib(adlib);
|
||||||
|
|
||||||
|
_musicVolume = ConfMan.getInt("music_volume");
|
||||||
|
|
||||||
|
if (!_musicVolume) {
|
||||||
|
debug(1, "Music disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MadeEngine::~MadeEngine() {
|
MadeEngine::~MadeEngine() {
|
||||||
@ -97,6 +116,7 @@ MadeEngine::~MadeEngine() {
|
|||||||
delete _screen;
|
delete _screen;
|
||||||
delete _dat;
|
delete _dat;
|
||||||
delete _script;
|
delete _script;
|
||||||
|
delete _music;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MadeEngine::init() {
|
int MadeEngine::init() {
|
||||||
|
@ -61,6 +61,7 @@ class PmvPlayer;
|
|||||||
class Screen;
|
class Screen;
|
||||||
class ScriptInterpreter;
|
class ScriptInterpreter;
|
||||||
class GameDatabase;
|
class GameDatabase;
|
||||||
|
class Music;
|
||||||
|
|
||||||
class MadeEngine : public ::Engine {
|
class MadeEngine : public ::Engine {
|
||||||
int _gameId;
|
int _gameId;
|
||||||
@ -93,10 +94,12 @@ public:
|
|||||||
Screen *_screen;
|
Screen *_screen;
|
||||||
GameDatabase *_dat;
|
GameDatabase *_dat;
|
||||||
ScriptInterpreter *_script;
|
ScriptInterpreter *_script;
|
||||||
|
Music *_music;
|
||||||
|
|
||||||
int _eventMouseX, _eventMouseY;
|
int _eventMouseX, _eventMouseY;
|
||||||
int _soundRate;
|
|
||||||
uint16 _eventKey;
|
uint16 _eventKey;
|
||||||
|
int _soundRate;
|
||||||
|
int _musicVolume;
|
||||||
|
|
||||||
int32 _timers[50];
|
int32 _timers[50];
|
||||||
int16 getTimer(int16 timerNum);
|
int16 getTimer(int16 timerNum);
|
||||||
|
@ -5,6 +5,7 @@ MODULE_OBJS = \
|
|||||||
detection.o \
|
detection.o \
|
||||||
graphics.o \
|
graphics.o \
|
||||||
made.o \
|
made.o \
|
||||||
|
music.o \
|
||||||
pmvplayer.o \
|
pmvplayer.o \
|
||||||
redreader.o \
|
redreader.o \
|
||||||
resource.o \
|
resource.o \
|
||||||
|
274
engines/made/music.cpp
Normal file
274
engines/made/music.cpp
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// FIXME: This code is taken from SAGA and needs more work (e.g. setVolume).
|
||||||
|
|
||||||
|
// MIDI and digital music class
|
||||||
|
|
||||||
|
#include "sound/audiostream.h"
|
||||||
|
#include "sound/mididrv.h"
|
||||||
|
#include "sound/midiparser.h"
|
||||||
|
#include "common/config-manager.h"
|
||||||
|
#include "common/file.h"
|
||||||
|
|
||||||
|
#include "made/music.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
MusicPlayer::MusicPlayer(MidiDriver *driver) : _parser(0), _driver(driver), _looping(false), _isPlaying(false), _passThrough(false), _isGM(false) {
|
||||||
|
memset(_channel, 0, sizeof(_channel));
|
||||||
|
_masterVolume = 0;
|
||||||
|
this->open();
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicPlayer::~MusicPlayer() {
|
||||||
|
_driver->setTimerCallback(NULL, NULL);
|
||||||
|
stopMusic();
|
||||||
|
this->close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::setVolume(int volume) {
|
||||||
|
volume = CLIP(volume, 0, 255);
|
||||||
|
|
||||||
|
if (_masterVolume == volume)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_masterVolume = volume;
|
||||||
|
|
||||||
|
for (int i = 0; i < 16; ++i) {
|
||||||
|
if (_channel[i]) {
|
||||||
|
_channel[i]->volume(_channelVolume[i] * _masterVolume / 255);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MusicPlayer::open() {
|
||||||
|
// Don't ever call open without first setting the output driver!
|
||||||
|
if (!_driver)
|
||||||
|
return 255;
|
||||||
|
|
||||||
|
int ret = _driver->open();
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
_driver->setTimerCallback(this, &onTimer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::close() {
|
||||||
|
stopMusic();
|
||||||
|
if (_driver)
|
||||||
|
_driver->close();
|
||||||
|
_driver = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::send(uint32 b) {
|
||||||
|
if (_passThrough) {
|
||||||
|
_driver->send(b);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
byte channel = (byte)(b & 0x0F);
|
||||||
|
if ((b & 0xFFF0) == 0x07B0) {
|
||||||
|
// Adjust volume changes by master volume
|
||||||
|
byte volume = (byte)((b >> 16) & 0x7F);
|
||||||
|
_channelVolume[channel] = volume;
|
||||||
|
volume = volume * _masterVolume / 255;
|
||||||
|
b = (b & 0xFF00FFFF) | (volume << 16);
|
||||||
|
} else if ((b & 0xF0) == 0xC0 && !_isGM && !_nativeMT32) {
|
||||||
|
b = (b & 0xFFFF00FF) | MidiDriver::_mt32ToGm[(b >> 8) & 0xFF] << 8;
|
||||||
|
}
|
||||||
|
else if ((b & 0xFFF0) == 0x007BB0) {
|
||||||
|
//Only respond to All Notes Off if this channel
|
||||||
|
//has currently been allocated
|
||||||
|
if (_channel[b & 0x0F])
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_channel[channel])
|
||||||
|
_channel[channel] = (channel == 9) ? _driver->getPercussionChannel() : _driver->allocateChannel();
|
||||||
|
|
||||||
|
if (_channel[channel])
|
||||||
|
_channel[channel]->send(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::metaEvent(byte type, byte *data, uint16 length) {
|
||||||
|
|
||||||
|
switch (type) {
|
||||||
|
case 0x2F: // End of Track
|
||||||
|
if (_looping)
|
||||||
|
_parser->jumpToTick(0);
|
||||||
|
else
|
||||||
|
stopMusic();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
//warning("Unhandled meta event: %02x", type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::onTimer(void *refCon) {
|
||||||
|
MusicPlayer *music = (MusicPlayer *)refCon;
|
||||||
|
Common::StackLock lock(music->_mutex);
|
||||||
|
|
||||||
|
if (music->_isPlaying)
|
||||||
|
music->_parser->onTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::playMusic() {
|
||||||
|
_isPlaying = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MusicPlayer::stopMusic() {
|
||||||
|
Common::StackLock lock(_mutex);
|
||||||
|
|
||||||
|
_isPlaying = false;
|
||||||
|
if (_parser) {
|
||||||
|
_parser->unloadMusic();
|
||||||
|
_parser = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Music::Music(MidiDriver *driver, int enabled) : _enabled(enabled), _adlib(false) {
|
||||||
|
_player = new MusicPlayer(driver);
|
||||||
|
_currentVolume = 0;
|
||||||
|
|
||||||
|
xmidiParser = MidiParser::createParser_XMIDI();
|
||||||
|
|
||||||
|
_songTableLen = 0;
|
||||||
|
_songTable = 0;
|
||||||
|
|
||||||
|
_midiMusicData = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
Music::~Music() {
|
||||||
|
delete _player;
|
||||||
|
xmidiParser->setMidiDriver(NULL);
|
||||||
|
delete xmidiParser;
|
||||||
|
|
||||||
|
free(_songTable);
|
||||||
|
if (_midiMusicData)
|
||||||
|
delete[] _midiMusicData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music::setVolume(int volume, int time) {
|
||||||
|
_targetVolume = volume * 2; // ScummVM has different volume scale
|
||||||
|
_currentVolumePercent = 0;
|
||||||
|
|
||||||
|
if (volume == -1) // Set Full volume
|
||||||
|
volume = 255;
|
||||||
|
|
||||||
|
if (time == 1) {
|
||||||
|
_player->setVolume(volume);
|
||||||
|
_currentVolume = volume;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Music::isPlaying() {
|
||||||
|
return _player->isPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music::play(XmidiResource *midiResource, MusicFlags flags) {
|
||||||
|
MidiParser *parser;
|
||||||
|
byte *resourceData;
|
||||||
|
size_t resourceSize;
|
||||||
|
|
||||||
|
debug(2, "Music::play %d", flags);
|
||||||
|
|
||||||
|
if (!_enabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isPlaying()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_player->stopMusic();
|
||||||
|
|
||||||
|
/*
|
||||||
|
if (!_vm->_musicVolume) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (flags == MUSIC_DEFAULT) {
|
||||||
|
flags = MUSIC_NORMAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load MIDI/XMI resource data
|
||||||
|
|
||||||
|
_player->setGM(true);
|
||||||
|
|
||||||
|
resourceSize = midiResource->getSize();
|
||||||
|
resourceData = new byte[resourceSize];
|
||||||
|
memcpy(resourceData, midiResource->getData(), resourceSize);
|
||||||
|
|
||||||
|
if (resourceSize < 4) {
|
||||||
|
error("Music::play() wrong music resource size");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (xmidiParser->loadMusic(resourceData, resourceSize)) {
|
||||||
|
//_player->setGM(false);
|
||||||
|
parser = xmidiParser;
|
||||||
|
}
|
||||||
|
|
||||||
|
parser->setTrack(0);
|
||||||
|
parser->setMidiDriver(_player);
|
||||||
|
parser->setTimerRate(_player->getBaseTempo());
|
||||||
|
parser->property(MidiParser::mpCenterPitchWheelOnUnload, 1);
|
||||||
|
|
||||||
|
_player->_parser = parser;
|
||||||
|
//setVolume(_vm->_musicVolume == 10 ? 255 : _vm->_musicVolume * 25);
|
||||||
|
setVolume(255);
|
||||||
|
|
||||||
|
if (flags & MUSIC_LOOP)
|
||||||
|
_player->setLoop(true);
|
||||||
|
else
|
||||||
|
_player->setLoop(false);
|
||||||
|
|
||||||
|
_player->playMusic();
|
||||||
|
if (_midiMusicData)
|
||||||
|
delete[] _midiMusicData;
|
||||||
|
_midiMusicData = resourceData;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music::pause(void) {
|
||||||
|
_player->setVolume(-1);
|
||||||
|
_player->setPlaying(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music::resume(void) {
|
||||||
|
//_player->setVolume(_vm->_musicVolume == 10 ? 255 : _vm->_musicVolume * 25);
|
||||||
|
setVolume(255);
|
||||||
|
_player->setPlaying(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Music::stop(void) {
|
||||||
|
_player->stopMusic();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // End of namespace Made
|
150
engines/made/music.h
Normal file
150
engines/made/music.h
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
/* 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.
|
||||||
|
*
|
||||||
|
* $URL$
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Music class
|
||||||
|
|
||||||
|
#ifndef MADE_MUSIC_H
|
||||||
|
#define MADE_MUSIC_H
|
||||||
|
|
||||||
|
#include "sound/audiocd.h"
|
||||||
|
#include "sound/mididrv.h"
|
||||||
|
#include "sound/midiparser.h"
|
||||||
|
#include "sound/mp3.h"
|
||||||
|
#include "sound/vorbis.h"
|
||||||
|
#include "sound/flac.h"
|
||||||
|
#include "common/mutex.h"
|
||||||
|
|
||||||
|
#include "made/resource.h"
|
||||||
|
|
||||||
|
namespace Made {
|
||||||
|
|
||||||
|
enum MusicFlags {
|
||||||
|
MUSIC_NORMAL = 0,
|
||||||
|
MUSIC_LOOP = 0x0001,
|
||||||
|
MUSIC_DEFAULT = 0xffff
|
||||||
|
};
|
||||||
|
|
||||||
|
class MusicPlayer : public MidiDriver {
|
||||||
|
public:
|
||||||
|
MusicPlayer(MidiDriver *driver);
|
||||||
|
~MusicPlayer();
|
||||||
|
|
||||||
|
bool isPlaying() { return _isPlaying; }
|
||||||
|
void setPlaying(bool playing) { _isPlaying = playing; }
|
||||||
|
|
||||||
|
void setVolume(int volume);
|
||||||
|
int getVolume() { return _masterVolume; }
|
||||||
|
|
||||||
|
void setNativeMT32(bool b) { _nativeMT32 = b; }
|
||||||
|
bool hasNativeMT32() { return _nativeMT32; }
|
||||||
|
void playMusic();
|
||||||
|
void stopMusic();
|
||||||
|
void setLoop(bool loop) { _looping = loop; }
|
||||||
|
void setPassThrough(bool b) { _passThrough = b; }
|
||||||
|
|
||||||
|
void setGM(bool isGM) { _isGM = isGM; }
|
||||||
|
|
||||||
|
//MidiDriver interface implementation
|
||||||
|
int open();
|
||||||
|
void close();
|
||||||
|
void send(uint32 b);
|
||||||
|
|
||||||
|
void metaEvent(byte type, byte *data, uint16 length);
|
||||||
|
|
||||||
|
void setTimerCallback(void *timerParam, void (*timerProc)(void *)) { }
|
||||||
|
uint32 getBaseTempo(void) { return _driver ? _driver->getBaseTempo() : 0; }
|
||||||
|
|
||||||
|
//Channel allocation functions
|
||||||
|
MidiChannel *allocateChannel() { return 0; }
|
||||||
|
MidiChannel *getPercussionChannel() { return 0; }
|
||||||
|
|
||||||
|
MidiParser *_parser;
|
||||||
|
Common::Mutex _mutex;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
static void onTimer(void *data);
|
||||||
|
|
||||||
|
MidiChannel *_channel[16];
|
||||||
|
MidiDriver *_driver;
|
||||||
|
byte _channelVolume[16];
|
||||||
|
bool _nativeMT32;
|
||||||
|
bool _isGM;
|
||||||
|
bool _passThrough;
|
||||||
|
|
||||||
|
bool _isPlaying;
|
||||||
|
bool _looping;
|
||||||
|
bool _randomLoop;
|
||||||
|
byte _masterVolume;
|
||||||
|
|
||||||
|
byte *_musicData;
|
||||||
|
uint16 *_buf;
|
||||||
|
size_t _musicDataSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Music {
|
||||||
|
public:
|
||||||
|
|
||||||
|
Music(MidiDriver *driver, int enabled);
|
||||||
|
~Music(void);
|
||||||
|
void setNativeMT32(bool b) { _player->setNativeMT32(b); }
|
||||||
|
bool hasNativeMT32() { return _player->hasNativeMT32(); }
|
||||||
|
void setAdlib(bool b) { _adlib = b; }
|
||||||
|
bool hasAdlib() { return _adlib; }
|
||||||
|
void setPassThrough(bool b) { _player->setPassThrough(b); }
|
||||||
|
bool isPlaying(void);
|
||||||
|
|
||||||
|
void play(XmidiResource *midiResource, MusicFlags flags = MUSIC_DEFAULT);
|
||||||
|
void pause(void);
|
||||||
|
void resume(void);
|
||||||
|
void stop(void);
|
||||||
|
|
||||||
|
void setVolume(int volume, int time = 1);
|
||||||
|
int getVolume() { return _currentVolume; }
|
||||||
|
|
||||||
|
int32 *_songTable;
|
||||||
|
int _songTableLen;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
MusicPlayer *_player;
|
||||||
|
uint32 _trackNumber;
|
||||||
|
|
||||||
|
int _enabled;
|
||||||
|
bool _adlib;
|
||||||
|
|
||||||
|
int _targetVolume;
|
||||||
|
int _currentVolume;
|
||||||
|
int _currentVolumePercent;
|
||||||
|
|
||||||
|
MidiParser *xmidiParser;
|
||||||
|
|
||||||
|
byte *_midiMusicData;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // End of namespace Made
|
||||||
|
|
||||||
|
#endif
|
@ -205,6 +205,22 @@ const char *MenuResource::getString(uint index) const {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* XmidiResource */
|
||||||
|
|
||||||
|
XmidiResource::XmidiResource() : _data(NULL), _size(0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
XmidiResource::~XmidiResource() {
|
||||||
|
if (_data)
|
||||||
|
delete[] _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
void XmidiResource::load(byte *source, int size) {
|
||||||
|
_data = new byte[size];
|
||||||
|
_size = size;
|
||||||
|
memcpy(_data, source, size);
|
||||||
|
}
|
||||||
|
|
||||||
/* ProjectReader */
|
/* ProjectReader */
|
||||||
|
|
||||||
ProjectReader::ProjectReader() {
|
ProjectReader::ProjectReader() {
|
||||||
@ -269,6 +285,10 @@ MenuResource *ProjectReader::getMenu(int index) {
|
|||||||
return createResource<MenuResource>(kResMENU, index);
|
return createResource<MenuResource>(kResMENU, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
XmidiResource *ProjectReader::getXmidi(int index) {
|
||||||
|
return createResource<XmidiResource>(kResXMID, index);
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectReader::loadIndex(ResourceSlots *slots) {
|
void ProjectReader::loadIndex(ResourceSlots *slots) {
|
||||||
_fd->readUint32LE(); // skip INDX
|
_fd->readUint32LE(); // skip INDX
|
||||||
_fd->readUint32LE(); // skip index size
|
_fd->readUint32LE(); // skip index size
|
||||||
|
@ -44,7 +44,8 @@ enum ResourceType {
|
|||||||
kResFLEX = MKID_BE('FLEX'),
|
kResFLEX = MKID_BE('FLEX'),
|
||||||
kResSNDS = MKID_BE('SNDS'),
|
kResSNDS = MKID_BE('SNDS'),
|
||||||
kResANIM = MKID_BE('ANIM'),
|
kResANIM = MKID_BE('ANIM'),
|
||||||
kResMENU = MKID_BE('MENU')
|
kResMENU = MKID_BE('MENU'),
|
||||||
|
kResXMID = MKID_BE('XMID')
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ResourceSlot;
|
struct ResourceSlot;
|
||||||
@ -110,6 +111,18 @@ protected:
|
|||||||
Common::Array<Common::String> _strings;
|
Common::Array<Common::String> _strings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class XmidiResource : public Resource {
|
||||||
|
public:
|
||||||
|
XmidiResource();
|
||||||
|
~XmidiResource();
|
||||||
|
void load(byte *source, int size);
|
||||||
|
byte *getData() const { return _data; }
|
||||||
|
int getSize() const { return _size; }
|
||||||
|
protected:
|
||||||
|
byte *_data;
|
||||||
|
int _size;
|
||||||
|
};
|
||||||
|
|
||||||
struct ResourceSlot {
|
struct ResourceSlot {
|
||||||
uint32 offs;
|
uint32 offs;
|
||||||
uint32 size;
|
uint32 size;
|
||||||
@ -133,6 +146,7 @@ public:
|
|||||||
AnimationResource *getAnimation(int index);
|
AnimationResource *getAnimation(int index);
|
||||||
SoundResource *getSound(int index);
|
SoundResource *getSound(int index);
|
||||||
MenuResource *getMenu(int index);
|
MenuResource *getMenu(int index);
|
||||||
|
XmidiResource *getXmidi(int index);
|
||||||
|
|
||||||
void freeResource(Resource *resource);
|
void freeResource(Resource *resource);
|
||||||
|
|
||||||
|
@ -472,4 +472,20 @@ void Screen::show() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::flash(int flashCount) {
|
||||||
|
int palSize = _paletteColorCount * 3;
|
||||||
|
if (flashCount < 1)
|
||||||
|
flashCount = 1;
|
||||||
|
for (int i = 0; i < palSize; i++)
|
||||||
|
_fxPalette[i] = CLIP<byte>(255 - _palette[i], 0, 255);
|
||||||
|
while (flashCount--) {
|
||||||
|
setRGBPalette(_fxPalette, 0, _paletteColorCount);
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
_vm->_system->delayMillis(30);
|
||||||
|
setRGBPalette(_palette, 0, _paletteColorCount);
|
||||||
|
_vm->_system->updateScreen();
|
||||||
|
_vm->_system->delayMillis(30);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace Made
|
} // End of namespace Made
|
||||||
|
@ -102,6 +102,7 @@ public:
|
|||||||
uint16 placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor);
|
uint16 placeText(uint16 channelIndex, uint16 textObjectIndex, int16 x, int16 y, uint16 fontNum, int16 textColor, int16 outlineColor);
|
||||||
|
|
||||||
void show();
|
void show();
|
||||||
|
void flash(int count);
|
||||||
|
|
||||||
byte _screenPalette[256 * 4];
|
byte _screenPalette[256 * 4];
|
||||||
|
|
||||||
@ -111,7 +112,7 @@ protected:
|
|||||||
bool _screenLock;
|
bool _screenLock;
|
||||||
bool _paletteLock;
|
bool _paletteLock;
|
||||||
|
|
||||||
byte _palette[768], _newPalette[768];
|
byte _palette[768], _newPalette[768], _fxPalette[768];
|
||||||
int _paletteColorCount, _oldPaletteColorCount;
|
int _paletteColorCount, _oldPaletteColorCount;
|
||||||
bool _paletteInitialized, _needPalette;
|
bool _paletteInitialized, _needPalette;
|
||||||
|
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "made/script.h"
|
#include "made/script.h"
|
||||||
#include "made/pmvplayer.h"
|
#include "made/pmvplayer.h"
|
||||||
#include "made/scriptfuncs.h"
|
#include "made/scriptfuncs.h"
|
||||||
|
#include "made/music.h"
|
||||||
|
|
||||||
namespace Made {
|
namespace Made {
|
||||||
|
|
||||||
@ -288,15 +289,25 @@ int16 ScriptFunctionsRtz::o1_PLAYSND(int16 argc, int16 *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_PLAYMUS(int16 argc, int16 *argv) {
|
||||||
|
int16 musicId = argv[0];
|
||||||
|
if (musicId > 0) {
|
||||||
|
XmidiResource *xmidi = _vm->_res->getXmidi(musicId);
|
||||||
|
_vm->_music->play(xmidi);
|
||||||
|
_vm->_res->freeResource(xmidi);
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_STOPMUS(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_STOPMUS(int16 argc, int16 *argv) {
|
||||||
|
_vm->_music->stop();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_ISMUS(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_ISMUS(int16 argc, int16 *argv) {
|
||||||
return 0;
|
if (_vm->_music->isPlaying())
|
||||||
|
return 1;
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
|
||||||
@ -304,6 +315,7 @@ int16 ScriptFunctionsRtz::o1_TEXTPOS(int16 argc, int16 *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_FLASH(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_FLASH(int16 argc, int16 *argv) {
|
||||||
|
_vm->_screen->flash(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,10 +548,20 @@ int16 ScriptFunctionsRtz::o1_PLAYMOVIE(int16 argc, int16 *argv) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_LOADSND(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_LOADSND(int16 argc, int16 *argv) {
|
||||||
|
SoundResource *sound = _vm->_res->getSound(argv[0]);
|
||||||
|
if (sound) {
|
||||||
|
_vm->_res->freeResource(sound);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int16 ScriptFunctionsRtz::o1_LOADMUS(int16 argc, int16 *argv) {
|
int16 ScriptFunctionsRtz::o1_LOADMUS(int16 argc, int16 *argv) {
|
||||||
|
XmidiResource *xmidi = _vm->_res->getXmidi(argv[0]);
|
||||||
|
if (xmidi) {
|
||||||
|
_vm->_res->freeResource(xmidi);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user