Skip to content

Commit

Permalink
BLADERUNNER: Rebuild VQADecoder on top of Video::VideoDecoder
Browse files Browse the repository at this point in the history
  • Loading branch information
madmoose authored and sev- committed Sep 29, 2016
1 parent 5fd05a4 commit a67e9e1
Show file tree
Hide file tree
Showing 10 changed files with 723 additions and 354 deletions.
167 changes: 167 additions & 0 deletions engines/bladerunner/aud_decoder.cpp
@@ -0,0 +1,167 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#include "bladerunner/aud_decoder.h"

#include "common/util.h"

namespace BladeRunner {

static const
int16 imaIndexTable[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };

static const
uint16 imaStepTable[712] =
{
0x0000,0x0001,0x0003,0x0004,0x0007,0x0008,0x000a,0x000b,
0x0001,0x0003,0x0005,0x0007,0x0009,0x000b,0x000d,0x000f,
0x0001,0x0003,0x0005,0x0007,0x000a,0x000c,0x000e,0x0010,
0x0001,0x0003,0x0006,0x0008,0x000b,0x000d,0x0010,0x0012,
0x0001,0x0003,0x0006,0x0008,0x000c,0x000e,0x0011,0x0013,
0x0001,0x0004,0x0007,0x000a,0x000d,0x0010,0x0013,0x0016,
0x0001,0x0004,0x0007,0x000a,0x000e,0x0011,0x0014,0x0017,
0x0001,0x0004,0x0008,0x000b,0x000f,0x0012,0x0016,0x0019,
0x0002,0x0006,0x000a,0x000e,0x0012,0x0016,0x001a,0x001e,
0x0002,0x0006,0x000a,0x000e,0x0013,0x0017,0x001b,0x001f,
0x0002,0x0006,0x000b,0x000f,0x0015,0x0019,0x001e,0x0022,
0x0002,0x0007,0x000c,0x0011,0x0017,0x001c,0x0021,0x0026,
0x0002,0x0007,0x000d,0x0012,0x0019,0x001e,0x0024,0x0029,
0x0003,0x0009,0x000f,0x0015,0x001c,0x0022,0x0028,0x002e,
0x0003,0x000a,0x0011,0x0018,0x001f,0x0026,0x002d,0x0034,
0x0003,0x000a,0x0012,0x0019,0x0022,0x0029,0x0031,0x0038,
0x0004,0x000c,0x0015,0x001d,0x0026,0x002e,0x0037,0x003f,
0x0004,0x000d,0x0016,0x001f,0x0029,0x0032,0x003b,0x0044,
0x0005,0x000f,0x0019,0x0023,0x002e,0x0038,0x0042,0x004c,
0x0005,0x0010,0x001b,0x0026,0x0032,0x003d,0x0048,0x0053,
0x0006,0x0012,0x001f,0x002b,0x0038,0x0044,0x0051,0x005d,
0x0006,0x0013,0x0021,0x002e,0x003d,0x004a,0x0058,0x0065,
0x0007,0x0016,0x0025,0x0034,0x0043,0x0052,0x0061,0x0070,
0x0008,0x0018,0x0029,0x0039,0x004a,0x005a,0x006b,0x007b,
0x0009,0x001b,0x002d,0x003f,0x0052,0x0064,0x0076,0x0088,
0x000a,0x001e,0x0032,0x0046,0x005a,0x006e,0x0082,0x0096,
0x000b,0x0021,0x0037,0x004d,0x0063,0x0079,0x008f,0x00a5,
0x000c,0x0024,0x003c,0x0054,0x006d,0x0085,0x009d,0x00b5,
0x000d,0x0027,0x0042,0x005c,0x0078,0x0092,0x00ad,0x00c7,
0x000e,0x002b,0x0049,0x0066,0x0084,0x00a1,0x00bf,0x00dc,
0x0010,0x0030,0x0051,0x0071,0x0092,0x00b2,0x00d3,0x00f3,
0x0011,0x0034,0x0058,0x007b,0x00a0,0x00c3,0x00e7,0x010a,
0x0013,0x003a,0x0061,0x0088,0x00b0,0x00d7,0x00fe,0x0125,
0x0015,0x0040,0x006b,0x0096,0x00c2,0x00ed,0x0118,0x0143,
0x0017,0x0046,0x0076,0x00a5,0x00d5,0x0104,0x0134,0x0163,
0x001a,0x004e,0x0082,0x00b6,0x00eb,0x011f,0x0153,0x0187,
0x001c,0x0055,0x008f,0x00c8,0x0102,0x013b,0x0175,0x01ae,
0x001f,0x005e,0x009d,0x00dc,0x011c,0x015b,0x019a,0x01d9,
0x0022,0x0067,0x00ad,0x00f2,0x0139,0x017e,0x01c4,0x0209,
0x0026,0x0072,0x00bf,0x010b,0x0159,0x01a5,0x01f2,0x023e,
0x002a,0x007e,0x00d2,0x0126,0x017b,0x01cf,0x0223,0x0277,
0x002e,0x008a,0x00e7,0x0143,0x01a1,0x01fd,0x025a,0x02b6,
0x0033,0x0099,0x00ff,0x0165,0x01cb,0x0231,0x0297,0x02fd,
0x0038,0x00a8,0x0118,0x0188,0x01f9,0x0269,0x02d9,0x0349,
0x003d,0x00b8,0x0134,0x01af,0x022b,0x02a6,0x0322,0x039d,
0x0044,0x00cc,0x0154,0x01dc,0x0264,0x02ec,0x0374,0x03fc,
0x004a,0x00df,0x0175,0x020a,0x02a0,0x0335,0x03cb,0x0460,
0x0052,0x00f6,0x019b,0x023f,0x02e4,0x0388,0x042d,0x04d1,
0x005a,0x010f,0x01c4,0x0279,0x032e,0x03e3,0x0498,0x054d,
0x0063,0x012a,0x01f1,0x02b8,0x037f,0x0446,0x050d,0x05d4,
0x006d,0x0148,0x0223,0x02fe,0x03d9,0x04b4,0x058f,0x066a,
0x0078,0x0168,0x0259,0x0349,0x043b,0x052b,0x061c,0x070c,
0x0084,0x018d,0x0296,0x039f,0x04a8,0x05b1,0x06ba,0x07c3,
0x0091,0x01b4,0x02d8,0x03fb,0x051f,0x0642,0x0766,0x0889,
0x00a0,0x01e0,0x0321,0x0461,0x05a2,0x06e2,0x0823,0x0963,
0x00b0,0x0210,0x0371,0x04d1,0x0633,0x0793,0x08f4,0x0a54,
0x00c2,0x0246,0x03ca,0x054e,0x06d2,0x0856,0x09da,0x0b5e,
0x00d5,0x027f,0x042a,0x05d4,0x0780,0x092a,0x0ad5,0x0c7f,
0x00ea,0x02bf,0x0495,0x066a,0x0840,0x0a15,0x0beb,0x0dc0,
0x0102,0x0306,0x050b,0x070f,0x0914,0x0b18,0x0d1d,0x0f21,
0x011c,0x0354,0x058c,0x07c4,0x09fc,0x0c34,0x0e6c,0x10a4,
0x0138,0x03a8,0x0619,0x0889,0x0afb,0x0d6b,0x0fdc,0x124c,
0x0157,0x0406,0x06b5,0x0964,0x0c14,0x0ec3,0x1172,0x1421,
0x017a,0x046e,0x0762,0x0a56,0x0d4a,0x103e,0x1332,0x1626,
0x019f,0x04de,0x081e,0x0b5d,0x0e9e,0x11dd,0x151d,0x185c,
0x01c9,0x055c,0x08ef,0x0c82,0x1015,0x13a8,0x173b,0x1ace,
0x01f7,0x05e5,0x09d4,0x0dc2,0x11b1,0x159f,0x198e,0x1d7c,
0x0229,0x067c,0x0acf,0x0f22,0x1375,0x17c8,0x1c1b,0x206e,
0x0260,0x0721,0x0be3,0x10a4,0x1567,0x1a28,0x1eea,0x23ab,
0x029d,0x07d8,0x0d14,0x124f,0x178b,0x1cc6,0x2202,0x273d,
0x02e0,0x08a1,0x0e63,0x1424,0x19e6,0x1fa7,0x2569,0x2b2a,
0x032a,0x097f,0x0fd4,0x1629,0x1c7e,0x22d3,0x2928,0x2f7d,
0x037b,0x0a72,0x1169,0x1860,0x1f57,0x264e,0x2d45,0x343c,
0x03d4,0x0b7d,0x1326,0x1acf,0x2279,0x2a22,0x31cb,0x3974,
0x0436,0x0ca3,0x1511,0x1d7e,0x25ec,0x2e59,0x36c7,0x3f34,
0x04a2,0x0de7,0x172c,0x2071,0x29b7,0x32fc,0x3c41,0x4586,
0x0519,0x0f4b,0x197e,0x23b0,0x2de3,0x3815,0x4248,0x4c7a,
0x059b,0x10d2,0x1c0a,0x2741,0x327a,0x3db1,0x48e9,0x5420,
0x062b,0x1281,0x1ed8,0x2b2e,0x3786,0x43dc,0x5033,0x5c89,
0x06c9,0x145b,0x21ee,0x2f80,0x3d14,0x4aa6,0x5839,0x65cb,
0x0777,0x1665,0x2553,0x3441,0x4330,0x521e,0x610c,0x6ffa,
0x0836,0x18a2,0x290f,0x397b,0x49e8,0x5a54,0x6ac1,0x7b2d,
0x0908,0x1b19,0x2d2a,0x3f3b,0x514c,0x635d,0x756e,0x877f,
0x09ef,0x1dce,0x31ae,0x458d,0x596d,0x6d4c,0x812c,0x950b,
0x0aee,0x20ca,0x36a6,0x4c82,0x625f,0x783b,0x8e17,0xa3f3,
0x0c05,0x2410,0x3c1c,0x5427,0x6c34,0x843f,0x9c4b,0xb456,
0x0d39,0x27ac,0x4220,0x5c93,0x7707,0x917a,0xabee,0xc661,
0x0e8c,0x2ba4,0x48bd,0x65d5,0x82ee,0xa006,0xbd1f,0xda37,
0x0fff,0x2ffe,0x4ffe,0x6ffd,0x8ffe,0xaffd,0xcffd,0xeffc
};

void ADPCMWestwoodDecoder::decode(uint8 *in, size_t size, int16 *out)
{
uint8 *end = in + size;

int16 stepIndex = _stepIndex;
int32 predictor = _predictor;

while (in != end)
{
uint16 bl = *in++;

for (int n = 0; n != 2; ++n)
{
uint8 nibble = (bl >> (4 * n)) & 0x0f;
uint8 code = nibble & 0x07;
uint8 sign = nibble & 0x08;

int diff = imaStepTable[(stepIndex << 3) | code];

// Westwood's IMA ADPCM differs from the below standard implementation
// in the LSB in a couple of places.
//int diff = imaStepTable_std[stepIndex] * code / 4 + imaStepTable_std[stepIndex] / 8;

if (sign)
predictor -= diff;
else
predictor += diff;

predictor = CLIP<int32>(predictor, -32768, 32767);

*out++ = (int16)predictor;

stepIndex = imaIndexTable[code] + stepIndex;
stepIndex = CLIP<int16>(stepIndex, 0, 88);
}
}

_stepIndex = stepIndex;
_predictor = predictor;
}

};
50 changes: 50 additions & 0 deletions engines/bladerunner/aud_decoder.h
@@ -0,0 +1,50 @@
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/

