comparison LOD.cpp @ 0:8b8875f5b359

Initial commit
author Nomad
date Fri, 05 Oct 2012 16:07:14 +0200
parents
children ac0fb48cd27a
comparison
equal deleted inserted replaced
-1:000000000000 0:8b8875f5b359
1 #include "LOD.h"
2 #include "Render.h"
3 #include "Allocator.h"
4 #include "PaletteManager.h"
5 #include "Viewport.h"
6
7 #include "mm7_data.h"
8
9
10
11
12
13
14
15 LODFile_IconsBitmaps *pEvents_LOD;
16 LODFile_IconsBitmaps *pIcons_LOD;
17 LODFile_Sprites *pSprites_LOD;
18 LODFile_IconsBitmaps *pBitmaps_LOD;
19
20 LODWriteableFile *pNew_LOD;
21 LODWriteableFile *pGames_LOD;
22
23
24
25
26 int _6A0CA4_lod_binary_search; // weak
27 int _6A0CA8_lod_unused; // weak
28
29
30
31
32
33 //----- (004355F7) --------------------------------------------------------
34 void LODFile_IconsBitmaps::_4355F7()
35 {
36 LODFile_IconsBitmaps *v1; // esi@1
37 int v2; // edi@2
38 Texture *v3; // ebp@3
39 struct IDirect3DTexture2 **v4; // eax@4
40 struct IDirect3DTexture2 *v5; // eax@5
41 struct IDirectDrawSurface **v6; // eax@7
42 struct IDirectDrawSurface *v7; // eax@8
43 int v8; // eax@11
44
45 v1 = this;
46 if ( this->uTexturePacksCount )
47 {
48 v2 = this->uNumLoadedFiles - 1;
49 if ( v2 >= this->uNumPrevLoadedFiles )
50 {
51 v3 = &this->pTextures[v2];
52 do
53 {
54 v3->Release();
55 v4 = v1->pHardwareTextures;
56 if ( v4 )
57 {
58 v5 = v4[v2];
59 if ( v5 )
60 {
61 v5->Release();
62 v1->pHardwareTextures[v2] = 0;
63 }
64 }
65 v6 = v1->pHardwareSurfaces;
66 if ( v6 )
67 {
68 v7 = v6[v2];
69 if ( v7 )
70 {
71 v7->Release();
72 v1->pHardwareSurfaces[v2] = 0;
73 }
74 }
75 --v2;
76 --v3;
77 }
78 while ( v2 >= v1->uNumPrevLoadedFiles );
79 }
80 v8 = v1->uNumPrevLoadedFiles;
81 v1->uNumPrevLoadedFiles = 0;
82 v1->uNumLoadedFiles = v8;
83 v1->uTexturePacksCount = 0;
84 }
85 }
86
87 //----- (004114F2) --------------------------------------------------------
88 void LODFile_IconsBitmaps::_4114F2()
89 {
90 LODFile_IconsBitmaps *v1; // esi@1
91 int *pTexturePacksCount; // eax@1
92 int v3; // ecx@1
93 int v4; // ecx@2
94 int v5; // edi@3
95 Texture *v6; // ebx@4
96 struct IDirect3DTexture2 **v7; // eax@5
97 struct IDirect3DTexture2 *v8; // eax@6
98 struct IDirectDrawSurface **v9; // eax@8
99 struct IDirectDrawSurface *v10; // eax@9
100 int v11; // eax@12
101
102 v1 = this;
103 pTexturePacksCount = &this->uTexturePacksCount;
104 v3 = this->uTexturePacksCount;
105 if ( v3 )
106 {
107 v4 = v3 - 1;
108 *pTexturePacksCount = v4;
109 if ( !v4 )
110 {
111 v5 = v1->uNumLoadedFiles - 1;
112 if ( v5 >= v1->uNumPrevLoadedFiles )
113 {
114 v6 = &v1->pTextures[v5];
115 do
116 {
117 v6->Release();
118 v7 = v1->pHardwareTextures;
119 if ( v7 )
120 {
121 v8 = v7[v5];
122 if ( v8 )
123 {
124 v8->Release();
125 v1->pHardwareTextures[v5] = 0;
126 }
127 }
128 v9 = v1->pHardwareSurfaces;
129 if ( v9 )
130 {
131 v10 = v9[v5];
132 if ( v10 )
133 {
134 v10->Release();
135 v1->pHardwareSurfaces[v5] = 0;
136 }
137 }
138 --v5;
139 --v6;
140 }
141 while ( v5 >= v1->uNumPrevLoadedFiles );
142 }
143 v11 = v1->uNumPrevLoadedFiles;
144 v1->uNumPrevLoadedFiles = 0;
145 v1->uNumLoadedFiles = v11;
146 }
147 }
148 }
149
150 //----- (004AC67E) --------------------------------------------------------
151 int LODFile_Sprites::LoadSpriteFromFile(LODSprite *pSpriteHeader, const char *pContainer)
152 {
153 FILE *v3; // eax@1
154 FILE *v4; // ebx@1
155 int result; // eax@2
156 LODSprite *v6; // esi@3
157 LODSprite_stru0 *v7; // eax@3
158 size_t v8; // ST10_4@3
159 int *v9; // ebx@3
160 int v10; // eax@3
161 void *v11; // eax@5
162 LODSprite_stru0 *v12; // eax@6
163 void *v13; // ecx@6
164 LODSprite_stru0 *i; // edx@6
165 FILE *File; // [sp+4h] [bp-4h]@1
166 void *DstBufa; // [sp+10h] [bp+8h]@4
167 int Sizea; // [sp+14h] [bp+Ch]@3
168
169 v3 = FindContainer(pContainer, 0);
170 v4 = v3;
171 File = v3;
172 if ( v3 )
173 {
174 v6 = pSpriteHeader;
175 fread(pSpriteHeader, 1u, 0x20u, v3);
176 strcpy(pSpriteHeader->pName, pContainer);
177 Sizea = pSpriteHeader->uSpriteSize;
178 v7 = (LODSprite_stru0 *)pAllocator->AllocNamedChunk(v6->pSpriteLines, 8 * v6->uHeight, v6->pName);
179 v8 = 8 * pSpriteHeader->uHeight;
180 pSpriteHeader->pSpriteLines = v7;
181 fread(v7, 1u, v8, v4);
182 v9 = &pSpriteHeader->uDecompressedSize;
183 v10 = pSpriteHeader->uDecompressedSize;
184 if ( v10 )
185 {
186 pSpriteHeader->pDecompressedBytes = pAllocator->AllocNamedChunk(
187 pSpriteHeader->pDecompressedBytes,
188 v10,
189 pSpriteHeader->pName);
190 DstBufa = pAllocator->AllocNamedChunk(0, Sizea, pSpriteHeader->pName);
191 fread(DstBufa, 1u, Sizea, File);
192 zlib::MemUnzip(v6->pDecompressedBytes, (unsigned int *)&v6->uDecompressedSize, DstBufa, v6->uSpriteSize);
193 v6->uSpriteSize = *v9;
194 pAllocator->FreeChunk(DstBufa);
195 }
196 else
197 {
198 v11 = pAllocator->AllocNamedChunk(pSpriteHeader->pDecompressedBytes, Sizea, pSpriteHeader->pName);
199 pSpriteHeader->pDecompressedBytes = v11;
200 fread(v11, 1u, Sizea, File);
201 }
202 v12 = v6->pSpriteLines;
203 v13 = v6->pDecompressedBytes;
204 for ( i = &v12[v6->uHeight]; v12 < i; i = &v6->pSpriteLines[v6->uHeight] )
205 {
206 v12->ptr_4 = (char *)v12->ptr_4 + (unsigned int)v13;
207 ++v12;
208 }
209 result = 1;
210 }
211 else
212 {
213 result = -1;
214 }
215 return result;
216 }
217
218 //----- (004AC795) --------------------------------------------------------
219 bool LODFile_Sprites::LoadSprites(const char *pFilename)
220 {
221 if (LoadHeader(pFilename, 1))
222 return false;
223 else
224 return LoadSubIndices("sprites08") == 0;
225 }
226
227 //----- (004AC7C0) --------------------------------------------------------
228 int LODFile_Sprites::LoadSprite(const char *pContainerName, unsigned int uPaletteID)
229 { signed int v3; // edi@1
230 LODFile_Sprites *v4; // esi@1
231 unsigned int v5; // eax@6
232 signed int v6; // ecx@10
233 Sprite *v7; // eax@11
234 FILE *v8; // eax@12
235 Sprite *v10; // edx@21
236 int v11; // eax@21
237 int v12; // eax@22
238 unsigned __int8 v13; // zf@23
239 unsigned __int8 v14; // sf@23
240 LODSprite DstBuf; // [sp+Ch] [bp-3Ch]@12
241 char *Str1; // [sp+34h] [bp-14h]@24
242 LODSprite *v17; // [sp+38h] [bp-10h]@3
243 int v18; // [sp+44h] [bp-4h]@12
244
245 auto a3 = uPaletteID;
246 v3 = 0;
247 v4 = this;
248 if ( pRenderer->pRenderD3D )
249 {
250 if ( (signed int)this->uNumLoadedSprites > 0 )
251 {
252 v17 = 0;
253 while ( _strcmpi(*(const char **)&v17->pName[(unsigned int)v4->pHardwareSprites], pContainerName) )
254 {
255 ++v17;
256 ++v3;
257 if ( v3 >= (signed int)v4->uNumLoadedSprites )
258 goto LABEL_6;
259 }
260 return v3;
261 }
262 }
263 else
264 {
265 if ( (signed int)this->uNumLoadedSprites > 0 )
266 {
267 v17 = this->pSpriteHeaders;
268 while ( _strcmpi(v17->pName, pContainerName) )
269 {
270 ++v17;
271 ++v3;
272 if ( v3 >= (signed int)v4->uNumLoadedSprites )
273 goto LABEL_6;
274 }
275 return v3;
276 }
277 }
278 LABEL_6:
279 v5 = v4->uNumLoadedSprites;
280 if ( v5 == 1500 )
281 return -1;
282 if ( pRenderer->pRenderD3D && v4->field_ECAC )
283 {
284 if ( !v4->pHardwareSprites )
285 {
286 v4->pHardwareSprites = (Sprite *)pAllocator->AllocNamedChunk(0, 0xEA60u, "hardSprites");
287 v6 = 0;
288 do
289 {
290 v7 = &v4->pHardwareSprites[v6];
291 ++v6;
292 v7->pName = 0;
293 v7->pTextureSurface = 0;
294 v7->pTexture = 0;
295 }
296 while ( v6 < 1500 );
297 }
298 DstBuf.uHeight = 0;
299 DstBuf.uPaletteId = 0;
300 DstBuf.word_1A = 0;
301 DstBuf.pSpriteLines = 0;
302 DstBuf.pDecompressedBytes = 0;
303 v18 = 0;
304 v8 = FindContainer(pContainerName, 0);
305 if ( !v8 )
306 {
307 v18 = -1;
308 //LODSprite::dtor(&DstBuf);
309 return -1;
310 }
311 fread(&DstBuf, 1u, 0x20u, v8);
312 v10 = v4->pHardwareSprites;
313 v11 = 5 * v4->uNumLoadedSprites;
314 v18 = -1;
315 pHardwareSprites[uNumLoadedSprites].uBufferWidth = DstBuf.uWidth;
316 pHardwareSprites[uNumLoadedSprites].uBufferHeight = DstBuf.uHeight;
317 pSpriteHeaders[uNumLoadedSprites].uWidth = DstBuf.uWidth;
318 pSpriteHeaders[uNumLoadedSprites].uHeight = DstBuf.uHeight;
319 //LODSprite::dtor(&DstBuf);
320 goto LABEL_29;
321 }
322 v12 = LoadSpriteFromFile( &v4->pSpriteHeaders[v5], pContainerName);
323 v4->pSpriteHeaders[v4->uNumLoadedSprites].word_1A = 0;
324 if ( v12 != -1 )
325 {
326 LABEL_28:
327 v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(
328 v4->pSpriteHeaders[v4->uNumLoadedSprites].uPaletteId);
329 LABEL_29:
330 if ( pRenderer->pRenderD3D )
331 {
332 v4->pHardwareSprites[v4->uNumLoadedSprites].pName = (const char *)pAllocator->AllocNamedChunk(
333 v4->pHardwareSprites[v4->uNumLoadedSprites].pName,
334 0x14u,
335 pContainerName);
336 strcpy((char *)pHardwareSprites[uNumLoadedSprites].pName, pContainerName);
337 v4->pHardwareSprites[v4->uNumLoadedSprites].uPaletteID = uPaletteID;
338 pRenderer->MoveSpriteToDevice(&pHardwareSprites[uNumLoadedSprites]);
339 }
340 ++v4->uNumLoadedSprites;
341 return v4->uNumLoadedSprites - 1;
342 }
343 v13 = v4->uNumLoadedSprites == 0;
344 v14 = (v4->uNumLoadedSprites & 0x80000000u) != 0;
345 v17 = 0;
346 if ( v14 | v13 )
347 {
348 LABEL_27:
349 if ( LoadSpriteFromFile(&v4->pSpriteHeaders[v4->uNumLoadedSprites], "pending") == -1 )
350 return -1;
351 goto LABEL_28;
352 }
353 Str1 = (char *)v4->pSpriteHeaders;
354 while ( _strcmpi(Str1, "pending") )
355 {
356 v17 = (LODSprite *)((char *)v17 + 1);
357 Str1 += 40;
358 if ( (signed int)v17 >= (signed int)v4->uNumLoadedSprites )
359 goto LABEL_27;
360 }
361 return (int)v17;
362 }
363
364 //----- (004ACADA) --------------------------------------------------------
365 void LODFile_Sprites::ReleaseLostHardwareSprites()
366 {
367 LODFile_Sprites *v1; // esi@1
368 signed int v2; // ebx@2
369 int v3; // edi@3
370 IDirectDrawSurface *v4; // eax@4
371 IDirect3DTexture2 *v5; // eax@6
372 IDirectDrawSurface *v6; // ST00_4@8
373
374 v1 = this;
375 if ( this->pHardwareSprites )
376 {
377 v2 = 0;
378 if ( (signed int)this->uNumLoadedSprites > 0 )
379 {
380 v3 = 0;
381 do
382 {
383 v4 = v1->pHardwareSprites[v3].pTextureSurface;
384 if ( v4 && v4->IsLost() == DDERR_SURFACELOST )
385 {
386 v5 = v1->pHardwareSprites[v3].pTexture;
387 if ( v5 )
388 {
389 v5->Release();
390 v1->pHardwareSprites[v3].pTexture = 0;
391 }
392 v6 = v1->pHardwareSprites[v3].pTextureSurface;
393 v6->Release();
394 v1->pHardwareSprites[v3].pTextureSurface = 0;
395 pRenderer->MoveSpriteToDevice(&v1->pHardwareSprites[v3]);
396 }
397 ++v2;
398 ++v3;
399 }
400 while ( v2 < (signed int)v1->uNumLoadedSprites );
401 }
402 }
403 }
404
405 //----- (004ACB70) --------------------------------------------------------
406 void LODFile_Sprites::ReleaseAll()
407 {
408 LODFile_Sprites *v1; // esi@1
409 signed int v2; // ebx@2
410 int v3; // edi@3
411 Sprite *v4; // eax@4
412 IDirect3DTexture2 *v5; // eax@5
413 Sprite *v6; // eax@7
414 IDirectDrawSurface *v7; // eax@8
415
416 v1 = this;
417 if ( this->pHardwareSprites )
418 {
419 v2 = 0;
420 if ( (signed int)this->uNumLoadedSprites > 0 )
421 {
422 v3 = 0;
423 do
424 {
425 v4 = v1->pHardwareSprites;
426 if ( v4 )
427 {
428 v5 = v4[v3].pTexture;
429 if ( v5 )
430 {
431 v5->Release();
432 v1->pHardwareSprites[v3].pTexture = 0;
433 }
434 v6 = v1->pHardwareSprites;
435 if ( v6 )
436 {
437 v7 = v6[v3].pTextureSurface;
438 if ( v7 )
439 {
440 v7->Release();
441 v1->pHardwareSprites[v3].pTextureSurface = 0;
442 }
443 }
444 }
445 ++v2;
446 ++v3;
447 }
448 while ( v2 < (signed int)v1->uNumLoadedSprites );
449 }
450 }
451 }
452
453 //----- (004ACBE0) --------------------------------------------------------
454 void LODFile_Sprites::MoveSpritesToVideoMemory()
455 {
456 LODFile_Sprites *v1; // esi@1
457 int v2; // ebx@1
458 signed int v3; // edi@2
459
460 v1 = this;
461 v2 = 0;
462 if ( this->pHardwareSprites )
463 {
464 v3 = 0;
465 if ( (signed int)this->uNumLoadedSprites > 0 )
466 {
467 do
468 {
469 pRenderer->MoveSpriteToDevice(&v1->pHardwareSprites[v2]);
470 ++v3;
471 ++v2;
472 }
473 while ( v3 < (signed int)v1->uNumLoadedSprites );
474 }
475 }
476 }
477
478 //----- (004ACC38) --------------------------------------------------------
479 int LODSprite::_4ACC38(RenderBillboardTransform_local0 *a2, char a3)
480 {
481 RenderBillboardTransform_local0 *v3; // edi@1
482 int result; // eax@1
483 int v5; // esi@2
484 int v6; // ST18_4@2
485 signed int v7; // eax@2
486 signed int v8; // ebx@2
487 int v9; // ebx@2
488 int *v10; // ecx@2
489 int v11; // esi@2
490 unsigned int v12; // edx@4
491 int v13; // esi@13
492 int v14; // esi@17
493 int v15; // ecx@17
494 char *v16; // edx@17
495 int v17; // esi@17
496 int v18; // ecx@18
497 int v19; // esi@18
498 LODSprite_stru0 *v20; // edx@21
499 int v21; // eax@22
500 int v22; // esi@22
501 int v23; // eax@25
502 int v24; // ecx@25
503 signed __int64 v25; // qtt@27
504 int v26; // eax@27
505 unsigned __int16 *v27; // eax@29
506 LODSprite_stru0 *v28; // edx@29
507 signed int v29; // ecx@30
508 int v30; // ecx@37
509 int v31; // ecx@38
510 signed int v32; // ecx@41
511 int v33; // ecx@47
512 int v34; // ecx@56
513 int v35; // esi@58
514 __int16 v36; // ax@58
515 int v37; // ecx@59
516 int v38; // eax@59
517 int v39; // ecx@62
518 signed int v40; // ST30_4@64
519 signed __int64 v41; // qtt@64
520 int v42; // ecx@64
521 unsigned __int16 *v43; // eax@66
522 LODSprite_stru0 *v44; // ecx@66
523 int v45; // edx@69
524 int v46; // edx@77
525 unsigned __int16 *pTarget; // [sp+Ch] [bp-50h]@2
526 signed int v48; // [sp+10h] [bp-4Ch]@2
527 signed int v49; // [sp+14h] [bp-48h]@2
528 int v50; // [sp+14h] [bp-48h]@19
529 int v51; // [sp+14h] [bp-48h]@57
530 int v52; // [sp+18h] [bp-44h]@13
531 int v53; // [sp+1Ch] [bp-40h]@2
532 int v54; // [sp+1Ch] [bp-40h]@22
533 int v55; // [sp+1Ch] [bp-40h]@32
534 int v56; // [sp+1Ch] [bp-40h]@69
535 int v57; // [sp+20h] [bp-3Ch]@2
536 int v58; // [sp+24h] [bp-38h]@1
537 int v59; // [sp+28h] [bp-34h]@2
538 int v60; // [sp+28h] [bp-34h]@13
539 unsigned __int16 *v61; // [sp+2Ch] [bp-30h]@2
540 int v62; // [sp+30h] [bp-2Ch]@2
541 void *v63; // [sp+30h] [bp-2Ch]@29
542 void *v64; // [sp+30h] [bp-2Ch]@66
543 int v65; // [sp+34h] [bp-28h]@2
544 int v66; // [sp+34h] [bp-28h]@22
545 int v67; // [sp+34h] [bp-28h]@59
546 int v68; // [sp+38h] [bp-24h]@13
547 unsigned int v69; // [sp+3Ch] [bp-20h]@2
548 int v70; // [sp+40h] [bp-1Ch]@2
549 signed int v71; // [sp+40h] [bp-1Ch]@15
550 int v72; // [sp+44h] [bp-18h]@2
551 unsigned __int16 *v73; // [sp+44h] [bp-18h]@29
552 unsigned __int16 *v74; // [sp+44h] [bp-18h]@66
553 int v75; // [sp+48h] [bp-14h]@4
554 int v76; // [sp+48h] [bp-14h]@22
555 int v77; // [sp+48h] [bp-14h]@59
556 LODSprite *v78; // [sp+4Ch] [bp-10h]@1
557 int v79; // [sp+50h] [bp-Ch]@4
558 int v80; // [sp+50h] [bp-Ch]@21
559 int v81; // [sp+50h] [bp-Ch]@62
560 int v82; // [sp+50h] [bp-Ch]@67
561 int v83; // [sp+50h] [bp-Ch]@75
562 int *pTargetZ; // [sp+54h] [bp-8h]@4
563 int v85; // [sp+58h] [bp-4h]@18
564 int v86; // [sp+58h] [bp-4h]@56
565 signed int v87; // [sp+64h] [bp+8h]@2
566 int v88; // [sp+68h] [bp+Ch]@18
567 int v89; // [sp+68h] [bp+Ch]@56
568
569 v3 = a2;
570 v78 = this;
571 result = a2->field_10;
572 v58 = a2->field_10;
573 if ( result <= 0 )
574 return result;
575 v5 = a2->field_14;
576 v6 = a2->field_10;
577 v87 = (signed __int64)0x100000000ui64 / result;
578 v48 = (signed __int64)0x100000000ui64 / result;
579 v62 = (signed __int64)0x100000000ui64 / v5;
580 v7 = this->uHeight;
581 v8 = (signed int)((signed __int64)0x100000000ui64 / v5) >> 1;
582 v53 = v8;
583 v70 = (this->uHeight << 16) - v8;
584 v49 = v7;
585 v69 = v3->uTargetPitch;
586 pTarget = v3->pTarget;
587 v57 = v3->field_28;
588 v61 = v3->pPalette;
589 v9 = (v6 * this->uWidth + 32768) >> 16;
590 v72 = v3->field_C;
591 result = (v5 * v7 + 32768) >> 16;
592 v10 = (int *)(v72 - result + 1);
593 v11 = v3->field_8 - (v9 >> 1) + 1;
594 v65 = v72 - result + 1;
595 v59 = v11 + v9 - 1;
596 if ( BYTE1(v3->uFlags) & 8 )
597 {
598 v10 = (int *)((char *)v10 + (v49 >> 1));
599 v72 += v49 >> 1;
600 v65 = (int)v10;
601 }
602 v12 = v72;
603 pTargetZ = v10;
604 v75 = v3->field_8 - (v9 >> 1) + 1;
605 v79 = v11 + v9 - 1;
606 if ( !(v3->uFlags & 8) )
607 {
608 if ( v65 < (signed int)v3->uViewportY )
609 pTargetZ = (int *)v3->uViewportY;
610 if ( v72 > (signed int)v3->uViewportW )
611 v12 = v3->uViewportW;
612 if ( v11 < (signed int)v3->uViewportX )
613 v75 = v3->uViewportX;
614 if ( v59 > (signed int)v3->uViewportZ )
615 v79 = v3->uViewportZ;
616 }
617 v68 = v75 - v11;
618 v13 = -v62;
619 v60 = v59 - v79;
620 v52 = -v62;
621 if ( v3->uFlags & 1 )
622 {
623 v13 = v62;
624 v70 = v53;
625 v52 = v62;
626 }
627 v71 = v13 * (v72 - v12) + v70;
628 if ( LOBYTE(viewparams->field_20) )
629 {
630 if ( a3 )
631 return result;
632 }
633 v14 = 5 * v12;
634 v15 = v69 * v12;
635 result = v12 - v72 + result - 1;
636 v16 = (char *)pTargetZ - v65;
637 v17 = v14 << 7;
638 if ( v3->uFlags & 4 )
639 {
640 v34 = v79 + v15;
641 v89 = v34;
642 v86 = v79 + v17;
643 if ( result < (signed int)v16 )
644 return result;
645 v51 = result - (int)v16 + 1;
646 while ( 1 )
647 {
648 v35 = v71 >> 16;
649 v36 = LOWORD(v78->pSpriteLines[v35].dword_0);
650 if ( v36 == -1 )
651 {
652 v34 -= v69;
653 v89 = v34;
654 goto LABEL_84;
655 }
656 v37 = v9 - ((unsigned __int64)(v36 * (signed __int64)v58) >> 16);
657 v67 = v87 * ((unsigned __int64)(LOWORD(v78->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16);
658 v38 = v9 - v60;
659 v77 = v9 - v60;
660 if ( v9 - v60 <= (signed int)(v9
661 - ((unsigned __int64)(HIWORD(v78->pSpriteLines[v35].dword_0) * (signed __int64)v58) >> 16))
662 || v68 >= v37 )
663 {
664 v89 -= v69;
665 v34 = v89;
666 LABEL_84:
667 v86 -= 640;
668 goto LABEL_85;
669 }
670 if ( v38 < v37 )
671 {
672 v81 = (v87 >> 1) + v87 * (v37 - v38);
673 }
674 else
675 {
676 v77 = v37;
677 v81 = v87 >> 1;
678 v39 = v37 - v9;
679 v89 += v39 + v60;
680 v86 += v60 + v39;
681 }
682 v40 = ((HIWORD(v78->pSpriteLines[v35].dword_0) + 1) << 16) - v81 - v67;
683 LODWORD(v41) = v40 << 16;
684 HIDWORD(v41) = v40 >> 16;
685 v42 = v77 - (((signed int)((unsigned __int64)(v41 / v48) - 32768) >> 16) + 1);
686 if ( v68 >= v42 )
687 v42 = v68;
688 v43 = &pTarget[v89];
689 v74 = &v43[v42 - v77 + 1];
690 v44 = &v78->pSpriteLines[v35];
691 v64 = v44->ptr_4;
692 if ( !v57 )
693 {
694 v83 = v67 + v81;
695 if ( ((v83 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 )
696 {
697 v83 += v87;
698 --v43;
699 --pTargetZ;
700 }
701 while ( v43 >= v74 )
702 {
703 v46 = (v83 - ((signed int)LOWORD(v78->pSpriteLines[v35].dword_0) << 16)) >> 16;
704 if ( *((char *)v64 + v46) )
705 *v43 = v61[*((char *)v64 + v46)];
706 v83 += v87;
707 --v43;
708 }
709 goto LABEL_81;
710 }
711 pTargetZ = &v3->pTargetZ[v86];
712 v82 = v67 + v81;
713 if ( ((v82 - (LOWORD(v44->dword_0) << 16)) & 0xFFFF0000) < 0 )
714 goto LABEL_72;
715 LABEL_73:
716 if ( v43 >= v74 )
717 break;
718 LABEL_81:
719 v89 += v9 - v77 - v60 - v69;
720 v34 = v89;
721 v86 = v86 + v9 - v77 - v60 - 640;
722 LABEL_85:
723 result = v52;
724 v71 += v52;
725 --v51;
726 if ( !v51 )
727 return result;
728 }
729 v45 = (v82 - ((signed int)LOWORD(v78->pSpriteLines[v35].dword_0) << 16)) >> 16;
730 v56 = *((char *)v64 + v45);
731 if ( *((char *)v64 + v45) && v57 <= (unsigned int)*pTargetZ )
732 {
733 *pTargetZ = v57;
734 *v43 = v61[v56];
735 }
736 LABEL_72:
737 v82 += v87;
738 --v43;
739 --pTargetZ;
740 goto LABEL_73;
741 }
742 v18 = v75 + v15;
743 v19 = v75 + v17;
744 v88 = v18;
745 v85 = v19;
746 if ( result >= (signed int)v16 )
747 {
748 v50 = result - (int)v16 + 1;
749 while ( 1 )
750 {
751 v20 = &v78->pSpriteLines[v71 >> 16];
752 v80 = v71 >> 16;
753 if ( LOWORD(v20->dword_0) != -1 )
754 break;
755 v18 -= v69;
756 v85 = v19 - 640;
757 v88 = v18;
758 LABEL_54:
759 result = v52;
760 v71 += v52;
761 --v50;
762 if ( !v50 )
763 return result;
764 v19 = v85;
765 }
766 v21 = (v58 * LOWORD(v20->dword_0) + 32768) >> 16;
767 v66 = v21 * v87;
768 v76 = v68;
769 v54 = HIWORD(v20->dword_0);
770 v22 = v9 - v60;
771 if ( v68 >= (v58 * v54 + 32768) >> 16 || v22 <= v21 )
772 {
773 v88 -= v69;
774 v85 -= 640;
775 goto LABEL_51;
776 }
777 if ( v68 > v21 )
778 {
779 v24 = (v87 >> 1) + v87 * (v68 - v21);
780 }
781 else
782 {
783 v76 = (v58 * LOWORD(v20->dword_0) + 32768) >> 16;
784 v23 = v21 - v68;
785 v88 += v23;
786 v24 = v87 >> 1;
787 v85 += v23;
788 }
789 LODWORD(v25) = (((v54 + 1) << 16) - v24 - v66) << 16;
790 HIDWORD(v25) = (((v54 + 1) << 16) - v24 - v66) >> 16;
791 v26 = v76 + ((signed int)(v25 / v48) >> 16) + 1;
792 if ( v22 > v26 )
793 v22 = v26;
794 v27 = &pTarget[v88];
795 v73 = &v27[v22 - v76 - 1];
796 v28 = &v78->pSpriteLines[v80];
797 v63 = v28->ptr_4;
798 if ( v57 )
799 {
800 pTargetZ = &v3->pTargetZ[v85];
801 v29 = v66 - (LOWORD(v28->dword_0) << 16) + v24;
802 if ( (v29 & 0xFFFF0000) >= 0 )
803 goto LABEL_36;
804 while ( 1 )
805 {
806 v29 += v87;
807 ++v27;
808 ++pTargetZ;
809 LABEL_36:
810 if ( v27 >= v73 )
811 break;
812 v55 = *((char *)v63 + (v29 >> 16));
813 if ( *((char *)v63 + (v29 >> 16)) && v57 <= (unsigned int)*pTargetZ )
814 {
815 *pTargetZ = v57;
816 *v27 = v61[v55];
817 }
818 }
819 v30 = v29 >> 16;
820 if ( v30 > HIWORD(v78->pSpriteLines[v80].dword_0) - (signed int)LOWORD(v78->pSpriteLines[v80].dword_0)
821 || (v31 = *((char *)v63 + v30)) == 0
822 || v57 > (unsigned int)*pTargetZ )
823 goto LABEL_50;
824 *pTargetZ = v57;
825 }
826 else
827 {
828 v32 = v66 - (LOWORD(v28->dword_0) << 16) + v24;
829 if ( (v32 & 0xFFFF0000) < 0 )
830 {
831 v32 += v87;
832 ++v27;
833 ++pTargetZ;
834 }
835 while ( v27 < v73 )
836 {
837 if ( *((char *)v63 + (v32 >> 16)) )
838 *v27 = v61[*((char *)v63 + (v32 >> 16))];
839 v32 += v87;
840 ++v27;
841 }
842 v33 = v32 >> 16;
843 if ( v33 > HIWORD(v78->pSpriteLines[v80].dword_0) - (signed int)LOWORD(v78->pSpriteLines[v80].dword_0)
844 || (v31 = *((char *)v63 + v33)) == 0 )
845 goto LABEL_50;
846 }
847 *v27 = v61[v31];
848 LABEL_50:
849 v88 += v68 - v76 - v69;
850 v85 = v85 + v68 - v76 - 640;
851 LABEL_51:
852 v18 = v88;
853 goto LABEL_54;
854 }
855 return result;
856 }
857
858 //----- (004AD2D1) --------------------------------------------------------
859 int LODSprite::_4AD2D1(struct RenderBillboardTransform_local0 *a2, int a3)
860 {
861 int result; // eax@1
862 unsigned int v4; // esi@1
863 int v5; // edi@1
864 LODSprite_stru0 *v6; // edx@2
865 __int16 v7; // bx@2
866 int v8; // ecx@3
867 unsigned __int16 *v9; // esi@3
868 int v10; // ebx@3
869 void *v11; // edx@3
870 unsigned __int16 *v12; // ecx@3
871 int v13; // ebx@4
872 LODSprite *v14; // [sp+8h] [bp-10h]@1
873 unsigned __int16 *v15; // [sp+10h] [bp-8h]@1
874 unsigned __int16 *v16; // [sp+14h] [bp-4h]@1
875 int i; // [sp+20h] [bp+8h]@1
876
877 result = (int)a2;
878 v14 = this;
879 v4 = a2->uTargetPitch;
880 v16 = a2->pTarget;
881 v15 = a2->pPalette;
882 v5 = this->uHeight - 1;
883 for ( i = v4 * a2->field_C - (this->uWidth >> 1) + a2->field_8 + 1; v5 >= 0; --v5 )
884 {
885 v6 = &this->pSpriteLines[v5];
886 v7 = LOWORD(v6->dword_0);
887 if ( LOWORD(v6->dword_0) != -1 )
888 {
889 v8 = v7;
890 v9 = &v16[v7 + i];
891 v10 = HIWORD(v6->dword_0);
892 v11 = v6->ptr_4;
893 v12 = &v9[v10 - v8];
894 while ( v9 <= v12 )
895 {
896 v13 = *(char *)v11;
897 v11 = (char *)v11 + 1;
898 if ( v13 )
899 *v9 = v15[v13];
900 ++v9;
901 }
902 v4 = *(int *)(result + 48);
903 //this = v14;
904 }
905 i -= v4;
906 }
907 return result;
908 }
909
910 //----- (0046454B) --------------------------------------------------------
911 void LODFile_IconsBitmaps::ReleaseAll2()
912 {
913 LODFile_IconsBitmaps *v1; // esi@1
914 int v2; // edi@1
915 Texture *v3; // ebx@2
916 struct IDirect3DTexture2 **v4; // eax@3
917 struct IDirect3DTexture2 *v5; // eax@4
918 struct IDirectDrawSurface **v6; // eax@6
919 struct IDirectDrawSurface *v7; // eax@7
920 int v8; // eax@10
921
922 v1 = this;
923 v2 = this->uNumLoadedFiles - 1;
924 if ( v2 >= this->dword_11B84 )
925 {
926 v3 = &this->pTextures[v2];
927 do
928 {
929 v3->Release();
930 v4 = v1->pHardwareTextures;
931 if ( v4 )
932 {
933 v5 = v4[v2];
934 if ( v5 )
935 {
936 v5->Release();
937 v1->pHardwareTextures[v2] = 0;
938 }
939 }
940 v6 = v1->pHardwareSurfaces;
941 if ( v6 )
942 {
943 v7 = v6[v2];
944 if ( v7 )
945 {
946 v7->Release();
947 v1->pHardwareSurfaces[v2] = 0;
948 }
949 }
950 --v2;
951 --v3;
952 }
953 while ( v2 >= v1->dword_11B84 );
954 }
955 v8 = v1->dword_11B84;
956 v1->uTexturePacksCount = 0;
957 v1->uNumPrevLoadedFiles = 0;
958 v1->uNumLoadedFiles = v8;
959 }
960
961 //----- (004645DC) --------------------------------------------------------
962 void LODFile_Sprites::DeleteSomeOtherSprites()
963 {
964 int *v1; // esi@1
965 int *v2; // edi@1
966
967 v1 = (int *)&this->uNumLoadedSprites;
968 v2 = &this->field_ECA0;
969 DeleteSpritesRange(field_ECA0, uNumLoadedSprites);
970 *v1 = *v2;
971 }
972
973
974 //----- (00461431) --------------------------------------------------------
975 void LOD::File::Close()
976 {
977 LOD::File *v1; // esi@1
978 LOD::Directory **v2; // edi@2
979 FILE *v3; // ST00_4@2
980
981 v1 = this;
982 if ( this->isFileOpened )
983 {
984 this->pContainerName[0] = 0;
985 this->uCurrentIndexDir = 0;
986 v2 = &this->pSubIndices;
987 pAllocator->FreeChunk(this->pSubIndices);
988 pAllocator->FreeChunk(v1->pRoot);
989 v3 = v1->pFile;
990 *v2 = 0;
991 v1->pRoot = 0;
992 fclose(v3);
993 v1->isFileOpened = 0;
994 _6A0CA8_lod_unused = 0;
995 }
996 }
997 // 6A0CA8: using guessed type int 6A0CA8_lod_unused;
998
999 //----- (00461492) --------------------------------------------------------
1000 int LODWriteableFile::_461492(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *Source)
1001 {
1002 LODWriteableFile *v4; // esi@1
1003 FILE *v6; // eax@5
1004
1005 v4 = this;
1006 if ( this->isFileOpened )
1007 return 1;
1008 if ( !pDir->pFilename[0] )
1009 return 2;
1010 strcpy((char *)pHeader, "LOD");
1011 pHeader->dword_0000A4 = 100;
1012 pHeader->uNumIndices = 1;
1013 pDir->pFilename[15] = 0;
1014 pDir->uDataSize = 0;
1015 pDir->uOfsetFromSubindicesStart = 288;
1016 strcpy((char *)v4->pLODName, Source);
1017 v6 = fopen((const char *)v4->pLODName, "wb+");
1018 v4->pFile = v6;
1019 if ( !v6 )
1020 return 3;
1021 fwrite(pHeader, 0x100u, 1u, v6);
1022 fwrite(pDir, 0x20u, 1u, v4->pFile);
1023 fclose(v4->pFile);
1024 v4->pFile = 0;
1025 return 0;
1026 }
1027
1028 //----- (0046153F) --------------------------------------------------------
1029 void LOD::File::ResetSubIndices()
1030 {
1031 LOD::Directory **pSubIndices_dup2; // esi@2
1032 LOD::Directory *pSubIndices_dup; // ST00_4@2
1033
1034 if ( this->isFileOpened )
1035 {
1036 pSubIndices_dup2 = &this->pSubIndices;
1037 this->pContainerName[0] = 0;
1038 this->uCurrentIndexDir = 0;
1039 pSubIndices_dup = this->pSubIndices;
1040 this->uOffsetToSubIndex = 0;
1041 this->uNumSubIndices = 0;
1042 this->uLODDataSize = 0;
1043 pAllocator->FreeChunk(pSubIndices_dup);
1044 *pSubIndices_dup2 = 0;
1045 }
1046 }
1047
1048
1049
1050
1051
1052
1053
1054 //----- (00450C8B) --------------------------------------------------------
1055 void LODFile_Sprites::DeleteSomeSprites()
1056 {
1057 int *v1; // esi@1
1058 int *v2; // edi@1
1059
1060 v1 = (int *)&this->uNumLoadedSprites;
1061 v2 = &this->field_ECA8;
1062 DeleteSpritesRange(this->field_ECA8, this->uNumLoadedSprites);
1063 *v1 = *v2;
1064 }
1065
1066 //----- (00450CA9) --------------------------------------------------------
1067 void LODFile_Sprites::DeleteSpritesRange(int uStartIndex, int uStopIndex)
1068 {
1069 LODFile_Sprites *v3; // edi@1
1070 int v4; // esi@3
1071 LODSprite *v5; // ebx@3
1072 LODSprite *v6; // esi@7
1073 int v7; // edi@7
1074 int a2a; // [sp+10h] [bp+8h]@3
1075
1076 v3 = this;
1077 if ( this->pHardwareSprites )
1078 {
1079 if ( uStartIndex < uStopIndex )
1080 {
1081 v4 = uStartIndex;
1082 v5 = &this->pSpriteHeaders[uStartIndex];
1083 a2a = uStopIndex - uStartIndex;
1084 do
1085 {
1086 v5->Release();
1087 pHardwareSprites[v4].Release();
1088 ++v4;
1089 ++v5;
1090 --a2a;
1091 }
1092 while ( a2a );
1093 }
1094 }
1095 else
1096 {
1097 if ( uStartIndex < uStopIndex )
1098 {
1099 v6 = &this->pSpriteHeaders[uStartIndex];
1100 v7 = uStopIndex - uStartIndex;
1101 do
1102 {
1103 v6->Release();
1104 ++v6;
1105 --v7;
1106 }
1107 while ( v7 );
1108 }
1109 }
1110 }
1111
1112 //----- (00450D1D) --------------------------------------------------------
1113 void LODSprite::Release()
1114 {
1115 LODSprite *v1; // esi@1
1116
1117 v1 = this;
1118 if ( !(HIBYTE(this->word_1A) & 4) )
1119 {
1120 pAllocator->FreeChunk(this->pDecompressedBytes);
1121 pAllocator->FreeChunk(v1->pSpriteLines);
1122 }
1123 v1->word_1A = 0;
1124 v1->pDecompressedBytes = 0;
1125 v1->pSpriteLines = 0;
1126 v1->pName[0] = 0;
1127 v1->word_16 = 0;
1128 v1->uPaletteId = 0;
1129 v1->uTexturePitch = 0;
1130 v1->uHeight = 0;
1131 v1->uWidth = 0;
1132 v1->uSpriteSize = 0;
1133 }
1134
1135 //----- (00450D68) --------------------------------------------------------
1136 void Sprite::Release()
1137 {
1138 Sprite *v1; // esi@1
1139 IDirectDrawSurface *v2; // eax@3
1140 IDirect3DTexture2 *v3; // eax@5
1141
1142 v1 = this;
1143 if ( this->pName )
1144 pAllocator->FreeChunk((void *)this->pName);
1145 v2 = v1->pTextureSurface;
1146 if ( v2 )
1147 v2->Release();
1148 v3 = v1->pTexture;
1149 if ( v3 )
1150 v3->Release();
1151 v1->pName = 0;
1152 v1->pTextureSurface = 0;
1153 v1->pTexture = 0;
1154 }
1155
1156
1157
1158
1159 //----- (0040FA2E) --------------------------------------------------------
1160 bool LODFile_IconsBitmaps::LoadBitmaps(const char *pFilename)
1161 {
1162 ReleaseAll();
1163 if (LoadHeader(pFilename, 1))
1164 return false;
1165 else
1166 return LoadSubIndices("bitmaps") == 0;
1167 }
1168
1169
1170 //----- (0040FAEE) --------------------------------------------------------
1171 bool LODFile_IconsBitmaps::LoadIconsOrEvents(const char *pLODFilename)
1172 {
1173 ReleaseAll();
1174
1175 if (LoadHeader(pLODFilename, 1))
1176 return false;
1177 else
1178 return LoadSubIndices("icons") == 0;
1179 }
1180
1181
1182 //----- (0040FA60) --------------------------------------------------------
1183 void LODFile_IconsBitmaps::ReleaseAll()
1184 {
1185 LODFile_IconsBitmaps *v1; // esi@1
1186 unsigned int v2; // edi@1
1187 Texture *v3; // ebp@2
1188 struct IDirect3DTexture2 **v4; // eax@3
1189 struct IDirect3DTexture2 *v5; // eax@4
1190 struct IDirectDrawSurface **v6; // eax@6
1191 struct IDirectDrawSurface *v7; // eax@7
1192
1193 v1 = this;
1194 v2 = this->uNumLoadedFiles - 1;
1195 if ( (v2 & 0x80000000u) == 0 )
1196 {
1197 v3 = &this->pTextures[v2];
1198 do
1199 {
1200 v3->Release();
1201 v4 = v1->pHardwareTextures;
1202 if ( v4 )
1203 {
1204 v5 = v4[v2];
1205 if ( v5 )
1206 {
1207 v5->Release();
1208 v1->pHardwareTextures[v2] = 0;
1209 }
1210 }
1211 v6 = v1->pHardwareSurfaces;
1212 if ( v6 )
1213 {
1214 v7 = v6[v2];
1215 if ( v7 )
1216 {
1217 v7->Release();
1218 v1->pHardwareSurfaces[v2] = 0;
1219 }
1220 }
1221 --v2;
1222 --v3;
1223 }
1224 while ( (v2 & 0x80000000u) == 0 );
1225 }
1226 v1->uTexturePacksCount = 0;
1227 v1->uNumPrevLoadedFiles = 0;
1228 v1->dword_11B84 = 0;
1229 v1->dword_11B80 = 0;
1230 v1->uNumLoadedFiles = 0;
1231 }
1232
1233 //----- (0040F9F0) --------------------------------------------------------
1234 unsigned int LODFile_IconsBitmaps::FindTextureByName(const char *pName)
1235 {
1236 LODFile_IconsBitmaps *v2; // esi@1
1237 unsigned int v3; // edi@1
1238 Texture *v4; // ebx@2
1239 unsigned int result; // eax@5
1240
1241 v2 = this;
1242 v3 = 0;
1243 if ( (signed int)this->uNumLoadedFiles <= 0 )
1244 {
1245 LABEL_5:
1246 result = -1;
1247 }
1248 else
1249 {
1250 v4 = this->pTextures;
1251 while ( _strcmpi(v4->pName, pName) )
1252 {
1253 ++v3;
1254 ++v4;
1255 if ( (signed int)v3 >= (signed int)v2->uNumLoadedFiles )
1256 goto LABEL_5;
1257 }
1258 result = v3;
1259 }
1260 return result;
1261 }
1262
1263 //----- (0040F9C5) --------------------------------------------------------
1264 int LODFile_IconsBitmaps::_40F9C5()
1265 {
1266 signed int result; // eax@1
1267 Texture *pTex; // edx@1
1268
1269 result = this->uNumLoadedFiles;
1270 for ( pTex = &this->pTextures[result]; !pTex->pName[0]; --pTex )
1271 --result;
1272 if ( result < (signed int)this->uNumLoadedFiles )
1273 {
1274 ++result;
1275 this->uNumLoadedFiles = result;
1276 }
1277 return result;
1278 }
1279
1280
1281
1282 //----- (0046249B) --------------------------------------------------------
1283 LODFile_Sprites::~LODFile_Sprites()
1284 {
1285 LODFile_Sprites *v1; // esi@1
1286 signed int v2; // ebx@1
1287 LODSprite *v3; // edi@3
1288 char *v4; // edi@6
1289 int thisa; // [sp+4h] [bp-10h]@3
1290 LODSprite *thisb; // [sp+4h] [bp-10h]@7
1291
1292 v1 = this;
1293 v2 = 0;
1294 if ( this->pHardwareSprites )
1295 {
1296 if ( (signed int)this->uNumLoadedSprites > 0 )
1297 {
1298 thisa = 0;
1299 v3 = this->pSpriteHeaders;
1300 do
1301 {
1302 v3->Release();
1303 v1->pHardwareSprites[thisa].Release();
1304 ++thisa;
1305 ++v2;
1306 ++v3;
1307 }
1308 while ( v2 < (signed int)v1->uNumLoadedSprites );
1309 }
1310 }
1311 else
1312 {
1313 v4 = (char *)&this->uNumLoadedSprites;
1314 if ( (signed int)this->uNumLoadedSprites > 0 )
1315 {
1316 thisb = this->pSpriteHeaders;
1317 do
1318 {
1319 thisb->Release();
1320 ++thisb;
1321 ++v2;
1322 }
1323 while ( v2 < *(int *)v4 );
1324 }
1325 }
1326 //_eh_vector_destructor_iterator_(v1->pSpriteHeaders, 40, 1500, LODSprite::dtor);
1327 //LOD::File::vdtor((LOD::File *)v1);
1328 }
1329 // 4CC2B4: using guessed type int __stdcall _eh vector destructor iterator_(int, int, int, int);
1330
1331
1332 //----- (00462463) --------------------------------------------------------
1333 LODSprite::~LODSprite()
1334 {
1335 LODSprite *v1; // esi@1
1336
1337 v1 = this;
1338 if ( !(HIBYTE(this->word_1A) & 4) )
1339 {
1340 pAllocator->FreeChunk(this->pDecompressedBytes);
1341 pAllocator->FreeChunk(v1->pSpriteLines);
1342 }
1343 v1->pDecompressedBytes = 0;
1344 v1->pSpriteLines = 0;
1345 }
1346
1347 //----- (004623E5) --------------------------------------------------------
1348 LODFile_Sprites::LODFile_Sprites():
1349 LOD::File()
1350 {
1351 /*_eh_vector_constructor_iterator_(
1352 v1->pSpriteHeaders,
1353 40,
1354 1500,
1355 (void (__thiscall *)(void *))LODSprite::LODSprite,
1356 (void (__thiscall *)(void *))LODSprite::dtor);*/
1357 field_ECA4 = 0;
1358 field_ECA0 = 0;
1359 pHardwareSprites = 0;
1360 field_ECAC = 0;
1361 field_ECB4 = 0;
1362 uNumLoadedSprites = 0;
1363 }
1364
1365 //----- (00462303) --------------------------------------------------------
1366 LODFile_IconsBitmaps::~LODFile_IconsBitmaps()
1367 {
1368 LODFile_IconsBitmaps *v1; // esi@1
1369 unsigned int v2; // edi@1
1370 struct IDirect3DTexture2 **v3; // eax@3
1371 struct IDirect3DTexture2 *v4; // eax@4
1372 struct IDirectDrawSurface **v5; // eax@6
1373 struct IDirectDrawSurface *v6; // eax@7
1374 Texture *thisa; // [sp+4h] [bp-10h]@2
1375
1376 v1 = this;
1377 v2 = this->uNumLoadedFiles - 1;
1378 if ( (v2 & 0x80000000u) == 0 )
1379 {
1380 thisa = &this->pTextures[v2];
1381 do
1382 {
1383 thisa->Release();
1384 v3 = v1->pHardwareTextures;
1385 if ( v3 )
1386 {
1387 v4 = v3[v2];
1388 if ( v4 )
1389 {
1390 v4->Release();
1391 v1->pHardwareTextures[v2] = 0;
1392 }
1393 }
1394 v5 = v1->pHardwareSurfaces;
1395 if ( v5 )
1396 {
1397 v6 = v5[v2];
1398 if ( v6 )
1399 {
1400 v6->Release();
1401 v1->pHardwareSurfaces[v2] = 0;
1402 }
1403 }
1404 --thisa;
1405 --v2;
1406 }
1407 while ( (v2 & 0x80000000u) == 0 );
1408 }
1409 if ( v1->pHardwareSurfaces )
1410 free(v1->pHardwareSurfaces);
1411 if ( v1->pHardwareTextures )
1412 free(v1->pHardwareTextures);
1413 if ( v1->ptr_011BB4 )
1414 free(v1->ptr_011BB4);
1415 //LOD::File::vdtor((LOD::File *)v1);
1416 }
1417
1418 //----- (00462272) --------------------------------------------------------
1419 LODFile_IconsBitmaps::LODFile_IconsBitmaps():
1420 LOD::File()
1421 {
1422 LODFile_IconsBitmaps *v1; // esi@1
1423 Texture *v2; // ebx@1
1424 signed int v3; // [sp+4h] [bp-10h]@1
1425
1426 v1 = this;
1427 /*v2 = v1->pTextures;
1428 v3 = 1000;
1429 do
1430 {
1431 Texture::Texture(v2);
1432 ++v2;
1433 --v3;
1434 }
1435 while ( v3 );*/
1436 v1->uTexturePacksCount = 0;
1437 v1->uNumPrevLoadedFiles = 0;
1438 v1->dword_11B84 = 0;
1439 v1->dword_11B80 = 0;
1440 v1->uNumLoadedFiles = 0;
1441 v1->dword_011BA4 = 0;
1442 v1->dword_011BA8 = 0;
1443 v1->pHardwareSurfaces = 0;
1444 v1->pHardwareTextures = 0;
1445 v1->ptr_011BB4 = 0;
1446 }
1447
1448
1449 //----- (004621A7) --------------------------------------------------------
1450 bool LODWriteableFile::_4621A7()
1451 {
1452 CloseWriteFile();
1453 return LoadFile(pLODName, 0);
1454 }
1455
1456
1457 //----- (00461FD4) --------------------------------------------------------
1458 int LODWriteableFile::Save()
1459 {
1460 LODWriteableFile *v1; // esi@1
1461 int v2; // edi@1
1462 unsigned int v3; // edx@1
1463 LOD::Directory *v4; // eax@2
1464 unsigned int v5; // ecx@2
1465 int v6; // eax@2
1466 signed int v7; // ebx@5
1467 int v8; // ecx@5
1468 LOD::Directory **v9; // edi@6
1469 int v10; // edx@6
1470 LOD::Directory *v11; // eax@6
1471 FILE *v12; // eax@9
1472 FILE *v13; // ebx@9
1473 signed int result; // eax@10
1474 unsigned int v15; // eax@11
1475 FILE *v16; // ST00_4@11
1476 size_t v17; // edi@12
1477 char OldFilename[256]; // [sp+Ch] [bp-228h]@9
1478 char NewFilename[256]; // [sp+10Ch] [bp-128h]@15
1479 //LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
1480 unsigned int v21; // [sp+22Ch] [bp-8h]@5
1481 int v22; // [sp+230h] [bp-4h]@1
1482
1483 v1 = this;
1484 v2 = 0;
1485 v3 = this->uNumSubIndices;
1486 v22 = 0;
1487 if ( (signed int)v3 > 0 )
1488 {
1489 v4 = this->pSubIndices;
1490 v5 = v3;
1491 v6 = (int)&v4->uDataSize;
1492 do
1493 {
1494 v2 += *(int *)v6;
1495 v6 += 32;
1496 --v5;
1497 }
1498 while ( v5 );
1499 v22 = v2;
1500 }
1501 v7 = 0;
1502 v21 = 32 * v3 + v2;
1503 v8 = 32 * v3;
1504 if ( (signed int)v3 > 0 )
1505 {
1506 v9 = &v1->pSubIndices;
1507 v10 = 0;
1508 v11 = v1->pSubIndices;
1509 do
1510 {
1511 v11[v10].uOfsetFromSubindicesStart = v8;
1512 v11 = *v9;
1513 v8 += (*v9)[v10].uDataSize;
1514 ++v7;
1515 ++v10;
1516 }
1517 while ( v7 < (signed int)v1->uNumSubIndices );
1518 v2 = v22;
1519 }
1520 strcpy(OldFilename, "lod.tmp");
1521 v12 = fopen(OldFilename, "wb+");
1522 v13 = v12;
1523 if ( v12 )
1524 {
1525 fwrite(&v1->header, 0x100u, 1u, v12);
1526
1527 LOD::Directory v0; // [sp+20Ch] [bp-28h]@11
1528 //LOD::Directory::LOD::Directory(&v0);
1529
1530 strcpy((char *)&v0, "chapter");
1531 v15 = v1->uOffsetToSubIndex;
1532 v0.dword_000018 = 0;
1533 v0.uOfsetFromSubindicesStart = v15;
1534 v0.word_00001E = 0;
1535 v0.uDataSize = v21;
1536 v0.uNumSubIndices = LOWORD(v1->uNumSubIndices);
1537 fwrite(&v0, 0x20u, 1u, v13);
1538 fwrite(v1->pSubIndices, 0x20u, v1->uNumSubIndices, v13);
1539 v16 = v1->pOutputFileHandle;
1540 v22 = v2;
1541 fseek(v16, 0, 0);
1542 if ( v2 > 0 )
1543 {
1544 do
1545 {
1546 v17 = v1->uIOBufferSize;
1547 if ( v22 <= (signed int)v17 )
1548 v17 = v22;
1549 fread(v1->pIOBuffer, 1u, v17, v1->pOutputFileHandle);
1550 fwrite(v1->pIOBuffer, 1u, v17, v13);
1551 v22 -= v17;
1552 }
1553 while ( v22 > 0 );
1554 }
1555 strcpy(NewFilename, (const char *)v1->pLODName);
1556 fclose(v13);
1557 fclose(v1->pOutputFileHandle);
1558 v1->CloseWriteFile();
1559 remove("lodapp.tmp");
1560 remove(NewFilename);
1561 rename(OldFilename, NewFilename);
1562 v1->CloseWriteFile();
1563 v1->LoadFile(v1->pLODName, 0);
1564 result = 0;
1565 }
1566 else
1567 {
1568 result = 5;
1569 }
1570 return result;
1571 }
1572
1573
1574 //----- (00461F71) --------------------------------------------------------
1575 bool LOD::File::AppendDirectory(LOD::Directory *pDir, const void *pData)
1576 {
1577 unsigned int v3; // edi@1
1578 bool result; // eax@2
1579 FILE *v5; // ST0C_4@3
1580
1581 v3 = this->uNumSubIndices;
1582 if ( (signed int)v3 < 299 )
1583 {
1584 memcpy(&this->pSubIndices[v3], pDir, sizeof(this->pSubIndices[v3]));
1585 v5 = this->pOutputFileHandle;
1586 ++this->uNumSubIndices;
1587 fwrite(pData, 1u, pDir->uDataSize, v5);
1588 result = 1;
1589 }
1590 else
1591 {
1592 MessageBoxA(0, "Unable to append item!", "LOD::File", 0x30u);
1593 result = 0;
1594 }
1595 return result;
1596 }
1597
1598
1599 //----- (00461F1E) --------------------------------------------------------
1600 int LODWriteableFile::CreateTempFile()
1601 {
1602 LODWriteableFile *v1; // esi@1
1603 int result; // eax@2
1604 FILE *pFile; // eax@5
1605 int v4; // eax@5
1606
1607 v1 = this;
1608 if ( this->isFileOpened )
1609 {
1610 if ( this->pIOBuffer && this->uIOBufferSize )
1611 {
1612 this->uCurrentIndexDir = 0;
1613 this->uNumSubIndices = 0;
1614 pFile = fopen("lodapp.tmp", "wb+");
1615 v1->pOutputFileHandle = pFile;
1616 v4 = -(pFile != 0);
1617 LOBYTE(v4) = v4 & 0xF9;
1618 result = v4 + 7;
1619 }
1620 else
1621 {
1622 result = 5;
1623 }
1624 }
1625 else
1626 {
1627 result = 1;
1628 }
1629 return result;
1630 }
1631
1632
1633
1634 //----- (00461EE9) --------------------------------------------------------
1635 void LODWriteableFile::CloseWriteFile()
1636 {
1637 FILE **v1; // esi@1
1638
1639 v1 = (FILE **)this;
1640 if ( this->isFileOpened )
1641 {
1642 this->pContainerName[0] = 0;
1643 this->uCurrentIndexDir = 0;
1644 this->isFileOpened = 0;
1645 _6A0CA8_lod_unused = 0;
1646 fflush(this->pFile);
1647 fclose(*v1);
1648 }
1649 }
1650 // 6A0CA8: using guessed type int 6A0CA8_lod_unused;
1651
1652 //----- (00461B48) --------------------------------------------------------
1653 unsigned int LODWriteableFile::Write(const LOD::Directory *pDir, const void *pDirData, int a4)
1654 {
1655 LODWriteableFile *v4; // ebx@1
1656 int v5; // esi@1
1657 unsigned __int8 v7; // zf@7
1658 unsigned __int8 v8; // sf@7
1659 const LOD::Directory *v9; // edi@9
1660 int v10; // eax@9
1661 unsigned __int8 v11; // of@15
1662 unsigned __int16 v12; // dx@17
1663 LOD::Directory *v13; // eax@17
1664 unsigned __int16 v14; // cx@17
1665 int v15; // edi@27
1666 unsigned int v16; // eax@27
1667 int v17; // eax@29
1668 int v18; // edx@31
1669 int v19; // eax@31
1670 void *v20; // edi@32
1671 LOD::Directory *v21; // edi@34
1672 signed int v22; // esi@34
1673 int v23; // eax@34
1674 LOD::Directory *v24; // ecx@35
1675 int v25; // edx@35
1676 __int32 v26; // eax@37
1677 int i; // esi@39
1678 __int32 v28; // esi@46
1679 char pFilename[256]; // [sp+Ch] [bp-230h]@22
1680 char NewFilename[256]; // [sp+10Ch] [bp-130h]@51
1681 //LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
1682 size_t v33; // [sp+22Ch] [bp-10h]@27
1683 int v34; // [sp+230h] [bp-Ch]@7
1684 __int32 v35; // [sp+234h] [bp-8h]@8
1685 int v36; // [sp+238h] [bp-4h]@7
1686 size_t Count; // [sp+244h] [bp+8h]@40
1687 __int32 Countc; // [sp+244h] [bp+8h]@46
1688 size_t Countb; // [sp+244h] [bp+8h]@47
1689 FILE *pFile; // [sp+24Ch] [bp+10h]@22
1690
1691 v4 = this;
1692 v5 = 0;
1693 if ( !this->isFileOpened )
1694 return 1;
1695 if ( !this->pSubIndices )
1696 return 2;
1697 if ( !this->pIOBuffer || !this->uIOBufferSize )
1698 return 3;
1699 v7 = this->uNumSubIndices == 0;
1700 v8 = (this->uNumSubIndices & 0x80000000u) != 0;
1701 v36 = 0;
1702 v34 = 0;
1703 if ( v8 | v7 )
1704 {
1705 v9 = pDir;
1706 goto LABEL_22;
1707 }
1708 v35 = 0;
1709 while ( 1 )
1710 {
1711 v9 = pDir;
1712 v10 = _strcmpi((const char *)v4->pSubIndices + v35, (const char *)pDir);
1713 if ( v10 )
1714 {
1715 if ( v10 > 0 )
1716 goto LABEL_22;
1717 goto LABEL_15;
1718 }
1719 if ( !a4 )
1720 goto LABEL_20;
1721 if ( a4 == 1 )
1722 break;
1723 if ( a4 == 2 )
1724 return 4;
1725 LABEL_15:
1726 v35 += 32;
1727 ++v5;
1728 v11 = __OFSUB__(v5, v4->uNumSubIndices);
1729 v8 = ((v5 - v4->uNumSubIndices) & 0x80000000u) != 0;
1730 v34 = v5;
1731 if ( !(v8 ^ v11) )
1732 goto LABEL_22;
1733 }
1734 v12 = pDir->uNumSubIndices;
1735 v13 = &v4->pSubIndices[v5];
1736 v14 = v13->uNumSubIndices;
1737 if ( v14 >= v12 && (v14 != v12 || (unsigned __int16)v13->word_00001E >= pDir->word_00001E) )
1738 return 4;
1739 LABEL_20:
1740 v36 = 1;
1741 LABEL_22:
1742 strcpy(pFilename, "lod.tmp");
1743 pFile = fopen(pFilename, "wb+");
1744 if ( !pFile )
1745 return 5;
1746 if ( v36 )
1747 v35 = v4->pSubIndices[v5].uDataSize;
1748 else
1749 v35 = 0;
1750 v33 = v9->uDataSize;
1751 v15 = v33 - v35;
1752
1753 LOD::Directory Str; // [sp+20Ch] [bp-30h]@27
1754 //LOD::Directory::LOD::Directory(&Str);
1755
1756 strcpy((char *)&Str, "chapter");
1757 v16 = v4->uLODDataSize;
1758 Str.uNumSubIndices = LOWORD(v4->uNumSubIndices);
1759 Str.dword_000018 = 0;
1760 Str.word_00001E = 0;
1761 if ( !v36 )
1762 {
1763 ++Str.uNumSubIndices;
1764 v15 += 32;
1765 }
1766 v7 = v36 == 0;
1767 Str.uDataSize = v15 + v16;
1768 Str.uOfsetFromSubindicesStart = 288;
1769 v17 = (signed __int16)Str.uNumSubIndices;
1770 v4->uNumSubIndices = (signed __int16)Str.uNumSubIndices;
1771 if ( v7 && v17 > v5 )
1772 {
1773 v18 = v17;
1774 v19 = v17 - v5;
1775 do
1776 {
1777 v20 = &v4->pSubIndices[v18];
1778 --v18;
1779 --v19;
1780 memcpy(v20, (char *)v20 - 32, 0x20u);
1781 }
1782 while ( v19 );
1783 v5 = v34;
1784 }
1785 v21 = v4->pSubIndices;
1786 v34 = 32 * v5;
1787 memcpy(&v21[v5], pDir, sizeof(v21[v5]));
1788 v22 = 0;
1789 v23 = 32 * v4->uNumSubIndices;
1790 if ( (signed int)v4->uNumSubIndices > 0 )
1791 {
1792 v24 = v4->pSubIndices;
1793 v25 = 0;
1794 do
1795 {
1796 v24[v25].uOfsetFromSubindicesStart = v23;
1797 v24 = v4->pSubIndices;
1798 v23 += v24[v25].uDataSize;
1799 ++v22;
1800 ++v25;
1801 }
1802 while ( v22 < (signed int)v4->uNumSubIndices );
1803 }
1804 fwrite(&v4->header, 0x100u, 1u, pFile);
1805 fwrite(&Str, 0x20u, 1u, pFile);
1806 fseek(v4->pFile, Str.uOfsetFromSubindicesStart, 0);
1807 fwrite(v4->pSubIndices, 0x20u, v4->uNumSubIndices, pFile);
1808 v26 = 32 * v4->uNumSubIndices;
1809 if ( !v36 )
1810 v26 -= 32;
1811 fseek(v4->pFile, v26, 1);
1812 for ( i = *(unsigned int *)((char *)&v4->pSubIndices->uOfsetFromSubindicesStart + v34)
1813 - v4->pSubIndices->uOfsetFromSubindicesStart; i > 0; i -= Count )
1814 {
1815 Count = v4->uIOBufferSize;
1816 if ( i <= (signed int)v4->uIOBufferSize )
1817 Count = i;
1818 fread(v4->pIOBuffer, 1u, Count, v4->pFile);
1819 fwrite(v4->pIOBuffer, 1u, Count, pFile);
1820 }
1821 fwrite(pDirData, 1u, v33, pFile);
1822 if ( v36 )
1823 fseek(v4->pFile, v35, 1);
1824 Countc = ftell(v4->pFile);
1825 fseek(v4->pFile, 0, 2);
1826 v28 = ftell(v4->pFile) - Countc;
1827 fseek(v4->pFile, Countc, 0);
1828 while ( v28 > 0 )
1829 {
1830 Countb = v4->uIOBufferSize;
1831 if ( v28 <= (signed int)v4->uIOBufferSize )
1832 Countb = v28;
1833 fread(v4->pIOBuffer, 1u, Countb, v4->pFile);
1834 fwrite(v4->pIOBuffer, 1u, Countb, pFile);
1835 v28 -= Countb;
1836 }
1837 strcpy(NewFilename, (const char *)v4->pLODName);
1838 fclose(pFile);
1839 v4->CloseWriteFile();
1840 remove(NewFilename);
1841 rename(pFilename, NewFilename);
1842 v4->CloseWriteFile();
1843 v4->LoadFile(v4->pLODName, 0);
1844 return 0;
1845 }
1846
1847
1848 //----- (00461A43) --------------------------------------------------------
1849 bool LODWriteableFile::LoadFile(const char *pFilename, bool bWriting)
1850 {
1851 LODWriteableFile *v3; // esi@1
1852 FILE *pFile_dup; // eax@4
1853 unsigned int v5; // ecx@5
1854 __int32 v6; // eax@5
1855 FILE *v7; // ST00_4@5
1856 size_t v8; // edi@5
1857 const char *v10; // [sp-4h] [bp-30h]@2
1858
1859 v3 = this;
1860 if ( bWriting & 1 )
1861 v10 = "rb";
1862 else
1863 v10 = "rb+";
1864 pFile_dup = fopen(pFilename, v10);
1865 v3->pFile = pFile_dup;
1866 if ( !pFile_dup )
1867 return 0;
1868 strcpy((char *)v3->pLODName, pFilename);
1869 fread(&v3->header, 0x100u, 1u, v3->pFile);
1870
1871 LOD::Directory dir; // [sp+Ch] [bp-20h]@5
1872 //LOD::Directory::LOD::Directory(&dir);
1873
1874 fread(&dir, 0x20u, 1u, v3->pFile);
1875 fseek(v3->pFile, 0, 0);
1876 v3->isFileOpened = 1;
1877 strcpy((char *)v3->pContainerName, "chapter");
1878 v5 = (signed __int16)dir.uNumSubIndices;
1879 v6 = dir.uOfsetFromSubindicesStart;
1880 v3->uCurrentIndexDir = 0;
1881 v3->uOffsetToSubIndex = v6;
1882 v7 = v3->pFile;
1883 v3->uNumSubIndices = v5;
1884 v3->uLODDataSize = dir.uDataSize;
1885 fseek(v7, v6, 0);
1886 v8 = v3->uNumSubIndices;
1887 if ( (signed int)v8 > 300 )
1888 {
1889 MessageBoxA(0, "LODchapterPages exceed 300", "LOD::File", MB_ICONEXCLAMATION);
1890 fclose(v3->pFile);
1891 return 0;
1892 }
1893 fread(v3->pSubIndices, 0x20u, v8, v3->pFile);
1894 return 1;
1895 }
1896
1897
1898 //----- (00461A11) --------------------------------------------------------
1899 void LOD::File::FreeSubIndexAndIO()
1900 {
1901 void *v1; // edi@1
1902 LOD::Directory **v2; // esi@1
1903
1904 v1 = this;
1905 v2 = &this->pSubIndices;
1906 pAllocator->FreeChunk(this->pSubIndices);
1907 v1 = (char *)v1 + 264;
1908 pAllocator->FreeChunk(pIOBuffer);// delete [] pIOBuffer;
1909 pIOBuffer = nullptr;
1910 pSubIndices = nullptr;
1911 }
1912
1913
1914 //----- (00461954) --------------------------------------------------------
1915 void LOD::File::AllocSubIndicesAndIO(unsigned int uNumSubIndices, unsigned int uBufferSize)
1916 {
1917 LOD::File *v3; // esi@1
1918 LOD::Directory *pSubIndices_dup; // eax@3
1919 char v5; // zf@3
1920
1921 v3 = this;
1922 if ( this->pSubIndices )
1923 {
1924 MessageBoxA(0, "Attempt to reset a LOD subindex!", "MM6", MB_ICONEXCLAMATION);
1925 pAllocator->FreeChunk(v3->pSubIndices);
1926 v3->pSubIndices = 0;
1927 }
1928 pSubIndices_dup = (LOD::Directory *)pAllocator->AllocNamedChunk(
1929 v3->pSubIndices,
1930 32 * uNumSubIndices,
1931 "LODsub");
1932 v5 = v3->pIOBuffer == 0;
1933 v3->pSubIndices = pSubIndices_dup;
1934 if ( !v5 )
1935 {
1936 MessageBoxA(0, "Attempt to reset a LOD IObuffer!", "MM6", MB_ICONEXCLAMATION);
1937 pAllocator->FreeChunk(v3->pIOBuffer);
1938 v3->pIOBuffer = 0;
1939 v3->uIOBufferSize = 0;
1940 }
1941 if ( uBufferSize )
1942 {
1943 v3->pIOBuffer = (unsigned __int8 *)pAllocator->AllocNamedChunk(v3->pIOBuffer, uBufferSize, "LODio");
1944 v3->uIOBufferSize = uBufferSize;
1945 }
1946 }
1947
1948
1949
1950 //----- (0046188A) --------------------------------------------------------
1951 int LOD::File::LoadSubIndices(const char *pContainer)
1952 {
1953 LOD::File *v2; // esi@1
1954 unsigned int uDir; // edi@1
1955 int uDir_dup; // ebx@2
1956 int result; // eax@5
1957 LOD::Directory *v6; // eax@7
1958 LOD::Directory *v7; // eax@7
1959 __int32 v8; // edx@7
1960 FILE *v9; // ST00_4@7
1961 LOD::Directory *pSubIndices_dup; // eax@7
1962
1963 v2 = this;
1964 ResetSubIndices();
1965 uDir = 0;
1966 if ( (signed int)v2->header.uNumIndices <= 0 )
1967 {
1968 LABEL_5:
1969 result = 3;
1970 }
1971 else
1972 {
1973 uDir_dup = 0;
1974 while ( _strcmpi(pContainer, (const char *)&v2->pRoot[uDir_dup]) )
1975 {
1976 ++uDir;
1977 ++uDir_dup;
1978 if ( (signed int)uDir >= (signed int)v2->header.uNumIndices )
1979 goto LABEL_5;
1980 }
1981 strcpy((char *)v2->pContainerName, pContainer);
1982 v6 = v2->pRoot;
1983 v2->uCurrentIndexDir = uDir;
1984 v7 = &v6[uDir];
1985 v8 = v7->uOfsetFromSubindicesStart;
1986 v2->uOffsetToSubIndex = v8;
1987 v9 = v2->pFile;
1988 v2->uNumSubIndices = v7->uNumSubIndices;
1989 fseek(v9, v8, 0);
1990 pSubIndices_dup = (LOD::Directory *)pAllocator->AllocNamedChunk(
1991 v2->pSubIndices,
1992 32 * (v2->uNumSubIndices + 5),
1993 "LOD Index");
1994 v2->pSubIndices = pSubIndices_dup;
1995 if ( pSubIndices_dup )
1996 fread(pSubIndices_dup, 0x20u, v2->uNumSubIndices, v2->pFile);
1997 result = 0;
1998 }
1999 return result;
2000 }
2001
2002 //----- (004617D5) --------------------------------------------------------
2003 bool LOD::File::LoadHeader(const char *pFilename, bool bWriting)
2004 {
2005 LOD::File *this_dup; // esi@1
2006 FILE *pFile_dup; // eax@6
2007 void *pRoot_dup; // eax@7
2008 const char *v6; // [sp-4h] [bp-Ch]@4
2009 FILE *v7; // [sp-4h] [bp-Ch]@7
2010
2011 this_dup = this;
2012 if ( this->isFileOpened )
2013 Close();
2014 if ( bWriting & 1 )
2015 v6 = "rb";
2016 else
2017 v6 = "rb+";
2018 pFile_dup = fopen(pFilename, v6);
2019 this_dup->pFile = pFile_dup;
2020 if ( pFile_dup )
2021 {
2022 strcpy(this_dup->pLODName, pFilename);
2023 fread(&this_dup->header, 0x100u, 1u, this_dup->pFile);
2024 pRoot_dup = pAllocator->AllocNamedChunk(this_dup->pRoot, 0xA0u, "LOD CArray");
2025 this_dup->pRoot = (LOD::Directory *)pRoot_dup;
2026 v7 = this_dup->pFile;
2027 if ( pRoot_dup )
2028 {
2029 fread(pRoot_dup, 0x20u, this_dup->header.uNumIndices, v7);
2030 fseek(this_dup->pFile, 0, 0);
2031 this_dup->isFileOpened = 1;
2032 return false;
2033 }
2034 else
2035 {
2036 fclose(v7);
2037 return true;
2038 }
2039 }
2040 return true;
2041 }
2042
2043
2044 //----- (004617B6) --------------------------------------------------------
2045 void LOD::FileHeader::Reset()
2046 {
2047 this->pSignature[0] = 0;
2048 this->array_000004[0] = 0;
2049 this->array_000054[0] = 0;
2050 this->dword_0000A4 = 0;
2051 this->dword_0000A8 = 0;
2052 this->uNumIndices = 0;
2053 }
2054
2055 //----- (00461790) --------------------------------------------------------
2056 LOD::File::~File()
2057 {
2058 LOD::File *v1; // esi@1
2059
2060 v1 = this;
2061 if ( this->isFileOpened )
2062 {
2063 fclose(this->pFile);
2064 pAllocator->FreeChunk(v1->pSubIndices);
2065 }
2066 }
2067
2068
2069 //----- (0046175B) --------------------------------------------------------
2070 LOD::File::File():
2071 pRoot(nullptr)
2072 {
2073 LOD::File *v1; // esi@1
2074
2075 v1 = this;
2076 v1->pFile = 0;
2077 v1->pSubIndices = 0;
2078 v1->pIOBuffer = 0;
2079 v1->isFileOpened = 0;
2080 v1->uIOBufferSize = 0;
2081 Close();
2082 }
2083
2084
2085 //----- (00461743) --------------------------------------------------------
2086 LOD::Directory *LOD::Directory::Reset()
2087 {
2088 LOD::Directory *result; // eax@1
2089
2090 result = this;
2091 this->pFilename[0] = 0;
2092 this->uOfsetFromSubindicesStart = 0;
2093 this->uDataSize = 0;
2094 this->dword_000018 = 0;
2095 this->uNumSubIndices = 0;
2096 this->word_00001E = 0;
2097 return result;
2098 }
2099
2100
2101 //----- (0046172B) --------------------------------------------------------
2102 LOD::Directory::Directory()
2103 {
2104 this->pFilename[0] = 0;
2105 this->uOfsetFromSubindicesStart = 0;
2106 this->uDataSize = 0;
2107 this->uNumSubIndices = 0;
2108 this->dword_000018 = 0;
2109 this->word_00001E = 0;
2110 }
2111
2112 //----- (0046165E) --------------------------------------------------------
2113 int LOD::File::CalcIndexFast(int startIndex, int maxIndex, const char *pContainerName)
2114 {
2115 int v4; // esi@1
2116 int v5; // ebx@2
2117 int result; // eax@2
2118 int v7; // edi@10
2119 int v8; // esi@11
2120 int v9; // esi@17
2121 LOD::File *v10; // [sp+Ch] [bp-4h]@1
2122
2123 v4 = startIndex;
2124 v10 = this;
2125 while ( 1 ) // binary search in LOD indices
2126 {
2127 while ( 1 )
2128 {
2129 v5 = maxIndex - v4;
2130 result = _strcmpi((const char *)pContainerName, (const char *)(&v10->pSubIndices[(maxIndex - v4) / 2] + v4));
2131 if ( !result )
2132 _6A0CA4_lod_binary_search = (maxIndex - v4) / 2 + v4;
2133 if ( v4 == maxIndex )
2134 goto LABEL_14;
2135 if ( result < 0 )
2136 break;
2137 if ( v5 <= 4 )
2138 {
2139 v7 = v4;
2140 if ( v4 < maxIndex )
2141 {
2142 v9 = v4;
2143 do
2144 {
2145 result = _strcmpi((const char *)pContainerName, (const char *)&v10->pSubIndices[v9]);
2146 if ( !result )
2147 goto LABEL_21;
2148 ++v7;
2149 ++v9;
2150 }
2151 while ( v7 < maxIndex );
2152 }
2153 LABEL_14:
2154 _6A0CA4_lod_binary_search = -1;
2155 return result;
2156 }
2157 v4 += (maxIndex - v4) / 2;
2158 }
2159 if ( v5 <= 4 )
2160 break;
2161 maxIndex = (maxIndex - v4) / 2 + v4;
2162 }
2163 v7 = v4;
2164 if ( v4 >= maxIndex )
2165 goto LABEL_14;
2166 v8 = v4;
2167 while ( 1 )
2168 {
2169 result = _strcmpi((const char *)pContainerName, (const char *)&v10->pSubIndices[v8]);
2170 if ( !result )
2171 break;
2172 ++v7;
2173 ++v8;
2174 if ( v7 >= maxIndex )
2175 goto LABEL_14;
2176 }
2177 LABEL_21:
2178 _6A0CA4_lod_binary_search = v7;
2179 return result;
2180 }
2181 // 6A0CA4: using guessed type int _6A0CA4_lod_binary_search;
2182
2183
2184 //----- (0046161C) --------------------------------------------------------
2185 bool LOD::File::DoesContainerExist(const char *pContainer)
2186 {
2187 LOD::File *this_dup; // esi@1
2188 int i; // ebx@1
2189 signed int i_dup; // edi@1
2190 bool result; // eax@4
2191
2192 this_dup = this;
2193 i = 0;
2194 i_dup = 0;
2195 if ( (signed int)this->uNumSubIndices <= 0 )
2196 {
2197 LABEL_4:
2198 result = 0;
2199 }
2200 else
2201 {
2202 while ( _strcmpi((const char *)pContainer, (const char *)&this_dup->pSubIndices[i]) )
2203 {
2204 ++i_dup;
2205 ++i;
2206 if ( i_dup >= (signed int)this_dup->uNumSubIndices )
2207 goto LABEL_4;
2208 }
2209 result = 1;
2210 }
2211 return result;
2212 }
2213
2214
2215 //----- (00461397) --------------------------------------------------------
2216 int LODFile_Sprites::_461397()
2217 {
2218 int result; // eax@1
2219 int *pfield_ECA0; // edi@1
2220 int v3; // esi@1
2221 int v4; // ecx@3
2222
2223 result = this->uNumLoadedSprites;
2224 pfield_ECA0 = &this->field_ECA0;
2225 v3 = this->field_ECA0;
2226 this->field_ECA8 = result;
2227 if ( result < v3 )
2228 this->field_ECA8 = v3;
2229 v4 = this->field_ECA4;
2230 if ( v3 < v4 )
2231 *pfield_ECA0 = v4;
2232 return result;
2233 }
2234
2235 //----- (00461580) --------------------------------------------------------
2236 FILE *LOD::File::FindContainer(const char *pContainerName, bool bLinearSearch)
2237 {
2238 LOD::File *this_dup; // esi@1
2239 unsigned int v4; // eax@4
2240 signed int v5; // edi@5
2241 int bLinearSearcha; // [sp+18h] [bp+Ch]@6
2242
2243 this_dup = this;
2244 if ( !this->isFileOpened )
2245 return 0;
2246 if ( bLinearSearch )
2247 {
2248 v5 = 0;
2249 if ( (signed int)this->uNumSubIndices > 0 )
2250 {
2251 bLinearSearcha = 0;
2252 while ( _strcmpi((const char *)pContainerName, (const char *)&this_dup->pSubIndices[bLinearSearcha]) )
2253 {
2254 ++bLinearSearcha;
2255 ++v5;
2256 if ( v5 >= (signed int)this_dup->uNumSubIndices )
2257 return 0;
2258 }
2259 v4 = this_dup->pSubIndices[v5].uOfsetFromSubindicesStart;
2260 goto LABEL_12;
2261 }
2262 return 0;
2263 }
2264 CalcIndexFast(0, this->uNumSubIndices, pContainerName);
2265 if ( _6A0CA4_lod_binary_search < 0 )
2266 return 0;
2267 v4 = this_dup->pSubIndices[_6A0CA4_lod_binary_search].uOfsetFromSubindicesStart;
2268 LABEL_12:
2269 fseek(this_dup->pFile, this_dup->uOffsetToSubIndex + v4, 0);
2270 return this_dup->pFile;
2271 }
2272 // 6A0CA4: using guessed type int _6A0CA4_lod_binary_search;
2273
2274 //----- (0041097D) --------------------------------------------------------
2275 void LODFile_IconsBitmaps::SetupPalettes(unsigned int uTargetRBits, unsigned int uTargetGBits, unsigned int uTargetBBits)
2276 {
2277 int v4; // edx@1
2278 LODFile_IconsBitmaps *v5; // esi@1
2279 int v6; // ecx@1
2280 unsigned __int8 v7; // zf@4
2281 unsigned __int8 v8; // sf@4
2282 unsigned __int16 **v9; // edi@5
2283 FILE *v10; // eax@7
2284 FILE *v11; // ebx@7
2285 signed int v12; // ebx@8
2286 int v13; // eax@9
2287 int v14; // edx@9
2288 int v16; // [sp+4Ch] [bp-8h]@4
2289 FILE *File; // [sp+50h] [bp-4h]@7
2290
2291 v4 = uTargetGBits;
2292 v5 = this;
2293 v6 = uTargetBBits;
2294 if ( v5->uTextureRedBits != uTargetRBits
2295 || v5->uTextureGreenBits != uTargetGBits
2296 || v5->uTextureBlueBits != uTargetBBits )
2297 {
2298 v16 = 0;
2299 v7 = v5->uNumLoadedFiles == 0;
2300 v8 = (v5->uNumLoadedFiles & 0x80000000u) != 0;
2301 v5->uTextureRedBits = uTargetRBits;
2302 v5->uTextureGreenBits = v4;
2303 v5->uTextureBlueBits = v6;
2304 if ( !(v8 | v7) )
2305 {
2306 v9 = &v5->pTextures[0].pPalette16;
2307 do
2308 {
2309 Texture DstBuf; // [sp+4h] [bp-50h]@6
2310 //Texture::Texture(&DstBuf);
2311
2312 if ( *v9 )
2313 {
2314 v10 = FindContainer((const char *)v9 - 64, 0);
2315 v11 = v10;
2316 File = v10;
2317 if ( v10 )
2318 {
2319 fread(&DstBuf, 1u, 0x30u, v10);
2320 fseek(v11, DstBuf.uTextureSize, 1);
2321 v12 = 0;
2322 do
2323 {
2324 fread((char *)&uTargetRBits + 3, 1u, 1u, File);
2325 fread((char *)&uTargetBBits + 3, 1u, 1u, File);
2326 v13 = fread((char *)&uTargetGBits + 3, 1u, 1u, File);
2327 LOWORD(v13) = (unsigned __int8)(BYTE3(uTargetRBits) >> (8 - LOBYTE(v5->uTextureRedBits)));
2328 (*v9)[v12] = v13 << (LOBYTE(v5->uTextureGreenBits) + LOBYTE(v5->uTextureBlueBits));
2329 LOWORD(v14) = (unsigned __int8)(BYTE3(uTargetBBits) >> (8 - LOBYTE(v5->uTextureGreenBits)));
2330 (*v9)[v12] |= v14 << v5->uTextureBlueBits;
2331 (*v9)[v12] |= BYTE3(uTargetGBits) >> (8 - LOBYTE(v5->uTextureBlueBits));
2332 ++v12;
2333 }
2334 while ( v12 < 256 );
2335 }
2336 }
2337 ++v16;
2338 v9 += 18;
2339 }
2340 while ( v16 < (signed int)v5->uNumLoadedFiles );
2341 }
2342 }
2343 }
2344
2345
2346
2347 //----- (0041088B) --------------------------------------------------------
2348 void *LOD::File::LoadRaw(const char *pContainer, int a3)
2349 {
2350 LOD::File *v3; // esi@1
2351 FILE *v4; // eax@1
2352 FILE *v5; // esi@1
2353 void *v6; // eax@5
2354 void *v7; // ebx@7
2355 void *v8; // edi@7
2356 void *v9; // eax@9
2357 Texture DstBuf; // [sp+Ch] [bp-4Ch]@1
2358 FILE *File; // [sp+54h] [bp-4h]@1
2359 unsigned int Argsa; // [sp+60h] [bp+8h]@3
2360
2361 v3 = this;
2362 v4 = FindContainer(pContainer, 0);
2363 v5 = v4;
2364 File = v4;
2365 if ( !v4 )
2366 Abortf("Unable to load %s", pContainer);
2367 fread(&DstBuf, 1u, 0x30u, v4);
2368 Argsa = DstBuf.uTextureSize;
2369 if ( DstBuf.uDecompressedSize )
2370 {
2371 if ( a3 )
2372 v6 = malloc(DstBuf.uDecompressedSize);
2373 else
2374 v6 = pAllocator->AllocNamedChunk(0, DstBuf.uDecompressedSize, DstBuf.pName);
2375 v7 = v6;
2376 v8 = pAllocator->AllocNamedChunk(0, DstBuf.uTextureSize, DstBuf.pName);
2377 fread(v8, 1u, Argsa, File);
2378 zlib::MemUnzip(v7, &DstBuf.uDecompressedSize, v8, DstBuf.uTextureSize);
2379 DstBuf.uTextureSize = DstBuf.uDecompressedSize;
2380 pAllocator->FreeChunk(v8);
2381 }
2382 else
2383 {
2384 if ( a3 )
2385 v9 = malloc(DstBuf.uTextureSize);
2386 else
2387 v9 = pAllocator->AllocNamedChunk(0, DstBuf.uTextureSize, DstBuf.pName);
2388 v7 = v9;
2389 fread(v9, 1u, Argsa, v5);
2390 }
2391 return v7;
2392 }
2393
2394
2395
2396 //----- (00410522) --------------------------------------------------------
2397 int LODFile_IconsBitmaps::_410522(Texture *pDst, const char *pContainer, unsigned int uTextureType)
2398 {
2399 LODFile_IconsBitmaps *v4; // edi@1
2400 Texture *v5; // esi@5
2401 unsigned int v6; // eax@5
2402 void *v7; // eax@6
2403 unsigned int v8; // ST28_4@6
2404 void *v9; // ST2C_4@6
2405 unsigned __int8 *v10; // eax@7
2406 FILE *v11; // ST28_4@7
2407 void *v12; // eax@9
2408 FILE *v13; // ST28_4@9
2409 signed int v14; // eax@12
2410 int v15; // ecx@12
2411 int v16; // ecx@12
2412 int v17; // eax@12
2413 signed int v18; // ebx@14
2414 int v19; // eax@15
2415 int v20; // edx@15
2416 signed int v21; // ecx@18
2417 signed int v22; // ecx@23
2418 char Args[100]; // [sp+4h] [bp-68h]@3
2419 FILE *File; // [sp+68h] [bp-4h]@1
2420
2421 v4 = this;
2422 File = FindContainer(pContainer, 0);
2423 if ( !File )
2424 {
2425 File = FindContainer("pending", 0);
2426 if ( !File )
2427 {
2428 sprintfex(Args, "Can't find %s!", pContainer);
2429 Abortf(Args);
2430 }
2431 }
2432 v5 = pDst;
2433 fread(pDst, 1u, 0x30u, File);
2434 strcpy(v5->pName, pContainer);
2435 pDst = (Texture *)v5->uTextureSize;
2436 v6 = v5->uDecompressedSize;
2437 v5->pLevelOfDetail0 = 0;
2438 if ( v6 )
2439 {
2440 v7 = operator new(v6);
2441 v8 = v5->uTextureSize;
2442 v5->pLevelOfDetail0 = (unsigned __int8 *)v7;
2443 pContainer = (const char *)operator new(v8);
2444 fread((void *)pContainer, 1u, (size_t)pDst, File);
2445 zlib::MemUnzip(v5->pLevelOfDetail0, &v5->uDecompressedSize, pContainer, v5->uTextureSize);
2446 v9 = (void *)pContainer;
2447 v5->uTextureSize = v5->uDecompressedSize;
2448 free(v9);
2449 }
2450 else
2451 {
2452 v10 = (unsigned __int8 *)operator new(0);
2453 v11 = File;
2454 v5->pLevelOfDetail0 = v10;
2455 fread(v10, 1u, (size_t)pDst, v11);
2456 }
2457 v5->pPalette24 = 0;
2458 if ( uTextureType == 1 )
2459 {
2460 v12 = operator new(0x300u);
2461 v13 = File;
2462 v5->pPalette24 = (unsigned __int8 *)v12;
2463 fread(v12, 1u, 0x300u, v13);
2464 LABEL_10:
2465 v5->pPalette16 = 0;
2466 goto LABEL_11;
2467 }
2468 if ( uTextureType != 2 )
2469 goto LABEL_10;
2470 v18 = 0;
2471 v5->pPalette16 = 0;
2472 v5->pPalette16 = (unsigned __int16 *)operator new(0x400u);
2473 do
2474 {
2475 fread((char *)&pContainer + 3, 1u, 1u, File);
2476 fread((char *)&uTextureType + 3, 1u, 1u, File);
2477 v19 = fread((char *)&pDst + 3, 1u, 1u, File);
2478 LOWORD(v19) = (unsigned __int8)(BYTE3(pContainer) >> (8 - LOBYTE(v4->uTextureRedBits)));
2479 v5->pPalette16[v18] = v19 << (LOBYTE(v4->uTextureBlueBits) + LOBYTE(v4->uTextureGreenBits));
2480 LOWORD(v20) = (unsigned __int8)(BYTE3(uTextureType) >> (8 - LOBYTE(v4->uTextureGreenBits)));
2481 v5->pPalette16[v18] += v20 << v4->uTextureBlueBits;
2482 v5->pPalette16[v18] += (unsigned __int8)(BYTE3(pDst) >> (8 - LOBYTE(v4->uTextureBlueBits)));
2483 ++v18;
2484 }
2485 while ( v18 < 256 );
2486 LABEL_11:
2487 if ( v5->pBits & 2 )
2488 {
2489 v14 = v5->uSizeOfMaxLevelOfDetail;
2490 v15 = (int)&v5->pLevelOfDetail0[v14];
2491 v5->pLevelOfDetail1 = (unsigned __int8 *)v15;
2492 v16 = (v14 >> 2) + v15;
2493 v5->pLevelOfDetail2 = (unsigned __int8 *)v16;
2494 v17 = v16 + (v14 >> 4);
2495 }
2496 else
2497 {
2498 v17 = 0;
2499 v5->pLevelOfDetail2 = 0;
2500 v5->pLevelOfDetail1 = 0;
2501 }
2502 v5->pLevelOfDetail3 = (unsigned __int8 *)v17;
2503 v21 = 1;
2504 while ( 1 << v21 != v5->uTextureWidth )
2505 {
2506 ++v21;
2507 if ( v21 >= 15 )
2508 goto LABEL_23;
2509 }
2510 v5->uWidthLn2 = v21;
2511 LABEL_23:
2512 v22 = 1;
2513 while ( 1 << v22 != v5->uTextureHeight )
2514 {
2515 ++v22;
2516 if ( v22 >= 15 )
2517 goto LABEL_28;
2518 }
2519 v5->uHeightLn2 = v22;
2520 LABEL_28:
2521 switch ( v5->uWidthLn2 )
2522 {
2523 case 2:
2524 v5->uWidthMinus1 = 3;
2525 break;
2526 case 3:
2527 v5->uWidthMinus1 = 7;
2528 break;
2529 case 4:
2530 v5->uWidthMinus1 = 15;
2531 break;
2532 case 5:
2533 v5->uWidthMinus1 = 31;
2534 break;
2535 case 6:
2536 v5->uWidthMinus1 = 63;
2537 break;
2538 case 7:
2539 v5->uWidthMinus1 = 127;
2540 break;
2541 case 8:
2542 v5->uWidthMinus1 = 255;
2543 break;
2544 case 9:
2545 v5->uWidthMinus1 = 511;
2546 break;
2547 case 10:
2548 v5->uWidthMinus1 = 1023;
2549 break;
2550 case 11:
2551 v5->uWidthMinus1 = 2047;
2552 break;
2553 case 12:
2554 v5->uWidthMinus1 = 4095;
2555 break;
2556 default:
2557 break;
2558 }
2559 switch ( v5->uHeightLn2 )
2560 {
2561 case 2:
2562 v5->uHeightMinus1 = 3;
2563 break;
2564 case 3:
2565 v5->uHeightMinus1 = 7;
2566 break;
2567 case 4:
2568 v5->uHeightMinus1 = 15;
2569 break;
2570 case 5:
2571 v5->uHeightMinus1 = 31;
2572 break;
2573 case 6:
2574 v5->uHeightMinus1 = 63;
2575 break;
2576 case 7:
2577 v5->uHeightMinus1 = 127;
2578 break;
2579 case 8:
2580 v5->uHeightMinus1 = 255;
2581 break;
2582 case 9:
2583 v5->uHeightMinus1 = 511;
2584 break;
2585 case 10:
2586 v5->uHeightMinus1 = 1023;
2587 break;
2588 case 11:
2589 v5->uHeightMinus1 = 2047;
2590 break;
2591 case 12:
2592 v5->uHeightMinus1 = 4095;
2593 break;
2594 default:
2595 return 1;
2596 }
2597 return 1;
2598 }
2599
2600
2601 //----- (00410423) --------------------------------------------------------
2602 void LODFile_IconsBitmaps::_410423_move_textures_to_device()
2603 {
2604 LODFile_IconsBitmaps *v1; // esi@1
2605 unsigned int v2; // edi@1
2606 char *v3; // ebx@2
2607 size_t v4; // eax@9
2608 char *v5; // ST1C_4@9
2609 void *v6; // eax@12
2610 signed int v7; // esi@13
2611
2612 v1 = this;
2613 v2 = this->uNumLoadedFiles - 1;
2614 if ( (v2 & 0x80000000u) == 0 )
2615 {
2616 v3 = &this->pTextures[v2].pName[2];
2617 do
2618 {
2619 if ( v1->ptr_011BB4[v2] )
2620 {
2621 if ( *(v3 - 2) != 'w' || *(v3 - 1) != 't' || *v3 != 'r' || v3[1] != 'd' || v3[2] != 'r' )
2622 {
2623 pRenderer->LoadTexture(
2624 v3 - 2,
2625 *((short *)v3 + 17),
2626 &v1->pHardwareSurfaces[v2],
2627 &v1->pHardwareTextures[v2]);
2628 }
2629 else
2630 {
2631 v4 = strlen(v3 - 2);
2632 v5 = (char *)operator new(v4 + 2);
2633 *v5 = 'h';
2634 strcpy(v5 + 1, v3 - 2);
2635 pRenderer->LoadTexture(
2636 v5,
2637 *((short *)v3 + 17),
2638 &v1->pHardwareSurfaces[v2],
2639 &v1->pHardwareTextures[v2]);
2640 free(v5);
2641 }
2642 }
2643 --v2;
2644 v3 -= 72;
2645 }
2646 while ( (v2 & 0x80000000u) == 0 );
2647 }
2648 v6 = v1->ptr_011BB4;
2649 if ( v6 )
2650 {
2651 v7 = v1->uNumLoadedFiles;
2652 if ( v7 > 1 )
2653 memset(v6, 0, v7 - 1);
2654 }
2655 }
2656
2657
2658 //----- (004103BB) --------------------------------------------------------
2659 void LODFile_IconsBitmaps::ReleaseHardwareTextures()
2660 {
2661 LODFile_IconsBitmaps *v1; // esi@1
2662 unsigned int v2; // edi@1
2663 struct IDirect3DTexture2 **v3; // eax@2
2664 struct IDirect3DTexture2 *v4; // eax@3
2665 struct IDirectDrawSurface **v5; // eax@5
2666 struct IDirectDrawSurface *v6; // eax@6
2667
2668 v1 = this;
2669 v2 = this->uNumLoadedFiles;
2670 while ( 1 )
2671 {
2672 --v2;
2673 if ( (v2 & 0x80000000u) != 0 )
2674 break;
2675 v3 = v1->pHardwareTextures;
2676 if ( v3 )
2677 {
2678 v4 = v3[v2];
2679 if ( v4 )
2680 {
2681 v4->Release();
2682 v1->pHardwareTextures[v2] = 0;
2683 v1->ptr_011BB4[v2] = 1;
2684 }
2685 }
2686 v5 = v1->pHardwareSurfaces;
2687 if ( v5 )
2688 {
2689 v6 = v5[v2];
2690 if ( v6 )
2691 {
2692 v6->Release();
2693 v1->pHardwareSurfaces[v2] = 0;
2694 v1->ptr_011BB4[v2] = 1;
2695 }
2696 }
2697 }
2698 }
2699
2700
2701 //----- (0041033D) --------------------------------------------------------
2702 void LODFile_IconsBitmaps::ReleaseLostHardwareTextures()
2703 {
2704 LODFile_IconsBitmaps *v1; // edi@1
2705 unsigned int i; // ebx@1
2706 struct IDirectDrawSurface **pHardwareSurfaces; // eax@2
2707 int v4; // esi@3
2708 struct IDirectDrawSurface *pSurface; // eax@3
2709 struct IDirect3DTexture2 **v6; // eax@5
2710 struct IDirect3DTexture2 *v7; // eax@6
2711
2712 v1 = this;
2713 for ( i = this->uNumLoadedFiles - 1; (i & 0x80000000u) == 0; --i )
2714 {
2715 pHardwareSurfaces = v1->pHardwareSurfaces;
2716 if ( pHardwareSurfaces )
2717 {
2718 v4 = i;
2719 pSurface = pHardwareSurfaces[i];
2720 if ( pSurface )
2721 {
2722 if ( pSurface->IsLost() == DDERR_SURFACELOST )
2723 {
2724 v6 = v1->pHardwareTextures;
2725 if ( v6 )
2726 {
2727 v7 = v6[v4];
2728 if ( v7 )
2729 {
2730 v7->Release();
2731 v1->pHardwareTextures[v4] = 0;
2732 }
2733 }
2734 v1->pHardwareSurfaces[v4]->Release();
2735 v1->pHardwareSurfaces[v4] = 0;
2736 v1->ptr_011BB4[i] = 1;
2737 }
2738 }
2739 }
2740 }
2741 }
2742
2743 //----- (004101B1) --------------------------------------------------------
2744 int LODFile_IconsBitmaps::ReloadTexture(Texture *pDst, const char *pContainer, int mode)
2745 {
2746 LODFile_IconsBitmaps *v4; // edi@1
2747 FILE *v5; // eax@1
2748 Texture *v6; // esi@2
2749 unsigned int v7; // ebx@6
2750 unsigned int v8; // ecx@6
2751 signed int result; // eax@7
2752 size_t *v10; // ebx@8
2753 signed int v11; // ebx@12
2754 int v12; // eax@13
2755 int v13; // edx@13
2756 FILE *File; // [sp+Ch] [bp-8h]@1
2757 unsigned __int8 v15; // [sp+11h] [bp-3h]@13
2758 unsigned __int8 v16; // [sp+12h] [bp-2h]@13
2759 unsigned __int8 DstBuf; // [sp+13h] [bp-1h]@13
2760 void *DstBufa; // [sp+1Ch] [bp+8h]@10
2761 void *Sourcea; // [sp+20h] [bp+Ch]@10
2762 unsigned int Counta; // [sp+24h] [bp+10h]@6
2763
2764 v4 = this;
2765 v5 = FindContainer(pContainer, 0);
2766 File = v5;
2767 if ( v5
2768 && (v6 = pDst, pDst->pLevelOfDetail0)
2769 && mode == 2
2770 && pDst->pPalette16
2771 && !pDst->pPalette24
2772 && (v7 = pDst->uTextureSize,
2773 fread(pDst, 1u, 0x30u, v5),
2774 strcpy(pDst->pName, pContainer),
2775 v8 = pDst->uTextureSize,
2776 Counta = pDst->uTextureSize,
2777 (signed int)v8 <= (signed int)v7) )
2778 {
2779 v10 = &pDst->uDecompressedSize;
2780 if ( !pDst->uDecompressedSize || v4->dword_011BA4 )
2781 {
2782 fread(pDst->pLevelOfDetail0, 1u, v8, File);
2783 }
2784 else
2785 {
2786 Sourcea = malloc(pDst->uDecompressedSize);
2787 DstBufa = malloc(pDst->uTextureSize);
2788 fread(DstBufa, 1u, Counta, File);
2789 zlib::MemUnzip(Sourcea, &v6->uDecompressedSize, DstBufa, v6->uTextureSize);
2790 v6->uTextureSize = *v10;
2791 free(DstBufa);
2792 memcpy(v6->pLevelOfDetail0, Sourcea, *v10);
2793 free(Sourcea);
2794 }
2795 v11 = 0;
2796 do
2797 {
2798 fread(&DstBuf, 1u, 1u, File);
2799 fread(&v16, 1u, 1u, File);
2800 v12 = fread(&v15, 1u, 1u, File);
2801 LOWORD(v12) = (unsigned __int8)(DstBuf >> (8 - LOBYTE(v4->uTextureRedBits)));
2802 v6->pPalette16[v11] = v12 << (LOBYTE(v4->uTextureBlueBits) + LOBYTE(v4->uTextureGreenBits));
2803 LOWORD(v13) = (unsigned __int8)(v16 >> (8 - LOBYTE(v4->uTextureGreenBits)));
2804 v6->pPalette16[v11] += v13 << v4->uTextureBlueBits;
2805 v6->pPalette16[v11] += (unsigned __int8)(v15 >> (8 - LOBYTE(v4->uTextureBlueBits)));
2806 ++v11;
2807 }
2808 while ( v11 < 256 );
2809 result = 1;
2810 }
2811 else
2812 {
2813 result = -1;
2814 }
2815 return result;
2816 }
2817
2818
2819 //----- (0040FC08) --------------------------------------------------------
2820 int LODFile_IconsBitmaps::LoadTextureFromLOD(Texture *pOutTex, const char *pContainer, enum TEXTURE_TYPE eTextureType)
2821 {
2822 const char *v4; // ebx@1
2823 LODFile_IconsBitmaps *v5; // edi@1
2824 FILE *v6; // eax@1
2825 Texture *v8; // esi@3
2826 char *v9; // eax@8
2827 void *v10; // ST24_4@8
2828 size_t v11; // eax@14
2829 enum TEXTURE_TYPE v12; // eax@14
2830 signed int v13; // esi@14
2831 unsigned int v14; // eax@21
2832 unsigned int v15; // ecx@25
2833 unsigned int *v16; // ebx@25
2834 void *v17; // eax@27
2835 unsigned int v18; // ST28_4@27
2836 void *v19; // ST3C_4@27
2837 Allocator *v20; // ebx@29
2838 void *v21; // eax@29
2839 size_t v22; // ST2C_4@29
2840 const void *v23; // ecx@29
2841 unsigned __int16 v24; // ax@29
2842 unsigned __int16 v25; // cx@29
2843 __int16 v26; // dx@29
2844 unsigned int v27; // ecx@29
2845 Texture *v28; // eax@29
2846 unsigned int v29; // ST28_4@30
2847 void *v30; // eax@30
2848 unsigned int v31; // ST2C_4@30
2849 void *v32; // eax@32
2850 void *v33; // eax@34
2851 signed int v34; // eax@37
2852 unsigned __int8 *v35; // ecx@37
2853 unsigned __int8 *v36; // ecx@37
2854 unsigned __int8 *v37; // eax@37
2855 signed int v38; // ebx@39
2856 int v39; // eax@40
2857 int v40; // edx@40
2858 signed int v41; // ecx@43
2859 signed int v42; // ecx@48
2860 FILE *File; // [sp+14h] [bp-4h]@1
2861
2862 v4 = pContainer;
2863 v5 = this;
2864 v6 = FindContainer(pContainer, 0);
2865 File = v6;
2866 if ( !v6 )
2867 return -1;
2868 v8 = pOutTex;
2869 fread(pOutTex, 1u, 0x30u, v6);
2870 strcpy(v8->pName, v4);
2871 if ( pRenderer->pRenderD3D && v8->pBits & 2 && v5->dword_011BA8 )
2872 {
2873 if ( !v5->pHardwareSurfaces || !v5->pHardwareTextures )
2874 {
2875 v5->pHardwareSurfaces = (struct IDirectDrawSurface **)operator new(0xFA0u);
2876 v5->pHardwareTextures = (struct IDirect3DTexture2 **)operator new(0xFA0u);
2877 v9 = (char *)operator new(0x3E8u);
2878 v10 = v5->pHardwareSurfaces;
2879 v5->ptr_011BB4 = v9;
2880 memset(v10, 0, 0xFA0u);
2881 memset(v5->pHardwareTextures, 0, 0xFA0u);
2882 memset(v5->ptr_011BB4, 0, 0x3E8u);
2883 }
2884 if ( *v4 != 'w' || v4[1] != 't' || v4[2] != 'r' || v4[3] != 'd' || v4[4] != 'r' )
2885 {
2886 if ( *v4 != 'W' || v4[1] != 't' || v4[2] != 'r' || v4[3] != 'T' || v4[4] != 'y' || v4[5] != 'l' )
2887 {
2888 v14 = v5->uNumLoadedFiles;
2889 }
2890 else
2891 {
2892 pRenderer->field_1036AC_bitmapid = v5->uNumLoadedFiles;
2893 v14 = v5->uNumLoadedFiles;
2894 }
2895 v13 = pRenderer->LoadTexture(
2896 v4,
2897 LOWORD(v8->palette),
2898 &v5->pHardwareSurfaces[v14],
2899 &v5->pHardwareTextures[v14]);
2900 }
2901 else
2902 {
2903 v11 = strlen(v4);
2904 v12 = (enum TEXTURE_TYPE)(int)operator new(v11 + 2);
2905 eTextureType = v12;
2906 *(char *)v12 = 104;
2907 strcpy((char *)(v12 + 1), v4);
2908 v13 = pRenderer->LoadTexture(
2909 (const char *)eTextureType,
2910 LOWORD(v8->palette),
2911 &v5->pHardwareSurfaces[v5->uNumLoadedFiles],
2912 &v5->pHardwareTextures[v5->uNumLoadedFiles]);
2913 free((void *)eTextureType);
2914 }
2915 return v13;
2916 }
2917 v15 = v8->uTextureSize;
2918 v16 = &v8->uDecompressedSize;
2919 pOutTex = (Texture *)v8->uTextureSize;
2920 if ( !v8->uDecompressedSize || v5->dword_011BA4 )
2921 {
2922 v20 = pAllocator;
2923 v32 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, v15, v8->pName);
2924 v8->pLevelOfDetail0 = (unsigned __int8 *)v32;
2925 fread(v32, 1u, (size_t)pOutTex, File);
2926 }
2927 else
2928 {
2929 v17 = malloc(v8->uDecompressedSize);
2930 v18 = v8->uTextureSize;
2931 pContainer = (const char *)v17;
2932 v19 = malloc(v18);
2933 fread(v19, 1u, (size_t)pOutTex, File);
2934 zlib::MemUnzip((void *)pContainer, &v8->uDecompressedSize, v19, v8->uTextureSize);
2935 v8->uTextureSize = *v16;
2936 free(v19);
2937 if ( bUseLoResSprites && v8->pBits & 2 )
2938 {
2939 v20 = pAllocator;
2940 pOutTex = (Texture *)(((signed int)v8->uSizeOfMaxLevelOfDetail >> 2)
2941 + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 4)
2942 + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 6));
2943 v21 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, (unsigned int)pOutTex, v8->pName);
2944 v22 = (size_t)pOutTex;
2945 v23 = &pContainer[v8->uTextureWidth * v8->uTextureHeight];
2946 v8->pLevelOfDetail0 = (unsigned __int8 *)v21;
2947 memcpy(v21, v23, v22);
2948 v8->uTextureWidth = (signed __int16)v8->uTextureWidth >> 1;
2949 v24 = v8->uTextureWidth;
2950 v8->uTextureHeight = (signed __int16)v8->uTextureHeight >> 1;
2951 v25 = v8->uTextureHeight;
2952 --v8->uWidthLn2;
2953 --v8->uHeightLn2;
2954 v8->uWidthMinus1 = v24 - 1;
2955 v26 = v25 - 1;
2956 v27 = (signed __int16)v24 * (signed __int16)v25;
2957 v28 = pOutTex;
2958 v8->uHeightMinus1 = v26;
2959 v8->uSizeOfMaxLevelOfDetail = v27;
2960 v8->uTextureSize = (unsigned int)v28;
2961 }
2962 else
2963 {
2964 v29 = *v16;
2965 v20 = pAllocator;
2966 v30 = pAllocator->AllocNamedChunk(v8->pLevelOfDetail0, v29, v8->pName);
2967 v31 = v8->uDecompressedSize;
2968 v8->pLevelOfDetail0 = (unsigned __int8 *)v30;
2969 memcpy(v30, pContainer, v31);
2970 }
2971 free((void *)pContainer);
2972 }
2973 pAllocator->FreeChunk(v8->pPalette16);
2974 pAllocator->FreeChunk(v8->pPalette24);
2975 if ( eTextureType == TEXTURE_24BIT_PALETTE )
2976 {
2977 v33 = pAllocator->AllocNamedChunk(v8->pPalette24, 0x300u, v8->pName);
2978 v8->pPalette24 = (unsigned __int8 *)v33;
2979 fread(v33, 1u, 0x300u, File);
2980 }
2981 else
2982 {
2983 v8->pPalette24 = 0;
2984 if ( eTextureType == TEXTURE_16BIT_PALETTE )
2985 {
2986 v8->pPalette16 = (unsigned __int16 *)pAllocator->AllocNamedChunk(v8->pPalette16, 0x200u, v8->pName);
2987 v38 = 0;
2988 do
2989 {
2990 fread((char *)&eTextureType + 3, 1u, 1u, File);
2991 fread((char *)&pContainer + 3, 1u, 1u, File);
2992 v39 = fread((char *)&pOutTex + 3, 1u, 1u, File);
2993 LOWORD(v39) = (unsigned __int8)(BYTE3(eTextureType) >> (8 - LOBYTE(v5->uTextureRedBits)));
2994 v8->pPalette16[v38] = v39 << (LOBYTE(v5->uTextureBlueBits) + LOBYTE(v5->uTextureGreenBits));
2995 LOWORD(v40) = (unsigned __int8)(BYTE3(pContainer) >> (8 - LOBYTE(v5->uTextureGreenBits)));
2996 v8->pPalette16[v38] += v40 << v5->uTextureBlueBits;
2997 v8->pPalette16[v38] += (unsigned __int8)(BYTE3(pOutTex) >> (8 - LOBYTE(v5->uTextureBlueBits)));
2998 ++v38;
2999 }
3000 while ( v38 < 256 );
3001 goto LABEL_36;
3002 }
3003 }
3004 v8->pPalette16 = 0;
3005 LABEL_36:
3006 if ( v8->pBits & 2 )
3007 {
3008 v34 = v8->uSizeOfMaxLevelOfDetail;
3009 v35 = &v8->pLevelOfDetail0[v34];
3010 v8->pLevelOfDetail1 = v35;
3011 v36 = &v35[v34 >> 2];
3012 v8->pLevelOfDetail2 = v36;
3013 v37 = &v36[v34 >> 4];
3014 }
3015 else
3016 {
3017 v37 = 0;
3018 v8->pLevelOfDetail2 = 0;
3019 v8->pLevelOfDetail1 = 0;
3020 }
3021 v8->pLevelOfDetail3 = v37;
3022 v41 = 1;
3023 while ( 1 << v41 != v8->uTextureWidth )
3024 {
3025 ++v41;
3026 if ( v41 >= 15 )
3027 goto LABEL_48;
3028 }
3029 v8->uWidthLn2 = v41;
3030 LABEL_48:
3031 v42 = 1;
3032 while ( 1 << v42 != v8->uTextureHeight )
3033 {
3034 ++v42;
3035 if ( v42 >= 15 )
3036 goto LABEL_53;
3037 }
3038 v8->uHeightLn2 = v42;
3039 LABEL_53:
3040 switch ( v8->uWidthLn2 )
3041 {
3042 case 2:
3043 v8->uWidthMinus1 = 3;
3044 break;
3045 case 3:
3046 v8->uWidthMinus1 = 7;
3047 break;
3048 case 4:
3049 v8->uWidthMinus1 = 15;
3050 break;
3051 case 5:
3052 v8->uWidthMinus1 = 31;
3053 break;
3054 case 6:
3055 v8->uWidthMinus1 = 63;
3056 break;
3057 case 7:
3058 v8->uWidthMinus1 = 127;
3059 break;
3060 case 8:
3061 v8->uWidthMinus1 = 255;
3062 break;
3063 case 9:
3064 v8->uWidthMinus1 = 511;
3065 break;
3066 case 10:
3067 v8->uWidthMinus1 = 1023;
3068 break;
3069 case 11:
3070 v8->uWidthMinus1 = 2047;
3071 break;
3072 case 12:
3073 v8->uWidthMinus1 = 4095;
3074 break;
3075 default:
3076 break;
3077 }
3078 switch ( v8->uHeightLn2 )
3079 {
3080 case 2:
3081 v8->uHeightMinus1 = 3;
3082 break;
3083 case 3:
3084 v8->uHeightMinus1 = 7;
3085 break;
3086 case 4:
3087 v8->uHeightMinus1 = 15;
3088 break;
3089 case 5:
3090 v8->uHeightMinus1 = 31;
3091 break;
3092 case 6:
3093 v8->uHeightMinus1 = 63;
3094 break;
3095 case 7:
3096 v8->uHeightMinus1 = 127;
3097 break;
3098 case 8:
3099 v8->uHeightMinus1 = 255;
3100 break;
3101 case 9:
3102 v8->uHeightMinus1 = 511;
3103 break;
3104 case 10:
3105 v8->uHeightMinus1 = 1023;
3106 break;
3107 case 11:
3108 v8->uHeightMinus1 = 2047;
3109 break;
3110 case 12:
3111 v8->uHeightMinus1 = 4095;
3112 break;
3113 default:
3114 return 1;
3115 }
3116 return 1;
3117 }
3118
3119
3120 //----- (0040FB20) --------------------------------------------------------
3121 unsigned int LODFile_IconsBitmaps::LoadTexture(const char *pContainer, enum TEXTURE_TYPE uTextureType)
3122 {
3123 LODFile_IconsBitmaps *v3; // esi@1
3124 unsigned int v4; // edi@1
3125 Texture *v5; // ebx@2
3126 unsigned int v6; // ebx@8
3127 const char *Sourcea; // [sp+14h] [bp+8h]@9
3128
3129 v3 = this;
3130 v4 = 0;
3131 areWeLoadingTexture = 1;
3132 if ( (signed int)this->uNumLoadedFiles <= 0 )
3133 {
3134 LABEL_5:
3135 if ( (signed int)v3->uNumLoadedFiles >= 1000 )
3136 AbortWithError();
3137 if ( v3->LoadTextureFromLOD(&v3->pTextures[v3->uNumLoadedFiles], pContainer, uTextureType) == -1 )
3138 {
3139 v6 = 0;
3140 if ( (signed int)v3->uNumLoadedFiles > 0 )
3141 {
3142 Sourcea = (const char *)v3->pTextures;
3143 while ( _strcmpi(Sourcea, "pending") )
3144 {
3145 Sourcea += 72;
3146 ++v6;
3147 if ( (signed int)v6 >= (signed int)v3->uNumLoadedFiles )
3148 goto LABEL_15;
3149 }
3150 return v6;
3151 }
3152 LABEL_15:
3153 v3->LoadTextureFromLOD(&v3->pTextures[v3->uNumLoadedFiles], "pending", uTextureType);
3154 }
3155 areWeLoadingTexture = 0;
3156 ++v3->uNumLoadedFiles;
3157 return v3->uNumLoadedFiles - 1;
3158 }
3159 v5 = this->pTextures;
3160 while ( _strcmpi(v5->pName, pContainer) )
3161 {
3162 ++v4;
3163 ++v5;
3164 if ( (signed int)v4 >= (signed int)v3->uNumLoadedFiles )
3165 goto LABEL_5;
3166 }
3167 return v4;
3168 }
3169 // 506128: using guessed type int areWeLoadingTexture;