aboutsummaryrefslogtreecommitdiff
path: root/engines/cryo/video.cpp
diff options
context:
space:
mode:
authorStrangerke2016-11-27 14:45:28 -0800
committerEugene Sandulenko2017-01-25 22:42:08 +0100
commit61998c7a996a52e6988c48275e3a784aa9a2901a (patch)
treeb8a4b8792af26f4a343aa0df81c37932dda6a746 /engines/cryo/video.cpp
parentb735962436c2f33a877f623d92b61a4a46680fb3 (diff)
downloadscummvm-rg350-61998c7a996a52e6988c48275e3a784aa9a2901a.tar.gz
scummvm-rg350-61998c7a996a52e6988c48275e3a784aa9a2901a.tar.bz2
scummvm-rg350-61998c7a996a52e6988c48275e3a784aa9a2901a.zip
CRYO: Move some more functions to HnmPlayer
Diffstat (limited to 'engines/cryo/video.cpp')
-rw-r--r--engines/cryo/video.cpp373
1 files changed, 361 insertions, 12 deletions
diff --git a/engines/cryo/video.cpp b/engines/cryo/video.cpp
index ab2bf4efc1..128c9815ee 100644
--- a/engines/cryo/video.cpp
+++ b/engines/cryo/video.cpp
@@ -42,6 +42,7 @@ HnmPlayer::HnmPlayer(CryoEngine *vm) : _vm(vm) {
use_adpcm = false;
custom_chunk_handler = nullptr;
preserve_color0 = false;
+ safe_palette = false;
for (int i = 0; i < 256; i++)
decomp_table[i] = 0;
@@ -152,12 +153,286 @@ void HnmPlayer::decompADPCM(byte *buffer, int16 *output, int size) {
*output++ = l += decomp_table[*buffer++];
*output++ = r += decomp_table[*buffer++];
if (l > 512 || r > 512)
- error("CLHNM_DecompADPCM - Unexpected values");
+ error("decompADPCM - Unexpected values");
}
pred_l = l;
pred_r = r;
}
+// Original name: CLHNM_ReadHeader
+void HnmPlayer::readHeader(hnm_t *hnm) {
+ int32 size = sizeof(hnm->_header);
+ hnm->_file->read(&hnm->_header, size);
+
+ hnm->_header._width = LE16(hnm->_header._width);
+ hnm->_header._height = LE16(hnm->_header._height);
+ hnm->_header._unusedFileSize = LE32(hnm->_header._unusedFileSize);
+ hnm->_header._numbFrame = LE32(hnm->_header._numbFrame);
+ hnm->_header._unusedTableOffset = LE32(hnm->_header._unusedTableOffset);
+ hnm->_header._unusedSpeed = LE16(hnm->_header._unusedSpeed);
+ hnm->_header._unusedMaxBuffer = LE16(hnm->_header._unusedMaxBuffer);
+ hnm->_header._bufferSize = LE32(hnm->_header._bufferSize);
+ hnm->_header._unusedUnknown = LE16(hnm->_header._unusedUnknown);
+ hnm->_header._bufferSize += 4096; //TODO: checkme
+}
+
+// Original name: CLHNM_GetVersion
+int16 HnmPlayer::getVersion(hnm_t *hnm) {
+ if (hnm->_header._signature == BE32('HNM4'))
+ return 4;
+ return -1;
+}
+
+// Original name: CLHNM_AllocMemory
+void HnmPlayer::allocMemory(hnm_t *hnm) {
+ hnm->tmpBuffer[0] = (byte *)malloc(hnm->_header._bufferSize + 2);
+
+ if (!hnm->tmpBuffer[0])
+ return;
+
+ hnm->tmpBuffer[1] = (byte *)malloc(hnm->_header._bufferSize + 2);
+
+ if (!hnm->tmpBuffer[1]) {
+ free(hnm->tmpBuffer[0]);
+ hnm->tmpBuffer[0] = nullptr;
+ return;
+ }
+
+ hnm->_readBuffer = (byte *)malloc(hnm->_header._bufferSize + 2);
+ if (!hnm->_readBuffer) {
+ free(hnm->tmpBuffer[0]);
+ hnm->tmpBuffer[0] = nullptr;
+ free(hnm->tmpBuffer[1]);
+ hnm->tmpBuffer[1] = nullptr;
+ }
+}
+
+// Original name: CLHNM_DeallocMemory
+void HnmPlayer::deallocMemory(hnm_t *hnm) {
+ free(hnm->tmpBuffer[0]);
+ free(hnm->tmpBuffer[1]);
+ free(hnm->_readBuffer);
+
+ hnm->tmpBuffer[0] = nullptr;
+ hnm->tmpBuffer[1] = nullptr;
+ hnm->_readBuffer = nullptr;
+}
+
+// Original name: CLHNM_SetFinalBuffer
+void HnmPlayer::setFinalBuffer(hnm_t *hnm, byte *buffer) {
+ hnm->finalBuffer = buffer;
+}
+
+// Original name: CLHNM_GetFrameNum
+int HnmPlayer::getFrameNum(hnm_t *hnm) {
+ return hnm->_frameNum;
+}
+
+// Original name: CLHNM_TryRead
+void HnmPlayer::tryRead(hnm_t *hnm, int size) {
+ hnm->_file->read(hnm->_readBuffer, size);
+}
+
+// Original name: CLHNM_LoadFrame
+bool HnmPlayer::loadFrame(hnm_t *hnm) {
+ int chunk;
+ tryRead(hnm, 4);
+ chunk = *(int *)hnm->_readBuffer;
+ chunk = LE32(chunk);
+ chunk &= 0xFFFFFF; // upper bit - keyframe mark?
+ if (!chunk)
+ return false;
+
+ if (chunk - 4 > hnm->_header._bufferSize)
+ error("loadFrame - Chunk size");
+
+ tryRead(hnm, chunk - 4);
+ hnm->_dataPtr = hnm->_readBuffer;
+ hnm->_totalRead += chunk;
+ return true;
+}
+
+// Original name CLHNM_DecompLempelZiv
+void HnmPlayer::decompLempelZiv(byte *buffer, byte *output) {
+ byte *inp = buffer;
+ byte *out = output;
+
+ unsigned int queue = 0;
+ int qpos = -1;
+
+ //TODO: fix for BE
+#define GetBit() ( 1 & ( (qpos >= 0) ? (queue >> qpos--) : (queue = *(unsigned int*)((inp += 4) - 4)) >> ((qpos = 30) + 1) ) )
+
+ for (;;) {
+ if (GetBit()) {
+ *out++ = *inp++;
+ } else {
+ int l, o;
+ if (GetBit()) {
+ l = *inp & 7;
+ o = *(uint16 *)inp >> 3;
+ inp += 2;
+ o -= 8192;
+ if (!l)
+ l = *inp++;
+ if (!l)
+ break;
+ } else {
+ l = GetBit() * 2 + GetBit();
+ o = *(inp++) - 256;
+ }
+ l += 2;
+ while (l--) {
+ *out = *(out + o);
+ out++;
+ }
+ }
+ }
+
+#undef GetBit
+
+ return;
+}
+
+// Original name: CLHNM_Desentrelace320
+void HnmPlayer::desentrelace320(byte *frame_buffer, byte *final_buffer, uint16 height) {
+ unsigned int *input = (unsigned int *)frame_buffer;
+ unsigned int *line0 = (unsigned int *)final_buffer;
+ unsigned int *line1 = (unsigned int *)(final_buffer + 320);
+ int count = (height) / 2;
+ while (count--) {
+ int16 i;
+ for (i = 0; i < 320 / 4; i++) {
+ unsigned int p0 = *input++;
+ unsigned int p4 = *input++;
+#if 0
+ *line0++ = ((p4 & 0xFF00) >> 8) | ((p4 & 0xFF000000) >> 16) | ((p0 & 0xFF00) << 8) | (p0 & 0xFF000000);
+ // *line0++ = (p0 & 0xFF000000) | ((p0 & 0xFF00) << 8) | ((p4 & 0xFF000000) >> 16) | ((p4 & 0xFF00) >> 8);
+ *line1++ = ((p0 & 0xFF0000) << 8) | ((p0 & 0xFF) << 16) | ((p4 & 0xFF0000) >> 8) | (p4 & 0xFF);
+#else
+ *line0++ = (p0 & 0xFF) | ((p0 & 0xFF0000) >> 8) | ((p4 & 0xFF) << 16) | ((p4 & 0xFF0000) << 8);
+ *line1++ = ((p0 & 0xFF00) >> 8) | ((p0 & 0xFF000000) >> 16) | ((p4 & 0xFF00) << 8) | (p4 & 0xFF000000);
+#endif
+ }
+ line0 += 320 / 4;
+ line1 += 320 / 4;
+ }
+}
+
+// Original name: CLHNM_Desentrelace
+void HnmPlayer::desentrelace(hnm_t *hnm) {
+ switch (hnm->_header._width) {
+ case 320:
+ desentrelace320(hnm->_newFrameBuffer, hnm->finalBuffer, hnm->_header._height);
+ break;
+ // case 480:
+ // CLHNM_Desentrelace480(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
+ // break;
+ default:
+ error("desentrelace - Unexpected width");
+ }
+}
+
+// Original name: CLHNM_DecompUBA
+void HnmPlayer::decompUBA(byte *output, byte *curr_buffer, byte *prev_buffer, byte *input, int width, char flags) {
+ unsigned int code;
+ byte mode, count, color;
+ uint16 offs;
+ byte *ref;
+ byte *out_start = output;
+ byte swap;
+ int shft1, shft2;
+ // return;
+ if ((flags & 1) == 0) {
+ //HNM4 classic
+ int twolinesabove = -(width * 2);
+ for (;;) {
+ code = PLE32(input) & 0xFFFFFF; //input++;
+ count = code & 0x1F;
+ if (count) {
+ input += 3;
+ mode = (code >> 5) & 0xF;
+ offs = code >> 9;
+ //
+ swap = mode >> 3;
+ ref = ((mode & 1) ? prev_buffer : curr_buffer) + (output - out_start) + (offs * 2) - 32768;
+ if (mode & 2) {
+ // ref += twolinesabove;
+ shft1 = twolinesabove + 1;
+ shft2 = 0;
+ //swap ^= 1;
+ } else {
+ shft1 = 0;
+ shft2 = 1;
+ }
+ while (count--) {
+ byte b0 = ref[shft1];
+ byte b1 = ref[shft2];
+ output[swap] = b0;
+ output[swap ^ 1] = b1;
+ output += 2;
+ ref += (mode & 4) ? -2 : 2;
+ }
+ } else {
+ input++;
+ mode = code & 0xFF; // bits 0..4 are zero
+ switch (mode) {
+ case 0:
+ *(output++) = *(input++);
+ *(output++) = *(input++);
+ break;
+ case 0x20:
+ output += 2 * *(input++);
+ break;
+ case 0x40:
+ output += 2 * (code >> 8);
+ input += 2;
+ break;
+ case 0x60:
+ count = *(input++);
+ color = *(input++);
+ while (count--) {
+ *(output++) = color;
+ *(output++) = color;
+ }
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ } else {
+ assert(0);
+ //HNM4 hires
+ for (;;) {
+ code = PLE32(input) & 0xFFFFFF;
+ input++;
+ count = code & 0x3F;
+ if (count) {
+ mode = (code >> 5) & 0xF;
+ offs = code >> 9;
+ //
+ } else {
+ mode = code & 0xFF; // bits 0..5 are zero
+ switch (mode) {
+ case 0x00:
+ output += *input++;
+ break;
+ case 0x40:
+ *output++ = *input++;
+ *(output++ + width) = *input++;
+ break;
+ case 0x80:
+ output += width;
+ break;
+ default:
+ return;
+ }
+ }
+ }
+ }
+}
+
// Original name: CLHNM_NextElement
bool HnmPlayer::nextElement(hnm_t *hnm) {
int sz;
@@ -171,7 +446,7 @@ bool HnmPlayer::nextElement(hnm_t *hnm) {
if (hnm->_frameNum == hnm->_header._numbFrame)
return false;
- if (!CLHNM_LoadFrame(hnm))
+ if (!loadFrame(hnm))
return false;
for (;;) {
@@ -186,23 +461,23 @@ bool HnmPlayer::nextElement(hnm_t *hnm) {
hnm->_chunkId = id;
switch (id) {
case BE16('PL'):
- CLHNM_ChangePalette(hnm);
+ changePalette(hnm);
hnm->_dataPtr += sz - 8;
break;
case BE16('IZ'):
hnm->_frameNum++;
- CLHNM_SelectBuffers(hnm);
- CLHNM_DecompLempelZiv(hnm->_dataPtr + 4, hnm->_newFrameBuffer);
+ selectBuffers(hnm);
+ 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
+ default:
+ memcpy(hnm->_oldFrameBuffer, hnm->_newFrameBuffer, hnm->_header._bufferSize); //TODO strange buffer size here
}
if (!(h6 & 1))
- CLHNM_Desentrelace(hnm);
+ desentrelace(hnm);
else {
// if(hnm->header.width == 640)
// CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
@@ -224,10 +499,10 @@ bool HnmPlayer::nextElement(hnm_t *hnm) {
return true;
case BE16('IU'):
hnm->_frameNum++;
- CLHNM_SelectBuffers(hnm);
- CLHNM_DecompUBA(hnm->_newFrameBuffer, hnm->_newFrameBuffer, hnm->_oldFrameBuffer, hnm->_dataPtr, hnm->_header._width, h6);
+ selectBuffers(hnm);
+ decompUBA(hnm->_newFrameBuffer, hnm->_newFrameBuffer, hnm->_oldFrameBuffer, hnm->_dataPtr, hnm->_header._width, h6);
if (!(h6 & 1))
- CLHNM_Desentrelace(hnm);
+ desentrelace(hnm);
else {
// if(hnm->header.width == 640)
// CLBlitter_RawCopy640(hnm->new_frame_buffer, hnm->final_buffer, hnm->header.height);
@@ -263,7 +538,7 @@ bool HnmPlayer::nextElement(hnm_t *hnm) {
CLSoundGroup_PlayNextSample(soundGroup_adpcm, soundChannel);
}
} else
- error("CLHNM_NextElement - unexpected flag");
+ error("nextElement - unexpected flag");
}
hnm->_dataPtr += sz - 8;
break;
@@ -285,5 +560,79 @@ soundchannel_t *HnmPlayer::getSoundChannel() {
void HnmPlayer::flushPreloadBuffer(hnm_t *hnm) {
}
+// Original name: CLHNM_ChangePalette
+void HnmPlayer::changePalette(hnm_t *hnm) {
+ int16 mincolor, maxcolor;
+ uint16 fst, cnt;
+ byte *pal;
+ color_t *color;
+ CLPalette_GetLastPalette(hnm->_palette);
+ pal = hnm->_dataPtr;
+ if (*(uint16 *)pal == 0xFFFF)
+ return;
+ mincolor = 255;
+ maxcolor = 0;
+ do {
+ fst = *pal++;
+ cnt = *pal++;
+ if (cnt == 0)
+ cnt = 256;
+ debug("hnm: setting palette, fst = %d, cnt = %d, last = %d", fst, cnt, fst + cnt - 1);
+ assert(fst + cnt <= 256);
+ if (mincolor > fst)
+ mincolor = fst;
+ if (maxcolor < fst + cnt)
+ maxcolor = fst + cnt;
+ color = hnm->_palette + fst;
+ if (safe_palette) {
+ while (cnt--) {
+ byte r = *pal++;
+ byte g = *pal++;
+ byte b = *pal++;
+ int16 rr = r << 10;
+ int16 gg = g << 10;
+ int16 bb = b << 10;
+ if (color->r != rr || color->g != gg || color->b != bb)
+ CLBlitter_OneBlackFlash();
+ color->r = rr;
+ color->g = gg;
+ color->b = bb;
+ color++;
+ }
+ } else {
+ while (cnt--) {
+ byte r = *pal++;
+ byte g = *pal++;
+ byte b = *pal++;
+ color->r = r << 10;
+ color->g = g << 10;
+ color->b = b << 10;
+ color++;
+ }
+ }
+
+ } while (*(uint16 *)pal != 0xFFFF);
+#if 0
+ if (preserve_color0) {
+ hnm->palette[0].r = 0;
+ hnm->palette[0].g = 0;
+ hnm->palette[0].b = 0;
+ }
+#endif
+ // CLBlitter_Send2ScreenNextCopy(hnm->palette, mincolor, maxcolor - mincolor);
+ CLBlitter_Send2ScreenNextCopy(hnm->_palette, 0, 256);
+}
+
+// Original name: CLHNM_SelectBuffers
+void HnmPlayer::selectBuffers(hnm_t *hnm) {
+ if (hnm->_frameNum % 2) {
+ hnm->_newFrameBuffer = hnm->tmpBuffer[1];
+ hnm->_oldFrameBuffer = hnm->tmpBuffer[0];
+ } else {
+ hnm->_newFrameBuffer = hnm->tmpBuffer[0];
+ hnm->_oldFrameBuffer = hnm->tmpBuffer[1];
+ }
+}
+
} // namespace Cryo