void Sky::init(MPQFile &f) { int addr = (int)f.getPos(); int ll[18]; int buf[64]; for (int k=0; k<4; k++) { if (k==0 || k==2) { f.seek(addr + k * 0x15f0); f.read(ll, 18*4); for (int i=0; i<18; i++) { f.read(buf,64*4); int *p=buf; int idx = (k/2)*18 + i; if (ll[i]==0) mmin[idx] = -1; else { mmin[idx] = *p; for (int l=0; l<ll[i]; l++) { SkyColor sc; sc.init(p[0],p[1]); p+=2; colorRows[idx].push_back(sc); } } } } } f.seek(addr + 4 * 0x15f0); }
inline void LoadMapChunk(MPQFile & mf, chunk*_chunk) { float h; uint32 fourcc; uint32 size; MapChunkHeader header; mf.seekRelative(4); mf.read(&size, 4); size_t lastpos = mf.getPos() + size; mf.read(&header, 0x80); _chunk->area_id =header.areaid ; _chunk->flag =0; float xbase = header.xpos; float ybase = header.ypos; float zbase = header.zpos; zbase = TILESIZE*32-zbase; xbase = TILESIZE*32-xbase; if(wmoc.x >xbase)wmoc.x =xbase; if(wmoc.z >zbase)wmoc.z =zbase; int chunkflags = header.flags; float zmin=999999999.0f; float zmax=-999999999.0f; //must be there, bl!zz uses some crazy format int nTextures; while (mf.getPos() < lastpos) { mf.read(&fourcc,4); mf.read(&size, 4); //if(size!=580) // printf("\n sz=%d",size); size_t nextpos = mf.getPos() + size; if(fourcc==0x4d435654) // MCVT { for (int j=0; j<17; j++) for (int i=0; i<((j%2)?8:9); i++) { mf.read(&h,4); float z=h+ybase; if (j%2) { if(isHole(header.holes,i,j)) _chunk->v8[i][j/2] = -1000; else _chunk->v8[i][j/2] = z; } else { if(isHole(header.holes,i,j)) _chunk->v9[i][j/2] = -1000; else _chunk->v9[i][j/2] = z; } if(z>zmax)zmax=z; //if(z<zmin)zmin=z; } } else if(fourcc==0x4d434e52) // MCNR { nextpos = mf.getPos() + 0x1C0; // size fix } else if(fourcc==0x4d434c51) // MCLQ { // liquid / water level //bool haswater; char fcc1[5]; mf.read(fcc1,4); flipcc(fcc1); fcc1[4]=0; if (!strcmp(fcc1,"MCSE")) { for(int i=0;i<9;i++) for(int j=0;j<9;j++) _chunk->waterlevel[i][j]=-999999; // no liquid/water } else { float maxheight; mf.read(&maxheight, 4); for(int j=0;j<9;j++) for(int i=0;i<9;i++) { mf.read(&h, 4); mf.read(&h, 4); if(h > maxheight) _chunk->waterlevel[i][j]=-999999; else _chunk->waterlevel[i][j]=h; } if(chunkflags & 4 || chunkflags & 8) _chunk->flag |=1; if(chunkflags & 16) _chunk->flag |=2; } break; } else if (fourcc==0x4d434c59) // MCLY { // texture info nTextures = (int)size; } else if (fourcc==0x4d43414c) // MCAL { if (nTextures<=0) continue; } mf.seek(nextpos); } }
LiquidModelInstance::LiquidModelInstance(MPQFile &f, uint32 base_pos, uint32 tileID, MH20_Header* header, uint32 mapID, uint32 tileX, uint32 tileY, FILE *pDirfile) : Info(false) { memset(&LiqHeader, 0, sizeof(LiquidHeader)); LiqHeader.layerCount = header->layerCount; if(header->ofsInformation == 0) { Info = false; return; } #ifdef _DEBUG printf("Information offset: %i\n", header->ofsInformation); #endif f.seek(header->ofsInformation+base_pos); f.read(&LiqHeader.info, sizeof(MH20_Information)); #ifdef _DEBUG if(LiqHeader.info.LiquidType != 2) // Skip oceans { printf("Liquid Data Dump:\n"); printf("Flags: %08i |\n", LiqHeader.info.flags); // printf("Height %08i |\n", LiqHeader.info.height); // printf("Level1 %08f |\n", LiqHeader.info.heightLevel1); // printf("Level2 %08f |\n", LiqHeader.info.heightLevel2); printf("LType: %08i |\n", LiqHeader.info.LiquidType); printf("Width: %08i |\n", LiqHeader.info.width); printf("xOfset %08i |\n", LiqHeader.info.xOffset); printf("yOfset %08i |\n", LiqHeader.info.yOffset); WaitForInput(); } #endif uint16* buff = new uint16[3]; buff[0] = buff[1] = buff[2] = 0; if(LiqHeader.info.ofsHeightmap > 0) { #ifdef _DEBUG printf("Height Map Offset: %i\n", LiqHeader.info.ofsHeightmap); #endif f.seek(LiqHeader.info.ofsHeightmap+base_pos); f.read(&LiqHeader.heightMap.heightMap, sizeof(float)*2); f.read(&LiqHeader.heightMap.transparency, sizeof(char)*2); buff[0] = sizeof(LiqHeader.heightMap); } if(LiqHeader.info.ofsMask2 > 0) { #ifdef _DEBUG printf("Mask Offset: %i\n", LiqHeader.info.ofsMask2); #endif f.seek(LiqHeader.info.ofsMask2+base_pos); f.read(&LiqHeader.Mask2, sizeof(uint8)); buff[1] = sizeof(uint8); } if(header->ofsRender > 0) { #ifdef _DEBUG printf("Render offset: %i\n", header->ofsRender); #endif f.seek(header->ofsRender+base_pos); f.read(&LiqHeader.Render, sizeof(uint64)); buff[2] = sizeof(uint64); } fwrite(&LiqHeader.layerCount, sizeof(uint32), 1, pDirfile); fwrite(&LiqHeader.info, sizeof(MH20_Information), 1, pDirfile); fwrite(&buff[0], sizeof(uint16), 1, pDirfile); if(buff[0]) fwrite(&LiqHeader.heightMap, sizeof(MH2O_HeightMapData), 1, pDirfile); fwrite(&buff[1], sizeof(uint16), 1, pDirfile); if(buff[1]) fwrite(&LiqHeader.Mask2, sizeof(uint8), 1, pDirfile); fwrite(&buff[2], sizeof(uint16), 1, pDirfile); if(buff[2]) fwrite(&LiqHeader.Render, sizeof(uint64), 1, pDirfile); }
inline void LoadMapChunk(MPQFile &mf, chunk *_chunk) { float h; uint32 fourcc; uint32 size; MapChunkHeader header; mf.seekRelative(4); mf.read(&size, 4); size_t lastpos = mf.getPos() + size; mf.read(&header, 0x80); // what if header size got changed? _chunk->area_id = header.areaid; float xbase = header.xpos; float ybase = header.ypos; float zbase = header.zpos; zbase = TILESIZE * 32 - zbase; xbase = TILESIZE * 32 - xbase; if(wmoc.x > xbase) wmoc.x = xbase; if(wmoc.z > zbase) wmoc.z = zbase; int chunkflags = header.flags; //printf("LMC: flags %X\n", chunkflags); float zmin = 999999999.0f; float zmax = -999999999.0f; // must be there, bl!zz uses some crazy format while (mf.getPos() < lastpos) { mf.read(&fourcc, 4); mf.read(&size, 4); size_t nextpos = mf.getPos() + size; if(fourcc == 0x4d435654) // MCVT { for (int j = 0; j < 17; ++j) { for (int i = 0; i < ((j % 2) ? 8 : 9); ++i) { mf.read(&h, 4); float z = h + ybase; if (j % 2) { if(isHole(header.holes, i, j)) _chunk->v8[i][j / 2] = -1000; else _chunk->v8[i][j / 2] = z; } else { if(isHole(header.holes, i, j)) _chunk->v9[i][j / 2] = -1000; else _chunk->v9[i][j / 2] = z; } if(z > zmax) zmax = z; //if(z < zmin) zmin = z; } } } else if(fourcc == 0x4d434e52) // MCNR { nextpos = mf.getPos() + 0x1C0; // size fix } else if(fourcc == 0x4d434c51) // MCLQ { // liquid / water level char fcc1[5]; mf.read(fcc1, 4); flipcc(fcc1); fcc1[4] = 0; float *ChunkLiqHeight = new float[81]; if (!strcmp(fcc1, "MCSE")) { for(int j = 0; j < 81; ++j) { ChunkLiqHeight[j] = -999999; // no liquid/water } } else { float maxheight; mf.read(&maxheight, 4); for(int j = 0; j < 81; ++j) { LiqData liq; mf.read(&liq, 8); if(liq.height > maxheight) ChunkLiqHeight[j] = -999999; else ChunkLiqHeight[j] = h; } if(chunkflags & 4 || chunkflags & 8) MapLiqFlag[chunk_num] |= 1; // water if(chunkflags & 16) MapLiqFlag[chunk_num] |= 2; // magma/slime } if(!(chunk_num % 16)) m = 1024 * (chunk_num / 16); k = m + (chunk_num % 16) * 8; for(int p = 0; p < 72; p += 9) { for(int s = 0; s < 8; ++s) { MapLiqHeight[k] = ChunkLiqHeight[p + s]; ++k; } k = k + 120; } delete []ChunkLiqHeight; break; } mf.seek(nextpos); } }