From a5993b21129b133bdbd570a3f540caf44c0c3958 Mon Sep 17 00:00:00 2001 From: Eugene Sandulenko Date: Wed, 13 Apr 2005 18:27:29 +0000 Subject: Support for Red Book audio in CD version of gob1. svn-id: r17588 --- gob/cdrom.cpp | 236 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gob/cdrom.h | 39 ++++++++++ gob/draw.cpp | 4 + gob/goblin.cpp | 4 + gob/init.cpp | 7 ++ gob/inter.cpp | 15 ++-- gob/module.mk | 1 + gob/scenery.cpp | 7 ++ 8 files changed, 307 insertions(+), 6 deletions(-) create mode 100644 gob/cdrom.cpp create mode 100644 gob/cdrom.h diff --git a/gob/cdrom.cpp b/gob/cdrom.cpp new file mode 100644 index 0000000000..26193ef1ff --- /dev/null +++ b/gob/cdrom.cpp @@ -0,0 +1,236 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005 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$ + * + */ +#include "gob/gob.h" +#include "gob/cdrom.h" +#include "gob/dataio.h" +#include "gob/game.h" +#include "gob/global.h" +#include "gob/util.h" +#include "sound/audiocd.h" + +namespace Gob { + +byte *cd_LICbuffer; +char cd_curTrack[16]; +uint16 cd_numTracks; +bool cd_globFlag; +uint32 cd_trackStop; +uint32 cd_startTime; + +void cd_readLIC(const char *fname) { + char tmp[80]; + int handle; + uint16 version, startChunk, pos; + + cd_freeLICbuffer(); + + *cd_curTrack = 0; + + strcpy(tmp, fname); + + handle = data_openData(tmp); + + if (handle == -1) + return; + + data_closeData(handle); + + data_getUnpackedData(tmp); + + handle = data_openData(tmp); + + data_readData(handle, (char *)&version, 2); + version = READ_LE_UINT16(&version); + + data_readData(handle, (char *)&startChunk, 2); + startChunk = READ_LE_UINT16(&startChunk); + + data_readData(handle, (char *)&cd_numTracks, 2); + cd_numTracks = READ_LE_UINT16(&cd_numTracks); + + if (version != 3) { + error("Wrong file %s (%d)", fname, version); + return; + } + + data_seekData(handle, 50, SEEK_SET); + + for (int i = 0; i < startChunk; i++) { + data_readData(handle, (char *)&pos, 2); + pos = READ_LE_UINT16(&pos); + + if (!pos) + break; + + data_seekData(handle, pos, SEEK_CUR); + } + + cd_LICbuffer = (byte *)malloc(cd_numTracks * 22); + data_readData(handle, (char *)cd_LICbuffer, cd_numTracks * 22); + + data_closeData(handle); +} + +void cd_freeLICbuffer(void) { + free(cd_LICbuffer); + cd_LICbuffer = 0; +} + +void cd_playBgMusic() { + static const char *tracks[][2] = { + {"avt00.tot", "mine"}, + {"avt001.tot", "nuit"}, + {"avt002.tot", "campagne"}, + {"avt003.tot", "extsor1"}, + {"avt004.tot", "interieure"}, + {"avt005.tot", "zombie"}, + {"avt006.tot", "zombie"}, + {"avt007.tot", "campagne"}, + {"avt008.tot", "campagne"}, + {"avt009.tot", "extsor1"}, + {"avt010.tot", "extsor1"}, + {"avt011.tot", "interieure"}, + {"avt012.tot", "zombie"}, + {"avt014.tot", "nuit"}, + {"avt015.tot", "interieure"}, + {"avt016.tot", "statue"}, + {"avt017.tot", "zombie"}, + {"avt018.tot", "statue"}, + {"avt019.tot", "mine"}, + {"avt020.tot", "statue"}, + {"avt021.tot", "mine"}, + {"avt022.tot", "zombie"} + }; + + for (int i = 0; i < ARRAYSIZE(tracks); i++) + if (!scumm_stricmp(game_curTotFile, tracks[i][0])) { + cd_startTrack(tracks[i][1]); + break; + } +} + +void cd_playMultMusic() { + static const char *tracks[][6] = { + {"avt005.tot", "fra1", "all1", "ang1", "esp1", "ita1"}, + {"avt006.tot", "fra2", "all2", "ang2", "esp2", "ita2"}, + {"avt012.tot", "fra3", "all3", "ang3", "esp3", "ita3"}, + {"avt016.tot", "fra4", "all4", "ang4", "esp4", "ita4"}, + {"avt019.tot", "fra5", "all5", "ang5", "esp5", "ita5"}, + {"avt022.tot", "fra6", "all6", "ang6", "esp6", "ita6"} + }; + + for (int i = 0; i < ARRAYSIZE(tracks); i++) + if (!scumm_stricmp(game_curTotFile, tracks[i][0])) { + cd_globFlag = true; + cd_startTrack(tracks[i][language + 1]); + break; + } +} + +void cd_startTrack(const char *trackname) { + byte *curPtr, *matchPtr; + + if (!cd_LICbuffer) + return; + + debug(3, "cd_startTrack(%s)", trackname); + + matchPtr = 0; + curPtr = cd_LICbuffer; + + for (int i = 0; i < cd_numTracks; i++) { + if (!scumm_stricmp((char *)curPtr, trackname)) { + matchPtr = curPtr; + break; + } + curPtr += 22; + } + + if (!matchPtr) { + error("Track %s not found", trackname); + return; + } + + strcpy(cd_curTrack, trackname); + + cd_stopPlaying(); + + while (cd_getTrackPos() != -1); + + uint32 start, end; + + start = READ_LE_UINT32(matchPtr + 12); + end = READ_LE_UINT32(matchPtr + 16); + + cd_play(start, end); + + cd_startTime = util_getTimeKey(); + cd_trackStop = cd_startTime + (end - start + 1 + 150) * 40 / 3 + 500; +} + +void cd_play(uint32 from, uint32 to) { + // play from sector [from] to sector [to] + // + // format is HSG: + // HSG encodes frame information into a double word: + // minute multiplied by 4500, plus second multiplied by 75, + // plus frame, minus 150 + debug(3, "cd_play(%d, %d)", from, to); + + AudioCD.play(1, 0, from, to - from + 1); +} + +int32 cd_getTrackPos(void) { + uint32 curPos = util_getTimeKey() - cd_startTime; + + if (AudioCD.isPlaying() && (util_getTimeKey() < cd_trackStop)) + return curPos * 3 / 40; + else + return -1; +} + +void cd_stopPlaying(void) { + cd_stop(); + + while (cd_getTrackPos() != -1); +} + +void cd_stop(void) { + debug(3, "cd_stop()"); + + AudioCD.stop(); +} + +void cd_testCD(int trySubst, const char *label) { + if (!trySubst) { + error("CDROM track substitution is not supported"); + return; + } + + cd_LICbuffer = 0; + cd_globFlag = false; + + // Original checked CD label here + // but will skip it as it will require OSystem extensions of direct + // CD secor reading +} + +} // End of namespace Gob diff --git a/gob/cdrom.h b/gob/cdrom.h new file mode 100644 index 0000000000..5d8b1a7f2c --- /dev/null +++ b/gob/cdrom.h @@ -0,0 +1,39 @@ +/* ScummVM - Scumm Interpreter + * Copyright (C) 2005 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$ + * + */ +#include "gob/gob.h" + +namespace Gob { + +extern bool cd_globFlag; + +void cd_readLIC(const char *fname); +void cd_freeLICbuffer(void); + +void cd_startTrack(const char *s); +void cd_playBgMusic(); +void cd_playMultMusic(); +void cd_play(uint32 from, uint32 to); +int32 cd_getTrackPos(void); +void cd_stopPlaying(void); +void cd_stop(void); +void cd_testCD(int trySubst, const char *label); + +} // End of namespace Gob diff --git a/gob/draw.cpp b/gob/draw.cpp index 4cc7de1966..480d8b016d 100644 --- a/gob/draw.cpp +++ b/gob/draw.cpp @@ -29,6 +29,7 @@ #include "gob/inter.h" #include "gob/video.h" #include "gob/palanim.h" +#include "gob/cdrom.h" namespace Gob { @@ -759,6 +760,9 @@ void draw_printText(void) { char buf[20]; index = inter_load16(); + + cd_playMultMusic(); + dataPtr = (char *)game_totTextData + game_totTextData->items[index].offset; ptr = dataPtr; diff --git a/gob/goblin.cpp b/gob/goblin.cpp index 0827490b68..80c007c6b1 100644 --- a/gob/goblin.cpp +++ b/gob/goblin.cpp @@ -31,6 +31,7 @@ #include "gob/sound.h" #include "gob/game.h" #include "gob/dataio.h" +#include "gob/cdrom.h" namespace Gob { @@ -3160,6 +3161,9 @@ void gob_interFunc(void) { case 1003: gob_drawObjects(); + + if (cd_getTrackPos() == -1) + cd_playBgMusic(); break; case 1004: diff --git a/gob/init.cpp b/gob/init.cpp index 90a2dd174e..21cb589932 100644 --- a/gob/init.cpp +++ b/gob/init.cpp @@ -30,6 +30,7 @@ #include "gob/game.h" #include "gob/draw.h" #include "gob/util.h" +#include "gob/cdrom.h" namespace Gob { @@ -276,8 +277,14 @@ memBlocks = word ptr -2*/ memset(inter_variables, 0, varsCount * 4); strcpy(game_curTotFile, buffer); + + cd_testCD(1, "GOB"); + cd_readLIC("gob.lic"); game_start(); + cd_stopPlaying(); + cd_freeLICbuffer(); + if (inter_variables != 0) free(inter_variables); diff --git a/gob/inter.cpp b/gob/inter.cpp index a2a418407b..69ff7a0161 100644 --- a/gob/inter.cpp +++ b/gob/inter.cpp @@ -29,6 +29,7 @@ #include "gob/draw.h" #include "gob/mult.h" #include "gob/goblin.h" +#include "gob/cdrom.h" namespace Gob { @@ -408,18 +409,20 @@ void inter_drawOperations(void) { break; case 32: - // FIXME // Used in gob1 CD - warning("unimplemented drawOperation: %d", cmd); inter_evalExpr(0); + cd_startTrack(inter_resStr); break; case 33: - // FIXME // Used in gob1 CD - warning("unimplemented drawOperation: %d", cmd); - WRITE_VAR(5, 32767); - break; + WRITE_VAR(5, cd_getTrackPos()); + break; + + case 34: + // Used in gob1 CD + cd_stopPlaying(); + break; case 48: i = inter_load16(); diff --git a/gob/module.mk b/gob/module.mk index 74f34da27e..5089182fb2 100644 --- a/gob/module.mk +++ b/gob/module.mk @@ -2,6 +2,7 @@ MODULE := gob MODULE_OBJS := \ gob/anim.o \ + gob/cdrom.o \ gob/dataio.o \ gob/draw.o \ gob/driver_vga.o \ diff --git a/gob/scenery.cpp b/gob/scenery.cpp index ac3d9a50d6..2de9587cf8 100644 --- a/gob/scenery.cpp +++ b/gob/scenery.cpp @@ -29,6 +29,7 @@ #include "gob/util.h" #include "gob/anim.h" #include "gob/parse.h" +#include "gob/cdrom.h" namespace Gob { @@ -383,6 +384,12 @@ int16 scen_loadAnim(char search) { int16 sprResId; int16 sprIndex; + if (cd_globFlag) { + while (cd_getTrackPos() != -1); + + cd_globFlag = false; + } + inter_evalExpr(&sceneryIndex); picsCount = inter_load16(); resId = inter_load16(); -- cgit v1.2.3