aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Gilbert2012-09-16 17:21:24 +1000
committerPaul Gilbert2012-09-16 17:21:24 +1000
commitd2bf3ae78c693e119ac765b1af3578eefecee773 (patch)
tree39dc37bcfb7e30982e350548de7d1ee4c978dfaa
parente02e950a40a5abbef9f53569d99b66af6dc30345 (diff)
downloadscummvm-rg350-d2bf3ae78c693e119ac765b1af3578eefecee773.tar.gz
scummvm-rg350-d2bf3ae78c693e119ac765b1af3578eefecee773.tar.bz2
scummvm-rg350-d2bf3ae78c693e119ac765b1af3578eefecee773.zip
HOPKINS: Implementing code for CHARGE_ANIM and dependent methods
-rw-r--r--engines/hopkins/anim.cpp310
-rw-r--r--engines/hopkins/anim.h9
-rw-r--r--engines/hopkins/files.cpp13
-rw-r--r--engines/hopkins/files.h5
-rw-r--r--engines/hopkins/globals.cpp11
-rw-r--r--engines/hopkins/globals.h15
6 files changed, 349 insertions, 14 deletions
diff --git a/engines/hopkins/anim.cpp b/engines/hopkins/anim.cpp
index 325dadcbf9..b0e48a9e59 100644
--- a/engines/hopkins/anim.cpp
+++ b/engines/hopkins/anim.cpp
@@ -297,8 +297,314 @@ void AnimationManager::BOBANIM_OFF(int a1) {
warning("TODO: BOBANIM_OFF");
}
-void AnimationManager::CHARGE_ANIM(const Common::String &filename) {
- warning("TODO: CHARGE_ANIM");
+void AnimationManager::CHARGE_ANIM(const Common::String &animName) {
+ byte v20[15];
+ char header[10];
+ char filename1[15];
+ char filename2[15];
+ char filename3[15];
+ char filename4[15];
+ char filename5[15];
+ char filename6[15];
+
+ CLEAR_ANIM();
+
+ Common::String filename = animName + ".ANI";
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPANIM, filename);
+
+ Common::File f;
+ if (!f.open(GLOBALS.NFICHIER))
+ error("Failed to open %s", GLOBALS.NFICHIER);
+
+ int filesize = f.size();
+ int nbytes = filesize - 115;
+ f.read(header, 10);
+ f.read(v20, 15);
+ f.read(filename1, 15);
+ f.read(filename2, 15);
+ f.read(filename3, 15);
+ f.read(filename4, 15);
+ f.read(filename5, 15);
+ f.read(filename6, 15);
+
+ if (header[0] != 'A' || header[1] != 'N' || header[2] != 'I' || header[3] != 'S')
+ error("File incompatible with this soft.");
+
+ const char *files[6] = { &filename1[0], &filename2[0], &filename3[0], &filename4[0],
+ &filename5[0], &filename6[0] };
+
+ for (int idx = 1; idx <= 6; ++idx) {
+ if (files[idx - 1][0]) {
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPANIM, files[idx - 1]);
+
+ if (!f.exists(GLOBALS.NFICHIER))
+ error("File not found");
+ if (CHARGE_BANK_SPRITE1(idx, files[idx - 1]))
+ error("File not compatible with this soft.");
+ }
+ }
+
+ byte *data = GLOBALS.dos_malloc2(nbytes + 1);
+ f.read(data, nbytes);
+ f.close();
+
+ for (int idx = 1; idx <= 20; ++idx) {
+ RECHERCHE_ANIM(data, idx, nbytes);
+ }
+
+ GLOBALS.dos_free2(data);
+}
+
+void AnimationManager::CLEAR_ANIM() {
+ for (int idx = 0; idx < 35; ++idx) {
+ if (GLOBALS.Bqe_Anim[idx].data != PTRNUL)
+ GLOBALS.Bqe_Anim[idx].data = GLOBALS.dos_free2(GLOBALS.Bqe_Anim[idx].data);
+ GLOBALS.Bqe_Anim[idx].field4 = 0;
+ }
+
+ for (int idx = 0; idx < 8; ++idx) {
+ if (GLOBALS.Bank[idx].data != PTRNUL)
+ GLOBALS.Bank[idx].data = GLOBALS.dos_free2(GLOBALS.Bank[idx].data);
+ GLOBALS.Bank[idx].field4 = 0;
+ GLOBALS.Bank[idx].filename1 = "";
+ GLOBALS.Bank[idx].fileHeader = 0;
+ GLOBALS.Bank[idx].field1C = 0;
+ }
+}
+
+int AnimationManager::CHARGE_BANK_SPRITE1(int idx, const Common::String &filename) {
+ byte *v3;
+ byte *v4;
+ int v7;
+ int v8;
+ int width;
+ int height;
+ byte *v13;
+ __int16 v16;
+ __int16 v17;
+ byte *ptr;
+ byte *v19;
+ __int16 v20;
+ __int16 v21;
+ int result = 0;
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPANIM, filename);
+ GLOBALS.Bank[idx].field1C = FileManager::FLONG(GLOBALS.NFICHIER);
+ GLOBALS.Bank[idx].field4 = 1;
+ GLOBALS.Bank[idx].filename1 = filename;
+ GLOBALS.Bank[idx].filename2 = GLOBALS.REP_SPR;
+
+ v3 = FileManager::CHARGE_FICHIER(GLOBALS.NFICHIER);
+ v4 = v3;
+
+ GLOBALS.Bank[idx].fileHeader = 0;
+ if (*(v3 + 1) == 'L' && *(v3 + 2) == 'E')
+ GLOBALS.Bank[idx].fileHeader = 1;
+ if (*(v3 + 1) == 'O' && *(v3 + 2) == 'R')
+ GLOBALS.Bank[184].fileHeader = 2;
+
+ if (GLOBALS.Bank[idx].fileHeader) {
+ GLOBALS.Bank[idx].data = v3;
+
+ v7 = 0;
+ v8 = 0;
+ do {
+ ptr = v4;
+ width = Get_Largeur(v4, v8);
+ height = Get_Hauteur(ptr, v8);
+ v4 = ptr;
+ if (!width && !height)
+ v7 = 1;
+ if (!v7)
+ ++v8;
+ if (v8 > 249)
+ v7 = 1;
+ } while (v7 != 1);
+
+ if (v8 <= 249) {
+ GLOBALS.Bank[idx].field1A = v8;
+
+ Common::String ofsFilename = GLOBALS.Bank[idx].filename1;
+ while (ofsFilename.lastChar() != '.')
+ ofsFilename.deleteLastChar();
+ ofsFilename += ".OFS";
+
+ FileManager::CONSTRUIT_FICHIER(GLOBALS.HOPANIM, ofsFilename);
+ Common::File f;
+ if (!f.exists(GLOBALS.NFICHIER)) {
+ v19 = FileManager::CHARGE_FICHIER(GLOBALS.NFICHIER);
+ v13 = v19;
+
+ if (GLOBALS.Bank[idx].field1A > 0) {
+ for (int v14 = 0; v14 < GLOBALS.Bank[idx].field1A; ++v14) {
+ v16 = READ_LE_UINT16(v13);
+ v17 = READ_LE_UINT16(v13 + 2);
+ v21 = READ_LE_UINT16(v13 + 4);
+ v20 = READ_LE_UINT16(v13 + 6);
+ v13 += 8;
+
+ set_offsetxy(GLOBALS.Bank[idx].data, v14, v16, v17, 0);
+ if (GLOBALS.Bank[idx].fileHeader == 2)
+ set_offsetxy(GLOBALS.Bank[idx].data, v14, v21, v20, 1);
+ }
+ }
+
+ GLOBALS.dos_free2(v19);
+ }
+
+ result = 0;
+ } else {
+ GLOBALS.dos_free2(ptr);
+ GLOBALS.Bank[idx].field4 = 0;
+ result = -2;
+ }
+ } else {
+ GLOBALS.dos_free2(v3);
+ GLOBALS.Bank[idx].field4 = 0;
+ result = -1;
+ }
+
+ return result;
+}
+
+void AnimationManager::set_offsetxy(byte *data, int idx, int xp, __int16 yp, bool isSize) {
+ byte *startP = data + 3;
+ for (int i = idx; i; --i)
+ startP += READ_LE_UINT32(startP) + 16;
+
+ byte *rectP = startP + 8;
+ if (isSize == 1) {
+ // Set size
+ byte *pointP = rectP + 4;
+ WRITE_LE_UINT16(pointP, xp);
+ WRITE_LE_UINT16(pointP + 2, yp);
+ } else {
+ // Set position
+ WRITE_LE_UINT16(rectP, xp);
+ WRITE_LE_UINT16(rectP + 2, yp);
+ }
+}
+
+void AnimationManager::RECHERCHE_ANIM(const byte *data, int idx, int nbytes) {
+ int v4;
+ const byte *v5;
+ int v6;
+ int v7;
+ byte *v9;
+ __int16 v10;
+ __int16 v11;
+ __int16 v12;
+ char v13;
+ signed int v14;
+ __int16 v15;
+ __int16 v16;
+ char v17;
+ int v19;
+ char v20;
+ int v21;
+ __int16 v22;
+ const byte *v23;
+ int v24;
+
+ bool doneFlag = false;
+ bool breakFlag;
+
+ v21 = 0;
+ v4 = 8 * idx;
+ v19 = 8 * idx;
+
+ do {
+ v20 = *(v21 + data);
+ if (*(data + v20) == 'A' && *(data + v20 + 1) == 'N' && *(data + v20 + 2) == 'I'
+ && *(data + v20 + 3) == 'M') {
+ v4 = *(data + v21 + 4);
+ if (idx == v4) {
+ v5 = v21 + data + 5;
+ v6 = v21 + 5;
+ v7 = 0;
+ breakFlag = false;
+
+ do {
+ if (*v5 == 'A' && *(v5 + 1) == 'N' && *(v5 + 2) == 'I' && *(v5 + 3) == 'M')
+ breakFlag = true;
+
+ if (*v5 == 'F' && *(v5 + 1) == 'I' && *(v5 + 2) == 'N')
+ breakFlag = true;
+
+ if (nbytes < v6) {
+ GLOBALS.Bqe_Anim[idx].field4 = 0;
+ GLOBALS.Bqe_Anim[idx].data = PTRNUL;
+ }
+
+ ++v6;
+ ++v7;
+ ++v5;
+ } while (!breakFlag);
+
+ GLOBALS.Bqe_Anim[idx].data = GLOBALS.dos_malloc2(v7 + 50);
+ GLOBALS.Bqe_Anim[idx].field4 = 1;
+ memcpy(GLOBALS.Bqe_Anim[idx].data, v21 + data + 5, 20);
+
+ byte *dataP = GLOBALS.Bqe_Anim[idx].data;
+
+ v9 = dataP + 20;
+ v23 = v21 + data + 25;
+ v10 = READ_LE_UINT16(v21 + data + 25);
+ v11 = READ_LE_UINT16(v21 + data + 27);
+ v22 = READ_LE_UINT16(v21 + data + 29);
+ v12 = READ_LE_UINT16(v21 + data + 31);
+ v13 = READ_LE_UINT16(v21 + data + 33);
+ *(dataP + 29) = *(v21 + data + 34);
+ WRITE_LE_UINT16(dataP + 20, v10);
+ WRITE_LE_UINT16(dataP + 22, v11);
+ WRITE_LE_UINT16(dataP + 24, v22);
+ WRITE_LE_UINT16(dataP + 26, v12);
+ WRITE_LE_UINT16(dataP + 28, v13);
+ v14 = 1;
+
+ do {
+ v9 += 10;
+ v23 += 10;
+ if (!v22)
+ break;
+
+ v24 = READ_LE_UINT16(v23);
+ v15 = READ_LE_UINT16(v23 + 2);
+ v22 = READ_LE_UINT16(v23 + 4);
+ v16 = READ_LE_UINT16(v23 + 6);
+ v17 = READ_LE_UINT16(v23 + 8);
+ *(v9 + 9) = *(v23 + 9);
+ WRITE_LE_UINT16(v9, v24);
+ WRITE_LE_UINT16(v9 + 2, v15);
+ WRITE_LE_UINT16(v9 + 4, v22);
+ WRITE_LE_UINT16(v9 + 6, v16);
+ WRITE_LE_UINT16(v9 + 8, v17);
+ ++v14;
+ } while (v14 <= 4999);
+
+ doneFlag = 1;
+ }
+ }
+
+ if (*(data + v20) == 'F' && *(data + v21 + 1) == 'I' && *(data + v21 + 2) == 'N')
+ doneFlag = 1;
+ ++v21;
+ } while (v21 <= nbytes && !doneFlag);
+}
+
+int AnimationManager::Get_Largeur(const byte *data, int idx) {
+ const byte *rectP = data + 3;
+ for (int i = idx; i; --i)
+ rectP += READ_LE_UINT32(rectP) + 16;
+
+ return (int16)READ_LE_UINT16(rectP + 4);
+}
+
+int AnimationManager::Get_Hauteur(const byte *data, int idx) {
+ const byte *rectP = data + 3;
+ for (int i = idx; i; --i)
+ rectP += READ_LE_UINT32(rectP) + 16;
+
+ return (int16)READ_LE_UINT16(rectP + 6);
}
} // End of namespace Hopkins
diff --git a/engines/hopkins/anim.h b/engines/hopkins/anim.h
index b18fc9be80..dcd04bd36c 100644
--- a/engines/hopkins/anim.h
+++ b/engines/hopkins/anim.h
@@ -33,6 +33,8 @@ namespace Hopkins {
class HopkinsEngine;
class AnimationManager {
+private:
+ int CHARGE_BANK_SPRITE1(int idx, const Common::String &filename);
public:
HopkinsEngine *_vm;
bool CLS_ANM;
@@ -45,7 +47,12 @@ public:
bool REDRAW_ANIM();
void BOBANIM_ON(int a1);
void BOBANIM_OFF(int a1);
- void CHARGE_ANIM(const Common::String &filename);
+ void CHARGE_ANIM(const Common::String &animName);
+ void CLEAR_ANIM();
+ void set_offsetxy(byte *data, int idx, int xp, __int16 yp, bool isSize);
+ void RECHERCHE_ANIM(const byte *data, int idx, int nbytes);
+ int Get_Largeur(const byte *data, int idx);
+ int Get_Hauteur(const byte *data, int idx);
};
} // End of namespace Hopkins
diff --git a/engines/hopkins/files.cpp b/engines/hopkins/files.cpp
index 951db67483..90b5cf0ae8 100644
--- a/engines/hopkins/files.cpp
+++ b/engines/hopkins/files.cpp
@@ -307,4 +307,17 @@ bool FileManager::RECHERCHE_CAT(const Common::String &file, int a2) {
return result;
}
+uint32 FileManager::FLONG(const Common::String &filename) {
+ Common::File f;
+ uint32 size;
+
+ if (!f.open(filename))
+ error("Could not find file %s", filename.c_str());
+
+ size = f.size();
+ f.close();
+
+ return size;
+}
+
} // End of namespace Hopkins
diff --git a/engines/hopkins/files.h b/engines/hopkins/files.h
index 8c8f01004d..e5e4be3566 100644
--- a/engines/hopkins/files.h
+++ b/engines/hopkins/files.h
@@ -44,6 +44,11 @@ public:
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);
+
+ /**
+ * Returns the size of a file. Throws an error if the file can't be found
+ */
+ static uint32 FLONG(const Common::String &filename);
};
} // End of namespace Hopkins
diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp
index f7d94ee90f..85d7033e7a 100644
--- a/engines/hopkins/globals.cpp
+++ b/engines/hopkins/globals.cpp
@@ -629,16 +629,17 @@ void Globals::HOPKINS_DATA() {
void Globals::INIT_ANIM() {
for (int idx = 0; idx < 35; ++idx) {
- Bge_Anim[idx].field0 = PTRNUL;
- Bge_Anim[idx].field4 = 0;
+ Bqe_Anim[idx].data = PTRNUL;
+ Bqe_Anim[idx].field4 = 0;
}
for (int idx = 0; idx < 8; ++idx) {
- Bank[idx].field0 = PTRNUL;
+ Bank[idx].data = PTRNUL;
Bank[idx].field4 = 0;
- Bank[idx].field5 = 0;
- Bank[idx].field19 = 0;
+ Bank[idx].filename1 = "";
+ Bank[idx].fileHeader = 0;
Bank[idx].field1C = 0;
+ Bank[idx].filename2 = "";
}
}
diff --git a/engines/hopkins/globals.h b/engines/hopkins/globals.h
index 0495607b5d..572d73ba8e 100644
--- a/engines/hopkins/globals.h
+++ b/engines/hopkins/globals.h
@@ -68,17 +68,19 @@ struct CarreZoneItem {
int field0;
};
-struct BgeAnimItem {
- byte *field0;
+struct BqeAnimItem {
+ byte *data;
int field4;
};
struct BankItem {
- byte *field0;
+ byte *data;
int8 field4;
- int8 field5;
- int8 field19;
+ Common::String filename1;
+ int fileHeader;
+ int field1A;
uint32 field1C;
+ Common::String filename2;
};
struct VBobItem {
@@ -133,6 +135,7 @@ public:
Common::String FICH_ZONE;
Common::String FICH_TEXTE;
Common::String NFICHIER;
+ Common::String REP_SPR;
int SOUNDVOL;
int MUSICVOL;
int VOICEVOL;
@@ -162,7 +165,7 @@ public:
LigneItem Ligne[400];
LigneZoneItem LigneZone[400];
CarreZoneItem CarreZone[100];
- BgeAnimItem Bge_Anim[35];
+ BqeAnimItem Bqe_Anim[35];
BankItem Bank[8];
VBobItem VBob[35];
ObjetWItem ObjetW[300];