changeset 2379:e07e297f292d

Implementing Grayface's mouse pick implementation/fix/workaround
author Grumpy7
date Sat, 21 Jun 2014 00:41:20 +0200
parents bbf8a522dcec
children 56f87a5c402b
files LOD.cpp LOD.h Vis.cpp
diffstat 3 files changed, 75 insertions(+), 83 deletions(-) [+]
line wrap: on
line diff
--- a/LOD.cpp	Mon May 12 01:55:23 2014 +0200
+++ b/LOD.cpp	Sat Jun 21 00:41:20 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 )
       {
--- a/LOD.h	Mon May 12 01:55:23 2014 +0200
+++ b/LOD.h	Sat Jun 21 00:41:20 2014 +0200
@@ -1,6 +1,7 @@
 #pragma once
 #include <stdio.h>
 #include <memory.h>
+#include <cstdint>
 
 #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)
 
--- a/Vis.cpp	Mon May 12 01:55:23 2014 +0200
+++ b/Vis.cpp	Sat Jun 21 00:41:20 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) --------------------------------------------------------