mirror of
https://github.com/libretro/scummvm.git
synced 2024-12-26 03:37:53 +00:00
2d1c8a3533
svn-id: r55818
385 lines
9.1 KiB
C++
385 lines
9.1 KiB
C++
/* 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$
|
|
*
|
|
*/
|
|
|
|
#ifndef LASTEXPRESS_SOUND_H
|
|
#define LASTEXPRESS_SOUND_H
|
|
|
|
/*
|
|
|
|
Sound entry: 68 bytes (this is what appears in the savegames)
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - entity
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
char {16} - name 1
|
|
char {16} - name 2
|
|
|
|
Sound queue entry: 120 bytes
|
|
uint16 {2} - status
|
|
byte {1} - ??
|
|
byte {1} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - file data pointer
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - archive structure pointer
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
uint32 {4} - entity
|
|
uint32 {4} - ??
|
|
uint32 {4} - ??
|
|
char {16} - name 1
|
|
char {16} - name 2
|
|
uint32 {4} - pointer to next entry in the queue
|
|
uint32 {4} - subtitle data pointer
|
|
|
|
*/
|
|
|
|
#include "lastexpress/data/snd.h"
|
|
#include "lastexpress/data/subtitle.h"
|
|
|
|
#include "lastexpress/shared.h"
|
|
|
|
#include "lastexpress/helpers.h"
|
|
|
|
#include "common/list.h"
|
|
#include "common/mutex.h"
|
|
#include "common/system.h"
|
|
#include "common/serializer.h"
|
|
|
|
namespace LastExpress {
|
|
|
|
class LastExpressEngine;
|
|
class SubtitleManager;
|
|
|
|
class SoundManager : Common::Serializable {
|
|
public:
|
|
enum SoundType {
|
|
kSoundTypeNone = 0,
|
|
kSoundType1,
|
|
kSoundType2,
|
|
kSoundType3,
|
|
kSoundType4,
|
|
kSoundType5,
|
|
kSoundType6,
|
|
kSoundType7,
|
|
kSoundType8,
|
|
kSoundType9,
|
|
kSoundType10,
|
|
kSoundType11,
|
|
kSoundType12,
|
|
kSoundType13,
|
|
kSoundType14,
|
|
kSoundType15,
|
|
kSoundType16
|
|
};
|
|
|
|
enum FlagType {
|
|
kFlagInvalid = -1,
|
|
kFlagNone = 0x0,
|
|
kFlag2 = 0x2,
|
|
kFlag3 = 0x3,
|
|
kFlag4 = 0x4,
|
|
kFlag5 = 0x5,
|
|
kFlag6 = 0x6,
|
|
kFlag7 = 0x7,
|
|
kFlag8 = 0x8,
|
|
kFlag9 = 0x9,
|
|
kFlag10 = 0xA,
|
|
kFlag11 = 0xB,
|
|
kFlag12 = 0xC,
|
|
kFlag13 = 0xD,
|
|
kFlag14 = 0xE,
|
|
kFlag15 = 0xF,
|
|
kFlagDefault = 0x10,
|
|
|
|
kFlagType1_2 = 0x1000000,
|
|
kFlagSteam = 0x1001007,
|
|
kFlagType13 = 0x3000000,
|
|
kFlagMenuClock = 0x3080010,
|
|
kFlagType7 = 0x4000000,
|
|
kFlagType11 = 0x5000000,
|
|
kFlagMusic = 0x5000010,
|
|
kFlagType3 = 0x6000000,
|
|
kFlagLoop = 0x6001008,
|
|
kFlagType9 = 0x7000000
|
|
};
|
|
|
|
SoundManager(LastExpressEngine *engine);
|
|
~SoundManager();
|
|
|
|
// Timer
|
|
void handleTimer();
|
|
|
|
// State
|
|
void resetState() { _state |= kSoundType1; }
|
|
|
|
// Sound queue
|
|
void updateQueue();
|
|
void resetQueue(SoundType type1, SoundType type2 = kSoundTypeNone);
|
|
void clearQueue();
|
|
|
|
// Subtitles
|
|
void updateSubtitles();
|
|
|
|
// Entry
|
|
bool isBuffered(Common::String filename, bool testForEntity = false);
|
|
bool isBuffered(EntityIndex entity);
|
|
void setupEntry(SoundType type, EntityIndex index);
|
|
void processEntry(EntityIndex entity);
|
|
void processEntry(SoundType type);
|
|
void processEntry(Common::String filename);
|
|
void processEntries();
|
|
void removeFromQueue(Common::String filename);
|
|
void removeFromQueue(EntityIndex entity);
|
|
uint32 getEntryTime(EntityIndex index);
|
|
|
|
// Misc
|
|
void unknownFunction4();
|
|
void clearStatus();
|
|
|
|
// Sound playing
|
|
void playSound(EntityIndex entity, Common::String filename, FlagType flag = kFlagInvalid, byte a4 = 0);
|
|
bool playSoundWithSubtitles(Common::String filename, FlagType flag, EntityIndex entity, byte a4 = 0);
|
|
void playSoundEvent(EntityIndex entity, byte action, byte a3 = 0);
|
|
void playDialog(EntityIndex entity, EntityIndex entityDialog, FlagType flag, byte a4);
|
|
void playSteam(CityIndex index);
|
|
void playFightSound(byte action, byte a4);
|
|
void playLocomotiveSound();
|
|
void playWarningCompartment(EntityIndex entity, ObjectIndex compartment);
|
|
|
|
// Dialog & Letters
|
|
void readText(int id);
|
|
const char *getDialogName(EntityIndex entity) const;
|
|
|
|
// Sound bites
|
|
void excuseMe(EntityIndex entity, EntityIndex entity2 = kEntityPlayer, FlagType flag = kFlagNone);
|
|
void excuseMeCath();
|
|
const char *justCheckingCath() const;
|
|
const char *wrongDoorCath() const;
|
|
const char *justAMinuteCath() const;
|
|
|
|
// FLags
|
|
SoundManager::FlagType getSoundFlag(EntityIndex index) const;
|
|
|
|
// Debug
|
|
void stopAllSound();
|
|
|
|
// Serializable
|
|
void saveLoadWithSerializer(Common::Serializer &ser);
|
|
uint32 count();
|
|
|
|
private:
|
|
typedef int32 *SoundBuffer;
|
|
|
|
enum SoundStatus {
|
|
kSoundStatus_20 = 0x20,
|
|
kSoundStatus_40 = 0x40,
|
|
kSoundStatusRemoved = 0x200,
|
|
kSoundStatus_400 = 0x400,
|
|
|
|
kSoundStatus_8000 = 0x8000,
|
|
kSoundStatus_20000 = 0x20000,
|
|
kSoundStatus_100000 = 0x100000,
|
|
kSoundStatus_40000000 = 0x40000000,
|
|
|
|
kSoundStatusClear0 = 0x10,
|
|
kSoundStatusClear1 = 0x1F,
|
|
kSoundStatusClear2 = 0x80,
|
|
kSoundStatusClear3 = 0x200,
|
|
kSoundStatusClear4 = 0x800,
|
|
kSoundStatusClearAll = 0xFFFFFFE0
|
|
};
|
|
|
|
enum SoundState {
|
|
kSoundState0 = 0,
|
|
kSoundState1 = 1,
|
|
kSoundState2 = 2
|
|
};
|
|
|
|
union SoundStatusUnion {
|
|
uint32 status;
|
|
byte status1;
|
|
byte status2;
|
|
byte status3;
|
|
byte status4;
|
|
|
|
SoundStatusUnion() {
|
|
status = 0;
|
|
}
|
|
};
|
|
|
|
struct SubtitleEntry;
|
|
|
|
struct SoundEntry {
|
|
SoundStatusUnion status;
|
|
SoundType type; // int
|
|
//int field_8;
|
|
//int field_C;
|
|
//int field_10;
|
|
//int fileData;
|
|
//int field_18;
|
|
int field_1C;
|
|
uint32 time;
|
|
//int field_24;
|
|
//int field_28;
|
|
Common::SeekableReadStream *stream; // int
|
|
//int field_30;
|
|
int field_34;
|
|
int field_38;
|
|
int field_3C;
|
|
int field_40;
|
|
EntityIndex entity;
|
|
int field_48;
|
|
int field_4C;
|
|
Common::String name1; //char[16];
|
|
Common::String name2; //char[16];
|
|
//int next; // offset to the next structure in the list (not used)
|
|
SubtitleEntry *subtitle;
|
|
|
|
// Sound stream
|
|
StreamedSound *soundStream;
|
|
|
|
SoundEntry() {
|
|
status.status = 0;
|
|
type = kSoundTypeNone;
|
|
|
|
field_1C = 0;
|
|
time = 0;
|
|
|
|
stream = NULL;
|
|
|
|
field_34 = 0;
|
|
field_38 = 0;
|
|
field_3C = 0;
|
|
field_40 = 0;
|
|
entity = kEntityPlayer;
|
|
field_48 = 0;
|
|
field_4C = 0;
|
|
|
|
subtitle = NULL;
|
|
|
|
soundStream = NULL;
|
|
}
|
|
|
|
~SoundEntry() {
|
|
// Entries that have been queued would have their streamed disposed automatically
|
|
if (!soundStream)
|
|
SAFE_DELETE(stream);
|
|
|
|
delete soundStream;
|
|
}
|
|
};
|
|
|
|
struct SubtitleEntry {
|
|
Common::String filename;
|
|
SoundStatusUnion status;
|
|
SoundEntry *sound;
|
|
SubtitleManager *data;
|
|
|
|
SubtitleEntry() {
|
|
status.status = 0;
|
|
sound = NULL;
|
|
data = NULL;
|
|
}
|
|
|
|
~SubtitleEntry() {
|
|
SAFE_DELETE(data);
|
|
}
|
|
};
|
|
|
|
// Engine
|
|
LastExpressEngine *_engine;
|
|
|
|
// State flag
|
|
int _state;
|
|
SoundType _currentType;
|
|
|
|
Common::Mutex _mutex;
|
|
|
|
// Unknown data
|
|
uint32 _data0;
|
|
uint32 _data1;
|
|
uint32 _data2;
|
|
uint32 _flag;
|
|
|
|
// Filters
|
|
int32 _buffer[2940]; ///< Static sound buffer
|
|
|
|
// Compartment warnings by Mertens or Coudert
|
|
uint32 _lastWarning[12];
|
|
|
|
// Looping sound
|
|
void playLoopingSound();
|
|
|
|
// Sound cache
|
|
Common::List<SoundEntry *> _cache;
|
|
|
|
SoundEntry *getEntry(EntityIndex index);
|
|
SoundEntry *getEntry(Common::String name);
|
|
SoundEntry *getEntry(SoundType type);
|
|
|
|
void setupEntry(SoundEntry *entry, Common::String name, FlagType flag, int a4);
|
|
void setEntryType(SoundEntry *entry, FlagType flag);
|
|
void setEntryStatus(SoundEntry *entry, FlagType flag) const;
|
|
bool setupCache(SoundEntry *entry);
|
|
void loadSoundData(SoundEntry *entry, Common::String name);
|
|
|
|
void updateEntry(SoundEntry *entry, uint value) const;
|
|
void updateEntryState(SoundEntry *entry) const;
|
|
void resetEntry(SoundEntry *entry) const;
|
|
void removeEntry(SoundEntry *entry);
|
|
|
|
// Subtitles
|
|
int _drawSubtitles;
|
|
Common::List<SubtitleEntry *> _subtitles;
|
|
SubtitleEntry *_currentSubtitle;
|
|
void showSubtitle(SoundEntry *entry, Common::String filename);
|
|
SubtitleEntry *loadSubtitle(Common::String filename, SoundEntry *soundEntry);
|
|
void loadSubtitleData(SubtitleEntry * entry);
|
|
void setupSubtitleAndDraw(SubtitleEntry *subtitle);
|
|
void drawSubtitle(SubtitleEntry *subtitle);
|
|
void drawSubtitleOnScreen(SubtitleEntry *subtitle);
|
|
|
|
// Sound filter
|
|
void applyFilter(SoundEntry *entry, SoundBuffer buffer);
|
|
};
|
|
|
|
} // End of namespace LastExpress
|
|
|
|
#endif // LASTEXPRESS_SOUND_H
|