protected override void ReadInternal(Reader reader) { R2ROMLoader l = MapLoader.Loader as R2ROMLoader; if (Settings.s.platform == Settings.Platform._3DS) { wExponent = reader.ReadByte(); hExponent = reader.ReadByte(); flags = reader.ReadUInt16(); flags2 = reader.ReadUInt16(); color_size = reader.ReadUInt16(); bpp = reader.ReadUInt16(); name = reader.ReadString(200); off_texture = Pointer.Current(reader); textureBytes = reader.ReadBytes(color_size); // max size: 0x10000 Texture2D rawTex = new ETC(textureBytes, 1 << wExponent, 1 << hExponent, bpp == 32).texture; if (l.exportTextures) { if (!File.Exists(l.gameDataBinFolder + "/textures/" + Path.GetDirectoryName(name) + "/" + Path.GetFileNameWithoutExtension(name) + ".png")) { Util.ByteArrayToFile(l.gameDataBinFolder + "/textures/" + Path.GetDirectoryName(name) + "/" + Path.GetFileNameWithoutExtension(name) + ".png", rawTex.EncodeToPNG()); } } Texture = rawTex; } else if (Settings.s.platform == Settings.Platform.DS || Settings.s.platform == Settings.Platform.N64) { texture_index = reader.ReadUInt16(); palette_index = reader.ReadUInt16(); alpha_index = reader.ReadUInt16(); wExponent = reader.ReadByte(); hExponent = reader.ReadByte(); flags = reader.ReadUInt16(); color_size = reader.ReadUInt16(); if (Settings.s.platform == Settings.Platform.DS) { palette_num_colors = reader.ReadUInt16(); } else { palette_num_colors = 16; } ushort ind_texture = 0xFFFF; bool rgba16 = alpha_index != 0xFFFF && texture_index != 0xFFFF; GF64.Format format = GF64.Format.I4; if ((flags & 1) != 0) { ind_texture = (ushort)((texture_index + l.ind_textureTable_i4) & 0xFFFF); } else if ((flags & 2) != 0) { format = GF64.Format.I8; ind_texture = (ushort)((texture_index + l.ind_textureTable_i8) & 0xFFFF); if (Settings.s.platform == Settings.Platform.N64) { palette_num_colors = 256; } } else if ((flags & 4) != 0) { format = GF64.Format.RGBA; ind_texture = (ushort)((texture_index + l.ind_textureTable_rgba) & 0xFFFF); } if (ind_texture != 0xFFFF) { off_texture = l.texturesTable[ind_texture]; if (l.texturesTableSeen != null) { l.texturesTableSeen[ind_texture] = true; } } if (alpha_index != 0xFFFF) { off_alpha = l.texturesTable[alpha_index]; if (l.texturesTableSeen != null) { l.texturesTableSeen[alpha_index] = true; } } off_palette = null; /*if (Settings.s.platform == Settings.Platform.DS) { * format = rgba16 ? GF64.Format.RGBA : (palette_num_colors == 16 ? GF64.Format.I4 : GF64.Format.I8); * }*/ if (palette_index != 0xFFFF) { if (Settings.s.platform == Settings.Platform.DS) { off_palette = l.palettesTable[palette_index & 0x7FFF]; if (l.palettesTableSeen != null) { l.palettesTableSeen[palette_index & 0x7FFF] = true; } } else { off_palette = l.GetStructPtr(FATEntry.Type.Palette, palette_index, global: true); } } /*l.print(((1 << hExponent) * (1 << wExponent)) + "\t" + (1 << wExponent) + "\t" + (1 << hExponent) + "\t" + (texture_index == 0xFFFF ? "-" : texture_index.ToString()) + "\t" + (alpha_index == 0xFFFF ? "-" : alpha_index.ToString()) + "\t" + (palette_index == 0xFFFF ? "-" : (palette_index & 0x7FFF).ToString()) + "\t" + String.Format("{0:X4}", flags) + "\t" + color_size + "\t" + palette_num_colors + "\t" + off_texture + "\t" + off_alpha + "\t" + off_palette + "\t");*/ if (off_texture != null) { mainTex = new GF64(reader, off_texture, (1 << wExponent), (1 << hExponent), format, off_palette, palette_num_colors); } if (off_alpha != null) { alphaTex = new GF64(reader, off_alpha, (1 << wExponent), (1 << hExponent), GF64.Format.I4Alpha, null, palette_num_colors); if (mainTex != null) { mainTex.LoadAlphaTexture(alphaTex); } } Texture2D rawTex = mainTex != null ? mainTex.texture : alphaTex?.texture; if (l.exportTextures) { if (rawTex != null) { string palette = (palette_index != 0xFFFF ? "_P" + (palette_index & 0x7FFF) : ""); string alpha = (alpha_index != 0xFFFF ? "_A" + (alpha_index & 0x7FFF) : ""); string main = (texture_index != 0xFFFF ? "_T" + (texture_index & 0x7FFF) : ""); if (!File.Exists(l.gameDataBinFolder + "/textures/" + format + main + alpha + palette + ".png")) { Util.ByteArrayToFile(l.gameDataBinFolder + "/textures/" + format + main + alpha + palette + ".png", rawTex.EncodeToPNG()); } } else { Debug.LogWarning("No mainTex or alphaTex for tex " + Offset); } } Texture = rawTex; } }
public void ExportTextures(Reader reader) { // Textures in data.bin texturesTableSeen = new bool[texturesTable.Length]; palettesTableSeen = new bool[palettesTable.Length]; for (int i = 0; i < fatTables.Length; i++) { for (int j = 0; j < fatTables[i].entries.Length; j++) { if (fatTables[i].entries[j].EntryType != FATEntry.Type.TextureInfo) { continue; } Pointer ptr = new Pointer(fatTables[i].entries[j].off_data, files_array[SMem.Data]); TextureInfo texInfo = new TextureInfo(); texInfo.Init(ptr, fatTables[i].entries[j].index); texInfo.Read(reader); } } for (int i = 0; i < texturesTable.Length; i++) { if (!texturesTableSeen[i]) { print("Unused Texture: " + i + " - " + texturesTable[i] + ". Est. length: " + (texturesTable[i + 1].offset - texturesTable[i].offset)); uint size = (texturesTable[i + 1].offset - texturesTable[i].offset); float logSize = Mathf.Log(size, 2); if (i < ind_textureTable_i8) { // I4 for (int w = 3; w < 15; w++) { for (int h = 3; h < 15; h++) { if (w + h == (int)logSize + 1) { GF64 gf = new GF64(reader, texturesTable[i], 1 << w, 1 << h, GF64.Format.I4, null, 16); Util.ByteArrayToFile(gameDataBinFolder + "/textures/unused/" + GF64.Format.I4 + "_T" + (i - ind_textureTable_i4) + "_" + gf.texture.width + "x" + gf.texture.height + ".png", gf.texture.EncodeToPNG()); } } } } else if (i < ind_textureTable_rgba) { // I8 for (int w = 3; w < 15; w++) { for (int h = 3; h < 15; h++) { if (w + h == (int)logSize) { GF64 gf = new GF64(reader, texturesTable[i], 1 << w, 1 << h, GF64.Format.I8, null, 32); Util.ByteArrayToFile(gameDataBinFolder + "/textures/unused/" + GF64.Format.I8 + "_T" + (i - ind_textureTable_i8) + "_" + gf.texture.width + "x" + gf.texture.height + ".png", gf.texture.EncodeToPNG()); } } } } else { // RGBA16 for (int w = 3; w < 15; w++) { for (int h = 3; h < 15; h++) { if (w + h == (int)logSize - 1) { GF64 gf = new GF64(reader, texturesTable[i], 1 << w, 1 << h, GF64.Format.RGBA, null, 32); Util.ByteArrayToFile(gameDataBinFolder + "/textures/unused/" + GF64.Format.RGBA + "_T" + (i - ind_textureTable_rgba) + "_" + gf.texture.width + "x" + gf.texture.height + ".png", gf.texture.EncodeToPNG()); } } } } } } /*for (int i = 0; i < palettesTable.Length; i++) { * if (!palettesTableSeen[i]) { * print("Unused Palette: " + i + " - " + palettesTable[i] + ". Est. num colors: " + (palettesTable[i+1].offset-palettesTable[i].offset)/2); * * if (!File.Exists(gameDataBinFolder + "/textures/unused/palettes/" + i + ".pal")) { * Pointer.DoAt(ref reader, palettesTable[i], () => { * byte[] bytes = reader.ReadBytes((int)(palettesTable[i + 1].offset - palettesTable[i].offset)); * Util.ByteArrayToFile(gameDataBinFolder + "/textures/unused/palettes/" + i + ".bin", bytes); * }); * } * } * }*/ //print("Unused textures: " + texturesTableSeen.Where(t => !t).Count() + " - Unused palettes: " + palettesTableSeen.Where(p => !p).Count()); if (Settings.s.platform == Settings.Platform.DS) { // R2 DS /*PAL palette = new PAL(gameDataBinFolder + "hud/objpal.bin"); * ExportNBFC("hud/sprlums1.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/sprcage1.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/sprraym1.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/sprraym2.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/sprenmy1.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/sprnumb0.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb1.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb2.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb3.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb4.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb5.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb6.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb7.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb8.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprnumb9.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/sprslash.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/spbars.nbfc", 1, 9, palette.palette); * ExportNBFC("hud/stick.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/stickbase.nbfc", 8, 8, palette.palette); * ExportNBFC("hud/sprspark.nbfc", 1, 1, palette.palette); * ExportNBFC("hud/ok.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/smaller.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/bigger.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/starhi.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/starmed.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/starlow.nbfc", 2, 2, palette.palette); * ExportNBFC("hud/slider.nbfc", 4, 4, palette.palette); * ExportNBFC("hud/slider.nbfc", 4, 4, palette.palette); * ExportGFX("hud/bgcalib.gfx", "hud/bgcalib.map", "hud/bgcalib.pal", 32, 32); // tiles: 768 * ExportGFX("hud/mainbg.gfx", "hud/mainbg.map", "hud/mainbg.pal", 32, 32); // tiles: 864*/ // RRR DS /*foreach (string bg in rrrMapBackgrounds) { * ExportGFX("hud/" + bg + ".bgc", "hud/" + bg + ".scr", "hud/" + bg + ".pal", 32, 32); * } * PAL[] palettes = rrrPalettes.Select(p => new PAL(gameDataBinFolder + "hud/" + p)).ToArray(); * foreach (RRRPalettedTextureReference texRef in rrrTexRefs) { * ExportNBFC("hud/" + texRef.name, texRef.width / 8, texRef.height / 8, palettes[texRef.palette].palette, i4: true); * } * ExportNBFC("hud/Cage_Icone.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Cage_Icone.pal").palette, i4: true); * ExportNBFC("hud/Etoile_Icone.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Etoile_Icone.pal").palette, i4: true); * ExportNBFC("hud/hud_map_corner.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/hud_Map_Ind.pal").palette, i4: true); * ExportNBFC("hud/ICO_Wind_NZ.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/ICO_Wind_NZ.pal").palette, i4: true); * ExportNBFC("hud/Jauge_Block.bgc", 1, 1, new PAL(gameDataBinFolder + "hud/Jauge_Block.pal").palette, i4: true); * ExportNBFC("hud/Jauge_Fond.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Jauge_Block.pal").palette, i4: true); * ExportNBFC("hud/Jauge_Quart.bgc", 1, 1, new PAL(gameDataBinFolder + "hud/Jauge_Block.pal").palette, i4: true); * ExportNBFC("hud/lums_jaune.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/lums_jaune.pal").palette, i4: true); * ExportNBFC("hud/Map2d_blocage.bgc", 1, 2, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Map2d_Cage.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Map2d_Crystal.bgc", 2, 4, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Map2d_Gard_Pris.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Map2d_Mont_Or.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Map2d_Teleport.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Map2d_blocage.pal").palette, i4: true); * ExportNBFC("hud/Panneau1.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Panneau1.pal").palette, i4: true); * ExportNBFC("hud/Panneau2.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Panneau2.pal").palette, i4: true); * ExportNBFC("hud/Panneau3.bgc", 4, 4, new PAL(gameDataBinFolder + "hud/Panneau3.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_0.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_1.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_2.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_3.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_4.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_5.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_6.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_7.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_8.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_9.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/Ray_Fnt_slash.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/Ray_Fnt_0.pal").palette, i4: true); * ExportNBFC("hud/trophee.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/trophee.pal").palette, i4: true); * ExportNBFC("hud/wifi_level_0.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/wifi_level_0.pal").palette, i4: true); * ExportNBFC("hud/wifi_level_1.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/wifi_level_0.pal").palette, i4: true); * ExportNBFC("hud/wifi_level_2.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/wifi_level_0.pal").palette, i4: true); * ExportNBFC("hud/wifi_level_3.bgc", 2, 2, new PAL(gameDataBinFolder + "hud/wifi_level_0.pal").palette, i4: true);*/ } if (Settings.s.platform == Settings.Platform._3DS) { // Stored separately for (int i = 1; i < 25; i++) { ExportEtcFile("LoadingAnimation/Course_" + i.ToString("D2") + ".etc", 64, 64, false); } ExportEtcFile("LoadingAnimation/home.etc", 64, 64, true); foreach (string file in Directory.EnumerateFiles(gameDataBinFolder + "/vignette")) { string fileName = file.Substring((gameDataBinFolder + "/vignette\\").Length); ExportEtcFile("vignette/" + fileName, 512, 256, false); } } }