/// <summary> /// Convert number to shape /// </summary> /// <param name="shape"></param> /// <returns></returns> public static string ToShapeString(this PsbNumber shape) { if (Enum.IsDefined(typeof(MmoShape), shape.IntValue)) { return(((MmoShape)shape.IntValue).ToString()); } Debug.WriteLine($"{shape.IntValue} is not a valid {nameof(MmoShape)}"); return(MmoShape.point.ToString()); }
public void TestPsbNumbers() { var p1 = new PsbNumber(2.4f); using (var ms = new MemoryStream()) { BinaryWriter bw = new BinaryWriter(ms); BinaryReader br = new BinaryReader(ms); p1.WriteTo(bw); var bts = ms.ToArray(); ms.Seek(0, SeekOrigin.Begin); var p2 = new PsbNumber((PsbObjType)br.ReadByte(), br); Assert.AreEqual(p1.IntValue, p2.IntValue); } }
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[Consts.ResourceKey] = 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 Dictionary <string, (string Tex, string IconName)> TranslateResources(PSB psb) { Dictionary <string, (string Tex, string IconName)> iconInfos = new Dictionary <string, (string, string)>(); Dictionary <string, Image> textures = new Dictionary <string, Image>(); var source = (PsbDictionary)psb.Objects["source"]; int maxSideLength = 2048; long area = 0; //Collect textures foreach (var tex in source) { var texName = tex.Key; var icons = (PsbDictionary)((PsbDictionary)tex.Value)["icon"]; foreach (var icon in icons) { var iconName = icon.Key; var info = (PsbDictionary)icon.Value; var width = (int)(PsbNumber)info["width"]; var height = (int)(PsbNumber)info["height"]; var res = (PsbResource)info["pixel"]; var bmp = info["compress"]?.ToString().ToUpperInvariant() == "RL" ? RL.DecompressToImage(res.Data, height, width, psb.Platform.DefaultPixelFormat()) : RL.ConvertToImage(res.Data, height, width, psb.Platform.DefaultPixelFormat()); bmp.Tag = iconName; textures.Add($"{texName}{Delimiter}{icon.Key}", bmp); //estimate area and side length area += width * height; if (width >= maxSideLength || height >= maxSideLength) { maxSideLength = 4096; } } } //Pack textures int size = 2048; if (maxSideLength > size || (area > 2048 * 2048 && psb.Header.Version > 2)) { size = 4096; } int padding = TexturePadding >= 0 && TexturePadding <= 100 ? TexturePadding : 1; TexturePacker packer = new TexturePacker { FitHeuristic = FitHeuristic }; packer.Process(textures, TextureSideLength ?? size, padding); //Add packed textures to source List <PsbDictionary> texs = new List <PsbDictionary>(); for (var i = 0; i < packer.Atlasses.Count; i++) { var atlas = packer.Atlasses[i]; var data = UseRL ? RL.CompressImage((Bitmap)atlas.ToImage(), TargetPixelFormat) : RL.GetPixelBytesFromImage(atlas.ToImage(), TargetPixelFormat); var texDic = new PsbDictionary(4); //metadata texDic.Add("metadata", new PsbString(i.ToString("D3"))); var texName = $"tex#{texDic["metadata"]}"; //icon var icons = new PsbDictionary(atlas.Nodes.Count); texDic.Add("icon", icons); int id = 0; foreach (var node in atlas.Nodes) { if (node.Texture == null) { continue; } var paths = node.Texture.Source.Split(new[] { Delimiter }, StringSplitOptions.RemoveEmptyEntries); var icon = (PsbDictionary)source[paths[0]].Children("icon").Children(paths[1]); icon.Remove("compress"); icon.Remove("pixel"); icon["attr"] = PsbNumber.Zero; icon["left"] = new PsbNumber(node.Bounds.Left); icon["top"] = new PsbNumber(node.Bounds.Top); icon.Parent = icons; var iconName = UseMeaningfulName ? node.Texture.Source : id.ToString(); icons.Add(iconName, icon); iconInfos.Add(node.Texture.Source, (texName, iconName)); id++; } //texture //TODO: support truncated var texture = new PsbDictionary(6) { { "height", new PsbNumber(atlas.Height) }, { "width", new PsbNumber(atlas.Width) }, { "truncated_height", new PsbNumber(atlas.Height) }, { "truncated_width", new PsbNumber(atlas.Width) }, { "type", new PsbString(TargetPixelFormat.ToStringForPsb()) } }; texture.Add("pixel", new PsbResource { Data = data, Parents = new List <IPsbCollection> { texture } }); texDic.Add("texture", texture); //type texDic.Add("type", PsbNumber.Zero); texs.Add(texDic); } source.Clear(); foreach (var t in texs) { source.Add($"tex#{t["metadata"]}", t); t["metadata"] = PsbNull.Null; } return(iconInfos); }
int GetIntValue(PsbNumber num, int ori) => deDuplication?Math.Max((int)num, ori) : (int)num;