1 #define _CRT_SECURE_NO_DEPRECATE
16 #include "mpq_libmpq.h"
18 unsigned int iRes
=256;
21 extern uint32 maxAreaId
;
28 int holetab_h
[4] = {0x1111, 0x2222, 0x4444, 0x8888};
29 int holetab_v
[4] = {0x000F, 0x00F0, 0x0F00, 0xF000};
31 bool LoadADT(char* filename
)
38 //printf("No such file %s\n",filename);
46 size_t mcnk_offsets
[256], mcnk_sizes
[256];
51 MH2O_presence
= false;
60 size_t nextpos
= mf
.getPos() + size
;
62 //if(fourcc==0x4d484452) // MHDR header
63 //if(fourcc==0x4d564552) // MVER
64 if(fourcc
==0x4d43494e) // MCIN
66 for (int i
=0; i
<256; ++i
)
68 mf
.read(&mcnk_offsets
[i
],4);
69 mf
.read(&mcnk_sizes
[i
],4);
73 //if(fourcc==0x4d544558) // MTEX textures (strings)
74 //if(fourcc==0x4d4d4458) // MMDX m2 models (strings)
75 //if(fourcc==0x4d4d4944) // MMID offsets for strings in MMDX
76 //if(fourcc==0x4d574d4f) // MWMO
77 //if(fourcc==0x4d574944) // MWID offsets for strings in MWMO
78 //if(fourcc==0x4d444446) // MDDF
79 //if(fourcc==0x4d4f4446) // MODF
80 if(fourcc
==0x4d48324f && size
) // MH2O new in WotLK
83 // çäåñü íàäî çàïîìíèòü áàçîâóþ ïîçèöèþ â ôàéëå òê âñå ñìåùåíèÿ áóäóò îò íåãî
84 uint32 base_pos
= mf
.getPos();
85 uint32 header_pos
= 0;
86 LiqOffsData
= new MH2O_offsData
;
87 LiqChunkData1
= new MH2O_Data1
;
88 ChunkLiqHeight
= new float[81];
89 for(;chunk_num
< 256; ++chunk_num
)
91 mf
.read(LiqOffsData
,12);
92 header_pos
= mf
.getPos();
93 if(LiqOffsData
->offsData1
!=0) // åñëè äàííûå â Data1 î âîäå åñòü, òî èõ íàäî êîíâåðòèðîâàòü
95 // ïåðåõîäèì ïî ñìåùåíèþ èç offsData1 ÎÒ ÍÀ×ÀËÀ êóñêà
96 mf
.seek(base_pos
+ LiqOffsData
->offsData1
);
97 mf
.read(LiqChunkData1
,24); // ñ÷èòûâàåì ñàìè äàííûå â ñòðóêòóðó òèïà MH2O_Data1
98 // çàíîñèì äàííûå ôëàãà äëÿ êóñêà
99 if(LiqChunkData1
->flags
& 4 || LiqChunkData1
->flags
& 8)
100 MapLiqFlag
[chunk_num
] |= 1;
101 if(LiqChunkData1
->flags
& 16)
102 MapLiqFlag
[chunk_num
] |= 2;
103 // ïðåäâàðèòåëüíî çàïîëíÿåì âåñü êóñîê äàííûìè - íåò âîäû
104 for(int j
=0;j
<81;++j
)
106 ChunkLiqHeight
[j
] = -999999; // no liquid/water
108 // òåïåðü âû÷èñëÿåì òå ÷òî ñ âîäîé è ïåðåçàïèñûâàåì èõ â êóñêå
109 for(int b
=0; b
<= LiqChunkData1
->height
; ++b
)
111 for(int c
=LiqChunkData1
->xOffset
; c
<= (LiqChunkData1
->xOffset
+LiqChunkData1
->width
); ++c
)
113 int n
= (9*(LiqChunkData1
->yOffset
+ b
))+c
;
114 ChunkLiqHeight
[n
] = LiqChunkData1
->heightLevel1
;
117 mf
.seek(header_pos
); // è íå çàáûòü âåðíóòüñÿ íà èñõîäíóþ ïîçèöèþ èìåííî Â ÕÈÄÅÐÅ
119 else // åñëè äàííûõ â Data1 íåò, òî íàäî çàïîëíèòü âåñü êóñîê, íî äàííûìè - íåò âîäû
121 for(int j
=0; j
<81; ++j
)
122 ChunkLiqHeight
[j
] = -999999; // no liquid/water
125 m
= 1024*(chunk_num
/16); // ñìåùåíèå ïî ðÿäàì êóñêîâ ñ ïåðåêðûòèåì = 1024
126 k
= m
+(chunk_num
%16)*8; // óñòàíàâëèâàåìñÿ íà íà÷àëüíûé èíäåêñ äëÿ çàïîëíåíèÿ ðÿäà
127 // çàíîñèì äàííûå êóñêà â ìàññèâ äëÿ êàðòû, ñ ïåðåêðûòèåì è îáðåçàíèåì êóñêîâ òê äàííûõ 81
128 // ýòî àíàëîã ñòàðîãî îáðåçàíèÿ ãðàíè÷íûõ ïðàâûõ-áîêîâûõ è íèæíèõ äàííûõ
129 for(int p
=0;p
<72;p
+=9) // íèæíèå 8 íå çàíîñèì òê îíè äóáëèðóåòñÿ ñëåä êóñêîì
131 for(int s
=0; s
<8; ++s
) // 9 çíà÷åíèå â ñòðîêå íå çàíîñèì òê îíî äóáëèðóåòñÿ ñëåä êóñêîì, à â ïðàâûõ-áîêîâûõ îáðåçàåòñÿ äëÿ 128õ128
133 MapLiqHeight
[k
] = ChunkLiqHeight
[p
+s
];
140 delete LiqChunkData1
;
141 delete []ChunkLiqHeight
;
144 //case 0x4d434e4b: // MCNK
145 //case 0x4d46424f: // MFBO new in BC
146 //case 0x4d545846: // MTXF new in WotLK
150 //printf("Loading chunks info\n");
151 // read individual map chunks
152 for (int j
=0; j
<16; ++j
)
154 for (int i
=0; i
<16; ++i
)
156 mf
.seek((int)mcnk_offsets
[j
*16+i
]);
157 LoadMapChunk(mf
,&(mcells
->ch
[i
][j
]));
165 bool isHole(int holes
, int i
, int j
)
169 if(testi
>3) testi
= 3;
170 if(testj
>3) testj
= 3;
171 return (holes
& holetab_h
[testi
] & holetab_v
[testj
])!=0;
174 inline void LoadMapChunk(MPQFile
& mf
, chunk
*_chunk
)
179 MapChunkHeader header
;
184 size_t lastpos
= mf
.getPos() + size
;
185 mf
.read(&header
, 0x80); // what if header size got changed?
186 _chunk
->area_id
=header
.areaid
;
188 float xbase
= header
.xpos
;
189 float ybase
= header
.ypos
;
190 float zbase
= header
.zpos
;
191 zbase
= TILESIZE
*32-zbase
;
192 xbase
= TILESIZE
*32-xbase
;
193 if(wmoc
.x
>xbase
)wmoc
.x
=xbase
;
194 if(wmoc
.z
>zbase
)wmoc
.z
=zbase
;
195 int chunkflags
= header
.flags
;
196 float zmin
=999999999.0f
;
197 float zmax
=-999999999.0f
;
198 // must be there, bl!zz uses some crazy format
199 while (mf
.getPos() < lastpos
)
203 size_t nextpos
= mf
.getPos() + size
;
204 if(fourcc
==0x4d435654) // MCVT
206 for (int j
=0; j
<17; ++j
)
207 for (int i
=0; i
<((j
%2)?8:9); ++i
)
213 if(isHole(header
.holes
,i
,j
))
214 _chunk
->v8
[i
][j
/2] = -1000;
216 _chunk
->v8
[i
][j
/2] = z
;
220 if(isHole(header
.holes
,i
,j
))
221 _chunk
->v9
[i
][j
/2] = -1000;
223 _chunk
->v9
[i
][j
/2] = z
;
230 else if(fourcc
==0x4d434e52) // MCNR
232 nextpos
= mf
.getPos() + 0x1C0; // size fix
234 else if(fourcc
==0x4d434c51 && !MH2O_presence
) // íå áóäåì ó÷èòûâàòü åñëè óæå áûëè äàííûå â MH2O, ïåðåñòðàõîâêà :) // MCLQ
236 // liquid / water level
241 ChunkLiqHeight
= new float[81];
243 if (!strcmp(fcc1
,"MCSE"))
245 for(int j
=0;j
<81;++j
)
247 ChunkLiqHeight
[j
] = -999999; // no liquid/water
253 mf
.read(&maxheight
, 4);
254 for(int j
=0;j
<81;++j
)
259 ChunkLiqHeight
[j
] = -999999;
261 ChunkLiqHeight
[j
] = h
;
264 if(chunkflags
& 4 || chunkflags
& 8)
265 MapLiqFlag
[chunk_num
] |= 1;
267 MapLiqFlag
[chunk_num
] |= 2;
269 // çàïîëíåì òàê æå êàê â MH2O
271 m
= 1024*(chunk_num
/16);
272 k
= m
+(chunk_num
%16)*8;
274 for(int p
=0;p
<72;p
+=9)
276 for(int s
=0; s
<8; ++s
)
278 MapLiqHeight
[k
] = ChunkLiqHeight
[p
+s
];
283 delete []ChunkLiqHeight
;
290 double solve (vec
*v
,vec
*p
)
292 double a
= v
[0].y
*(v
[1].z
- v
[2].z
) + v
[1].y
*(v
[2].z
- v
[0].z
) + v
[2].y
*(v
[0].z
- v
[1].z
);
293 double b
= v
[0].z
*(v
[1].x
- v
[2].x
) + v
[1].z
*(v
[2].x
- v
[0].x
) + v
[2].z
*(v
[0].x
- v
[1].x
);
294 double c
= v
[0].x
*(v
[1].y
- v
[2].y
) + v
[1].x
*(v
[2].y
- v
[0].y
) + v
[2].x
*(v
[0].y
- v
[1].y
);
295 double d
= v
[0].x
*(v
[1].y
*v
[2].z
- v
[2].y
*v
[1].z
) + v
[1].x
* (v
[2].y
*v
[0].z
- v
[0].y
*v
[2].z
) + v
[2].x
* (v
[0].y
*v
[1].z
- v
[1].y
*v
[0].z
);
298 // plane equation ax+by+cz+d=0
299 return ((a
*p
->x
+c
*p
->z
-d
)/b
);
302 inline double GetZ(double x
, double z
)
308 int xc
=(int)(x
/UNITSIZE
);
309 int zc
=(int)(z
/UNITSIZE
);
313 double lx
=x
-xc
*UNITSIZE
;
314 double lz
=z
-zc
*UNITSIZE
;
319 v
[0].y
=cell
->v8
[xc
][zc
];
325 v
[1].y
=cell
->v9
[xc
+1][zc
];
331 v
[1].y
=cell
->v9
[xc
][zc
+1];
338 v
[2].y
=cell
->v9
[xc
+1][zc
+1];
344 v
[2].y
=cell
->v9
[xc
][zc
];
352 inline void TransformData()
356 for(int x
=0;x
<128;++x
)
358 for(int y
=0;y
<128;++y
)
360 cell
->v8
[x
][y
] = (float)mcells
->ch
[x
/8][y
/8].v8
[x
%8][y
%8];
361 cell
->v9
[x
][y
] = (float)mcells
->ch
[x
/8][y
/8].v9
[x
%8][y
%8];
364 // extra 1 point on bounds
365 cell
->v9
[x
][128] = (float)mcells
->ch
[x
/8][15].v9
[x
%8][8];
367 cell
->v9
[128][x
] = (float)mcells
->ch
[15][x
/8].v9
[8][x
%8];
372 cell
->v9
[128][128] = (float)mcells
->ch
[15][15].v9
[8][8];
377 const char MAP_MAGIC
[] = "MAP_2.01";
379 bool ConvertADT(char * filename
,char * filename2
)
381 MapLiqHeight
= new float[16384];
382 MapLiqFlag
= new char[256];
383 for(int j
= 0; j
< 256; ++j
)
385 for(int j
= 0; j
< 16384; ++j
)
386 MapLiqHeight
[j
] = -999999;
388 if(!LoadADT(filename
))
390 delete [] MapLiqHeight
;
391 delete [] MapLiqFlag
;
395 FILE *output
=fopen(filename2
,"wb");
398 printf("Can't create the output file '%s'\n",filename2
);
399 delete [] MapLiqHeight
;
400 delete [] MapLiqFlag
;
404 // write magic header
405 fwrite(MAP_MAGIC
,1,8,output
);
407 for(unsigned int x
=0;x
<16;++x
)
409 for(unsigned int y
=0;y
<16;++y
)
411 if(mcells
->ch
[y
][x
].area_id
&& mcells
->ch
[y
][x
].area_id
<= maxAreaId
)
413 if(areas
[mcells
->ch
[y
][x
].area_id
]==0xffff)
414 printf("\nCan't find area flag for areaid %u.\n",mcells
->ch
[y
][x
].area_id
);
416 fwrite(&areas
[mcells
->ch
[y
][x
].area_id
],1,2,output
);
421 fwrite(&flag
,1,2,output
);
426 fwrite(MapLiqFlag
,1,256,output
);
427 delete [] MapLiqFlag
;
429 fwrite(MapLiqHeight
,sizeof(float),16384,output
);
430 delete [] MapLiqHeight
;
434 for(unsigned int x
=0;x
<iRes
;++x
)
436 for(unsigned int y
=0;y
<iRes
;++y
)
439 (((double)(y
))*TILESIZE
)/((double)(iRes
-1)),
440 (((double)(x
))*TILESIZE
)/((double)(iRes
-1)));
442 fwrite(&z
,1,sizeof(z
),output
);