#ifndef BLADERUNNER_AUD_DECODER_H
#define BLADERUNNER_AUD_DECODER_H

#include "common/types.h"

namespace BladeRunner {

class ADPCMWestwoodDecoder {
int16 _stepIndex;
int32 _predictor;

public:
ADPCMWestwoodDecoder()
: _stepIndex(0), _predictor(0)
{}

void setParameters(int16 stepIndex, int32 predictor)
{
_stepIndex = stepIndex;
_predictor = predictor;
}

void decode(uint8 *in, size_t size, int16 *out);
};

};

#endif
15 changes: 9 additions & 6 deletions engines/bladerunner/bladerunner.cpp
Expand Up @@ -58,13 +58,12 @@ Common::Error BladeRunnerEngine::run() {

startup();

if (!warnUserAboutUnsupportedGame())
return Common::kNoError;
if (warnUserAboutUnsupportedGame()) {
init2();

init2();

/* TODO: Check for save games and enter KIA */
gameLoop();
/* TODO: Check for save games and enter KIA */
gameLoop();
}

shutdown();

Expand Down Expand Up @@ -169,6 +168,10 @@ void BladeRunnerEngine::gameTick() {
// TODO: Only run if not in Kia, script, nor AI
_settings->openNewScene();

outtakePlay(28, true);
outtakePlay(41, true);
outtakePlay( 0, false);

// TODO: Autosave
// TODO: Kia
// TODO: Spinner
Expand Down
4 changes: 2 additions & 2 deletions engines/bladerunner/module.mk
Expand Up @@ -2,6 +2,7 @@ MODULE := engines/bladerunner

MODULE_OBJS = \
archive.o \
aud_decoder.o \
bladerunner.o \
chapters.o \
decompress_lcw.o \
Expand All @@ -11,8 +12,7 @@ MODULE_OBJS = \
image.o \
outtake.o \
settings.o \
vqa_decoder.o \
vqa_player.o
vqa_decoder.o

# This module can be built as a plugin
ifeq ($(ENABLE_BLADERUNNER), DYNAMIC_PLUGIN)
Expand Down
40 changes: 24 additions & 16 deletions engines/bladerunner/outtake.cpp
Expand Up @@ -23,8 +23,10 @@
#include "bladerunner/outtake.h"

#include "bladerunner/bladerunner.h"
#include "bladerunner/vqa_player.h"
#include "bladerunner/vqa_decoder.h"

#include "common/debug.h"
#include "common/events.h"
#include "common/system.h"

namespace BladeRunner {
Expand All @@ -41,27 +43,33 @@ void OuttakePlayer::play(const Common::String &name, bool noLocalization, int co
else
resName = name + "_E.VQA";

_vqaPlayer = new VQAPlayer(_vm, &_vm->_surface1);
_vqaPlayer->open(resName);
Common::SeekableReadStream *s = _vm->getResourceStream(resName);

for (;;) {
_vm->handleEvents();
if (_vm->shouldQuit())
break;
_vqaDecoder = new VQADecoder();
_vqaDecoder->loadStream(s);

int r = _vqaPlayer->update();
if (r == -3)
break;
_vqaDecoder->start();

if (r >= 0) {
_vm->_system->copyRectToScreen(_vm->_surface1.getPixels(), _vm->_surface1.pitch, 0, 0, _vm->_surface1.w, _vm->_surface1.h);
uint32 last = _vm->_system->getMillis();

while (!_vqaDecoder->endOfVideo() && !_vm->shouldQuit()) {
if (_vqaDecoder->needsUpdate()) {
uint32 now = _vm->_system->getMillis();
debug("delta: %d", now - last);
last = now;

const Graphics::Surface *surface = _vqaDecoder->decodeNextFrame();
_vm->_system->copyRectToScreen((const byte *)surface->getBasePtr(0, 0), surface->pitch, 0, 0, 640, 480);
_vm->_system->updateScreen();
_vm->_system->delayMillis(10);
}
}

delete _vqaPlayer;
_vqaPlayer = nullptr;
Common::Event event;
while (_vm->_system->getEventManager()->pollEvent(event))
if ((event.type == Common::EVENT_KEYDOWN && event.kbd.keycode == Common::KEYCODE_ESCAPE) || event.type == Common::EVENT_LBUTTONUP)
return;

_vm->_system->delayMillis(10);
}
}

}; // End of namespace BladeRunner
6 changes: 3 additions & 3 deletions engines/bladerunner/outtake.h
Expand Up @@ -30,20 +30,20 @@
namespace BladeRunner {

class BladeRunnerEngine;
class VQAPlayer;
class VQADecoder;

class OuttakePlayer {
BladeRunnerEngine *_vm;

bool _isVQAOpen;
VQAPlayer *_vqaPlayer;
VQADecoder *_vqaDecoder;
Graphics::Surface *_surface;

public:
OuttakePlayer(BladeRunnerEngine *vm) :
_vm(vm),
_isVQAOpen(false),
_vqaPlayer(nullptr)
_vqaDecoder(nullptr)
{}

void play(const Common::String &name, bool noLocalization, int container);
Expand Down

0 comments on commit a67e9e1

Please sign in to comment.