aboutsummaryrefslogtreecommitdiff
path: root/gob/pack.cpp
diff options
context:
space:
mode:
authorEugene Sandulenko2005-04-05 15:07:40 +0000
committerEugene Sandulenko2005-04-05 15:07:40 +0000
commit1758c5b211a39c29a193546348e7cc6e7bc2e8c9 (patch)
tree225d803c62c79d6a6d95ada0096e8832e9e65044 /gob/pack.cpp
parentb399a052f1a60df4731aa15d330e1c0b759ed857 (diff)
downloadscummvm-rg350-1758c5b211a39c29a193546348e7cc6e7bc2e8c9.tar.gz
scummvm-rg350-1758c5b211a39c29a193546348e7cc6e7bc2e8c9.tar.bz2
scummvm-rg350-1758c5b211a39c29a193546348e7cc6e7bc2e8c9.zip
Initial checking of Gob engine
svn-id: r17388
Diffstat (limited to 'gob/pack.cpp')
-rw-r--r--gob/pack.cpp94
1 files changed, 94 insertions, 0 deletions
diff --git a/gob/pack.cpp b/gob/pack.cpp
new file mode 100644
index 0000000000..064321c5e9
--- /dev/null
+++ b/gob/pack.cpp
@@ -0,0 +1,94 @@
+/*
+** Gobliiins 1
+** Original game by CoktelVision
+**
+** Reverse engineered by Ivan Dubrov <WFrag@yandex.ru>
+**
+*/
+#include "gob/gob.h"
+#include "gob/pack.h"
+#include "gob/debug.h"
+
+namespace Gob {
+
+int32 unpackData(char *sourceBuf, char *destBuf) {
+ uint32 realSize;
+ uint32 counter;
+ uint16 cmd;
+ byte *src;
+ byte *dest;
+ byte *tmpBuf;
+ int16 off;
+ byte len;
+ byte i;
+ int16 j;
+ uint16 tmpIndex;
+
+ realSize = READ_LE_UINT32(sourceBuf);
+ counter = READ_LE_UINT32(sourceBuf);
+
+ tmpBuf = (byte *)malloc(4114);
+
+ /*
+ * Can use assembler unpacker for small blocks - for speed.
+ * Don't need this anymore :)
+ */
+ /*
+ * if(realSize < 65000)
+ * {
+ * asm_unpackData(sourceBuf, destBuf, tmpBuf);
+ * free(tmpBuf);
+ * return realSize;
+ * }
+ */
+
+ if (tmpBuf == 0)
+ return 0;
+
+ for (j = 0; j < 4078; j++)
+ tmpBuf[j] = 0x20;
+ tmpIndex = 4078;
+
+ src = (byte *)(sourceBuf + 4);
+ dest = (byte *)destBuf;
+
+ cmd = 0;
+ while (1) {
+ cmd >>= 1;
+ if ((cmd & 0x0100) == 0) {
+ cmd = *src | 0xff00;
+ src++;
+ }
+ if ((cmd & 1) != 0) { /* copy */
+ *dest++ = *src;
+ tmpBuf[tmpIndex] = *src;
+ src++;
+ tmpIndex++;
+ tmpIndex %= 4096;
+ counter--;
+ if (counter == 0)
+ break;
+ } else { /* copy string */
+
+ off = *src++;
+ off |= (*src & 0xf0) << 4;
+ len = (*src & 0x0f) + 3;
+ src++;
+ for (i = 0; i < len; i++) {
+ *dest++ = tmpBuf[(off + i) % 4096];
+ counter--;
+ if (counter == 0) {
+ free(tmpBuf);
+ return realSize;
+ }
+ tmpBuf[tmpIndex] = tmpBuf[(off + i) % 4096];
+ tmpIndex++;
+ tmpIndex %= 4096;
+ }
+ }
+ }
+ free(tmpBuf);
+ return realSize;
+}
+
+} // End of namespace Gob