# HG changeset patch # User Grumpy7 # Date 1403304154 -7200 # Node ID 56f87a5c402bf6a4a9b72a314475273d02f74fae # Parent e07e297f292dd20c02248f5ef9f1193748e3dcc8# Parent 48dbf99c0f7f3743858741c400a2169fc1756335 Merge diff -r 48dbf99c0f7f -r 56f87a5c402b LOD.cpp --- a/LOD.cpp Mon Jun 09 16:26:07 2014 +0600 +++ b/LOD.cpp Sat Jun 21 00:42:34 2014 +0200 @@ -185,6 +185,7 @@ v8 = 8 * pSpriteHeader->uHeight; pSpriteHeader->pSpriteLines = v7; fread(v7, 1u, v8, v4); + v9 = &pSpriteHeader->uDecompressedSize; v10 = pSpriteHeader->uDecompressedSize; if ( v10 ) @@ -206,7 +207,7 @@ v13 = v6->pDecompressedBytes; for ( i = &v12[v6->uHeight]; v12 < i; i = &v6->pSpriteLines[v6->uHeight] ) { - v12->ptr_4 = (char *)v12->ptr_4 + (unsigned int)v13; + v12->pos = (char *)v12->pos + (unsigned int)v13; ++v12; } result = 1; @@ -283,6 +284,7 @@ pHardwareSprites[uNumLoadedSprites].uBufferHeight = temp_sprite_hdr.uHeight; pSpriteHeaders[uNumLoadedSprites].uWidth = temp_sprite_hdr.uWidth; pSpriteHeaders[uNumLoadedSprites].uHeight = temp_sprite_hdr.uHeight; + LoadSpriteFromFile( &pSpriteHeaders[uNumLoadedSprites], pContainerName); //this line is not present here in the original. necessary for Grayface's mouse picking fix } /*else { @@ -610,7 +612,7 @@ while ( 1 ) { v35 = v71 >> 16; - v36 = LOWORD(this->pSpriteLines[v35].dword_0); + v36 = this->pSpriteLines[v35].a1; if ( v36 == -1 ) { v34 -= v69; @@ -618,10 +620,10 @@ goto LABEL_84; } v37 = v9 - ((unsigned __int64)(v36 * (signed __int64)v58) >> 16); - v67 = v87 * ((unsigned __int64)(LOWORD(this->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16); + v67 = v87 * ((unsigned __int64)(this->pSpriteLines[v35].a2 * (signed __int64)v58) >> 16); v38 = v9 - v60; v77 = v9 - v60; - if ( v9 - v60 <= (signed int)(v9 - ((unsigned __int64)(HIWORD(this->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16)) + if ( v9 - v60 <= (signed int)(v9 - ((unsigned __int64)(this->pSpriteLines[v35].a2 * (signed __int64)v58) >> 16)) || v68 >= v37 ) { v89 -= v69; @@ -640,7 +642,7 @@ v89 += v39 + v60; v86 += v60 + v39; } - v40 = ((HIWORD(this->pSpriteLines[v35].dword_0) + 1) << 16) - v81 - v67; + v40 = ((this->pSpriteLines[v35].a2 + 1) << 16) - v81 - v67; LODWORD(v41) = v40 << 16; HIDWORD(v41) = v40 >> 16; v42 = v77 - (((signed int)((unsigned __int64)(v41 / v48) - 0x8000) >> 16) + 1); @@ -649,11 +651,11 @@ v43 = &pTarget[v89]; v74 = &v43[v42 - v77 + 1]; v44 = &this->pSpriteLines[v35]; - v64 = v44->ptr_4; + v64 = v44->pos; if ( !v57 ) { v83 = v67 + v81; - if ( ((v83 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 ) + if ( ((v83 - (v44->a1 << 16)) & 0xFFFF0000) < 0 ) { v83 += v87; --v43; @@ -661,7 +663,7 @@ } while ( v43 >= v74 ) { - v46 = (v83 - ((signed int)LOWORD(this->pSpriteLines[v35].dword_0) << 16)) >> 16; + v46 = (v83 - ((signed int)this->pSpriteLines[v35].a1 << 16)) >> 16; if ( *((char *)v64 + v46) ) *v43 = v61[*((char *)v64 + v46)]; v83 += v87; @@ -671,7 +673,7 @@ } pTargetZ = &v3->pTargetZ[v86]; v82 = v67 + v81; - if ( ((v82 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 ) + if ( ((v82 - (v44->a1 << 16)) & 0xFFFF0000) < 0 ) goto LABEL_72; LABEL_73: if ( v43 >= v74 ) @@ -687,7 +689,7 @@ if ( !v51 ) return result; } - v45 = (v82 - ((signed int)LOWORD(this->pSpriteLines[v35].dword_0) << 16)) >> 16; + v45 = (v82 - ((signed int)this->pSpriteLines[v35].a1 << 16)) >> 16; v56 = *((char *)v64 + v45); if ( *((char *)v64 + v45) && v57 <= (unsigned int)*pTargetZ ) { @@ -711,7 +713,7 @@ { v20 = &this->pSpriteLines[v71 >> 16]; v80 = v71 >> 16; - if ( LOWORD(v20->dword_0) != -1 ) + if ( v20->a1 != -1 ) break; v18 -= v69; v85 = v19 - window->GetWidth(); @@ -724,10 +726,10 @@ return result; v19 = v85; } - v21 = (v58 * LOWORD(v20->dword_0) + 32768) >> 16; + v21 = (v58 * v20->a1 + 32768) >> 16; v66 = v21 * v87; v76 = v68; - v54 = HIWORD(v20->dword_0); + v54 = v20->a2; v22 = v9 - v60; if ( v68 >= (v58 * v54 + 32768) >> 16 || v22 <= v21 ) { @@ -741,7 +743,7 @@ } else { - v76 = (v58 * LOWORD(v20->dword_0) + 0x8000) >> 16; + v76 = (v58 * v20->a1 + 0x8000) >> 16; v23 = v21 - v68; v88 += v23; v24 = v87 >> 1; @@ -755,11 +757,11 @@ v27 = &pTarget[v88]; v73 = &v27[v22 - v76 - 1]; v28 = &this->pSpriteLines[v80]; - v63 = v28->ptr_4; + v63 = v28->pos; if ( v57 ) { pTargetZ = &v3->pTargetZ[v85]; - v29 = v66 - (LOWORD(v28->dword_0) << 16) + v24; + v29 = v66 - (v28->a1 << 16) + v24; if ( (v29 & 0xFFFF0000) >= 0 ) goto LABEL_36; while ( 1 ) @@ -778,7 +780,7 @@ } } v30 = v29 >> 16; - if ( v30 > HIWORD(this->pSpriteLines[v80].dword_0) - (signed int)LOWORD(this->pSpriteLines[v80].dword_0) + if ( v30 > this->pSpriteLines[v80].a2 - (signed int)this->pSpriteLines[v80].a1 || (v31 = *((char *)v63 + v30)) == 0 || v57 > (unsigned int)*pTargetZ ) goto LABEL_50; @@ -786,7 +788,7 @@ } else { - v32 = v66 - (LOWORD(v28->dword_0) << 16) + v24; + v32 = v66 - (v28->a1 << 16) + v24; if ( (v32 & 0xFFFF0000) < 0 ) { v32 += v87; @@ -801,7 +803,7 @@ ++v27; } v33 = v32 >> 16; - if ( v33 > HIWORD(this->pSpriteLines[v80].dword_0) - (signed int)LOWORD(this->pSpriteLines[v80].dword_0) + if ( v33 > this->pSpriteLines[v80].a2 - (signed int)this->pSpriteLines[v80].a1 || (v31 = *((char *)v63 + v33)) == 0 ) goto LABEL_50; } @@ -846,13 +848,13 @@ for ( i = v4 * a2->uScreenSpaceY - (this->uWidth >> 1) + a2->uScreenSpaceX + 1; v5 >= 0; --v5 ) { v6 = &this->pSpriteLines[v5]; - v7 = LOWORD(v6->dword_0); - if ( LOWORD(v6->dword_0) != -1 ) + v7 = v6->a1; + if ( v6->a1 != -1 ) { v8 = v7; v9 = &v16[v7 + i]; - v10 = HIWORD(v6->dword_0); - v11 = v6->ptr_4; + v10 = v6->a2; + v11 = v6->pos; v12 = &v9[v10 - v8]; while ( v9 <= v12 ) { diff -r 48dbf99c0f7f -r 56f87a5c402b LOD.h --- a/LOD.h Mon Jun 09 16:26:07 2014 +0600 +++ b/LOD.h Sat Jun 21 00:42:34 2014 +0200 @@ -1,6 +1,7 @@ #pragma once #include #include +#include #include "Texture.h" @@ -298,8 +299,9 @@ #pragma pack(push, 1) struct LODSprite_stru0 { - int dword_0; - void *ptr_4; + int16_t a1; + int16_t a2; + char* pos; }; #pragma pack(pop) diff -r 48dbf99c0f7f -r 56f87a5c402b Vis.cpp --- a/Vis.cpp Mon Jun 09 16:26:07 2014 +0600 +++ b/Vis.cpp Sat Jun 21 00:42:34 2014 +0200 @@ -1,5 +1,7 @@ #define _CRT_SECURE_NO_WARNINGS #include "Vis.h" +#include "Sprites.h" +#include "Lod.h" #include "Outdoor.h" #include "BSPModel.h" #include "Game.h" @@ -231,73 +233,59 @@ } } + //----- (004C1607) -------------------------------------------------------- -bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y) +bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y) { - //RenderBillboardD3D *result; // eax@1 - double v5; // st7@2 - float v6; // ecx@2 - float v7; // ST00_4@3 -// __int16 v8; // fps@6 - double v9; // st6@6 -// char v10; // c0@6 -// char v11; // c2@6 -// char v12; // c3@6 -// __int16 v13; // fps@7 - double v14; // st6@7 -// unsigned __int8 v15; // c0@7 -// char v16; // c2@7 -// unsigned __int8 v17; // c3@7 -// __int16 v18; // fps@8 - double v19; // st6@8 -// char v20; // c0@8 -// char v21; // c2@8 -// char v22; // c3@8 -// __int16 v23; // fps@9 - double v24; // st6@9 -// unsigned __int8 v25; // c0@9 -// char v26; // c2@9 -// unsigned __int8 v27; // c3@9 - float v28; // [sp+4h] [bp-8h]@2 - float v29; // [sp+8h] [bp-4h]@2 - float a1a; // [sp+14h] [bp+8h]@2 + /*Not the original implementation. + This function is redone to use Grayface's mouse pick implementation to take only the visible + parts of billboards into account - I don't really have too much of an idea how it actually works*/ + float drX; // st7@2 + float drY; // ecx@2 + float drH; // [sp+4h] [bp-8h]@2 + float drW; // [sp+14h] [bp+8h]@2 if ( a1->sParentBillboardID == -1 ) return false; - //result = a1; - v5 = a1->pQuads[0].pos.x; - a1a = a1->pQuads[3].pos.x; - v6 = a1->pQuads[0].pos.y; - //result = (RenderBillboardD3D *)LODWORD(result->pQuads[1].pos.y); - v29 = v6; - v28 = a1->pQuads[1].pos.y; - if ( v5 > a1a ) - { - v7 = v5; - //HIWORD(result) = HIWORD(v7); - v5 = a1a; - a1a = v7; - } - if ( v6 > (double)v28 ) + drX = a1->pQuads[0].pos.x; + drW = a1->pQuads[3].pos.x - drX; + drY = a1->pQuads[0].pos.y; + drH = a1->pQuads[1].pos.y - drY; + + Sprite* ownerSprite = nullptr; + for (int i = 0; i < pSprites_LOD->uNumLoadedSprites; ++i) { - //result = (RenderBillboardD3D *)LODWORD(v28); - v28 = v6; - v29 = v28; + if (pSprites_LOD->pHardwareSprites[i].pTexture == a1->pTexture) + { + ownerSprite = &pSprites_LOD->pHardwareSprites[i]; + break; + } } - v9 = x + 1.0; - //UNDEF(v8); - //v10 = v9 < v5; - //v11 = 0; - //v12 = v9 == v5; - //BYTE1(result) = HIBYTE(v8);//crash - if (v9 >= v5 && - (v14 = x - 1.0, v14<=a1a) &&///*UNDEF(v13),*/ v15 = v14 < a1a, v16 = 0, v17 = v14 == a1a, BYTE1(result) = HIBYTE(v13), v15 | v17) - (v19 = y + 1.0, v19>=v29) &&///*UNDEF(v18),*/ v20 = v19 < v29, v21 = 0, v22 = v19 == v29, BYTE1(result) = HIBYTE(v18), v19 >= v29) - (v24 = y - 1.0, v24<=v28))///*UNDEF(v23),*/ v25 = v24 < v28, v26 = 0, v27 = v24 == v28, BYTE1(result) = HIBYTE(v23), v25 | v27) ) - return true; - else + + int i = ownerSprite->uAreaX + int(ownerSprite->uAreaWidth * (x - drX) / drW); + int j = ownerSprite->uAreaY + int(ownerSprite->uAreaHeight * (y - drY) / drH); + + + LODSprite* spriteHeader = nullptr; + + for (int i = 0; i < MAX_LOD_SPRITES; ++i) + { + if (strcmp(pSprites_LOD->pSpriteHeaders[i].pName, ownerSprite->pName) == 0) + { + spriteHeader = &pSprites_LOD->pSpriteHeaders[i]; + break; + } + } + + if (j < 0 || j >= spriteHeader->uHeight) return false; + + if (spriteHeader->pSpriteLines[j].a1 < 0 || i > spriteHeader->pSpriteLines[j].a2 || i < spriteHeader->pSpriteLines[j].a1) + { + return false; + } + return *(spriteHeader->pSpriteLines[j].pos + i - spriteHeader->pSpriteLines[j].a1) != 0; } //----- (004C16B4) --------------------------------------------------------