aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-01-12 22:23:57 +1100
committerStrangerke2012-04-06 08:19:36 +0200
commite183f9f055c121d745a130d84dea0fa84a58fc66 (patch)
tree1b36bbce5885131e5a081db817aa440297fb8205
parent41ddc9958ae4d1256f392b9e92fff241566ab930 (diff)
downloadscummvm-rg350-e183f9f055c121d745a130d84dea0fa84a58fc66.tar.gz
scummvm-rg350-e183f9f055c121d745a130d84dea0fa84a58fc66.tar.bz2
scummvm-rg350-e183f9f055c121d745a130d84dea0fa84a58fc66.zip
MORTEVIELLE: Beginnings of code for picture decoding
-rw-r--r--engines/mortevielle/graphics.cpp261
-rw-r--r--engines/mortevielle/graphics.h54
-rw-r--r--engines/mortevielle/level15.cpp3
-rw-r--r--engines/mortevielle/module.mk1
-rw-r--r--engines/mortevielle/mort.cpp2
5 files changed, 319 insertions, 2 deletions
diff --git a/engines/mortevielle/graphics.cpp b/engines/mortevielle/graphics.cpp
new file mode 100644
index 0000000000..3df9001c3b
--- /dev/null
+++ b/engines/mortevielle/graphics.cpp
@@ -0,0 +1,261 @@
+/* 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 "mortevielle/graphics.h"
+
+namespace Mortevielle {
+
+#define INCR_TAIX { if (_xSize & 1) ++_xSize; }
+
+void GfxSurface::decode(const byte *pSrc) {
+ _width = _height = 0;
+ _var1 = *pSrc++;
+ _entryCount = *pSrc++;
+ pSrc += 2;
+
+ if (!_var1)
+ pSrc += 30;
+
+ // First run through the data to calculate starting offsets
+ const byte *p = pSrc;
+ int xOffset = 0xffff, yOffset = 0xffff;
+
+ for (int idx = 0; idx < _entryCount; ++idx) {
+ _xp = READ_BE_UINT16(p + 4);
+ if (_xp < xOffset)
+ _xOffset = _xp;
+
+ _yp = READ_BE_UINT16(p + 6);
+ if (_yp < _yOffset)
+ _yOffset = _yp;
+
+ // Move to next entry
+ int size = READ_BE_UINT16(p) + READ_BE_UINT16(p + 2);
+ if ((size % 2) == 1)
+ ++size;
+
+ p += size + 14;
+ }
+
+ // Temporary output buffer
+ byte outputBuffer[65536];
+ byte *pDest = &outputBuffer[0];
+ const byte *pSrcStart = pSrc;
+
+ byte table4140[256];
+ byte table7110[256];
+
+ // Main processing loop
+ do {
+ _var4 = READ_BE_UINT16(pSrc);
+ _var6 = READ_BE_UINT16(pSrc + 2);
+ _xp = READ_BE_UINT16(pSrc + 4) - _xOffset;
+ _yp = READ_BE_UINT16(pSrc + 6) - _yOffset;
+ pSrc += 8;
+
+ _varC = READ_BE_UINT16(pSrc);
+ _xSize = READ_BE_UINT16(pSrc + 2) + 1;
+ _ySize = READ_BE_UINT16(pSrc + 4) + 1;
+ majTtxTty();
+
+ _var15 = _var18 = 0;
+
+ int decomIndex = 0;
+ if (_varC >> 8) {
+ // Build up reference table
+ int tableOffset = 0;
+
+ if (_varC & 1) {
+ do {
+ _var12 = desanalyse(pSrc);
+ _var14 = desanalyse(pSrc);
+
+ int savedVar15 = _var15;
+ int savedVar18 = _var18;
+
+ do {
+ const byte *pTemp = pSrc;
+ _var15 = savedVar15;
+ _var18 = savedVar18;
+
+ assert(_var14 < 256);
+ for (int idx = 0; idx < _var14; ++idx, ++tableOffset)
+ table4140[tableOffset] = suiv(pTemp);
+ } while (--_var12 > 0);
+ } while (_var18 < (_var4 - 1));
+
+ } else {
+ assert(_var4 < 256);
+ for (int idx = 0; idx < _var4; ++idx)
+ table4140[idx] = suiv(pSrc);
+ }
+
+ if (_var15) {
+ ++pSrc;
+ _var15 = 0;
+ }
+ if ((_var4 + _var6) & 1)
+ ++pSrc;
+
+ tableOffset = 0;
+ _var18 = 0;
+
+ if (_varC & 2) {
+ do {
+ _var12 = desanalyse(pSrc);
+ _var18 = _var14 = desanalyse(pSrc);
+ if (_var15 & 1) {
+ ++pSrc;
+ ++_var18;
+ _var15 = 0;
+ }
+
+ const byte *pStart = pSrc;
+ do {
+ pSrc = pStart;
+ for (int idx = 0; idx < _var14; ++idx) {
+ table7110[tableOffset++] = *pSrc++;
+ }
+ } while (--_var12 > 0);
+ } while (_var18 < (_var6 - 1));
+ } else {
+ assert(_var6 < 256);
+ for (int idx = 0; idx < _var4; ++idx)
+ table7110[idx] = *pSrc++;
+ }
+
+ if (_var15)
+ ++pSrc;
+
+ pSrcStart = pSrc;
+ pDest = &outputBuffer[_yp * SCREEN_WIDTH + _xp];
+ pSrc = &table7110[0];
+ _var1A = _var18 = _var15 = 0;
+ decomIndex = _varC;
+ }
+
+ // Main decompression switch
+ switch (decomIndex) {
+ case 0:
+ // Draw rect at pos
+ pDest = &outputBuffer[_yp * SCREEN_WIDTH + _xp];
+ pSrcStart = pSrc;
+ INCR_TAIX;
+
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest += SCREEN_WIDTH) {
+ byte *pDestLine = pDest;
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *pDestLine++ = suiv(pSrc);
+ }
+ }
+
+ pSrc = pSrcStart + _var4 + ((_var4 & 1) ? 1 : 0);
+ break;
+
+ case 1:
+ // Draw rect alternating left to right, right to left
+ INCR_TAIX;
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr) {
+ if (yCtr % 2) {
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *pDest++ = suiv(pSrc);
+ }
+ } else {
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ *--pDest = suiv(pSrc);
+ }
+ }
+ pDest += SCREEN_WIDTH;
+ }
+ break;
+
+ case 2:
+ // Draw rect alternating top to bottom, bottom to top
+ INCR_TAIX;
+ for (int xCtr = 0; xCtr < _xSize; ++xCtr) {
+ if (xCtr % 2) {
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest += SCREEN_WIDTH) {
+ *pDest = suiv(pSrc);
+ }
+ } else {
+ for (int yCtr = 0; yCtr < _ySize; ++yCtr, pDest -= SCREEN_WIDTH) {
+ *pDest = suiv(pSrc);
+ }
+ }
+ ++pDest;
+ }
+ break;
+
+ case 3:
+ // Draw horizontal line?
+ _var1C = 2;
+ horizontal(pSrc, pDest);
+ break;
+ }
+
+ pSrc = pSrcStart;
+ } while (--_entryCount > 0);
+}
+
+void GfxSurface::majTtxTty() {
+ if (!_yp)
+ _width += _xSize;
+
+ if (!_xp)
+ _height += _ySize;
+}
+
+byte GfxSurface::suiv(const byte *&pSrc) {
+ int v = *pSrc;
+ if (_var15) {
+ ++pSrc;
+ ++_var18;
+ _var15 = 0;
+ return v & 0xf;
+ } else {
+ _var15 = ~(v >> 8);
+ return v >> 4;
+ }
+}
+
+int GfxSurface::desanalyse(const byte *&pSrc) {
+ int total = 0;
+ int v = suiv(pSrc);
+ if (!v) {
+ int v2;
+ do {
+ v2 = suiv(pSrc);
+ } while (v2 == 15);
+
+ total *= 15;
+ v = suiv(pSrc);
+ }
+
+ total += v;
+ return total;
+}
+
+void GfxSurface::horizontal(const byte *&pSrc, byte *&pDest) {
+
+}
+
+} // End of namespace Mortevielle
diff --git a/engines/mortevielle/graphics.h b/engines/mortevielle/graphics.h
new file mode 100644
index 0000000000..d3f64a01fe
--- /dev/null
+++ b/engines/mortevielle/graphics.h
@@ -0,0 +1,54 @@
+/* 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 MORTEVIELLE_GRAPHICS_H
+#define MORTEVIELLE_GRAPHICS_H
+
+#include "graphics/surface.h"
+#include "mortevielle/mortevielle.h"
+
+namespace Mortevielle {
+
+class GfxSurface: public Graphics::Surface {
+private:
+ int _var1;
+ int _entryCount;
+ int _var4, _var6;
+ int _xp, _yp;
+ int _varC, _xSize, _ySize, _var12;
+ int _var14, _var15, _var18, _var1A;
+ int _var1C, _var1E, _var20, _var22;
+ int _var24, _var26, _var28;
+ int _width, _height;
+ int _xOffset, _yOffset;
+
+ void majTtxTty();
+ byte suiv(const byte *&pSrc);
+ int desanalyse(const byte *&pSrc);
+ void horizontal(const byte *&pSrc, byte *&pDest);
+public:
+ void decode(const byte *pSrc);
+};
+
+} // End of namespace Mortevielle
+
+#endif
diff --git a/engines/mortevielle/level15.cpp b/engines/mortevielle/level15.cpp
index 86319e0e07..073b93fd96 100644
--- a/engines/mortevielle/level15.cpp
+++ b/engines/mortevielle/level15.cpp
@@ -98,10 +98,11 @@ void writepal(int n) {
void pictout(int seg, int dep, int x, int y) {
+#ifdef DEBUG
GfxSurface surface;
surface.decode(&mem[0x7000 * 16]);
+#endif
-warning("TODO: complete picture decoding");
decomp(seg, dep);
if (gd == her) {
mem[0x7000 * 16 + 2] = 0;
diff --git a/engines/mortevielle/module.mk b/engines/mortevielle/module.mk
index 21cb02587a..327c4ba3c9 100644
--- a/engines/mortevielle/module.mk
+++ b/engines/mortevielle/module.mk
@@ -8,6 +8,7 @@ MODULE_OBJS := \
detection.o \
disk.o \
droite.o \
+ graphics.o \
keyboard.o \
level15.o \
menu.o \
diff --git a/engines/mortevielle/mort.cpp b/engines/mortevielle/mort.cpp
index 9b05196ab9..e24e9b58f9 100644
--- a/engines/mortevielle/mort.cpp
+++ b/engines/mortevielle/mort.cpp
@@ -71,7 +71,7 @@ int mortevielle_main(int argc, const char *argv[]) {
/*init_debug;*/
/* ecri_seg;*/
//pio_initialize(argc, argv);
- gd = cga;
+ gd = ega;
newgd = gd;
zuul = false;
tesok = false;