Mercurial > mm7
view GUIFont.cpp @ 564:8b77231088d8
Moon Temple doesn't crash
author | Nomad |
---|---|
date | Tue, 05 Mar 2013 01:45:15 +0200 |
parents | 1527f66fd81b |
children | c0bfb386b15f |
line wrap: on
line source
#include <string> #include <assert.h> #include "LOD.h" #include "GUIFont.h" #include "GUIWindow.h" #include "Render.h" #include "mm7_data.h" extern LODFile_IconsBitmaps *pIcons_LOD; struct GUIFont *pAutonoteFont; struct GUIFont *pSpellFont; struct GUIFont *pFontArrus; struct GUIFont *pFontLucida; struct GUIFont *pBook2Font; struct GUIFont *pBookFont; struct GUIFont *pFontCreate; struct GUIFont *pFontCChar; struct GUIFont *pFontComic; struct GUIFont *pFontSmallnum; char temp_string[2048]; char pTmpBuf3[10000]; //----- (0044C448) -------------------------------------------------------- GUIFont *LoadFont(const char *pFontFile, const char *pFontPalette, ...) { int pallete_index; // eax@3 GUIFont *pFont; unsigned int palletes_count =0; va_list palettes_ptr; pFont = (GUIFont *)pIcons_LOD->LoadRaw(pFontFile, 0); va_start(palettes_ptr, pFontFile); while (NULL!=(pFontPalette=va_arg(palettes_ptr, const char *))) { pallete_index =pIcons_LOD->LoadTexture(pFontPalette, TEXTURE_16BIT_PALETTE); if (pallete_index == -1) { wsprintfA(pTmpBuf, "Unable to open %s", pFontPalette); Abortf(pTmpBuf); } pFont->pFontPalettes[palletes_count] = pIcons_LOD->pTextures[pallete_index].pPalette16; ++palletes_count; } va_end(palettes_ptr); pFont->palletes_count = palletes_count; return pFont; } //----- (0044D2FD) -------------------------------------------------------- void GUIFont::_44D2FD_prolly_draw_credits_entry(GUIFont *pFont, int Str, int a4, unsigned int w, unsigned int h, unsigned __int16 a7, unsigned __int16 a8, const char *pString, unsigned __int16 *pPixels, unsigned int uPixelsWidth) { int v11; // ebx@1 int v12; // edi@1 char *v13; // eax@1 char *v14; // eax@1 unsigned __int16 *v15; // esi@1 GUIFont *v16; // edi@4 signed int v17; // ecx@4 signed int v18; // eax@6 int v19; // [sp+Ch] [bp-5Ch]@1 int v20; // [sp+10h] [bp-58h]@1 unsigned int v21; // [sp+14h] [bp-54h]@1 unsigned int v22; // [sp+18h] [bp-50h]@1 unsigned int v23; // [sp+1Ch] [bp-4Ch]@1 unsigned int v24; // [sp+20h] [bp-48h]@1 GUIFont *v25; // [sp+60h] [bp-8h]@1 GUIFont *v26; // [sp+64h] [bp-4h]@1 char *Stra; // [sp+70h] [bp+8h]@1 int a4a; // [sp+74h] [bp+Ch]@4 int a7a; // [sp+80h] [bp+18h]@2 v11 = a7; v22 = h; v12 = Str; v26 = this; v24 = a4 + h - 1; v21 = w; v25 = pFont; v23 = Str + w - 1; ui_current_text_color = a7; v19 = Str; v20 = a4; v13 = GUIFont::_44C933(pString, this, pFont, (int)&v19, 0, 1); v14 = strtok(v13, "\n"); Stra = v14; v15 = &pPixels[uPixelsWidth * a4]; if ( v14 ) { a7a = v12 >> 1; while ( 1 ) { v16 = v26; ui_current_text_color = v11; v17 = 0; a4a = v11; if ( *v14 == '_' ) { v16 = v25; a4a = a8; ui_current_text_color = a8; v17 = 1; } v18 = (signed int)(w - v16->GetLineWidth(&v14[v17])) >> 1; if ( v18 < 0 ) v18 = 0; v16->_44D0B5(a4a, a8, (int)&v15[v18 + a7a], Stra, uPixelsWidth); v15 += uPixelsWidth * (LOBYTE(v16->uFontHeight) - 3); Stra = strtok(0, "\n"); if ( !Stra ) break; v14 = Stra; } } } // 5C6DB4: using guessed type int ui_current_text_color; //----- (0044D1E7) -------------------------------------------------------- void GUIFont::DrawTextLine(unsigned int uDefaultColor, signed int uX, signed int uY, const char *Str, int a6) { size_t v6; // ebx@1 GUIFont *pFont; // esi@1 signed int v8; // edi@3 unsigned __int8 v9; // cl@4 int v10; // eax@5 int v11; // ecx@5 int v12; // ecx@6 int v13; // ecx@7 int v14; // ecx@9 unsigned int v15; // edx@9 unsigned __int16 v16; // cx@12 unsigned __int8 *v17; // eax@12 char Dest[20]; // [sp+Ch] [bp-1Ch]@16 //char v19; // [sp+11h] [bp-17h]@16 size_t v20; // [sp+20h] [bp-8h]@2 int v21; // [sp+24h] [bp-4h]@1 int uXa; // [sp+30h] [bp+8h]@9 v6 = 0; v21 = uDefaultColor; pFont = this; if ( Str ) { v21 = ui_current_text_color; v20 = strlen(Str); if ( (signed int)v20 > 0 ) { v8 = uX; do { if ( pFont->IsCharValid(v9 = Str[v6]) ) { v10 = v9; v11 = v9 - 9; if ( v11 ) { v12 = v11 - 1; if ( !v12 ) return; v13 = v12 - 2; if ( v13 ) { if ( v13 != 1 ) { v14 = 3 * v10 + 9; v15 = *((int *)&pFont->cFirstChar + v14); uXa = *((int *)&pFont->cFirstChar + v14); if ( v15 ) { if ( (signed int)v6 > 0 ) v8 += pFont->pMetrics[v10].uLeftSpacing; v16 = v21; v17 = (unsigned __int8 *)((char *)&pFont[1] + pFont->field_C20[v10]); if ( !v21 ) v16 = -1; pRenderer->DrawText(v8, uY, v17, v15, pFont->uFontHeight, pFont->pFontPalettes[0], v16, 0); v8 += uXa; if ( (signed int)v6 < (signed int)v20 ) v8 += pFont->pMetrics[(unsigned __int8)Str[v6]].uRightSpacing; } } } else { strncpy(Dest, &Str[v6 + 1], 5u); Dest[5] = 0; v21 = atoi(Dest); ui_current_text_color = v21; v6 += 5; } } } ++v6; } while ( (signed int)v6 < (signed int)v20 ); } } } // 5C6DB4: using guessed type int ui_current_text_color; //----- (0044D0B5) -------------------------------------------------------- void GUIFont::_44D0B5(int a2, int a3, int a4, const char *pString, int a6) { int v6; // ebx@1 GUIFont *v7; // esi@1 int v8; // edi@3 unsigned __int8 v9; // cl@4 int v10; // eax@5 int v11; // ecx@5 int v12; // ecx@6 int v13; // ecx@7 int v14; // ecx@8 int v15; // ebx@10 int v16; // edx@13 __int16 v17; // ax@13 char Dest; // [sp+Ch] [bp-20h]@17 char v19; // [sp+11h] [bp-1Bh]@17 size_t v20; // [sp+20h] [bp-Ch]@2 int v21; // [sp+24h] [bp-8h]@1 int v22; // [sp+28h] [bp-4h]@2 const char *v23; // [sp+38h] [bp+Ch]@4 v6 = 0; v21 = a2; v7 = this; if ( pString ) { v21 = ui_current_text_color; v20 = strlen(pString); v22 = 0; if ( (signed int)v20 > 0 ) { v8 = a4; do { v23 = &pString[v6]; if ( v7->IsCharValid(v9 = pString[v6]) ) { v10 = v9; v11 = v9 - 9; if ( v11 ) { v12 = v11 - 1; if ( !v12 ) return; v13 = v12 - 2; if ( v13 ) { v14 = v13 - 1; if ( v14 ) { if ( v14 != 82 ) { v15 = *((int *)&v7->cFirstChar + 3 * v10 + 9); if ( v15 ) { if ( v22 > 0 ) v8 += 2 * v7->pMetrics[v10].uLeftSpacing; v16 = (int)((char *)&v7[1] + v7->field_C20[v10]); v17 = v21; if ( !v21 ) v17 = -1; sub_40F845(v8, v16, v15, LOBYTE(v7->uFontHeight), (int)v7->pFontPalettes[0], v17, 2 * a6); v8 += 2 * v15; if ( v22 < (signed int)v20 ) v8 += 2 * v7->pMetrics[(unsigned __int8)*v23].uRightSpacing; } } } } else { strncpy(&Dest, &pString[v6 + 1], 5u); v19 = 0; v21 = atoi(&Dest); ui_current_text_color = v21; v22 = v6 + 5; } } } v6 = v22++ + 1; } while ( v22 < (signed int)v20 ); } } } // 5C6DB4: using guessed type int ui_current_text_color; //----- (0044C933) -------------------------------------------------------- char * GUIFont::_44C933(const char *pString, GUIFont *pFont, GUIFont *a3, int a4, int a5, int a6) { const char *v6; // esi@1 size_t v8; // eax@3 size_t v9; // edi@3 int v10; // eax@3 GUIFont *v11; // esi@3 int v12; // ebx@3 char v13; // cl@5 int v14; // edx@11 int v15; // ecx@11 int v16; // edx@12 int v17; // edx@13 int v18; // edx@14 int v19; // edx@15 int v20; // edi@17 int v21; // edx@17 int v22; // ecx@17 int v23; // edi@18 char v24; // zf@18 int v25; // ecx@19 int v26; // eax@19 char v27; // dl@24 int v28; // eax@46 std::string v29; // [sp-18h] [bp-48h]@2 const char *v30; // [sp-8h] [bp-38h]@2 int v31; // [sp-4h] [bp-34h]@2 const char *v32; // [sp+Ch] [bp-24h]@1 char Str; // [sp+10h] [bp-20h]@46 char v34; // [sp+13h] [bp-1Dh]@46 GUIFont *v35; // [sp+14h] [bp-1Ch]@1 int v36; // [sp+18h] [bp-18h]@3 int v37; // [sp+1Ch] [bp-14h]@3 int v38; // [sp+20h] [bp-10h]@4 int v39; // [sp+24h] [bp-Ch]@3 int v40; // [sp+28h] [bp-8h]@3 int i; // [sp+2Ch] [bp-4h]@17 std::string *v42; // [sp+38h] [bp+8h]@2 v6 = pString; v35 = pFont; v32 = pString; if ( !pString ) { MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:558", 0); return 0; } v8 = strlen(pString); v9 = v8; v39 = v8; assert(strlen(v6) < sizeof(pTmpBuf3)); strcpy(pTmpBuf3, v6); v10 = a5; v11 = v35; v12 = 0; v40 = 0; v37 = a5; v36 = 0; if ( (signed int)v9 > 0 ) { v38 = v9 - 1; do { v13 = pTmpBuf3[v12]; if ( (unsigned __int8)v13 >= v11->cFirstChar && (unsigned __int8)v13 <= v11->cLastChar || v13 == '\f' || v13 == '\r' || v13 == '\t' || v13 == '\n' ) { v14 = (unsigned __int8)v13 - 9; v15 = (int)&v11->pMetrics[(unsigned __int8)v13]; if ( v14 ) { v16 = v14 - 1; if ( v16 ) { v17 = v16 - 2; if ( v17 ) { v18 = v17 - 1; if ( v18 ) { v19 = v18 - 19; if ( v19 ) { if ( v19 == 63 ) { v11 = a3; } else { v20 = *(int *)(v15 + 8); v21 = *(int *)(v15 + 4); v22 = *(int *)v15; i = v20; if ( (unsigned int)(v10 + v20 + v22 + v21) < *(int *)(a4 + 8) ) { v12 = v36; if ( v36 > v40 ) v10 += v22; v10 += v21; if ( v36 < v39 ) v10 += i; } else { v23 = v40; v24 = v11 == a3; pTmpBuf3[v40] = 10; if ( v24 ) { v25 = v38; v26 = v23 + 1; while ( v25 >= v26 ) { pTmpBuf3[v25] = byte_5C45AF[v25]; --v25; } ++v39; ++v38; pTmpBuf3[v23++ + 1] = 95; v40 = v26; } v12 = v36; v10 = v37; for ( i = v23; i <= v36; ++i ) { v27 = pTmpBuf3[i]; if ( (unsigned __int8)v27 >= v11->cFirstChar && (unsigned __int8)v27 <= v11->cLastChar || v27 == 12 || v27 == 13 || v27 == 9 || v27 == 10 ) { if ( i > v23 ) v10 += v11->pMetrics[(unsigned __int8)v27].uLeftSpacing; v10 += *((int *)&v11->cFirstChar + 3 * (unsigned __int8)v27 + 9); if ( i < v36 ) v10 += v11->pMetrics[(unsigned __int8)v27].uRightSpacing; } } } } } else { v10 += *(int *)(v15 + 4); v40 = v12; } } else { if ( !a6 ) return (char *)v32; } } else { v12 += 5; } } else { v10 = v37; v11 = v35; v40 = v12; } } else { strncpy(&Str, &pTmpBuf3[v12 + 1], 3u); v34 = 0; v28 = atoi(&Str); v10 = a5 + v28; v12 += 3; v37 = v10; } } ++v12; v36 = v12; } while ( v12 < v39 ); } return pTmpBuf3; } //----- (0044C6C2) -------------------------------------------------------- int GUIFont::_44C6C2(const char *pInString, GUIWindow *pWindow, unsigned int uX, int a5) { const char *v5; // esi@1 int v6; // edi@1 unsigned __int8 *v8; // ebx@3 size_t v9; // eax@3 signed int v10; // esi@3 int v11; // edx@4 unsigned int v12; // cl@4 GUIFont *v13; // [sp+Ch] [bp-4h]@1 size_t uXa; // [sp+1Ch] [bp+Ch]@3 auto pFont = this; v5 = pInString; v6 = 0; v13 = pFont; if ( !pInString ) return 0; v8 = (unsigned __int8 *)FitTextInAWindow(pInString, pFont, pWindow, uX, 0); v9 = strlen(v5); v10 = 0; uXa = v9; if ( (signed int)v9 > 0 ) { while ( v10 < (signed int)uXa ) { if(IsCharValid(*v8)) { v12=(unsigned int)v8; if ( v12 != 9 ) { if ( v12 == 10 ) { v6 = v6 + *(char *)(v11 + 5) - 3; if ( v6 >= (signed int)(a5 * pWindow->uFrameHeight) ) return (int)(v8 + 1); if ( v6 >= (signed int)(a5 * pWindow->uFrameHeight) ) return (int)v8; } else if ( v12 == 12 ) { v8 += 5; v10 += 5; if ( v6 >= (signed int)(a5 * pWindow->uFrameHeight) ) return (int)v8; } else if ( v12 != 13 ) { if ( v6 >= (signed int)(a5 * pWindow->uFrameHeight) ) return (int)v8; } } if(v12 == 13 || v12 == 9) { v8 += 3; v10 += 3; } if ( v6 >= (signed int)(a5 * pWindow->uFrameHeight) ) return (int)v8; } ++v10; ++v8; } } return (int)v8; } //----- (0044C62E) -------------------------------------------------------- int GUIFont::GetStringHeight2(GUIFont *a2, const char *Str, int a4, int a5, int a6) { GUIFont *v6; // edi@1 int v8; // esi@3 unsigned __int8 *v9; // ebx@3 size_t v10; // eax@3 unsigned __int8 v11; // cl@4 signed int Stra; // [sp+Ch] [bp+8h]@3 size_t v13; // [sp+14h] [bp+10h]@3 auto a1 = this; v6 = a1; if ( !Str ) return 0; v8 = LOBYTE(a1->uFontHeight) - 3; v9 = (unsigned __int8 *)GUIFont::_44C933(Str, a1, a2, a4, a5, 0); v10 = strlen(Str); Stra = 0; v13 = v10; while ( Stra < (signed int)v13 ) { if ( GUIFont::IsCharValid(v11 = *v9) ) { if ( v11 == 9 ) goto LABEL_9; switch ( v11 ) { case 0xAu: v8 = v8 + LOBYTE(v6->uFontHeight) - 3; break; case 0xCu: v9 += 5; Stra += 5; break; case 0xDu: LABEL_9: if ( a6 != 1 ) { v9 += 3; Stra += 3; } break; } } ++Stra; ++v9; } return v8; } //----- (0044C59D) -------------------------------------------------------- int GUIFont::CalcTextHeight(const char *pString, GUIWindow *pWindow, int uXOffset, int a5) { int uAllHeght; unsigned int uStringLen; char c; char *test_string; if (!pString) return 0; uAllHeght = this->uFontHeight - 3; test_string = FitTextInAWindow(pString, this, pWindow, uXOffset, 0); uStringLen = strlen(pString); for (int i = 0; i < uStringLen; ++i) { c = test_string[i]; if (IsCharValid(c)) { switch (c) { case '\n': //Line Feed 0A 10: uAllHeght+= this->uFontHeight - 3; break; case '\f': //Form Feed, page eject 0C 12 i += 5; break; case '\t': // Horizontal tab 09 case '\r': //Carriage Return 0D 13 if (a5 != 1) i += 3; break; } } } return uAllHeght; } //----- (0044C51E) -------------------------------------------------------- int GUIFont::GetLineWidth(const char *pString) { unsigned int str_len; // ebp@3 int string_line_width; // esi@3 unsigned char c; if (!pString) return 0; str_len = strlen(pString); string_line_width = 0; for ( int i = 0; i < str_len; ++i ) { c = pString[i]; if (IsCharValid(c)) { switch (c) { case '\t': case '\n': case '\r': return string_line_width; case '\f': i += 5; break; default: if (i > 0) string_line_width += this->pMetrics[c].uLeftSpacing; string_line_width += this->pMetrics[c].uWidth; if (i < str_len) string_line_width +=this->pMetrics[c].uRightSpacing; } } } return string_line_width; } //----- (0044C502) -------------------------------------------------------- int GUIFont::AlignText_Center(unsigned int uCenterX, const char *pString) { signed int position; // esi@1 position = (signed int)(uCenterX - GetLineWidth(pString)) >> 1; if ( position >= 0 ) return position; else return 0; } //----- (0044C768) -------------------------------------------------------- char * FitTextInAWindow(const char *pInString, GUIFont *pFont, GUIWindow *pWindow, unsigned int uX, int a5) { unsigned char c; unsigned int uInStrLen; char digits[4]; int possible_transition_point; int string_pixel_Width; int start_pixel_offset; if (!pInString) { MessageBoxW(nullptr, L"Invalid string passed !", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Font.cpp:445", 0); return 0; } uInStrLen = strlen(pInString); strcpy(&temp_string[0], pInString); if (uInStrLen==0) return &temp_string[0]; start_pixel_offset=string_pixel_Width=uX; possible_transition_point=0; for(int i=0; i<uInStrLen; ++i) { c=temp_string[i]; if (pFont->IsCharValid(c)) { switch (c) { case '\t': // Horizontal tab 09 { strncpy(digits, &temp_string[i+1],3); digits[3]=0; string_pixel_Width= atoi(digits)+uX; i+=3; break; } case '\n': //Line Feed 0A 10 { string_pixel_Width=start_pixel_offset; possible_transition_point=i; break; } case '\f': //Form Feed, page eject 0C 12 { i+=5; break; } case '\r': //Carriage Return 0D 13 { if (!a5) return (char*)pInString; break; } case ' ' : { string_pixel_Width+=pFont->pMetrics[c].uWidth; possible_transition_point=i; break; } default: if ((string_pixel_Width+pFont->pMetrics[c].uWidth+ pFont->pMetrics[c].uLeftSpacing+ pFont->pMetrics[c].uRightSpacing)<pWindow->uFrameWidth) { if(i>possible_transition_point) string_pixel_Width+=pFont->pMetrics[c].uLeftSpacing; string_pixel_Width+=pFont->pMetrics[c].uWidth; if (i<uInStrLen) string_pixel_Width+=pFont->pMetrics[c].uRightSpacing; } else { temp_string[possible_transition_point]='\n'; string_pixel_Width=start_pixel_offset; if (i>possible_transition_point) { for(int j=possible_transition_point;j<i; ++j ) { c=temp_string[j]; if (pFont->IsCharValid(c)) { if(j>possible_transition_point) string_pixel_Width+=pFont->pMetrics[c].uLeftSpacing; string_pixel_Width+=pFont->pMetrics[c].uWidth; if (j<i) string_pixel_Width+=pFont->pMetrics[c].uRightSpacing; } } } } } } } return &temp_string[0]; }