comparison Vis.cpp @ 194:650d96af8855

Vis overhaul; sprites can be picked by mouse
author Nomad
date Sat, 16 Feb 2013 18:32:37 +0200
parents 1860917d953f
children 982c1ec5a983
comparison
equal deleted inserted replaced
192:1c8add70bcf9 194:650d96af8855
1 #include <assert.h>
2
1 #include "Vis.h" 3 #include "Vis.h"
2 #include "Outdoor.h" 4 #include "Outdoor.h"
3 #include "Game.h" 5 #include "Game.h"
4 #include "Actor.h" 6 #include "Actor.h"
5 #include "IndoorCamera.h" 7 #include "IndoorCamera.h"
6 #include "Viewport.h" 8 #include "Viewport.h"
7 #include "stru157.h"
8 9
9 #include "mm7_data.h" 10 #include "mm7_data.h"
10 //#include "MM7.h" 11 //#include "MM7.h"
11 12
12 13
13 static Vis_stru1 Vis_static_sub_4C1944_stru_F8BDE8; 14 static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8;
15
16 Vis_SelectionFilter vis_sprite_filter_1 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E1C
17 Vis_SelectionFilter vis_sprite_filter_2 = {VisObjectType_Sprite, OBJECT_Decoration, 0, 0, 2}; // 00F93E30
18 Vis_SelectionFilter vis_face_filter = {VisObjectType_Face, OBJECT_Any, -1, 0, 0}; // 00F93E44
19 Vis_SelectionFilter vis_door_filter = {VisObjectType_Face, OBJECT_BLVDoor, -1, 0x100000, 0}; // 00F93E58
20 Vis_SelectionFilter vis_sprite_filter_3 = {VisObjectType_Sprite, OBJECT_Decoration, -1, 0, 4}; // 00F93E6C
21 Vis_SelectionFilter vis_sprite_filter_4 = {VisObjectType_Any, OBJECT_Item, -1, 0, 0}; // static to sub_44EEA7
14 22
15 23
16 24
17 //----- (004C1026) -------------------------------------------------------- 25 //----- (004C1026) --------------------------------------------------------
18 Vis_stru1_stru0 *Vis::_4C1026(BLVFace *a2, unsigned int a3, float a4) 26 Vis_ObjectInfo *Vis::_4C1026(BLVFace *a2, unsigned int a3, float a4)
19 { 27 {
20 char *v4; // eax@4 28 char *v4; // eax@4
21 signed int v5; // ecx@4 29 signed int v5; // ecx@4
22 BLVFace *v6; // ecx@7 30 BLVFace *v6; // ecx@7
23 unsigned int v7; // edi@7 31 unsigned int v7; // edi@7
27 Vec3_int_ **v11; // edx@13 35 Vec3_int_ **v11; // edx@13
28 char *v12; // eax@13 36 char *v12; // eax@13
29 double v13; // st7@14 37 double v13; // st7@14
30 signed int v14; // ebx@14 38 signed int v14; // ebx@14
31 Vis *v15; // ebx@15 39 Vis *v15; // ebx@15
32 Vis_stru1_stru0 *result; // eax@21 40 Vis_ObjectInfo *result; // eax@21
33 Vis_stru1_stru0 *v17; // ecx@24 41 Vis_ObjectInfo *v17; // ecx@24
34 RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17 42 RenderVertexSoft pRay[2]; // [sp+20h] [bp-70h]@17
35 int v20; // [sp+84h] [bp-Ch]@10 43 int v20; // [sp+84h] [bp-Ch]@10
36 int v21; // [sp+88h] [bp-8h]@16 44 int v21; // [sp+88h] [bp-8h]@16
37 int v22; // [sp+8Ch] [bp-4h]@16 45 int v22; // [sp+8Ch] [bp-4h]@16
38 signed int v23; // [sp+98h] [bp+8h]@7 46 signed int v23; // [sp+98h] [bp+8h]@7
39 47
40 auto ecx0 = this; 48 auto ecx0 = this;
41 49
42 static Vis_stru1 static_sub_4C1026_stru_F8FE00; 50 static Vis_SelectionList static_sub_4C1026_stru_F8FE00;
43 static_sub_4C1026_stru_F8FE00.uNumPointers = 0; 51 static_sub_4C1026_stru_F8FE00.uNumPointers = 0;
44 52
45 static bool _init_flag = false; 53 static bool _init_flag = false;
46 static RenderVertexSoft static_sub_4C1026_array_F8F200[64]; 54 static RenderVertexSoft static_sub_4C1026_array_F8F200[64];
47 if (!_init_flag) 55 if (!_init_flag)
97 v15 = this; 105 v15 = this;
98 SortVectors_x(static_sub_4C1026_array_F8F200, 0, v7 - 1); 106 SortVectors_x(static_sub_4C1026_array_F8F200, 0, v7 - 1);
99 if ( static_sub_4C1026_array_F8F200[0].vWorldViewPosition.x > (double)a4 107 if ( static_sub_4C1026_array_F8F200[0].vWorldViewPosition.x > (double)a4
100 || (_4C1495(static_sub_4C1026_array_F8F200, v7, (float *)&v21, (float *)&v22), 108 || (_4C1495(static_sub_4C1026_array_F8F200, v7, (float *)&v21, (float *)&v22),
101 _4C12C3_FindSomeBillboard(static_sub_4C1026_array_F8F200, v7, *(float *)&v21, *(float *)&v22)) 109 _4C12C3_FindSomeBillboard(static_sub_4C1026_array_F8F200, v7, *(float *)&v21, *(float *)&v22))
102 || ((CastPickRay(pRay, *(float *)&v21, *(float *)&v22, a4), uCurrentlyLoadedLevelType != LEVEL_Indoor) ? PickOutdoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &a5, 1) : PickIndoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &a5), 110 || ((CastPickRay(pRay, *(float *)&v21, *(float *)&v22, a4), uCurrentlyLoadedLevelType != LEVEL_Indoor) ? PickOutdoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter, 1) : PickIndoor(a4, pRay, &static_sub_4C1026_stru_F8FE00, &vis_face_filter),
103 (static_sub_4C1026_stru_F8FE00.create_object_pointers(0), 111 (static_sub_4C1026_stru_F8FE00.create_object_pointers(Vis_SelectionList::All),
104 sort_object_pointers( 112 sort_object_pointers(
105 static_sub_4C1026_stru_F8FE00.array_1804, 113 static_sub_4C1026_stru_F8FE00.object_pointers,
106 0, 114 0,
107 static_sub_4C1026_stru_F8FE00.uNumPointers - 1), 115 static_sub_4C1026_stru_F8FE00.uNumPointers - 1),
108 !static_sub_4C1026_stru_F8FE00.uNumPointers) 116 !static_sub_4C1026_stru_F8FE00.uNumPointers)
109 || (result = static_sub_4C1026_stru_F8FE00.sub_4C2551(2, a3)) == 0 117 || (result = static_sub_4C1026_stru_F8FE00.sub_4C2551(2, a3)) == 0
110 || (signed int)static_sub_4C1026_stru_F8FE00.uNumPointers > 1 118 || (signed int)static_sub_4C1026_stru_F8FE00.uNumPointers > 1
111 && ((signed int)static_sub_4C1026_stru_F8FE00.uNumPointers <= 0 ? (v17 = 0) : (v17 = static_sub_4C1026_stru_F8FE00.array_1804[0]), 119 && ((signed int)static_sub_4C1026_stru_F8FE00.uNumPointers <= 0 ? (v17 = 0) : (v17 = static_sub_4C1026_stru_F8FE00.object_pointers[0]),
112 result != v17)) ) 120 result != v17)) )
113 result = 0; 121 result = 0;
114 return result; 122 return result;
115 } 123 }
116 // F91E08: using guessed type char static_sub_4C1026_byte_F91E08__init_flags; 124 // F91E08: using guessed type char static_sub_4C1026_byte_F91E08__init_flags;
219 static_sub_4C1495_array_F8DDF8[i].flt_2C = 0.0f; 227 static_sub_4C1495_array_F8DDF8[i].flt_2C = 0.0f;
220 } 228 }
221 229
222 memcpy(static_sub_4C1495_array_F8DDF8, Src, 48 * a2); 230 memcpy(static_sub_4C1495_array_F8DDF8, Src, 48 * a2);
223 sort_objects_2(static_sub_4C1495_array_F8DDF8, 0, a2 - 1); 231 sort_objects_2(static_sub_4C1495_array_F8DDF8, 0, a2 - 1);
224 *a3 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.array_1804[12 * a2 + 509] 232 *a3 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[12 * a2 + 509]
225 - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX) 233 - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX)
226 * 0.5 234 * 0.5
227 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX; 235 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjX;
228 sort_objects_3(static_sub_4C1495_array_F8DDF8, 0, a2 - 1); 236 sort_objects_3(static_sub_4C1495_array_F8DDF8, 0, a2 - 1);
229 result = a4; 237 result = a4;
230 *a4 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.array_1804[12 * a2 + 510] 238 *a4 = (*(float *)&Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[12 * a2 + 510]
231 - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY) 239 - static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY)
232 * 0.5 240 * 0.5
233 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY; 241 + static_sub_4C1495_array_F8DDF8[0].vWorldViewProjY;
234 return result; 242 return result;
235 } 243 }
236 244
237 //----- (004C1542) -------------------------------------------------------- 245 //----- (004C1542) --------------------------------------------------------
238 void Vis::PickBillboards(float fPickDepth, float fX, float fY, Vis_stru1 *a4, stru157 *a2) 246 void Vis::PickBillboards_Mouse(float fPickDepth, float fX, float fY, Vis_SelectionList *list, Vis_SelectionFilter *filter)
239 { 247 {
240 int v6; // ST1C_4@6 248 for (uint i = 0; i < pRenderer->uNumBillboardsToDraw; ++i)
241 Vis_stru1_stru0 *v7; // edi@6 249 {
242 Vis *thisa; // [sp+20h] [bp-Ch]@1 250 auto d3d_billboard = pRenderer->pBillboardRenderListD3D + i;
243 RenderBillboardD3D *v9; // [sp+24h] [bp-8h]@2 251 if (is_part_of_selection((void *)i, filter) && IsPointInsideD3DBillboard(d3d_billboard, fX, fY))
244 unsigned int uD3DBillboardIdx; // [sp+28h] [bp-4h]@1 252 {
245 253 if (DoesRayIntersectBillboard(fPickDepth, i))
246 uD3DBillboardIdx = 0; 254 {
247 thisa = this; 255 auto billboard = &pBillboardRenderList[d3d_billboard->uParentBillboardID];
248 if ( (signed int)pRenderer->uNumBillboardsToDraw > 0 ) 256
249 { 257 list->AddObject((void *)d3d_billboard->uParentBillboardID, VisObjectType_Sprite, billboard->sZValue);
250 v9 = pRenderer->pBillboardRenderListD3D;//[0].uParentBillboardID; 258 }
251 do 259 }
252 {
253 if ( is_part_of_selection((BLVFace *)uD3DBillboardIdx, a2)
254 && IsPointInsideD3DBillboard((RenderBillboardD3D *)(v9 - 38), fX, fY) )
255 {
256 if ( DoesRayIntersectBillboard(fPickDepth, uD3DBillboardIdx) )
257 {
258 v6 = pBillboardRenderList[v9->uParentBillboardID].sZValue;
259 v7 = &a4->array_0004[a4->uNumPointers];
260 v7->pObjectInfo = (void *)v9->uParentBillboardID;
261 v7 = (Vis_stru1_stru0 *)((char *)v7 + 4);
262 v7->pObjectInfo = (void *)v6;
263 v7->sZValue = 1;
264 ++a4->uNumPointers;
265 }
266 }
267 ++uD3DBillboardIdx;
268 ++v9;
269 }
270 while ( (signed int)uD3DBillboardIdx < (signed int)pRenderer->uNumBillboardsToDraw );
271 } 260 }
272 } 261 }
273 262
274 //----- (004C1607) -------------------------------------------------------- 263 //----- (004C1607) --------------------------------------------------------
275 bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y) 264 bool Vis::IsPointInsideD3DBillboard(RenderBillboardD3D *a1, float x, float y)
276 { 265 {
277 RenderBillboardD3D *result; // eax@1 266 //RenderBillboardD3D *result; // eax@1
278 double v5; // st7@2 267 double v5; // st7@2
279 float v6; // ecx@2 268 float v6; // ecx@2
280 float v7; // ST00_4@3 269 float v7; // ST00_4@3
281 __int16 v8; // fps@6 270 __int16 v8; // fps@6
282 double v9; // st6@6 271 double v9; // st6@6
300 unsigned __int8 v27; // c3@9 289 unsigned __int8 v27; // c3@9
301 float v28; // [sp+4h] [bp-8h]@2 290 float v28; // [sp+4h] [bp-8h]@2
302 float v29; // [sp+8h] [bp-4h]@2 291 float v29; // [sp+8h] [bp-4h]@2
303 float a1a; // [sp+14h] [bp+8h]@2 292 float a1a; // [sp+14h] [bp+8h]@2
304 293
305 result = a1;
306 if ( a1->uParentBillboardID == -1 ) 294 if ( a1->uParentBillboardID == -1 )
307 goto LABEL_14; 295 return false;
296
297 //result = a1;
308 v5 = a1->pQuards[0].pos.x; 298 v5 = a1->pQuards[0].pos.x;
309 a1a = a1->pQuards[3].pos.x; 299 a1a = a1->pQuards[3].pos.x;
310 v6 = result->pQuards[0].pos.y; 300 v6 = a1->pQuards[0].pos.y;
311 result = (RenderBillboardD3D *)LODWORD(result->pQuards[1].pos.y); 301 //result = (RenderBillboardD3D *)LODWORD(result->pQuards[1].pos.y);
312 v29 = v6; 302 v29 = v6;
313 LODWORD(v28) = (int)result; 303 v28 = a1->pQuards[1].pos.y;
314 if ( v5 > a1a ) 304 if ( v5 > a1a )
315 { 305 {
316 v7 = v5; 306 v7 = v5;
317 HIWORD(result) = HIWORD(v7); 307 //HIWORD(result) = HIWORD(v7);
318 v5 = a1a; 308 v5 = a1a;
319 a1a = v7; 309 a1a = v7;
320 } 310 }
321 if ( v6 > (double)v28 ) 311 if ( v6 > (double)v28 )
322 { 312 {
323 result = (RenderBillboardD3D *)LODWORD(v28); 313 //result = (RenderBillboardD3D *)LODWORD(v28);
324 v28 = v6; 314 v28 = v6;
325 LODWORD(v29) = (int)result; 315 v29 = v28;
326 } 316 }
327 v9 = x + 1.0; 317 v9 = x + 1.0;
328 //UNDEF(v8); 318 //UNDEF(v8);
329 //v10 = v9 < v5; 319 //v10 = v9 < v5;
330 //v11 = 0; 320 //v11 = 0;
331 //v12 = v9 == v5; 321 //v12 = v9 == v5;
332 //BYTE1(result) = HIBYTE(v8);//crash 322 //BYTE1(result) = HIBYTE(v8);//crash
333 if ( v9 >= v5 323 if (v9 >= v5 &&
334 && (v14 = x - 1.0, v14<=a1a)///*UNDEF(v13),*/ v15 = v14 < a1a, v16 = 0, v17 = v14 == a1a, BYTE1(result) = HIBYTE(v13), v15 | v17) 324 (v14 = x - 1.0, v14<=a1a) &&///*UNDEF(v13),*/ v15 = v14 < a1a, v16 = 0, v17 = v14 == a1a, BYTE1(result) = HIBYTE(v13), v15 | v17)
335 && (v19 = y + 1.0, v19>=v29)///*UNDEF(v18),*/ v20 = v19 < v29, v21 = 0, v22 = v19 == v29, BYTE1(result) = HIBYTE(v18), v19 >= v29) 325 (v19 = y + 1.0, v19>=v29) &&///*UNDEF(v18),*/ v20 = v19 < v29, v21 = 0, v22 = v19 == v29, BYTE1(result) = HIBYTE(v18), v19 >= v29)
336 && (v24 = y - 1.0, v24<=v28))///*UNDEF(v23),*/ v25 = v24 < v28, v26 = 0, v27 = v24 == v28, BYTE1(result) = HIBYTE(v23), v25 | v27) ) 326 (v24 = y - 1.0, v24<=v28))///*UNDEF(v23),*/ v25 = v24 < v28, v26 = 0, v27 = v24 == v28, BYTE1(result) = HIBYTE(v23), v25 | v27) )
337 LOBYTE(result) = 1; 327 return true;
338 else 328 else
339 LABEL_14: 329 return false;
340 LOBYTE(result) = 0;
341 return (bool)result;
342 } 330 }
343 331
344 //----- (004C16B4) -------------------------------------------------------- 332 //----- (004C16B4) --------------------------------------------------------
345 void Vis::PickIndoor(float fDepth, RenderVertexSoft *pRay, Vis_stru1 *a4, stru157 *a5) 333 void Vis::PickIndoor(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter)
346 { 334 {
347 int v5; // eax@1 335 int v5; // eax@1
348 signed int v6; // edi@2 336 signed int v6; // edi@2
349 signed int v7; // esi@4 337 signed int v7; // esi@4
350 int v8; // ecx@7 338 int v8; // ecx@7
351 int v9; // eax@7 339 int v9; // eax@7
352 unsigned int *pNumPointers; // eax@7 340 unsigned int *pNumPointers; // eax@7
353 unsigned int v11; // ecx@7 341 unsigned int v11; // ecx@7
354 Vis_stru1_stru0 *v12; // edi@7 342 Vis_ObjectInfo *v12; // edi@7
355 RenderVertexSoft a1; // [sp+Ch] [bp-44h]@1 343 RenderVertexSoft a1; // [sp+Ch] [bp-44h]@1
356 BLVFace *v14; // [sp+3Ch] [bp-14h]@7 344 BLVFace *v14; // [sp+3Ch] [bp-14h]@7
357 void *v15; // [sp+40h] [bp-10h]@7 345 void *v15; // [sp+40h] [bp-10h]@7
358 int v16; // [sp+44h] [bp-Ch]@7 346 int v16; // [sp+44h] [bp-Ch]@7
359 int v17; // [sp+48h] [bp-8h]@1 347 int v17; // [sp+48h] [bp-8h]@1
368 if ( v6 >= 0 ) 356 if ( v6 >= 0 )
369 { 357 {
370 if ( v6 < (signed int)pIndoor->uNumFaces ) 358 if ( v6 < (signed int)pIndoor->uNumFaces )
371 { 359 {
372 v7 = v6; 360 v7 = v6;
373 if ( is_part_of_selection(&pIndoor->pFaces[v6], a5) ) 361 if ( is_part_of_selection(&pIndoor->pFaces[v6], filter) )
374 { 362 {
375 if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[v7]) ) 363 if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[v7]) )
376 { 364 {
377 if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &pIndoor->pFaces[v7], 0xFFFFFFFFu) ) 365 if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &pIndoor->pFaces[v7], 0xFFFFFFFFu) )
378 { 366 {
379 pGame->pIndoorCameraD3D->ViewTransform(&a1, 1u); 367 pGame->pIndoorCameraD3D->ViewTransform(&a1, 1u);
380 v9 = _48B561_mess_with_scaling_along_z(/*v8, */a1.vWorldViewPosition.x); 368 v9 = _48B561_mess_with_scaling_along_z(/*v8, */a1.vWorldViewPosition.x);
381 LOWORD(v9) = 0; 369 LOWORD(v9) = 0;
382 v15 = (void *)((8 * v6 | 6) + v9); 370 v15 = (void *)((8 * v6 | 6) + v9);
383 pNumPointers = &a4->uNumPointers; 371 pNumPointers = &list->uNumPointers;
384 v16 = 2; 372 v16 = 2;
385 v11 = a4->uNumPointers; 373 v11 = list->uNumPointers;
386 v14 = &pIndoor->pFaces[v7]; 374 v14 = &pIndoor->pFaces[v7];
387 v12 = &a4->array_0004[v11]; 375 v12 = &list->object_pool[v11];
388 v12->pObjectInfo = &pIndoor->pFaces[v7]; 376 v12->object = &pIndoor->pFaces[v7];
389 v12 = (Vis_stru1_stru0 *)((char *)v12 + 4); 377 v12 = (Vis_ObjectInfo *)((char *)v12 + 4);
390 v12->pObjectInfo = v15; 378 v12->object = v15;
391 v12->sZValue = v16; 379 v12->sZValue = v16;
392 ++*pNumPointers; 380 ++*pNumPointers;
393 } 381 }
394 } 382 }
395 } 383 }
398 v5 = v17 + 1; 386 v5 = v17 + 1;
399 } 387 }
400 } 388 }
401 389
402 //----- (004C17CF) -------------------------------------------------------- 390 //----- (004C17CF) --------------------------------------------------------
403 void Vis::PickOutdoor(float fDepth, RenderVertexSoft *pRay, Vis_stru1 *a4, stru157 *a5, char a6) 391 void Vis::PickOutdoor(float fDepth, RenderVertexSoft *pRay, Vis_SelectionList *list, Vis_SelectionFilter *filter, char a6)
404 { 392 {
405 int v6; // esi@1 393 int v6; // esi@1
406 unsigned int v7; // ecx@1 394 unsigned int v7; // ecx@1
407 BSPModel *v8; // ebx@3 395 BSPModel *v8; // ebx@3
408 bool v9; // eax@3 396 bool v9; // eax@3
409 int v10; // eax@8 397 int v10; // eax@8
410 ODMFace *v11; // esi@10 398 ODMFace *v11; // esi@10
411 int v12; // ecx@12 399 int v12; // ecx@12
412 int v13; // eax@12 400 int v13; // eax@12
413 unsigned int *pNumPointers; // eax@12 401 unsigned int *pNumPointers; // eax@12
414 Vis_stru1_stru0 *v15; // edi@12 402 Vis_ObjectInfo *v15; // edi@12
415 BLVFace thisa; // [sp+10h] [bp-B8h]@1 403 BLVFace thisa; // [sp+10h] [bp-B8h]@1
416 RenderVertexSoft a1; // [sp+70h] [bp-58h]@1 404 RenderVertexSoft a1; // [sp+70h] [bp-58h]@1
417 void *v18; // [sp+A0h] [bp-28h]@12 405 void *v18; // [sp+A0h] [bp-28h]@12
418 void *v19; // [sp+A4h] [bp-24h]@12 406 void *v19; // [sp+A4h] [bp-24h]@12
419 int v20; // [sp+A8h] [bp-20h]@12 407 int v20; // [sp+A8h] [bp-20h]@12
452 { 440 {
453 v23 = v6; 441 v23 = v6;
454 do 442 do
455 { 443 {
456 v11 = (ODMFace *)((char *)v8->pFaces + v23); 444 v11 = (ODMFace *)((char *)v8->pFaces + v23);
457 if ( is_part_of_selection((BLVFace *)((char *)v8->pFaces + v23), a5) ) 445 if ( is_part_of_selection((BLVFace *)((char *)v8->pFaces + v23), filter) )
458 { 446 {
459 thisa.FromODM(v11); 447 thisa.FromODM(v11);
460 if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &thisa, v26) ) 448 if ( Intersect_Ray_Face(pRay, pRay + 1, &fDepth, &a1, &thisa, v26) )
461 { 449 {
462 pGame->pIndoorCameraD3D->ViewTransform(&a1, 1u); 450 pGame->pIndoorCameraD3D->ViewTransform(&a1, 1u);
463 v18 = v11; 451 v18 = v11;
464 v13 = _48B561_mess_with_scaling_along_z(/*v12, */a1.vWorldViewPosition.x); 452 v13 = _48B561_mess_with_scaling_along_z(/*v12, */a1.vWorldViewPosition.x);
465 LOWORD(v13) = 0; 453 LOWORD(v13) = 0;
466 v20 = 2; 454 v20 = 2;
467 v19 = (void *)((8 * (v27 | (v26 << 6)) | 6) + v13); 455 v19 = (void *)((8 * (v27 | (v26 << 6)) | 6) + v13);
468 pNumPointers = &a4->uNumPointers; 456 pNumPointers = &list->uNumPointers;
469 v15 = &a4->array_0004[a4->uNumPointers]; 457 v15 = &list->object_pool[list->uNumPointers];
470 v15->pObjectInfo = v18; 458 v15->object = v18;
471 v15 = (Vis_stru1_stru0 *)((char *)v15 + 4); 459 v15 = (Vis_ObjectInfo *)((char *)v15 + 4);
472 v15->pObjectInfo = v19; 460 v15->object = v19;
473 v15->sZValue = v20; 461 v15->sZValue = v20;
474 ++*pNumPointers; 462 ++*pNumPointers;
475 } 463 }
476 } 464 }
477 ++v27; 465 ++v27;
499 //----- (004C1930) -------------------------------------------------------- 487 //----- (004C1930) --------------------------------------------------------
500 //bool Vis::j_DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) 488 //bool Vis::j_DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx)
501 //{return DoesRayIntersectBillboard(fDepth, uD3DBillboardIdx);} 489 //{return DoesRayIntersectBillboard(fDepth, uD3DBillboardIdx);}
502 490
503 //----- (004C1944) -------------------------------------------------------- 491 //----- (004C1944) --------------------------------------------------------
504 int Vis::_4C1944(int a2, unsigned int a3, int a4, int a5, int a6) 492 int Vis::_4C1944(int object_id, unsigned int a3, int a4, int a5, int a6)
505 { 493 {
506 float v6; // ST00_4@3 494 float v6; // ST00_4@3
507 int result; // eax@4 495 int result; // eax@4
508 stru157 v8; // [sp+18h] [bp-20h]@3 496 Vis_SelectionFilter v8; // [sp+18h] [bp-20h]@3
509 __int64 v9; // [sp+2Ch] [bp-Ch]@3 497 __int64 v9; // [sp+2Ch] [bp-Ch]@3
510 Vis *v14; // [sp+34h] [bp-4h]@1 498 Vis *v14; // [sp+34h] [bp-4h]@1
511 499
512 v14 = this; 500 v14 = this;
513 501
514 static Vis_stru1 Vis_static_sub_4C1944_stru_F8BDE8; 502 static Vis_SelectionList Vis_static_sub_4C1944_stru_F8BDE8;
515 503
516 v8.field_4 = a2; 504 v8.object_id = object_id;
517 v8.field_8 = a6; 505 v8.field_8 = a6;
518 v8.field_C = a5; 506 v8.field_C = a5;
519 v8.field_10 = a4; 507 v8.field_10 = a4;
520 v9 = a3; 508 v9 = a3;
521 Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0; 509 Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers = 0;
522 v6 = (double)a3; 510 v6 = (double)a3;
523 v8.field_0 = 1; 511 v8.object_type = VisObjectType_Sprite;
524 _4C06F8(v6, &Vis_static_sub_4C1944_stru_F8BDE8, &v8); 512 PickBillboards_All(v6, &Vis_static_sub_4C1944_stru_F8BDE8, &v8);
525 Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(1u); 513 Vis_static_sub_4C1944_stru_F8BDE8.create_object_pointers(Vis_SelectionList::Unique);
526 sort_object_pointers( 514 sort_object_pointers(
527 Vis_static_sub_4C1944_stru_F8BDE8.array_1804, 515 Vis_static_sub_4C1944_stru_F8BDE8.object_pointers,
528 0, 516 0,
529 Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers - 1); 517 Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers - 1);
530 if ( (signed int)Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers <= 0 ) 518 if ( (signed int)Vis_static_sub_4C1944_stru_F8BDE8.uNumPointers <= 0 )
531 result = -1; 519 result = -1;
532 else 520 else
533 result = Vis_static_sub_4C1944_stru_F8BDE8.array_1804[0]->sZValue; 521 result = Vis_static_sub_4C1944_stru_F8BDE8.object_pointers[0]->sZValue;
534 return result; 522 return result;
535 } 523 }
536 // F8DDF0: using guessed type char Vis_static_sub_4C1944_byte_F8DDF0_init;
537 524
538 //----- (004C1A02) -------------------------------------------------------- 525 //----- (004C1A02) --------------------------------------------------------
539 void Vis::_4C1A02() 526 void Vis::_4C1A02()
540 { 527 {
541 RenderVertexSoft v1; // [sp+8h] [bp-C0h]@1 528 RenderVertexSoft v1; // [sp+8h] [bp-C0h]@1
624 } 611 }
625 return true; 612 return true;
626 } 613 }
627 614
628 //----- (004C1BAA) -------------------------------------------------------- 615 //----- (004C1BAA) --------------------------------------------------------
629 int Vis::get_object_zbuf_val(Vis_stru1_stru0 *a2) 616 int Vis::get_object_zbuf_val(Vis_ObjectInfo *info)
630 { 617 {
631 unsigned int v2; // eax@1 618 switch (info->object_type)
632 int result; // eax@3 619 {
633 std::string v4; // [sp-18h] [bp-1Ch]@4 620 case VisObjectType_Sprite:
634 const char *v5; // [sp-8h] [bp-Ch]@4 621 case VisObjectType_Face:
635 int v6; // [sp-4h] [bp-8h]@4 622 return info->sZValue;
636 Vis *v7; // [sp+0h] [bp-4h]@1 623
637 624 default:
638 v7 = this; 625 MessageBoxW(nullptr, L"Undefined type requested for: CVis::get_object_zbuf_val()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1037", 0);
639 v2 = a2->uObjectType; 626 return -1;
640 if ( (signed int)v2 <= 0 || (signed int)v2 > 2 ) 627 }
641 {
642 MessageBoxW(nullptr, L"Undefined type requested for: CVis::get_object_zbuf_val()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1037", 0);
643 result = -1;
644 }
645 else
646 {
647 result = a2->sZValue;
648 }
649 return result;
650 } 628 }
651 629
652 //----- (004C1BF1) -------------------------------------------------------- 630 //----- (004C1BF1) --------------------------------------------------------
653 int Vis::get_picked_object_zbuf_val() 631 int Vis::get_picked_object_zbuf_val()
654 { 632 {
655 int result; // eax@2 633 if (!default_list.uNumPointers)
656 634 return -1;
657 if ( (signed int)this->stru1.uNumPointers <= 0 ) 635
658 result = -1; 636 return get_object_zbuf_val(default_list.object_pointers[0]);
659 else
660 result = get_object_zbuf_val(this->stru1.array_1804[0]);
661 return result;
662 } 637 }
663 638
664 //----- (004C1C0C) -------------------------------------------------------- 639 //----- (004C1C0C) --------------------------------------------------------
665 bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6) 640 bool Vis::Intersect_Ray_Face(RenderVertexSoft *pRayStart, RenderVertexSoft *pRayEnd, float *pDepth, RenderVertexSoft *a4, BLVFace *a5, unsigned int a6)
666 { 641 {
1124 memcpy(pRay, &v11[1], 0x30u); 1099 memcpy(pRay, &v11[1], 0x30u);
1125 memcpy(&pRay[1], v11, sizeof(pRay[1])); 1100 memcpy(&pRay[1], v11, sizeof(pRay[1]));
1126 } 1101 }
1127 1102
1128 //----- (004C2551) -------------------------------------------------------- 1103 //----- (004C2551) --------------------------------------------------------
1129 Vis_stru1_stru0 *Vis_stru1::sub_4C2551(int a2, int a3) 1104 Vis_ObjectInfo *Vis_SelectionList::sub_4C2551(int a2, int a3)
1130 { 1105 {
1131 unsigned int v3; // esi@1 1106 unsigned int v3; // esi@1
1132 signed int v4; // edx@1 1107 signed int v4; // edx@1
1133 char *v5; // eax@2 1108 char *v5; // eax@2
1134 Vis_stru1_stru0 *result; // eax@6 1109 Vis_ObjectInfo *result; // eax@6
1135 1110
1136 v3 = this->uNumPointers; 1111 v3 = this->uNumPointers;
1137 v4 = 0; 1112 v4 = 0;
1138 if ( (signed int)v3 <= 0 ) 1113 if ( (signed int)v3 <= 0 )
1139 { 1114 {
1140 LABEL_6: 1115 LABEL_6:
1141 result = 0; 1116 result = 0;
1142 } 1117 }
1143 else 1118 else
1144 { 1119 {
1145 v5 = (char *)&this->array_0004[0].sZValue; 1120 v5 = (char *)&this->object_pool[0].sZValue;
1146 while ( *((int *)v5 + 1) != a2 || (*(int *)v5 & 0xFFFF) != a3 ) 1121 while ( *((int *)v5 + 1) != a2 || (*(int *)v5 & 0xFFFF) != a3 )
1147 { 1122 {
1148 ++v4; 1123 ++v4;
1149 v5 += 12; 1124 v5 += 12;
1150 if ( v4 >= (signed int)v3 ) 1125 if ( v4 >= (signed int)v3 )
1151 goto LABEL_6; 1126 goto LABEL_6;
1152 } 1127 }
1153 result = &this->array_0004[v4]; 1128 result = &this->object_pool[v4];
1154 } 1129 }
1155 return result; 1130 return result;
1156 } 1131 }
1157 1132
1158 //----- (004C2591) -------------------------------------------------------- 1133 //----- (004C2591) --------------------------------------------------------
1159 Vis_stru1_stru0 **Vis_stru1::create_object_pointers(unsigned int flag) 1134 void Vis_SelectionList::create_object_pointers(PointerCreationType type)
1160 { 1135 {
1161 Vis_stru1_stru0 **result; // eax@1 1136 switch (type)
1162 signed int v3; // esi@2 1137 {
1163 Vis_stru1_stru0 *v4; // edx@3 1138 case All:
1164 unsigned __int8 v5; // zf@7 1139 {
1165 unsigned __int8 v6; // sf@7 1140 for (uint i = 0; i < uNumPointers; ++i)
1166 Vis_stru1_stru0 **v7; // ebx@8 1141 object_pointers[i] = &object_pool[i];
1167 Vis_stru1_stru0 *v8; // esi@8 1142 }
1168 signed int v9; // edi@9 1143 break;
1169 Vis_stru1_stru0 **v10; // edx@10 1144
1170 std::string v11; // [sp-18h] [bp-28h]@19 1145 case Unique: // seems quite retarted; the inner if condition will never trigger, since we compare pointers, not values. pointers will always be unique
1171 const char *v12; // [sp-8h] [bp-18h]@19 1146 { // but it may be decompilation error thou
1172 int v13; // [sp-4h] [bp-14h]@19 1147 bool create = true;
1173 char v14; // [sp+Ch] [bp-4h]@19 1148
1174 1149 for (uint i = 0; i < uNumPointers; ++i)
1175 result = 0; 1150 {
1176 if ( flag ) 1151 for (uint j = 0; j < i; ++j)
1177 {
1178 if ( flag == 1 )
1179 {
1180 v5 = this->uNumPointers == 0;
1181 v6 = (this->uNumPointers & 0x80000000u) != 0;
1182 BYTE3(flag) = 1;
1183 if ( !(v6 | v5) )
1184 {
1185 v7 = this->array_1804;
1186 v8 = this->array_0004;
1187 do
1188 { 1152 {
1189 v9 = 0; 1153 if (object_pointers[j] == &object_pool[i])
1190 if ( (signed int)result > 0 )
1191 { 1154 {
1192 v10 = this->array_1804; 1155 create = false;
1193 while ( *v10 != v8 ) 1156 break;
1194 {
1195 ++v9;
1196 ++v10;
1197 if ( v9 >= (signed int)result )
1198 goto LABEL_15;
1199 }
1200 BYTE3(flag) = 0;
1201 } 1157 }
1202 LABEL_15:
1203 if ( BYTE3(flag) )
1204 *v7 = v8;
1205 result = (Vis_stru1_stru0 **)((char *)result + 1);
1206 ++v7;
1207 ++v8;
1208 } 1158 }
1209 while ( (signed int)result < (signed int)this->uNumPointers ); 1159
1210 } 1160 if (create)
1211 } 1161 object_pointers[i] = &object_pool[i];
1212 else 1162 }
1213 { 1163 }
1164
1165 default:
1214 MessageBoxW(nullptr, L"Unknown pointer creation flag passed to ::create_object_pointers()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1358", 0); 1166 MessageBoxW(nullptr, L"Unknown pointer creation flag passed to ::create_object_pointers()", L"E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:1358", 0);
1215 } 1167 }
1216 }
1217 else
1218 {
1219 v3 = 0;
1220 if ( (signed int)this->uNumPointers > 0 )
1221 {
1222 result = this->array_1804;
1223 v4 = this->array_0004;
1224 do
1225 {
1226 *result = v4;
1227 ++v3;
1228 ++result;
1229 ++v4;
1230 }
1231 while ( v3 < (signed int)this->uNumPointers );
1232 }
1233 }
1234 return result;
1235 } 1168 }
1236 1169
1237 //----- (004C264A) -------------------------------------------------------- 1170 //----- (004C264A) --------------------------------------------------------
1238 void Vis::sort_object_pointers(Vis_stru1_stru0 **pPointers, int left, int right) 1171 void Vis::sort_object_pointers(Vis_ObjectInfo **pPointers, int left, int right)
1239 { 1172 {
1240 int v4; // edx@1 1173 int v4; // edx@1
1241 int v5; // ebx@1 1174 int v5; // ebx@1
1242 int v6; // esi@2 1175 int v6; // esi@2
1243 signed int i; // ecx@2 1176 signed int i; // ecx@2
1244 int v8; // eax@3 1177 int v8; // eax@3
1245 int v9; // ebx@4 1178 int v9; // ebx@4
1246 int v10; // ebx@6 1179 int v10; // ebx@6
1247 Vis_stru1_stru0 *v11; // eax@7 1180 Vis_ObjectInfo *v11; // eax@7
1248 Vis *thisa; // [sp+4h] [bp-4h]@1 1181 Vis *thisa; // [sp+4h] [bp-4h]@1
1249 Vis_stru1_stru0 *a3a; // [sp+14h] [bp+Ch]@2 1182 Vis_ObjectInfo *a3a; // [sp+14h] [bp+Ch]@2
1250 1183
1251 v4 = left; 1184 v4 = left;
1252 v5 = right; 1185 v5 = right;
1253 thisa = this; 1186 thisa = this;
1254 if ( right > left ) 1187 if ( right > left )
1408 v7 = v11; 1341 v7 = v11;
1409 } 1342 }
1410 memcpy(&v12, &v5[v8], sizeof(v12)); 1343 memcpy(&v12, &v5[v8], sizeof(v12));
1411 memcpy(&v5[v8], v15, sizeof(v5[v8])); 1344 memcpy(&v5[v8], v15, sizeof(v5[v8]));
1412 memcpy(v15, &v12, 0x20u); 1345 memcpy(v15, &v12, 0x20u);
1413 //__debugbreak(); 1346 SortVerticesByY(v5, uStart, v8 - 1);
1414 SortVerticesByX(v5, uStart, v8 - 1); 1347 SortVerticesByY(a2, v8 + 1, uEnd);
1415 SortVerticesByX(a2, v8 + 1, uEnd);
1416 } 1348 }
1417 return true; 1349 return true;
1418 } 1350 }
1419 1351
1420 //----- (004C288E) -------------------------------------------------------- 1352 //----- (004C288E) --------------------------------------------------------
1568 memcpy(&v1->stru_209C, &v4, sizeof(v1->stru_209C)); 1500 memcpy(&v1->stru_209C, &v4, sizeof(v1->stru_209C));
1569 v1->field_20CC = 512; 1501 v1->field_20CC = 512;
1570 } 1502 }
1571 1503
1572 //----- (004C055C) -------------------------------------------------------- 1504 //----- (004C055C) --------------------------------------------------------
1573 Vis_stru1::Vis_stru1() 1505 Vis_SelectionList::Vis_SelectionList()
1574 { 1506 {
1575 for (uint i = 0; i < 512; ++i) 1507 for (uint i = 0; i < 512; ++i)
1576 { 1508 {
1577 array_0004[i].pObjectInfo = 0; 1509 object_pool[i].object = nullptr;
1578 array_0004[i].sZValue = -1; 1510 object_pool[i].sZValue = -1;
1579 array_0004[i].uObjectType = 0; 1511 object_pool[i].object_type = VisObjectType_Any;
1580 } 1512 }
1581 uNumPointers = 0; 1513 uNumPointers = 0;
1582 } 1514 }
1583 1515
1584 //----- (004C05CC) -------------------------------------------------------- 1516 //----- (004C05CC) --------------------------------------------------------
1585 bool Vis::PickKeyboard(Vis_stru1 *a2, stru157 *a3, stru157 *a4) 1517 bool Vis::PickKeyboard(Vis_SelectionList *list, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter)
1586 { 1518 {
1587 Vis_stru1 *v4; // esi@1 1519 if (!list)
1588 Vis *v5; // ebx@1 1520 list = &default_list;
1589 char *v6; // edi@3 1521 list->uNumPointers = 0;
1590 float v7; // ST00_4@3 1522
1591 bool result; // eax@6 1523 PickBillboards_All(field_20CC, list, face_filter);
1592 float v9; // [sp+4h] [bp-14h]@3 1524 if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
1593 1525 _4C0D32_KeyboardPickFaces_BLV(field_20CC, list, face_filter);
1594 v4 = a2; 1526 else if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
1595 v5 = this; 1527 _4C0DEA_KeyboardPickFaces_ODM(field_20CC, list, face_filter);
1596 if ( !a2 )
1597 v4 = &this->stru1;
1598 v4->uNumPointers = 0;
1599 v6 = (char *)&this->field_20CC;
1600 v7 = (double)this->field_20CC;
1601 _4C06F8(v7, v4, a3);
1602 v9 = (double)*(signed int *)v6;
1603 if ( uCurrentlyLoadedLevelType == LEVEL_Indoor )
1604 _4C0D32_BLV(v9, v4, a4);
1605 else 1528 else
1606 _4C0DEA_ODM(v9, v4, a4); 1529 assert(false);
1607 v4->create_object_pointers(1u); 1530
1608 sort_object_pointers(v4->array_1804, 0, v4->uNumPointers - 1); 1531 list->create_object_pointers(Vis_SelectionList::Unique);
1532 sort_object_pointers(list->object_pointers, 0, list->uNumPointers - 1);
1533
1609 return true; 1534 return true;
1610 } 1535 }
1611 1536
1612 //----- (004C0646) -------------------------------------------------------- 1537 //----- (004C0646) --------------------------------------------------------
1613 bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY, stru157 *a5, stru157 *a6) 1538 bool Vis::PickMouse(float fDepth, float fMouseX, float fMouseY, Vis_SelectionFilter *sprite_filter, Vis_SelectionFilter *face_filter)
1614 { 1539 {
1615 RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1 1540 RenderVertexSoft pMouseRay[2]; // [sp+1Ch] [bp-60h]@1
1616 1541
1617 stru1.uNumPointers = 0; 1542 default_list.uNumPointers = 0;
1618 CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth); 1543 CastPickRay(pMouseRay, fMouseX, fMouseY, fDepth);
1619 //PickBillboards(fDepth, fMouseX, fMouseY, &stru1, a5);//Ritor1: do comment to test 1544 PickBillboards_Mouse(fDepth, fMouseX, fMouseY, &default_list, sprite_filter);
1620 if (uCurrentlyLoadedLevelType == LEVEL_Indoor) 1545 if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
1621 PickIndoor(fDepth, pMouseRay, &stru1, a6); 1546 PickIndoor(fDepth, pMouseRay, &default_list, face_filter);
1622 else 1547 else
1623 PickOutdoor(fDepth, pMouseRay, &stru1, a6, 0); 1548 PickOutdoor(fDepth, pMouseRay, &default_list, face_filter, 0);
1624 stru1.create_object_pointers(0); 1549 default_list.create_object_pointers(Vis_SelectionList::All);
1625 sort_object_pointers(stru1.array_1804, 0, stru1.uNumPointers - 1); 1550 sort_object_pointers(default_list.object_pointers, 0, default_list.uNumPointers - 1);
1551
1626 return true; 1552 return true;
1627 } 1553 }
1628 1554
1629 //----- (004C06F8) -------------------------------------------------------- 1555 //----- (004C06F8) --------------------------------------------------------
1630 void Vis::_4C06F8(float arg0, Vis_stru1 *a3, stru157 *a2) 1556 void Vis::PickBillboards_All(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
1631 { 1557 {
1632 int v4; // ST18_4@5 1558 for (int i = 0; i < pRenderer->uNumBillboardsToDraw; ++i)
1633 Vis_stru1_stru0 *v5; // edi@5 1559 {
1634 void **v7; // [sp+24h] [bp-8h]@2 1560 auto d3d_billboard = &pRenderer->pBillboardRenderListD3D[i];
1635 unsigned int uD3DBillboardIdx; // [sp+28h] [bp-4h]@1 1561
1636 1562 if (is_part_of_selection((void *)i, filter))
1637 uD3DBillboardIdx = 0; 1563 {
1638 auto ecx0 = this; 1564 if (DoesRayIntersectBillboard(pick_depth, i))
1639 if ( (signed int)pRenderer->uNumBillboardsToDraw > 0 ) 1565 {
1640 { 1566 auto billboard = &pBillboardRenderList[d3d_billboard->uParentBillboardID];
1641 v7 = (void **)&pRenderer->pBillboardRenderListD3D[0].uParentBillboardID; 1567
1642 do 1568 list->AddObject((void *)d3d_billboard->uParentBillboardID, VisObjectType_Sprite, billboard->sZValue);
1643 { 1569 }
1644 if ( is_part_of_selection((BLVFace *)uD3DBillboardIdx, a2) ) 1570 }
1645 { 1571 }
1646 if ( DoesRayIntersectBillboard(arg0, uD3DBillboardIdx) ) 1572 }
1647 { 1573
1648 v4 = pBillboardRenderList[(int)*v7].sZValue; 1574
1649 v5 = &a3->array_0004[a3->uNumPointers]; 1575 // tests the object against selection filter to determine whether it can be picked or not
1650 v5->pObjectInfo = *v7;
1651 v5 = (Vis_stru1_stru0 *)((char *)v5 + 4);
1652 v5->pObjectInfo = (void *)v4;
1653 v5->sZValue = 1;
1654 ++a3->uNumPointers;
1655 }
1656 }
1657 ++uD3DBillboardIdx;
1658 v7 += 39;
1659 }
1660 while ( (signed int)uD3DBillboardIdx < (signed int)pRenderer->uNumBillboardsToDraw );
1661 }
1662 }
1663
1664 //----- (004C0791) -------------------------------------------------------- 1576 //----- (004C0791) --------------------------------------------------------
1665 bool Vis::is_part_of_selection(BLVFace *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, stru157 *a2) 1577 bool Vis::is_part_of_selection(void *uD3DBillboardIdx_or_pBLVFace_or_pODMFace, Vis_SelectionFilter *filter)
1666 { 1578 {
1667 stru157 *v3; // esi@1 1579 //stru157 *v3; // esi@1
1668 int result; // eax@1 1580 //int result; // eax@1
1669 int v5; // edx@2 1581 int v5; // edx@2
1670 int v6; // ecx@2 1582 //int v6; // ecx@2
1671 char v7; // zf@3 1583 //char v7; // zf@3
1672 int v8; // esi@5 1584 int v8; // esi@5
1673 std::string *v9; // ecx@7 1585 std::string *v9; // ecx@7
1674 Actor *v10; // edi@18 1586 Actor *v10; // edi@18
1675 char v11; // zf@26 1587 //const char *v12; // [sp-20h] [bp-2Ch]@7
1676 const char *v12; // [sp-20h] [bp-2Ch]@7
1677 int v13; // [sp-1Ch] [bp-28h]@7 1588 int v13; // [sp-1Ch] [bp-28h]@7
1678 std::string v14; // [sp-18h] [bp-24h]@7 1589 //std::string v14; // [sp-18h] [bp-24h]@7
1679 const char *v15; // [sp-8h] [bp-14h]@7 1590 //const char *v15; // [sp-8h] [bp-14h]@7
1680 int v16; // [sp-4h] [bp-10h]@7 1591 int v16; // [sp-4h] [bp-10h]@7
1681 1592
1682 v3 = a2; 1593 switch (filter->object_type)
1683 result = a2->field_0; 1594 {
1684 if ( a2->field_0 != 1 ) 1595 case VisObjectType_Any:
1685 {
1686 if ( result != 2
1687 || (uCurrentlyLoadedLevelType != LEVEL_Indoor ? (v11 = LOWORD(uD3DBillboardIdx_or_pBLVFace_or_pODMFace[3].pFacePlane.vNormal.y) == 0,
1688 result = uD3DBillboardIdx_or_pBLVFace_or_pODMFace->pFacePlane_old.dist) : (v11 = pIndoor->pFaceExtras[uD3DBillboardIdx_or_pBLVFace_or_pODMFace->uFaceExtraID].uEventID == 0, result = uD3DBillboardIdx_or_pBLVFace_or_pODMFace->uAttributes),
1689 a2->field_4 != 1) )
1690 goto LABEL_16;
1691 if ( v11 || result & a2->field_C )
1692 goto LABEL_33;
1693 v7 = (result & a2->field_8) == 0;
1694 goto LABEL_32;
1695 }
1696 v5 = a2->field_10;
1697 result = (pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].uParentBillboardID].sZValue & 0xFFFF) >> 3;
1698 v6 = pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].uParentBillboardID].sZValue & 7;
1699 if ( v5 & 2 )
1700 {
1701 v7 = v6 == a2->field_4;
1702 goto LABEL_32;
1703 }
1704 if ( v5 & 4 )
1705 {
1706 v8 = a2->field_4;
1707 if ( v6 != v8 )
1708 goto LABEL_16;
1709 if ( v8 != 5 )
1710 {
1711 v15 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:207";
1712 v12 = "Unsupported \"exclusion if no event\" type in CVis::is_part_of_selection";
1713 LABEL_15:
1714 MessageBoxA(nullptr, v12, v15, 0);
1715 return true; 1596 return true;
1716 } 1597
1717 result *= 32; 1598 case VisObjectType_Sprite:
1718 if ( *(__int16 *)((char *)&pLevelDecorations[0].uCog + result) 1599 {
1719 || *(__int16 *)((char *)&pLevelDecorations[0].field_16_event_id + result) ) 1600 v5 = filter->field_10;
1720 goto LABEL_16; 1601 int object_idx = (pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].uParentBillboardID].object_pid & 0xFFFF) >> 3;
1721 result = pLevelDecorations[result / sizeof(LevelDecoration)].IsInteractive(); 1602 int object_type = pBillboardRenderList[pRenderer->pBillboardRenderListD3D[(int)uD3DBillboardIdx_or_pBLVFace_or_pODMFace].uParentBillboardID].object_pid & 7;
1722 goto LABEL_11; 1603 if ( v5 & 2 )
1723 } 1604 {
1724 if ( v6 == a2->field_4 ) 1605 if (object_type == filter->object_id)
1725 { 1606 return false;
1726 if ( v6 != 3 ) 1607 return true;
1727 { 1608 }
1728 v15 = "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:245"; 1609 if ( v5 & 4 )
1729 v12 = "Default case reached in VIS"; 1610 {
1730 goto LABEL_15; 1611 v8 = filter->object_id;
1731 } 1612 if ( object_type != filter->object_id)
1732 v10 = &pActors[result]; 1613 return true;
1733 result = 1 << LOBYTE(v10->uAIState); 1614 if (v8 != OBJECT_Decoration)
1734 if ( result & a2->field_C 1615 {
1735 || !(result & a2->field_8) 1616 MessageBoxA(nullptr, "Unsupported \"exclusion if no event\" type in CVis::is_part_of_selection", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:207", 0);
1736 || v5 & 8 && (result = MonsterStats::BelongsToSupertype(v10->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD)) == 0 ) 1617 return true;
1737 goto LABEL_33; 1618 }
1738 if ( !(v3->field_10 & 1) ) 1619 if (pLevelDecorations[object_idx].uCog || pLevelDecorations[object_idx].field_16_event_id)
1739 goto LABEL_16; 1620 return true;
1740 result = v10->GetActorsRelation(nullptr); 1621 return pLevelDecorations[object_idx].IsInteractive();
1741 LABEL_11: 1622 }
1742 v7 = result == 0; 1623 if (object_type == filter->object_id)
1743 LABEL_32: 1624 {
1744 if ( v7 ) 1625 if (object_type != OBJECT_Actor)
1745 goto LABEL_33; 1626 {
1746 LABEL_16: 1627 MessageBoxA(nullptr, "Default case reached in VIS", "E:\\WORK\\MSDEV\\MM7\\MM7\\Code\\Vis.cpp:245", 0);
1747 return true; 1628 return true;
1748 } 1629 }
1749 LABEL_33: 1630
1750 LOBYTE(result) = 0; 1631 v10 = &pActors[object_idx];
1751 return result; 1632 int result = 1 << LOBYTE(v10->uAIState);
1633 if ( result & filter->field_C
1634 || !(result & filter->field_8)
1635 || v5 & 8 && (result = MonsterStats::BelongsToSupertype(v10->pMonsterInfo.uID, MONSTER_SUPERTYPE_UNDEAD)) == 0 )
1636 return false;
1637 if ( !(filter->field_10 & 1) )
1638 return true;
1639
1640 result = v10->GetActorsRelation(nullptr);
1641 if (result == 0)
1642 return false;
1643 return true;
1644 }
1645 return false;
1646 }
1647
1648 case VisObjectType_Face:
1649 {
1650 uint face_attrib = 0;
1651 bool no_event = true;
1652 if (uCurrentlyLoadedLevelType == LEVEL_Outdoor)
1653 {
1654 auto face = (ODMFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace;
1655 no_event = face->sCogTriggeredID == 0;
1656 face_attrib = face->uAttributes;
1657 }
1658 else if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
1659 {
1660 auto face = (BLVFace *)uD3DBillboardIdx_or_pBLVFace_or_pODMFace;
1661 no_event = pIndoor->pFaceExtras[face->uFaceExtraID].uEventID == 0;
1662 face_attrib = face->uAttributes;
1663 }
1664 else
1665 assert(false);
1666
1667 if (filter->object_id != OBJECT_BLVDoor)
1668 return true;
1669 if (no_event || face_attrib & filter->field_C)
1670 return false;
1671 return (face_attrib & filter->field_8) != 0;
1672 }
1673
1674 default:
1675 assert(false);
1676 }
1752 } 1677 }
1753 1678
1754 //----- (004C091D) -------------------------------------------------------- 1679 //----- (004C091D) --------------------------------------------------------
1755 bool Vis::DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx) 1680 bool Vis::DoesRayIntersectBillboard(float fDepth, unsigned int uD3DBillboardIdx)
1756 { 1681 {
1757 int v3; // eax@3 1682 int v3; // eax@3
1758 //signed int v5; // ecx@4 1683 //signed int v5; // ecx@4
1759 //float v6; // ST04_4@6 1684 //float v6; // ST04_4@6
1760 //float v7; // ST00_4@7 1685 //float v7; // ST00_4@7
1761 int v8; // eax@10 1686 //int v8; // eax@10
1762 unsigned int v9; // eax@12 1687 //unsigned int v9; // eax@12
1763 int v10; // eax@17 1688 int v10; // eax@17
1764 double v11; // st6@18 1689 double v11; // st6@18
1765 double v12; // st7@18 1690 double v12; // st7@18
1766 double v13; // st4@18 1691 double v13; // st4@18
1767 float v14; // ST0C_4@22 1692 float v14; // ST0C_4@22
1768 float v15; // ST08_4@22 1693 float v15; // ST08_4@22
1769 //float v16; // ST04_4@23 1694 //float v16; // ST04_4@23
1770 //float v17; // ST00_4@24 1695 //float v17; // ST00_4@24
1771 signed int v18; // eax@27 1696 //signed int v18; // eax@27
1772 unsigned int v19; // eax@29 1697 //unsigned int v19; // eax@29
1773 double v20; // st6@32 1698 double v20; // st6@32
1774 double v21; // st7@32 1699 double v21; // st7@32
1775 int v22; // eax@32 1700 int v22; // eax@32
1776 double v23; // st7@36 1701 double v23; // st7@36
1777 //void *v24; // esi@40 1702 //void *v24; // esi@40
1787 //int v32; // [sp+80h] [bp-7Ch]@22 1712 //int v32; // [sp+80h] [bp-7Ch]@22
1788 float v33; // [sp+E0h] [bp-1Ch]@33 1713 float v33; // [sp+E0h] [bp-1Ch]@33
1789 float v34; // [sp+E4h] [bp-18h]@32 1714 float v34; // [sp+E4h] [bp-18h]@32
1790 int v35; // [sp+E8h] [bp-14h]@5 1715 int v35; // [sp+E8h] [bp-14h]@5
1791 int v36; // [sp+ECh] [bp-10h]@5 1716 int v36; // [sp+ECh] [bp-10h]@5
1792 unsigned int v37; // [sp+F0h] [bp-Ch]@5 1717 int v37; // [sp+F0h] [bp-Ch]@5
1793 float v38; // [sp+F4h] [bp-8h]@17 1718 float v38; // [sp+F4h] [bp-8h]@17
1794 //void *v39; // [sp+F8h] [bp-4h]@1 1719 //void *v39; // [sp+F8h] [bp-4h]@1
1795 signed int v40; // [sp+108h] [bp+Ch]@17 1720 signed int v40; // [sp+108h] [bp+Ch]@17
1796 float v41; // [sp+108h] [bp+Ch]@32 1721 float v41; // [sp+108h] [bp+Ch]@32
1797 1722
1798 static Vis_stru1 Vis_static_stru_F91E10; 1723 static Vis_SelectionList Vis_static_stru_F91E10;
1799 Vis_static_stru_F91E10.uNumPointers = 0; 1724 Vis_static_stru_F91E10.uNumPointers = 0;
1800 v3 = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].uParentBillboardID; 1725 v3 = pRenderer->pBillboardRenderListD3D[uD3DBillboardIdx].uParentBillboardID;
1801 if (v3 == -1) 1726 if (v3 == -1)
1802 return false; 1727 return false;
1803 if (pBillboardRenderList[v3].GetFloatZ() > fDepth) 1728 if (pBillboardRenderList[v3].GetFloatZ() > fDepth)
1804 { 1729 {
1805 LABEL_49: 1730 LABEL_49:
1806 return false; 1731 return false;
1807 } 1732 }
1808 else 1733
1809 {
1810 v37 = pBillboardRenderList[v3].sZValue & 0xFFFF0000; 1734 v37 = pBillboardRenderList[v3].sZValue & 0xFFFF0000;
1811 GetPolygonCenter(pRenderer->pBillboardRenderListD3D[v3].pQuards, 4, (float *)&v35, (float *)&v36); 1735 GetPolygonCenter(pRenderer->pBillboardRenderListD3D[v3].pQuards, 4, (float *)&v35, (float *)&v36);
1812 this->CastPickRay(pPickingRay, *(float *)&v35, *(float *)&v36, fDepth); 1736 CastPickRay(pPickingRay, *(float *)&v35, *(float *)&v36, fDepth);
1813 if (uCurrentlyLoadedLevelType == 1) 1737 if (uCurrentlyLoadedLevelType == LEVEL_Indoor)
1814 PickIndoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &a5); 1738 PickIndoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter);
1815 else 1739 else
1816 PickOutdoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &a5, 0); 1740 PickOutdoor(fDepth, pPickingRay, &Vis_static_stru_F91E10, &vis_face_filter, 0);
1817 Vis_static_stru_F91E10.create_object_pointers(0); 1741 Vis_static_stru_F91E10.create_object_pointers();
1818 sort_object_pointers(Vis_static_stru_F91E10.array_1804, 0, Vis_static_stru_F91E10.uNumPointers - 1); 1742 sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1);
1819 if (Vis_static_stru_F91E10.uNumPointers) 1743 if (Vis_static_stru_F91E10.uNumPointers)
1820 { 1744 {
1821 if (Vis_static_stru_F91E10.uNumPointers <= 0) 1745 if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z)
1822 v8 = 0; 1746 return 1;
1823 else v8 = (int)Vis_static_stru_F91E10.array_1804;
1824 v9 = *(_DWORD *)(v8 + 4);
1825 LOWORD(v9) = 0;
1826 if (v9 > v37)
1827 return 1;
1828 } 1747 }
1829 else if ((double)(pViewport->uScreenX) <= *(float *)&v35 && 1748 else if ((double)(pViewport->uScreenX) <= *(float *)&v35 &&
1830 (double)pViewport->uScreenZ >= *(float *)&v35 && 1749 (double)pViewport->uScreenZ >= *(float *)&v35 &&
1831 (double)pViewport->uScreenY <= *(float *)&v36 && 1750 (double)pViewport->uScreenY <= *(float *)&v36 &&
1832 (double)pViewport->uScreenW >= *(float *)&v36) 1751 (double)pViewport->uScreenW >= *(float *)&v36)
1850 { 1769 {
1851 v14 = v11; 1770 v14 = v11;
1852 v15 = v12; 1771 v15 = v12;
1853 CastPickRay(local_80, SLODWORD(v15), v14, fDepth); 1772 CastPickRay(local_80, SLODWORD(v15), v14, fDepth);
1854 if ( uCurrentlyLoadedLevelType == 1 ) 1773 if ( uCurrentlyLoadedLevelType == 1 )
1855 PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &a5); 1774 PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter);
1856 else 1775 else
1857 PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &a5, 0); 1776 PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, 0);
1858 Vis_static_stru_F91E10.create_object_pointers(0); 1777 Vis_static_stru_F91E10.create_object_pointers();
1859 sort_object_pointers(Vis_static_stru_F91E10.array_1804, 0, Vis_static_stru_F91E10.uNumPointers - 1); 1778 sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1);
1860 if ( !Vis_static_stru_F91E10.uNumPointers ) 1779 if ( !Vis_static_stru_F91E10.uNumPointers )
1861 break; 1780 break;
1862 v18 = Vis_static_stru_F91E10.uNumPointers <= 0 ? 0 : (int)Vis_static_stru_F91E10.array_1804; 1781 else
1863 v19 = *(_DWORD *)(v18 + 4); 1782 {
1864 LOWORD(v19) = 0; 1783 //v18 = Vis_static_stru_F91E10.uNumPointers <= 0 ? 0 : (int);
1865 if ( v19 > v37 ) 1784 //v19 = *(_DWORD *)(v18 + 4);
1785 //LOWORD(v19) = 0;
1786 if (Vis_static_stru_F91E10.object_pointers[0]->actual_z > pBillboardRenderList[v3].actual_z)
1866 break; 1787 break;
1788 }
1867 } 1789 }
1868 } 1790 }
1869 } 1791 }
1870 } 1792 }
1871 ++v40; 1793 ++v40;
1894 if ( v23 < (double)(pViewport->uScreenX) 1816 if ( v23 < (double)(pViewport->uScreenX)
1895 || v23 > (double)pViewport->uScreenZ 1817 || v23 > (double)pViewport->uScreenZ
1896 || (double)pViewport->uScreenY > v41 1818 || (double)pViewport->uScreenY > v41
1897 || (double)pViewport->uScreenW < v41 1819 || (double)pViewport->uScreenW < v41
1898 || ((v25 = v23, CastPickRay(local_80, SLODWORD(v25), v41, fDepth), uCurrentlyLoadedLevelType != 1) ? 1820 || ((v25 = v23, CastPickRay(local_80, SLODWORD(v25), v41, fDepth), uCurrentlyLoadedLevelType != 1) ?
1899 (PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &a5, 0)) : 1821 (PickOutdoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter, 0)) :
1900 (PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &a5)), 1822 (PickIndoor(fDepth, local_80, &Vis_static_stru_F91E10, &vis_face_filter)),
1901 (Vis_static_stru_F91E10.create_object_pointers(0), 1823 (Vis_static_stru_F91E10.create_object_pointers(),
1902 sort_object_pointers(Vis_static_stru_F91E10.array_1804, 0, Vis_static_stru_F91E10.uNumPointers - 1), 1824 sort_object_pointers(Vis_static_stru_F91E10.object_pointers, 0, Vis_static_stru_F91E10.uNumPointers - 1),
1903 Vis_static_stru_F91E10.uNumPointers) 1825 Vis_static_stru_F91E10.uNumPointers)
1904 && (Vis_static_stru_F91E10.uNumPointers <= 0 ? (v28 = 0) : (v28 = (int)Vis_static_stru_F91E10.array_1804), 1826 && (Vis_static_stru_F91E10.uNumPointers <= 0 ? (v28 = 0) : (v28 = (int)Vis_static_stru_F91E10.object_pointers),
1905 v29 = *(_DWORD *)(v28 + 4), 1827 v29 = *(_DWORD *)(v28 + 4),
1906 LOWORD(v29) = 0, 1828 LOWORD(v29) = 0,
1907 v29 <= v37)) ) 1829 v29 <= v37)) )
1908 return false; 1830 return false;
1909 break; 1831 break;
1910 } 1832 }
1911 } 1833 }
1912 result = 1; 1834 return true;
1913 }
1914 return result;
1915 } 1835 }
1916 // F93E18: using guessed type char static_byte_F93E18_init; 1836 // F93E18: using guessed type char static_byte_F93E18_init;
1917 1837
1918 //----- (004C0D32) -------------------------------------------------------- 1838 //----- (004C0D32) --------------------------------------------------------
1919 int Vis::_4C0D32_BLV(float a1, Vis_stru1 *arg4, stru157 *a2) 1839 int Vis::_4C0D32_KeyboardPickFaces_BLV(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
1920 { 1840 {
1921 int result; // eax@1 1841 int result; // eax@1
1922 signed int v5; // esi@2 1842 signed int v5; // esi@2
1923 BLVFace *v6; // edi@4 1843 BLVFace *v6; // edi@4
1924 unsigned int v7; // eax@6 1844 unsigned int v7; // eax@6
1925 Vis_stru1_stru0 *v8; // eax@6 1845 Vis_ObjectInfo *v8; // eax@6
1926 int v9; // ST18_4@7 1846 //int v9; // ST18_4@7
1927 unsigned int v10; // ST1C_4@7 1847 //unsigned int v10; // ST1C_4@7
1928 unsigned int v11; // ecx@7 1848 //unsigned int v11; // ecx@7
1929 signed int i; // [sp+18h] [bp-8h]@1 1849 signed int i; // [sp+18h] [bp-8h]@1
1930 Vis *thisa; // [sp+1Ch] [bp-4h]@1 1850 Vis *thisa; // [sp+1Ch] [bp-4h]@1
1931 1851
1932 result = 0; 1852 result = 0;
1933 thisa = this; 1853 thisa = this;
1939 if ( v5 < (signed int)pIndoor->uNumFaces ) 1859 if ( v5 < (signed int)pIndoor->uNumFaces )
1940 { 1860 {
1941 v6 = &pIndoor->pFaces[v5]; 1861 v6 = &pIndoor->pFaces[v5];
1942 if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[v5]) ) 1862 if ( !pGame->pIndoorCameraD3D->IsCulled(&pIndoor->pFaces[v5]) )
1943 { 1863 {
1944 if ( is_part_of_selection(v6, a2) ) 1864 if ( is_part_of_selection(v6, filter) )
1945 { 1865 {
1946 v7 = 8 * v5; 1866 v7 = 8 * v5;
1947 LOBYTE(v7) = 8 * v5 | 6; 1867 LOBYTE(v7) = 8 * v5 | OBJECT_BModel;
1948 v8 = _4C1026(v6, v7, a1); 1868 v8 = _4C1026(v6, v7, pick_depth);
1949 if ( v8 ) 1869 if ( v8 )
1950 { 1870 list->AddObject(v8->object, v8->object_type, v8->sZValue);
1951 v9 = v8->sZValue;
1952 v10 = v8->uObjectType;
1953 v11 = 3 * arg4->uNumPointers;
1954 arg4->array_0004[arg4->uNumPointers].pObjectInfo = v8->pObjectInfo;
1955 arg4->array_0004[4 * v11 / 0xC].sZValue = v9;
1956 arg4->array_0004[4 * v11 / 0xC].uObjectType = v10;
1957 ++arg4->uNumPointers;
1958 }
1959 } 1871 }
1960 } 1872 }
1961 } 1873 }
1962 } 1874 }
1963 result = i + 1; 1875 result = i + 1;
1964 } 1876 }
1965 return result; 1877 return result;
1966 } 1878 }
1967 1879
1968 //----- (004C0DEA) -------------------------------------------------------- 1880 //----- (004C0DEA) --------------------------------------------------------
1969 void Vis::_4C0DEA_ODM(float arg0, Vis_stru1 *a3, stru157 *a2) 1881 void Vis::_4C0DEA_KeyboardPickFaces_ODM(float pick_depth, Vis_SelectionList *list, Vis_SelectionFilter *filter)
1970 { 1882 {
1971 int v4; // esi@1 1883 int v4; // esi@1
1972 BSPModel *v5; // ebx@3 1884 BSPModel *v5; // ebx@3
1973 unsigned __int8 v6; // zf@5 1885 unsigned __int8 v6; // zf@5
1974 char v7; // sf@5 1886 char v7; // sf@5
1975 unsigned __int8 v8; // of@5 1887 unsigned __int8 v8; // of@5
1976 ODMFace *v9; // esi@7 1888 ODMFace *v9; // esi@7
1977 unsigned int v10; // eax@8 1889 unsigned int v10; // eax@8
1978 Vis_stru1_stru0 *v11; // eax@8 1890 Vis_ObjectInfo *v11; // eax@8
1979 unsigned int v12; // ecx@9 1891 //unsigned int v12; // ecx@9
1980 BLVFace f; // [sp+10h] [bp-84h]@1 1892 BLVFace f; // [sp+10h] [bp-84h]@1
1981 void *v14; // [sp+70h] [bp-24h]@9 1893 //void *v14; // [sp+70h] [bp-24h]@9
1982 int v15; // [sp+74h] [bp-20h]@9 1894 //int v15; // [sp+74h] [bp-20h]@9
1983 unsigned int v16; // [sp+78h] [bp-1Ch]@9 1895 //unsigned int v16; // [sp+78h] [bp-1Ch]@9
1984 int v17; // [sp+7Ch] [bp-18h]@1 1896 int v17; // [sp+7Ch] [bp-18h]@1
1985 Vis *v18; // [sp+80h] [bp-14h]@1 1897 Vis *v18; // [sp+80h] [bp-14h]@1
1986 int v19; // [sp+84h] [bp-10h]@6 1898 int v19; // [sp+84h] [bp-10h]@6
1987 unsigned int v20; // [sp+88h] [bp-Ch]@2 1899 unsigned int v20; // [sp+88h] [bp-Ch]@2
1988 int v21; // [sp+8Ch] [bp-8h]@5 1900 int v21; // [sp+8Ch] [bp-8h]@5
2011 { 1923 {
2012 v19 = v4; 1924 v19 = v4;
2013 do 1925 do
2014 { 1926 {
2015 v9 = (ODMFace *)((char *)v5->pFaces + v19); 1927 v9 = (ODMFace *)((char *)v5->pFaces + v19);
2016 if ( is_part_of_selection((BLVFace *)((char *)v5->pFaces + v19), a2) ) 1928 if ( is_part_of_selection((BLVFace *)((char *)v5->pFaces + v19), filter) )
2017 { 1929 {
2018 f.FromODM(v9); 1930 f.FromODM(v9);
2019 v10 = 8 * (v21 | (a1 << 6)); 1931 v10 = 8 * (v21 | (a1 << 6));
2020 LOBYTE(v10) = v10 | 6; 1932 LOBYTE(v10) = v10 | OBJECT_BModel;
2021 v11 = _4C1026(&f, v10, arg0); 1933 v11 = _4C1026(&f, v10, pick_depth);
2022 if ( v11 ) 1934 if ( v11 )
2023 { 1935 {
2024 v14 = v11->pObjectInfo; 1936 /*v14 = v11->object;
2025 v15 = v11->sZValue; 1937 v15 = v11->sZValue;
2026 v12 = a3->uNumPointers; 1938 v12 = a3->uNumPointers;
2027 v16 = v11->uObjectType; 1939 //v16 = v11->uObjectType;
2028 v12 *= 3; 1940 v12 *= 3;
2029 *((int *)&a3->array_0004[0].pObjectInfo + v12) = (int)v14; 1941 *((int *)&a3->object_pool[0].object + v12) = (int)v14;
2030 *(&a3->array_0004[0].sZValue + v12) = v15; 1942 *(&a3->object_pool[0].sZValue + v12) = v15;
2031 *(&a3->array_0004[0].uObjectType + v12) = v16; 1943 *(&a3->object_pool[0].object_type + v12) = v11->object_type;
2032 ++a3->uNumPointers; 1944 ++a3->uNumPointers;*/
1945 list->AddObject(v11->object, v11->object_type, v11->sZValue);
2033 } 1946 }
2034 } 1947 }
2035 ++v21; 1948 ++v21;
2036 v19 += 308; 1949 v19 += 308;
2037 } 1950 }