[Scummvm-cvs-logs] CVS: scummvm/kyra codecs.cpp,1.6,1.7 cpsimage.cpp,1.1,1.2 kyra.cpp,1.7,1.8 kyra.h,1.3,1.4 module.mk,1.4,1.5 palette.cpp,1.2,1.3 resource.cpp,1.5,1.6 resource.h,1.3,1.4 script.cpp,1.6,1.7 script.h,1.2,1.3 script_v1.cpp,1.4,1.5 wsamovie.cpp,1.2,1.3 wsamovie.h,1.1,1.2
James Brown
ender at users.sourceforge.net
Thu Nov 11 05:36:00 CET 2004
Update of /cvsroot/scummvm/scummvm/kyra
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4570/kyra
Modified Files:
codecs.cpp cpsimage.cpp kyra.cpp kyra.h module.mk palette.cpp
resource.cpp resource.h script.cpp script.h script_v1.cpp
wsamovie.cpp wsamovie.h
Log Message:
Bring kyra up-to-date with patch 1051358
Index: codecs.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/codecs.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- codecs.cpp 30 Oct 2004 21:54:18 -0000 1.6
+++ codecs.cpp 11 Nov 2004 13:35:21 -0000 1.7
@@ -84,9 +84,13 @@
copyp = (const uint8*)&image_out[READ_LE_UINT16(readp)];
readp += 2;
- memcpy(writep, copyp, count);
- writep += count;
- copyp += count;
+ // FIXME: Using memmove sometimes segfaults
+ // (reproducably for Ender), which suggests something Bad here
+ //memmove(writep, copyp, count);
+ //writep += count;
+ //copyp += count;
+ while (count--)
+ *writep++ = *copyp++;
} else if (count == 0x3e) {
//command 3 (11111110 c c v): fill
Index: cpsimage.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/cpsimage.cpp,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- cpsimage.cpp 15 Oct 2004 06:06:47 -0000 1.1
+++ cpsimage.cpp 11 Nov 2004 13:35:21 -0000 1.2
@@ -51,6 +51,7 @@
if (!buffer) {
error("resource created without data");
}
+ _ownPalette = 0;
Common::MemoryReadStream bufferstream(buffer, size);
// reads in the Header
@@ -61,11 +62,15 @@
// lets check a bit
if(_cpsHeader._pal == 0x3000000) {
- warning("CPS images with a palette aren't supported");
-
- // skip 768 bytes
// if this was a compressed palette you should have strange graphics
- bufferstream.seek(bufferstream.pos() + 768);
+
+ uint8* palbuffer = new uint8[768];
+ assert(palbuffer);
+
+ bufferstream.read(palbuffer, 768 * sizeof(uint8));
+
+ _ownPalette = new Palette(palbuffer, 768);
+ assert(palbuffer);
}
_image = new uint8[_cpsHeader._imagesize];
@@ -104,16 +109,15 @@
}
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y) {
+ uint8* src = _image;
+ uint8* dst = &plane[y * planepitch + x];
+ uint32 copysize = planepitch - x;
+
+ if (copysize > _width)
+ copysize = _width;
+
if (_transparency == -1) {
// 'fast' blitting
-
- uint8* src = _image;
- uint8* dst = &plane[y * planepitch + x];
- uint32 copysize = planepitch - x;
-
- if (copysize > _width)
- copysize = _width;
-
for (uint16 y_ = 0; y_ < _height && y + y_ < planeheight; ++y_) {
memcpy(dst, src, copysize * sizeof(uint8));
dst += planepitch;
@@ -122,11 +126,9 @@
} else {
// oh no! we have transparency so we have a very slow copy :/
- uint8* src = _image;
- uint8* dst = &plane[y * planepitch + x];
for (uint16 yadd = 0; yadd < _height; ++yadd) {
- for (uint16 xadd = 0; xadd < _width; ++xadd) {
+ for (uint16 xadd = 0; xadd < copysize; ++xadd) {
if (*src == _transparency) {
++dst;
++src;
@@ -135,23 +137,26 @@
}
}
- dst += planepitch - _width;
+ src += _width - copysize;
+ dst += planepitch - copysize;
}
}
}
void CPSImage::drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
uint16 srcx, uint16 srcy, uint16 srcwidth, uint16 srcheight) {
+ uint8* src = &_image[srcy * _width + srcx];
+ uint8* dst = &plane[y * planepitch + x];
+ uint32 copysize = planepitch - x;
+
+ if (srcwidth > _width)
+ srcwidth = _width;
+
+ if (copysize > srcwidth)
+ copysize = srcwidth;
+
if (_transparency == -1) {
// 'fast' blitting
-
- uint8* src = &_image[srcy * _width + srcx];
- uint8* dst = &plane[y * planepitch + x];
- uint32 copysize = planepitch - x;
-
- if (copysize > srcwidth)
- copysize = srcwidth;
-
for (uint16 y_ = 0; y_ < srcheight && y + y_ < planeheight; ++y_) {
memcpy(dst, src, copysize * sizeof(uint8));
dst += planepitch;
@@ -160,12 +165,9 @@
} else {
// oh no! we have transparency so we have a very slow copy :/
- // blit it without transparency
- uint8* src = &_image[srcy * _width + srcx];
- uint8* dst = &plane[y * planepitch + x];
- for (uint16 yadd = 0; yadd < _height; ++yadd) {
- for (uint16 xadd = 0; xadd < _width; ++xadd) {
+ for (uint16 yadd = 0; yadd < srcheight; ++yadd) {
+ for (uint16 xadd = 0; xadd < copysize; ++xadd) {
if (*src == _transparency) {
++dst;
++src;
@@ -174,8 +176,8 @@
}
}
- dst += planepitch - _width;
- src += _width - srcwidth;
+ dst += planepitch - copysize;
+ src += _width - copysize;
}
}
}
Index: kyra.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- kyra.cpp 10 Nov 2004 18:45:30 -0000 1.7
+++ kyra.cpp 11 Nov 2004 13:35:21 -0000 1.8
@@ -28,10 +28,13 @@
#include "sound/mixer.h"
#include "common/file.h"
#include "common/config-manager.h"
+#include "sound/mididrv.h"
#include "kyra.h"
#include "resource.h"
#include "script.h"
+#include "wsamovie.h"
+#include "sound.h"
struct KyraGameSettings {
const char *name;
@@ -44,10 +47,13 @@
}
};
-static const KyraGameSettings kyra_settings[] = {
- {"kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE & GF_KYRA1, "CHAPTER1.VRM"},
- {"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY & GF_KYRA1, "INTRO.SND"},
- { 0, 0, 0, 0}
+static const KyraGameSettings kyra_settings[] = {
+ {"kyra1", "Legend of Kyrandia (Floppy)", GF_FLOPPY | GF_KYRA1, "INTRO.SND"},
+ {"kyra1cd", "Legend of Kyrandia (CD)", GF_TALKIE | GF_KYRA1, "CHAPTER1.VRM"},
+ {"kyra2", "Hand of Fate (Floppy)", GF_FLOPPY | GF_KYRA2, 0 },
+ {"kyra2cd", "Hand of Fate (CD)", GF_TALKIE | GF_KYRA2, "AUDIO.PAK"},
+ {"kyra3", "Malcom's Revenge", GF_TALKIE | GF_KYRA3, "K3INTRO0.VQA"},
+ {0, 0, 0, 0}
};
GameList Engine_KYRA_gameList() {
@@ -99,10 +105,40 @@
_mixer->setVolume(ConfMan.getInt("sfx_volume") * ConfMan.getInt("master_volume") / 255);
+ // gets the game
+ if (detector->_game.features & GF_KYRA1) {
+ if (detector->_game.features & GF_FLOPPY)
+ _game = KYRA1;
+ else
+ _game = KYRA1CD;
+ } else if (detector->_game.features & GF_KYRA2) {
+ if (detector->_game.features & GF_FLOPPY)
+ _game = KYRA2;
+ else
+ _game = KYRA2CD;
+ } else if (detector->_game.features & GF_KYRA3) {
+ _game = KYRA3;
+ } else {
+ error("unknown game");
+ }
+
+ MidiDriver *driver = GameDetector::createMidi(GameDetector::detectMusicDriver(MDT_NATIVE | MDT_PREFER_NATIVE));
+ if (driver) {
+ if (ConfMan.getBool("native_mt32"))
+ driver->property(MidiDriver::PROP_CHANNEL_MASK, 0x03FE);
+ _midiDriver = new MusicPlayer(driver, this);
+ assert(_midiDriver);
+ _midiDriver->hasNativeMT32(ConfMan.getBool("native_mt32"));
+ _midiDriver->setVolume(255);
+ } else {
+ warning("Couldn't create MIDI driver... No music!");
+ _midiDriver = NULL;
+ };
+
// Initialize backen
syst->initSize(320, 200);
- _screen = new uint8[320 * 200];
- memset(_screen, 0, 320 * 200);
+ _screen = new uint8[320*200];
+ memset(_screen, 0, sizeof(uint8) * 320 * 200);
_resMgr = new Resourcemanager(this);
assert(_resMgr);
@@ -110,15 +146,23 @@
setCurrentPalette(_resMgr->loadPalette("PALETTE.COL"));
// loads the 2 cursors
- _mouse = _resMgr->loadImage("MOUSE.CPS"); //startup.pak
+ _mouse = _resMgr->loadImage("MOUSE.CPS");
_items = _resMgr->loadImage("ITEMS.CPS");
// loads the Font
_font = _resMgr->loadFont("8FAT.FNT");
-
- // loads out scripts
+
_npcScript = _resMgr->loadScript("_NPC.EMC");
- _currentScript = _resMgr->loadScript("_STARTUP.EMC");
+
+ // loads the scripts (only Kyrandia 1)
+ if (_game == KYRA1 || _game == KYRA1CD) {
+ _currentScript = _resMgr->loadScript("_STARTUP.EMC");
+ } else {
+ error("game start files not known");
+ }
+
+ assert(_npcScript);
+ assert(_currentScript);
}
KyraEngine::~KyraEngine() {
@@ -138,7 +182,7 @@
void KyraEngine::go() {
warning("Kyrandia Engine ::go()");
// starts the init script
- if (!_currentScript->startScript(kSetupScene)) {
+ /*if (!_currentScript->startScript(kSetupScene)) {
error("couldn't init '_STARTUP.EMC' script");
}
@@ -148,25 +192,67 @@
} else {
warning("init script returned: %d", _currentScript->state());
}
- }
+ }*/
+
+ Movie* movie = _resMgr->loadMovie("MAL-KAL.WSA");
+ assert(movie);
+ CPSImage* image = _resMgr->loadImage("GEMCUT.CPS");
+ assert(image);
+
+ int16 currentFrame = 0;
+ uint32 lastFrameChange = 0;
+
+ image->transparency(0);
+ image->drawToPlane(_screen, 320, 200, 0, 0, 0, 0, 320, 136);
+ movie->setImageBackground(_screen, 320, 200);
+ movie->position(16, 58);
+
+ setCurrentPalette(_resMgr->loadPalette("MAL-KAL.COL"));
+ uint8* _buffer = new uint8[320 * 200];
+ assert(_buffer);
+ memcpy(_buffer, _screen, 320 * 200);
+ movie->renderFrame(_buffer, 320, 200, movie->countFrames() - 1);
+
+ if (_midiDriver) {
+ _midiDriver->playMusic("KYRA2A.XMI");
+ _midiDriver->playTrack(3);
+ }
+
while(true) {
OSystem::Event event;
//if (_debugger->isAttached())
// _debugger->onFrame();
+
+ memcpy(_screen, _buffer, 320 * 200);
+ if (lastFrameChange + movie->frameChange() < _system->getMillis()) {
+ lastFrameChange = _system->getMillis();
+ ++currentFrame;
+ if (currentFrame >= (int16)movie->countFrames()) {
+ currentFrame = 0;
+ }
+ }
+
+ movie->renderFrame(_screen, 320, 200, currentFrame);
+ _font->drawStringToPlane("This is only a test!", _screen, 320, 200, 75, 179, 136);
+ _font->drawStringToPlane("Nothing scripted!", _screen, 320, 200, 85, 189, 136);
updateScreen();
while (g_system->pollEvent(event)) {
switch (event.event_code) {
- case OSystem::EVENT_QUIT:
- g_system->quit();
- break;
- default:
- break;
+ case OSystem::EVENT_QUIT:
+ g_system->quit();
+ break;
+ default:
+ break;
}
}
_system->delayMillis(10);
}
+
+ delete movie;
+ delete image;
+ delete [] _buffer;
}
void KyraEngine::shutdown() {
@@ -179,12 +265,15 @@
}
void KyraEngine::setCurrentPalette(Palette* pal, bool delNextTime) {
-// if (_delPalNextTime)
-// delete _currentPal;
+ if (!pal)
+ return;
-// _delPalNextTime = delNextTime;
+// if (_delPalNextTime)
+// delete _currentPal;
-// _currentPal = pal;
+// _delPalNextTime = delNextTime;
+
+// _currentPal = pal;
if (pal->getData()) {
_system->setPalette(pal->getData(), 0, 256);
Index: kyra.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/kyra.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- kyra.h 16 Oct 2004 22:28:29 -0000 1.3
+++ kyra.h 11 Nov 2004 13:35:21 -0000 1.4
@@ -8,7 +8,7 @@
* 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
+ * 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
@@ -31,7 +31,17 @@
GF_FLOPPY = 1 << 0,
GF_TALKIE = 1 << 1,
GF_KYRA1 = 1 << 2,
- GF_KYRA2 = 1 << 3
+ GF_KYRA2 = 1 << 3,
+ GF_KYRA3 = 1 << 4,
+ GF_AUDIOCD = 1 << 5 // FM-Towns versions seems to use audio CD
+};
+
+enum {
+ KYRA1 = 0,
+ KYRA1CD = 1,
+ KYRA2 = 2,
+ KYRA2CD = 3,
+ KYRA3 = 4
};
namespace Kyra {
@@ -40,6 +50,7 @@
class Font;
class Palette;
class VMContext;
+ class MusicPlayer;
class KyraEngine : public Engine {
public:
@@ -51,13 +62,17 @@
void setCurrentPalette(Palette* pal, bool delNextTime = true);
Resourcemanager* resManager(void) { return _resMgr; }
-// MidiDriver* midiDriver(void) { return _midiDriver; }
+ MusicPlayer* midiDriver(void) { return _midiDriver; }
+
+ uint8 game(void) { return _game; }
protected:
void go();
void shutdown();
Resourcemanager* _resMgr;
+ MusicPlayer* _midiDriver;
uint8 *_screen;
+ uint8 _game;
Font* _font;
CPSImage* _mouse;
Index: module.mk
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/module.mk,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- module.mk 6 Nov 2004 09:26:36 -0000 1.4
+++ module.mk 11 Nov 2004 13:35:21 -0000 1.5
@@ -9,6 +9,7 @@
kyra/resource.o \
kyra/script_v1.o \
kyra/script.o \
+ kyra/sound.o \
kyra/wsamovie.o
MODULE_DIRS += \
Index: palette.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/palette.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- palette.cpp 16 Oct 2004 22:28:29 -0000 1.2
+++ palette.cpp 11 Nov 2004 13:35:21 -0000 1.3
@@ -21,7 +21,7 @@
#include "stdafx.h"
#include "resource.h"
-
+
#include "common/stream.h"
#include "codecs.h"
@@ -52,7 +52,7 @@
}
delete [] data;
- data = _palette;
+ data = _palette;
}
// hmm.. common/system.h Docu is wrong or SDL Backend has a bug :)
Index: resource.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- resource.cpp 10 Nov 2004 18:09:14 -0000 1.5
+++ resource.cpp 11 Nov 2004 13:35:21 -0000 1.6
@@ -34,21 +34,48 @@
// ugly a hardcoded list
// TODO: use the FS Backend to get all .PAK Files and load them
- static const char* kyraFilelist[] = {
+ // or any other thing to get all files
+ static const char* kyra1Filelist[] = {
"A_E.PAK", "DAT.PAK", "F_L.PAK", "MAP_5.PAK", "MSC.PAK", "M_S.PAK",
"S_Z.PAK", "WSA1.PAK", "WSA2.PAK", "WSA3.PAK", "WSA4.PAK", "WSA5.PAK",
- "WSA6.PAK", "startup.pak", "intro1.pak", 0
+ "WSA6.PAK", 0
};
- for (uint32 tmp = 0; kyraFilelist[tmp]; ++tmp) {
+ static const char* kyra1CDFilelist[] = {
+ "ADL.PAK", "BRINS.PAK", "CLIFF.PAK", "ENTER.PAK", "FORESTA.PAK", "GEM.PAK", "INTRO1.PAK",
+ "LEPHOLE.PAK", "OAKS.PAK", "SPELL.PAK", "WILLOW.PAK", "ALCHEMY.PAK", "BROKEN.PAK", "COL.PAK",
+ "EXTHEAL.PAK", "FORESTB.PAK", "GEMCUT.PAK", "INTRO2.PAK", "LIBRARY.PAK", "PLATEAU.PAK", "SPRING.PAK",
+ "WISE.PAK", "ALGAE.PAK", "BURN.PAK", "DARMS.PAK", "EXTPOT.PAK", "FORESTC.PAK", "GENCAVB.PAK",
+ "INTRO3.PAK", "MISC.PAK", "PLTCAVE.PAK", "SQUARE.PAK", "XEDGE.PAK", "ALTAR.PAK", "CASTLE.PAK",
+ "DEAD.PAK", "EXTSPEL.PAK", "FOUNTN.PAK", "GENHALL.PAK", "INTRO4.PAK", "MIX.PAK", "POTION.PAK",
+ "STARTUP.PAK", "XEDGEB.PAK", "ARCH.PAK", "CATACOM.PAK", "DNSTAIR.PAK", "FALLS.PAK", "FOYER.PAK",
+ "GEN_CAV.PAK", "KITCHEN.PAK", "MOONCAV.PAK", "RUBY.PAK", "STUMP.PAK", "XEDGEC.PAK", "BALCONY.PAK",
+ "CAVE.PAK", "DRAGON.PAK", "FESTSTH.PAK", "FSOUTH.PAK", "GLADE.PAK", "KYRAGEM.PAK", "NCLIFF.PAK",
+ "SICKWIL.PAK", "TEMPLE.PAK", "XMI.PAK", "BELROOM.PAK", "CAVEB.PAK", "EDGE.PAK", "FGOWEST.PAK",
+ "FSOUTHB.PAK", "GRAVE.PAK", "LAGOON.PAK", "NCLIFFB.PAK", "SND.PAK", "TRUNK.PAK", "ZROCK.PAK",
+ "BONKBG.PAK", "CGATE.PAK", "EDGEB.PAK", "FINALE.PAK", "FWSTSTH.PAK", "GRTHALL.PAK", "LANDING.PAK",
+ "NWCLIFB.PAK", "SONG.PAK", "UPSTAIR.PAK", "BRIDGE.PAK", "CHASM.PAK", "EMCAV.PAK", "FNORTH.PAK",
+ "GATECV.PAK", "HEALER.PAK", "LAVA.PAK", "NWCLIFF.PAK", "SORROW.PAK", "WELL.PAK", 0
+ };
+
+ const char** usedFilelist = 0;
+
+ if (_engine->game() == KYRA1)
+ usedFilelist = kyra1Filelist;
+ else if (_engine->game() == KYRA1CD)
+ usedFilelist = kyra1CDFilelist;
+ else
+ error("no filelist found for this game");
+
+ for (uint32 tmp = 0; usedFilelist[tmp]; ++tmp) {
// prefetch file
- PAKFile* file = new PAKFile(kyraFilelist[tmp]);
+ PAKFile* file = new PAKFile(usedFilelist[tmp]);
assert(file);
- if (file->isOpen() && file->isValid())
+ if (file->isOpen() && file->isValid())
_pakfiles.push_back(file);
else
- warning("couldn't load file '%s' correctly", kyraFilelist[tmp]);
+ debug("couldn't load file '%s' correctly", usedFilelist[tmp]);
}
}
@@ -63,11 +90,8 @@
uint8* Resourcemanager::fileData(const char* file, uint32* size) {
uint8* buffer = 0;
-
- debug("looking for file '%s'", file);
-
File file_;
-
+
// test to open it in the main dir
if (file_.open(file)) {
@@ -83,37 +107,39 @@
} else {
// opens the file in a PAK File
Common::List<PAKFile*>::iterator start = _pakfiles.begin();
-
+
for (;start != _pakfiles.end(); ++start) {
*size = (*start)->getFileSize(file);
-
- if (!*size)
+
+ if (!(*size))
continue;
-
+
buffer = new uint8[*size];
assert(buffer);
-
+
// creates a copy of the file
memcpy(buffer, (*start)->getFile(file), *size);
-
+
break;
}
}
if (!buffer || !(*size)) {
- warning("couldn't find file '%s'", file);
+ return 0;
}
return buffer;
}
- Palette* Resourcemanager::loadPalette(const char* file) {
+ Palette* Resourcemanager::loadPalette(const char* file) {
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
- if (!buffer)
+ if (!buffer) {
+ warning("ResMgr: Failed loading palette %s", file);
return 0;
+ }
return new Palette(buffer, size);
}
@@ -140,9 +166,12 @@
uint32 size = 0;
uint8* buffer = 0;
buffer = fileData(file, &size);
- if (!buffer)
+ if (!buffer || !size)
return 0;
- return new WSAMovieV1(buffer, size);
+ if (_engine->game() == KYRA1 || _engine->game() == KYRA1CD)
+ return new WSAMovieV1(buffer, size, _engine->game());
+ else
+ return new WSAMovieV2(buffer, size);
}
VMContext* Resourcemanager::loadScript(const char* file) {
@@ -154,13 +183,13 @@
///////////////////////////////////////////
// Pak file manager
#define PAKFile_Iterate Common::List<PakChunk*>::iterator start=_files.begin();start != _files.end(); ++start
- PAKFile::PAKFile(const Common::String& file) {
+ PAKFile::PAKFile(/*const Common::String &path, */const Common::String& file) {
File pakfile;
_buffer = 0;
_open = false;
- if (!pakfile.open(file.c_str())) {
- warning("PAKFile couldn't open: '%s'", file.c_str());
+ if (!pakfile.open(file.c_str())){ /*, File::kFileReadMode, path.c_str())) {*/
+ printf("pakfile couldn't open %s\n", file.c_str());
return;
}
@@ -184,18 +213,25 @@
// saves the name
chunk->_name = reinterpret_cast<const char*>(_buffer + pos);
pos += strlen(chunk->_name) + 1;
- if(!chunk->_name)
+ if(!(*chunk->_name))
break;
endoffset = READ_LE_UINT32(_buffer + pos);
pos += 4;
+
+ if (endoffset == 0) {
+ endoffset = filesize;
+ }
chunk->_data = _buffer + startoffset;
chunk->_size = endoffset - startoffset;
- startoffset = endoffset;
-
_files.push_back(chunk);
+
+ if (endoffset == filesize)
+ break;
+
+ startoffset = endoffset;
}
_open = true;
}
@@ -212,7 +248,7 @@
}
const uint8* PAKFile::getFile(const char* file) {
- for (PAKFile_Iterate) {
+ for (PAKFile_Iterate) {
if (!scumm_stricmp((*start)->_name, file))
return (*start)->_data;
}
Index: resource.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/resource.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- resource.h 10 Nov 2004 18:09:14 -0000 1.3
+++ resource.h 11 Nov 2004 13:35:21 -0000 1.4
@@ -114,7 +114,7 @@
bool hasPalette(void) { return (_ownPalette != 0); }
// if col == -1 then no transparany
- void setTransparencyColor(int16 col) { _transparency = col; }
+ void transparency(int16 col) { _transparency = col; }
void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y);
void drawToPlane(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 x, uint16 y,
Index: script.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- script.cpp 10 Nov 2004 18:45:31 -0000 1.6
+++ script.cpp 11 Nov 2004 13:35:21 -0000 1.7
@@ -25,6 +25,7 @@
#include "resource.h"
#include "common/stream.h"
+#include "common/util.h"
#define COMMAND(x) { &VMContext::x, #x }
#define OPCODE(x) { &VMContext::x, #x }
@@ -54,7 +55,7 @@
// 0x0C
COMMAND(c1_addToSP),
COMMAND(c1_subFromSP),
- COMMAND(c1_execOpcode),
+ COMMAND(c1_execOpcode),
COMMAND(c1_ifNotGoTo),
// 0x10
COMMAND(c1_negate),
@@ -82,7 +83,7 @@
// 0x0C
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x10
COMMAND(o1_unknownOpcode),
@@ -107,7 +108,7 @@
// 0x20
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x24
COMMAND(o1_unknownOpcode),
@@ -132,7 +133,7 @@
// 0x34
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x38
COMMAND(o1_unknownOpcode),
@@ -157,7 +158,7 @@
// 0x48
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x4C
COMMAND(o1_unknownOpcode),
@@ -182,7 +183,7 @@
// 0x5C
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x60
COMMAND(o1_unknownOpcode),
@@ -207,7 +208,7 @@
// 0x70
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x74
COMMAND(o1_unknownOpcode),
@@ -232,7 +233,7 @@
// 0x84
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0x88
COMMAND(o1_unknownOpcode),
@@ -262,7 +263,7 @@
// 0x9C
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0xA0
COMMAND(o1_unknownOpcode),
@@ -287,7 +288,7 @@
// 0xB0
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0xB4
COMMAND(o1_unknownOpcode),
@@ -312,7 +313,7 @@
// 0xC4
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0xC8
COMMAND(o1_unknownOpcode),
@@ -337,7 +338,7 @@
// 0xD8
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0xDC
COMMAND(o1_unknownOpcode),
@@ -362,7 +363,7 @@
// 0xEC
COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
- COMMAND(o1_unknownOpcode),
+ COMMAND(o1_unknownOpcode),
COMMAND(o1_unknownOpcode),
// 0xF0
COMMAND(o1_unknownOpcode),
@@ -398,8 +399,8 @@
_scriptFileSize = 0;
}
- debug("--------------");
-
+ memset(_stack, 0, sizeof(int32) * ARRAYSIZE(_stack));
+
// loads the new file
_scriptFile = _engine->resManager()->fileData(file, &_scriptFileSize);
@@ -415,32 +416,27 @@
while(true) {
if (script.eof()) {
break;
- }
+ }
// lets read only the first 4 chars
script.read(chunkName, sizeof(uint8) * 4);
chunkName[4] = '\0';
- debug("chunk name(4 chars): '%s'", chunkName);
-
+
// check name of chunk
if (!scumm_stricmp((const char *)chunkName, "FORM")) {
// FreeKyra swaps the size I only read it in BigEndian :)
_chunks[kForm]._size = script.readUint32BE();
- debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);
+ debug("_chunks[kForm]._size = %d", _chunks[kForm]._size);
} else if (!scumm_stricmp((const char *)chunkName, "TEXT")) {
uint32 text_size = script.readUint32BE();
text_size += text_size % 2 != 0 ? 1 : 0;
_chunks[kText]._data = _scriptFile + script.pos();
_chunks[kText]._size = READ_BE_UINT16(_chunks[kText]._data) >> 1;
- _chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);
- debug("_chunks[kText]._size = %d, real chunk size = %d", _chunks[kText]._size, text_size);
-
+ _chunks[kText]._additional = _chunks[kText]._data + (_chunks[kText]._size << 1);
script.seek(script.pos() + text_size);
} else if (!scumm_stricmp((const char *)chunkName, "DATA")) {
_chunks[kData]._size = script.readUint32BE();
- _chunks[kData]._data = _scriptFile + script.pos();
- debug("_chunks[kData]._size = %d", _chunks[kData]._size);
-
+ _chunks[kData]._data = _scriptFile + script.pos();
// mostly it will be the end of the file because all files should end with a 'DATA' chunk
script.seek(script.pos() + _chunks[kData]._size);
} else {
@@ -451,25 +447,20 @@
if (!scumm_stricmp((const char *)chunkName, "EMC2ORDR")) {
_chunks[kEmc2Ordr]._size = script.readUint32BE() >> 1;
- _chunks[kEmc2Ordr]._data = _scriptFile + script.pos();
- debug("_chunks[kEmc2Ordr]._size = %d, real chunk size = %d", _chunks[kEmc2Ordr]._size, _chunks[kEmc2Ordr]._size * 2);
-
+ _chunks[kEmc2Ordr]._data = _scriptFile + script.pos();
script.seek(script.pos() + _chunks[kEmc2Ordr]._size * 2);
} else {
// any unkown chunk or problems with seeking through the file
- error("unknown chunk");
+ error("unknown chunk(%s)", chunkName);
}
}
}
-
- // so file loaded
- debug("--------------");
}
int32 VMContext::param(int32 index) {
- if (_stackPos - index + 1 >= 16 || _stackPos - index + 1 < 0)
+ if (_stackPos - index - 1 >= ARRAYSIZE(_stack) || _stackPos - index - 1 < 0)
return -0xFFFF;
- return _stack[_stackPos - index + 1];
+ return _stack[_stackPos - index - 1];
}
const char* VMContext::stringAtIndex(int32 index) {
@@ -485,11 +476,28 @@
return false;
}
- _instructionPos = (READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1) + 2;
+ _instructionPos = READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[func]) << 1;
_stackPos = 0;
_tempPos = 0;
_delay = 0;
_scriptState = kScriptRunning;
+
+ uint32 pos = 0xFFFFFFFE;
+
+ // get start of next script
+ for (uint32 tmp = 0; tmp < _chunks[kEmc2Ordr]._size; ++tmp) {
+ if ((uint32)((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1)) > (uint32)_instructionPos &&
+ (uint32)((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1)) < pos) {
+ pos = ((READ_BE_UINT16(&_chunks[kEmc2Ordr]._data[tmp]) << 1));
+ }
+ }
+
+ if (pos > _scriptFileSize) {
+ pos = _scriptFileSize;
+ }
+
+ _nextScriptPos = pos;
+
return true;
}
@@ -505,6 +513,9 @@
debug("_instructionPos( = %d) > _chunks[kData]._size( = %d)", _instructionPos, _chunks[kData]._size);
_error = true;
break;
+ } else if(_instructionPos >= _nextScriptPos) {
+ _scriptState = kScriptStopped;
+ break;
}
_currentCommand = *(script_start + _instructionPos++);
@@ -525,9 +536,12 @@
_instructionPos += 2;
} else {
debug("unknown way of getting the command");
+ // next thing
+ continue;
}
_currentCommand &= 0x1f;
+
if (_currentCommand < _numCommands) {
CommandProc currentProc = _commands[_currentCommand].proc;
(this->*currentProc)();
Index: script.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- script.h 10 Nov 2004 18:45:31 -0000 1.2
+++ script.h 11 Nov 2004 13:35:21 -0000 1.3
@@ -71,14 +71,15 @@
uint32 _delay;
int32 _registers[32]; // registers of the interpreter
- int32 _stack[32]; // our stack
+ int32 _stack[64]; // our stack
// TODO: check for 'under'flow
- int32 popStack(void) { return _stack[_stackPos--]; }
+ int32 popStack(void) { return _stack[--_stackPos]; }
int32& topStack(void) { return _stack[_stackPos]; }
uint32 _returnValue;
+ int32 _nextScriptPos;
int32 _instructionPos;
int32 _stackPos;
int32 _tempPos;
@@ -131,7 +132,7 @@
void c1_goToLine(void); // 0x00
void c1_setReturn(void); // 0x01
void c1_pushRetRec(void); // 0x02
- void c1_push(void); // 0x03 & 0x04
+ void c1_push(void); // 0x03 & 0x04
void c1_pushVar(void); // 0x05
void c1_pushFrameNeg(void); // 0x06
void c1_pushFramePos(void); // 0x07
@@ -148,7 +149,7 @@
void c1_unknownCommand(void);
// the opcode procs
- void o1_0x68(void); // 0x68
+ void o1_0x68(void); // 0x68
void o1_unknownOpcode(void);
};
} // end of namespace Kyra
Index: script_v1.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/script_v1.cpp,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- script_v1.cpp 10 Nov 2004 18:45:32 -0000 1.4
+++ script_v1.cpp 11 Nov 2004 13:35:21 -0000 1.5
@@ -237,6 +237,7 @@
}
void VMContext::o1_0x68(void) {
- debug("o1_0x68 was called with param0: '%d' and param1: '%d'", param(0), param(1));
+ debug("o1_0x68 was called with param0: '%d'", param(0));
+ _error = true;
}
} // end of namespace Kyra
Index: wsamovie.cpp
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/wsamovie.cpp,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- wsamovie.cpp 15 Oct 2004 19:48:07 -0000 1.2
+++ wsamovie.cpp 11 Nov 2004 13:35:21 -0000 1.3
@@ -18,25 +18,67 @@
* $Header$
*
*/
-
+
#include "stdafx.h"
#include "wsamovie.h"
#include "codecs.h"
#include "common/stream.h"
+#ifdef DUMP_FILES
+#include <stdio.h>
+#endif
+
namespace Kyra {
- WSAMovieV1::WSAMovieV1(uint8* data, uint32 size) {
+ WSAMovieV1::WSAMovieV1(uint8* data, uint32 size, uint8 gameid) {
if (!data) {
error("resource created without data");
}
+ _background = 0;
+ _currentFrame = 0;
+ _ownPalette = 0;
+ _offsetTable = 0;
+ _prefetchedFrame = 0xFFFE;
_buffer = data;
// I like these Streams .... =)
Common::MemoryReadStream datastream(data, size);
datastream.read(&_wsaHeader, sizeof(_wsaHeader));
+
+#ifdef DUMP_FILES
+ FILE* wsaheader = fopen("dumps/wsaheader.txt", "w+");
+
+ if (wsaheader) {
+ for (uint32 pos = 0; pos < sizeof(_wsaHeader); ++pos)
+ fprintf(wsaheader, "%d pos. byte: %d\n", pos + 1, ((uint8*)&_wsaHeader)[pos]);
+ fprintf(wsaheader, "\n");
+ for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 2; ++pos)
+ fprintf(wsaheader, "%d pos. word: %d\n", pos + 1, ((uint16*)&_wsaHeader)[pos]);
+ fprintf(wsaheader, "\n");
+ for (uint32 pos = 0; pos < sizeof(_wsaHeader) / 4; ++pos)
+ fprintf(wsaheader, "%d pos. dword: %d\n", pos + 1, ((uint32*)&_wsaHeader)[pos]);
+ }
+ fclose(wsaheader);
+#endif
+
+ if (gameid == KYRA1CD) {
+ uint16 tmp = _wsaHeader._delta;
+ _wsaHeader._delta = _wsaHeader._type;
+ _wsaHeader._type = tmp;
+
+ // skip 2 bytes
+ datastream.readUint16LE();
+ }
+
+ debug("_wsaHeader._numFrames = %d", _wsaHeader._numFrames);
+ debug("_wsaHeader._width = %d", _wsaHeader._width);
+ debug("_wsaHeader._height = %d", _wsaHeader._height);
+ debug("_wsaHeader._xPos = %d", _wsaHeader._xPos);
+ debug("_wsaHeader._yPos = %d", _wsaHeader._yPos);
+ debug("_wsaHeader._delta = %d", _wsaHeader._delta);
+ debug("_wsaHeader._type = %d", _wsaHeader._type);
// check for version
if (_wsaHeader._type) {
@@ -55,27 +97,34 @@
offsetAdd = 768 /* 0x300 */;
}
- _frameCount = _wsaHeader._numFrames;
+ // last frame seems every time to be a empty one
+ _frameCount = _wsaHeader._numFrames - 1;
_offsetTable = new uint32[_wsaHeader._numFrames + 2];
- assert(!_offsetTable);
+ assert(_offsetTable);
// loads the offset table
- for (uint32 tmp = 0; tmp < _wsaHeader._numFrames; ++tmp) {
+ for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) {
_offsetTable[tmp] = datastream.readUint32LE() + offsetAdd;
}
if (offsetAdd) {
uint8* palbuffer = new uint8[offsetAdd];
- assert(!palbuffer);
+ assert(palbuffer);
+
+ datastream.read(palbuffer, offsetAdd);
_ownPalette = new Palette(palbuffer, offsetAdd);
- assert(!_ownPalette);
- }
+ assert(_ownPalette);
+ }
+
+ // FIXME: Confirm the default value here?
+ _transparency = -1;
}
WSAMovieV1::~WSAMovieV1() {
delete [] _buffer;
delete [] _offsetTable;
+ delete [] _currentFrame;
delete _ownPalette;
}
@@ -89,21 +138,215 @@
if (!_currentFrame) {
_currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
assert(_currentFrame);
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
}
+ if (frame >= _wsaHeader._numFrames)
+ return 0;
+
uint8* frameData = 0;
- uint8 image40[64000]; // I think this will crash on Plam OS :)
+ static uint8 image40[64000]; // I think this will crash on Plam OS :)
+ memset(image40, 0, ARRAYSIZE(image40));
if (frame == _prefetchedFrame + 1) {
- frameData = _buffer + _offsetTable[frame] + (hasPalette() ? 768 : 0);
+ frameData = _buffer + _offsetTable[frame];
Compression::decode80(frameData, image40);
Compression::decode40(image40, _currentFrame);
} else {
- memset(_currentFrame, 0, _wsaHeader._width * _wsaHeader._height);
+ if (_background) {
+ setImageBackground(_background, _backWidth, _backHeight);
+ } else {
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+ }
+
+ for (uint32 i = 0; i <= frame; ++i)
+ {
+ frameData = _buffer + _offsetTable[i];
+ Compression::decode80(frameData, image40);
+ Compression::decode40(image40, _currentFrame);
+ }
+ }
+
+ _prefetchedFrame = frame;
+ return _currentFrame;
+ }
+
+ return 0;
+ }
+
+ void WSAMovieV1::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) {
+ if (!loadFrame(frame, 0, 0))
+ return;
+
+ uint8* src = _currentFrame;
+ uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+ uint32 copysize = planepitch - _wsaHeader._xPos;
+
+ if (copysize > _wsaHeader._width)
+ copysize = _wsaHeader._width;
+
+ if (_transparency == -1) {
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) {
+ memcpy(dst, src, copysize * sizeof(uint8));
+ dst += planepitch;
+ src += _wsaHeader._width;
+ }
+ } else {
+ for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) {
+ for (uint16 xadd = 0; xadd < copysize; ++xadd) {
+ if (*src == _transparency) {
+ ++dst;
+ ++src;
+ } else {
+ *dst++ = *src++;
+ }
+ }
- for (uint32 i = 0; i <= frame; i++)
+ src += _wsaHeader._width - copysize;
+ dst += planepitch - copysize;
+ }
+ }
+ }
+
+ void WSAMovieV1::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {
+ assert(plane);
+
+ _background = plane;
+ _backWidth = planepitch; _backHeight = height;
+
+ if (!_currentFrame) {
+ _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+ assert(_currentFrame);
+ }
+
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+
+ uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+ uint8* dst = _currentFrame;
+ uint32 copysize = planepitch - _wsaHeader._xPos;
+
+ if (copysize > _wsaHeader._width)
+ copysize = _wsaHeader._width;
+
+ // now copy the rect of the plane
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+ memcpy(dst, src, copysize * sizeof(uint8));
+ dst += _wsaHeader._width;
+ src += planepitch;
+ }
+
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+ for (uint16 x = 0; x < _wsaHeader._width; ++x) {
+ _currentFrame[y_ * _wsaHeader._width + x] ^= 0;
+ }
+ }
+
+ _prefetchedFrame = 0xFFFE;
+ }
+
+ // Kyrandia 2+ Movies
+ WSAMovieV2::WSAMovieV2(uint8* data, uint32 size) {
+ if (!data) {
+ error("resource created without data");
+ }
+
+ _background = 0;
+ _currentFrame = 0;
+ _ownPalette = 0;
+ _offsetTable = 0;
+ _prefetchedFrame = 0xFFFE;
+ _looping = false;
+ _buffer = data;
+
+ // I like these Streams .... =)
+ Common::MemoryReadStream datastream(data, size);
+
+ datastream.read(&_wsaHeader, sizeof(_wsaHeader));
+
+ // check for version
+ if (!_wsaHeader._type) {
+ error("loading a WSA version 1 with the WSA version 2 loader");
+ }
+
+ uint16 offsetAdd = 0;
+
+ // checks now for own palette
+ if (_wsaHeader._type % 2) {
+ // don't now if this will work right, because a few lines before we use
+ // _wsaHeader._type for detect the version of the WSA movie,
+ // but this code was from FreeKyra Tools so I think it will work
+
+ // if this is a packed palette we have a problem :)
+ offsetAdd = 768 /* 0x300 */;
+ }
+
+ _offsetTable = new uint32[_wsaHeader._numFrames + 2];
+ assert(_offsetTable);
+
+ // loads the offset table
+ for (uint32 tmp = 0; tmp < (uint32)_wsaHeader._numFrames + 2; ++tmp) {
+ _offsetTable[tmp] = datastream.readUint32LE() + offsetAdd;
+ }
+
+ if (offsetAdd) {
+ uint8* palbuffer = new uint8[offsetAdd];
+ assert(palbuffer);
+
+ datastream.read(palbuffer, offsetAdd);
+
+ _ownPalette = new Palette(palbuffer, offsetAdd);
+ assert(_ownPalette);
+ }
+
+ if (_offsetTable[_wsaHeader._numFrames + 1] - offsetAdd) {
+ ++_wsaHeader._numFrames;
+ _looping = true;
+ }
+
+ _frameCount = _wsaHeader._numFrames;
+ }
+
+ WSAMovieV2::~WSAMovieV2() {
+ delete [] _buffer;
+ delete [] _offsetTable;
+ delete [] _currentFrame;
+ delete _ownPalette;
+ }
+
+ const uint8* WSAMovieV2::loadFrame(uint16 frame, uint16* width, uint16* height) {
+ if (width) *width = _wsaHeader._width;
+ if (height) *height = _wsaHeader._height;
+
+ if (frame == _prefetchedFrame) {
+ return _currentFrame;
+ } else {
+ if (!_currentFrame) {
+ _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+ assert(_currentFrame);
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+ }
+
+ if (frame >= _wsaHeader._numFrames)
+ return 0;
+
+ uint8* frameData = 0;
+ static uint8 image40[64000]; // I think this will crash on Plam OS :)
+ memset(image40, 0, ARRAYSIZE(image40));
+
+ if (frame == _prefetchedFrame + 1) {
+ frameData = _buffer + _offsetTable[frame];
+ Compression::decode80(frameData, image40);
+ Compression::decode40(image40, _currentFrame);
+ } else {
+ if (_background) {
+ setImageBackground(_background, _backWidth, _backHeight);
+ } else {
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+ }
+
+ for (uint32 i = 0; i <= frame; ++i)
{
- frameData = _buffer + _offsetTable[i] + (hasPalette() ? 768 : 0);
+ frameData = _buffer + _offsetTable[i];
Compression::decode80(frameData, image40);
Compression::decode40(image40, _currentFrame);
}
@@ -115,5 +358,75 @@
return 0;
}
+
+ void WSAMovieV2::renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) {
+ if (!loadFrame(frame, 0, 0))
+ return;
+
+ uint8* src = _currentFrame;
+ uint8* dst = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+ uint32 copysize = planepitch - _wsaHeader._xPos;
+
+ if (copysize > _wsaHeader._width)
+ copysize = _wsaHeader._width;
+
+ if (_transparency == -1) {
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < planeheight; ++y_) {
+ memcpy(dst, src, copysize * sizeof(uint8));
+ dst += planepitch;
+ src += _wsaHeader._width;
+ }
+ } else {
+ for (uint16 yadd = 0; yadd < _wsaHeader._height; ++yadd) {
+ for (uint16 xadd = 0; xadd < copysize; ++xadd) {
+ if (*src == _transparency) {
+ ++dst;
+ ++src;
+ } else {
+ *dst++ = *src++;
+ }
+ }
+
+ src += _wsaHeader._width - copysize;
+ dst += planepitch - copysize;
+ }
+ }
+ }
+
+ void WSAMovieV2::setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {
+ assert(plane);
+
+ _background = plane;
+ _backWidth = planepitch; _backHeight = height;
+
+ if (!_currentFrame) {
+ _currentFrame = new uint8[_wsaHeader._width * _wsaHeader._height];
+ assert(_currentFrame);
+ }
+
+ memset(_currentFrame, 0, sizeof(uint8) * _wsaHeader._width * _wsaHeader._height);
+
+ uint8* src = &plane[_wsaHeader._yPos * planepitch + _wsaHeader._xPos];
+ uint8* dst = _currentFrame;
+ uint32 copysize = planepitch - _wsaHeader._xPos;
+
+ if (copysize > _wsaHeader._width)
+ copysize = _wsaHeader._width;
+
+ // now copy the rect of the plane
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+ memcpy(dst, src, copysize * sizeof(uint8));
+ dst += _wsaHeader._width;
+ src += planepitch;
+ }
+
+ for (uint16 y_ = 0; y_ < _wsaHeader._height && _wsaHeader._yPos + y_ < height; ++y_) {
+ for (uint16 x = 0; x < _wsaHeader._width; ++x) {
+ _currentFrame[y_ * _wsaHeader._width + x] ^= 0;
+ }
+ }
+
+ _prefetchedFrame = 0xFFFE;
+ }
} // end of namespace Kyra
Index: wsamovie.h
===================================================================
RCS file: /cvsroot/scummvm/scummvm/kyra/wsamovie.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- wsamovie.h 15 Oct 2004 06:06:47 -0000 1.1
+++ wsamovie.h 11 Nov 2004 13:35:21 -0000 1.2
@@ -31,30 +31,42 @@
public:
- virtual ~Movie() {}
+ virtual ~Movie() { _transparency = -1; _ownPalette = 0; _frameCount = 0; }
+ virtual void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame) = 0;
virtual const uint8* loadFrame(uint16 frame, uint16* width = 0, uint16* height = 0) = 0;
virtual uint16 countFrames(void) { return _frameCount; }
+ // could be deleted(not imdiantly maybe it's needed sometime)
+ virtual void transparency(int16 color) { _transparency = color; }
+ virtual void position(uint16 x, uint16 y) = 0;
+
virtual bool hasPalette(void) { return (_ownPalette != 0); }
virtual Palette* palette(void) { return _ownPalette; }
+
+ virtual bool looping(void) { return false; }
+ virtual uint32 frameChange(void) { return 100; }
+ virtual void setImageBackground(uint8* plane, uint16 planepitch, uint16 height) {};
protected:
+ int16 _transparency;
uint16 _frameCount;
Palette* _ownPalette;
};
// movie format for Kyrandia 1
- // there is also a new WSA Format for Kyrandia 2
- // which i will implement in future
class WSAMovieV1 : public Movie {
public:
- WSAMovieV1(uint8* data, uint32 size);
+ WSAMovieV1(uint8* data, uint32 size, uint8 gameid);
~WSAMovieV1();
+ void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame);
const uint8* loadFrame(uint16 frame, uint16* width, uint16* height);
+ void setImageBackground(uint8* plane, uint16 planepitch, uint16 height);
+
+ void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; }
protected:
uint8* _buffer;
@@ -62,19 +74,60 @@
#pragma START_PACK_STRUCTS
struct WSAHeader {
uint16 _numFrames; // All right
+ uint16 _width; // All right
+ uint16 _height; // All right
+ uint8 _xPos; // is wrong
+ uint8 _yPos; // is wrong
+ uint16 _delta; // should be right
+ uint16 _type; // should be right
+ } GCC_PACK _wsaHeader;
+#pragma END_PACK_STRUCTS
+
+ uint32* _offsetTable;
+
+ uint8* _currentFrame;
+ uint16 _prefetchedFrame;
+
+ uint8* _background; // only a pointer to the screen
+ uint16 _backWidth, _backHeight;
+ };
+
+ // movie format for Kyrandia 2+
+ class WSAMovieV2 : public Movie {
+
+ public:
+ WSAMovieV2(uint8* data, uint32 size);
+ ~WSAMovieV2();
+
+ void renderFrame(uint8* plane, uint16 planepitch, uint16 planeheight, uint16 frame);
+ const uint8* loadFrame(uint16 frame, uint16* width, uint16* height);
+ void setImageBackground(uint8* plane, uint16 planepitch, uint16 height);
+
+ void position(uint16 x, uint16 y) { _wsaHeader._xPos = x; _wsaHeader._yPos = y; }
+ bool looping(void) { return _looping; }
+ protected:
+
+ uint8* _buffer;
+
+ struct WSAHeader {
+ uint16 _numFrames; // All right
uint16 _width; // should be right
uint16 _height; // should be right
- uint8 _xPos; // could be wrong
- uint8 _yPos; // could be wrong
+ uint16 _xPos; // could be wrong
+ uint16 _yPos; // could be wrong
uint16 _delta; // could be wrong
uint16 _type; // should be right
} GCC_PACK _wsaHeader;
-#pragma END_PACK_STRUCTS
-
+
uint32* _offsetTable;
uint8* _currentFrame;
uint16 _prefetchedFrame;
+
+ uint8* _background; // only a pointer to the screen
+ uint16 _backWidth, _backHeight;
+
+ bool _looping;
};
} // end of namespace Kyra
More information about the Scummvm-git-logs
mailing list