aboutsummaryrefslogtreecommitdiff
path: root/engines/cryo
diff options
context:
space:
mode:
authorStrangerke2016-11-27 12:47:04 -0800
committerEugene Sandulenko2017-01-25 22:42:08 +0100
commitb735962436c2f33a877f623d92b61a4a46680fb3 (patch)
tree81bcfc0a55f70a7f793b04654bfe43308744cb68 /engines/cryo
parent899d22805f65ac9907bb46359efcc042aaf1b865 (diff)
downloadscummvm-rg350-b735962436c2f33a877f623d92b61a4a46680fb3.tar.gz
scummvm-rg350-b735962436c2f33a877f623d92b61a4a46680fb3.tar.bz2
scummvm-rg350-b735962436c2f33a877f623d92b61a4a46680fb3.zip
CRYO: Move some functions from cryolib to HnmPlayer
Diffstat (limited to 'engines/cryo')
-rw-r--r--engines/cryo/clhnm.cpp241
-rw-r--r--engines/cryo/cryo.cpp3
-rw-r--r--engines/cryo/cryo.h3
-rw-r--r--engines/cryo/cryolib.h15
-rw-r--r--engines/cryo/defs.h1
-rw-r--r--engines/cryo/eden.cpp49
-rw-r--r--engines/cryo/module.mk3
-rw-r--r--engines/cryo/video.cpp289
-rw-r--r--engines/cryo/video.h81
9 files changed, 403 insertions, 282 deletions
diff --git a/engines/cryo/clhnm.cpp b/engines/cryo/clhnm.cpp
index 19633ef236..0881126197 100644
--- a/engines/cryo/clhnm.cpp
+++ b/engines/cryo/clhnm.cpp
@@ -27,24 +27,7 @@
namespace Cryo {
static bool safe_palette = false;
-static int16 pred_r = 0, pred_l = 0;
-static bool use_adpcm = false;
-static float hnm_rate = 0.0;
-static float next_frame_time = 0.0;
-static float expected_frame_time = 0.0;
-static float time_drift = 0.0;
static bool use_mono = false;
-static bool use_sound = false;
-static bool use_sound_sync = false;
-static int16 pending_sounds = 0;
-static bool sound_started = false;
-static bool preserve_color0 = false;
-static soundchannel_t *soundChannel_adpcm = nullptr;
-static soundgroup_t *soundGroup_adpcm = nullptr;
-static soundchannel_t *soundChannel = nullptr;
-static soundgroup_t *soundGroup = 0;
-static void (*custom_chunk_handler)(byte *buffer, int size, int16 id, char h6, char h7) = nullptr;
-static int16 decomp_table[256];
void CLHNM_Desentrelace320(byte *frame_buffer, byte *final_buffer, uint16 height);
@@ -189,64 +172,9 @@ void CLHNM_DecompUBA(byte *output, byte *curr_buffer, byte *prev_buffer,
}
}
-void CLHNM_Init() {
- custom_chunk_handler = nullptr;
- preserve_color0 = false;
-}
-
void CLHNM_Done() {
}
-void CLHNM_SetupTimer(float rate) {
- hnm_rate = 100.0 / rate;
-}
-
-void CLHNM_WaitLoop(hnm_t *hnm) {
- expected_frame_time += hnm_rate;
- next_frame_time = expected_frame_time - time_drift;
- if (use_sound_sync && TimerTicks > 1000.0 + next_frame_time)
- use_sound = false;
- while (TimerTicks < next_frame_time) ; // waste time
- time_drift = TimerTicks - next_frame_time;
-}
-
-void CLHNM_SetupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode) {
- soundChannel = CLSoundChannel_New(mode);
- soundGroup = CLSoundGroup_New(numSounds, length, sampleSize, rate, mode);
- if (sampleSize == 16)
- CLSoundGroup_Reverse16All(soundGroup);
-}
-
-void CLHNM_SetupSoundADPCM(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode) {
- soundChannel_adpcm = CLSoundChannel_New(mode);
- soundGroup_adpcm = CLSoundGroup_New(numSounds, length, sampleSize, rate, mode);
-}
-
-void CLHNM_CloseSound() {
- if (soundChannel) {
- CLSoundChannel_Stop(soundChannel);
- CLSoundChannel_Free(soundChannel);
- soundChannel = nullptr;
- }
- if (soundGroup) {
- CLSoundGroup_Free(soundGroup);
- soundGroup = nullptr;
- }
- if (soundChannel_adpcm) {
- CLSoundChannel_Stop(soundChannel_adpcm);
- CLSoundChannel_Free(soundChannel_adpcm);
- soundChannel = nullptr;
- }
- if (soundGroup_adpcm) {
- CLSoundGroup_Free(soundGroup_adpcm);
- soundGroup = nullptr;
- }
-}
-
-void CLHNM_SetForceZero2Black(bool forceblack) {
- preserve_color0 = forceblack;
-}
-
hnm_t *CLHNM_New(int preload_size) {
hnm_t *hnm = (hnm_t *)malloc(sizeof(*hnm));
@@ -407,31 +335,10 @@ void CLHNM_Desentrelace(hnm_t *hnm) {
}
}
-void CLHNM_FlushPreloadBuffer(hnm_t *hnm) {
-}
-
-soundchannel_t *CLHNM_GetSoundChannel() {
- return soundChannel;
-}
-
void CLHNM_TryRead(hnm_t *hnm, int size) {
hnm->_file->read(hnm->_readBuffer, size);
}
-void CLHNM_ResetInternalTimer() {
- time_drift = 0.0;
- next_frame_time = expected_frame_time = TimerTicks;
-}
-
-void CLHNM_Reset(hnm_t *hnm) {
- hnm->_frameNum = 0;
- hnm->ff_4 = 0;
- hnm->_totalRead = 0;
- sound_started = false;
- pending_sounds = 0;
- CLHNM_ResetInternalTimer();
-}
-
bool CLHNM_LoadFrame(hnm_t *hnm) {
int chunk;
CLHNM_TryRead(hnm, 4);
@@ -450,158 +357,10 @@ bool CLHNM_LoadFrame(hnm_t *hnm) {
return true;
}
-void CLHNM_WantsSound(bool sound) {
- use_sound = sound;
-}
-
-void CLHNM_LoadDecompTable(int16 *buffer) {
- int16 i;
- int16 e;
- for (i = 0; i < 256; i++) {
- e = *buffer++;
- decomp_table[i] = LE16(e);
- }
-}
-
-void CLHNM_DecompADPCM(byte *buffer, int16 *output, int size) {
- int16 l = pred_l;
- int16 r = pred_r;
- size &= ~1;
- while (size--) {
- *output++ = l += decomp_table[*buffer++];
- *output++ = r += decomp_table[*buffer++];
- if (l > 512 || r > 512)
- error("CLHNM_DecompADPCM - Unexpected values");
- }
- pred_l = l;
- pred_r = r;
-}
-
-void CLHNM_SoundInADPCM(bool isAdpcm) {
- use_adpcm = isAdpcm;
-}
-
void CLHNM_SoundMono(bool isMono) {
use_mono = isMono;
}
-bool CLHNM_NextElement(hnm_t *hnm) {
- int sz;
- int16 id;
- char h6, h7;
- int16 i;
- if (hnm->_frameNum == 0) {
- CLHNM_ResetInternalTimer();
- pred_l = pred_r = 0;
- }
- if (hnm->_frameNum == hnm->_header._numbFrame)
- return false;
-
- if (!CLHNM_LoadFrame(hnm))
- return false;
-
- for (;;) {
- sz = PLE32(hnm->_dataPtr) & 0xFFFFFF;
- hnm->_dataPtr += 4;
- id = *(int16 *)hnm->_dataPtr;
- hnm->_dataPtr += 2;
- h6 = *hnm->_dataPtr;
- hnm->_dataPtr += 1;
- h7 = *hnm->_dataPtr;
- hnm->_dataPtr += 1;
- hnm->_chunkId = id;
- switch (id) {
- case BE16('PL'):
- CLHNM_ChangePalette(hnm);
- hnm->_dataPtr += sz - 8;
- break;
- case BE16('IZ'):
- hnm->_frameNum++;
- CLHNM_SelectBuffers(hnm);
- CLHNM_DecompLempelZiv(hnm->_dataPtr + 4, hnm->_newFrameBuffer);
- switch (hnm->_header._width) {
-// case 320: CLBlitter_RawCopy320ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
-// case 480: CLBlitter_RawCopy480ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
-// case 640: CLBlitter_RawCopy640ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
-// default: memcpy(hnm->old_frame_buffer, hnm->new_frame_buffer, hnm->header.width * hnm->header.height);
- default:
- memcpy(hnm->_oldFrameBuffer, hnm->_newFrameBuffer, hnm->_header._bufferSize); //TODO strange buffer size here
- }
- if (!(h6 & 1))
- CLHNM_Desentrelace(hnm);
- else {
-// if(hnm->header.width == 640)
-// CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
-// else
- memcpy(hnm->finalBuffer, hnm->_newFrameBuffer, hnm->_header._height); //TODO: wrong size?
- }
- if (use_adpcm) {
- if (!sound_started) {
- for (i = 0; i < pending_sounds; i++)
- CLSoundGroup_PlayNextSample(soundGroup_adpcm, soundChannel);
- sound_started = true;
- }
- } else if (!sound_started) {
- for (i = 0; i < pending_sounds; i++)
- CLSoundGroup_PlayNextSample(soundGroup, soundChannel);
- sound_started = true;
- }
-
- return true;
- case BE16('IU'):
- hnm->_frameNum++;
- CLHNM_SelectBuffers(hnm);
- CLHNM_DecompUBA(hnm->_newFrameBuffer, hnm->_newFrameBuffer, hnm->_oldFrameBuffer, hnm->_dataPtr, hnm->_header._width, h6);
- if (!(h6 & 1))
- CLHNM_Desentrelace(hnm);
- else {
-// if(hnm->header.width == 640)
-// CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
-// else
- memcpy(hnm->finalBuffer, hnm->_newFrameBuffer, hnm->_header._width * hnm->_header._height);
- }
- return true;
-
- case BE16('sd'):
- case BE16('SD'):
- if (use_sound) {
- if (!h6) {
- int sound_size = sz - 8;
- if (!use_adpcm) {
- CLSoundGroup_SetDatas(soundGroup, hnm->_dataPtr, sound_size - 2, false);
- if (sound_started)
- CLSoundGroup_PlayNextSample(soundGroup, soundChannel);
- else
- pending_sounds++;
- } else {
- int16 *sound_buffer = (int16 *)CLSoundGroup_GetNextBuffer(soundGroup_adpcm);
- if (!pending_sounds) {
- const int kDecompTableSize = 256 * sizeof(int16);
- CLHNM_LoadDecompTable((int16 *)hnm->_dataPtr);
- CLHNM_DecompADPCM(hnm->_dataPtr + kDecompTableSize, sound_buffer, sound_size - kDecompTableSize);
- CLSoundGroup_AssignDatas(soundGroup_adpcm, sound_buffer, (sound_size - kDecompTableSize) * 2, false);
- } else {
- CLHNM_DecompADPCM(hnm->_dataPtr, sound_buffer, sound_size);
- CLSoundGroup_AssignDatas(soundGroup_adpcm, sound_buffer, sound_size * 2, false);
- }
- pending_sounds++;
- if (sound_started)
- CLSoundGroup_PlayNextSample(soundGroup_adpcm, soundChannel);
- }
- } else
- error("CLHNM_NextElement - unexpected flag");
- }
- hnm->_dataPtr += sz - 8;
- break;
- default:
- if (custom_chunk_handler)
- custom_chunk_handler(hnm->_dataPtr, sz - 8, id, h6, h7);
- hnm->_dataPtr += sz - 8;
- }
- }
- return true;
-}
-
void CLHNM_ReadHeader(hnm_t *hnm) {
int32 size = sizeof(hnm->_header);
hnm->_file->read(&hnm->_header, size);
diff --git a/engines/cryo/cryo.cpp b/engines/cryo/cryo.cpp
index 220ba13524..1f15b0e5b3 100644
--- a/engines/cryo/cryo.cpp
+++ b/engines/cryo/cryo.cpp
@@ -60,6 +60,7 @@ CryoEngine::CryoEngine(OSystem *syst, const ADGameDescription *gameDesc) : Engin
// Don't forget to register your random source
_rnd = new Common::RandomSource("cryo");
_game = nullptr;
+ _video = nullptr;
debug("CryoEngine::CryoEngine");
@@ -72,6 +73,7 @@ CryoEngine::~CryoEngine() {
// Dispose your resources here
delete _rnd;
delete _game;
+ delete _video;
// Remove all of our debug levels here
DebugMan.clearAllDebugChannels();
@@ -79,6 +81,7 @@ CryoEngine::~CryoEngine() {
Common::Error CryoEngine::run() {
_game = new EdenGame(this);
+ _video = new HnmPlayer(this);
// Initialize graphics using following:
initGraphics(320, 200, false);
diff --git a/engines/cryo/cryo.h b/engines/cryo/cryo.h
index 4993a482d3..d9e6135a9a 100644
--- a/engines/cryo/cryo.h
+++ b/engines/cryo/cryo.h
@@ -34,7 +34,9 @@
#include "gui/debugger.h"
#include "graphics/surface.h"
#include "graphics/screen.h"
+
#include "cryo/eden.h"
+#include "cryo/video.h"
namespace Cryo {
@@ -66,6 +68,7 @@ public:
Graphics::Surface _screen;
EdenGame *_game;
+ HnmPlayer *_video;
private:
Console *_console;
diff --git a/engines/cryo/cryolib.h b/engines/cryo/cryolib.h
index 7b7799ad2f..2daed71034 100644
--- a/engines/cryo/cryolib.h
+++ b/engines/cryo/cryolib.h
@@ -255,14 +255,7 @@ void CRYOLib_ManagersDone();
void CLHNM_DecompLempelZiv(byte *buffer, byte *output);
void CLHNM_DecompUBA(byte *output, byte *curr_buffer, byte *prev_buffer,
byte *input, int width, char flags);
-void CLHNM_Init();
void CLHNM_Done();
-void CLHNM_SetupTimer(float rate);
-void CLHNM_WaitLoop(hnm_t *hnm);
-void CLHNM_SetupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode);
-void CLHNM_SetupSoundADPCM(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode);
-void CLHNM_CloseSound();
-void CLHNM_SetForceZero2Black(bool forceblack);
hnm_t *CLHNM_New(int preload_size);
void CLHNM_Dispose(hnm_t *hnm);
void CLHNM_SetFile(hnm_t *hnm, file_t *file);
@@ -273,17 +266,9 @@ void CLHNM_CanLoop(hnm_t *hnm, bool canLoop);
void CLHNM_SelectBuffers(hnm_t *hnm);
void CLHNM_ChangePalette(hnm_t *hnm);
void CLHNM_Desentrelace(hnm_t *hnm);
-void CLHNM_FlushPreloadBuffer(hnm_t *hnm);
-soundchannel_t *CLHNM_GetSoundChannel();
-void CLHNM_ResetInternalTimer();
-void CLHNM_Reset(hnm_t *hnm);
bool CLHNM_LoadFrame(hnm_t *hnm);
void CLHNM_WantsSound(int16 sound);
-void CLHNM_LoadDecompTable(int16 *buffer);
-void CLHNM_DecompADPCM(byte *buffer, int16 *output, int size);
-void CLHNM_SoundInADPCM(int16 is_adpcm);
void CLHNM_SoundMono(int16 is_mono);
-bool CLHNM_NextElement(hnm_t *hnm);
void CLHNM_ReadHeader(hnm_t *hnm);
int16 CLHNM_GetVersion(hnm_t *hnm);
int CLHNM_GetFrameNum(hnm_t *hnm);
diff --git a/engines/cryo/defs.h b/engines/cryo/defs.h
index 8ff50763ce..1660305c83 100644
--- a/engines/cryo/defs.h
+++ b/engines/cryo/defs.h
@@ -630,7 +630,6 @@ struct global_t {
uint16 roomPersoItems; //TODO: write-only?
uint16 roomPersoPowers; //TODO: write-only?
uint16 gameFlags;
- uint16 curVideoNum;
uint16 morkusSpyVideoNum1; //TODO: pad?
uint16 morkusSpyVideoNum2; //TODO: pad?
uint16 morkusSpyVideoNum3; //TODO: pad?
diff --git a/engines/cryo/eden.cpp b/engines/cryo/eden.cpp
index 5adacac664..3c11a5785c 100644
--- a/engines/cryo/eden.cpp
+++ b/engines/cryo/eden.cpp
@@ -4976,7 +4976,6 @@ void EdenGame::init_globals() {
p_global->roomPersoItems = 0;
p_global->roomPersoPowers = 0;
p_global->gameFlags = 0;
- p_global->curVideoNum = 0;
p_global->morkusSpyVideoNum1 = 89;
p_global->morkusSpyVideoNum2 = 88;
p_global->morkusSpyVideoNum3 = 83;
@@ -5570,11 +5569,11 @@ void EdenGame::run() {
word_378CE = 0;
CRYOLib_ManagersInit();
- CLHNM_SetupSound(5, 0x2000, 8, 11025 * 65536.0 , 0);
- CLHNM_SetForceZero2Black(true);
- CLHNM_SetupTimer(12.5);
+ _vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0 , 0);
+ _vm->_video->setForceZero2Black(true);
+ _vm->_video->setupTimer(12.5);
voiceSound = CLSoundRaw_New(0, 11025 * 65536.0, 8, 0);
- _hnmSoundChannel = CLHNM_GetSoundChannel();
+ _hnmSoundChannel = _vm->_video->getSoundChannel();
CLSound_SetWantsDesigned(1); // CHECKME: Used?
_musicChannel = new CSoundChannel(_vm->_mixer, 11025, false);
@@ -5678,18 +5677,18 @@ void EdenGame::intro() {
if (_vm->getPlatform() == Common::kPlatformMacintosh) {
// Play intro videos in HQ
CLSoundChannel_Stop(_hnmSoundChannel);
- CLHNM_CloseSound();
- CLHNM_SetupSound(5, 0x2000, 16, 22050 * 65536.0, 0);
- _hnmSoundChannel = CLHNM_GetSoundChannel();
+ _vm->_video->closeSound();
+ _vm->_video->setupSound(5, 0x2000, 16, 22050 * 65536.0, 0);
+ _hnmSoundChannel = _vm->_video->getSoundChannel();
playHNM(2012);
playHNM(171);
CLBlitter_FillScreenView(0);
specialTextMode = false;
playHNM(2001);
CLSoundChannel_Stop(_hnmSoundChannel);
- CLHNM_CloseSound();
- CLHNM_SetupSound(5, 0x2000, 8, 11025 * 65536.0, 0);
- _hnmSoundChannel = CLHNM_GetSoundChannel();
+ _vm->_video->closeSound();
+ _vm->_video->setupSound(5, 0x2000, 8, 11025 * 65536.0, 0);
+ _hnmSoundChannel = _vm->_video->getSoundChannel();
} else {
playHNM(98); // Cryo logo
playHNM(171); // Virgin logo
@@ -6209,14 +6208,16 @@ void EdenGame::mouse() {
// Original name: showfilm
void EdenGame::showMovie(char arg1) {
CLHNM_ReadHeader(_hnmContext);
- if (p_global->curVideoNum == 92) {
+ if (_vm->_video->curVideoNum == 92) {
// _hnmContext->_header._unusedFlag2 = 0; CHECKME: Useless?
CLSoundChannel_SetVolumeLeft(_hnmSoundChannel, 0);
CLSoundChannel_SetVolumeRight(_hnmSoundChannel, 0);
}
- bool playing = true;
+
if (CLHNM_GetVersion(_hnmContext) != 4)
return;
+
+ bool playing = true;
CLHNM_AllocMemory(_hnmContext);
p_hnmview = CLView_New(_hnmContext->_header._width, _hnmContext->_header._height);
CLView_SetSrcZoomValues(p_hnmview, 0, 0);
@@ -6233,8 +6234,8 @@ void EdenGame::showMovie(char arg1) {
p_hnmview->_doubled = _doubledScreen;
do {
hnm_position = CLHNM_GetFrameNum(_hnmContext);
- CLHNM_WaitLoop(_hnmContext);
- playing = CLHNM_NextElement(_hnmContext);
+ _vm->_video->waitLoop(_hnmContext);
+ playing = _vm->_video->nextElement(_hnmContext);
if (specialTextMode)
displayHNMSubtitles();
else
@@ -6270,7 +6271,7 @@ void EdenGame::showMovie(char arg1) {
void EdenGame::playHNM(int16 num) {
perso_t *perso = nullptr;
int16 oldDialogType = -1;
- p_global->curVideoNum = num;
+ _vm->_video->curVideoNum = num;
if (num != 2001 && num != 2012 && num != 98 && num != 171) {
byte oldMusicType = p_global->newMusicType;
p_global->newMusicType = MusicType::mtEvent;
@@ -6289,8 +6290,8 @@ void EdenGame::playHNM(int16 num) {
showVideoSubtitle = false;
videoCanceled = 0;
shnmfl(num);
- CLHNM_Reset(_hnmContext);
- CLHNM_FlushPreloadBuffer(_hnmContext);
+ _vm->_video->reset(_hnmContext);
+ _vm->_video->flushPreloadBuffer(_hnmContext);
if (needToFade) {
fadetoblack(4);
ClearScreen();
@@ -6311,15 +6312,15 @@ void EdenGame::playHNM(int16 num) {
}
if (videoCanceled)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
- if (p_global->curVideoNum == 167)
+ if (_vm->_video->curVideoNum == 167)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
- if (p_global->curVideoNum == 104)
+ if (_vm->_video->curVideoNum == 104)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
- if (p_global->curVideoNum == 102)
+ if (_vm->_video->curVideoNum == 102)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
- if (p_global->curVideoNum == 77)
+ if (_vm->_video->curVideoNum == 77)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
- if (p_global->curVideoNum == 149)
+ if (_vm->_video->curVideoNum == 149)
p_global->ff_F1 = RoomFlags::rf40 | RoomFlags::rf04 | RoomFlags::rf01;
}
@@ -6327,7 +6328,7 @@ void EdenGame::playHNM(int16 num) {
void EdenGame::displayHNMSubtitles() {
int16 *frames;
perso_t *perso;
- switch (p_global->curVideoNum) {
+ switch (_vm->_video->curVideoNum) {
case 170:
frames = kFramesVid170;
perso = &kPersons[PER_UNKN_156];
diff --git a/engines/cryo/module.mk b/engines/cryo/module.mk
index deb2a71398..bc47aea777 100644
--- a/engines/cryo/module.mk
+++ b/engines/cryo/module.mk
@@ -9,7 +9,8 @@ MODULE_OBJS = \
eden.o \
cryo.o \
detection.o \
- staticdata.o
+ staticdata.o \
+ video.o
# This module can be built as a plugin
ifeq ($(ENABLE_CRYO), DYNAMIC_PLUGIN)
diff --git a/engines/cryo/video.cpp b/engines/cryo/video.cpp
new file mode 100644
index 0000000000..ab2bf4efc1
--- /dev/null
+++ b/engines/cryo/video.cpp
@@ -0,0 +1,289 @@
+/* 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 "cryo/cryo.h"
+#include "cryo/video.h"
+
+namespace Cryo {
+HnmPlayer::HnmPlayer(CryoEngine *vm) : _vm(vm) {
+ curVideoNum = 0;
+ sound_started = false;
+ pending_sounds = 0;
+ time_drift = 0.0;
+ next_frame_time = 0.0;
+ expected_frame_time = 0.0;
+ hnm_rate = 0.0;
+ use_sound_sync = false;
+ use_sound = false;
+ soundChannel = nullptr;
+ soundGroup = nullptr;
+ soundChannel_adpcm = nullptr;
+ soundGroup_adpcm = nullptr;
+ pred_r = pred_l = 0;
+ use_adpcm = false;
+ custom_chunk_handler = nullptr;
+ preserve_color0 = false;
+
+ for (int i = 0; i < 256; i++)
+ decomp_table[i] = 0;
+}
+
+// Original name: CLHNM_SetupTimer
+void HnmPlayer::setupTimer(float rate) {
+ hnm_rate = 100.0 / rate;
+}
+
+// Original name: CLHNM_ResetInternalTimer
+void HnmPlayer::resetInternalTimer() {
+ time_drift = 0.0;
+ next_frame_time = expected_frame_time = TimerTicks;
+}
+
+// Original name: CLHNM_Reset
+void HnmPlayer::reset(hnm_t *hnm) {
+ hnm->_frameNum = 0;
+ hnm->ff_4 = 0;
+ hnm->_totalRead = 0;
+ sound_started = false;
+ pending_sounds = 0;
+ resetInternalTimer();
+}
+
+// Original name: CLHNM_Init
+void HnmPlayer::init() {
+ custom_chunk_handler = nullptr;
+ preserve_color0 = false;
+}
+
+// Original name: CLHNM_SetForceZero2Black
+void HnmPlayer::setForceZero2Black(bool forceblack) {
+ preserve_color0 = forceblack;
+}
+
+// Original name: CLHNM_WaitLoop
+void HnmPlayer::waitLoop(hnm_t *hnm) {
+ expected_frame_time += hnm_rate;
+ next_frame_time = expected_frame_time - time_drift;
+ if (use_sound_sync && TimerTicks > 1000.0 + next_frame_time)
+ use_sound = false;
+ while (TimerTicks < next_frame_time) ; // waste time
+ time_drift = TimerTicks - next_frame_time;
+}
+
+// Original name: CLHNM_WantsSound
+void HnmPlayer::wantsSound(bool sound) {
+ use_sound = sound;
+}
+
+// Original name: CLHNM_SetupSound
+void HnmPlayer::setupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode) {
+ soundChannel = CLSoundChannel_New(mode);
+ soundGroup = CLSoundGroup_New(numSounds, length, sampleSize, rate, mode);
+ if (sampleSize == 16)
+ CLSoundGroup_Reverse16All(soundGroup);
+}
+
+// Original name: CLHNM_SetupSoundADPCM
+void HnmPlayer::setupSoundADPCM(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode) {
+ soundChannel_adpcm = CLSoundChannel_New(mode);
+ soundGroup_adpcm = CLSoundGroup_New(numSounds, length, sampleSize, rate, mode);
+}
+
+// Original name: CLHNM_SoundInADPCM
+void HnmPlayer::soundInADPCM(bool isAdpcm) {
+ use_adpcm = isAdpcm;
+}
+
+// Original name: CLHNM_CloseSound
+void HnmPlayer::closeSound() {
+ if (soundChannel) {
+ CLSoundChannel_Stop(soundChannel);
+ CLSoundChannel_Free(soundChannel);
+ soundChannel = nullptr;
+ }
+ if (soundGroup) {
+ CLSoundGroup_Free(soundGroup);
+ soundGroup = nullptr;
+ }
+ if (soundChannel_adpcm) {
+ CLSoundChannel_Stop(soundChannel_adpcm);
+ CLSoundChannel_Free(soundChannel_adpcm);
+ soundChannel = nullptr;
+ }
+ if (soundGroup_adpcm) {
+ CLSoundGroup_Free(soundGroup_adpcm);
+ soundGroup = nullptr;
+ }
+}
+
+// Original name: CLHNM_LoadDecompTable
+void HnmPlayer::loadDecompTable(int16 *buffer) {
+ for (int16 i = 0; i < 256; i++) {
+ int16 e = *buffer++;
+ decomp_table[i] = LE16(e);
+ }
+}
+
+// Original name: CLHNM_DecompADPCM
+void HnmPlayer::decompADPCM(byte *buffer, int16 *output, int size) {
+ int16 l = pred_l;
+ int16 r = pred_r;
+ size &= ~1;
+ while (size--) {
+ *output++ = l += decomp_table[*buffer++];
+ *output++ = r += decomp_table[*buffer++];
+ if (l > 512 || r > 512)
+ error("CLHNM_DecompADPCM - Unexpected values");
+ }
+ pred_l = l;
+ pred_r = r;
+}
+
+// Original name: CLHNM_NextElement
+bool HnmPlayer::nextElement(hnm_t *hnm) {
+ int sz;
+ int16 id;
+ char h6, h7;
+ int16 i;
+ if (hnm->_frameNum == 0) {
+ resetInternalTimer();
+ pred_l = pred_r = 0;
+ }
+ if (hnm->_frameNum == hnm->_header._numbFrame)
+ return false;
+
+ if (!CLHNM_LoadFrame(hnm))
+ return false;
+
+ for (;;) {
+ sz = PLE32(hnm->_dataPtr) & 0xFFFFFF;
+ hnm->_dataPtr += 4;
+ id = *(int16 *)hnm->_dataPtr;
+ hnm->_dataPtr += 2;
+ h6 = *hnm->_dataPtr;
+ hnm->_dataPtr += 1;
+ h7 = *hnm->_dataPtr;
+ hnm->_dataPtr += 1;
+ hnm->_chunkId = id;
+ switch (id) {
+ case BE16('PL'):
+ CLHNM_ChangePalette(hnm);
+ hnm->_dataPtr += sz - 8;
+ break;
+ case BE16('IZ'):
+ hnm->_frameNum++;
+ CLHNM_SelectBuffers(hnm);
+ CLHNM_DecompLempelZiv(hnm->_dataPtr + 4, hnm->_newFrameBuffer);
+ switch (hnm->_header._width) {
+ // case 320: CLBlitter_RawCopy320ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
+ // case 480: CLBlitter_RawCopy480ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
+ // case 640: CLBlitter_RawCopy640ASM(hnm->new_frame_buffer, hnm->old_frame_buffer, hnm->header.height); break;
+ // default: memcpy(hnm->old_frame_buffer, hnm->new_frame_buffer, hnm->header.width * hnm->header.height);
+ default:
+ memcpy(hnm->_oldFrameBuffer, hnm->_newFrameBuffer, hnm->_header._bufferSize); //TODO strange buffer size here
+ }
+ if (!(h6 & 1))
+ CLHNM_Desentrelace(hnm);
+ else {
+ // if(hnm->header.width == 640)
+ // CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
+ // else
+ memcpy(hnm->finalBuffer, hnm->_newFrameBuffer, hnm->_header._height); //TODO: wrong size?
+ }
+ if (use_adpcm) {
+ if (!sound_started) {
+ for (i = 0; i < pending_sounds; i++)
+ CLSoundGroup_PlayNextSample(soundGroup_adpcm, soundChannel);
+ sound_started = true;
+ }
+ } else if (!sound_started) {
+ for (i = 0; i < pending_sounds; i++)
+ CLSoundGroup_PlayNextSample(soundGroup, soundChannel);
+ sound_started = true;
+ }
+
+ return true;
+ case BE16('IU'):
+ hnm->_frameNum++;
+ CLHNM_SelectBuffers(hnm);
+ CLHNM_DecompUBA(hnm->_newFrameBuffer, hnm->_newFrameBuffer, hnm->_oldFrameBuffer, hnm->_dataPtr, hnm->_header._width, h6);
+ if (!(h6 & 1))
+ CLHNM_Desentrelace(hnm);
+ else {
+ // if(hnm->header.width == 640)
+ // CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
+ // else
+ memcpy(hnm->finalBuffer, hnm->_newFrameBuffer, hnm->_header._width * hnm->_header._height);
+ }
+ return true;
+
+ case BE16('sd'):
+ case BE16('SD'):
+ if (use_sound) {
+ if (!h6) {
+ int sound_size = sz - 8;
+ if (!use_adpcm) {
+ CLSoundGroup_SetDatas(soundGroup, hnm->_dataPtr, sound_size - 2, false);
+ if (sound_started)
+ CLSoundGroup_PlayNextSample(soundGroup, soundChannel);
+ else
+ pending_sounds++;
+ } else {
+ int16 *sound_buffer = (int16 *)CLSoundGroup_GetNextBuffer(soundGroup_adpcm);
+ if (!pending_sounds) {
+ const int kDecompTableSize = 256 * sizeof(int16);
+ loadDecompTable((int16 *)hnm->_dataPtr);
+ decompADPCM(hnm->_dataPtr + kDecompTableSize, sound_buffer, sound_size - kDecompTableSize);
+ CLSoundGroup_AssignDatas(soundGroup_adpcm, sound_buffer, (sound_size - kDecompTableSize) * 2, false);
+ } else {
+ decompADPCM(hnm->_dataPtr, sound_buffer, sound_size);
+ CLSoundGroup_AssignDatas(soundGroup_adpcm, sound_buffer, sound_size * 2, false);
+ }
+ pending_sounds++;
+ if (sound_started)
+ CLSoundGroup_PlayNextSample(soundGroup_adpcm, soundChannel);
+ }
+ } else
+ error("CLHNM_NextElement - unexpected flag");
+ }
+ hnm->_dataPtr += sz - 8;
+ break;
+ default:
+ if (custom_chunk_handler)
+ custom_chunk_handler(hnm->_dataPtr, sz - 8, id, h6, h7);
+ hnm->_dataPtr += sz - 8;
+ }
+ }
+ return true;
+}
+
+// Original name: CLHNM_GetSoundChannel
+soundchannel_t *HnmPlayer::getSoundChannel() {
+ return soundChannel;
+}
+
+// Original name: CLHNM_FlushPreloadBuffer
+void HnmPlayer::flushPreloadBuffer(hnm_t *hnm) {
+}
+
+} // namespace Cryo
+
diff --git a/engines/cryo/video.h b/engines/cryo/video.h
new file mode 100644
index 0000000000..b574fe0ec8
--- /dev/null
+++ b/engines/cryo/video.h
@@ -0,0 +1,81 @@
+/* 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 CRYO_VIDEO_H
+#define CRYO_VIDEO_H
+
+namespace Cryo {
+
+class CryoEngine;
+
+class HnmPlayer {
+private:
+ CryoEngine *_vm;
+
+ void resetInternalTimer();
+ void wantsSound(bool sound);
+ void decompADPCM(byte *buffer, int16 *output, int size);
+ void loadDecompTable(int16 *buffer);
+ void soundInADPCM(bool is_adpcm); // Unused
+
+ bool sound_started;
+ int16 pending_sounds;
+ float time_drift;
+ float next_frame_time;
+ float expected_frame_time;
+ float hnm_rate;
+ bool use_sound_sync;
+ bool use_sound;
+ int16 pred_r;
+ int16 pred_l;
+ bool use_adpcm;
+ bool preserve_color0;
+ int16 decomp_table[256];
+
+ void (*custom_chunk_handler)(byte *buffer, int size, int16 id, char h6, char h7);
+
+ soundchannel_t *soundChannel;
+ soundgroup_t *soundGroup;
+ soundchannel_t *soundChannel_adpcm;
+ soundgroup_t *soundGroup_adpcm;
+
+public:
+ uint16 curVideoNum;
+
+ HnmPlayer(CryoEngine *vm);
+
+ void setupTimer(float rate);
+ void reset(hnm_t *hnm);
+ void closeSound();
+ void waitLoop(hnm_t *hnm);
+ void flushPreloadBuffer(hnm_t *hnm);
+ void setupSound(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode);
+ void setupSoundADPCM(int16 numSounds, int16 length, int16 sampleSize, float rate, int16 mode);
+ bool nextElement(hnm_t *hnm);
+ void init();
+ void setForceZero2Black(bool forceblack);
+ soundchannel_t *getSoundChannel();
+};
+
+} // End of namespace Cryo
+
+#endif