Ticket #8865: rtz_saturn_updated.diff

File rtz_saturn_updated.diff, 19.1 KB (added by SF/mthreepwood, 16 years ago)

Updated Patch

  • common/util.cpp

     
    288288        {"macintosh", "mac", "mac", "Macintosh", kPlatformMacintosh},
    289289        {"pce", "pce", "pce", "PC-Engine", kPlatformPCEngine },
    290290        {"nes", "nes", "nes", "NES", kPlatformNES},
     291        {"saturn", "saturn", "saturn", "Sega Saturn", kPlatformSaturn},
    291292        {"segacd", "segacd", "sega", "SegaCD", kPlatformSegaCD},
    292293        {"windows", "win", "win", "Windows", kPlatformWindows},
    293294
  • common/util.h

     
    207207        kPlatformSegaCD,
    208208        kPlatform3DO,
    209209        kPlatformPCEngine,
    210 
    211210        kPlatformApple2GS,
    212211        kPlatformPC98,
     212        kPlatformSaturn,
    213213
    214214        kPlatformUnknown = -1
    215215};
  • engines/made/cpkplayer.cpp

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#include "common/scummsys.h"
     27#include "common/endian.h"
     28 
     29#include "made/cpkplayer.h"
     30#include "made/screen.h"
     31
     32#include "sound/adpcm.h"
     33
     34namespace Made {
     35
     36CpkPlayer::CpkPlayer(MadeEngine *vm, Audio::Mixer *mixer) : _fd(NULL), _vm(vm), _mixer(mixer) {
     37}
     38
     39CpkPlayer::~CpkPlayer() {
     40}
     41
     42struct SampleTableEntry {
     43        uint32 offset;
     44        uint32 length;
     45        uint32 sampleInfo1;
     46        uint32 sampleInfo2;
     47};
     48
     49void CpkPlayer::play(const char *filename) {
     50
     51        // Note: Most of this code is based off the document from http://wiki.multimedia.cx/index.php?title=Sega_FILM
     52
     53        _abort = false;
     54        _surface = new Graphics::Surface();
     55
     56        _fd = new Common::File();
     57        _fd->open(filename);
     58
     59        // FILM Chunk
     60        assert(_fd->readUint32BE() == MKID_BE('FILM'));
     61        uint32 filmHeaderLength = _fd->readUint32BE();
     62        uint32 filmVersion = _fd->readUint32BE();
     63        _fd->readUint32BE(); // Reserved???
     64       
     65        // FDSC Chunk
     66        assert(_fd->readUint32BE() == MKID_BE('FDSC'));
     67        uint32 fdscChunkSize = _fd->readUint32BE();
     68        uint32 videoCodec = _fd->readUint32BE();
     69        uint32 height = _fd->readUint32BE();
     70        uint32 width = _fd->readUint32BE();
     71        _fd->readByte(); // Unknown
     72        byte audioChannels = _fd->readByte();
     73        byte audioSamplingBits = _fd->readByte();
     74        _fd->readByte(); // Unknown
     75        uint16 audioFrequency = _fd->readUint16BE();
     76       
     77        // STAB Chunk
     78        assert(_fd->readUint32BE() == MKID_BE('STAB'));
     79        uint32 stabChunkSize = _fd->readUint32BE();
     80        uint32 frameRateBaseFreq = _fd->readUint32BE();
     81        uint32 sampleTableEntryCount = _fd->readUint32BE();
     82        SampleTableEntry *sampleTableEntries = new SampleTableEntry[sampleTableEntryCount];
     83        for (uint32 i = 0; i < sampleTableEntryCount; i++) {
     84                sampleTableEntries[i].offset = _fd->readUint32BE();
     85                sampleTableEntries[i].length = _fd->readUint32BE();
     86                sampleTableEntries[i].sampleInfo1 = _fd->readUint32BE();
     87                sampleTableEntries[i].sampleInfo2 = _fd->readUint32BE();
     88        }
     89       
     90        // Where's the actual frame rate? There is none! It's variable and can differ between frames.
     91
     92        _mixer->stopAll();
     93
     94        byte audioFlags = 0;
     95        if (audioChannels == 2)
     96                audioFlags |= Audio::Mixer::FLAG_STEREO;
     97        if (audioSamplingBits == 16)
     98                audioFlags |= Audio::Mixer::FLAG_16BITS;
     99       
     100        _audioStream = Audio::makeAppendableAudioStream(audioFrequency, audioFlags);
     101       
     102       
     103        // Uh-oh.... is it 8bpp???
     104        _surface->create(width, height, 1);
     105
     106        for (uint32 i = 0; i < sampleTableEntryCount && !_abort && !_fd->eof(); i++) {
     107                _fd->seek(sampleTableEntries[i].offset + filmHeaderLength);
     108               
     109                // Audio Data
     110                if (sampleTableEntries[i].sampleInfo1 == (uint32)~0) {
     111                        Common::SeekableSubReadStream *soundData = new Common::SeekableSubReadStream(_fd, 0, sampleTableEntries[i].length);
     112                        Audio::AudioStream *adpcmStream = Audio::makeADPCMStream(soundData, false, 0, Audio::kADPCMMS, audioFrequency, audioChannels, 0);
     113                        // TODO: L R L R L R L R
     114                        // The Sound data alternates left/right
     115                } else {
     116                // Video Data
     117                        // TODO: Cinepak for SEGA
     118                }
     119
     120                handleEvents();
     121                updateScreen();
     122        }
     123
     124        _audioStream->finish();
     125        _mixer->stopHandle(_audioStreamHandle);
     126       
     127        //delete _audioStream;
     128        delete _fd;
     129        delete _surface;
     130
     131}
     132
     133void CpkPlayer::handleEvents() {
     134        Common::Event event;
     135        while (_vm->_system->getEventManager()->pollEvent(event)) {
     136                switch (event.type) {
     137                case Common::EVENT_KEYDOWN:
     138                        if (event.kbd.keycode == Common::KEYCODE_ESCAPE)
     139                                _abort = true;
     140                        break;
     141                case Common::EVENT_QUIT:
     142                        _vm->_quit = true;
     143                        _abort = true;
     144                        break;
     145                default:
     146                        break;
     147                }
     148        }
     149}
     150
     151void CpkPlayer::updateScreen() {
     152        _vm->_system->copyRectToScreen((const byte*)_surface->pixels, _surface->pitch,
     153                                                                        (320 - _surface->w) / 2, (200 - _surface->h) / 2, _surface->w, _surface->h);
     154        _vm->_system->updateScreen();
     155}
     156
     157}
  • engines/made/cpkplayer.h

     
     1/* ScummVM - Graphic Adventure Engine
     2 *
     3 * ScummVM is the legal property of its developers, whose names
     4 * are too numerous to list here. Please refer to the COPYRIGHT
     5 * file distributed with this source distribution.
     6 *
     7 * This program is free software; you can redistribute it and/or
     8 * modify it under the terms of the GNU General Public License
     9 * as published by the Free Software Foundation; either version 2
     10 * of the License, or (at your option) any later version.
     11
     12 * This program is distributed in the hope that it will be useful,
     13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15 * GNU General Public License for more details.
     16
     17 * You should have received a copy of the GNU General Public License
     18 * along with this program; if not, write to the Free Software
     19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
     20 *
     21 * $URL$
     22 * $Id$
     23 *
     24 */
     25
     26#ifndef MADE_CPKPLAYER_H
     27#define MADE_CPKPLAYER_H
     28
     29#include "common/system.h"
     30#include "common/events.h"
     31#include "common/file.h"
     32#include "common/endian.h"
     33#include "graphics/surface.h"
     34#include "sound/mixer.h"
     35#include "sound/audiostream.h"
     36
     37#include "made/graphics.h"
     38#include "made/sound.h"
     39#include "made/made.h"
     40
     41namespace Made {
     42
     43class MadeEngine;
     44
     45class CpkPlayer {
     46public:
     47        CpkPlayer(MadeEngine *vm, Audio::Mixer *mixer);
     48        ~CpkPlayer();
     49        void play(const char *filename);
     50protected:
     51        MadeEngine *_vm;
     52        Audio::Mixer *_mixer;
     53        Common::File *_fd;
     54        Audio::AppendableAudioStream *_audioStream;
     55        Audio::SoundHandle _audioStreamHandle;
     56        Graphics::Surface *_surface;
     57        bool _abort;
     58        void handleEvents();
     59        void updateScreen();
     60};
     61
     62}
     63
     64#endif
  • engines/made/database.cpp

     
    3939        < 0x7FFE  object
    4040*/
    4141
    42 Object::Object() : _objData(NULL), _freeData(false) {
     42Object::Object(bool bigEndian) : _objData(NULL), _freeData(false), _bigEndian(bigEndian) {
    4343}
    4444
    4545Object::~Object() {
     
    4747                delete[] _objData;
    4848}
    4949
    50 int Object::loadVersion2(Common::SeekableReadStream &source) {
    51 
     50int Object::loadVersion2(Common::SeekableReadStream &source) { 
    5251        if (_freeData && _objData)
    5352                delete[] _objData;
    5453
     
    102101        return _objSize;
    103102}
    104103
     104int Object::loadVersionSegaSaturn(Common::SeekableReadStream &source) {
     105        _freeData = true;
     106        source.readUint16BE(); // skip flags
     107        uint16 type = source.readUint16BE();
     108        if (type == 0x7FFF) {
     109                _objSize = source.readUint16BE();
     110        } else if (type == 0x7FFE) {
     111                _objSize = source.readUint16BE() * 2;
     112        } else if (type < 0x7FFE) {
     113                byte count1 = source.readByte();
     114                byte count2 = source.readByte();
     115                _objSize = (count1 + count2) * 2;
     116        }
     117        source.seek(-6, SEEK_CUR);
     118        _objSize += 6;
     119        _objData = new byte[_objSize];
     120        source.read(_objData, _objSize);
     121        return _objSize;
     122}
     123
    105124int Object::loadVersion3(byte *source) {
    106125        _objData = source;
    107126        _freeData = false;
     
    115134}
    116135
    117136uint16 Object::getFlags() const {
     137        if (_bigEndian)
     138                return READ_BE_UINT16(_objData);
    118139        return READ_LE_UINT16(_objData);
    119140}
    120141
    121142uint16 Object::getClass() const {
     143        if (_bigEndian)
     144                return READ_BE_UINT16(_objData + 2);
    122145        return READ_LE_UINT16(_objData + 2);
    123146}
    124147
    125148uint16 Object::getSize() const {
     149        if (_bigEndian)
     150                return READ_BE_UINT16(_objData + 4);
    126151        return READ_LE_UINT16(_objData + 4);
    127152}
    128153
     
    181206                return vector[index];
    182207        } else if (getClass() == 0x7FFE) {
    183208                int16 *vector = (int16*)getData();
     209                if (_bigEndian)
     210                        return READ_BE_UINT16(&vector[index]);
    184211                return READ_LE_UINT16(&vector[index]);
    185212        } else if (getClass() < 0x7FFE) {
    186213                int16 *vector = (int16*)getData();
     214                if (_bigEndian)
     215                        return READ_BE_UINT16(&vector[index]);
    187216                return READ_LE_UINT16(&vector[index]);
    188217        } else {
    189218                // should never reach here
     
    198227                vector[index] = value;
    199228        } else if (getClass() <= 0x7FFE) {
    200229                int16 *vector = (int16*)getData();
    201                 WRITE_LE_UINT16(&vector[index], value);
     230                if (_bigEndian)
     231                        WRITE_BE_UINT16(&vector[index], value);
     232                else
     233                        WRITE_LE_UINT16(&vector[index], value);
    202234        }
    203235}
    204236
     
    245277                debug(2, "loading version 2 dat");
    246278                loadVersion2(sourceS);
    247279        } else if (_vm->getGameID() == GID_RTZ) {
    248                 debug(2, "loading version 3 dat");
    249                 loadVersion3(sourceS);
     280                if (_vm->getPlatform() == Common::kPlatformSaturn) {
     281                        debug(2, "loading Sega Saturn dat");
     282                        loadVersionSegaSaturn(sourceS);
     283                } else {
     284                        debug(2, "loading version 3 dat");
     285                        loadVersion3(sourceS);
     286                }
    250287        }
    251288
    252289}
     
    341378
    342379}
    343380
     381void GameDatabase::loadVersionSegaSaturn(Common::SeekableReadStream &sourceS) {
     382
     383        // TODO: Read/verifiy header
     384
     385        sourceS.seek(0x1E);
     386
     387        uint32 objectIndexOffs = sourceS.readUint32BE();
     388        uint16 objectCount = sourceS.readUint16BE();
     389        uint32 gameStateOffs = sourceS.readUint32BE();
     390        _gameStateSize = sourceS.readUint32BE();
     391        uint32 objectsOffs = sourceS.readUint32BE();
     392        uint32 objectsSize = sourceS.readUint32BE();
     393        _mainCodeObjectIndex = sourceS.readUint16BE();
     394
     395        debug(2, "objectIndexOffs = %08X; objectCount = %d; gameStateOffs = %08X; gameStateSize = %d; objectsOffs = %08X; objectsSize = %d\n", objectIndexOffs, objectCount, gameStateOffs, _gameStateSize, objectsOffs, objectsSize);
     396
     397        _gameState = new byte[_gameStateSize];
     398        sourceS.seek(gameStateOffs);
     399        sourceS.read(_gameState, _gameStateSize);
     400
     401        Common::Array<uint32> objectOffsets;
     402        sourceS.seek(objectIndexOffs);
     403        for (uint32 i = 0; i < objectCount; i++)
     404                objectOffsets.push_back(sourceS.readUint32BE());
     405
     406        for (uint32 i = 0; i < objectCount; i++) {
     407                Object *obj = new Object(true);
     408
     409                // The LSB indicates if it's a constant or variable object.
     410                // Constant objects are loaded from disk, while variable objects exist
     411                // in the _gameState buffer.
     412
     413                debug(3, "obj(%04X) ofs = %08X\n", i, objectOffsets[i]);
     414
     415                if (objectOffsets[i] & 1) {
     416                        debug(3, "-> const %08X\n", objectsOffs + objectOffsets[i] - 1);
     417                        sourceS.seek(objectsOffs + objectOffsets[i] - 1);
     418                        obj->loadVersionSegaSaturn(sourceS);
     419                } else {
     420                        debug(3, "-> var\n");
     421                        obj->loadVersion3(_gameState + objectOffsets[i]);
     422                }
     423                _objects.push_back(obj);
     424        }
     425
     426}
     427
    344428bool GameDatabase::getSavegameDescription(const char *filename, Common::String &description) {
    345429
    346430        Common::InSaveFile *in;
     
    456540}
    457541
    458542int16 GameDatabase::getVar(int16 index) {
     543        if (_vm->getPlatform() == Common::kPlatformSaturn)
     544                return (int16)READ_BE_UINT16(_gameState + index * 2);
    459545        return (int16)READ_LE_UINT16(_gameState + index * 2);
    460546}
    461547
    462548void GameDatabase::setVar(int16 index, int16 value) {
    463         WRITE_LE_UINT16(_gameState + index * 2, value);
     549        if (_vm->getPlatform() == Common::kPlatformSaturn)
     550                WRITE_BE_UINT16(_gameState + index * 2, value);
     551        else
     552                WRITE_LE_UINT16(_gameState + index * 2, value);
    464553}
    465554
    466555int16 *GameDatabase::getObjectPropertyPtrV2(int16 objectIndex, int16 propertyId, int16 &propertyFlag) {
     
    625714}
    626715
    627716int16 GameDatabase::getObjectProperty(int16 objectIndex, int16 propertyId) {
    628 
    629717        if (objectIndex == 0)
    630718                return 0;
    631719
  • engines/made/database.h

     
    3939
    4040class Object {
    4141public:
    42         Object();
     42        Object(bool bigEndian = false);
    4343        ~Object();
    4444
    4545        int loadVersion2(Common::SeekableReadStream &source);
    4646        int saveVersion2(Common::WriteStream &dest);
    4747
    4848        int loadVersion3(Common::SeekableReadStream &source);
     49        int loadVersionSegaSaturn(Common::SeekableReadStream &source);
    4950        int loadVersion3(byte *source);
    5051
    5152        uint16 getFlags() const;
     
    7071        void dump(const char *filename);
    7172
    7273protected:
     74        bool _bigEndian;
    7375        bool _freeData;
    7476        uint16 _objSize;
    7577        byte *_objData;
     
    123125        void load(Common::SeekableReadStream &sourceS);
    124126        void loadVersion2(Common::SeekableReadStream &sourceS);
    125127        void loadVersion3(Common::SeekableReadStream &sourceS);
     128        void loadVersionSegaSaturn(Common::SeekableReadStream &sourceS);
    126129        int16 savegameV2(Common::OutSaveFile *out, const char *description, int16 version);
    127130        int16 loadgameV2(Common::InSaveFile *in, int16 version);
    128131        int16 savegameV3(Common::OutSaveFile *out, const char *description, int16 version);
  • engines/made/detection.cpp

     
    227227                GF_FLOPPY,
    228228                0,
    229229        },
     230       
     231        {
     232                // Return to Zork - Japanese Sega Saturn version
     233                {
     234                        "rtz",
     235                        "",
     236                        AD_ENTRY1("rtz.dat", "023e46f6b43913792bd535558cce7bf7"),
     237                        Common::JA_JPN,
     238                        Common::kPlatformSaturn,
     239                        Common::ADGF_NO_FLAGS
     240                },
     241                GID_RTZ,
     242                0,
     243                GF_FLOPPY,
     244                0,
     245        },
    230246
    231247        {
    232248                // Return to Zork - Demo
  • engines/made/made.cpp

     
    8484                _system->openCD(cd_num);
    8585               
    8686        _pmvPlayer = new PmvPlayer(this, _mixer);
     87        _cpkPlayer = new CpkPlayer(this, _mixer);
    8788        _res = new ProjectReader();
    8889        _screen = new Screen(this);
    8990        _dat = new GameDatabase(this);
  • engines/made/made.h

     
    4545
    4646#include "engines/engine.h"
    4747
     48#include "made/cpkplayer.h"
     49
    4850namespace Made {
    4951
    5052enum MadeGameID {
     
    6567struct MadeGameDescription;
    6668
    6769class ProjectReader;
     70class CpkPlayer;
    6871class PmvPlayer;
    6972class Screen;
    7073class ScriptInterpreter;
     
    97100private:
    98101public:
    99102        PmvPlayer *_pmvPlayer;
     103        CpkPlayer *_cpkPlayer;
    100104        ProjectReader *_res;
    101105        Screen *_screen;
    102106        GameDatabase *_dat;
  • engines/made/module.mk

     
    11MODULE := engines/made
    22
    33MODULE_OBJS = \
     4        cpkplayer.o \
    45        database.o \
    56        detection.o \
    67        graphics.o \
  • engines/made/script.cpp

     
    191191        _runningScriptObjectIndex = scriptObjectIndex;
    192192
    193193        _localStackPos = _stack.getStackPos();
    194 
     194       
    195195        _codeBase = _vm->_dat->getObject(_runningScriptObjectIndex)->getData();
    196196        _codeIp = _codeBase;
    197197       
     
    215215}
    216216
    217217int16 ScriptInterpreter::readInt16() {
    218         int16 temp = (int16)READ_LE_UINT16(_codeIp);
     218        int16 temp;
     219        if (_vm->getPlatform() == Common::kPlatformSaturn)
     220                temp = (int16)READ_BE_UINT16(_codeIp);
     221        else
     222                temp = (int16)READ_LE_UINT16(_codeIp);
    219223        _codeIp += 2;
    220224        debug(4, "readInt16() value = %04X", temp);
    221225        return temp;
  • engines/made/scriptfuncs.cpp

     
    4646        _externalFuncNames.push_back(#x);
    4747void ScriptFunctions::setupExternalsTable() {
    4848
    49         External(sfSystemCall);
    50         External(sfInitGraf);
    51         External(sfRestoreGraf);
     49        if (_vm->getPlatform() != Common::kPlatformSaturn) {
     50                External(sfSystemCall);
     51                External(sfInitGraf);
     52                External(sfRestoreGraf);
     53        }
     54       
    5255        External(sfDrawPicture);
    5356        External(sfClearScreen);
    5457        External(sfShowPage);
     
    115118        }
    116119       
    117120        if (_vm->getGameID() == GID_RTZ) {
    118                 External(sfPrintf);
     121                if (_vm->getPlatform() != Common::kPlatformSaturn)
     122                        External(sfPrintf);
    119123                External(sfClearMono);
    120124                External(sfGetSoundEnergy);
    121125                External(sfClearText);
     
    150154                External(sfReadMenu);
    151155                External(sfDrawMenu);
    152156                External(sfGetMenuCount);
    153                 External(sfSaveGame);
    154                 External(sfLoadGame);
    155                 External(sfGetGameDescription);
     157                if (_vm->getPlatform() == Common::kPlatformSaturn) {
     158                        External(sfFaceIcon);
     159                } else {
     160                        External(sfSaveGame);
     161                        External(sfLoadGame);
     162                        External(sfGetGameDescription);
     163                }
    156164                External(sfShakeScreen);
    157165                External(sfPlaceMenu);
    158166                External(sfSetSoundVolume);
     
    880888
    881889}
    882890
     891int16 ScriptFunctions::sfFaceIcon(int16 argc, int16 *argv) {
     892        // RTZ Sega Saturn
     893        warning("Unimplemented opcode: sfFaceIcon");
     894        return 0;
     895}
     896
    883897int16 ScriptFunctions::sfShakeScreen(int16 argc, int16 *argv) {
    884898        // TODO: Used in RTZ
    885899        warning("Unimplemented opcode: sfShakeScreen");
  • engines/made/scriptfuncs.h

     
    161161        int16 sfSaveGame(int16 argc, int16 *argv);
    162162        int16 sfLoadGame(int16 argc, int16 *argv);
    163163        int16 sfGetGameDescription(int16 argc, int16 *argv);
     164        int16 sfFaceIcon(int16 argc, int16 *argv);
    164165        int16 sfShakeScreen(int16 argc, int16 *argv);
    165166        int16 sfPlaceMenu(int16 argc, int16 *argv);
    166167        int16 sfSetSoundVolume(int16 argc, int16 *argv);