Ticket #8865: sega_film_player.diff

File sega_film_player.diff, 8.6 KB (added by SF/mthreepwood, 16 years ago)

WIP sega film player patch

  • 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}
  • 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
  • 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);
  • 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;
     
    98101private:
    99102public:
    100103        PmvPlayer *_pmvPlayer;
     104        CpkPlayer *_cpkPlayer;
    101105        ProjectReader *_res;
    102106        Screen *_screen;
    103107        GameDatabase *_dat;
  • module.mk

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

     
    584584
    585585int16 ScriptFunctionsRtz::o1_PLAYMOVIE(int16 argc, int16 *argv) {
    586586        const char *movieName = _vm->_dat->getObject(argv[1])->getString();
    587         _vm->_pmvPlayer->play(movieName);
     587        if (_vm->getPlatform() == Common::kPlatformSaturn)
     588                _vm->_cpkPlayer->play(movieName);
     589        else
     590                _vm->_pmvPlayer->play(movieName);
    588591        return 0;
    589592}
    590593