From ddb4fdcf12f8a0e09d7f9b5583984edec99325cc Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Wed, 26 Sep 2012 22:13:15 +1000 Subject: HOPKINS: Implementing font methods --- engines/hopkins/font.cpp | 498 ++++++++++++++++++++++++++++++++++++++++++- engines/hopkins/font.h | 16 +- engines/hopkins/globals.cpp | 2 +- engines/hopkins/globals.h | 2 +- engines/hopkins/graphics.cpp | 49 +++++ engines/hopkins/graphics.h | 1 + engines/hopkins/objects.cpp | 8 +- engines/hopkins/objects.h | 2 - 8 files changed, 565 insertions(+), 13 deletions(-) diff --git a/engines/hopkins/font.cpp b/engines/hopkins/font.cpp index 4a99dd357a..bbf83518a0 100644 --- a/engines/hopkins/font.cpp +++ b/engines/hopkins/font.cpp @@ -23,6 +23,11 @@ #include "common/system.h" #include "common/textconsole.h" #include "hopkins/font.h" +#include "hopkins/files.h" +#include "hopkins/globals.h" +#include "hopkins/graphics.h" +#include "hopkins/hopkins.h" +#include "hopkins/objects.h" namespace Hopkins { @@ -45,8 +50,499 @@ void FontManager::clearAll() { } } +void FontManager::TEXTE_ON(int idx) { + if ((signed __int16)(idx - 5) > 11) + error("Attempted to display text > MAX_TEXT."); + + TxtItem &txt = Txt[idx - 5]; + txt.field0 = 1; + txt.field408 = 0; + + if (txt.field400 != PTRNUL) { + _vm->_globals.dos_free2(txt.field400); + txt.field400 = PTRNUL; + } +} + + void FontManager::TEXTE_OFF(int idx) { - warning("TODO: TEXTE_OFF"); + if ((signed __int16)(idx - 5) > 11) + error("Attempted to display text > MAX_TEXT."); + + TxtItem &txt = Txt[idx - 5]; + txt.field0 = 0; + txt.field408 = 0; + + if (txt.field400 != PTRNUL) { + _vm->_globals.dos_free2(txt.field400); + txt.field400 = PTRNUL; + } +} + +void FontManager::COUL_TXT(int idx, byte colByte) { + Txt[idx - 5].field40A = colByte; +} + +void FontManager::OPTI_COUL_TXT(int idx1, int idx2, int idx3, int idx4) { + COUL_TXT(idx1, 255); + COUL_TXT(idx2, 255); + COUL_TXT(idx3, 255); + COUL_TXT(idx4, 253); +} + +void FontManager::DOS_TEXT(int idx, int a2, const Common::String &filename, int a4, int a5, int a6, int a7, int a8, int a9, int a10) { + if ((idx - 5) > 11) + error("Attempted to display text > MAX_TEXT."); + + TxtItem &txt = Txt[idx - 5]; + txt.field0 = 0; + txt.field4 = filename; + txt.field8 = a4; + txt.fieldA = a5; + txt.fieldC = a2; + txt.fieldE = a6; + txt.field10 = a7; + txt.field3FC = a8; + txt.field3FE = a9; + txt.field40A = a10; +} + +void FontManager::BOITE(int idx, int fileIndex, const Common::String &filename, int xp, int yp) { + /* There's something seriously wrong with the automatic disassembly.. it seems to have + * an extra code end block. I'll likely need to manually disassemble the method + + byte *v5; + int v6; + int v7; + int v8; + byte *v9; + const byte *v10; + int v11; + int v12; + char v13; + char v14; + int v15; + char v16; + int v17; + int v18; + int v19; + int v20; + int v21; + int v22; + int v23; + char v24; + int v25; + int v26; + int v27; + int v28; + int v29; + int v30; + int v31; + int v32; + int v33; + int v34; + int v35; + int v36; + int v37; + int v38; + int v39; + int v40; + int ptr; + char *ptra; + int ptrb; + int ptrc; + void *ptrd; + void *ptre; + int s; + int v49; + int v50; + int v51; + int v52; + int v53; + int v54; + int v55; + int v56; + int v57; + int v58; + void *v59; + void *v60; + void *v61; + int v62; + int v63; + int v64; + int v65; + int v66; + int v67; + int v68; + int v69; + int v70; + int v71; + int v72; + int v73; + int i; + int v75; + Common::String fname; + + v73 = xp; + v70 = yp; + v58 = 0; + if (idx < 0) + error("Bad number for text"); + + _vm->_globals.police_l = 11; + + v5 = idx; + largeur_boite = 11 * Txt[idx].field3FE; + if (Txt[idx].field408) { + v34 = Txt[idx].field3FC; + if (v34 != 6 && v34 != 1 && v34 != 3 && v34 != 5) { + v72 = yp + 5; + v38 = 0; + if (Txt[idx].field12 > 0) { + do { + v40 = idx; + TEXT_NOW1(xp + 5, v72, Txt[idx].field14[v38], Txt[idx].field40A); + v5 = police_h + v72 + 1; + v72 += police_h + 1; + ++v38; + idx = v40; + } while (Txt[v40].field12 > v38); + } + } else { + v35 = idx; + v36 = *(_WORD *)&Txt[v35 + 1030]; + v37 = *(_WORD *)&Txt[v35 + 1028]; + + _vm->_graphicsManager.Restore_Mem(_vm->_graphicsManager.VESA_BUFFER, + Txt[v35].field400, xp, yp, Txt[v35].field404, Txt[v35].field406); + v5 = _vm->_graphicsManager.Ajoute_Segment_Vesa(xp, yp, xp + v37, yp + v36); + } + } else { + v62 = 0; + do { + TRIER_TEXT[v62++] = 0; + while (v62 <= 19); + + &Txt[idx].field408 = 1; + FileManager::CONSTRUIT_FICHIER(HOPLINK, filename); + fname = _vm->_globals.NFICHIER; + + if (strncmp(fname.c_str(), oldname.c_str(), fname.size())) { + oldname = fname; + nom_indexoldname = fname; + + //*(int *)((char *)&dword_80AE4DC + strlen(nom_index) + 1) = dword_807C98D; + Common::File f; + if (!f.open(nom_index)) + error("error opening file - %s", nom_index.c_str()); + + int fileSize = f.size(); + for (int i = 0; i < (fileSize / 4); ++i) + Index[i] = f.readUint32LE(); + f.close(); + } + + if (fname[0] != 'Z' || fname[1] != 'O') { + Common::File f; + if (!f.open(fname)) + error("error opening file - %s", fname.c_str()); + + v69 = 2048; + f.seek(Index[fileIndex]); + texte_tmp = _vm->_globals.dos_malloc2(2058); + if (texte_tmp == PTRNUL) + error("temporary text"); + + f.read(texte_temp, 2048); + f.close(); + texte_long = 2048; + } else { + v69 = 100; + texte_long = 100; + v9 = _vm->_globals.dos_malloc2(110); + texte_tmp = v9; + v10 = BUF_ZONE + Index[fileIndex]; + memcpy(v9, v10, 96); + + v11 = 0; + WRITE_LE_UINT16((uint16 *)v9 + 48, READ_LE_UINT16((uint16 *)v10 + 48)); + } + + v59 = texte_tmp; + v63 = 0; + + if (!v69) + goto LABEL_43; + + do { + v13 = v59; + if ((unsigned __int8)(*v59 + 46) > 0x1Bu) { + if ((unsigned __int8)(v13 + 80) > 0x1Bu) { + if ((unsigned __int8)(v13 - 65) <= 0x19u || (unsigned __int8)(v13 - 97) <= 0x19u) + v13 = 32; + } else { + v13 -= 79; + } + } else { + v13 += 111; + } + + *v59 = v13; + v59 = v59 + 1; + ++v63; + } while (v63 < v69); + + v60 = texte_tmp; + v64 = 0; + if (v69) { + ptr = idx; + + for (;;) { + v14 = *(v60 + v64); + if (v14 == 10 || v14 == 13) { + *(v60 + v64) = 0; + v11 = &Txt[0]; + if (!Txt[ptr].field3FE) + break; + } + + ++v64; + if (v69 <= v64) + goto LABEL_43; + } + + Txt[ptr].field3FE = v64; + largeur_boite = 0; + + v15 = 0; + if (v64 + 1 > 0) { + do { + v16 = *(v60 + v15); + if ((unsigned __int8)v16 <= 0x1Fu) + v16 = 32; + largeur_boite += _vm->_objectManager.Get_Largeur(police, (unsigned __int8)v16 - 32); + ++v15; + } while (v15 < v64 + 1); + } + + largeur_boite += 2; + v17 = largeur_boite / 2; + if (v17 < 0) + v17 = -v17; + *Txt[idx].field8 = 320 - v17; + v73 = start_x + 320 - v17; + v58 = 1; + v18 = 0; + + if (v64 + 1 > 0) { + ptra = Txt[ptr]; + + do { + ptra.field14[v18].field0 = *(v60 + v18); + ++v18; + } while (v18 < v64 + 1); + } + } else { +LABEL_43: + + if (!largeur_boite) + largeur_boite = 240; + v65 = 0; + v61 = texte_tmp; + + do { + v19 = 0; + ptrb = largeur_boite - 4; + + for (;;) { + v57 = v19; + do { + v11 = *(v61 + v65 + v19++); + } while (v11 != 32 && v11 != 37); + + if (v19 >= ptrb / police_l) + break; + if (v11 == 37) { + if (v19 < ptrb / police_l) + goto LABEL_55; + break; + } + } + + if (v11 != 37) + goto LABEL_57; + v11 = 32; +LABEL_55: + if (v11 == 37) + v57 = v19; +LABEL_57: + v20 = v58; + v21 = v11; + + Txt[idx].field14[v20] = (const char *)v61 + v65; + //strncpy((char *)(v20 + 1036 * idx + 134911728), (const char *)v61 + v65, v57); + TRIER_TEXT[v58++] = v57; + + v65 += v57; + v11 = v21; + } while ((byte)v21 != 37); + + v66 = 0; + do { + v22 = TRIER_TEXT[v66]; + if (v22 <= 0) { + TRIER_TEXT[v66] = 0; + } else { + ptrc = 0; + v23 = 0; + if (v22 - 1 > 0) { + do { + v24 = *(&Txt[1036 * idx + 20] + 100 * v66 + v23); + if ((unsigned __int8)v24 <= 0x1Fu) + v24 = 32; + + ptrc += _vm->_objectManager.Get_Largeur(police, (unsigned __int8)v24 - 32); + ++v23; + } while (v23 < TRIER_TEXT[v66] - 1); + } + + TRIER_TEXT[v66] = ptrc; + } + ++v66; + } while (v66 <= 19); + + v67 = 0; + do { + v25 = v67; + do { + ++v25; + if (v25 == 20) + v25 = 0; + if (TRIER_TEXT[v67] < TRIER_TEXT[v25]) + TRIER_TEXT[v67] = 0; + } while (v25 != v67); + ++v67; + } while ((signed __int16)v67 <= 19); + + v68 = 0; + do { + if (TRIER_TEXT[v68]) + largeur_boite = TRIER_TEXT[v68]; + ++v68; + } while (v68 <= 19); + + if ((unsigned __int16)(Txt[idx].field3FC - 2) > 1u) { + for (i = xp - start_x; largeur_boite + i > 638 && i > -2 && Txt[idx].field3FC]; i -= 2) + ; + Txt[idx].field8 = i; + v73 = start_x + i; + } else { + if (nbrligne == 639) { + while (largeur_boite + v73 > 638 && v73 > -2) + v73 -= 2; + } + if (nbrligne == (SCREEN_WIDTH * 2)) { + while (largeur_boite + v73 > 1278 && v73 > -2) + v73 -= 2; + } + Txt[idx].field8 = v73; + } + } + + hauteur_boite = (police_h + 1) * v58 + 2; + v56 = v73; + v55 = yp; + v53 = largeur_boite + 10; + v51 = (police_h + 1) * v58 + 12; + + v26 = idx; + if (Txt[idx].field3FC == 6) { + v27 = v53 / 2; + if (v27 < 0) + v27 = -v27; + + Txt[v26].field8 = 315 - v27; + v28 = start_x + 315 - v27; + v73 = start_x + 315 - v27; + Txt[v26].fieldA = 50; + v70 = 50; + v55 = 50; + v56 = v28; + } + + v29 = Txt[idx].field3FC; + if (v29 == 1 || v29 == 3 || (unsigned __int16)(v29 - 5) <= 1u) { + v49 = v51 * v53; + ptrd = _vm->_globals.dos_malloc2(v51 * v53); + + if (ptrd == PTRNUL) + error("Error allocating block (%d)", v49); + } + + _vm->_graphicsManager.Capture_Mem(_vm->_graphicsManager.VESA_BUFFER, ptrd, v56, v55, v53, v51); + _vm->_graphicsManager.Trans_bloc2(ptrd, TABLE_COUL, v49); + _vm->_graphicsManager.Restore_Mem(_vm->_graphicsManager.VESA_BUFFER, ptrd, v56, v55, v53, v51); + _vm->_globals.dos_free2(ptrd); + + _vm->_graphicsManager.Plot_Hline(_vm->_graphicsManager.VESA_BUFFER, v56, v55, v53, -2); + _vm->_graphicsManager.Plot_Hline(_vm->_graphicsManager.VESA_BUFFER, v56, (signed __int16)(v51 + v55), v53, -2); + _vm->_graphicsManager.Plot_Vline(_vm->_graphicsManager.VESA_BUFFER, v56, v70, v51, -2); + _vm->_graphicsManager.Plot_Vline(_vm->_graphicsManager.VESA_BUFFER, (signed __int16)(v53 + v56), v70, v51, -2); + } + + Txt[idx].field12 = v58; + v75 = v73 + 5; + v71 = v70 + 5; + v30 = 0; + + if (v58 > 0) { + do { + TEXT_NOW1(v75, v71, Txt[idx].field14[v30], Txt[idx].field40A); + v71 += police_h + 1; + ++v30; + } while ( v58 > v30 ); + } + + v54 = v53 + 1; + v52 = v51 + 1; + v31 = 1036 * idx; + Txt[v31].field404 = v54; + Txt[v31].field406 = v52; + v32 = Txt[v31].field3FC; + + if (v32 == 6 || v32 == 1 || v32 == 3 || v32 == 5) { + v33 = idx; + if (Txt[v33].field400 != PTRNUL) + Txt[v33].field400 = _vm->_globals.dos_free2(Txt[v33].field400); + + v50 = v52 * v54; + ptre = dos_malloc2(v50 + 20); + if (ptre == PTRNUL) + error("Error allocating block (%d)", v50); + } + + Txt[v33].field400 = ptre; + Txt[v33].field404 = v54; + Txt[v33].field406 = v52; + _vm->_graphicsManager.Capture_Mem(_vm->_graphicsManager.VESA_BUFFER, Txt[v33].field400, v56, v55, + Txt[v33].field404, v52); + } + + texte_tmp = _vm->_globals.dos_free2(texte_tmp); + */ +} + +void FontManager::TEXT_NOW1(int xp, int yp, const Common::String &message, int transColour) { + for (uint idx = 0; idx < message.size(); ++idx) { + char currentChar = message[idx]; + + if (currentChar > 31) { + int characterIndex = currentChar - 32; + _vm->_graphicsManager.Affiche_Fonte(_vm->_graphicsManager.VESA_BUFFER, _vm->_globals.police, + xp, yp, characterIndex, transColour); + xp += _vm->_objectsManager.Get_Largeur(_vm->_globals.police, characterIndex); + } + } } } // End of namespace Hopkins diff --git a/engines/hopkins/font.h b/engines/hopkins/font.h index fb53401f13..89f74ca673 100644 --- a/engines/hopkins/font.h +++ b/engines/hopkins/font.h @@ -33,16 +33,17 @@ class HopkinsEngine; struct TxtItem { int field0; int field2; - int field4; + Common::String field4; int field8; int fieldA; int fieldC; int fieldE; int field10; int field12; + Common::String field14[10]; int field3FC; int field3FE; - int field400; + byte *field400; int field404; int field406; int field408; @@ -64,11 +65,22 @@ private: public: TxtItem Txt[12]; ListeTxtItem ListeTxt[12]; + int TRIER_TEXT[21]; + Common::String oldname; + Common::String nom_index; + int Index[4048]; + byte *texte_tmp; public: void setParent(HopkinsEngine *vm); void clearAll(); + void TEXTE_ON(int idx); void TEXTE_OFF(int idx); + void COUL_TXT(int idx, byte colByte); + void OPTI_COUL_TXT(int idx1, int idx2, int idx3, int idx4); + void DOS_TEXT(int idx, int a2, const Common::String &filename, int a4, int a5, int a6, int a7, int a8, int a9, int a10); + void BOITE(int idx, int a2, const Common::String &filename, int xp, int yp); + void TEXT_NOW1(int xp, int yp, const Common::String &message, int transColour); }; } // End of namespace Hopkins diff --git a/engines/hopkins/globals.cpp b/engines/hopkins/globals.cpp index 771b0b2aea..446e5788f4 100644 --- a/engines/hopkins/globals.cpp +++ b/engines/hopkins/globals.cpp @@ -200,7 +200,7 @@ void Globals::clearAll() { texte_tmp = PTRNUL; texte_long = 0; - police = (void *)PTRNUL; + police = PTRNUL; police_h = 0; police_l = 0; hauteur_boite = 0; diff --git a/engines/hopkins/globals.h b/engines/hopkins/globals.h index 207c187d0d..78601a916a 100644 --- a/engines/hopkins/globals.h +++ b/engines/hopkins/globals.h @@ -234,7 +234,7 @@ public: int g_old_anim; int g_old_sens; int HopkinsArr[140]; - void *police; + byte *police; int police_l; int police_h; byte *TETE; diff --git a/engines/hopkins/graphics.cpp b/engines/hopkins/graphics.cpp index 4d8a3b79a5..d8ad4de283 100644 --- a/engines/hopkins/graphics.cpp +++ b/engines/hopkins/graphics.cpp @@ -2192,4 +2192,53 @@ void GraphicsManager::Copy_Mem(const byte *srcSurface, int x1, int y1, unsigned } while (yCurrent != 1); } +void GraphicsManager::Affiche_Fonte(byte *surface, const byte *spriteData, int xp, int yp, + int characterIndex, int transColour) { + const byte *v6; + int i; + const byte *v8; + int v9; + int v10; + const byte *v11; + byte *destP; + int v13; + byte v14; + byte *destLineP; + int v16; + + v6 = spriteData + 3; + for (i = characterIndex; i; --i) + v6 += READ_LE_UINT32(v6) + 16; + + v9 = 0; + v10 = 0; + v8 = v6 + 4; + v9 = READ_LE_UINT16(v8); + v8 += 2; + v10 = READ_LE_UINT16(v8); + v11 = v8 + 10; + destP = surface + xp + nbrligne2 * yp; + Largeur = v9; + + do { + v16 = v10; + destLineP = destP; + v13 = v9; + do { + v14 = *v11; + if (*v11) { + if (v14 == (byte)-4) + v14 = transColour; + *destP = v14; + } + + ++destP; + ++v11; + --v13; + } while (v13); + destP = nbrligne2 + destLineP; + v10 = v16 - 1; + } while (v16 != 1); +} + } // End of namespace Hopkins diff --git a/engines/hopkins/graphics.h b/engines/hopkins/graphics.h index 3a3b4c5e9e..4a567e9a00 100644 --- a/engines/hopkins/graphics.h +++ b/engines/hopkins/graphics.h @@ -167,6 +167,7 @@ public: void AFFICHE_SPEED(const byte *spriteData, int xp, int yp, int spriteIndex); void SCOPY(const byte *surface, int x1, int y1, int x2, int y2, byte *destSurface, int destX, int destY); void Copy_Mem(const byte *srcSurface, int x1, int y1, unsigned int width, int height, byte *destSurface, int destX, int destY); + void Affiche_Fonte(byte *surface, const byte *spriteData, int xp, int yp, int characterIndex, int transColour); }; } // End of namespace Hopkins diff --git a/engines/hopkins/objects.cpp b/engines/hopkins/objects.cpp index 5dec33df09..170692d9e4 100644 --- a/engines/hopkins/objects.cpp +++ b/engines/hopkins/objects.cpp @@ -461,11 +461,11 @@ void ObjectsManager::AFF_SPRITES() { v16 = v38; if (_vm->_fontManager.Txt[v16].field0 == 1) { if ((uint16)(_vm->_fontManager.Txt[v16].field3FC - 2) > 1) - BOITE(v38, + _vm->_fontManager.BOITE(v38, _vm->_fontManager.Txt[v16].fieldC, _vm->_fontManager.Txt[v16].field4, _vm->_eventsManager.start_x + _vm->_fontManager.Txt[v16].field8, _vm->_fontManager.Txt[v16].fieldA); else - BOITE( + _vm->_fontManager.BOITE( v38, _vm->_fontManager.Txt[v16].fieldC, _vm->_fontManager.Txt[v16].field4, @@ -1512,8 +1512,4 @@ void ObjectsManager::AFF_VBOB() { } while ( idx <= 29 ); } -void ObjectsManager::BOITE(int a1, int a2, int a3, int a4, int a5) { - warning("TODO: BOITE"); -} - } // End of namespace Hopkins diff --git a/engines/hopkins/objects.h b/engines/hopkins/objects.h index 1055dfdb1a..67460323e6 100644 --- a/engines/hopkins/objects.h +++ b/engines/hopkins/objects.h @@ -111,8 +111,6 @@ public: int AvantTri(int a1, int a2, int a3); void AFF_BOB_ANIM(); void AFF_VBOB(); - - void BOITE(int a1, int a2, int a3, int a4, int a5); }; } // End of namespace Hopkins -- cgit v1.2.3