void ParseInfo(string info_name) { if (null == m_layer_map) { m_layer_map = new Dictionary <string, StxLayerInfo>(); } else { m_layer_map.Clear(); } using (var info = VFS.OpenView(info_name)) { if (!info.View.AsciiEqual(0, "CDBD")) { return; } int count = info.View.ReadInt32(4); uint current_offset = 0x10; uint info_base = current_offset + info.View.ReadUInt32(8); uint info_total_size = info.View.ReadUInt32(12); info.View.Reserve(0, info_base + info_total_size); uint names_base = current_offset + (uint)count * 0x18; var dir = new List <StxEntry> (count); for (int i = 0; i < count; ++i) { uint name_offset = names_base + info.View.ReadUInt32(current_offset); int parent_dir = info.View.ReadInt32(current_offset + 8); int attr = info.View.ReadInt32(current_offset + 0xC); uint info_offset = info.View.ReadUInt32(current_offset + 0x10); uint info_size = info.View.ReadUInt32(current_offset + 0x14); var name = info.View.ReadString(name_offset, info_base - name_offset); string path_name = name; if (parent_dir != -1) { path_name = Path.Combine(dir[parent_dir].FullName, path_name); } if (attr != -1 && info_size != 0) { info_offset += info_base; } var entry = new StxEntry { FullName = path_name, Name = name, Attr = attr, InfoOffset = info_offset, InfoSize = info_size, }; if (name == "filename" && parent_dir != -1 && info_size != 0) { uint filename_length = info.View.ReadUInt32(info_offset); var filename = info.View.ReadString(info_offset + 4, filename_length); m_layer_map[filename] = new StxLayerInfo { Path = dir[parent_dir].FullName + Path.DirectorySeparatorChar, }; } dir.Add(entry); current_offset += 0x18; } foreach (var layer in m_layer_map.Values) { foreach (var field in dir.Where(e => e.Attr != -1 && e.FullName.StartsWith(layer.Path))) { if ("rect" == field.Name && 0x14 == field.InfoSize) { int left = info.View.ReadInt32(field.InfoOffset + 4); int top = info.View.ReadInt32(field.InfoOffset + 8); int right = info.View.ReadInt32(field.InfoOffset + 12); int bottom = info.View.ReadInt32(field.InfoOffset + 16); layer.Rect = new Rectangle(left, top, right - left, bottom - top); } else if ("effect" == field.Name && field.InfoSize > 4) { // "norm" uint effect_length = info.View.ReadUInt32(field.InfoOffset); layer.Effect = info.View.ReadString(field.InfoOffset + 4, effect_length); if (layer.Effect != "norm") { Trace.WriteLine(string.Format("{0}: {1}effect = {2}", info_name, layer.Path, layer.Effect), "[Glib2.STX]"); } } else if ("blend" == field.Name && 4 == field.InfoSize) { // 0xFF -> opaque layer.Blend = info.View.ReadInt32(field.InfoOffset); if (layer.Blend != 0xFF) { Trace.WriteLine(string.Format("{0}: {1}blend = {2}", info_name, layer.Path, layer.Blend), "[Glib2.STX]"); } } } } } m_last_info_dir = string.Join(":", VFS.FullPath); }
void ParseInfo(string info_name) { if (null == m_layer_map) m_layer_map = new Dictionary<string, StxLayerInfo>(); else m_layer_map.Clear(); using (var info = VFS.OpenView (info_name)) { if (!info.View.AsciiEqual (0, "CDBD")) return; int count = info.View.ReadInt32 (4); uint current_offset = 0x10; uint info_base = current_offset + info.View.ReadUInt32 (8); uint info_total_size = info.View.ReadUInt32 (12); info.View.Reserve (0, info_base+info_total_size); uint names_base = current_offset + (uint)count * 0x18; var dir = new List<StxEntry> (count); for (int i = 0; i < count; ++i) { uint name_offset = names_base + info.View.ReadUInt32 (current_offset); int parent_dir = info.View.ReadInt32 (current_offset+8); int attr = info.View.ReadInt32 (current_offset+0xC); uint info_offset = info.View.ReadUInt32 (current_offset+0x10); uint info_size = info.View.ReadUInt32 (current_offset+0x14); var name = info.View.ReadString (name_offset, info_base-name_offset); string path_name = name; if (parent_dir != -1) path_name = Path.Combine (dir[parent_dir].FullName, path_name); if (attr != -1 && info_size != 0) info_offset += info_base; var entry = new StxEntry { FullName = path_name, Name = name, Attr = attr, InfoOffset = info_offset, InfoSize = info_size, }; if (name == "filename" && parent_dir != -1 && info_size != 0) { uint filename_length = info.View.ReadUInt32 (info_offset); var filename = info.View.ReadString (info_offset+4, filename_length); m_layer_map[filename] = new StxLayerInfo { Path = dir[parent_dir].FullName + Path.DirectorySeparatorChar, }; } dir.Add (entry); current_offset += 0x18; } foreach (var layer in m_layer_map.Values) { foreach (var field in dir.Where (e => e.Attr != -1 && e.FullName.StartsWith (layer.Path))) { if ("rect" == field.Name && 0x14 == field.InfoSize) { int left = info.View.ReadInt32 (field.InfoOffset+4); int top = info.View.ReadInt32 (field.InfoOffset+8); int right = info.View.ReadInt32 (field.InfoOffset+12); int bottom = info.View.ReadInt32 (field.InfoOffset+16); layer.Rect = new Rectangle (left, top, right-left, bottom-top); } else if ("effect" == field.Name && field.InfoSize > 4) { // "norm" uint effect_length = info.View.ReadUInt32 (field.InfoOffset); layer.Effect = info.View.ReadString (field.InfoOffset+4, effect_length); if (layer.Effect != "norm") Trace.WriteLine (string.Format ("{0}: {1}effect = {2}", info_name, layer.Path, layer.Effect), "[Glib2.STX]"); } else if ("blend" == field.Name && 4 == field.InfoSize) { // 0xFF -> opaque layer.Blend = info.View.ReadInt32 (field.InfoOffset); if (layer.Blend != 0xFF) Trace.WriteLine (string.Format ("{0}: {1}blend = {2}", info_name, layer.Path, layer.Blend), "[Glib2.STX]"); } } } } m_last_info_dir = string.Join (":", VFS.FullPath); }