comparison Engine/LOD.cpp @ 2499:68cdef6879a0

engine folder
author Ritor1
date Fri, 19 Sep 2014 02:57:42 +0600
parents
children fb1c61a82a55
comparison
equal deleted inserted replaced
2498:92eeeb5200f2 2499:68cdef6879a0
1 #define _CRTDBG_MAP_ALLOC
2 #include <stdlib.h>
3 #include <crtdbg.h>
4
5 #define _CRT_SECURE_NO_WARNINGS
6 #include "Engine/ErrorHandling.h"
7 #include "LOD.h"
8 #include "Engine/Graphics/Render.h"
9 #include "Engine/Graphics/Viewport.h"
10 #include "mm7_data.h"
11 #include "ZlibWrapper.h"
12
13 #include "Engine/Graphics/Sprites.h"
14
15
16
17
18
19
20 LODFile_IconsBitmaps *pEvents_LOD = nullptr;
21
22 LODFile_IconsBitmaps *pIcons_LOD = nullptr;
23 LODFile_IconsBitmaps *pIcons_LOD_mm6 = nullptr;
24 LODFile_IconsBitmaps *pIcons_LOD_mm8 = nullptr;
25
26 LODFile_IconsBitmaps *pBitmaps_LOD = nullptr;
27 LODFile_IconsBitmaps *pBitmaps_LOD_mm6 = nullptr;
28 LODFile_IconsBitmaps *pBitmaps_LOD_mm8 = nullptr;
29
30 LODFile_Sprites *pSprites_LOD = nullptr;
31 LODFile_Sprites *pSprites_LOD_mm6 = nullptr;
32 LODFile_Sprites *pSprites_LOD_mm8 = nullptr;
33
34 LODWriteableFile *pNew_LOD = nullptr;
35 LODWriteableFile *pGames_LOD = nullptr;
36
37
38
39
40 int _6A0CA4_lod_binary_search; // weak
41 int _6A0CA8_lod_unused; // weak
42
43
44 // inlined
45 //----- (mm6c::00408860) --------------------------------------------------
46 void LODFile_IconsBitmaps::_inlined_sub2()
47 {
48 ++uTexturePacksCount;
49 if (!uNumPrevLoadedFiles)
50 uNumPrevLoadedFiles = uNumLoadedFiles;
51 }
52
53 // inlined
54 //----- (mm6c::0045BE60) --------------------------------------------------
55 void LODFile_IconsBitmaps::_inlined_sub1()
56 {
57 dword_11B84 = uNumLoadedFiles;
58 }
59
60 // inlined
61 //----- (mm6c::0045C310) --------------------------------------------------
62 void LODFile_Sprites::_inlined_sub1()
63 {
64 field_ECA0 = uNumLoadedSprites;
65 }
66
67 // inlined
68 //----- (mm6c::0045C5B0) --------------------------------------------------
69 void LODFile_IconsBitmaps::_inlined_sub0()
70 {
71 dword_11B80 = uNumLoadedFiles;
72 if (dword_11B84 < uNumLoadedFiles)
73 dword_11B84 = uNumLoadedFiles;
74 }
75
76
77 // inlined
78 //----- (mm6c::0045C660) --------------------------------------------------
79 void LODFile_Sprites::_inlined_sub0()
80 {
81 field_ECA4 = uNumLoadedSprites;
82 if (field_ECA0 < uNumLoadedSprites)
83 field_ECA0 = uNumLoadedSprites;
84 }
85
86 //----- (004355F7) --------------------------------------------------------
87 void LODFile_IconsBitmaps::RemoveTexturesFromTextureList()
88 {
89 if ( this->uTexturePacksCount )
90 {
91 if ( (this->uNumLoadedFiles - 1) >= this->uNumPrevLoadedFiles )
92 {
93 for ( uint i = this->uNumLoadedFiles - 1; i >= this->uNumPrevLoadedFiles; --i )
94 {
95 this->pTextures[i].Release();
96 if ( this->pHardwareTextures )
97 {
98 if ( this->pHardwareTextures[i] )
99 {
100 this->pHardwareTextures[i]->Release();
101 this->pHardwareTextures[i] = 0;
102 }
103 }
104 if ( this->pHardwareSurfaces )
105 {
106 if ( this->pHardwareSurfaces[i] )
107 {
108 this->pHardwareSurfaces[i]->Release();
109 this->pHardwareSurfaces[i] = 0;
110 }
111 }
112 }
113 }
114 this->uNumLoadedFiles = this->uNumPrevLoadedFiles;
115 this->uNumPrevLoadedFiles = 0;
116 this->uTexturePacksCount = 0;
117 }
118 }
119
120 //----- (004114F2) --------------------------------------------------------
121 void LODFile_IconsBitmaps::RemoveTexturesPackFromTextureList()
122 {
123 if ( this->uTexturePacksCount )
124 {
125 this->uTexturePacksCount--;
126 if ( !this->uTexturePacksCount )
127 {
128 if ( (this->uNumLoadedFiles - 1) >= this->uNumPrevLoadedFiles )
129 {
130 for ( uint i = this->uNumLoadedFiles - 1; i >= this->uNumPrevLoadedFiles; --i )
131 {
132 this->pTextures[i].Release();
133 if ( this->pHardwareTextures )
134 {
135 if ( this->pHardwareTextures[i] )
136 {
137 this->pHardwareTextures[i]->Release();
138 this->pHardwareTextures[i] = 0;
139 }
140 }
141 if ( this->pHardwareSurfaces )
142 {
143 if ( this->pHardwareSurfaces[i] )
144 {
145 this->pHardwareSurfaces[i]->Release();
146 this->pHardwareSurfaces[i] = 0;
147 }
148 }
149 }
150 }
151 this->uNumLoadedFiles = this->uNumPrevLoadedFiles;
152 this->uNumPrevLoadedFiles = 0;
153 }
154 }
155 }
156
157 //----- (004AC67E) --------------------------------------------------------
158 int LODFile_Sprites::LoadSpriteFromFile(LODSprite *pSpriteHeader, const char *pContainer)
159 {
160 FILE *File; // [sp+4h] [bp-4h]@1
161 void *DstBufa; // [sp+10h] [bp+8h]@4
162 int Sizea; // [sp+14h] [bp+Ch]@3
163
164 File = FindContainer(pContainer, 0);
165 if ( File )
166 {
167 fread(pSpriteHeader, 1, 0x20u, File);
168 strcpy(pSpriteHeader->pName, pContainer);
169 Sizea = pSpriteHeader->uSpriteSize;
170 pSpriteHeader->pSpriteLines = (LODSprite_stru0 *)malloc(8 * pSpriteHeader->uHeight);
171 fread(pSpriteHeader->pSpriteLines, 1, 8 * pSpriteHeader->uHeight, File);
172
173 if ( pSpriteHeader->uDecompressedSize )
174 {
175 pSpriteHeader->pDecompressedBytes = malloc(pSpriteHeader->uDecompressedSize);
176 DstBufa = malloc(Sizea);
177 fread(DstBufa, 1, Sizea, File);
178 zlib::MemUnzip(pSpriteHeader->pDecompressedBytes, (unsigned int *)&pSpriteHeader->uDecompressedSize, DstBufa, pSpriteHeader->uSpriteSize);
179 pSpriteHeader->uSpriteSize = pSpriteHeader->uDecompressedSize;
180 free(DstBufa);
181 }
182 else
183 {
184 pSpriteHeader->pDecompressedBytes = malloc(Sizea);
185 fread(pSpriteHeader->pDecompressedBytes, 1, Sizea, File);
186 }
187 for ( uint i = 0; i < pSpriteHeader->uHeight; i++ )
188 pSpriteHeader->pSpriteLines[i].pos += (unsigned int)pSpriteHeader->pDecompressedBytes;
189 return 1;
190 }
191 else
192 return -1;
193 }
194
195 //----- (004AC795) --------------------------------------------------------
196 bool LODFile_Sprites::LoadSprites(const char *pFilename)
197 {
198 if (LoadHeader(pFilename, 1))
199 return false;
200 else
201 return LoadSubIndices("sprites08") == 0;
202 }
203
204 //----- (004AC7C0) --------------------------------------------------------
205 int LODFile_Sprites::LoadSprite(const char *pContainerName, unsigned int uPaletteID)
206 {
207
208 FILE *sprite_file; // eax@12
209 LODSprite temp_sprite_hdr; // [sp+Ch] [bp-3Ch]@12
210 int i;//, sprite_indx;
211
212 //find if already loaded
213 //if ( pRenderer->pRenderD3D )
214 {
215 for (i=0; i<uNumLoadedSprites;++i)
216 {
217 if (!(_stricmp(pHardwareSprites[i].pName, pContainerName)))
218 return i;
219 }
220 }
221 /*else
222 {
223 for (i=0; i<uNumLoadedSprites;++i)
224 {
225 if (!(_stricmp(pSpriteHeaders[i].pName, pContainerName)))
226 return i;
227 }
228 }*/
229
230 if (uNumLoadedSprites >= 1500 )
231 return -1;
232 //if not loaded - load from file
233
234 //if ( pRenderer->pRenderD3D && can_load_hardware_sprites )
235 {
236 if ( !pHardwareSprites )
237 {
238 pHardwareSprites = (Sprite *)malloc(1500*sizeof(Sprite));//0xEA60u
239 for (i=0; i<1500;++i)
240 {
241 pHardwareSprites[i].pName=nullptr;
242 pHardwareSprites[i].pTextureSurface=nullptr;
243 pHardwareSprites[i].pTexture=nullptr;
244 }
245 }
246 temp_sprite_hdr.uHeight = 0;
247 temp_sprite_hdr.uPaletteId = 0;
248 temp_sprite_hdr.word_1A = 0;
249 temp_sprite_hdr.pSpriteLines = nullptr;
250 temp_sprite_hdr.pDecompressedBytes = nullptr;
251 sprite_file = FindContainer(pContainerName, 0);
252 if ( !sprite_file )
253 return -1;
254 //fread(&temp_sprite_hdr, 1, sizeof(LODSprite), sprite_file);
255 fread(&temp_sprite_hdr, 1, 0x20, sprite_file);
256 pHardwareSprites[uNumLoadedSprites].uBufferWidth = temp_sprite_hdr.uWidth;
257 pHardwareSprites[uNumLoadedSprites].uBufferHeight = temp_sprite_hdr.uHeight;
258 pSpriteHeaders[uNumLoadedSprites].uWidth = temp_sprite_hdr.uWidth;
259 pSpriteHeaders[uNumLoadedSprites].uHeight = temp_sprite_hdr.uHeight;
260 LoadSpriteFromFile( &pSpriteHeaders[uNumLoadedSprites], pContainerName); //this line is not present here in the original. necessary for Grayface's mouse picking fix
261 }
262 /*else
263 {
264 sprite_indx = LoadSpriteFromFile( &pSpriteHeaders[uNumLoadedSprites], pContainerName);
265 pSpriteHeaders[uNumLoadedSprites].word_1A = 0;
266
267 if ( sprite_indx != -1 )
268 {
269 pSpriteHeaders[uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(pSpriteHeaders[uNumLoadedSprites].uPaletteId);
270 }
271 else
272 {
273 if ( uNumLoadedSprites<=0 )
274 uNumLoadedSprites=0;
275 else
276 {
277 for (i=0; i<uNumLoadedSprites;++i)
278 {
279 if (!(_stricmp(pSpriteHeaders[i].pName, "pending")))
280 return i;
281 }
282 }
283 if ( LoadSpriteFromFile(&pSpriteHeaders[uNumLoadedSprites], "pending") == -1 )
284 return -1;
285 pSpriteHeaders[uNumLoadedSprites].uPaletteId = pPaletteManager->LoadPalette(pSpriteHeaders[uNumLoadedSprites].uPaletteId);
286 }
287 }*/
288
289 //if ( pRenderer->pRenderD3D )
290 {
291 pHardwareSprites[uNumLoadedSprites].pName = (const char *)malloc(20);
292 strcpy((char *)pHardwareSprites[uNumLoadedSprites].pName, pContainerName);
293 pHardwareSprites[uNumLoadedSprites].uPaletteID = uPaletteID;
294 pRenderer->MoveSpriteToDevice(&pHardwareSprites[uNumLoadedSprites]);
295 }
296 ++uNumLoadedSprites;
297 return uNumLoadedSprites - 1;
298
299 }
300
301 //----- (004ACADA) --------------------------------------------------------
302 void LODFile_Sprites::ReleaseLostHardwareSprites()
303 {
304 signed int v2; // ebx@2
305 int v3; // edi@3
306 IDirectDrawSurface *v4; // eax@4
307 IDirect3DTexture2 *v5; // eax@6
308 IDirectDrawSurface *v6; // ST00_4@8
309
310 if ( this->pHardwareSprites )
311 {
312 v2 = 0;
313 if ( (signed int)this->uNumLoadedSprites > 0 )
314 {
315 v3 = 0;
316 do
317 {
318 v4 = (IDirectDrawSurface *)this->pHardwareSprites[v3].pTextureSurface;
319 if ( v4 && v4->IsLost() == DDERR_SURFACELOST )
320 {
321 v5 = this->pHardwareSprites[v3].pTexture;
322 if ( v5 )
323 {
324 v5->Release();
325 this->pHardwareSprites[v3].pTexture = nullptr;
326 }
327 v6 = (IDirectDrawSurface *)this->pHardwareSprites[v3].pTextureSurface;
328 v6->Release();
329 this->pHardwareSprites[v3].pTextureSurface = nullptr;
330 pRenderer->MoveSpriteToDevice(&this->pHardwareSprites[v3]);
331 }
332 ++v2;
333 ++v3;
334 }
335 while ( v2 < (signed int)this->uNumLoadedSprites );
336 }
337 }
338 }
339
340 //----- (004ACB70) --------------------------------------------------------
341 void LODFile_Sprites::ReleaseAll()
342 {
343 if ( this->pHardwareSprites )
344 {
345 for ( int i = 0; i < this->uNumLoadedSprites; ++i )
346 {
347 if ( this->pHardwareSprites )
348 {
349 if ( this->pHardwareSprites[i].pTexture )
350 {
351 this->pHardwareSprites[i].pTexture->Release();
352 this->pHardwareSprites[i].pTexture = nullptr;
353 }
354 if ( this->pHardwareSprites )
355 {
356 if ( this->pHardwareSprites[i].pTextureSurface )
357 {
358 this->pHardwareSprites[i].pTextureSurface->Release();
359 this->pHardwareSprites[i].pTextureSurface = nullptr;
360 }
361 }
362 }
363 }
364 }
365 }
366
367 //----- (004ACBE0) --------------------------------------------------------
368 void LODFile_Sprites::MoveSpritesToVideoMemory()
369 {
370 if ( this->pHardwareSprites )
371 {
372 for ( int i = 0; i < this->uNumLoadedSprites; ++i )
373 pRenderer->MoveSpriteToDevice(&this->pHardwareSprites[i]);
374 }
375 }
376
377 //----- (004ACC38) --------------------------------------------------------
378 int LODSprite::DrawSprite_sw(RenderBillboardTransform_local0 *a2, char a3)
379 {
380 RenderBillboardTransform_local0 *v3; // edi@1
381 int result; // eax@1
382 int v5; // esi@2
383 int v6; // ST18_4@2
384 //signed int v7; // eax@2
385 signed int v8; // ebx@2
386 int v9; // ebx@2
387 int *v10; // ecx@2
388 int v11; // esi@2
389 unsigned int v12; // edx@4
390 int v13; // esi@13
391 int v14; // esi@17
392 int v15; // ecx@17
393 char *v16; // edx@17
394 int v17; // esi@17
395 int v18; // ecx@18
396 int v19; // esi@18
397 LODSprite_stru0 *v20; // edx@21
398 int v21; // eax@22
399 int v22; // esi@22
400 int v23; // eax@25
401 int v24; // ecx@25
402 signed __int64 v25; // qtt@27
403 int v26; // eax@27
404 unsigned __int16 *v27; // eax@29
405 LODSprite_stru0 *v28; // edx@29
406 signed int v29; // ecx@30
407 int v30; // ecx@37
408 int v31; // ecx@38
409 signed int v32; // ecx@41
410 int v33; // ecx@47
411 int v34; // ecx@56
412 int v35; // esi@58
413 __int16 v36; // ax@58
414 int v37; // ecx@59
415 int v38; // eax@59
416 int v39; // ecx@62
417 signed int v40; // ST30_4@64
418 signed __int64 v41; // qtt@64
419 int v42; // ecx@64
420 unsigned __int16 *v43; // eax@66
421 LODSprite_stru0 *v44; // ecx@66
422 int v45; // edx@69
423 int v46; // edx@77
424 //unsigned __int16 *pTarget; // [sp+Ch] [bp-50h]@2
425 signed int v48; // [sp+10h] [bp-4Ch]@2
426 signed int v49; // [sp+14h] [bp-48h]@2
427 int v50; // [sp+14h] [bp-48h]@19
428 int v51; // [sp+14h] [bp-48h]@57
429 int v52; // [sp+18h] [bp-44h]@13
430 int v53; // [sp+1Ch] [bp-40h]@2
431 int v54; // [sp+1Ch] [bp-40h]@22
432 int v55; // [sp+1Ch] [bp-40h]@32
433 int v56; // [sp+1Ch] [bp-40h]@69
434 int v57; // [sp+20h] [bp-3Ch]@2
435 int v58; // [sp+24h] [bp-38h]@1
436 int v59; // [sp+28h] [bp-34h]@2
437 int v60; // [sp+28h] [bp-34h]@13
438 unsigned __int16 *v61; // [sp+2Ch] [bp-30h]@2
439 int v62; // [sp+30h] [bp-2Ch]@2
440 void *v63; // [sp+30h] [bp-2Ch]@29
441 void *v64; // [sp+30h] [bp-2Ch]@66
442 int v65; // [sp+34h] [bp-28h]@2
443 int v66; // [sp+34h] [bp-28h]@22
444 int v67; // [sp+34h] [bp-28h]@59
445 int v68; // [sp+38h] [bp-24h]@13
446 unsigned int v69; // [sp+3Ch] [bp-20h]@2
447 int v70; // [sp+40h] [bp-1Ch]@2
448 signed int v71; // [sp+40h] [bp-1Ch]@15
449 int v72; // [sp+44h] [bp-18h]@2
450 unsigned __int16 *v73; // [sp+44h] [bp-18h]@29
451 unsigned __int16 *v74; // [sp+44h] [bp-18h]@66
452 int v75; // [sp+48h] [bp-14h]@4
453 int v76; // [sp+48h] [bp-14h]@22
454 int v77; // [sp+48h] [bp-14h]@59
455 //LODSprite *v78; // [sp+4Ch] [bp-10h]@1
456 int v79; // [sp+50h] [bp-Ch]@4
457 int v80; // [sp+50h] [bp-Ch]@21
458 int v81; // [sp+50h] [bp-Ch]@62
459 int v82; // [sp+50h] [bp-Ch]@67
460 int v83; // [sp+50h] [bp-Ch]@75
461 int *pTargetZ; // [sp+54h] [bp-8h]@4
462 int v85; // [sp+58h] [bp-4h]@18
463 int v86; // [sp+58h] [bp-4h]@56
464 signed int v87; // [sp+64h] [bp+8h]@2
465 int v88; // [sp+68h] [bp+Ch]@18
466 int v89; // [sp+68h] [bp+Ch]@56
467
468 v3 = a2;
469 //v78 = this;
470 result = a2->_screenspace_x_scaler_packedfloat;
471 v58 = a2->_screenspace_x_scaler_packedfloat;
472 if ( result <= 0 )
473 return result;
474 v5 = a2->_screenspace_y_scaler_packedfloat;
475 v6 = a2->_screenspace_x_scaler_packedfloat;
476 v87 = (signed __int64)0x100000000ui64 / result;
477 v48 = (signed __int64)0x100000000ui64 / result;
478 v62 = (signed __int64)0x100000000ui64 / v5;
479 //v7 = this->uHeight;
480 v8 = (signed int)((signed __int64)0x100000000ui64 / v5) >> 1;
481 v53 = v8;
482 v70 = (this->uHeight << 16) - v8;
483 v49 = this->uHeight;
484 v69 = v3->uTargetPitch;
485
486 __debugbreak(); // target surface will most likely be 32bit, but this sub awaits 16bits
487 auto pTarget = (unsigned __int16 *)v3->pTarget;
488 v57 = v3->sZValue;
489 v61 = v3->pPalette;
490 v9 = (v6 * this->uWidth + 0x8000) >> 16;
491 v72 = v3->uScreenSpaceY;
492 result = (v5 * this->uHeight + 0x8000) >> 16;
493 v10 = (int *)(v72 - result + 1);
494 v11 = v3->uScreenSpaceX - (v9 >> 1) + 1;
495 v65 = v72 - result + 1;
496 v59 = v11 + v9 - 1;
497 if ( v3->uFlags & 0x800 )
498 {
499 v10 = (int *)((char *)v10 + (v49 >> 1));
500 v72 += v49 >> 1;
501 v65 = (int)v10;
502 }
503 v12 = v72;
504 pTargetZ = v10;
505 v75 = v3->uScreenSpaceX - (v9 >> 1) + 1;
506 v79 = v11 + v9 - 1;
507 if ( !(v3->uFlags & 8) )
508 {
509 if ( v65 < (signed int)v3->uViewportY )
510 pTargetZ = (int *)v3->uViewportY;
511 if ( v72 > (signed int)v3->uViewportW )
512 v12 = v3->uViewportW;
513 if ( v11 < (signed int)v3->uViewportX )
514 v75 = v3->uViewportX;
515 if ( v59 > (signed int)v3->uViewportZ )
516 v79 = v3->uViewportZ;
517 }
518 v68 = v75 - v11;
519 v13 = -v62;
520 v60 = v59 - v79;
521 v52 = -v62;
522 if ( v3->uFlags & 1 )
523 {
524 v13 = v62;
525 v70 = v53;
526 v52 = v62;
527 }
528 v71 = v13 * (v72 - v12) + v70;
529 if ( LOBYTE(viewparams->field_20) )
530 {
531 if ( a3 )
532 return result;
533 }
534 v14 = 5 * v12;
535 v15 = v69 * v12;
536 result = v12 - v72 + result - 1;
537 v16 = (char *)pTargetZ - v65;
538 v17 = v14 << 7;
539 if ( v3->uFlags & 4 )
540 {
541 v34 = v79 + v15;
542 v89 = v34;
543 v86 = v79 + v17;
544 if ( result < (signed int)v16 )
545 return result;
546 v51 = result - (int)v16 + 1;
547 while ( 1 )
548 {
549 v35 = v71 >> 16;
550 v36 = this->pSpriteLines[v35].a1;
551 if ( v36 == -1 )
552 {
553 v34 -= v69;
554 v89 = v34;
555 goto LABEL_84;
556 }
557 v37 = v9 - ((unsigned __int64)(v36 * (signed __int64)v58) >> 16);
558 v67 = v87 * ((unsigned __int64)(this->pSpriteLines[v35].a2 * (signed __int64)v58) >> 16);
559 v38 = v9 - v60;
560 v77 = v9 - v60;
561 if ( v9 - v60 <= (signed int)(v9 - ((unsigned __int64)(this->pSpriteLines[v35].a2 * (signed __int64)v58) >> 16))
562 || v68 >= v37 )
563 {
564 v89 -= v69;
565 v34 = v89;
566 LABEL_84:
567 v86 -= window->GetWidth();
568 goto LABEL_85;
569 }
570 if ( v38 < v37 )
571 v81 = (v87 >> 1) + v87 * (v37 - v38);
572 else
573 {
574 v77 = v37;
575 v81 = v87 >> 1;
576 v39 = v37 - v9;
577 v89 += v39 + v60;
578 v86 += v60 + v39;
579 }
580 v40 = ((this->pSpriteLines[v35].a2 + 1) << 16) - v81 - v67;
581 LODWORD(v41) = v40 << 16;
582 HIDWORD(v41) = v40 >> 16;
583 v42 = v77 - (((signed int)((unsigned __int64)(v41 / v48) - 0x8000) >> 16) + 1);
584 if ( v68 >= v42 )
585 v42 = v68;
586 v43 = &pTarget[v89];
587 v74 = &v43[v42 - v77 + 1];
588 v44 = &this->pSpriteLines[v35];
589 v64 = v44->pos;
590 if ( !v57 )
591 {
592 v83 = v67 + v81;
593 if ( ((v83 - (v44->a1 << 16)) & 0xFFFF0000) < 0 )
594 {
595 v83 += v87;
596 --v43;
597 --pTargetZ;
598 }
599 while ( v43 >= v74 )
600 {
601 v46 = (v83 - ((signed int)this->pSpriteLines[v35].a1 << 16)) >> 16;
602 if ( *((char *)v64 + v46) )
603 *v43 = v61[*((char *)v64 + v46)];
604 v83 += v87;
605 --v43;
606 }
607 goto LABEL_81;
608 }
609 pTargetZ = &v3->pTargetZ[v86];
610 v82 = v67 + v81;
611 if ( ((v82 - (v44->a1 << 16)) & 0xFFFF0000) < 0 )
612 goto LABEL_72;
613 LABEL_73:
614 if ( v43 >= v74 )
615 break;
616 LABEL_81:
617 v89 += v9 - v77 - v60 - v69;
618 v34 = v89;
619 v86 = v86 + v9 - v77 - v60 - window->GetWidth();
620 LABEL_85:
621 result = v52;
622 v71 += v52;
623 --v51;
624 if ( !v51 )
625 return result;
626 }
627 v45 = (v82 - ((signed int)this->pSpriteLines[v35].a1 << 16)) >> 16;
628 v56 = *((char *)v64 + v45);
629 if ( *((char *)v64 + v45) && v57 <= (unsigned int)*pTargetZ )
630 {
631 *pTargetZ = v57;
632 *v43 = v61[v56];
633 }
634 LABEL_72:
635 v82 += v87;
636 --v43;
637 --pTargetZ;
638 goto LABEL_73;
639 }
640 v18 = v75 + v15;
641 v19 = v75 + v17;
642 v88 = v18;
643 v85 = v19;
644 if ( result >= (signed int)v16 )
645 {
646 v50 = result - (int)v16 + 1;
647 while ( 1 )
648 {
649 v20 = &this->pSpriteLines[v71 >> 16];
650 v80 = v71 >> 16;
651 if ( v20->a1 != -1 )
652 break;
653 v18 -= v69;
654 v85 = v19 - window->GetWidth();
655 v88 = v18;
656 LABEL_54:
657 result = v52;
658 v71 += v52;
659 --v50;
660 if ( !v50 )
661 return result;
662 v19 = v85;
663 }
664 v21 = (v58 * v20->a1 + 32768) >> 16;
665 v66 = v21 * v87;
666 v76 = v68;
667 v54 = v20->a2;
668 v22 = v9 - v60;
669 if ( v68 >= (v58 * v54 + 32768) >> 16 || v22 <= v21 )
670 {
671 v88 -= v69;
672 v85 -= window->GetWidth();
673 goto LABEL_51;
674 }
675 if ( v68 > v21 )
676 {
677 v24 = (v87 >> 1) + v87 * (v68 - v21);
678 }
679 else
680 {
681 v76 = (v58 * v20->a1 + 0x8000) >> 16;
682 v23 = v21 - v68;
683 v88 += v23;
684 v24 = v87 >> 1;
685 v85 += v23;
686 }
687 LODWORD(v25) = (((v54 + 1) << 16) - v24 - v66) << 16;
688 HIDWORD(v25) = (((v54 + 1) << 16) - v24 - v66) >> 16;
689 v26 = v76 + ((signed int)(v25 / v48) >> 16) + 1;
690 if ( v22 > v26 )
691 v22 = v26;
692 v27 = &pTarget[v88];
693 v73 = &v27[v22 - v76 - 1];
694 v28 = &this->pSpriteLines[v80];
695 v63 = v28->pos;
696 if ( v57 )
697 {
698 pTargetZ = &v3->pTargetZ[v85];
699 v29 = v66 - (v28->a1 << 16) + v24;
700 if ( (v29 & 0xFFFF0000) >= 0 )
701 goto LABEL_36;
702 while ( 1 )
703 {
704 v29 += v87;
705 ++v27;
706 ++pTargetZ;
707 LABEL_36:
708 if ( v27 >= v73 )
709 break;
710 v55 = *((char *)v63 + (v29 >> 16));
711 if ( *((char *)v63 + (v29 >> 16)) && v57 <= (unsigned int)*pTargetZ )
712 {
713 *pTargetZ = v57;
714 *v27 = v61[v55];
715 }
716 }
717 v30 = v29 >> 16;
718 if ( v30 > this->pSpriteLines[v80].a2 - (signed int)this->pSpriteLines[v80].a1
719 || (v31 = *((char *)v63 + v30)) == 0
720 || v57 > (unsigned int)*pTargetZ )
721 goto LABEL_50;
722 *pTargetZ = v57;
723 }
724 else
725 {
726 v32 = v66 - (v28->a1 << 16) + v24;
727 if ( (v32 & 0xFFFF0000) < 0 )
728 {
729 v32 += v87;
730 ++v27;
731 ++pTargetZ;
732 }
733 while ( v27 < v73 )
734 {
735 if ( *((char *)v63 + (v32 >> 16)) )
736 *v27 = v61[*((char *)v63 + (v32 >> 16))];
737 v32 += v87;
738 ++v27;
739 }
740 v33 = v32 >> 16;
741 if ( v33 > this->pSpriteLines[v80].a2 - (signed int)this->pSpriteLines[v80].a1
742 || (v31 = *((char *)v63 + v33)) == 0 )
743 goto LABEL_50;
744 }
745 *v27 = v61[v31];
746 LABEL_50:
747 v88 += v68 - v76 - v69;
748 v85 = v85 + v68 - v76 - window->GetWidth();
749 LABEL_51:
750 v18 = v88;
751 goto LABEL_54;
752 }
753 return result;
754 }
755
756 //----- (004AD2D1) --------------------------------------------------------
757 int LODSprite::_4AD2D1(struct RenderBillboardTransform_local0 *a2, int a3)
758 {
759 int result; // eax@1
760 unsigned int v4; // esi@1
761 int v5; // edi@1
762 LODSprite_stru0 *v6; // edx@2
763 __int16 v7; // bx@2
764 int v8; // ecx@3
765 unsigned __int16 *v9; // esi@3
766 int v10; // ebx@3
767 void *v11; // edx@3
768 unsigned __int16 *v12; // ecx@3
769 int v13; // ebx@4
770 //LODSprite *v14; // [sp+8h] [bp-10h]@1
771 unsigned __int16 *v15; // [sp+10h] [bp-8h]@1
772 unsigned __int16 *v16; // [sp+14h] [bp-4h]@1
773 int i; // [sp+20h] [bp+8h]@1
774
775 result = (int)a2;
776 v4 = a2->uTargetPitch;
777
778 __debugbreak(); // sub expects 16bit target surface, we may have 32bit
779 v16 = (unsigned short *)a2->pTarget;
780 v15 = a2->pPalette;
781 v5 = this->uHeight - 1;
782 for ( i = v4 * a2->uScreenSpaceY - (this->uWidth >> 1) + a2->uScreenSpaceX + 1; v5 >= 0; --v5 )
783 {
784 v6 = &this->pSpriteLines[v5];
785 v7 = this->pSpriteLines[v5].a1;
786 if ( this->pSpriteLines[v5].a1 != -1 )
787 {
788 v8 = v7;
789 v9 = &v16[v7 + i];
790 v10 = v6->a2;
791 v11 = v6->pos;
792 v12 = &v9[v10 - v8];
793 while ( v9 <= v12 )
794 {
795 v13 = *(char *)v11;
796 v11 = (char *)v11 + 1;
797 if ( v13 )
798 *v9 = v15[v13];
799 ++v9;
800 }
801 v4 = *(int *)(result + 48);
802 //this = v14;
803 }
804 i -= v4;
805 }
806 return result;
807 }
808
809 //----- (0046454B) --------------------------------------------------------
810 void LODFile_IconsBitmaps::ReleaseAll2()
811 {
812 for ( uint i = (uint)this->dword_11B84; i < this->uNumLoadedFiles; i++ )
813 {
814 this->pTextures[i].Release();
815 if ( this->pHardwareTextures )
816 {
817 if ( this->pHardwareTextures[i] )
818 {
819 this->pHardwareTextures[i]->Release();
820 this->pHardwareTextures[i] = 0;
821 }
822 }
823 if ( this->pHardwareSurfaces )
824 {
825 if ( this->pHardwareSurfaces[i] )
826 {
827 this->pHardwareSurfaces[i]->Release();
828 this->pHardwareSurfaces[i] = 0;
829 }
830 }
831 }
832 this->uTexturePacksCount = 0;
833 this->uNumPrevLoadedFiles = 0;
834 this->uNumLoadedFiles = this->dword_11B84;
835 }
836
837 //----- (004645DC) --------------------------------------------------------
838 void LODFile_Sprites::DeleteSomeOtherSprites()
839 {
840 int *v1; // esi@1
841 int *v2; // edi@1
842
843 v1 = (int *)&this->uNumLoadedSprites;
844 v2 = &this->field_ECA0;
845 DeleteSpritesRange(field_ECA0, uNumLoadedSprites);
846 *v1 = *v2;
847 }
848
849 //----- (00461431) --------------------------------------------------------
850 void LOD::File::Close()
851 {
852 if (isFileOpened )
853 {
854 this->pContainerName[0] = 0;
855 this->uCurrentIndexDir = 0;
856 free(pSubIndices);
857 free(pRoot);
858 pSubIndices = nullptr;
859 pRoot = nullptr;
860 fclose(pFile);
861 isFileOpened = false;
862 _6A0CA8_lod_unused = 0;
863 }
864 }
865
866 //----- (00461492) --------------------------------------------------------
867 int LODWriteableFile::CreateNewLod(LOD::FileHeader *pHeader, LOD::Directory *pDir, const char *lod_name)
868 {
869 if (isFileOpened)
870 return 1;
871 if ( !pDir->pFilename[0] )
872 return 2;
873 strcpy(pHeader->pSignature, "LOD");
874 pHeader->LODSize = 100;
875 pHeader->uNumIndices = 1;
876 pDir->field_F = 0;
877 pDir->uDataSize = 0;
878 pDir->uOfsetFromSubindicesStart = 288;
879 strcpy(pLODName, lod_name);
880
881 pFile = fopen(pLODName, "wb+");
882 if (!pFile)
883 return 3;
884 fwrite(pHeader,sizeof(LOD::FileHeader), 1, pFile);
885 fwrite(pDir, sizeof(LOD::Directory), 1, pFile);
886 fclose(pFile);
887 pFile = nullptr;
888 return 0;
889 }
890
891 //----- (0046153F) --------------------------------------------------------
892 void LOD::File::ResetSubIndices()
893 {
894 if ( isFileOpened )
895 {
896 pContainerName[0] = 0;
897 uCurrentIndexDir = 0;
898 uOffsetToSubIndex = 0;
899 uNumSubDirs = 0;
900 uLODDataSize = 0;
901 free(pSubIndices);
902 pSubIndices = nullptr;
903 }
904 }
905
906 //----- (00450C8B) --------------------------------------------------------
907 void LODFile_Sprites::DeleteSomeSprites()
908 {
909 int *v1; // esi@1
910 int *v2; // edi@1
911
912 v1 = (int *)&this->uNumLoadedSprites;
913 v2 = &this->field_ECA8;
914 DeleteSpritesRange(this->field_ECA8, this->uNumLoadedSprites);
915 *v1 = *v2;
916 }
917
918 //----- (00450CA9) --------------------------------------------------------
919 void LODFile_Sprites::DeleteSpritesRange(int uStartIndex, int uStopIndex)
920 {
921 if ( this->pHardwareSprites )
922 {
923 if ( uStartIndex < uStopIndex )
924 {
925 for ( int i = uStartIndex; i < uStopIndex; i++ )
926 {
927 this->pSpriteHeaders[i].Release();
928 pHardwareSprites[i].Release();
929 }
930 }
931 }
932 else
933 {
934 if ( uStartIndex < uStopIndex )
935 {
936 for ( int i = uStartIndex; i < uStopIndex; i++ )
937 this->pSpriteHeaders[i].Release();
938 }
939 }
940 }
941
942 //----- (00450D1D) --------------------------------------------------------
943 void LODSprite::Release()
944 {
945 if ( !(HIBYTE(this->word_1A) & 4) )
946 {
947 free(this->pDecompressedBytes);
948 free(this->pSpriteLines);
949 }
950 this->word_1A = 0;
951 this->pDecompressedBytes = nullptr;
952 this->pSpriteLines = nullptr;
953 this->pName[0] = 0;
954 this->word_16 = 0;
955 this->uPaletteId = 0;
956 this->uTexturePitch = 0;
957 this->uHeight = 0;
958 this->uWidth = 0;
959 this->uSpriteSize = 0;
960 }
961
962 //----- (00450D68) --------------------------------------------------------
963 void Sprite::Release()
964 {
965 free((void *)pName);
966 pName = nullptr;
967
968 if (pTextureSurface)
969 pTextureSurface->Release();
970 pTextureSurface = nullptr;
971
972 if (pTexture)
973 pTexture->Release();
974 pTexture = nullptr;
975 }
976
977 //----- (0040FAEE) --------------------------------------------------------
978 //----- (0040FA2E) --------------------------------------------------------
979 bool LODFile_IconsBitmaps::Load(const char *pLODFilename, const char *pFolderName)
980 {
981 ReleaseAll();
982
983 if (LoadHeader(pLODFilename, 1))
984 return false;
985
986 return LoadSubIndices(pFolderName) == 0;
987 }
988
989 //----- (0040FA60) --------------------------------------------------------
990 void LODFile_IconsBitmaps::ReleaseAll()
991 {
992 for( uint i = 0; i < this->uNumLoadedFiles; i++ )
993 {
994 this->pTextures[i].Release();
995 if ( this->pHardwareTextures )
996 {
997 if ( this->pHardwareTextures[i] )
998 {
999 this->pHardwareTextures[i]->Release();
1000 this->pHardwareTextures[i] = 0;
1001 }
1002 }
1003 if ( this->pHardwareSurfaces )
1004 {
1005 if ( this->pHardwareSurfaces[i] )
1006 {
1007 this->pHardwareSurfaces[i]->Release();
1008 this->pHardwareSurfaces[i] = 0;
1009 }
1010 }
1011 }
1012 this->uTexturePacksCount = 0;
1013 this->uNumPrevLoadedFiles = 0;
1014 this->dword_11B84 = 0;
1015 this->dword_11B80 = 0;
1016 this->uNumLoadedFiles = 0;
1017 }
1018
1019 //----- (0040F9F0) --------------------------------------------------------
1020 unsigned int LODFile_IconsBitmaps::FindTextureByName(const char *pName)
1021 {
1022 for ( uint i = 0; i < this->uNumLoadedFiles; i++ )
1023 {
1024 if ( !_stricmp(this->pTextures[i].pName, pName) )
1025 return i;
1026 }
1027 return -1;
1028 }
1029
1030 //----- (0040F9C5) --------------------------------------------------------
1031 void LODFile_IconsBitmaps::SyncLoadedFilesCount()
1032 {
1033 signed int loaded_files; // eax@1
1034 Texture *pTex; // edx@1
1035
1036 loaded_files = this->uNumLoadedFiles;
1037 for ( pTex = &this->pTextures[loaded_files]; !pTex->pName[0]; --pTex )
1038 --loaded_files;
1039 if ( loaded_files < (signed int)this->uNumLoadedFiles )
1040 {
1041 ++loaded_files;
1042 this->uNumLoadedFiles = loaded_files;
1043 }
1044
1045 }
1046
1047 //----- (0046249B) --------------------------------------------------------
1048 LODFile_Sprites::~LODFile_Sprites()
1049 {
1050 if ( this->pHardwareSprites )
1051 {
1052 for ( int i = 0; i < this->uNumLoadedSprites; ++i )
1053 {
1054 this->pSpriteHeaders[i].Release();
1055 this->pHardwareSprites[i].Release();
1056 }
1057 }
1058 else
1059 {
1060 for ( int i = 0; i < this->uNumLoadedSprites; ++i )
1061 this->pSpriteHeaders[i].Release();
1062 }
1063 //_eh_vector_destructor_iterator_(v1->pSpriteHeaders, 40, 1500, LODSprite::dtor);
1064 //LOD::File::vdtor((LOD::File *)v1);
1065 }
1066 // 4CC2B4: using guessed type int __stdcall _eh vector destructor iterator_(int, int, int, int);
1067
1068 //----- (00462463) --------------------------------------------------------
1069 LODSprite::~LODSprite()
1070 {
1071 if ( !(HIBYTE(this->word_1A) & 4) )
1072 {
1073 free(pDecompressedBytes);
1074 free(pSpriteLines);
1075 }
1076 pDecompressedBytes = nullptr;
1077 pSpriteLines = nullptr;
1078 }
1079
1080 //----- (004623E5) --------------------------------------------------------
1081 LODFile_Sprites::LODFile_Sprites():
1082 LOD::File()
1083 {
1084 /*_eh_vector_constructor_iterator_(
1085 v1->pSpriteHeaders,
1086 40,
1087 1500,
1088 (void ( *)(void *))LODSprite::LODSprite,
1089 (void ( *)(void *))LODSprite::dtor);*/
1090 field_ECA4 = 0;
1091 field_ECA0 = 0;
1092 pHardwareSprites = 0;
1093 //can_load_hardware_sprites = 0;
1094 field_ECB4 = 0;
1095 uNumLoadedSprites = 0;
1096 }
1097
1098 //----- (00462303) --------------------------------------------------------
1099 LODFile_IconsBitmaps::~LODFile_IconsBitmaps()
1100 {
1101
1102 for ( uint i = 0; i < this->uNumLoadedFiles; i++ )
1103 {
1104 this->pTextures[i].Release();
1105 if ( this->pHardwareTextures )
1106 {
1107 if ( this->pHardwareTextures[i] )
1108 {
1109 this->pHardwareTextures[i]->Release();
1110 this->pHardwareTextures[i] = 0;
1111 }
1112 }
1113 if ( this->pHardwareSurfaces )
1114 {
1115 if ( this->pHardwareSurfaces[i] )
1116 {
1117 this->pHardwareSurfaces[i]->Release();
1118 this->pHardwareSurfaces[i] = 0;
1119 }
1120 }
1121 }
1122 free(this->pHardwareSurfaces);
1123 free(this->pHardwareTextures);
1124 free(this->ptr_011BB4);
1125 //LOD::File::vdtor((LOD::File *)v1);
1126 }
1127
1128 //----- (00462272) --------------------------------------------------------
1129 LODFile_IconsBitmaps::LODFile_IconsBitmaps():
1130 LOD::File()
1131 {
1132 /*v2 = v1->pTextures;
1133 v3 = 1000;
1134 do
1135 {
1136 Texture::Texture(v2);
1137 ++v2;
1138 --v3;
1139 }
1140 while ( v3 );*/
1141 this->uTexturePacksCount = 0;
1142 this->uNumPrevLoadedFiles = 0;
1143 this->dword_11B84 = 0;
1144 this->dword_11B80 = 0;
1145 this->uNumLoadedFiles = 0;
1146 this->dword_011BA4 = 0;
1147 //this->can_load_hardware_sprites = 0;
1148 this->pHardwareSurfaces = 0;
1149 this->pHardwareTextures = 0;
1150 this->ptr_011BB4 = 0;
1151 this->uTextureRedBits = 0;
1152 this->uTextureGreenBits = 0;
1153 this->uTextureBlueBits = 0;
1154 }
1155
1156 //----- (004621A7) --------------------------------------------------------
1157 bool LODWriteableFile::_4621A7()//çàêðûòü è çàãðóçèòü çàïèñûâàåìûé ô-ë(ïðè ñîõðàíåíèè)
1158 {
1159 CloseWriteFile();
1160 return LoadFile(pLODName, 0);
1161 }
1162
1163 //----- (00461FD4) ---LODFile_sub_461FD4---text:004632EA --------------------------------------------------
1164 int LODWriteableFile::FixDirectoryOffsets()
1165 {
1166 int total_size; // edi@1
1167 int temp_offset; // ecx@5
1168 FILE *tmp_file; // eax@9
1169 size_t write_size; // edi@12
1170 int result;
1171 char Filename[256]; // [sp+Ch] [bp-228h]@9
1172 char NewFilename[256]; // [sp+10Ch] [bp-128h]@15
1173 int i;
1174
1175 total_size = 0;
1176 for ( i = 0; i < uNumSubDirs; i++ )
1177 total_size += pSubIndices[i].uDataSize;
1178 //fix offsets
1179 temp_offset = sizeof(LOD::Directory) * uNumSubDirs;
1180 for ( i = 0; i < uNumSubDirs; i++ )
1181 {
1182 pSubIndices[i].uOfsetFromSubindicesStart=temp_offset;
1183 temp_offset+=pSubIndices[i].uDataSize;
1184 }
1185 strcpy(Filename, "lod.tmp");
1186 tmp_file = fopen(Filename, "wb+");
1187
1188 if ( tmp_file )
1189 {
1190 fwrite((const void *)&header, sizeof(LOD::FileHeader), 1, tmp_file);
1191
1192 LOD::Directory Lindx;
1193 strcpy(Lindx.pFilename, "chapter");
1194 Lindx.uOfsetFromSubindicesStart = uOffsetToSubIndex; //10h 16
1195 Lindx.uDataSize = sizeof(LOD::Directory) * uNumSubDirs + total_size; //14h 20
1196 Lindx.dword_000018 = 0; //18h 24
1197 Lindx.uNumSubIndices = uNumSubDirs; //1ch 28
1198 Lindx.word_00001E = 0; // 1Eh 30
1199 fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
1200 fwrite(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, tmp_file);
1201 fseek(pOutputFileHandle, 0, 0);
1202 if ( total_size > 0 )
1203 {
1204 do
1205 {
1206 write_size = uIOBufferSize;
1207 if ( total_size <= (signed int)uIOBufferSize )
1208 write_size =total_size;
1209 fread(pIOBuffer, 1, write_size, pOutputFileHandle);
1210 fwrite(pIOBuffer, 1, write_size, tmp_file);
1211 total_size -= write_size;
1212 }
1213 while ( total_size > 0 );
1214 }
1215 strcpy(NewFilename, (const char *)&pLODName);
1216 fclose(tmp_file);
1217 fclose(pOutputFileHandle);
1218 CloseWriteFile();
1219 remove("lodapp.tmp");
1220 remove(NewFilename);
1221 rename(Filename, NewFilename);
1222 CloseWriteFile();
1223 LoadFile( (const char *)&pLODName, 0);
1224 result = 0;
1225 }
1226 else
1227 result = 5;
1228 return result;
1229 }
1230
1231 //----- (00461F71) --------------------------------------------------------
1232 bool LOD::File::AppendDirectory(LOD::Directory *pDir, const void *pData)
1233 {
1234 Assert(uNumSubDirs < 299);
1235
1236 memcpy(&pSubIndices[uNumSubDirs++], pDir, sizeof(LOD::Directory));
1237 fwrite(pData, 1, pDir->uDataSize, pOutputFileHandle);
1238 return true;
1239 }
1240
1241 //----- (00461F1E) --------------------------------------------------------
1242 int LODWriteableFile::CreateTempFile()
1243 {
1244 if (!isFileOpened)
1245 return 1;
1246
1247 if (pIOBuffer && uIOBufferSize )
1248 {
1249 uCurrentIndexDir = 0;
1250 uNumSubDirs = 0;
1251 pOutputFileHandle = fopen("lodapp.tmp", "wb+");
1252 return pOutputFileHandle ? 1 : 7;
1253 }
1254 else
1255 return 5;
1256 }
1257
1258 //----- (00461EE9) --------------------------------------------------------
1259 void LODWriteableFile::CloseWriteFile()
1260 {
1261 if (isFileOpened)
1262 {
1263 pContainerName[0] = 0;
1264 uCurrentIndexDir = 0;
1265 _6A0CA8_lod_unused = 0;
1266
1267 isFileOpened = false;
1268 fflush(pFile);
1269 fclose(pFile);
1270 pFile = nullptr;
1271 }
1272 //else
1273 //__debugbreak();
1274 }
1275 // 6A0CA8: using guessed type int 6A0CA8_lod_unused;
1276
1277
1278 //----- (00461B48) --------------------------------------------------------
1279 unsigned int LODWriteableFile::Write(const LOD::Directory *pDir, const void *pDirData, int a4)
1280 {
1281 char Filename[256];
1282 char NewFilename[256];
1283 FILE *tmp_file;
1284 int comp_res;
1285 bool bRewrite_data;
1286 int offset_to_data;
1287 int total_data_size;
1288 int size_correction;
1289 int to_copy_size;
1290 int read_size;
1291 int curr_position;
1292 int insert_index;
1293
1294 //insert new data in sorted index lod file
1295 bRewrite_data = false;
1296 insert_index = -1;
1297 if ( !isFileOpened )//sometimes gives crash
1298 return 1;
1299 if ( !pSubIndices )
1300 return 2;
1301 if ( !pIOBuffer || !uIOBufferSize )
1302 return 3;
1303
1304 for ( int i = 0; i < uNumSubDirs; i++ )
1305 {
1306 comp_res = _stricmp(pSubIndices[i].pFilename, pDir->pFilename);
1307 if( comp_res == 0 )
1308 {
1309 insert_index = i;
1310 if ( a4 == 0 )
1311 {
1312 bRewrite_data = true;
1313 break;
1314 }
1315 if ( a4 == 1 )
1316 {
1317 if ( pSubIndices[i].uNumSubIndices < pDir->uNumSubIndices )
1318 {
1319 if ( pSubIndices[i].word_00001E < pDir->word_00001E )
1320 return 4;
1321 }
1322 else
1323 bRewrite_data = true;
1324 break;
1325 }
1326 if ( a4 == 2 )
1327 return 4;
1328 }
1329 else if ( comp_res > 0 )
1330 {
1331 if ( insert_index == -1 )
1332 {
1333 insert_index=i;
1334 break;
1335 }
1336 }
1337 }
1338 strcpy(Filename, "lod.tmp");
1339 tmp_file = fopen(Filename, "wb+");
1340 if ( !tmp_file )
1341 return 5;
1342 if (!bRewrite_data)
1343 size_correction = 0;
1344 else
1345 size_correction = pSubIndices[insert_index].uDataSize;
1346
1347 //create chapter index
1348 LOD::Directory Lindx;
1349 strcpy(Lindx.pFilename, "chapter");
1350 Lindx.dword_000018 = 0;
1351 Lindx.word_00001E = 0;
1352 Lindx.uNumSubIndices = uNumSubDirs;
1353 Lindx.uOfsetFromSubindicesStart = sizeof(LOD::FileHeader) + sizeof(LOD::Directory);
1354 total_data_size = uLODDataSize + pDir->uDataSize-size_correction;
1355 if (!bRewrite_data)
1356 {
1357 total_data_size += sizeof(LOD::Directory);
1358 Lindx.uNumSubIndices++;
1359 }
1360
1361 Lindx.uDataSize = total_data_size;
1362 uNumSubDirs = Lindx.uNumSubIndices;
1363 //move indexes +1 after insert point
1364 if ( !bRewrite_data && (insert_index < uNumSubDirs) )//ïåðåçàïèñûâàíèå ôàéëîâ äëÿ îñâîáîæäåíèÿ ìåñòà äëÿ íîâîãî ô-ëà
1365 {
1366 for( int i = uNumSubDirs; i > insert_index; --i )
1367 memcpy(&pSubIndices[i], &pSubIndices[i - 1], sizeof(LOD::Directory)); //Uninitialized memory access
1368 }
1369 //insert
1370 memcpy(&pSubIndices[insert_index], pDir, sizeof(LOD::Directory));//çàïèñàòü òåêóùèé ôàéë
1371 //correct offsets to data
1372 if (uNumSubDirs > 0)
1373 {
1374 offset_to_data = sizeof(LOD::Directory) * uNumSubDirs;
1375 for ( int i = 0; i < uNumSubDirs; i++ )
1376 {
1377 pSubIndices[i].uOfsetFromSubindicesStart = offset_to_data;
1378 offset_to_data += pSubIndices[i].uDataSize;
1379 }
1380 }
1381
1382 //construct lod file with added data
1383 fwrite(&header, sizeof(LOD::FileHeader), 1, tmp_file);
1384 fwrite(&Lindx, sizeof(LOD::Directory), 1, tmp_file);
1385 fseek(pFile,Lindx.uOfsetFromSubindicesStart, SEEK_SET);
1386 fwrite(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, tmp_file);
1387
1388 offset_to_data = sizeof(LOD::Directory) * uNumSubDirs;
1389 if ( !bRewrite_data )
1390 offset_to_data -= sizeof(LOD::Directory);
1391
1392 fseek(pFile, offset_to_data, SEEK_CUR);
1393 //copy from open lod to temp lod first half
1394 to_copy_size = pSubIndices[insert_index].uOfsetFromSubindicesStart - pSubIndices[0].uOfsetFromSubindicesStart;
1395 while(to_copy_size > 0)
1396 {
1397 read_size = uIOBufferSize;
1398 if ( to_copy_size <= uIOBufferSize )
1399 read_size = to_copy_size;
1400 fread(pIOBuffer, 1, read_size, pFile);
1401 fwrite(pIOBuffer, 1, read_size, tmp_file);
1402 to_copy_size -= read_size;
1403 }
1404 // add container data
1405 fwrite(pDirData, 1, pDir->uDataSize, tmp_file);// Uninitialized memory access(tmp_file)
1406 if ( bRewrite_data )
1407 fseek(pFile,size_correction , SEEK_CUR);
1408
1409 //add remainng data last half
1410 curr_position = ftell(pFile);
1411 fseek(pFile, 0, SEEK_END);
1412 to_copy_size = ftell(pFile) - curr_position;
1413 fseek(pFile, curr_position, SEEK_SET);
1414 while ( to_copy_size > 0 )
1415 {
1416 read_size = uIOBufferSize;
1417 if ( to_copy_size <= uIOBufferSize )
1418 read_size = to_copy_size;
1419 fread(pIOBuffer, 1, read_size, pFile);
1420 fwrite(pIOBuffer, 1, read_size, tmp_file);
1421 to_copy_size -= read_size;
1422 }
1423 //replace old file by new with added data
1424 strcpy(NewFilename, (const char *)&pLODName);
1425 fclose(tmp_file);
1426 fclose(pFile);
1427 CloseWriteFile();
1428 remove(NewFilename);
1429 rename(Filename, NewFilename);
1430 CloseWriteFile();
1431 //reload new
1432 LoadFile((const char *)&pLODName, 0);//isFileOpened == true, next file
1433 return 0;
1434 }
1435
1436 //----- (00461A43) --------------------------------------------------------
1437 bool LODWriteableFile::LoadFile(const char *pFilename, bool bWriting)
1438 {
1439 if (bWriting & 1)
1440 pFile = fopen(pFilename, "rb");
1441 else
1442 pFile = fopen(pFilename, "rb+");
1443 if (!pFile)
1444 {
1445 __debugbreak();
1446 return false;// âîçìîæíî ôàéë íå çàêðûò, ïîýòîìó íå îòêðûâàåòñÿ
1447 }
1448
1449 strcpy(pLODName, pFilename);
1450 fread(&header, sizeof(LOD::FileHeader), 1, pFile);
1451
1452 LOD::Directory lod_indx;
1453 fread( &lod_indx,sizeof(LOD::Directory), 1, pFile);
1454
1455 fseek(pFile, 0, SEEK_SET);
1456 isFileOpened = true;
1457 strcpy(pContainerName, "chapter");
1458 uCurrentIndexDir = 0;
1459 uLODDataSize = lod_indx.uDataSize;
1460 uNumSubDirs = lod_indx.uNumSubIndices;
1461 Assert(uNumSubDirs <= 300);
1462
1463 uOffsetToSubIndex = lod_indx.uOfsetFromSubindicesStart;
1464 fseek(pFile, uOffsetToSubIndex, SEEK_SET);
1465
1466 fread(pSubIndices, sizeof(LOD::Directory), uNumSubDirs, pFile);
1467 return true;
1468 }
1469
1470 //----- (00461A11) --------------------------------------------------------
1471 void LOD::File::FreeSubIndexAndIO()
1472 {
1473 free(pSubIndices);
1474 free(pIOBuffer);// delete [] pIOBuffer;
1475 pIOBuffer = nullptr;
1476 pSubIndices = nullptr;
1477 }
1478
1479 //----- (00461954) --------------------------------------------------------
1480 void LOD::File::AllocSubIndicesAndIO(unsigned int uNumSubIndices, unsigned int uBufferSize)
1481 {
1482 if (pSubIndices)
1483 {
1484 MessageBoxA(0, "Attempt to reset a LOD subindex!", "MM6", MB_ICONEXCLAMATION);
1485 free(pSubIndices);
1486 pSubIndices = nullptr;
1487 }
1488 pSubIndices =(LOD::Directory *)malloc(32 * uNumSubIndices);
1489 if (pIOBuffer)
1490 {
1491 MessageBoxA(0, "Attempt to reset a LOD IObuffer!", "MM6", MB_ICONEXCLAMATION);
1492 free(pIOBuffer);
1493 pIOBuffer = nullptr;
1494 uIOBufferSize = 0;
1495 }
1496 if ( uBufferSize )
1497 {
1498 pIOBuffer = (unsigned __int8 *)malloc(uBufferSize);
1499 uIOBufferSize = uBufferSize;
1500 }
1501 }
1502
1503 //----- (0046188A) --------------------------------------------------------
1504 int LOD::File::LoadSubIndices(const char *pContainer)
1505 {
1506 unsigned int uDir; // edi@1
1507 LOD::Directory *curr_index; // eax@7
1508
1509 ResetSubIndices();
1510 uDir = 0;
1511
1512 for (uDir=0; uDir <header.uNumIndices;++uDir)
1513 {
1514 if (!_stricmp(pContainer, pRoot[uDir].pFilename))
1515 {
1516 strcpy(pContainerName, pContainer);
1517 uCurrentIndexDir = uDir;
1518 curr_index = (LOD::Directory *)&pRoot[uDir];
1519 uOffsetToSubIndex = curr_index->uOfsetFromSubindicesStart ;
1520 uNumSubDirs = curr_index->uNumSubIndices;// *(_WORD *)(v8 + 28);
1521 fseek( pFile, uOffsetToSubIndex, SEEK_SET);
1522 pSubIndices = (LOD::Directory *)malloc(sizeof(LOD::Directory)*(uNumSubDirs + 5));
1523
1524 if ( pSubIndices)
1525 fread( pSubIndices, sizeof(LOD::Directory), uNumSubDirs, pFile);
1526 return 0;
1527 }
1528 }
1529 return 3;
1530 }
1531
1532 //----- (004617D5) --------------------------------------------------------
1533 bool LOD::File::LoadHeader(const char *pFilename, bool bWriting)
1534 {
1535 const char *v6; // [sp-4h] [bp-Ch]@4
1536
1537 if ( this->isFileOpened )
1538 Close();
1539 if ( bWriting & 1 )
1540 v6 = "rb";
1541 else
1542 v6 = "rb+";
1543
1544 pFile = fopen(pFilename, v6);
1545 if ( pFile )
1546 {
1547 strcpy(pLODName, pFilename);
1548 fread(&header, sizeof(LOD::FileHeader), 1, pFile);
1549 pRoot = (LOD::Directory *)malloc(160);
1550 if ( pRoot )
1551 {
1552 fread(pRoot, sizeof(LOD::Directory), header.uNumIndices, pFile);
1553 fseek(pFile, 0, SEEK_SET);
1554 isFileOpened = true;
1555 return false;
1556 }
1557 else
1558 {
1559 fclose(pFile);
1560 return true;
1561 }
1562 }
1563 return true;
1564 }
1565
1566 //----- (00461790) --------------------------------------------------------
1567 LOD::File::~File()
1568 {
1569 if ( this->isFileOpened )
1570 {
1571 fclose(this->pFile);
1572 free(this->pSubIndices);
1573 }
1574 }
1575
1576 //----- (0046175B) --------------------------------------------------------
1577 LOD::File::File():
1578 pRoot(nullptr),
1579 isFileOpened(false)
1580 {
1581 memset(pLODName, 0, 256);
1582 memset(pContainerName, 0, 16);
1583 this->pFile = nullptr;
1584 this->pSubIndices = nullptr;
1585 this->pIOBuffer = nullptr;
1586 this->isFileOpened = false;
1587 this->uIOBufferSize = 0;
1588 Close();
1589 }
1590
1591 //----- (0046172B) --------------------------------------------------------
1592 LOD::Directory::Directory()
1593 {
1594 memset(pFilename, 0, 16);
1595 this->pFilename[0] = 0;
1596 this->uOfsetFromSubindicesStart = 0;
1597 this->uDataSize = 0;
1598 this->uNumSubIndices = 0;
1599 this->dword_000018 = 0;
1600 this->word_00001E = 0;
1601 }
1602
1603 //----- (0046165E) --------------------------------------------------------
1604 int LOD::File::CalcIndexFast(int startIndex, int maxIndex, const char *pContainerName)
1605 {
1606 int pCurrent_position; // esi@1
1607 int v5; // ebx@2
1608 int result; // eax@2
1609
1610 pCurrent_position = startIndex;
1611 while ( 1 ) // binary search in LOD indices
1612 {
1613
1614 while ( 1 )
1615 {
1616 v5 = maxIndex - pCurrent_position;
1617 result = _stricmp(pContainerName, (const char *)(&this->pSubIndices[(maxIndex - pCurrent_position) / 2] + pCurrent_position));
1618 if ( !_stricmp(pContainerName, (const char *)(&this->pSubIndices[(maxIndex - pCurrent_position) / 2] + pCurrent_position)) )
1619 _6A0CA4_lod_binary_search = (maxIndex - pCurrent_position) / 2 + pCurrent_position;
1620 if ( pCurrent_position == maxIndex )
1621 {
1622 _6A0CA4_lod_binary_search = -1;
1623 return result;
1624 }
1625 if ( result < 0 )//ïåðâàÿ ñòðîêà ìåíüøå âòîðîé
1626 break;
1627 if ( v5 <= 4 )
1628 {
1629 for ( int i = pCurrent_position; i < maxIndex; ++i )
1630 {
1631 result = _stricmp(pContainerName, this->pSubIndices[i].pFilename);
1632 if ( !_stricmp(pContainerName, this->pSubIndices[i].pFilename) )
1633 {
1634 _6A0CA4_lod_binary_search = i;
1635 return 0;//ñòðîêè ðîâíû
1636 }
1637 }
1638 _6A0CA4_lod_binary_search = -1;
1639 return result;
1640 }
1641 pCurrent_position += (maxIndex - pCurrent_position) / 2;
1642 }
1643
1644 if ( v5 <= 4 )
1645 break;
1646 maxIndex = (maxIndex - pCurrent_position) / 2 + pCurrent_position;
1647 }
1648
1649 for (int i = pCurrent_position; i < maxIndex; ++i)
1650 {
1651 result = _stricmp(pContainerName, this->pSubIndices[i].pFilename);
1652 if ( !_stricmp(pContainerName, this->pSubIndices[i].pFilename) )
1653 {
1654 _6A0CA4_lod_binary_search = i;
1655 return 0;
1656 }
1657 }
1658 _6A0CA4_lod_binary_search = -1;
1659 return result;
1660 }
1661 // 6A0CA4: using guessed type int _6A0CA4_lod_binary_search;
1662
1663 //----- (0046161C) --------------------------------------------------------
1664 bool LOD::File::DoesContainerExist(const char *pContainer)
1665 {
1666 for ( int i = 0; i < (signed int)this->uNumSubDirs; ++i )
1667 {
1668 if ( !_stricmp(pContainer, this->pSubIndices[i].pFilename) )
1669 return 1;
1670 }
1671 return 0;
1672 }
1673
1674 //----- (00461397) --------------------------------------------------------
1675 int LODFile_Sprites::_461397()
1676 {
1677 this->field_ECA8 = this->uNumLoadedSprites;
1678 if ( this->uNumLoadedSprites < this->field_ECA0 )
1679 this->field_ECA8 = this->field_ECA0;
1680 if ( this->field_ECA0 < this->field_ECA4 )
1681 field_ECA0 = this->field_ECA4;
1682 return this->uNumLoadedSprites;
1683 }
1684
1685 //----- (00461580) --------------------------------------------------------
1686 FILE *LOD::File::FindContainer(const char *pContainer_Name, bool bLinearSearch)
1687 {
1688 if (!isFileOpened)
1689 return 0;
1690
1691 if (bLinearSearch)
1692 {
1693 for (uint i = 0; i < uNumSubDirs; ++i)
1694 if (!_stricmp(pContainer_Name, pSubIndices[i].pFilename))
1695 {
1696 fseek(pFile, uOffsetToSubIndex + pSubIndices[i].uOfsetFromSubindicesStart, SEEK_SET);
1697 return pFile;
1698 }
1699 return nullptr;
1700 }
1701 else
1702 {
1703 CalcIndexFast(0, uNumSubDirs, pContainer_Name);
1704 if ( _6A0CA4_lod_binary_search < 0 )
1705 return 0;
1706 fseek(pFile, uOffsetToSubIndex + pSubIndices[_6A0CA4_lod_binary_search].uOfsetFromSubindicesStart, SEEK_SET);
1707 return pFile;
1708 }
1709 }
1710
1711 //----- (0041097D) --------------------------------------------------------
1712 void LODFile_IconsBitmaps::SetupPalettes(unsigned int uTargetRBits, unsigned int uTargetGBits, unsigned int uTargetBBits)
1713 {
1714 FILE *File; // [sp+50h] [bp-4h]@7
1715
1716 if ( this->uTextureRedBits != uTargetRBits
1717 || this->uTextureGreenBits != uTargetGBits
1718 || this->uTextureBlueBits != uTargetBBits ) //Uninitialized memory access
1719 {
1720 this->uTextureRedBits = uTargetRBits;
1721 this->uTextureGreenBits = uTargetGBits;
1722 this->uTextureBlueBits = uTargetBBits;
1723 for ( uint i = 0; i < this->uNumLoadedFiles; ++i )
1724 {
1725 Texture DstBuf; // [sp+4h] [bp-50h]@6
1726 //Texture::Texture(&DstBuf);
1727 if ( this->pTextures[i].pPalette16 )
1728 {
1729 File = FindContainer((const char *)this->pTextures[i].pName, 0);
1730 if ( File )
1731 {
1732 fread(&DstBuf, 1, 0x30u, File);
1733 fseek(File, DstBuf.uTextureSize, 1);
1734 for ( uint j = 0; j < 256; ++j )
1735 {
1736 fread((char *)&uTargetRBits + 3, 1, 1, File);
1737 fread((char *)&uTargetGBits + 3, 1, 1, File);
1738 fread((char *)&uTargetBBits + 3, 1, 1, File);
1739 this->pTextures[i].pPalette16[j] = (BYTE3(uTargetRBits) >> (8 - LOBYTE(this->uTextureRedBits)))
1740 << (LOBYTE(this->uTextureGreenBits) + LOBYTE(this->uTextureBlueBits));
1741 this->pTextures[i].pPalette16[j] |= (BYTE3(uTargetGBits) >> (8 - LOBYTE(this->uTextureGreenBits)))
1742 << this->uTextureBlueBits;
1743 this->pTextures[i].pPalette16[j] |= BYTE3(uTargetBBits) >> (8 - LOBYTE(this->uTextureBlueBits));
1744 }
1745 }
1746 }
1747 }
1748 }
1749 }
1750
1751 //----- (0041088B) --------------------------------------------------------
1752 void *LOD::File::LoadRaw(const char *pContainer, int a3)
1753 {
1754 FILE *File; // eax@1
1755 void *v7; // ebx@7
1756 void *v8; // edi@7
1757 Texture DstBuf; // [sp+Ch] [bp-4Ch]@1
1758
1759 File = FindContainer(pContainer, 0);
1760 if ( !File )
1761 Error("Unable to load %s", pContainer);
1762
1763 fread(&DstBuf, 1, 0x30u, File);
1764 if ( DstBuf.uDecompressedSize )
1765 {
1766 if ( a3 )
1767 v7 = malloc(DstBuf.uDecompressedSize+1);
1768 else
1769 v7 = malloc(DstBuf.uDecompressedSize+1);
1770 v8 = malloc(DstBuf.uTextureSize+1);
1771 fread(v8, 1, DstBuf.uTextureSize, File);
1772 zlib::MemUnzip(v7, &DstBuf.uDecompressedSize, v8, DstBuf.uTextureSize);
1773 DstBuf.uTextureSize = DstBuf.uDecompressedSize;
1774 free(v8);
1775 }
1776 else
1777 {
1778 if ( a3 )
1779 v7 = malloc(DstBuf.uTextureSize+1);
1780 else
1781 v7 = malloc(DstBuf.uTextureSize+1);
1782 fread(v7, 1, DstBuf.uTextureSize, File);
1783 }
1784 return v7;
1785 }
1786
1787 //----- (00410522) --------------------------------------------------------
1788 int LODFile_IconsBitmaps::_410522(Texture *pDst, const char *pContainer, unsigned int uTextureType)
1789 {
1790 void *v9; // ST2C_4@6
1791 int v15; // ecx@12
1792 int v16; // ecx@12
1793 int v17; // eax@12
1794 signed int v21; // ecx@18
1795 signed int v22; // ecx@23
1796 FILE *File; // [sp+68h] [bp-4h]@1
1797 unsigned int uTargetRBits;
1798 unsigned int uTargetGBits;
1799 unsigned int uTargetBBits;
1800
1801 File = FindContainer(pContainer, 0);
1802 if ( !File )
1803 {
1804 File = FindContainer("pending", 0);
1805 if ( !File )
1806 Error("Can't find %s!", pContainer);
1807 }
1808
1809 fread(pDst, 1, 0x30u, File);
1810 strcpy(pDst->pName, pContainer);
1811 pDst->pLevelOfDetail0_prolly_alpha_mask = 0;
1812 if ( pDst->uDecompressedSize )
1813 {
1814 pDst->pLevelOfDetail0_prolly_alpha_mask = (unsigned __int8 *)malloc(pDst->uDecompressedSize);
1815 v9 = malloc(pDst->uTextureSize);
1816 fread((void *)v9, 1, (size_t)pDst->uTextureSize, File);
1817 zlib::MemUnzip(pDst->pLevelOfDetail0_prolly_alpha_mask, &pDst->uDecompressedSize, v9, pDst->uTextureSize);
1818 pDst->uTextureSize = pDst->uDecompressedSize;
1819 free(v9);
1820 }
1821 else
1822 {
1823 pDst->pLevelOfDetail0_prolly_alpha_mask = (unsigned __int8 *)malloc(0);
1824 fread(pDst->pLevelOfDetail0_prolly_alpha_mask, 1, (size_t)pDst->uTextureSize, File);
1825 }
1826 pDst->pPalette16 = 0;
1827 pDst->pPalette24 = 0;
1828 if ( uTextureType == 1 )
1829 {
1830 pDst->pPalette24 = (unsigned __int8 *)malloc(0x300u);
1831 fread(pDst->pPalette24, 1, 0x300u, File);
1832 }
1833 else if ( uTextureType == 2 )
1834 {
1835 pDst->pPalette16 = (unsigned __int16 *)malloc(0x400u);
1836 for ( uint i = 0; i < 256; ++i )
1837 {
1838 fread((char *)&uTargetRBits + 3, 1, 1, File);
1839 fread((char *)&uTargetGBits + 3, 1, 1, File);
1840 fread((char *)&uTargetBBits + 3, 1, 1, File);
1841 pDst->pPalette16[i] = (unsigned __int8)(BYTE3(uTargetRBits) >> (8 - LOBYTE(this->uTextureRedBits)))
1842 << (LOBYTE(this->uTextureBlueBits) + LOBYTE(this->uTextureGreenBits));
1843 pDst->pPalette16[i] += (unsigned __int8)(BYTE3(uTargetGBits) >> (8 - LOBYTE(this->uTextureGreenBits)))
1844 << this->uTextureBlueBits;
1845 pDst->pPalette16[i] += (unsigned __int8)(BYTE3(uTargetBBits) >> (8 - LOBYTE(this->uTextureBlueBits)));
1846 }
1847 }
1848
1849 if ( pDst->pBits & 2 )
1850 {
1851 v15 = (int)&pDst->pLevelOfDetail0_prolly_alpha_mask[pDst->uSizeOfMaxLevelOfDetail];
1852 pDst->pLevelOfDetail1 = (unsigned __int8 *)v15;
1853 v16 = (pDst->uSizeOfMaxLevelOfDetail >> 2) + v15;
1854 pDst->pLevelOfDetail2 = (unsigned __int8 *)v16;
1855 v17 = v16 + (pDst->uSizeOfMaxLevelOfDetail >> 4);
1856 }
1857 else
1858 {
1859 v17 = 0;
1860 pDst->pLevelOfDetail2 = 0;
1861 pDst->pLevelOfDetail1 = 0;
1862 }
1863 pDst->pLevelOfDetail3 = (unsigned __int8 *)v17;
1864 v21 = 1;
1865 while ( 1 << v21 != pDst->uTextureWidth )
1866 {
1867 ++v21;
1868 if ( v21 >= 15 )
1869 goto LABEL_23;
1870 }
1871 pDst->uWidthLn2 = v21;
1872 LABEL_23:
1873 v22 = 1;
1874 while ( 1 << v22 != pDst->uTextureHeight )
1875 {
1876 ++v22;
1877 if ( v22 >= 15 )
1878 goto LABEL_28;
1879 }
1880 pDst->uHeightLn2 = v22;
1881 LABEL_28:
1882 switch ( pDst->uWidthLn2 )
1883 {
1884 case 2:
1885 pDst->uWidthMinus1 = 3;
1886 break;
1887 case 3:
1888 pDst->uWidthMinus1 = 7;
1889 break;
1890 case 4:
1891 pDst->uWidthMinus1 = 15;
1892 break;
1893 case 5:
1894 pDst->uWidthMinus1 = 31;
1895 break;
1896 case 6:
1897 pDst->uWidthMinus1 = 63;
1898 break;
1899 case 7:
1900 pDst->uWidthMinus1 = 127;
1901 break;
1902 case 8:
1903 pDst->uWidthMinus1 = 255;
1904 break;
1905 case 9:
1906 pDst->uWidthMinus1 = 511;
1907 break;
1908 case 10:
1909 pDst->uWidthMinus1 = 1023;
1910 break;
1911 case 11:
1912 pDst->uWidthMinus1 = 2047;
1913 break;
1914 case 12:
1915 pDst->uWidthMinus1 = 4095;
1916 break;
1917 default:
1918 break;
1919 }
1920 switch ( pDst->uHeightLn2 )
1921 {
1922 case 2:
1923 pDst->uHeightMinus1 = 3;
1924 break;
1925 case 3:
1926 pDst->uHeightMinus1 = 7;
1927 break;
1928 case 4:
1929 pDst->uHeightMinus1 = 15;
1930 break;
1931 case 5:
1932 pDst->uHeightMinus1 = 31;
1933 break;
1934 case 6:
1935 pDst->uHeightMinus1 = 63;
1936 break;
1937 case 7:
1938 pDst->uHeightMinus1 = 127;
1939 break;
1940 case 8:
1941 pDst->uHeightMinus1 = 255;
1942 break;
1943 case 9:
1944 pDst->uHeightMinus1 = 511;
1945 break;
1946 case 10:
1947 pDst->uHeightMinus1 = 1023;
1948 break;
1949 case 11:
1950 pDst->uHeightMinus1 = 2047;
1951 break;
1952 case 12:
1953 pDst->uHeightMinus1 = 4095;
1954 break;
1955 default:
1956 return 1;
1957 }
1958 return 1;
1959 }
1960
1961 //----- (00410423) --------------------------------------------------------
1962 void LODFile_IconsBitmaps::_410423_move_textures_to_device()
1963 {
1964 size_t v4; // eax@9
1965 char *v5; // ST1C_4@9
1966
1967 for ( uint i = 0; i < this->uNumLoadedFiles; i++ )
1968 {
1969 if ( this->ptr_011BB4[i] )
1970 {
1971 if ( this->pTextures[i].pName[0] != 'w' || this->pTextures[i].pName[1] != 't'
1972 || this->pTextures[i].pName[2] != 'r' || this->pTextures[i].pName[3] != 'd' || this->pTextures[i].pName[4] != 'r' )
1973 pRenderer->LoadTexture(&this->pTextures[i].pName[0], this->pTextures[i].uTextureSize, (IDirectDrawSurface4 **)&this->pHardwareSurfaces[i],
1974 &this->pHardwareTextures[i]);
1975 else
1976 {
1977 v4 = strlen(&this->pTextures[i].pName[0]);
1978 v5 = (char *)malloc(v4 + 2);
1979 *v5 = 'h';
1980 strcpy(v5 + 1, &this->pTextures[i].pName[0]);
1981 pRenderer->LoadTexture(v5, this->pTextures[i].uTextureSize, (IDirectDrawSurface4 **)&this->pHardwareSurfaces[i], &this->pHardwareTextures[i]);
1982 free(v5);
1983 }
1984 }
1985 }
1986 if ( this->ptr_011BB4 )
1987 {
1988 if ( this->uNumLoadedFiles > 1 )
1989 memset(this->ptr_011BB4, 0, this->uNumLoadedFiles - 1);
1990 }
1991 }
1992
1993 //----- (004103BB) --------------------------------------------------------
1994 void LODFile_IconsBitmaps::ReleaseHardwareTextures()
1995 {
1996 for ( uint i = 0; i < this->uNumLoadedFiles; i++ )
1997 {
1998 if ( this->pHardwareTextures )
1999 {
2000 if ( this->pHardwareTextures[i] )
2001 {
2002 this->pHardwareTextures[i]->Release();
2003 this->pHardwareTextures[i] = 0;
2004 this->ptr_011BB4[i] = 1;
2005 }
2006 }
2007 if ( this->pHardwareSurfaces )
2008 {
2009 if ( this->pHardwareSurfaces[i] )
2010 {
2011 this->pHardwareSurfaces[i]->Release();
2012 this->pHardwareSurfaces[i] = 0;
2013 this->ptr_011BB4[i] = 1;
2014 }
2015 }
2016 }
2017 }
2018
2019 //----- (0041033D) --------------------------------------------------------
2020 void LODFile_IconsBitmaps::ReleaseLostHardwareTextures()
2021 {
2022 for ( uint i = 0; i < this->uNumLoadedFiles; ++i )
2023 {
2024 if ( this->pHardwareSurfaces )
2025 {
2026 if ( this->pHardwareSurfaces[i] )
2027 {
2028 if ( this->pHardwareSurfaces[i]->IsLost() == DDERR_SURFACELOST )
2029 {
2030 if ( this->pHardwareTextures )
2031 {
2032 if ( this->pHardwareTextures[i] )
2033 {
2034 this->pHardwareTextures[i]->Release();
2035 this->pHardwareTextures[i] = 0;
2036 }
2037 }
2038 this->pHardwareSurfaces[i]->Release();
2039 this->pHardwareSurfaces[i] = 0;
2040 this->ptr_011BB4[i] = 1;
2041 }
2042 }
2043 }
2044 }
2045 }
2046
2047 //----- (004101B1) --------------------------------------------------------
2048 int LODFile_IconsBitmaps::ReloadTexture(Texture *pDst, const char *pContainer, int mode)
2049 {
2050 Texture *v6; // esi@2
2051 unsigned int v7; // ebx@6
2052 unsigned int v8; // ecx@6
2053 signed int result; // eax@7
2054 FILE *File; // [sp+Ch] [bp-8h]@1
2055 unsigned __int8 v15; // [sp+11h] [bp-3h]@13
2056 unsigned __int8 v16; // [sp+12h] [bp-2h]@13
2057 unsigned __int8 DstBuf; // [sp+13h] [bp-1h]@13
2058 void *DstBufa; // [sp+1Ch] [bp+8h]@10
2059 void *Sourcea; // [sp+20h] [bp+Ch]@10
2060
2061 File = FindContainer(pContainer, 0);
2062 v6 = pDst;
2063 if ( File && pDst->pLevelOfDetail0_prolly_alpha_mask
2064 && mode == 2
2065 && pDst->pPalette16 && !pDst->pPalette24
2066 && (v7 = pDst->uTextureSize,
2067 fread(pDst, 1, 0x30u, File),
2068 strcpy(pDst->pName, pContainer),
2069 v8 = pDst->uTextureSize,
2070 (signed int)v8 <= (signed int)v7) )
2071 {
2072 if ( !pDst->uDecompressedSize || this->dword_011BA4 )
2073 {
2074 fread(pDst->pLevelOfDetail0_prolly_alpha_mask, 1, pDst->uTextureSize, File);
2075 }
2076 else
2077 {
2078 Sourcea = malloc(pDst->uDecompressedSize);
2079 DstBufa = malloc(pDst->uTextureSize);
2080 fread(DstBufa, 1, pDst->uTextureSize, File);
2081 zlib::MemUnzip(Sourcea, &v6->uDecompressedSize, DstBufa, v6->uTextureSize);
2082 v6->uTextureSize = pDst->uDecompressedSize;
2083 free(DstBufa);
2084 memcpy(v6->pLevelOfDetail0_prolly_alpha_mask, Sourcea, pDst->uDecompressedSize);
2085 free(Sourcea);
2086 }
2087 for( uint i = 0; i < 256; ++i )
2088 {
2089 fread(&DstBuf, 1, 1, File);
2090 fread(&v16, 1, 1, File);
2091 fread(&v15, 1, 1, File);
2092 v6->pPalette16[i] = (unsigned __int8)(DstBuf >> (8 - LOBYTE(this->uTextureRedBits)))
2093 << (LOBYTE(this->uTextureBlueBits) + LOBYTE(this->uTextureGreenBits));
2094 v6->pPalette16[i] += (unsigned __int8)(v16 >> (8 - LOBYTE(this->uTextureGreenBits)))
2095 << this->uTextureBlueBits;
2096 v6->pPalette16[i] += (unsigned __int8)(v15 >> (8 - LOBYTE(this->uTextureBlueBits)));
2097 }
2098 result = 1;
2099 }
2100 else
2101 result = -1;
2102 return result;
2103 }
2104
2105 //----- (0040FC08) --------------------------------------------------------
2106 int LODFile_IconsBitmaps::LoadTextureFromLOD(Texture *pOutTex, const char *pContainer, enum TEXTURE_TYPE eTextureType)
2107 {
2108 Texture *v8; // esi@3
2109 enum TEXTURE_TYPE v12; // eax@14
2110 signed int result; // esi@14
2111 unsigned int v14; // eax@21
2112 void *v19; // ST3C_4@27
2113 size_t v22; // ST2C_4@29
2114 const void *v23; // ecx@29
2115 void *v30; // eax@30
2116 signed int v41; // ecx@43
2117 signed int v42; // ecx@48
2118
2119 FILE* pFile = FindContainer(pContainer, false);
2120 if (!pFile)
2121 return -1;
2122 v8 = pOutTex;
2123 fread(pOutTex, 1, 0x30, pFile);
2124 strcpy(pOutTex->pName, pContainer);
2125 if (/*pRenderer->pRenderD3D &&*/ (pOutTex->pBits & 2) && strcmp(v8->pName, "sptext01"))//Ritor1: "&& strcmp(v8->pName, "sptext01")" - temporarily for red_aura
2126 {
2127 if (!pHardwareSurfaces || !pHardwareTextures)
2128 {
2129 pHardwareSurfaces = new IDirectDrawSurface *[1000];
2130 memset(pHardwareSurfaces, 0, 1000 * sizeof(IDirectDrawSurface4 *));
2131
2132 pHardwareTextures = new IDirect3DTexture2 *[1000];
2133 memset(pHardwareTextures, 0, 1000 * sizeof(IDirect3DTexture2 *));
2134
2135 ptr_011BB4 = new char[1000];
2136 memset(ptr_011BB4, 0, 1000);
2137 }
2138 if (_strnicmp(pContainer, "wtrdr", 5))
2139 {
2140 if (_strnicmp(pContainer, "WtrTyl", 6))
2141 v14 = uNumLoadedFiles;
2142 else
2143 {
2144 pRenderer->hd_water_tile_id = uNumLoadedFiles;
2145 v14 = uNumLoadedFiles;
2146 }
2147 result = pRenderer->LoadTexture(pContainer, pOutTex->palette_id1, (IDirectDrawSurface4 **)&pHardwareSurfaces[v14], &pHardwareTextures[v14]);
2148 }
2149 else
2150 {
2151 char *temp_container;
2152 temp_container = (char *)malloc(strlen(pContainer) + 2);
2153 *temp_container = 104;//'h'
2154 strcpy(temp_container + 1, pContainer);
2155 result = pRenderer->LoadTexture((const char *)temp_container, pOutTex->palette_id1,
2156 (IDirectDrawSurface4 **)&pHardwareSurfaces[uNumLoadedFiles], &pHardwareTextures[uNumLoadedFiles]);
2157 free((void *)temp_container);
2158 }
2159 return result;
2160 }
2161 if ( !v8->uDecompressedSize || dword_011BA4 )
2162 {
2163 v8->pLevelOfDetail0_prolly_alpha_mask = (unsigned __int8 *)malloc(v8->uTextureSize);
2164 fread(v8->pLevelOfDetail0_prolly_alpha_mask, 1, (size_t)v8->uTextureSize, pFile);
2165 }
2166 else
2167 {
2168 pContainer = (const char *)malloc(v8->uDecompressedSize);
2169 v19 = malloc(v8->uTextureSize);
2170 fread(v19, 1, (size_t)v8->uTextureSize, pFile);
2171 zlib::MemUnzip((void *)pContainer, &v8->uDecompressedSize, v19, v8->uTextureSize);
2172 v8->uTextureSize = v8->uDecompressedSize;
2173 free(v19);
2174 if ( /*bUseLoResSprites*/false && v8->pBits & 2 )
2175 {
2176 pOutTex = (Texture *)(((signed int)v8->uSizeOfMaxLevelOfDetail >> 2)
2177 + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 4)
2178 + ((signed int)v8->uSizeOfMaxLevelOfDetail >> 6));
2179 v22 = (size_t)pOutTex;
2180 v23 = &pContainer[v8->uTextureWidth * v8->uTextureHeight];
2181 v8->pLevelOfDetail0_prolly_alpha_mask = (unsigned __int8 *)malloc((unsigned int)pOutTex);
2182 memcpy(v8->pLevelOfDetail0_prolly_alpha_mask, v23, v22);
2183 v8->uTextureWidth = (signed __int16)v8->uTextureWidth / 2;
2184 v8->uTextureHeight = (signed __int16)v8->uTextureHeight / 2;
2185 --v8->uWidthLn2;
2186 --v8->uHeightLn2;
2187 v8->uWidthMinus1 = v8->uTextureWidth - 1;
2188 v8->uHeightMinus1 = v8->uTextureHeight - 1;
2189 v8->uSizeOfMaxLevelOfDetail = (signed __int16)v8->uTextureWidth * (signed __int16)v8->uTextureHeight;
2190 v8->uTextureSize = (unsigned int)pOutTex;
2191 }
2192 else
2193 {
2194 v8->pLevelOfDetail0_prolly_alpha_mask = (unsigned __int8 *)malloc(v8->uDecompressedSize);
2195 memcpy(v8->pLevelOfDetail0_prolly_alpha_mask, pContainer, v8->uDecompressedSize);
2196 }
2197 free((void *)pContainer);
2198 }
2199
2200 free(v8->pPalette16);
2201 v8->pPalette16 = NULL;
2202
2203 free(v8->pPalette24);
2204 v8->pPalette24 = NULL;
2205
2206 if ( eTextureType == TEXTURE_24BIT_PALETTE )
2207 {
2208 v8->pPalette24 = (unsigned __int8 *)malloc(0x300);
2209 fread(v8->pPalette24, 1, 0x300, pFile);
2210 }
2211 else
2212 {
2213 if ( eTextureType == TEXTURE_16BIT_PALETTE )
2214 {
2215 v8->pPalette16 = (unsigned __int16 *)malloc(0x200);
2216 for ( uint i = 0; i < 256; ++i )
2217 {
2218 fread((char *)&eTextureType + 3, 1, 1, pFile);
2219 fread((char *)&pContainer + 3, 1, 1, pFile);
2220 fread((char *)&pOutTex + 3, 1, 1, pFile);
2221 v8->pPalette16[i] = (unsigned __int8)(BYTE3(eTextureType) >> (8 - LOBYTE(this->uTextureRedBits))) //Uninitialized memory access
2222 << (LOBYTE(this->uTextureBlueBits) + LOBYTE(this->uTextureGreenBits));
2223 v8->pPalette16[i] += (unsigned __int8)(BYTE3(pContainer) >> (8 - LOBYTE(this->uTextureGreenBits)))
2224 << this->uTextureBlueBits;
2225 v8->pPalette16[i] += (unsigned __int8)(BYTE3(pOutTex) >> (8 - LOBYTE(this->uTextureBlueBits)));
2226 }
2227 }
2228 }
2229
2230 if ( v8->pBits & 2 )
2231 {
2232 v8->pLevelOfDetail1 = &v8->pLevelOfDetail0_prolly_alpha_mask[v8->uSizeOfMaxLevelOfDetail];
2233 v8->pLevelOfDetail2 = &v8->pLevelOfDetail1[v8->uSizeOfMaxLevelOfDetail >> 2];
2234 v8->pLevelOfDetail3 = &v8->pLevelOfDetail2[v8->uSizeOfMaxLevelOfDetail >> 4];
2235 }
2236 else
2237 {
2238 v8->pLevelOfDetail1 = 0;
2239 v8->pLevelOfDetail2 = 0;
2240 v8->pLevelOfDetail3 = 0;
2241 }
2242 for ( v41 = 1; v41 < 15; ++v41 )
2243 {
2244 if ( 1 << v41 == v8->uTextureWidth )
2245 v8->uWidthLn2 = v41;
2246 }
2247 for ( v42 = 1; v42 < 15; ++v42 )
2248 {
2249 if ( 1 << v42 == v8->uTextureHeight )
2250 v8->uHeightLn2 = v42;
2251 }
2252
2253 switch ( v8->uWidthLn2 )
2254 {
2255 case 2:
2256 v8->uWidthMinus1 = 3;
2257 break;
2258 case 3:
2259 v8->uWidthMinus1 = 7;
2260 break;
2261 case 4:
2262 v8->uWidthMinus1 = 15;
2263 break;
2264 case 5:
2265 v8->uWidthMinus1 = 31;
2266 break;
2267 case 6:
2268 v8->uWidthMinus1 = 63;
2269 break;
2270 case 7:
2271 v8->uWidthMinus1 = 127;
2272 break;
2273 case 8:
2274 v8->uWidthMinus1 = 255;
2275 break;
2276 case 9:
2277 v8->uWidthMinus1 = 511;
2278 break;
2279 case 10:
2280 v8->uWidthMinus1 = 1023;
2281 break;
2282 case 11:
2283 v8->uWidthMinus1 = 2047;
2284 break;
2285 case 12:
2286 v8->uWidthMinus1 = 4095;
2287 break;
2288 default:
2289 break;
2290 }
2291 switch ( v8->uHeightLn2 )
2292 {
2293 case 2:
2294 v8->uHeightMinus1 = 3;
2295 break;
2296 case 3:
2297 v8->uHeightMinus1 = 7;
2298 break;
2299 case 4:
2300 v8->uHeightMinus1 = 15;
2301 break;
2302 case 5:
2303 v8->uHeightMinus1 = 31;
2304 break;
2305 case 6:
2306 v8->uHeightMinus1 = 63;
2307 break;
2308 case 7:
2309 v8->uHeightMinus1 = 127;
2310 break;
2311 case 8:
2312 v8->uHeightMinus1 = 255;
2313 break;
2314 case 9:
2315 v8->uHeightMinus1 = 511;
2316 break;
2317 case 10:
2318 v8->uHeightMinus1 = 1023;
2319 break;
2320 case 11:
2321 v8->uHeightMinus1 = 2047;
2322 break;
2323 case 12:
2324 v8->uHeightMinus1 = 4095;
2325 break;
2326 default:
2327 return 1;
2328 }
2329 return 1;
2330 }
2331
2332 Texture *LODFile_IconsBitmaps::LoadTexturePtr(const char *pContainer, enum TEXTURE_TYPE uTextureType)
2333 {
2334 uint id = LoadTexture(pContainer, uTextureType);
2335
2336 Assert(id != -1 && L"Texture not found");
2337
2338 return &pTextures[id];
2339 }
2340
2341 //----- (0040FB20) --------------------------------------------------------
2342 unsigned int LODFile_IconsBitmaps::LoadTexture(const char *pContainer, enum TEXTURE_TYPE uTextureType)
2343 {
2344 areWeLoadingTexture = 1;
2345
2346 //check loaded texture?
2347 for (uint i = 0; i < uNumLoadedFiles; ++i)
2348 {
2349 if (!_stricmp(pContainer, pTextures[i].pName))
2350 return i;
2351 }
2352
2353 // if (!uNumLoadedFiles)
2354 // {
2355 //LABEL_5:
2356 Assert(uNumLoadedFiles < 1000);
2357 /*if (uNumLoadedFiles >= 1000)
2358 {
2359 Log::Warning(L"Maximum texture number exceeded");
2360 AbortWithError();
2361 }*/
2362 if (LoadTextureFromLOD(&pTextures[uNumLoadedFiles], pContainer, uTextureType) == -1)
2363 {
2364 for ( uint i = 0; i < uNumLoadedFiles; ++i )
2365 {
2366 if (!_stricmp(pTextures[i].pName, "pending"))
2367 return i;
2368 }
2369 LoadTextureFromLOD(&pTextures[uNumLoadedFiles], "pending", uTextureType);
2370 }
2371 areWeLoadingTexture = 0;
2372 ++uNumLoadedFiles;
2373 return uNumLoadedFiles - 1;
2374 // }
2375 // v5 = pTextures;
2376 // while ( _stricmp(v5->pName, pContainer) )
2377 // {
2378 // ++v4;
2379 // ++v5;
2380 // if (v4 >= uNumLoadedFiles )
2381 // goto LABEL_5;
2382 // }
2383 // return v4;
2384 }
2385
2386 Texture * LODFile_IconsBitmaps::GetTexture( int idx )
2387 {
2388 Assert(idx < MAX_LOD_TEXTURES, "Texture index out of bounds (%u)", idx);
2389 if (idx == -1)
2390 {
2391 //Log::Warning(L"Texture id = %d missing", idx);
2392 return pTextures + LoadDummyTexture();
2393 }
2394 return pTextures + idx;
2395 }
2396
2397 //----- (0046082C) --------------------------------------------------------
2398 bool Initialize_GamesLOD_NewLOD()
2399 {
2400 pGames_LOD = new LODWriteableFile;
2401 pGames_LOD->AllocSubIndicesAndIO(300, 0);
2402 if (pGames_LOD->LoadFile("data\\games.lod", 1))
2403 {
2404 pNew_LOD = new LODWriteableFile;
2405 pNew_LOD->AllocSubIndicesAndIO(300, 100000);
2406 return true;
2407 }
2408 return false;
2409 }