music support,
fixed timing bugs svn-id: r3491
This commit is contained in:
parent
279d5b2fd7
commit
b8d259d60e
18 changed files with 3298 additions and 376 deletions
3
Makefile
3
Makefile
|
@ -13,7 +13,8 @@ INCS = scumm.h scummsys.h stdafx.h
|
|||
|
||||
OBJS = actor.o boxes.o costume.o gfx.o object.o resource.o \
|
||||
saveload.o script.o scummvm.o sound.o string.o \
|
||||
sys.o verbs.o sdl.o script_v1.o script_v2.o debug.o gui.o
|
||||
sys.o verbs.o sdl.o script_v1.o script_v2.o debug.o gui.o \
|
||||
imuse.o
|
||||
|
||||
DISTFILES=actor.cpp boxes.cpp costume.cpp gfx.cpp object.cpp resource.cpp \
|
||||
saveload.cpp script.cpp scummvm.cpp sound.cpp string.cpp \
|
||||
|
|
|
@ -585,6 +585,8 @@ void Scumm::showActors() {
|
|||
void Scumm::stopTalk() {
|
||||
int act;
|
||||
|
||||
stopTalkSound();
|
||||
|
||||
_haveMsg = 0;
|
||||
_talkDelay = 0;
|
||||
|
||||
|
|
2
gfx.cpp
2
gfx.cpp
|
@ -1396,7 +1396,7 @@ void Scumm::unkScreenEffect7(int a) {
|
|||
tab_2[i] += tab_1[i];
|
||||
|
||||
updateScreen(this);
|
||||
waitForTimer(this,3);
|
||||
waitForTimer(this,30);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
47
gui.cpp
47
gui.cpp
|
@ -2,6 +2,11 @@
|
|||
#include "scumm.h"
|
||||
#include "gui.h"
|
||||
|
||||
enum {
|
||||
SAVELOAD_DIALOG,
|
||||
PAUSE_DIALOG
|
||||
};
|
||||
|
||||
void Gui::draw(int start,int end) {
|
||||
int i;
|
||||
|
||||
|
@ -249,6 +254,12 @@ const GuiWidget save_load_dialog[] = {
|
|||
{0}
|
||||
};
|
||||
|
||||
const GuiWidget pause_dialog[] = {
|
||||
{GUI_TEXT,0x01,GWF_DEFAULT,50,80,220,16,0,10},
|
||||
{0},
|
||||
};
|
||||
|
||||
|
||||
void Gui::handleCommand(int cmd) {
|
||||
int lastEdit = _editString;
|
||||
showCaret(false);
|
||||
|
@ -332,18 +343,20 @@ const byte string_map_table_v6[] = {
|
|||
99, /* Cancel */
|
||||
100, /* Quit */
|
||||
101, /* Ok */
|
||||
93, /* Game paused */
|
||||
};
|
||||
|
||||
const byte string_map_table_v5[] = {
|
||||
0, /* How may I serve you? */
|
||||
20, /* Select a game to LOAD */
|
||||
21, /* Name your SAVE game */
|
||||
19, /* Name your SAVE game */
|
||||
7, /* Save */
|
||||
8, /* Load */
|
||||
9, /* Play */
|
||||
10, /* Cancel */
|
||||
11, /* Quit */
|
||||
12, /* Ok */
|
||||
4, /* Game paused */
|
||||
};
|
||||
|
||||
const char *Gui::queryString(int string, int id) {
|
||||
|
@ -399,6 +412,8 @@ void Gui::editString(int i) {
|
|||
}
|
||||
|
||||
void Gui::addLetter(byte letter) {
|
||||
switch(_dialog) {
|
||||
case SAVELOAD_DIALOG:
|
||||
if (_editString==-1)
|
||||
return;
|
||||
|
||||
|
@ -413,13 +428,12 @@ void Gui::addLetter(byte letter) {
|
|||
_editLen--;
|
||||
}
|
||||
showCaret(true);
|
||||
}
|
||||
|
||||
void Gui::saveLoadDialog() {
|
||||
_widgets[0] = save_load_dialog;
|
||||
_editString = -1;
|
||||
_cur_page = 0;
|
||||
_active = 1;
|
||||
break;
|
||||
case PAUSE_DIALOG:
|
||||
if (letter==32)
|
||||
close();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
byte Gui::getDefaultColor(int color) {
|
||||
|
@ -431,7 +445,6 @@ byte Gui::getDefaultColor(int color) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void Gui::init(Scumm *s) {
|
||||
_s = s;
|
||||
_bgcolor = getDefaultColor(0);
|
||||
|
@ -447,6 +460,7 @@ void Gui::loop() {
|
|||
draw(0,100);
|
||||
_s->_cursorAnimate++;
|
||||
_s->gdi._cursorActive = 1;
|
||||
_s->pauseSounds(true);
|
||||
}
|
||||
|
||||
_s->getKeyInput(0);
|
||||
|
@ -471,5 +485,20 @@ void Gui::close() {
|
|||
_s->_fullRedraw = true;
|
||||
_s->_completeScreenRedraw = true;
|
||||
_s->_cursorAnimate--;
|
||||
_s->pauseSounds(false);
|
||||
_active = false;
|
||||
}
|
||||
|
||||
void Gui::saveLoadDialog() {
|
||||
_widgets[0] = save_load_dialog;
|
||||
_editString = -1;
|
||||
_cur_page = 0;
|
||||
_active = true;
|
||||
_dialog = SAVELOAD_DIALOG;
|
||||
}
|
||||
|
||||
void Gui::pause() {
|
||||
_widgets[0] = pause_dialog;
|
||||
_active = true;
|
||||
_dialog = PAUSE_DIALOG;
|
||||
}
|
||||
|
|
2
gui.h
2
gui.h
|
@ -43,6 +43,7 @@ struct Gui {
|
|||
byte _active;
|
||||
byte _clickTimer;
|
||||
byte _cur_page;
|
||||
byte _dialog;
|
||||
int _clickWidget;
|
||||
char *_queryMess;
|
||||
|
||||
|
@ -77,6 +78,7 @@ struct Gui {
|
|||
void saveLoadDialog();
|
||||
void queryMessage(const char *msg, const char *alts);
|
||||
byte getDefaultColor(int color);
|
||||
void pause();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -551,12 +551,12 @@ byte *Scumm::getResourceAddress(int type, int index) {
|
|||
ensureResourceLoaded(type, index);
|
||||
}
|
||||
|
||||
setResourceCounter(type, index, 1);
|
||||
|
||||
ptr=(byte*)res.address[type][index];
|
||||
if (!ptr)
|
||||
return NULL;
|
||||
|
||||
setResourceCounter(type, index, 1);
|
||||
|
||||
return ptr + sizeof(ResHeader);
|
||||
}
|
||||
|
||||
|
|
46
saveload.cpp
46
saveload.cpp
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "scumm.h"
|
||||
#include "sound.h"
|
||||
|
||||
struct SaveGameHeader {
|
||||
uint32 type;
|
||||
|
@ -29,7 +30,7 @@ struct SaveGameHeader {
|
|||
char name[32];
|
||||
};
|
||||
|
||||
#define CURRENT_VER 4
|
||||
#define CURRENT_VER 5
|
||||
|
||||
bool Scumm::saveState(int slot, bool compat) {
|
||||
char filename[256];
|
||||
|
@ -67,6 +68,7 @@ bool Scumm::loadState(int slot, bool compat) {
|
|||
SaveGameHeader hdr;
|
||||
Serializer ser;
|
||||
int sb,sh;
|
||||
SoundEngine *se;
|
||||
|
||||
makeSavegameName(filename, slot, compat);
|
||||
out = fopen(filename,"rb");
|
||||
|
@ -89,6 +91,8 @@ bool Scumm::loadState(int slot, bool compat) {
|
|||
|
||||
memcpy(_saveLoadName, hdr.name, sizeof(hdr.name));
|
||||
|
||||
pauseSounds(true);
|
||||
|
||||
CHECK_HEAP
|
||||
|
||||
openRoom(-1);
|
||||
|
@ -134,6 +138,8 @@ bool Scumm::loadState(int slot, bool compat) {
|
|||
|
||||
debug(1,"State loaded from '%s'", filename);
|
||||
|
||||
pauseSounds(false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -413,20 +419,22 @@ void Scumm::saveOrLoad(Serializer *s) {
|
|||
};
|
||||
|
||||
const SaveLoadEntry stringTabEntries[] = {
|
||||
MKLINE(StringTab,t_xpos,sleInt16),
|
||||
MKLINE(StringTab,t_ypos,sleInt16),
|
||||
MKLINE(StringTab,t_center,sleByte),
|
||||
MKLINE(StringTab,t_overhead,sleByte),
|
||||
MKLINE(StringTab,t_no_talk_anim,sleByte),
|
||||
MKLINE(StringTab,t_right,sleInt16),
|
||||
MKLINE(StringTab,t_color,sleInt16),
|
||||
MKLINE(StringTab,t_charset,sleInt16),
|
||||
MKLINE(StringTab,xpos,sleInt16),
|
||||
MKLINE(StringTab,t_xpos,sleInt16),
|
||||
MKLINE(StringTab,ypos,sleInt16),
|
||||
MKLINE(StringTab,center,sleInt16),
|
||||
MKLINE(StringTab,overhead,sleInt16),
|
||||
MKLINE(StringTab,no_talk_anim,sleInt16),
|
||||
MKLINE(StringTab,t_ypos,sleInt16),
|
||||
MKLINE(StringTab,right,sleInt16),
|
||||
MKLINE(StringTab,t_right,sleInt16),
|
||||
MKLINE(StringTab,color,sleInt8),
|
||||
MKLINE(StringTab,t_color,sleInt8),
|
||||
MKLINE(StringTab,charset,sleInt8),
|
||||
MKLINE(StringTab,t_charset,sleInt8),
|
||||
MKLINE(StringTab,center,sleByte),
|
||||
MKLINE(StringTab,t_center,sleByte),
|
||||
MKLINE(StringTab,overhead,sleByte),
|
||||
MKLINE(StringTab,t_overhead,sleByte),
|
||||
MKLINE(StringTab,no_talk_anim,sleByte),
|
||||
MKLINE(StringTab,t_no_talk_anim,sleByte),
|
||||
MKEND()
|
||||
};
|
||||
|
||||
|
@ -478,6 +486,9 @@ void Scumm::saveOrLoad(Serializer *s) {
|
|||
res.flags[r][s->loadWord()] |= 0x80;
|
||||
}
|
||||
}
|
||||
|
||||
if (_soundDriver)
|
||||
((SoundEngine*)_soundDriver)->save_or_load(s);
|
||||
}
|
||||
|
||||
void Scumm::saveLoadResource(Serializer *ser, int type, int index) {
|
||||
|
@ -630,9 +641,10 @@ void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
|
|||
int replen;
|
||||
byte type;
|
||||
byte *at;
|
||||
|
||||
int size;
|
||||
int value;
|
||||
int num;
|
||||
void *ptr;
|
||||
|
||||
while(sle->offs != 0xFFFF) {
|
||||
at = (byte*)d + sle->offs;
|
||||
|
@ -642,10 +654,12 @@ void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
|
|||
if (size==0xFF) {
|
||||
if (_saveOrLoad) {
|
||||
/* save reference */
|
||||
saveWord((*_save_ref)(_ref_me, type, *((void**)at)));
|
||||
ptr = *((void**)at);
|
||||
saveWord(ptr ? ((*_save_ref)(_ref_me, type, ptr ) + 1) : 0);
|
||||
} else {
|
||||
/* load reference */
|
||||
*((void**)at) = (*_load_ref)(_ref_me, type, loadWord());
|
||||
num = loadWord();
|
||||
*((void**)at) = num ? (*_load_ref)(_ref_me, type, num-1) : NULL;
|
||||
}
|
||||
} else {
|
||||
replen = 1;
|
||||
|
@ -655,8 +669,8 @@ void Serializer::saveLoadEntries(void *d, const SaveLoadEntry *sle) {
|
|||
type&=~128;
|
||||
}
|
||||
saveLoadArrayOf(at, replen, size, type);
|
||||
sle++;
|
||||
}
|
||||
sle++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1227,7 +1227,7 @@ void Scumm::o5_putActorInRoom() {
|
|||
void Scumm::o5_quitPauseRestart() {
|
||||
switch(fetchScriptByte()) {
|
||||
case 1:
|
||||
pauseGame(0);
|
||||
pauseGame(false);
|
||||
break;
|
||||
case 3:
|
||||
shutDown(0);
|
||||
|
|
|
@ -1794,7 +1794,7 @@ void Scumm::o6_isAnyOf() {
|
|||
void Scumm::o6_quitPauseRestart() {
|
||||
switch(fetchScriptByte()) {
|
||||
case 158:
|
||||
pauseGame(0);
|
||||
pauseGame(false);
|
||||
break;
|
||||
case 160:
|
||||
shutDown(0);
|
||||
|
|
43
scumm.h
43
scumm.h
|
@ -28,8 +28,14 @@ struct Actor;
|
|||
|
||||
typedef void (Scumm::*OpcodeProc)();
|
||||
|
||||
#define NUM_SCRIPT_SLOT 25
|
||||
#define NUM_ACTORS 13
|
||||
/* System Wide Constants */
|
||||
enum {
|
||||
SAMPLES_PER_SEC = 22050,
|
||||
BITS_PER_SAMPLE = 16,
|
||||
NUM_MIXER = 4,
|
||||
NUM_SCRIPT_SLOT = 25,
|
||||
NUM_ACTORS = 13
|
||||
};
|
||||
|
||||
#pragma START_PACK_STRUCTS
|
||||
|
||||
|
@ -596,6 +602,16 @@ struct Gdi {
|
|||
void updateDirtyScreen(VirtScreen *vs);
|
||||
};
|
||||
|
||||
struct MixerChannel {
|
||||
void *_sfx_sound;
|
||||
uint32 _sfx_pos;
|
||||
uint32 _sfx_size;
|
||||
uint32 _sfx_fp_speed;
|
||||
uint32 _sfx_fp_pos;
|
||||
|
||||
void mix(int16 *data, uint32 len);
|
||||
void clear();
|
||||
};
|
||||
|
||||
enum GameId {
|
||||
GID_TENTACLE = 1,
|
||||
|
@ -640,6 +656,8 @@ struct Scumm {
|
|||
bool _dynamicRoomOffsets;
|
||||
byte _resFilePathId;
|
||||
|
||||
bool _soundsPaused;
|
||||
|
||||
bool _useTalkAnims;
|
||||
|
||||
char *_resFilePrefix;
|
||||
|
@ -918,6 +936,8 @@ struct Scumm {
|
|||
|
||||
char _saveLoadName[32];
|
||||
|
||||
MixerChannel _mixer_channel[NUM_MIXER];
|
||||
|
||||
OpcodeProc getOpcode(int i) { return _opcodes[i]; }
|
||||
|
||||
void openRoom(int room);
|
||||
|
@ -925,7 +945,6 @@ struct Scumm {
|
|||
void readRoomsOffsets();
|
||||
void askForDisk(const char *filename);
|
||||
|
||||
|
||||
bool openResourceFile(const char *filename);
|
||||
|
||||
void fileClose(void *file);
|
||||
|
@ -1449,7 +1468,7 @@ struct Scumm {
|
|||
void addObjectToInventory(uint obj, uint room);
|
||||
void removeObjectFromRoom(int obj);
|
||||
void decodeParseString();
|
||||
void pauseGame(int i);
|
||||
void pauseGame(bool user);
|
||||
void shutDown(int i);
|
||||
void lock(int type, int i);
|
||||
void unlock(int type, int i);
|
||||
|
@ -1590,6 +1609,7 @@ struct Scumm {
|
|||
void talkSound(uint32 a, uint32 b, int mode);
|
||||
void processSfxQueues();
|
||||
void startTalkSound(uint32 a, uint32 b, int mode);
|
||||
void stopTalkSound();
|
||||
bool isMouthSyncOff(uint pos);
|
||||
void startSfxSound(void *file);
|
||||
void *openSfxFile();
|
||||
|
@ -1631,6 +1651,17 @@ struct Scumm {
|
|||
void drawEnqueuedObject(EnqueuedObject *eo);
|
||||
void removeEnqueuedObjects();
|
||||
void removeEnqueuedObject(EnqueuedObject *eo);
|
||||
|
||||
void pauseSounds(bool pause);
|
||||
|
||||
MixerChannel *allocateMixer();
|
||||
bool isSfxFinished();
|
||||
void playSfxSound(void *sound, uint32 size, uint rate);
|
||||
void stopSfxSound();
|
||||
|
||||
void mixWaves(int16 *sounds, int len);
|
||||
|
||||
|
||||
};
|
||||
|
||||
struct ScummDebugger {
|
||||
|
@ -1671,6 +1702,7 @@ struct Serializer {
|
|||
union {
|
||||
SerializerSaveReference *_save_ref;
|
||||
SerializerLoadReference *_load_ref;
|
||||
void *_saveload_ref;
|
||||
};
|
||||
void *_ref_me;
|
||||
|
||||
|
@ -1690,6 +1722,7 @@ struct Serializer {
|
|||
uint32 loadUint32();
|
||||
|
||||
bool isSaving() { return _saveOrLoad; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -1714,4 +1747,4 @@ void blit(byte *dst, byte *src, int w, int h);
|
|||
byte *findResource(uint32 id, byte *searchin, int index);
|
||||
void playSfxSound(void *sound, uint32 size, uint rate);
|
||||
bool isSfxFinished();
|
||||
void waitForTimer(Scumm *s, int delay);
|
||||
void waitForTimer(Scumm *s, int msec_delay);
|
20
scummvm.cpp
20
scummvm.cpp
|
@ -196,8 +196,8 @@ void Scumm::scummMain(int argc, char **argv) {
|
|||
|
||||
_debugMode = 1;
|
||||
|
||||
_maxHeapThreshold = 500000;
|
||||
_minHeapThreshold = 450000;
|
||||
_maxHeapThreshold = 450000;
|
||||
_minHeapThreshold = 400000;
|
||||
|
||||
parseCommandLine(argc, argv);
|
||||
|
||||
|
@ -213,6 +213,11 @@ void Scumm::scummMain(int argc, char **argv) {
|
|||
_bootParam = -7873;
|
||||
}
|
||||
|
||||
if (_gameId==GID_MONKEY2 && _bootParam==0) {
|
||||
_bootParam = 10001;
|
||||
}
|
||||
|
||||
|
||||
initGraphics(this, _fullScreen);
|
||||
|
||||
if (_majorScummVersion==6)
|
||||
|
@ -752,9 +757,8 @@ void Scumm::unkRoomFunc4(int a, int b, int c, int d, int e) {
|
|||
warning("unkRoomFunc4: not implemented");
|
||||
}
|
||||
|
||||
void Scumm::pauseGame(int i) {
|
||||
/* TODO: implement this */
|
||||
warning("pauseGame: not implemented");
|
||||
void Scumm::pauseGame(bool user) {
|
||||
((Gui*)_gui)->pause();
|
||||
}
|
||||
|
||||
void Scumm::shutDown(int i) {
|
||||
|
@ -777,12 +781,12 @@ void Scumm::processKbd() {
|
|||
|
||||
if (_lastKeyHit==_vars[VAR_RESTART_KEY]) {
|
||||
warning("Restart not implemented");
|
||||
pauseGame(1);
|
||||
// pauseGame(true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_lastKeyHit==_vars[VAR_PAUSE_KEY]) {
|
||||
warning("Pause not implemented");
|
||||
pauseGame(true);
|
||||
/* pause */
|
||||
return;
|
||||
}
|
||||
|
@ -793,6 +797,8 @@ void Scumm::processKbd() {
|
|||
((Gui*)_gui)->saveLoadDialog();
|
||||
} else if (_lastKeyHit==_vars[VAR_TALKSTOP_KEY]) {
|
||||
_talkDelay = 0;
|
||||
if (_sfxMode==2)
|
||||
stopTalk();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
10
scummvm.dsp
10
scummvm.dsp
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
|||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Zp4 /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D "DUMP_SCRIPTS" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /Zp4 /MD /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x41d /d "NDEBUG"
|
||||
# ADD RSC /l 0x41d /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
@ -157,6 +157,10 @@ SOURCE=.\gui.cpp
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\imuse.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\object.cpp
|
||||
|
||||
!IF "$(CFG)" == "scummvm - Win32 Release"
|
||||
|
@ -335,6 +339,10 @@ SOURCE=.\scummsys.h
|
|||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\sound.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# End Group
|
||||
|
|
179
sdl.cpp
179
sdl.cpp
|
@ -24,10 +24,9 @@
|
|||
#include "stdafx.h"
|
||||
#include "scumm.h"
|
||||
#include "gui.h"
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
#include "sound.h"
|
||||
#endif
|
||||
|
||||
#include "SDL_thread.h"
|
||||
|
||||
#define SCALEUP_2x2
|
||||
|
||||
|
@ -35,9 +34,7 @@ Scumm scumm;
|
|||
ScummDebugger debugger;
|
||||
Gui gui;
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
SoundEngine sound;
|
||||
#endif
|
||||
|
||||
static SDL_Surface *screen;
|
||||
|
||||
|
@ -74,9 +71,21 @@ int mapKey(int key, byte mod) {
|
|||
return key;
|
||||
}
|
||||
|
||||
void waitForTimer(Scumm *s, int delay) {
|
||||
void waitForTimer(Scumm *s, int msec_delay) {
|
||||
SDL_Event event;
|
||||
uint32 start_time;
|
||||
|
||||
if (msec_delay<0)
|
||||
return;
|
||||
|
||||
if (s->_fastMode&2)
|
||||
msec_delay = 0;
|
||||
else if (s->_fastMode&1)
|
||||
msec_delay = 10;
|
||||
|
||||
start_time = SDL_GetTicks();
|
||||
|
||||
do {
|
||||
while (SDL_PollEvent(&event)) {
|
||||
switch(event.type) {
|
||||
case SDL_KEYDOWN:
|
||||
|
@ -107,21 +116,21 @@ void waitForTimer(Scumm *s, int delay) {
|
|||
s->resourceStats();
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__APPLE__)
|
||||
if (event.key.keysym.sym=='q' && event.key.keysym.mod&KMOD_LMETA) {
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
break;
|
||||
case SDL_MOUSEMOTION: {
|
||||
int newx,newy;
|
||||
#if !defined(SCALEUP_2x2)
|
||||
#if !defined(SCALEUP_2x2)
|
||||
newx = event.motion.x;
|
||||
newy = event.motion.y;
|
||||
#else
|
||||
#else
|
||||
newx = event.motion.x>>1;
|
||||
newy = event.motion.y>>1;
|
||||
#endif
|
||||
#endif
|
||||
if (newx != s->mouse.x || newy != s->mouse.y) {
|
||||
s->mouse.x = newx;
|
||||
s->mouse.y = newy;
|
||||
|
@ -142,10 +151,10 @@ void waitForTimer(Scumm *s, int delay) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!(s->_fastMode&2)) {
|
||||
assert(delay<500);
|
||||
SDL_Delay(delay*10);
|
||||
}
|
||||
if (SDL_GetTicks() >= start_time + msec_delay)
|
||||
break;
|
||||
SDL_Delay(10);
|
||||
} while (1);
|
||||
}
|
||||
|
||||
#define MAX_DIRTY_RECTS 40
|
||||
|
@ -468,111 +477,31 @@ void drawMouse(Scumm *s, int xdraw, int ydraw, int color, byte *mask, bool visib
|
|||
old_mouse_x = xdraw;
|
||||
old_mouse_y = ydraw;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#define SAMPLES_PER_SEC 22050
|
||||
#define BUFFER_SIZE (8192)
|
||||
#define BITS_PER_SAMPLE 16
|
||||
|
||||
struct MixerChannel {
|
||||
void *_sfx_sound;
|
||||
uint32 _sfx_pos;
|
||||
uint32 _sfx_size;
|
||||
uint32 _sfx_fp_speed;
|
||||
uint32 _sfx_fp_pos;
|
||||
|
||||
void mix(int16 *data, uint32 len);
|
||||
void clear();
|
||||
};
|
||||
|
||||
#define NUM_MIXER 4
|
||||
|
||||
static MixerChannel mixer_channel[NUM_MIXER];
|
||||
|
||||
MixerChannel *find_channel() {
|
||||
int i;
|
||||
MixerChannel *mc = mixer_channel;
|
||||
for(i=0; i<NUM_MIXER; i++,mc++) {
|
||||
if (!mc->_sfx_sound)
|
||||
return mc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool isSfxFinished() {
|
||||
int i;
|
||||
for(i=0; i<NUM_MIXER; i++)
|
||||
if (mixer_channel[i]._sfx_sound)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void playSfxSound(void *sound, uint32 size, uint rate) {
|
||||
MixerChannel *mc = find_channel();
|
||||
|
||||
if (!mc) {
|
||||
warning("No mixer channel available");
|
||||
return;
|
||||
}
|
||||
|
||||
mc->_sfx_sound = sound;
|
||||
mc->_sfx_pos = 0;
|
||||
mc->_sfx_fp_speed = (1<<16) * rate / 22050;
|
||||
mc->_sfx_fp_pos = 0;
|
||||
|
||||
while (size&0xFFFF0000) size>>=1, rate>>=1;
|
||||
mc->_sfx_size = size * 22050 / rate;
|
||||
}
|
||||
|
||||
void MixerChannel::mix(int16 *data, uint32 len) {
|
||||
int8 *s;
|
||||
int i;
|
||||
uint32 fp_pos, fp_speed;
|
||||
|
||||
if (!_sfx_sound)
|
||||
return;
|
||||
if (len > _sfx_size)
|
||||
len = _sfx_size;
|
||||
_sfx_size -= len;
|
||||
|
||||
s = (int8*)_sfx_sound + _sfx_pos;
|
||||
fp_pos = _sfx_fp_pos;
|
||||
fp_speed = _sfx_fp_speed;
|
||||
|
||||
do {
|
||||
fp_pos += fp_speed;
|
||||
*data++ += (*s<<6);
|
||||
s += fp_pos >> 16;
|
||||
fp_pos &= 0x0000FFFF;
|
||||
} while (--len);
|
||||
|
||||
_sfx_pos = s - (int8*)_sfx_sound;
|
||||
_sfx_fp_speed = fp_speed;
|
||||
_sfx_fp_pos = fp_pos;
|
||||
|
||||
if (!_sfx_size)
|
||||
clear();
|
||||
}
|
||||
|
||||
void MixerChannel::clear() {
|
||||
free(_sfx_sound);
|
||||
_sfx_sound = NULL;
|
||||
}
|
||||
static uint32 midi_counter;
|
||||
|
||||
void fill_sound(void *userdata, Uint8 *stream, int len) {
|
||||
int i;
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
sound.generate_samples((int16*)stream, len>>1);
|
||||
#else
|
||||
memset(stream, 0, len);
|
||||
#endif
|
||||
scumm.mixWaves((int16*)stream, len>>1);
|
||||
}
|
||||
|
||||
for(i=NUM_MIXER-1; i>=0;i--) {
|
||||
mixer_channel[i].mix((int16*)stream, len>>1);
|
||||
int music_thread(Scumm *s) {
|
||||
int old_time, cur_time;
|
||||
|
||||
old_time = SDL_GetTicks();
|
||||
|
||||
do {
|
||||
SDL_Delay(10);
|
||||
|
||||
cur_time = SDL_GetTicks();
|
||||
while (old_time < cur_time) {
|
||||
old_time += 10;
|
||||
sound.on_timer();
|
||||
}
|
||||
} while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void initGraphics(Scumm *s, bool fullScreen) {
|
||||
|
@ -599,10 +528,12 @@ void initGraphics(Scumm *s, bool fullScreen) {
|
|||
SDL_OpenAudio(&desired, NULL);
|
||||
SDL_PauseAudio(0);
|
||||
|
||||
|
||||
SDL_WM_SetCaption(buf,buf);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
|
||||
/* Create Music Thread */
|
||||
SDL_CreateThread((int (*)(void *))&music_thread, &scumm);
|
||||
|
||||
#if !defined(SCALEUP_2x2)
|
||||
screen = SDL_SetVideoMode(320, 200, 8, fullScreen ? (SDL_SWSURFACE | SDL_FULLSCREEN) : SDL_SWSURFACE);
|
||||
#else
|
||||
|
@ -627,33 +558,31 @@ void initGraphics(Scumm *s, bool fullScreen) {
|
|||
|
||||
int main(int argc, char* argv[]) {
|
||||
int delta,tmp;
|
||||
int last_time, new_time;
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
sound.initialize(NULL);
|
||||
sound.initialize(&scumm);
|
||||
scumm._soundDriver = &sound;
|
||||
#endif
|
||||
|
||||
scumm._gui = &gui;
|
||||
scumm.scummMain(argc, argv);
|
||||
|
||||
gui.init(&scumm);
|
||||
|
||||
last_time = SDL_GetTicks();
|
||||
delta = 0;
|
||||
do {
|
||||
updateScreen(&scumm);
|
||||
|
||||
new_time = SDL_GetTicks();
|
||||
waitForTimer(&scumm, delta * 15 + last_time - new_time);
|
||||
last_time = SDL_GetTicks();
|
||||
|
||||
if (gui._active) {
|
||||
gui.loop();
|
||||
tmp = 5;
|
||||
delta = 5;
|
||||
} else {
|
||||
tmp = delta = scumm.scummLoop(delta);
|
||||
tmp += tmp>>1;
|
||||
|
||||
if (scumm._fastMode)
|
||||
tmp=1;
|
||||
delta = scumm.scummLoop(delta);
|
||||
}
|
||||
|
||||
waitForTimer(&scumm, tmp);
|
||||
} while(1);
|
||||
|
||||
return 0;
|
||||
|
|
138
sound.cpp
138
sound.cpp
|
@ -21,20 +21,7 @@
|
|||
|
||||
#include "stdafx.h"
|
||||
#include "scumm.h"
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
#include "sound.h"
|
||||
#else
|
||||
struct SoundEngine {
|
||||
byte **_base_sounds;
|
||||
int start_sound(int sound) { return -1; }
|
||||
int stop_sound(int sound) { return -1; }
|
||||
int stop_all_sounds() { return -1; }
|
||||
int32 do_command(int a, int b, int c, int d, int e, int f, int g, int h) { return -1; }
|
||||
int get_sound_status(int sound) { return -1; }
|
||||
int clear_queue() { return -1; }
|
||||
};
|
||||
#endif
|
||||
|
||||
void Scumm::addSoundToQueue(int sound) {
|
||||
_vars[VAR_LAST_SOUND] = sound;
|
||||
|
@ -170,6 +157,13 @@ void Scumm::startTalkSound(uint32 offset, uint32 b, int mode) {
|
|||
startSfxSound(_sfxFile);
|
||||
}
|
||||
|
||||
void Scumm::stopTalkSound() {
|
||||
if (_sfxMode==2) {
|
||||
stopSfxSound();
|
||||
_sfxMode = 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool Scumm::isMouthSyncOff(uint pos) {
|
||||
uint j;
|
||||
bool val = true;
|
||||
|
@ -204,7 +198,6 @@ int Scumm::isSoundRunning(int sound) {
|
|||
if (!isResourceLoaded(rtSound, sound))
|
||||
return 0;
|
||||
|
||||
|
||||
se = (SoundEngine*)_soundDriver;
|
||||
if (!se)
|
||||
return 0;
|
||||
|
@ -251,6 +244,7 @@ void Scumm::stopAllSounds() {
|
|||
se->clear_queue();
|
||||
}
|
||||
clearSoundQue();
|
||||
stopSfxSound();
|
||||
}
|
||||
|
||||
void Scumm::clearSoundQue() {
|
||||
|
@ -283,27 +277,41 @@ void Scumm::talkSound(uint32 a, uint32 b, int mode) {
|
|||
_talk_sound_mode = mode;
|
||||
}
|
||||
|
||||
/* The sound code currently only supports General Midi.
|
||||
* General Midi is used in Day Of The Tentacle.
|
||||
* Roland music is also playable, but doesn't sound well.
|
||||
* A mapping between roland instruments and GM instruments
|
||||
* is needed.
|
||||
*/
|
||||
|
||||
static const uint32 sound_tags[] = {
|
||||
MKID('ADL ')
|
||||
MKID('GMD ')
|
||||
};
|
||||
|
||||
void Scumm::setupSound() {
|
||||
SoundEngine *se = (SoundEngine*)_soundDriver;
|
||||
if (se) {
|
||||
if (se)
|
||||
se->_base_sounds = res.address[rtSound];
|
||||
}
|
||||
|
||||
_soundTagTable = (byte*)sound_tags;
|
||||
_numSoundTags = 1;
|
||||
_sfxFile = openSfxFile();
|
||||
}
|
||||
|
||||
void Scumm::pauseSounds(bool pause) {
|
||||
SoundEngine *se = (SoundEngine*)_soundDriver;
|
||||
if (se)
|
||||
se->pause(pause);
|
||||
_soundsPaused = pause;
|
||||
}
|
||||
|
||||
struct VOCHeader {
|
||||
byte id[19];
|
||||
byte extra[7];
|
||||
};
|
||||
|
||||
static const char VALID_VOC_ID[] = "Creative Voice File";
|
||||
static const char VALID_VOC_VERSION[] = "";
|
||||
|
||||
void Scumm::startSfxSound(void *file) {
|
||||
VOCHeader hdr;
|
||||
int block_type;
|
||||
|
@ -355,3 +363,97 @@ void Scumm::startSfxSound(void *file) {
|
|||
void *Scumm::openSfxFile() {
|
||||
return fopen("monster.sou", "rb");
|
||||
}
|
||||
|
||||
#define NUM_MIXER 4
|
||||
|
||||
MixerChannel *Scumm::allocateMixer() {
|
||||
int i;
|
||||
MixerChannel *mc = _mixer_channel;
|
||||
for(i=0; i<NUM_MIXER; i++,mc++) {
|
||||
if (!mc->_sfx_sound)
|
||||
return mc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void Scumm::stopSfxSound() {
|
||||
MixerChannel *mc = _mixer_channel;
|
||||
int i;
|
||||
for(i=0; i<NUM_MIXER; i++,mc++) {
|
||||
if (mc->_sfx_sound)
|
||||
mc->clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool Scumm::isSfxFinished() {
|
||||
int i;
|
||||
for(i=0; i<NUM_MIXER; i++)
|
||||
if (_mixer_channel[i]._sfx_sound)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void Scumm::playSfxSound(void *sound, uint32 size, uint rate) {
|
||||
MixerChannel *mc = allocateMixer();
|
||||
|
||||
if (!mc) {
|
||||
warning("No mixer channel available");
|
||||
return;
|
||||
}
|
||||
|
||||
mc->_sfx_sound = sound;
|
||||
mc->_sfx_pos = 0;
|
||||
mc->_sfx_fp_speed = (1<<16) * rate / 22050;
|
||||
mc->_sfx_fp_pos = 0;
|
||||
|
||||
while (size&0xFFFF0000) size>>=1, rate>>=1;
|
||||
mc->_sfx_size = size * 22050 / rate;
|
||||
}
|
||||
|
||||
void MixerChannel::mix(int16 *data, uint32 len) {
|
||||
int8 *s;
|
||||
int i;
|
||||
uint32 fp_pos, fp_speed;
|
||||
|
||||
if (!_sfx_sound)
|
||||
return;
|
||||
if (len > _sfx_size)
|
||||
len = _sfx_size;
|
||||
_sfx_size -= len;
|
||||
|
||||
s = (int8*)_sfx_sound + _sfx_pos;
|
||||
fp_pos = _sfx_fp_pos;
|
||||
fp_speed = _sfx_fp_speed;
|
||||
|
||||
do {
|
||||
fp_pos += fp_speed;
|
||||
*data++ += (*s<<6);
|
||||
s += fp_pos >> 16;
|
||||
fp_pos &= 0x0000FFFF;
|
||||
} while (--len);
|
||||
|
||||
_sfx_pos = s - (int8*)_sfx_sound;
|
||||
_sfx_fp_speed = fp_speed;
|
||||
_sfx_fp_pos = fp_pos;
|
||||
|
||||
if (!_sfx_size)
|
||||
clear();
|
||||
}
|
||||
|
||||
void MixerChannel::clear() {
|
||||
free(_sfx_sound);
|
||||
_sfx_sound = NULL;
|
||||
}
|
||||
|
||||
void Scumm::mixWaves(int16 *sounds, int len) {
|
||||
int i;
|
||||
|
||||
if (_soundsPaused)
|
||||
return;
|
||||
|
||||
for(i=NUM_MIXER-1; i>=0;i--) {
|
||||
_mixer_channel[i].mix(sounds, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
358
sound.h
Normal file
358
sound.h
Normal file
|
@ -0,0 +1,358 @@
|
|||
/* ScummVM - Scumm Interpreter
|
||||
* Copyright (C) 2001 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.
|
||||
*
|
||||
* Change Log:
|
||||
* $Log$
|
||||
* Revision 1.1 2001/11/14 18:37:38 strigeus
|
||||
* music support,
|
||||
* fixed timing bugs
|
||||
*
|
||||
*/
|
||||
|
||||
struct Part;
|
||||
struct MidiChannel;
|
||||
struct VolumeFader;
|
||||
struct Player;
|
||||
struct HookDatas;
|
||||
struct SoundEngine;
|
||||
|
||||
struct Part {
|
||||
SoundEngine *_se;
|
||||
Part *_next, *_prev;
|
||||
MidiChannel *_mc;
|
||||
Player *_player;
|
||||
int16 _pitchbend;
|
||||
byte _pitchbend_factor;
|
||||
int8 _transpose,_transpose_eff;
|
||||
byte _vol,_vol_eff;
|
||||
int8 _detune,_detune_eff;
|
||||
int8 _pan,_pan_eff;
|
||||
bool _on;
|
||||
byte _modwheel;
|
||||
bool _pedal;
|
||||
byte _program;
|
||||
int8 _pri;
|
||||
byte _pri_eff;
|
||||
byte _chan;
|
||||
byte _effect_level;
|
||||
byte _chorus;
|
||||
byte _gmidi_5;
|
||||
byte _gmidi_1;
|
||||
|
||||
void key_on(byte note, byte velocity);
|
||||
void key_off(byte note);
|
||||
void set_param(int b, byte c) {}
|
||||
void init(SoundEngine *se);
|
||||
void setup(Player *player);
|
||||
void uninit();
|
||||
void off();
|
||||
void silence();
|
||||
void set_instrument(uint b);
|
||||
void set_instrument(byte *data) {}
|
||||
|
||||
void set_transpose(int8 transpose);
|
||||
void set_vol(uint8 volume);
|
||||
void set_detune(int8 detune);
|
||||
void set_pri(int8 pri, bool recalc);
|
||||
void set_pan(int8 pan);
|
||||
void set_modwheel(uint value);
|
||||
void set_pedal(bool value);
|
||||
void set_pitchbend(int value);
|
||||
void release_pedal();
|
||||
void set_program(byte program);
|
||||
void set_chorus(uint chorus);
|
||||
void set_effect_level(uint level);
|
||||
void set_chan_param(int b, int c) {}
|
||||
void mod_changed();
|
||||
void vol_changed();
|
||||
void pedal_changed();
|
||||
void modwheel_changed();
|
||||
void pan_changed();
|
||||
void effect_level_changed();
|
||||
void program_changed();
|
||||
void chorus_changed();
|
||||
int update_actives(uint16 *active);
|
||||
void set_pitchbend_factor(uint8 value);
|
||||
void set_onoff(bool on);
|
||||
|
||||
void fix_after_load();
|
||||
};
|
||||
|
||||
struct MidiChannel {
|
||||
Part *_part;
|
||||
byte _chan;
|
||||
uint16 _actives[8];
|
||||
|
||||
void init(byte chan);
|
||||
};
|
||||
|
||||
struct VolumeFader {
|
||||
Player *player;
|
||||
bool active;
|
||||
byte curvol;
|
||||
uint16 speed_lo_max,num_steps;
|
||||
int8 speed_hi;
|
||||
int8 direction;
|
||||
int8 speed_lo;
|
||||
uint16 speed_lo_counter;
|
||||
|
||||
void initialize() { active = false; }
|
||||
void on_timer();
|
||||
};
|
||||
|
||||
struct HookDatas {
|
||||
byte _jump,_transpose;
|
||||
byte _part_onoff[16];
|
||||
byte _part_volume[16];
|
||||
byte _part_program[16];
|
||||
byte _part_transpose[16];
|
||||
|
||||
int query_param(int param, byte chan);
|
||||
int set(byte cls, byte value, byte chan);
|
||||
};
|
||||
|
||||
struct Player {
|
||||
SoundEngine *_se;
|
||||
|
||||
Part *_parts;
|
||||
bool _active;
|
||||
bool _scanning;
|
||||
int _id;
|
||||
byte _priority;
|
||||
byte _volume;
|
||||
int8 _pan;
|
||||
int8 _transpose;
|
||||
int8 _detune;
|
||||
uint _vol_chan;
|
||||
byte _vol_eff;
|
||||
|
||||
uint _song_index;
|
||||
uint _track_index;
|
||||
uint _timer_counter;
|
||||
uint _loop_to_beat;
|
||||
uint _loop_from_beat;
|
||||
uint _loop_counter;
|
||||
uint _loop_to_tick;
|
||||
uint _loop_from_tick;
|
||||
uint32 _tempo;
|
||||
uint32 _tempo_eff; /* NoSave */
|
||||
uint32 _cur_pos;
|
||||
uint32 _next_pos;
|
||||
uint32 _song_offset;
|
||||
uint32 _timer_speed; /* NoSave */
|
||||
uint _tick_index;
|
||||
uint _beat_index;
|
||||
uint _ticks_per_beat;
|
||||
byte _speed; /* NoSave */
|
||||
bool _abort;
|
||||
|
||||
HookDatas _hook;
|
||||
|
||||
/* Player part */
|
||||
void hook_clear();
|
||||
void clear();
|
||||
bool start_sound(int sound);
|
||||
void uninit_parts();
|
||||
byte *parse_midi(byte *s);
|
||||
void key_off(uint8 chan, byte data);
|
||||
void key_on(uint8 chan, byte data, byte velocity);
|
||||
void part_set_transpose(uint8 chan, byte relative, int8 b);
|
||||
void parse_sysex(byte *p, uint len);
|
||||
void maybe_jump(byte *data);
|
||||
void maybe_set_transpose(byte *data);
|
||||
void maybe_part_onoff(byte *data);
|
||||
void maybe_set_volume(byte *data);
|
||||
void maybe_set_program(byte *data);
|
||||
void maybe_set_transpose_part(byte *data);
|
||||
uint update_actives();
|
||||
Part *get_part(uint8 part);
|
||||
void turn_off_pedals();
|
||||
int set_vol(byte vol);
|
||||
int get_param(int param, byte chan);
|
||||
int query_part_param(int param, byte chan);
|
||||
int set_transpose(byte relative, int b);
|
||||
void set_priority(int pri);
|
||||
void set_pan(int pan);
|
||||
void set_detune(int detune);
|
||||
void silence_parts();
|
||||
void play_active_notes();
|
||||
void cancel_volume_fade();
|
||||
|
||||
static void decode_sysex_bytes(byte *src, byte *dst, int len);
|
||||
|
||||
void clear_active_note(int chan, byte note);
|
||||
void set_active_note(int chan, byte note);
|
||||
void clear_active_notes();
|
||||
|
||||
/* Sequencer part */
|
||||
bool set_loop(uint count, uint tobeat, uint totick, uint frombeat, uint fromtick);
|
||||
void clear_loop();
|
||||
void set_speed(byte speed);
|
||||
bool jump(uint track, uint beat, uint tick);
|
||||
void uninit_seq();
|
||||
void set_tempo(uint32 data);
|
||||
int start_seq_sound(int sound);
|
||||
void find_sustaining_notes(byte *a, byte *b, uint32 l);
|
||||
int scan(uint totrack, uint tobeat, uint totick);
|
||||
int query_param(int param);
|
||||
|
||||
int fade_vol(byte vol, int time);
|
||||
void sequencer_timer();
|
||||
};
|
||||
|
||||
|
||||
struct SustainingNotes {
|
||||
SustainingNotes *next;
|
||||
SustainingNotes *prev;
|
||||
Player *player;
|
||||
byte note,chan;
|
||||
uint32 off_pos;
|
||||
uint32 pos;
|
||||
uint16 counter;
|
||||
};
|
||||
|
||||
struct CommandQueue {
|
||||
uint16 array[8];
|
||||
};
|
||||
|
||||
struct IsNoteCmdData {
|
||||
byte chan;
|
||||
byte note;
|
||||
byte vel;
|
||||
};
|
||||
|
||||
struct SoundEngine {
|
||||
void *_mo; /* midi out */
|
||||
|
||||
byte **_base_sounds;
|
||||
|
||||
Scumm *_s;
|
||||
|
||||
byte _locked;
|
||||
|
||||
bool _paused;
|
||||
bool _active_volume_faders;
|
||||
bool _initialized;
|
||||
byte _volume_fader_counter;
|
||||
|
||||
uint _queue_end, _queue_pos, _queue_sound;
|
||||
byte _queue_adding;
|
||||
|
||||
SustainingNotes *_sustain_notes_used;
|
||||
SustainingNotes *_sustain_notes_free;
|
||||
SustainingNotes *_sustain_notes_head;
|
||||
|
||||
uint16 _timer_counter_1;
|
||||
|
||||
byte _queue_marker;
|
||||
byte _queue_cleared;
|
||||
byte _master_volume;
|
||||
|
||||
uint16 _trigger_count;
|
||||
|
||||
uint16 _channel_volume[8];
|
||||
uint16 _channel_volume_eff[8]; /* NoSave */
|
||||
uint16 _volchan_table[8];
|
||||
|
||||
Player _players[8];
|
||||
SustainingNotes _sustaining_notes[24];
|
||||
VolumeFader _volume_fader[8];
|
||||
Part _parts[32];
|
||||
MidiChannel _midi_channels[9];
|
||||
uint16 _active_notes[128];
|
||||
CommandQueue _cmd_queue[64];
|
||||
|
||||
int16 _midi_pitchbend_last[16];
|
||||
uint8 _midi_volume_last[16];
|
||||
bool _midi_pedal_last[16];
|
||||
byte _midi_modwheel_last[16];
|
||||
byte _midi_effectlevel_last[16];
|
||||
byte _midi_chorus_last[16];
|
||||
int8 _midi_pan_last[16];
|
||||
|
||||
byte *findTag(int sound, char *tag, int index);
|
||||
int initialize(Scumm *scumm);
|
||||
int terminate();
|
||||
int save_or_load(Serializer *ser);
|
||||
int set_master_volume(uint vol);
|
||||
int get_master_volume();
|
||||
bool start_sound(int sound);
|
||||
int stop_sound(int sound);
|
||||
int stop_all_sounds();
|
||||
int get_sound_status(int sound);
|
||||
int get_queue_sound_status(int sound);
|
||||
Player *allocate_player(byte priority);
|
||||
void handle_marker(uint id, byte data);
|
||||
int get_channel_volume(uint a);
|
||||
void init_players();
|
||||
void init_parts();
|
||||
void init_volume_fader();
|
||||
void init_sustaining_notes();
|
||||
void init_queue();
|
||||
|
||||
void on_timer();
|
||||
void sequencer_timers();
|
||||
void expire_sustain_notes();
|
||||
void expire_volume_faders();
|
||||
|
||||
void set_instrument(uint slot, byte *data) {}
|
||||
|
||||
int32 do_command(int a, int b, int c, int d, int e, int f, int g, int h);
|
||||
Part *allocate_part(byte pri);
|
||||
|
||||
int clear_queue();
|
||||
int enqueue_command(int a, int b, int c, int d, int e, int f, int g);
|
||||
int enqueue_trigger(int sound, int marker);
|
||||
int query_queue(int param);
|
||||
Player *get_player_byid(int id);
|
||||
|
||||
int get_volchan_entry(uint a);
|
||||
int set_volchan_entry(uint a, uint b);
|
||||
int set_channel_volume(uint chan, uint vol);
|
||||
void update_volumes();
|
||||
void reset_tick();
|
||||
VolumeFader *allocate_volume_fader();
|
||||
|
||||
int set_volchan(int sound, int volchan);
|
||||
|
||||
void midiPitchBend(byte chan, int16 pitchbend);
|
||||
void midiVolume(byte chan, byte volume);
|
||||
void midiPedal(byte chan, bool pedal);
|
||||
void midiModWheel(byte chan, byte modwheel);
|
||||
void midiEffectLevel(byte chan, byte level);
|
||||
void midiChorus(byte chan, byte chorus);
|
||||
void midiControl0(byte chan, byte value);
|
||||
void midiProgram(byte chan, byte program);
|
||||
void midiPan(byte chan, int8 pan);
|
||||
void midiNoteOn(byte chan, byte note, byte velocity);
|
||||
void midiNoteOff(byte chan, byte note);
|
||||
void midiSilence(byte chan);
|
||||
void midiInit();
|
||||
|
||||
void adjust_priorities();
|
||||
|
||||
void fix_parts_after_load();
|
||||
void fix_players_after_load();
|
||||
|
||||
static int saveReference(SoundEngine *me, byte type, void *ref);
|
||||
static void *loadReference(SoundEngine *me, byte type, int ref);
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
void pause(bool paused);
|
||||
};
|
|
@ -276,6 +276,8 @@ void Scumm::CHARSET_1() {
|
|||
_lastXstart = virtscr[0].xstart;
|
||||
if (charset._center) {
|
||||
charset._xpos2 -= charset.getStringWidth(0, buffer,0) >> 1;
|
||||
if (charset._xpos2<0)
|
||||
charset._xpos2 = 0;
|
||||
}
|
||||
|
||||
charset._disableOffsX = charset._unk12 = !_keepText;
|
||||
|
|
133
windows.cpp
133
windows.cpp
|
@ -31,11 +31,7 @@
|
|||
#endif
|
||||
|
||||
#include "scumm.h"
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
#include "sound.h"
|
||||
#endif
|
||||
|
||||
#include "gui.h"
|
||||
|
||||
#if !defined(ALLOW_GDI)
|
||||
|
@ -135,10 +131,7 @@ int sel;
|
|||
Scumm scumm;
|
||||
ScummDebugger debugger;
|
||||
Gui gui;
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
SoundEngine sound;
|
||||
#endif
|
||||
|
||||
WndMan wm[1];
|
||||
byte veryFastMode;
|
||||
|
@ -819,95 +812,6 @@ void blitToScreen(Scumm *s, byte *src,int x, int y, int w, int h) {
|
|||
|
||||
}
|
||||
|
||||
#define SAMPLES_PER_SEC 22050
|
||||
#define BUFFER_SIZE (8192)
|
||||
#define BITS_PER_SAMPLE 16
|
||||
|
||||
struct MixerChannel {
|
||||
void *_sfx_sound;
|
||||
uint32 _sfx_pos;
|
||||
uint32 _sfx_size;
|
||||
uint32 _sfx_fp_speed;
|
||||
uint32 _sfx_fp_pos;
|
||||
|
||||
void mix(int16 *data, uint32 len);
|
||||
void clear();
|
||||
};
|
||||
|
||||
#define NUM_MIXER 4
|
||||
|
||||
static MixerChannel mixer_channel[NUM_MIXER];
|
||||
|
||||
MixerChannel *find_channel() {
|
||||
int i;
|
||||
MixerChannel *mc = mixer_channel;
|
||||
for(i=0; i<NUM_MIXER; i++,mc++) {
|
||||
if (!mc->_sfx_sound)
|
||||
return mc;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool isSfxFinished() {
|
||||
int i;
|
||||
for(i=0; i<NUM_MIXER; i++)
|
||||
if (mixer_channel[i]._sfx_sound)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
void playSfxSound(void *sound, uint32 size, uint rate) {
|
||||
MixerChannel *mc = find_channel();
|
||||
|
||||
if (!mc) {
|
||||
warning("No mixer channel available");
|
||||
return;
|
||||
}
|
||||
|
||||
mc->_sfx_sound = sound;
|
||||
mc->_sfx_pos = 0;
|
||||
mc->_sfx_fp_speed = (1<<16) * rate / 22050;
|
||||
mc->_sfx_fp_pos = 0;
|
||||
|
||||
while (size&0xFFFF0000) size>>=1, rate>>=1;
|
||||
mc->_sfx_size = size * 22050 / rate;
|
||||
}
|
||||
|
||||
void MixerChannel::mix(int16 *data, uint32 len) {
|
||||
int8 *s;
|
||||
int i;
|
||||
uint32 fp_pos, fp_speed;
|
||||
|
||||
if (!_sfx_sound)
|
||||
return;
|
||||
if (len > _sfx_size)
|
||||
len = _sfx_size;
|
||||
_sfx_size -= len;
|
||||
|
||||
s = (int8*)_sfx_sound + _sfx_pos;
|
||||
fp_pos = _sfx_fp_pos;
|
||||
fp_speed = _sfx_fp_speed;
|
||||
|
||||
do {
|
||||
fp_pos += fp_speed;
|
||||
*data++ += (*s<<6);
|
||||
s += fp_pos >> 16;
|
||||
fp_pos &= 0x0000FFFF;
|
||||
} while (--len);
|
||||
|
||||
_sfx_pos = s - (int8*)_sfx_sound;
|
||||
_sfx_fp_speed = fp_speed;
|
||||
_sfx_fp_pos = fp_pos;
|
||||
|
||||
if (!_sfx_size)
|
||||
clear();
|
||||
}
|
||||
|
||||
void MixerChannel::clear() {
|
||||
free(_sfx_sound);
|
||||
_sfx_sound = NULL;
|
||||
}
|
||||
|
||||
int clock;
|
||||
|
||||
|
@ -923,8 +827,8 @@ void updateScreen(Scumm *s) {
|
|||
void waitForTimer(Scumm *s, int delay) {
|
||||
wm->handleMessage();
|
||||
if (!veryFastMode) {
|
||||
assert(delay<500);
|
||||
Sleep(delay*10);
|
||||
assert(delay<5000);
|
||||
Sleep(delay);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -940,16 +844,8 @@ void drawMouse(Scumm *s, int x, int y, int w, int h, byte *buf, bool visible) {
|
|||
}
|
||||
|
||||
void fill_buffer(int16 *buf, int len) {
|
||||
int i;
|
||||
#if defined(USE_IMUSE)
|
||||
sound.generate_samples(buf,len);
|
||||
#else
|
||||
memset(buf, 0, len*2);
|
||||
#endif
|
||||
for(i=NUM_MIXER-1; i>=0;i--) {
|
||||
mixer_channel[i].mix((int16*)buf, len);
|
||||
}
|
||||
|
||||
scumm.mixWaves(buf, len);
|
||||
}
|
||||
|
||||
void WndMan::prepare_header(WAVEHDR *wh, int i) {
|
||||
|
@ -975,6 +871,7 @@ void WndMan::sound_init() {
|
|||
wfx.nBlockAlign = BITS_PER_SAMPLE * 1 / 8;
|
||||
|
||||
CreateThread(NULL, 0, (unsigned long (__stdcall *)(void *))&sound_thread, this, 0, &_threadId);
|
||||
SetThreadPriority((void*)_threadId, THREAD_PRIORITY_HIGHEST);
|
||||
|
||||
_event = CreateEvent(NULL, false, false, NULL);
|
||||
|
||||
|
@ -988,8 +885,19 @@ void WndMan::sound_init() {
|
|||
|
||||
DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
|
||||
int i;
|
||||
bool signaled;
|
||||
int time = GetTickCount(), cur;
|
||||
|
||||
while (1) {
|
||||
WaitForSingleObject(wm->_event, INFINITE);
|
||||
cur = GetTickCount();
|
||||
while (time < cur) {
|
||||
sound.on_timer();
|
||||
time += 10;
|
||||
}
|
||||
|
||||
signaled = WaitForSingleObject(wm->_event, time - cur) == WAIT_OBJECT_0;
|
||||
|
||||
if (signaled) {
|
||||
for(i=0; i<2; i++) {
|
||||
WAVEHDR *hdr = &wm->_hdr[i];
|
||||
if (hdr->dwFlags & WHDR_DONE) {
|
||||
|
@ -998,6 +906,7 @@ DWORD _stdcall WndMan::sound_thread(WndMan *wm) {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -1011,10 +920,8 @@ int main(int argc, char* argv[]) {
|
|||
wm->_vgabuf = (byte*)calloc(320,200);
|
||||
wm->_scumm = &scumm;
|
||||
|
||||
#if defined(USE_IMUSE)
|
||||
sound.initialize(NULL);
|
||||
sound.initialize(&scumm);
|
||||
scumm._soundDriver = &sound;
|
||||
#endif
|
||||
|
||||
scumm._gui = &gui;
|
||||
scumm.scummMain(argc, argv);
|
||||
|
@ -1024,6 +931,8 @@ int main(int argc, char* argv[]) {
|
|||
do {
|
||||
updateScreen(&scumm);
|
||||
|
||||
waitForTimer(&scumm, tmp*10);
|
||||
|
||||
if (gui._active) {
|
||||
gui.loop();
|
||||
tmp = 5;
|
||||
|
@ -1035,8 +944,6 @@ int main(int argc, char* argv[]) {
|
|||
if (scumm._fastMode)
|
||||
tmp=1;
|
||||
}
|
||||
|
||||
waitForTimer(&scumm, tmp);
|
||||
} while(1);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue