/// <summary> /// <see cref="PsbResCollector.CollectResources"/> for packed-texture specs, like <see cref="PsbSpec.win"/> /// </summary> /// <param name="psb"></param> /// <returns></returns> public static List <ResourceMetadata> CollectSplitResources(this PSB psb) { List <ResourceMetadata> resList = new List <ResourceMetadata>(); var source = (PsbDictionary)psb.Objects["source"]; foreach (var tex in source) { if (tex.Value is PsbDictionary texDic) { var typeStr = (PsbString)texDic["texture"].Children("type"); var bmps = SplitTexture(texDic, psb.Platform); var icons = (PsbDictionary)texDic["icon"]; foreach (var iconPair in icons) { var res = new PsbResource() { Data = RL.GetPixelBytesFromImage(bmps[iconPair.Key], typeStr.Value.ToPsbPixelFormat(psb.Platform)) }; var icon = (PsbDictionary)iconPair.Value; var md = PsbResCollector.GenerateMotionResMetadata(icon, res); md.Spec = psb.Platform; md.TypeString = typeStr; resList.Add(md); } } } return(resList); }
/// <summary> /// Add stubs (<see cref="PsbResource"/> with null Data) into a Motion PSB. A stub must be linked with a texture, or it will be null after <see cref="PSB.Build"/> /// </summary> /// <param name="resources"></param> /// <param name="obj"></param> private static void GenerateMotionResourceStubs(List <PsbResource> resources, IPsbValue obj) { switch (obj) { case PsbList c: c.ForEach(o => GenerateMotionResourceStubs(resources, o)); break; case PsbDictionary d: if (d.ContainsKey(Consts.ResourceKey) && (d[Consts.ResourceKey] == null || d[Consts.ResourceKey] is PsbNull)) { if (d.ContainsKey("width") && d.ContainsKey("height")) { //confirmed, add stub PsbResource res = new PsbResource(); resources.Add(res); res.Index = (uint)resources.IndexOf(res); d[Consts.ResourceKey] = res; } } foreach (var o in d.Values) { GenerateMotionResourceStubs(resources, o); } break; } }
private Dictionary <string, List <string> > TranslateResources(PSB psb) { Dictionary <string, List <string> > iconInfos = new Dictionary <string, List <string> >(); var source = (PsbDictionary)psb.Objects["source"]; foreach (var tex in source) { if (tex.Value is PsbDictionary texDic) { var iconList = new List <string>(); iconInfos.Add(tex.Key, iconList); var bmps = TextureSpliter.SplitTexture(texDic, psb.Platform); var icons = (PsbDictionary)texDic["icon"]; foreach (var iconPair in icons) { iconList.Add(iconPair.Key); var icon = (PsbDictionary)iconPair.Value; var data = UseRL ? RL.CompressImage(bmps[iconPair.Key], TargetPixelFormat) : RL.GetPixelBytesFromImage(bmps[iconPair.Key], TargetPixelFormat); icon["pixel"] = new PsbResource { Data = data, Parents = new List <IPsbCollection> { icon } }; icon["compress"] = UseRL ? new PsbString("RL") : new PsbString(); icon.Remove("left"); icon.Remove("top"); //There is no obvious match for attr? //if (icon["attr"] is PsbNumber n && n.AsInt > 0) //{ // icon["attr"] = PsbNull.Null; //} //else //{ // icon.Remove("attr"); //} icon.Remove("attr"); } texDic.Remove("texture"); texDic["type"] = new PsbNumber(1); } } return(iconInfos); }
private static ResourceMetadata GenerateTachieResMetadata(PsbDictionary d, PsbResource r, string label = "") { int width = 1, height = 1; int top = 0, left = 0; var dd = d.Parent as PsbDictionary ?? d; if ((d["width"] ?? d["truncated_width"] ?? dd["width"]) is PsbNumber nw) { width = (int)nw; } if ((d["height"] ?? d["truncated_height"] ?? dd["height"]) is PsbNumber nh) { height = (int)nh; } if ((dd["top"] ?? d["top"]) is PsbNumber nx) { top = nx.AsInt; } if ((dd["left"] ?? d["left"]) is PsbNumber ny) { left = ny.AsInt; } var md = new ResourceMetadata() { Top = top, Left = left, TypeString = d["type"] as PsbString, Width = width, Height = height, Name = r.Index.ToString(), Part = label, Resource = r, }; return(md); }
/// <summary> /// Extract resource info /// </summary> /// <param name="d">PsbObject which contains "pixel"</param> /// <param name="r">Resource</param> /// <param name="duplicatePalette">When set to true, Pal.Data may not be set!</param> /// <returns></returns> internal static ImageMetadata GenerateImageMetadata(PsbDictionary d, PsbResource r = null, bool duplicatePalette = false) { if (r == null) { if (d.ContainsKey(Consts.ResourceKey) && d[Consts.ResourceKey] is PsbResource rr) { r = rr; } else //this may find Pal { r = d.Values.FirstOrDefault(v => v is PsbResource) as PsbResource; } } bool is2D = false; var part = GetPartName(d); var name = d.GetName(); RectangleF clip = RectangleF.Empty; if (d["clip"] is PsbDictionary clipDic && clipDic.Count > 0) { is2D = true; clip = RectangleF.FromLTRB( left: clipDic["left"] == null ? 0f : (float)(PsbNumber)clipDic["left"], top: clipDic["top"] == null ? 0f : (float)(PsbNumber)clipDic["top"], right: clipDic["right"] == null ? 1f : (float)(PsbNumber)clipDic["right"], bottom: clipDic["bottom"] == null ? 1f : (float)(PsbNumber)clipDic["bottom"] ); } var compress = PsbCompressType.None; if (d["compress"] is PsbString sc) { is2D = true; if (sc.Value.ToUpperInvariant() == "RL") { compress = PsbCompressType.RL; } } int width = 1, height = 1; float originX = 0, originY = 0; if (d["width"] is PsbNumber nw) { is2D = true; width = (int)nw; } if (d["height"] is PsbNumber nh) { is2D = true; height = (int)nh; } if (d["originX"] is PsbNumber nx) { is2D = true; originX = (float)nx; } if (d["originY"] is PsbNumber ny) { is2D = true; originY = (float)ny; } PsbString typeString = null; if (d["type"] is PsbString typeStr) { typeString = typeStr; } int top = 0, left = 0; if (d["top"] is PsbNumber nt) { is2D = true; top = (int)nt; } if (d["left"] is PsbNumber nl) { is2D = true; left = (int)nl; } PsbResource palResource = null; PsbString palTypeString = null; if (d["pal"] is PsbResource palRes) { if (duplicatePalette) { palResource = new PsbResource(palRes.Index); d["pal"] = palResource; } else { palResource = palRes; } palTypeString = d["palType"] as PsbString; } var md = new ImageMetadata() { Index = r.Index ?? int.MaxValue, Compress = compress, Name = name, Part = part, Clip = clip, Is2D = is2D, OriginX = originX, OriginY = originY, Top = top, Left = left, Width = width, Height = height, TypeString = typeString, Resource = r, Palette = palResource, PaletteTypeString = palTypeString }; return(md); }
/// <summary> /// Extract resource info /// </summary> /// <param name="d">PsbObject which contains "pixel"</param> /// <param name="r">Resource</param> /// <returns></returns> internal static ResourceMetadata GenerateMotionResMetadata(PsbDictionary d, PsbResource r = null) { if (r == null) { r = d.Values.FirstOrDefault(v => v is PsbResource) as PsbResource; } bool is2D = false; var part = d.GetPartName(); var name = d.GetName(); RectangleF clip = RectangleF.Empty; if (d["clip"] is PsbDictionary clipDic && clipDic.Count > 0) { is2D = true; clip = RectangleF.FromLTRB( left: clipDic["left"] == null ? 0f : (float)(PsbNumber)clipDic["left"], top: clipDic["top"] == null ? 0f : (float)(PsbNumber)clipDic["top"], right: clipDic["right"] == null ? 1f : (float)(PsbNumber)clipDic["right"], bottom: clipDic["bottom"] == null ? 1f : (float)(PsbNumber)clipDic["bottom"] ); } var compress = PsbCompressType.None; if (d["compress"] is PsbString sc) { is2D = true; if (sc.Value.ToUpperInvariant() == "RL") { compress = PsbCompressType.RL; } } int width = 1, height = 1; float originX = 0, originY = 0; if (d["width"] is PsbNumber nw) { is2D = true; width = (int)nw; } if (d["height"] is PsbNumber nh) { is2D = true; height = (int)nh; } if (d["originX"] is PsbNumber nx) { is2D = true; originX = (float)nx; } if (d["originY"] is PsbNumber ny) { is2D = true; originY = (float)ny; } PsbString typeString = null; if (d["type"] is PsbString typeStr) { typeString = typeStr; } int top = 0, left = 0; if (d["top"] is PsbNumber nt) { is2D = true; top = (int)nt; } if (d["left"] is PsbNumber nl) { is2D = true; left = (int)nl; } var md = new ResourceMetadata() { Index = r.Index ?? int.MaxValue, Compress = compress, Name = name, Part = part, Clip = clip, Is2D = is2D, OriginX = originX, OriginY = originY, Top = top, Left = left, Width = width, Height = height, TypeString = typeString, Resource = r, }; return(md); }