public FindChunkAndDecode ( int bitmap, int chunknumber, int mipmap, |
||
bitmap | int | The bitmap. |
chunknumber | int | The chunknumber. |
mipmap | int | The mipmap. |
meta | The meta. | |
map | The map. | |
visualchunkindex | int | The visualchunkindex. |
bspnumber | int | The bspnumber. |
return |
public Bitmap FindChunkAndDecode(
int bitmap,
int chunknumber,
int mipmap,
ref Meta meta,
Map map,
int visualchunkindex,
int bspnumber)
{
for (int x = 0; x < meta.raw.rawChunks.Count; x++)
{
BitmapRawDataChunk tempb = (BitmapRawDataChunk)meta.raw.rawChunks[x];
if (tempb.inchunk == bitmap && tempb.num == chunknumber)
{
int width = this.Properties[bitmap].width >> chunknumber;
int height = this.Properties[bitmap].height >> chunknumber;
int depth = this.Properties[bitmap].depth >> chunknumber;
depth = depth < 1 ? 1 : depth;
int pixeloff = this.Properties[bitmap].pixelOffset;
int bpp = this.Properties[bitmap].bitsPerPixel;
int offset = 0;
byte[] guh;
#region 2D & 3D (Volume) Textures
if (this.Properties[bitmap].typename != BitmapType.BITM_TYPE_CUBEMAP)
{
for (int i = 0; i < mipmap; i++)
{
//offset += Math.Max(width >> i, 1) * Math.Max(height >> i, 1) * Math.Max(depth >> i, 1) * (bpp >> 3);
switch (this.Properties[bitmap].formatname)
{
case BitmapFormat.BITM_FORMAT_DXT1:
offset += Math.Max( Math.Max(width >> i, 1) * Math.Max(height >> i, 1) * Math.Max(depth >> i, 1) * (bpp >> 3) / 8, 8);
break;
case BitmapFormat.BITM_FORMAT_DXT2AND3:
case BitmapFormat.BITM_FORMAT_DXT4AND5:
offset += Math.Max(Math.Max(width >> i, 1) * Math.Max(height >> i, 1) * Math.Max(depth >> i, 1) * (bpp >> 3) / 4, 16);
break;
/*
case BitmapFormat.BITM_FORMAT_DXT1:
offset /= 8;
break;
case BitmapFormat.BITM_FORMAT_DXT2AND3:
case BitmapFormat.BITM_FORMAT_DXT4AND5:
offset /= 4;
break;
*/
default:
offset += Math.Max(width >> i, 1) * Math.Max(height >> i, 1) * Math.Max(depth >> i, 1) * (bpp >> 3);
break;
}
}
// XZodia hack to fix issue in 03b_newmombosa, 2nd BSP, G8B8 bitmap issue
if (offset > tempb.size)
offset = tempb.size;
int tempsize = tempb.size - offset;
guh = new byte[tempsize];
Array.Copy(tempb.MS.ToArray(), offset, guh, 0, tempsize);
}
#endregion
#region Cubemap
else
{
for (int i = 0; i < mipmap; i++)
{
offset += tempb.mipmaps[i].size;
}
int tempsize = tempb.size - offset * 6;
guh = new byte[tempsize];
tempsize /= 6;
for (int i = 0; i < 6; i++)
{
Array.Copy(
tempb.MS.ToArray(), i * (offset + tempsize) + offset, guh, i * tempsize, tempsize);
}
}
#endregion
width = Math.Max(width >> mipmap, 1);
height = Math.Max(height >> mipmap, 1);
depth = Math.Max(depth >> mipmap, 1);
int widthPad = 0;
// 2D AY8 bitmaps are 64 byte padded?
int padding = (this.Properties[bitmap].formatname == BitmapFormat.BITM_FORMAT_AY8)
? 64 : 16;
if (this.Properties[bitmap].width % padding != 0 && width % padding != 0)
widthPad += padding - (width % padding);
Bitmap b;
try
{
b = DecodeBitm(
guh,
height,
width + widthPad,
depth,
bpp,
this.Properties[bitmap].typename,
this.Properties[bitmap].formatname,
this.Properties[bitmap].swizzle,
map,
visualchunkindex,
bspnumber);
}
catch
{
b = DecodeBitm(
guh,
height,
width,
depth,
bpp,
this.Properties[bitmap].typename,
this.Properties[bitmap].formatname,
this.Properties[bitmap].swizzle,
map,
visualchunkindex,
bspnumber);
}
return b;
}
}
return null;
}
/// <summary> /// The h 2 shader info. /// </summary> /// <param name="TagIndex">The TagIndex.</param> /// <param name="map">The map.</param> /// <remarks></remarks> public void H2ShaderInfo(int TagIndex, Map map) { bool alreadyOpen = true; if (!(map.isOpen && map.openMapType == MapTypes.Internal)) { map.OpenMap(MapTypes.Internal); alreadyOpen = false; } this.TagIndex = TagIndex; if (this.TagIndex == -1) { return; } this.shaderName = map.FileNames.Name[this.TagIndex]; map.BR.BaseStream.Position = map.MetaInfo.Offset[this.TagIndex] + 4; int tempstem = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempstem != -1) { if (map.FileNames.Name[tempstem].IndexOf("alphatest") != -1) { this.Alpha = AlphaType.AlphaTest; } else if (map.FileNames.Name[tempstem].IndexOf("alpha") != -1) { this.Alpha = AlphaType.AlphaBlend; } else if (map.FileNames.Name[tempstem].IndexOf("water") != -1) { this.Alpha = AlphaType.AlphaBlend; } else { this.Alpha = AlphaType.None; } } else { this.Alpha = AlphaType.None; } map.BR.BaseStream.Position = map.MetaInfo.Offset[this.TagIndex] + 12; int tempc2 = map.BR.ReadInt32(); int tempr2 = map.BR.ReadInt32() - map.SecondaryMagic; if (tempc2 != 0) { map.BR.BaseStream.Position = tempr2 + 4; int tempcrap = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempcrap != -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); this.MainBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); this.MainName = map.FileNames.Name[tempcrap]; this.levels = pm.Properties[0].mipMapCount; } } //map.OpenMap(MapTypes.Internal); map.BR.BaseStream.Position = map.MetaInfo.Offset[this.TagIndex] + 32; tempc2 = map.BR.ReadInt32(); tempr2 = map.BR.ReadInt32() - map.SecondaryMagic; map.BR.BaseStream.Position = tempr2 + 24; int fuckr = map.BR.ReadInt32(); if (fuckr != 0) { fuckr -= map.SecondaryMagic; map.BR.BaseStream.Position = fuckr; this.primarydetailuscale = map.BR.ReadSingle(); this.primarydetailvscale = map.BR.ReadSingle(); this.primarydetailwscale = map.BR.ReadSingle(); map.BR.ReadSingle(); this.secondarydetailuscale = map.BR.ReadSingle(); this.secondarydetailvscale = map.BR.ReadSingle(); this.secondarydetailwscale = map.BR.ReadSingle(); } map.BR.BaseStream.Position = tempr2 + 4; tempc2 = map.BR.ReadInt32(); tempr2 = map.BR.ReadInt32() - map.SecondaryMagic; /* for (int x = 0; x < tempc2; x++) { map.BR.BaseStream.Position = tempr2 + (x * 12); int tempcrap = map.Functions.Meta.FindMetaByID(map.BR.ReadInt32(), map); if (tempcrap == -1) { continue; } Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, map, false); Raw.ParsedBitmap pm = new Raw.ParsedBitmap(ref tempmeta, map); Bitmaps.Add(pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0)); BitmapNames.Add(map.FileNames.Name[tempcrap]); } */ // map.BR.BaseStream.Position = tempr + 20; // tempc2 = map.BR.ReadInt32(); // tempr2 = map.BR.ReadInt32() - map.SecondaryMagic; // tempc2 = tempc; // tempr2 = tempr; if (tempc2 != 0) { map.BR.BaseStream.Position = tempr2; int tempcrap = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempcrap != -1) { int test = map.FileNames.Name[tempcrap].IndexOf("reflection_maps"); if (map.FileNames.Name[tempcrap].IndexOf("_bump") != -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); // this.BumpMapBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); this.BumpMapName = map.FileNames.Name[tempcrap]; } else if (map.FileNames.Name[tempcrap].IndexOf("_cube_map") != -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); // this.CubeMapBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); this.CubeMapName = map.FileNames.Name[tempcrap]; } else if (map.FileNames.Name[tempcrap].IndexOf("default_") == -1 && this.MainBitmap == null && test == -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); // Try to load LOD2-MIP3 if that fails, load LOD2-MIP0, otherwise LOD0-MIP0 this.MainBitmap = pm.FindChunkAndDecode(0, 2, 3, ref tempmeta, map, 0, 0); if (this.MainBitmap == null) { this.MainBitmap = pm.FindChunkAndDecode(0, 2, 0, ref tempmeta, map, 0, 0); if (this.MainBitmap == null) this.MainBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); } this.MainName = map.FileNames.Name[tempcrap]; this.levels = pm.Properties[0].mipMapCount; } else if (test != -1) { map.BR.BaseStream.Position += 8; tempcrap = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); // this.MainBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map); // this.MainName = map.FileNames.Name[tempcrap]; } } map.BR.BaseStream.Position = tempr2 + 24; tempcrap = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempcrap != -1 && this.MainBitmap == null) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); this.MainBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); this.MainName = map.FileNames.Name[tempcrap]; this.levels = pm.Properties[0].mipMapCount; } else if (this.MainBitmap == null) { map.BR.BaseStream.Position = tempr2 + 12; tempcrap = map.Functions.ForMeta.FindMetaByID(map.BR.ReadInt32()); if (tempcrap != -1) { Meta tempmeta = new Meta(map); tempmeta.ReadMetaFromMap(tempcrap, false); ParsedBitmap pm = new ParsedBitmap(ref tempmeta, map); this.MainBitmap = pm.FindChunkAndDecode(0, 0, 0, ref tempmeta, map, 0, 0); this.MainName = map.FileNames.Name[tempcrap]; this.levels = pm.Properties[0].mipMapCount; } } } if (!alreadyOpen) { map.CloseMap(); } }