public void UpdateTxm2DWithImage(TXM Txm, Bitmap Bitmap, params string[] TxmNames) { foreach (var Name in TxmNames) { Txm.Surface2DEntriesByName[Name].UpdateBitmap(Bitmap); } }
public void UpdateTxm2DWithEmpty(TXM Txm, params string[] TxmNames) { foreach (var Name in TxmNames) { var Entry = Txm.Surface2DEntriesByName[Name]; Entry.UpdateBitmap(new Bitmap(Entry.Width, Entry.Height)); } }
//private void ReduceRowColors(Bitmap Bitmap) //{ // for (int y = 0; y < Bitmap.Height; y++) // { // var Rle = new List<RleItem>(); // for (int x = 0; x < Bitmap.Width - 1; x++) // { // int R = Bitmap.GetPixel(x + 0, y).R; // int G = Bitmap.GetPixel(x + 0, y).G; // int B = Bitmap.GetPixel(x + 0, y).B; // int Count = 1; // while ((x < Bitmap.Width - 1) && (ColorDistance(Bitmap.GetPixel(x, y), Bitmap.GetPixel(x + 1, y)) < 6)) // { // R += Bitmap.GetPixel(x + 1, y).R; // G += Bitmap.GetPixel(x + 1, y).G; // B += Bitmap.GetPixel(x + 1, y).B; // Count++; // x++; // } // var Color2 = Color.FromArgb(R / Count, G / Count, B / Count); // Rle.Add(new RleItem(Color2, Count)); // //Console.WriteLine("{0}: {1}", Color2, Count); // } // int x2 = 0; // ReduceRle(Rle); // foreach (var Item in Rle) // { // var Color = Item.Color; // var Count = Item.Count; // while (Count-- > 0) Bitmap.SetPixel(x2++, y, Color); // } // } //} // //public void UpdateTxm2DWithPngDxt5Loosy(TXM Txm, string PatchPngPath, params string[] TxmNames) //{ // PatcherGetImage(PatchPngPath, (Bitmap) => // { // //Bitmap = new DXT5().CompressColors(Bitmap); // ReduceRowColors(Bitmap); // // Bitmap.Save(@"c:\temp\temp." + TxmNames[0] + ".png"); // foreach (var Name in TxmNames) // { // Txm.Surface2DEntriesByName[Name].UpdateBitmap(Bitmap); // } // }); //} public void UpdateTxm2DWithPng(TXM Txm, string PatchPngPath, params string[] TxmNames) { PatcherGetImage(PatchPngPath, (Bitmap) => { foreach (var Name in TxmNames) { Txm.Surface2DEntriesByName[Name].UpdateBitmap(Bitmap); } }); }
public override string ToString() { using (FPS4 fps4 = new FPS4(Stream.Duplicate())) using (DuplicatableStream txmvStream = fps4.GetChildByIndex(1).AsFile.DataStream.Duplicate()) using (FPS4 txmv = new FPS4(txmvStream.Duplicate())) using (DuplicatableStream txmStream = txmv.GetChildByIndex(0).AsFile.DataStream.Duplicate()) { TXM txm = new TXM(txmStream.Duplicate()); return(txm.TXMRegulars[0].Name); } }
public static Stream ProcessTexture(string name, DuplicatableStream ustream, DuplicatableStream wstream) { FPS4 w = new FPS4(wstream.Duplicate()); TXM wtxm = new TXM(w.GetChildByIndex(0).AsFile.DataStream.Duplicate()); TXV wtxv = new TXV(wtxm, w.GetChildByIndex(1).AsFile.DataStream.Duplicate(), false); FPS4 u = new FPS4(ustream.Duplicate()); TXM utxm = new TXM(u.GetChildByIndex(0).AsFile.DataStream.Duplicate()); TXV utxv = new TXV(utxm, u.GetChildByIndex(1).AsFile.DataStream.Duplicate(), false); List <TexConvRules> convs = new List <TexConvRules>(); if (name == "rootR.cpk/mg/tex/karuta.tex") { convs.Add(new TexConvRules() { WTexId = 2, UTexId = 1, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKarutaHalfAndHalf(wtex, utex, 82, 134, 294) }); convs.Add(new TexConvRules() { WTexId = 4, UTexId = 3, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKarutaHalfAndHalf(wtex, utex, 86, 134, 294) }); convs.Add(new TexConvRules() { WTexId = 7, UTexId = 7, Method = TexConvMethod.DownscaleTwoThirds }); convs.Add(new TexConvRules() { WTexId = 13, UTexId = 13, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DoKaruta13(wtex, utex) }); convs.Add(new TexConvRules() { WTexId = 17, UTexId = 17, Method = TexConvMethod.DownscaleTwoThirds }); convs.Add(new TexConvRules() { WTexId = 22, UTexId = 23, Method = TexConvMethod.Delegate, Delegate = (wtex, utex) => DownscaleTwoThirds(CropExpandCanvas(utex, 2, -2, (uint)(utex.Width + 3), (uint)(utex.Height - 3))) }); } else if (name == "rootR.cpk/mnu/tex/main.tex") { convs.Add(new TexConvRules() { WTexId = 110, UTexId = 61, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 111, UTexId = 62, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 112, UTexId = 63, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 113, UTexId = 64, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 114, UTexId = 65, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 115, UTexId = 66, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 116, UTexId = 67, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 117, UTexId = 68, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 118, UTexId = 69, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 119, UTexId = 70, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 124, UTexId = 75, Method = TexConvMethod.Downscale2x }); } else if (name == "rootR.cpk/mnu/tex/shop.tex") { convs.Add(new TexConvRules() { WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 2, UTexId = 2, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 3, UTexId = 3, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 4, UTexId = 4, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 5, UTexId = 5, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 6, UTexId = 6, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 7, UTexId = 7, Method = TexConvMethod.Downscale2x }); } else if (name == "rootR.cpk/mnu/tex/skill.tex") { convs.Add(new TexConvRules() { WTexId = 0, UTexId = 0, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 2, UTexId = 2, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 3, UTexId = 3, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 4, UTexId = 4, Method = TexConvMethod.Downscale2x }); convs.Add(new TexConvRules() { WTexId = 5, UTexId = 5, Method = TexConvMethod.Downscale2x }); } else if (name == "rootR.cpk/mnu/tex/snd_test.tex") { convs.Add(new TexConvRules() { WTexId = 1, UTexId = 1, Method = TexConvMethod.Downscale2x }); } else if (name == "rootR.cpk/SysSub/JA/TitleTexture.tex") { convs.Add(new TexConvRules() { WTexId = 1, UTexId = 1, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 2, UTexId = 4, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 3, UTexId = 6, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 4, UTexId = 8, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 6, UTexId = 12, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 7, UTexId = 14, Method = TexConvMethod.CropExpandCanvas }); convs.Add(new TexConvRules() { WTexId = 8, UTexId = 16, Method = TexConvMethod.CropExpandCanvas }); } else if (name.EndsWith(".CLG")) { convs.Add(new TexConvRules() { WTexId = 0, UTexId = 0, Method = TexConvMethod.DownscaleTwoThirds }); convs.Add(new TexConvRules() { WTexId = 1, UTexId = 1, Method = TexConvMethod.Clear }); } MemoryStream s = wstream.Duplicate().CopyToMemory(); s.Position = 0; foreach (TexConvRules c in convs) { var wm = wtxm.TXMRegulars[c.WTexId]; var um = utxm.TXMRegulars[c.UTexId]; var wv = wtxv.textures.Where(x => x.TXM == wm).First(); var uv = utxv.textures.Where(x => x.TXM == um).First(); System.Drawing.Bitmap newImage = null; switch (c.Method) { case TexConvMethod.Downscale2x: { newImage = FontProcessing.DownscaleInteger(uv.GetBitmaps()[0], 2); } break; case TexConvMethod.DownscaleTwoThirds: { newImage = DownscaleTwoThirds(uv.GetBitmaps()[0]); } break; case TexConvMethod.CropExpandCanvas: { newImage = DoCropExpandCanvas(uv.GetBitmaps()[0], wm.Width, wm.Height); } break; case TexConvMethod.Clear: { newImage = new Bitmap(wv.GetBitmaps()[0]); for (int y = 0; y < newImage.Height; ++y) { for (int x = 0; x < newImage.Width; ++x) { newImage.SetPixel(x, y, Color.FromArgb(0, 0, 0, 0)); } } } break; case TexConvMethod.Delegate: { newImage = c.Delegate(wv.GetBitmaps()[0], uv.GetBitmaps()[0]); } break; default: { throw new Exception("don't know how to convert " + uv.TXM.Name); } } if (newImage != null) { HyoutaTools.Util.Assert(newImage.Width == wm.Width); HyoutaTools.Util.Assert(newImage.Height == wm.Height); if (wm.Format == HyoutaTools.Tales.Vesperia.Texture.TextureFormat.Indexed8Bits_RGB5A3) { ChopBitsRGB5A3(newImage); var palette = GeneratePalette256(newImage); s.Position = w.Files[1].Location.Value + wm.TxvLocation; foreach (var loc in new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(newImage.Width, newImage.Height, 8, 4)) { int cval = 0; if (loc.X < newImage.Width && loc.Y < newImage.Height) { cval = palette.lookup[newImage.GetPixel(loc.X, loc.Y)]; } s.WriteByte((byte)cval); } for (int ci = 0; ci < 256; ++ci) { ushort cval = 0; if (ci < palette.colors.Count) { cval = HyoutaTools.Textures.ColorFetchingIterators.ColorFetcherRGB5A3.ColorToRGB5A3(palette.colors[ci]); } s.WriteUInt16(cval.ToEndian(EndianUtils.Endianness.BigEndian)); } } else if (wm.Format == HyoutaTools.Tales.Vesperia.Texture.TextureFormat.GamecubeRGBA8) { s.Position = w.Files[1].Location.Value + wm.TxvLocation; byte[] tmpb = new byte[0x40]; int tmpp = 0; foreach (var loc in new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(newImage.Width, newImage.Height, 4, 4)) { Color col = newImage.GetPixel(loc.X, loc.Y); tmpb[tmpp * 2 + 0] = col.A; tmpb[tmpp * 2 + 1] = col.R; tmpb[tmpp * 2 + 0 + 0x20] = col.G; tmpb[tmpp * 2 + 1 + 0x20] = col.B; ++tmpp; if (tmpp == 16) { tmpp = 0; s.Write(tmpb); } } if (tmpp != 0) { throw new Exception("Unexpected tile size for " + wm.Name); } } else { Console.WriteLine("don't know how to encode into " + wm.Format); } } } s.Position = 0; return(s); }
public static (DuplicatableStream metrics, DuplicatableStream texture, Dictionary <char, (int w1, int w2)> charToWidthMap) Run(FileFetcher _fc, Config config) { bool debug = config.DebugFontOutputPath != null; bool adjustMetrics = debug; DuplicatableStream metricsWiiStream = _fc.GetFile("rootR.cpk/sys/FontBinary2.bin", Version.W); DuplicatableStream textureWiiStream = _fc.GetFile("rootR.cpk/sys/FontTexture2.tex", Version.W); DuplicatableStream texturePs3Stream = _fc.GetFile("rootR.cpk/sys/FontTexture2.tex", Version.U); FPS4 metricsWiiFps4 = new FPS4(metricsWiiStream); DuplicatableStream metricsWiiData = metricsWiiFps4.GetChildByIndex(1).AsFile.DataStream; FPS4 textureWiiFps4 = new FPS4(textureWiiStream); FPS4 texturePs3Fps4 = new FPS4(texturePs3Stream); TXM textureWiiTxm = new TXM(textureWiiFps4.GetChildByIndex(0).AsFile.DataStream); TXV textureWiiTxv = new TXV(textureWiiTxm, textureWiiFps4.GetChildByIndex(1).AsFile.DataStream, false); TXM texturePs3Txm = new TXM(texturePs3Fps4.GetChildByIndex(0).AsFile.DataStream); TXV texturePs3Txv = new TXV(texturePs3Txm, texturePs3Fps4.GetChildByIndex(1).AsFile.DataStream, false); Bitmap bitmapWii = textureWiiTxv.textures[0].GetBitmaps()[0]; Bitmap bitmapPs3 = texturePs3Txv.textures[0].GetBitmaps()[0]; if (debug) { Directory.CreateDirectory(config.DebugFontOutputPath); bitmapWii.Save(Path.Combine(config.DebugFontOutputPath, "wii.png")); bitmapPs3.Save(Path.Combine(config.DebugFontOutputPath, "ps3.png")); } var img_wii = bitmapWii; var img_ps3 = bitmapPs3; const int tile_extent_in_image = 25; const int tile_extent_actual = 24; int tiles_x = (img_wii.Width + 1) / tile_extent_in_image; int tiles_y = (img_wii.Height + 1) / tile_extent_in_image; const int ps3_tile_extent_in_image = 37; const int ps3_tile_extent_actual = 36; int ps3_tiles_x = (img_ps3.Width + 1) / ps3_tile_extent_in_image; int ps3_tiles_y = (img_ps3.Height + 1) / ps3_tile_extent_in_image; // split into individual tiles and extract source colors HashSet <Color> colors = new HashSet <Color>(); List <Bitmap> tiles_wii = new List <Bitmap>(); List <Bitmap> tiles_ps3 = new List <Bitmap>(); for (int ty = 0; ty < tiles_y; ++ty) { for (int tx = 0; tx < tiles_x; ++tx) { var bmp = new Bitmap(tile_extent_actual, tile_extent_actual); for (int y = 0; y < tile_extent_actual; ++y) { for (int x = 0; x < tile_extent_actual; ++x) { var px = img_wii.GetPixel(tx * tile_extent_in_image + x, ty * tile_extent_in_image + y); colors.Add(px); bmp.SetPixel(x, y, px); } } tiles_wii.Add(bmp); } } for (int ty = 0; ty < ps3_tiles_y; ++ty) { for (int tx = 0; tx < ps3_tiles_x; ++tx) { var bmp = new Bitmap(ps3_tile_extent_actual, ps3_tile_extent_actual); for (int y = 0; y < ps3_tile_extent_actual; ++y) { for (int x = 0; x < ps3_tile_extent_actual; ++x) { var px = img_ps3.GetPixel(tx * ps3_tile_extent_in_image + x, ty * ps3_tile_extent_in_image + y); bmp.SetPixel(x, y, px); } } tiles_ps3.Add(bmp); } } // inject ps3 tiles over wii tiles List <(int where, int ps3where, string chars)> charsets = new List <(int where, int ps3where, string chars)>(); charsets.Add((0, 0, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")); charsets.Add((243, 74, ",.")); charsets.Add((246, 77, ":;?!_")); charsets.Add((254, 83, "/\\~|…")); charsets.Add((260, 118, "‘")); charsets.Add((261, 118, "’")); charsets.Add((262, 119, "“")); charsets.Add((263, 119, "”")); charsets.Add((264, 93, "()[]{}")); charsets.Add((276, 105, "+")); charsets.Add((277, 82, "-")); // copy the dash minus instead of the math minus, looks better in text flow charsets.Add((278, 107, "±×÷=≠<>≤≥")); charsets.Add((289, 118, "'\"")); charsets.Add((293, 122, "$%#&*@")); Dictionary <char, (int w1, int w2)> charToWidthMap = new Dictionary <char, (int w1, int w2)>(); byte[] metrics = new byte[metricsWiiData.Length]; metricsWiiData.Read(metrics, 0, metrics.Length); foreach (var charset in charsets) { int where = charset.where; int ps3where = charset.ps3where; foreach (char ch in charset.chars) { var wiitile = tiles_wii[where]; var averagescaled = DownscaleTileFromPs3ToWiiWithUnweightedAverageScaling(tiles_ps3[ps3where]); //var downscaled = DownscaleTileFromPs3ToWiiWithWeightedScaling(tiles_ps3[ps3where]); var downscaled = averagescaled; PosterizeImage(wiitile, downscaled, colors, tile_extent_actual); PosterizeImage(averagescaled, averagescaled, colors, tile_extent_actual); if (debug) { wiitile.Save(Path.Combine(config.DebugFontOutputPath, string.Format("wii_new_{0:D4}.png", where))); } int cutoff_1 = 180; int cutoff_2 = 220; int leftwhere = where * 8 + 0; int rightwhere = where * 8 + 1; int leftwhere2 = where * 8 + 4; int rightwhere2 = where * 8 + 5; // forcing vertical extents to be the same for all, because text looks *really weird* in english if lines have different heights // for digits, forcing horizontal extents to be the same as well so they look nice in vertical lists bool isDigit = ch == '0' || ch == '1' || ch == '2' || ch == '3' || ch == '4' || ch == '5' || ch == '6' || ch == '7' || ch == '8' || ch == '9'; if (isDigit) { metrics[leftwhere] = ch == '1' ? (byte)(6) : ch == '2' ? (byte)(6) : (byte)(7); metrics[rightwhere] = ch == '1' ? (byte)(8) : ch == '2' ? (byte)(8) : (byte)(7); //metrics[leftwhere2] = ch == '1' ? (byte)(7) : ch == '2' ? (byte)(7) : (byte)(8); //metrics[rightwhere2] = ch == '1' ? (byte)(9) : ch == '2' ? (byte)(9) : (byte)(8); } else { metrics[leftwhere] = (byte)MeasureAlphaFromLeft(averagescaled, cutoff_1); metrics[rightwhere] = (byte)MeasureAlphaFromRight(averagescaled, cutoff_1); //metrics[leftwhere2] = (byte)MeasureAlphaFromLeft(averagescaled, cutoff_2); //metrics[rightwhere2] = (byte)MeasureAlphaFromRight(averagescaled, cutoff_2); } switch (ch) { case 'j': case ';': metrics[leftwhere] += 1; break; case 'A': case 'P': case 'Q': case 'T': case 'Y': case 'W': case 'f': case 's': case 'w': case 'y': case '[': metrics[rightwhere] += 1; break; case 't': metrics[leftwhere] += 1; metrics[rightwhere] += 1; break; default: break; } metrics[leftwhere2] = metrics[leftwhere]; metrics[rightwhere2] = metrics[rightwhere]; switch (ch) { case '.': case ',': metrics[leftwhere2] += 1; metrics[rightwhere] += 1; break; default: break; } metrics[where * 8 + 2] = 0; //(byte)MeasureAlphaFromTop(test, cutoff_1); metrics[where * 8 + 3] = 4; //(byte)MeasureAlphaFromBottom(test, cutoff_1); metrics[where * 8 + 6] = 0; //(byte)MeasureAlphaFromTop(test, cutoff_2); metrics[where * 8 + 7] = 4; //(byte)MeasureAlphaFromBottom(test, cutoff_2); int width1 = tile_extent_actual - (metrics[leftwhere] + metrics[rightwhere]); int width2 = tile_extent_actual - (metrics[leftwhere2] + metrics[rightwhere2]); charToWidthMap.Add(ch, (width1, width2)); ++where; ++ps3where; } } // manually generate good metrics for space; see also code patches in main.dol metrics[0x6F70] = 10; metrics[0x6F71] = 10; metrics[0x6F72] = 0; metrics[0x6F73] = 4; metrics[0x6F74] = 10; metrics[0x6F75] = 10; metrics[0x6F76] = 0; metrics[0x6F77] = 4; charToWidthMap.Add(' ', (tile_extent_actual - 20, tile_extent_actual - 20)); // write out visual representation of font metrics for adjustments if (adjustMetrics) { foreach (var charset in charsets) { int where = charset.where; foreach (char ch in charset.chars) { int factor = 10; var test = PointScale(tiles_wii[where], factor); for (int metricsset = 0; metricsset < 2; ++metricsset) { Color col = metricsset == 0 ? Color.Red : Color.Yellow; int xl = (metrics[where * 8 + metricsset * 4] - 1) * factor + factor - 1; int xr = (tiles_wii[where].Width - metrics[where * 8 + metricsset * 4 + 1]) * factor; int yt = (metrics[where * 8 + metricsset * 4 + 2] - 1) * factor + factor - 1; int yb = (tiles_wii[where].Width - metrics[where * 8 + metricsset * 4 + 3]) * factor; for (int y = 0; y < test.Height; ++y) { if (xl >= 0 && xl < test.Width) { test.SetPixel(xl, y, col); } if (xr >= 0 && xr < test.Width) { test.SetPixel(xr, y, col); } } for (int x = 0; x < test.Width; ++x) { if (yt >= 0 && yt < test.Height) { test.SetPixel(x, yt, col); } if (yb >= 0 && yb < test.Height) { test.SetPixel(x, yb, col); } } } PointScale(test, 3).Save(Path.Combine(config.DebugFontOutputPath, string.Format("metrics_view_{0:D4}.png", where))); ++where; } } } // join indvidiual tiles back into full texture int idx = 0; for (int ty = 0; ty < tiles_y; ++ty) { for (int tx = 0; tx < tiles_x; ++tx) { var bmp = tiles_wii[idx]; for (int y = 0; y < tile_extent_actual; ++y) { for (int x = 0; x < tile_extent_actual; ++x) { var px = bmp.GetPixel(x, y); img_wii.SetPixel(tx * tile_extent_in_image + x, ty * tile_extent_in_image + y, px); } } ++idx; } } if (debug) { img_wii.Save(Path.Combine(config.DebugFontOutputPath, "wii_new.png")); } // inject metrics DuplicatableStream outputMetricsStream; { Stream stream = metricsWiiStream.Duplicate().CopyToMemory(); stream.Position = 0x43E0; stream.Write(metrics); stream.Position = 0; byte[] data = new byte[stream.Length]; stream.Read(data, 0, data.Length); outputMetricsStream = new HyoutaUtils.Streams.DuplicatableByteArrayStream(data); } // encode texture DuplicatableStream outputTextureStream; { Stream stream = textureWiiStream.Duplicate().CopyToMemory(); stream.Position = 0x80100; List <(int idx, ushort v)> stuff = new List <(int idx, ushort v)>(); for (int i = 0; i < 16; ++i) { stuff.Add((i, stream.ReadUInt16().FromEndian(EndianUtils.Endianness.BigEndian))); } stream.Position = 0x100; var pxit = new HyoutaTools.Textures.PixelOrderIterators.TiledPixelOrderIterator(img_wii.Width, img_wii.Height, 8, 8); byte storage = 0; bool even = false; foreach (var px in pxit) { if (px.X < img_wii.Width && px.Y < img_wii.Height) { Color col = img_wii.GetPixel(px.X, px.Y); ushort value = HyoutaTools.Textures.ColorFetchingIterators.ColorFetcherGrey8Alpha8.ColorToGrey8Alpha8(col); var colidx = stuff.First(x => x.v == value).idx; if (!even) { storage = (byte)colidx; } else { storage = (byte)(storage << 4 | (byte)colidx); stream.WriteByte(storage); } even = !even; } } stream.Position = 0; byte[] data = new byte[stream.Length]; stream.Read(data, 0, data.Length); outputTextureStream = new HyoutaUtils.Streams.DuplicatableByteArrayStream(data); } return(outputMetricsStream, outputTextureStream, charToWidthMap); }
protected void Expand(string FilePath) { if (FilePath.Contains('*') || FilePath.Contains('?')) { var BasePath = Path.GetDirectoryName(FilePath); var Recursive = false; if (BasePath == "") { BasePath = "."; } foreach (var FileName in Directory.EnumerateFiles(BasePath, Path.GetFileName(FilePath), Recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)) { Expand(FileName); } return; } var ListToExpand = new List <string>(); //Console.WriteLine("Expanding '{0}'...", FilePath); using (var _FileStream = File.OpenRead(FilePath)) { if (_FileStream.Length == 0) { //Console.WriteLine("EMPTY: {0}", FilePath); return; } var FileStream = DecompressIfCompressedStream(_FileStream); var MagicData = FileStream.Slice().ReadBytesUpTo(0x100); if (false) { } else if (TO8SCEL.IsValid(MagicData)) { try { var To8Scel = new TO8SCEL(FileStream); foreach (var Entry in To8Scel) { var EntryFilePath = FilePath + ".d/" + Entry.Index; if (Overwrite || !File.Exists(EntryFilePath)) { Console.WriteLine("{0}", EntryFilePath); try { var EntryStream = DecompressIfCompressedStream(Entry.CompressedStream); if (EntryStream.Length > 0) { EntryStream.CopyToFile(EntryFilePath); } } catch (Exception Exception) { ShowException(Exception); } } if (File.Exists(EntryFilePath)) { ListToExpand.Add(EntryFilePath); } } } catch (Exception Exception) { ShowException(Exception); } } else if (FPS4.IsValid(MagicData)) { //Console.WriteLine("FPS4"); try { var Fps4 = new FPS4(FileStream); foreach (var Entry in Fps4) { var EntryFilePath = FilePath + ".d/" + Entry.Name; if (Overwrite || !File.Exists(EntryFilePath)) { Console.WriteLine("{0}", EntryFilePath); try { var EntryStream = DecompressIfCompressedStream(Entry.Open()); if (EntryStream.Length > 0) { EntryStream.CopyToFile(EntryFilePath); } } catch (Exception Exception) { ShowException(Exception); } } if (File.Exists(EntryFilePath)) { ListToExpand.Add(EntryFilePath); } } } catch (Exception Exception) { ShowException(Exception); } } else if (TSS.IsValid(MagicData)) { int RoomId = 0; try { RoomId = int.Parse(Path.GetFileNameWithoutExtension(FilePath)); } catch { } var TxtFile = FilePath + ".txt"; Console.WriteLine("{0}", TxtFile); if (Overwrite || !File.Exists(TxtFile)) { var Tss = new TSS().Load(FileStream.Slice()); using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { try { Tss.DumpTexts(TextWriter); } catch (Exception Exception) { ShowException(Exception); } } } var ScrFile = FilePath + ".scr"; Console.WriteLine("{0}", ScrFile); if (Overwrite || !File.Exists(ScrFile)) { var Tss = new TSS().Load(FileStream.Slice()); using (var TxtStream = File.Open(ScrFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { try { var ErrorString = ConsoleUtils.CaptureError(() => { Tss.DumpScript(TextWriter); }); } catch (Exception Exception) { ShowException(Exception); } } } } else if (TO8CHTX.IsValid(MagicData)) { var Chtx = new TO8CHTX(FileStream); var TxtFile = FilePath + ".txt"; Console.WriteLine("{0}", TxtFile); if (Overwrite || !File.Exists(TxtFile)) { using (var TxtStream = File.Open(TxtFile, FileMode.Create, FileAccess.Write)) using (var TextWriter = new StreamWriter(TxtStream)) { foreach (var Entry in Chtx.Entries) { TextWriter.WriteLine("{0}", Entry.Title); TextWriter.WriteLine("{0}", Entry.TextOriginal); TextWriter.WriteLine("{0}", Entry.TextTranslated); TextWriter.WriteLine(""); } } //Chtx.Entries[0].Title //Console.WriteLine("CHAT!"); } } else if (SE3.IsValid(MagicData)) { var Se3 = new SE3().Load(FileStream); foreach (var Entry in Se3.Entries) { var EntryFullNameXma = FilePath + "." + Entry.Name + ".xma"; var EntryFullNameWav = FilePath + "." + Entry.Name + ".wav"; Console.WriteLine("{0}", EntryFullNameXma); if (Overwrite || !File.Exists(EntryFullNameXma)) { Entry.ToXmaWav().CopyToFile(EntryFullNameXma); } if (Overwrite || !File.Exists(EntryFullNameWav)) { using (var WavOut = File.Open(EntryFullNameWav, FileMode.Create, FileAccess.Write)) { Entry.ToWav(WavOut); } } } } else if (TXM.IsValid(MagicData)) { string BasePath; string TxmPath; string TxvPath; if (Path.GetExtension(FilePath).ToLower() == ".txm") { BasePath = Path.GetDirectoryName(FilePath) + "/" + Path.GetFileNameWithoutExtension(FilePath); TxmPath = BasePath + ".txm"; TxvPath = BasePath + ".txv"; } else { var DirectoryPath = Path.GetDirectoryName(FilePath); TxmPath = DirectoryPath + "/" + Path.GetFileName(FilePath); TxvPath = DirectoryPath + "/" + (int.Parse(Path.GetFileName(TxmPath)) + 1); BasePath = TxmPath; } var Txm = TXM.FromTxmTxv(File.OpenRead(TxmPath), File.OpenRead(TxvPath)); /* * if (Txm.Surface2DEntries.Length > 0 && Txm.Surface3DEntries.Length > 0) * { * // 3D and 2D surfaces * //Console.WriteLine("ERROR 3D and 2D SURFACES! (2D: {0}, 3D: {1})", Txm.Surface2DEntries.Length, Txm.Surface3DEntries.Length); * } * else if (Txm.Surface2DEntries.Length > 0) * { * // 2D Surfaces * //Console.WriteLine("2D SURFACES! {0}", Txm.Surface2DEntries.Length); * } * else if (Txm.Surface3DEntries.Length > 0) * { * // 3D Surfaces * //Console.WriteLine("3D SURFACES! {0}", Txm.Surface3DEntries.Length); * } */ foreach (var Entry in Txm.Surface2DEntries) { var ImagePath = BasePath + "." + Entry.Name + ".png"; if (Overwrite || !File.Exists(ImagePath)) { try { Entry.Bitmap.Save(ImagePath); } catch (Exception Exception) { ShowException(Exception); } } } foreach (var Entry in Txm.Surface3DEntries) { var ImagePath0 = BasePath + "." + Entry.Name + "." + 0 + ".png"; if (Overwrite || !File.Exists(ImagePath0)) { try { var n = 0; foreach (var Bitmap in Entry.Bitmaps.Bitmaps) { var ImagePath = BasePath + "." + Entry.Name + "." + n + ".png"; Console.WriteLine("{0}", ImagePath); if (Overwrite || !File.Exists(ImagePath)) { Bitmap.Save(ImagePath); } n++; } } catch (Exception Exception) { ShowException(Exception); } } } } else { } } // Expand all the queued stuff foreach (var Item in ListToExpand) { try { Expand(Item); } catch (Exception Exception) { Console.WriteLine(" ERROR: {0}", Verbose ? Exception.ToString() : Exception.Message.ToString()); } } }