aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-09-09 19:55:05 +1000
committerPaul Gilbert2012-09-09 19:55:05 +1000
commit97e84b2169e8f3084e568776b1a9561a2df6878e (patch)
treee70cab3661314615ab0b123ef6654f18e7cc954f
parent42a09f00b336ce3405ff7558719f07e6f15326aa (diff)
downloadscummvm-rg350-97e84b2169e8f3084e568776b1a9561a2df6878e.tar.gz
scummvm-rg350-97e84b2169e8f3084e568776b1a9561a2df6878e.tar.bz2
scummvm-rg350-97e84b2169e8f3084e568776b1a9561a2df6878e.zip
HOPKINS: Implemented image loading code
-rw-r--r--engines/hopkins/files.cpp161
-rw-r--r--engines/hopkins/files.h1
-rw-r--r--engines/hopkins/globals.cpp7
-rw-r--r--engines/hopkins/globals.h5
-rw-r--r--engines/hopkins/graphics.cpp710
-rw-r--r--engines/hopkins/graphics.h64
-rw-r--r--engines/hopkins/hopkins.cpp9
-rw-r--r--engines/hopkins/hopkins.h5
8 files changed, 844 insertions, 118 deletions
diff --git a/engines/hopkins/files.cpp b/engines/hopkins/files.cpp
index cf6c06f22c..565143d3ff 100644
--- a/engines/hopkins/files.cpp
+++ b/engines/hopkins/files.cpp
@@ -163,4 +163,165 @@ byte *FileManager::LIBERE_FICHIER(byte *ptr) {
return PTRNUL;
}
+bool FileManager::RECHERCHE_CAT(const Common::String &file, int a2) {
+ byte *ptr; // [sp+1Ch] [bp-40h]@0
+ Common::File f;
+
+ switch (a2) {
+ case 1:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_INI.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_INI.RES");
+ break;
+
+ case 2:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_REP.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_REP.RES");
+ break;
+
+ case 3:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_LIN.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_LIN.RES");
+ break;
+
+ case 4:
+ CONSTRUIT_FICHIER(GLOBALS.HOPANIM, "RES_ANI.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ CONSTRUIT_FICHIER(GLOBALS.HOPANIM, "RES_ANI.RES");
+ break;
+
+ case 5:
+ CONSTRUIT_FICHIER(GLOBALS.HOPANIM, "RES_PER.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ CONSTRUIT_FICHIER(GLOBALS.HOPANIM, "RES_PER.RES");
+ break;
+
+ case 6:
+ CONSTRUIT_FICHIER(GLOBALS.HOPIMAGE, "PIC.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ break;
+
+ case 7:
+ CONSTRUIT_FICHIER(GLOBALS.HOPANIM, "RES_SAN.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ break;
+
+ case 8:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_SLI.CAT");
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ break;
+
+ case 9:
+ switch (GLOBALS.FR) {
+ case 0:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_VAN.CAT");
+ break;
+ case 1:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_VFR.CAT");
+ break;
+ case 2:
+ CONSTRUIT_FICHIER(GLOBALS.HOPLINK, "RES_VES.CAT");
+ break;
+ }
+
+ if (!f.exists(GLOBALS.NFICHIER))
+ return PTRNUL;
+
+ ptr = CHARGE_FICHIER(GLOBALS.NFICHIER);
+ break;
+ // Deliberate fall-through to
+ default:
+ break;
+ }
+
+ // Scan for an entry in the catalogue
+ const byte *startP = ptr;
+ int result; // eax@50
+ void *v22; // ebx@53
+ bool matchFlag = false;
+ int offsetVal = 0;
+
+ do {
+ Common::String name = (const char *)startP;
+
+ if (file == name) {
+ // Found entry for file, so get it's details from the catalogue entry
+ const byte *pData = startP + offsetVal;
+ startP += offsetVal + 15;
+ GLOBALS.CAT_POSI = READ_LE_UINT32(pData + 15);
+ GLOBALS.CAT_TAILLE = READ_LE_UINT32(pData + 19);
+ matchFlag = true;
+ }
+
+ const char *finishString = "FINIS";
+ const char *nameP = name.c_str();
+ int finishRemainingChars = 6;
+ int v19 = 0;
+ bool finishMatch = true;
+
+ do {
+ if (!finishRemainingChars)
+ break;
+ finishMatch = *finishString++ == *nameP++;
+ --finishRemainingChars;
+ } while (finishMatch);
+
+ if (!finishMatch)
+ v19 = *(byte *)(finishString - 1) - *(byte *)(nameP - 1);
+ if (!v19) {
+ GLOBALS.dos_free2(ptr);
+ return PTRNUL;
+ }
+
+ offsetVal += 23;
+ } while (!matchFlag);
+ GLOBALS.dos_free2(ptr);
+
+ // TODO: Double check whether this really should be an unsigned int comparison
+ if ((uint16)(a2 - 6) > 1 && (uint16)(a2 - 8) > 1) {
+ if (!f.open(GLOBALS.NFICHIER))
+ error("CHARGE_FICHIER");
+
+ f.seek(GLOBALS.CAT_POSI);
+
+ byte *catData = GLOBALS.dos_malloc2(GLOBALS.CAT_TAILLE);
+ if (catData == PTRNUL)
+ error("CHARGE_FICHIER");
+
+ bload_it(f, catData, GLOBALS.CAT_TAILLE);
+ f.close();
+ result = true;
+ } else {
+ result = false;
+ }
+
+ return result;
+}
+
} // End of namespace Hopkins
diff --git a/engines/hopkins/files.h b/engines/hopkins/files.h
index 52412c11e8..8c8f01004d 100644
--- a/engines/hopkins/files.h
+++ b/engines/hopkins/files.h
@@ -43,6 +43,7 @@ public:
static int CONSTRUIT_SYSTEM(const Common::String &file);
static void CONSTRUIT_FICHIER(const Common::String &hop, const Common::String &file);
static byte *LIBERE_FICHIER(byte *ptr);
+ static bool RECHERCHE_CAT(const Common::String &file, int a2);
};
} // End of namespace Hopkins
diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp
index 1f00651f9c..a04387e3a4 100644
--- a/engines/hopkins/globals.cpp
+++ b/engines/hopkins/globals.cpp
@@ -30,8 +30,6 @@ namespace Hopkins {
Globals::Globals() {
FR = 0;
SVGA = 2;
- MANU_SCROLL = 1;
- SPEED_SCROLL = 16;
internet = 1;
PUBEXIT = 0;
FADESPD = 15;
@@ -658,4 +656,9 @@ byte *Globals::dos_malloc2(int count) {
return result;
}
+byte *Globals::dos_free2(byte *p) {
+ free(p);
+ return PTRNUL;
+}
+
} // End of namespace Hopkins
diff --git a/engines/hopkins/globals.h b/engines/hopkins/globals.h
index 3289a49575..8a10315cf7 100644
--- a/engines/hopkins/globals.h
+++ b/engines/hopkins/globals.h
@@ -111,8 +111,6 @@ public:
int FADESPD;
int FR;
int SVGA;
- int MANU_SCROLL;
- int SPEED_SCROLL;
int internet;
int PUBEXIT;
bool XFULLSCREEN;
@@ -202,6 +200,8 @@ public:
int OBJL, OBJH;
int Nouv_objet;
int HELICO;
+ uint32 CAT_POSI;
+ uint32 CAT_TAILLE;
Globals();
~Globals();
@@ -213,6 +213,7 @@ public:
void INIT_VBOB();
void CHARGE_OBJET();
byte *dos_malloc2(int count);
+ byte *dos_free2(byte *p);
};
#define PTRNUL (byte *)NULL
diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp
index 21c5d6c478..385d9f46e8 100644
--- a/engines/hopkins/graphics.cpp
+++ b/engines/hopkins/graphics.cpp
@@ -21,6 +21,7 @@
*/
#include "common/system.h"
+#include "common/file.h"
#include "common/rect.h"
#include "engines/util.h"
#include "hopkins/files.h"
@@ -30,6 +31,614 @@
namespace Hopkins {
+GraphicsManager::GraphicsManager() {
+ SDL_MODEYES = false;
+ MANU_SCROLL = 1;
+ SPEED_SCROLL = 16;
+ Agr_x = Agr_y = 0;
+ Agr_Flag_x = Agr_Flag_y = 0;
+}
+
+GraphicsManager::~GraphicsManager() {
+}
+
+
+void GraphicsManager::SET_MODE(int width, int height) {
+ if (!SDL_MODEYES) {
+ SDL_ECHELLE = 0;
+
+ if (GLOBALS.XSETMODE == 1)
+ SDL_ECHELLE = 0;
+ if (GLOBALS.XSETMODE == 2)
+ SDL_ECHELLE = 25;
+ if (GLOBALS.XSETMODE == 3)
+ SDL_ECHELLE = 50;
+ if (GLOBALS.XSETMODE == 4)
+ SDL_ECHELLE = 75;
+ if (GLOBALS.XSETMODE == 5)
+ SDL_ECHELLE = GLOBALS.XZOOM;
+
+ int bpp = 8;
+ if (GLOBALS.XFORCE8 == 1)
+ bpp = 8;
+ if (GLOBALS.XFORCE16 == 1)
+ bpp = 16;
+
+ if (SDL_ECHELLE) {
+ error("TODO: Implement zooming support");
+ //width = Reel_Zoom(width, SDL_ECHELLE);
+ //height = Reel_Zoom(height, SDL_ECHELLE);
+ }
+
+ if (bpp == 8) {
+ initGraphics(width, height, true);
+ } else {
+ Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
+ initGraphics(width, height, true, &pixelFormat);
+ }
+
+ // Init surfaces
+ //VESA_SCREEN = dos_malloc2(0x96000u);
+ //VESA_BUFFER = dos_malloc2(0x96000u);
+
+ VideoPtr = NULL;
+ XSCREEN = width;
+ YSCREEN = height;
+
+ Linear = true;
+ Winbpp = bpp;
+ WinScan = width;
+
+ PAL_PIXELS = SD_PIXELS;
+ nbrligne = width;
+
+ for (int idx = 0; idx < 256; ++idx) {
+ cmap[idx].r = cmap[idx].g = cmap[idx].b = 0;
+ }
+
+ SDL_MODEYES = true;
+ } else {
+ error("Called SET_MODE multiple times");
+ }
+}
+
+void GraphicsManager::DD_Lock() {
+ VideoPtr = g_system->lockScreen();
+}
+
+void GraphicsManager::DD_Unlock() {
+ g_system->unlockScreen();
+}
+
+void GraphicsManager::Cls_Video() {
+ assert(VideoPtr);
+
+ VideoPtr->fillRect(Common::Rect(0, 0, XSCREEN, YSCREEN), 0);
+}
+
+void GraphicsManager::LOAD_IMAGE(const Common::String &file) {
+ Common::String filename = Common::String::format("%s.PCX", file);
+ CHARGE_ECRAN(filename);
+ GraphicsManager::INIT_TABLE(165, 170, Palette);
+}
+
+void GraphicsManager::CHARGE_ECRAN(const Common::String &file) {
+ int v1;
+ byte *v4;
+ byte *v5;
+ Common::File f;
+
+ FileManager::DMESS1();
+
+ v1 = 1;
+ if (FileManager::RECHERCHE_CAT(file, 6)) {
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPIMAGE, file);
+ if (!f.open(GLOBALS.NFICHIER))
+ error("CHARGE_ECRAN - %s", file.c_str());
+
+ f.seek(0, SEEK_END);
+ f.close();
+ v1 = 0;
+ }
+
+ SCROLL_ECRAN(0);
+ A_PCXSCREEN_WIDTH_SCREEN_HEIGHT((byte *)VESA_SCREEN.pixels, file, Palette, v1);
+
+ SCROLL = 0;
+ OLD_SCROLL = 0;
+ Cls_Pal();
+
+ if (!DOUBLE_ECRAN) {
+ souris_max();
+ SCANLINE(SCREEN_WIDTH);
+ GLOBALS.max_x = SCREEN_WIDTH;
+ DD_Lock();
+ Cls_Video();
+ if (Winbpp == 2) {
+ if (SDL_ECHELLE)
+ m_scroll16A((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ else
+ m_scroll16((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ } else if (Winbpp == 1) {
+ if (!SDL_ECHELLE)
+ m_scroll2((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ else
+ m_scroll2A((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ }
+ } else {
+ SCANLINE(0x500u);
+ GLOBALS.max_x = SCREEN_WIDTH * 2;
+ DD_Lock();
+ Cls_Video();
+ DD_Unlock();
+
+ if (MANU_SCROLL == 1) {
+ DD_Lock();
+ if (Winbpp == 2) {
+ if (SDL_ECHELLE)
+ m_scroll16A((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ else
+ m_scroll16((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ }
+ if (Winbpp == 1) {
+ if (!SDL_ECHELLE)
+ m_scroll2((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ else
+ m_scroll2A((byte *)VESA_SCREEN.pixels, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0);
+ }
+
+ DD_Unlock();
+ }
+ }
+
+ v4 = (byte *)VESA_BUFFER.pixels;
+ v5 = (byte *)VESA_SCREEN.pixels;
+ memcpy(v4, v5, 614396);
+
+ v5 = (byte *)v5 + 614396;
+ v4 = (byte *)v4 + 614396;
+ WRITE_LE_UINT16(v4, READ_LE_UINT16(v5));
+ *((byte *)v4 + 2) = *((byte *)v5 + 2);
+}
+
+void GraphicsManager::INIT_TABLE(int a1, int a2, byte *a3) {
+ for (int idx = 0; idx < 256; ++idx)
+ TABLE_COUL[idx] = idx;
+
+ Trans_bloc(TABLE_COUL, a3, 256, a1, a2);
+
+ for (int idx = 0; idx < 256; ++idx) {
+ byte v = TABLE_COUL[idx];
+ if (v > 27)
+ TABLE_COUL[idx] = 0;
+ if (!v)
+ TABLE_COUL[idx] = 0;
+ }
+
+ TABLE_COUL[0] = 1;
+}
+
+int GraphicsManager::SCROLL_ECRAN(int amount) {
+ int result = CLIP(amount, 0, SCREEN_WIDTH);
+ start_x = result;
+ ofscroll = result;
+ SCROLL = result;
+ return result;
+}
+
+void GraphicsManager::Trans_bloc(byte *destP, byte *srcP, int count, int param1, int param2) {
+ byte *v5;
+ int v6;
+ int v7;
+ int v8;
+ unsigned int v11;
+ int v12;
+ int v13;
+ int v14;
+ int v15;
+ int v16;
+ int v17;
+ unsigned int v18;
+ char v19;
+ int v20;
+ bool breakFlag;
+
+ v5 = destP;
+ v6 = count - 1;
+ do {
+ breakFlag = v6;
+ v7 = *(byte *)v5++;
+ v8 = (unsigned int)(3 * v7);
+
+ // TODO: Ensure this is the right calculation
+ v11 = *(byte *)(v8 + srcP) + *(byte *)(v8 + srcP + 1)
+ + *(byte *)(v8 + srcP + 2);
+
+ v12 = 0;
+ for (;;) {
+ v13 = v12 + 1;
+ if ( v13 == 38 )
+ break;
+
+ v20 = v13;
+ v8 = 3 * v8;
+ v14 = *(byte *)(v8 + srcP);
+ v15 = v14;
+ v14 = *(byte *)(v8 + srcP + 1);
+ v16 = v14 + v15;
+ v14 = *(byte *)(v8 + srcP + 2);
+ v17 = v14 + v16;
+ v12 = v20;
+ v18 = param1 + v17;
+ if (v18 >= v11 && (unsigned int)(v18 - param2) <= v11) {
+ v19 = v20;
+ if (!v20)
+ v19 = 1;
+ *(byte *)(v5 - 1) = v19;
+ break;
+ }
+ }
+
+ v6 = breakFlag - 1;
+ } while ( !breakFlag);
+}
+
+// TODO: See if it's feasible and/or desirable to change this to use the Common PCX decoder
+void GraphicsManager::A_PCXSCREEN_WIDTH_SCREEN_HEIGHT(byte *surface, const Common::String &file, byte *palette, bool typeFlag) {
+ int filesize;
+ signed __int16 v6;
+ int v7;
+ __int16 v8;
+ int v9;
+ int v10;
+ int v11;
+ unsigned __int8 v12;
+ int v13;
+ int v14;
+ char v15;
+ int v18;
+ int v19;
+ int v20;
+ unsigned int v21;
+ int v22;
+ int32 v23;
+ byte *ptr;
+ Common::File f;
+
+ // Clear the passed surface
+ memset(surface, 0, SCREEN_WIDTH * 2 * SCREEN_HEIGHT);
+
+ if (typeFlag) {
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPIMAGE, "PIC.RES");
+ if (!f.open(GLOBALS.NFICHIER))
+ error("(nom)Erreur en cours de lecture.");
+ f.seek(GLOBALS.CAT_POSI);
+
+ v7 = GLOBALS.CAT_TAILLE - 896;
+ v8 = f.read(HEADER_PCX, 128);
+
+ v6 = READ_LE_UINT16(&HEADER_PCX[8]) + 1;
+ v20 = READ_LE_UINT16(&HEADER_PCX[10]) + 1;
+ if ((READ_LE_UINT16(&HEADER_PCX[8]) + 1) <= SCREEN_WIDTH) {
+ DOUBLE_ECRAN = false;
+ } else {
+ v6 = SCREEN_WIDTH * 2;
+ DOUBLE_ECRAN = true;
+ }
+ if (v20 > SCREEN_HEIGHT)
+ v20 = SCREEN_HEIGHT;
+ PCX_L = v6;
+ PCX_H = v20;
+ if (v8 == -1)
+ error("Erreur en cours de lecture.");
+ } else {
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPIMAGE, file);
+ if (!f.open(GLOBALS.NFICHIER))
+ error("(nom)Erreur en cours de lecture.");
+
+ filesize = f.size();
+ int bytesRead = f.read(HEADER_PCX, 128);
+ if (bytesRead < 128)
+ error("Erreur en cours de lecture.");
+
+ v6 = READ_LE_UINT16(&HEADER_PCX[8]) + 1;
+ v20 = READ_LE_UINT16(&HEADER_PCX[10]) + 1;
+ if (v6 <= SCREEN_WIDTH) {
+ DOUBLE_ECRAN = false;
+ } else {
+ v6 = SCREEN_WIDTH * 2;
+ DOUBLE_ECRAN = true;
+ }
+ if (v20 > SCREEN_HEIGHT)
+ v20 = SCREEN_HEIGHT;
+ PCX_L = v6;
+ PCX_H = v20;
+ v7 = filesize - 896;
+ }
+
+ ptr = GLOBALS.dos_malloc2(0xEE60u);
+ if (v7 >= 60000) {
+ v21 = v7 / 60000 + 1;
+ v23 = 60000 * (v7 / 60000) - v7;
+
+ if (((uint32)v23 & 0x80000000u) != 0)
+ v23 = -v23;
+ f.read(ptr, 60000);
+ v7 = 60000;
+ } else {
+ v21 = 1;
+ v23 = v7;
+ f.read(ptr, v7);
+ }
+ v22 = v21 - 1;
+ v18 = 0;
+ v9 = 0;
+ v10 = 0;
+ v19 = v6;
+
+ do {
+ if (v9 == v7) {
+ v9 = 0;
+ --v22;
+ v7 = 60000;
+ if ( !v22 )
+ v7 = v23;
+ v11 = v10;
+ f.read(ptr, v7);
+ v10 = v11;
+ }
+
+ v12 = *((byte *)ptr + v9++);
+ if (v12 > 0xC0u) {
+ v13 = v12 - 192;
+ if (v9 == v7) {
+ v9 = 0;
+ --v22;
+ v7 = 60000;
+ if ( v22 == 1 )
+ v7 = v23;
+ v14 = v10;
+ f.read(ptr, v7);
+ v10 = v14;
+ }
+ v15 = *((byte *)ptr + v9++);
+
+ do {
+ *((byte *)surface + v10++) = v15;
+ ++v18;
+ --v13;
+ } while (v13);
+ } else {
+ *((byte *)surface + v10++) = v12;
+ ++v18;
+ }
+ } while (v18 < v19 * v20);
+
+ if (typeFlag) {
+ f.seek(GLOBALS.CAT_TAILLE + GLOBALS.CAT_POSI - 768);
+ } else {
+ filesize = f.size();
+ f.seek(filesize - 768);
+ }
+
+ if (f.read(palette, PALETTE_SIZE * 3) != (PALETTE_SIZE * 3))
+ error("A_PCXSCREEN_WIDTH_SCREEN_HEIGHT");
+
+ f.close();
+ GLOBALS.dos_free2(ptr);
+}
+
+void GraphicsManager::Cls_Pal() {
+ warning("TODO");
+}
+void GraphicsManager::souris_max() {
+ warning("TODO");
+}
+
+void GraphicsManager::SCANLINE(int width) {
+ // Original has no implementatoin
+}
+
+void GraphicsManager::m_scroll(const byte *surface, int xs, int ys, int width, int height, int destX, int destY) {
+ const byte *v7;
+ byte *v8;
+ int v9;
+ int v10;
+ byte *v11;
+ const byte *v12;
+ unsigned int v13;
+
+ assert(VideoPtr);
+ v7 = xs + nbrligne2 * ys + surface;
+ v8 = destX + WinScan * destY + (byte *)VideoPtr->pixels;
+ v9 = height;
+ do {
+ v10 = v9;
+ memcpy((byte *)v8, (const byte *)v7, 4 * (width >> 2));
+ v12 = (const byte *)(v7 + 4 * (width >> 2));
+ v11 = (byte *)(v8 + 4 * (width >> 2));
+ v13 = width - 4 * (width >> 2);
+ memcpy(v11, v12, v13);
+ v8 = ((byte *)v11 + v13 + WinScan - width);
+ v7 = ((byte *)v12 + v13 + nbrligne2 - width);
+ v9 = v10 - 1;
+ } while (v10 != 1);
+}
+
+void GraphicsManager::m_scroll2(const byte *surface, int xs, int ys, int width, int height, int destX, int destY) {
+ const byte *v7;
+ byte *v8;
+ int v9;
+ int v10;
+ int v11;
+
+ assert(VideoPtr);
+ v7 = (const byte *)(xs + nbrligne2 * ys + surface);
+ v8 = (byte *)(destX + WinScan * destY + (byte *)VideoPtr->pixels);
+ v9 = WinScan - SCREEN_WIDTH;
+ v10 = nbrligne2 - SCREEN_WIDTH;
+ v11 = height;
+
+ do {
+ memcpy(v8, v7, SCREEN_WIDTH);
+ v8 = (byte *)v8 + v9 + SCREEN_WIDTH;
+ v7 = (const byte *)v7 + v10 + SCREEN_WIDTH;
+ --v11;
+ } while (v11);
+}
+
+void GraphicsManager::m_scroll2A(const byte *surface, int xs, int ys, int width, int height, int destX, int destY) {
+ const byte *v7;
+ const byte *v8;
+ int v9;
+ int v10;
+ byte v11;
+ const byte *v12;
+ const byte *v13;
+
+ assert(VideoPtr);
+ v7 = xs + nbrligne2 * ys + surface;
+ v8 = destX + WinScan * destY + (byte *)VideoPtr->pixels;
+ v9 = height;
+ Agr_x = 0;
+ Agr_y = 0;
+ Agr_Flag_y = 0;
+ do {
+ for (;;) {
+ v13 = v8;
+ v12 = v7;
+ v10 = width;
+ Agr_x = 0;
+ do {
+ v11 = *(byte *)v7;
+ *(byte *)v8++ = *(byte *)v7++;
+ Agr_x += SDL_ECHELLE;
+ if ((unsigned int)Agr_x >= 100) {
+ Agr_x -= 100;
+ *(byte *)v8++ = v11;
+ }
+ --v10;
+ } while ( v10 );
+
+ v7 = v12;
+ v8 = WinScan + v13;
+ if (Agr_Flag_y)
+ break;
+
+ Agr_y += SDL_ECHELLE;
+ if ((unsigned int)Agr_y < 100)
+ break;
+
+ Agr_y -= 100;
+ Agr_Flag_y = 1;
+ }
+
+ Agr_Flag_y = 0;
+ v7 = nbrligne2 + v12;
+ --v9;
+ } while (v9);
+}
+
+void GraphicsManager::m_scroll16(const byte *surface, int xs, int ys, int width, int height, int destX, int destY) {
+ const byte *v7;
+ const byte *v8;
+ int v9;
+ int v10;
+ const byte *v11;
+ int v12;
+ const byte *v13;
+ const byte *v14;
+
+ assert(VideoPtr);
+ v7 = xs + nbrligne2 * ys + surface;
+ v8 = destX + destX + WinScan * destY + (byte *)VideoPtr->pixels;
+ v9 = height;
+
+ do {
+ v14 = v8;
+ v13 = v7;
+ v10 = width;
+ v12 = v9;
+ v11 = PAL_PIXELS;
+
+ do {
+ *(uint16 *)v8 = *(uint16 *)(v11 + 2 * *(byte *)v7++);
+ v8 += 2;
+ --v10;
+ } while (v10);
+
+ v7 = nbrligne2 + v13;
+ v8 = WinScan + v14;
+ v9 = v12 - 1;
+ } while (v12 != 1);
+}
+
+void GraphicsManager::m_scroll16A(const byte *surface, int xs, int ys, int width, int height, int destX, int destY) {
+ const byte *v7;
+ const byte *v8;
+ int v9;
+ int v10;
+ const byte *v11;
+ int v12;
+ int v13;
+ const byte *v14;
+ const byte *v15;
+
+ assert(VideoPtr);
+ v7 = xs + nbrligne2 * ys + surface;
+ v8 = destX + destX + WinScan * destY + (byte *)VideoPtr->pixels;
+ v9 = height;
+ Agr_x = 0;
+ Agr_y = 0;
+ Agr_Flag_y = 0;
+
+ do {
+ for (;;) {
+ v15 = v8;
+ v14 = v7;
+ v10 = width;
+ v13 = v9;
+ v11 = PAL_PIXELS;
+ Agr_x = 0;
+
+ do {
+ v12 = *(uint16 *)(v11 + 2 * *(byte *)v7);
+ *(uint16 *)v8 = v12;
+ ++v7;
+ v8 += 2;
+ Agr_x += SDL_ECHELLE;
+ if ((unsigned int)Agr_x >= 100) {
+ Agr_x -= 100;
+ *(uint16 *)v8 = v12;
+ v8 += 2;
+ }
+
+ --v10;
+ } while (v10);
+
+ v9 = v13;
+ v7 = v14;
+ v8 = WinScan + v15;
+ if (Agr_Flag_y == 1)
+ break;
+
+ Agr_y += SDL_ECHELLE;
+
+ if ((unsigned int)Agr_y < 100)
+ break;
+
+ Agr_y -= 100;
+ Agr_Flag_y = 1;
+ }
+
+ Agr_Flag_y = 0;
+ v7 = nbrligne2 + v14;
+ v9 = v13 - 1;
+ } while (v13 != 1);
+}
+
+/*------------------------------------------------------------------------*/
+
byte *ObjectManager::CHANGE_OBJET(int objIndex) {
byte *result = ObjectManager::CAPTURE_OBJET(objIndex, 1);
GLOBALS.Bufferobjet = result;
@@ -43,23 +652,23 @@ byte *ObjectManager::CAPTURE_OBJET(int objIndex, int mode) {
byte *dataP;
dataP = 0;
- int v2 = GLOBALS.ObjetW[objIndex].field0;
- int v3 = GLOBALS.ObjetW[objIndex].field1;
+ int val1 = GLOBALS.ObjetW[objIndex].field0;
+ int val2 = GLOBALS.ObjetW[objIndex].field1;
if (mode == 1)
- ++v3;
- if (v2 != GLOBALS.NUM_FICHIER_OBJ) {
+ ++val2;
+ if (val1 != GLOBALS.NUM_FICHIER_OBJ) {
if (GLOBALS.ADR_FICHIER_OBJ != PTRNUL)
ObjectManager::DEL_FICHIER_OBJ();
- if (v2 == 1) {
+ if (val1 == 1) {
FileManager::CONSTRUIT_SYSTEM("OBJET1.SPR");
GLOBALS.ADR_FICHIER_OBJ = ObjectManager::CHARGE_SPRITE(GLOBALS.NFICHIER);
}
- GLOBALS.NUM_FICHIER_OBJ = v2;
+ GLOBALS.NUM_FICHIER_OBJ = val1;
}
- int width = ObjectManager::Get_Largeur(GLOBALS.ADR_FICHIER_OBJ, v3);
- int height = ObjectManager::Get_Hauteur(GLOBALS.ADR_FICHIER_OBJ, v3);
+ int width = ObjectManager::Get_Largeur(GLOBALS.ADR_FICHIER_OBJ, val2);
+ int height = ObjectManager::Get_Hauteur(GLOBALS.ADR_FICHIER_OBJ, val2);
GLOBALS.OBJL = width;
GLOBALS.OBJH = height;
@@ -69,16 +678,16 @@ byte *ObjectManager::CAPTURE_OBJET(int objIndex, int mode) {
if (dataP == PTRNUL)
error("CAPTURE_OBJET");
- ObjectManager::capture_mem_sprite(GLOBALS.ADR_FICHIER_OBJ, dataP, v3);
+ ObjectManager::capture_mem_sprite(GLOBALS.ADR_FICHIER_OBJ, dataP, val2);
break;
case 1:
- ObjectManager::sprite_alone(GLOBALS.ADR_FICHIER_OBJ, GLOBALS.Bufferobjet, v3);
+ ObjectManager::sprite_alone(GLOBALS.ADR_FICHIER_OBJ, GLOBALS.Bufferobjet, val2);
result = GLOBALS.Bufferobjet;
break;
case 3:
- ObjectManager::capture_mem_sprite(GLOBALS.ADR_FICHIER_OBJ, GLOBALS.INVENTAIRE_OBJET, v3);
+ ObjectManager::capture_mem_sprite(GLOBALS.ADR_FICHIER_OBJ, GLOBALS.INVENTAIRE_OBJET, val2);
result = GLOBALS.INVENTAIRE_OBJET;
break;
@@ -162,83 +771,4 @@ int ObjectManager::AJOUTE_OBJET(int objIndex) {
return arrIndex;
}
-/*------------------------------------------------------------------------*/
-
-GraphicsManager::GraphicsManager() {
- SDL_MODEYES = false;
-}
-
-GraphicsManager::~GraphicsManager() {
-}
-
-
-void GraphicsManager::SET_MODE(int width, int height) {
- if (!SDL_MODEYES) {
- SDL_ECHELLE = 0;
-
- if (GLOBALS.XSETMODE == 1)
- SDL_ECHELLE = 0;
- if (GLOBALS.XSETMODE == 2)
- SDL_ECHELLE = 25;
- if (GLOBALS.XSETMODE == 3)
- SDL_ECHELLE = 50;
- if (GLOBALS.XSETMODE == 4)
- SDL_ECHELLE = 75;
- if (GLOBALS.XSETMODE == 5)
- SDL_ECHELLE = GLOBALS.XZOOM;
-
- int bpp = 8;
- if (GLOBALS.XFORCE8 == 1)
- bpp = 8;
- if (GLOBALS.XFORCE16 == 1)
- bpp = 16;
-
- if (SDL_ECHELLE) {
- error("TODO: Implement zooming support");
- //width = Reel_Zoom(a1, SDL_ECHELLE);
- //height = Reel_Zoom(a2, SDL_ECHELLE);
- }
-
- if (bpp == 8) {
- initGraphics(width, height, true);
- } else {
- Graphics::PixelFormat pixelFormat(2, 5, 5, 5, 0, 10, 5, 0, 0);
- initGraphics(width, height, true, &pixelFormat);
- }
-
- VideoPtr = NULL;
- XSCREEN = width;
- YSCREEN = height;
-
- Linear = true;
- Winbpp = bpp;
- WinScan = width;
-
- PAL_PIXELS = SD_PIXELS;
- nbrligne = width;
-
- for (int idx = 0; idx < 256; ++idx) {
- cmap[idx].r = cmap[idx].g = cmap[idx].b = 0;
- }
-
- SDL_MODEYES = true;
- } else {
- error("Called SET_MODE multiple times");
- }
-}
-
-void GraphicsManager::DD_Lock() {
- VideoPtr = g_system->lockScreen();
-}
-
-void GraphicsManager::DD_Unlock() {
- g_system->unlockScreen();
-}
-
-void GraphicsManager::Cls_Video() {
- assert(VideoPtr);
-
- VideoPtr->fillRect(Common::Rect(0, 0, XSCREEN, YSCREEN), 0);
-}
-
} // End of namespace Hopkins
diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h
index 18cb44254e..e6d56575f5 100644
--- a/engines/hopkins/graphics.h
+++ b/engines/hopkins/graphics.h
@@ -30,28 +30,17 @@
namespace Hopkins {
+#define PALETTE_SIZE 256
+
struct RGB8 {
byte r;
byte g;
byte b;
};
-class ObjectManager {
-public:
- static byte *CHANGE_OBJET(int objIndex);
- static byte *CAPTURE_OBJET(int objIndex, int mode);
-
- static int Get_Largeur(const byte *objectData, int objIndex);
- static int Get_Hauteur(const byte *objectData, int objIndex);
- static int sprite_alone(const byte *objectData, byte *sprite, int objIndex);
- static byte *DEL_FICHIER_OBJ();
-
- static byte *CHARGE_SPRITE(const Common::String &file);
- static int capture_mem_sprite(const byte *objectData, byte *sprite, int objIndex);
- static int AJOUTE_OBJET(int objIndex);
-};
-
class GraphicsManager {
+private:
+ void CHARGE_ECRAN(const Common::String &file);
public:
bool SDL_MODEYES;
int SDL_ECHELLE;
@@ -62,9 +51,26 @@ public:
byte SD_PIXELS[514];
byte *PAL_PIXELS;
int nbrligne;
+ byte TABLE_COUL[256];
RGB8 cmap[256];
+ byte Palette[PALETTE_SIZE * 3];
bool Linear;
Graphics::Surface *VideoPtr;
+ Graphics::Surface VESA_SCREEN;
+ Graphics::Surface VESA_BUFFER;
+ int start_x;
+ int ofscroll;
+ int SCROLL;
+ byte HEADER_PCX[128];
+ int PCX_L, PCX_H;
+ bool DOUBLE_ECRAN;
+ int OLD_SCROLL;
+ int MANU_SCROLL;
+ int SPEED_SCROLL;
+ int nbrligne2;
+ int Agr_x, Agr_y;
+ int Agr_Flag_x, Agr_Flag_y;
+
public:
GraphicsManager();
~GraphicsManager();
@@ -73,6 +79,34 @@ public:
void DD_Lock();
void DD_Unlock();
void Cls_Video();
+ void LOAD_IMAGE(const Common::String &file);
+ void INIT_TABLE(int a1, int a2, byte *a3);
+ int SCROLL_ECRAN(int amount);
+ void Trans_bloc(byte *destP, byte *srcP, int count, int param1, int param2);
+ void A_PCXSCREEN_WIDTH_SCREEN_HEIGHT(byte *surface, const Common::String &file, byte *palette, bool typeFlag);
+ void Cls_Pal();
+ void souris_max();
+ void SCANLINE(int width);
+ void m_scroll(const byte *surface, int xs, int ys, int width, int height, int destX, int destY);
+ void m_scroll2(const byte *surface, int xs, int ys, int width, int height, int destX, int destY);
+ void m_scroll2A(const byte *surface, int xs, int ys, int width, int height, int destX, int destY);
+ void m_scroll16(const byte *surface, int xs, int ys, int width, int height, int destX, int destY);
+ void m_scroll16A(const byte *surface, int xs, int ys, int width, int height, int destX, int destY);
+};
+
+class ObjectManager {
+public:
+ static byte *CHANGE_OBJET(int objIndex);
+ static byte *CAPTURE_OBJET(int objIndex, int mode);
+
+ static int Get_Largeur(const byte *objectData, int objIndex);
+ static int Get_Hauteur(const byte *objectData, int objIndex);
+ static int sprite_alone(const byte *objectData, byte *sprite, int objIndex);
+ static byte *DEL_FICHIER_OBJ();
+
+ static byte *CHARGE_SPRITE(const Common::String &file);
+ static int capture_mem_sprite(const byte *objectData, byte *sprite, int objIndex);
+ static int AJOUTE_OBJET(int objIndex);
};
} // End of namespace Hopkins
diff --git a/engines/hopkins/hopkins.cpp b/engines/hopkins/hopkins.cpp
index af8cd668ef..0dd1fbc03b 100644
--- a/engines/hopkins/hopkins.cpp
+++ b/engines/hopkins/hopkins.cpp
@@ -43,9 +43,6 @@ HopkinsEngine::~HopkinsEngine() {
}
Common::Error HopkinsEngine::run() {
-// char v1; // al@93
-// char v2; // al@114
-
FileManager::initSaves();
Common::StringMap iniParams;
@@ -69,8 +66,9 @@ Common::Error HopkinsEngine::run() {
_graphicsManager.DD_Lock();
_graphicsManager.Cls_Video();
_graphicsManager.DD_Unlock();
+
+ _graphicsManager.LOAD_IMAGE("LINUX");
/*
- LOAD_IMAGE("LINUX");
FADE_INW();
SDL_Delay(1500);
FADE_OUTW();
@@ -503,9 +501,6 @@ void HopkinsEngine::INIT_SYSTEM() {
// Set graphics mode
_graphicsManager.SET_MODE(640, 480);
- // TODO: init surfaces
- //VESA_SCREEN = dos_malloc2(0x96000u);
- //VESA_BUFFER = dos_malloc2(0x96000u);
_mouse.mouse_linux = true;
switch (GLOBALS.FR) {
diff --git a/engines/hopkins/hopkins.h b/engines/hopkins/hopkins.h
index 5f6b19d47a..1a2e6961b2 100644
--- a/engines/hopkins/hopkins.h
+++ b/engines/hopkins/hopkins.h
@@ -57,14 +57,15 @@ enum {
#define DEBUG_INTERMEDIATE 2
#define DEBUG_DETAILED 3
+#define SCREEN_WIDTH 640
+#define SCREEN_HEIGHT 480
+
struct HopkinsGameDescription;
class HopkinsEngine : public Engine {
private:
const HopkinsGameDescription *_gameDescription;
Common::RandomSource _randomSource;
- Graphics::Surface VESA_SCREEN;
- Graphics::Surface VESA_BUFFER;
Mouse _mouse;
GraphicsManager _graphicsManager;