public static SpriteFileLocations FromPsxIso(Stream iso) { SpriteFileLocations result = new SpriteFileLocations(); byte[] spriteBytes = PatcherLib.Iso.PsxIso.ReadFile(iso, spriteLocationsPosition); byte[] sp2Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, sp2LocationsPosition); var sp2 = new Dictionary <byte, SpriteLocation>(); for (byte i = 0; i < numSp2; i++) { const byte offset = 0x87; sp2[(byte)(i + offset)] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(sp2LocationsPosition.Sector, sp2LocationsPosition.StartLocation + i * 8, 8), sp2Bytes.Sub(i * 8, (i + 1) * 8 - 1)); } IList <SpriteLocation> sprites = new SpriteLocation[numSprites + numWep]; for (byte i = 0; i < numSprites; i++) { if (psxSp2toSpriteMapping.ContainsKey(i)) { IList <byte> values = psxSp2toSpriteMapping[i]; SpriteLocation[] sp2s = new SpriteLocation[values.Count]; for (int j = 0; j < values.Count; j++) { sp2s[j] = sp2[values[j]]; } sprites[i] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(spriteLocationsPosition.Sector, spriteLocationsPosition.StartLocation + i * 8, 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1), sp2s); } else { sprites[i] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(spriteLocationsPosition.Sector, spriteLocationsPosition.StartLocation + i * 8, 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1)); } } //byte[] wep1Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)); //byte[] wep2Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)); //byte[] wep3Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, (256 * 256 / 2 + 0x200) * 2, 256 * 144 / 2 + 0x200)); result.sprites = sprites; result.sp2 = sp2; return(result); }
public static bool DetectExpansionOfPsxIso(Stream iso) { UInt32 sectors = PatcherLib.Iso.PsxIso.ReadFile(iso, PatcherLib.Iso.PsxIso.NumberOfSectorsLittleEndian).ToUInt32(); //38 // length of record //00 // nothing //D6 E9 00 00 00 00 E9 D6 // sector //01 92 00 00 00 00 92 01 // size //61 // year //05 // month //10 // day //12 // hour //15 // minutes //1E // seconds //24 // GMT offset //01 // hidden file //00 00 //01 00 00 01 //09 // name length //31 30 4D 2E 53 50 52 3B 31 // name 10M.SPR;1 //2A 00 2A 00 // owner id //08 01 // attributes //58 41 // X A //00 // file number //00 00 00 00 00 // reserved //30 //00 //90 82 03 00 00 03 82 90 //00 00 01 00 00 01 00 00 //61 //0A //11 //12 //25 //15 //24 //00 //00 00 //01 00 00 01 //0E //53 50 52 49 54 45 30 30 2E 53 50 52 3B 31 //00 return(iso.Length > defaultIsoLength && iso.Length >= expandedIsoLength && sectors > defaultSectorCount && sectors >= expandedSectorCount && //!SpriteFileLocations.IsoHasDefaultSpriteLocations( iso ) && SpriteFileLocations.IsoHasPatchedSpriteLocations(iso)); }
private AllSprites(Context context, AllSpriteAttributes attrs, SpriteFileLocations locs, IList <Sprite> otherSprites) { Count = attrs.Count + otherSprites.Count; sprites = new Sprite[Count]; IList <string> spriteNames = context == Context.US_PSP ? PSPResources.Lists.SpriteFiles : PSXResources.Lists.SpriteFiles; for (int i = 0; i < attrs.Count; i++) { sprites[i] = new CharacterSprite( context, string.Format("{0:X2} - {1}", i + 1, spriteNames[i]), attrs[i], locs[i]); } otherSprites.CopyTo(sprites, attrs.Count); this.attrs = attrs; this.locs = locs; Dictionary <Sprite, IList <int> > sharedSPRs = new Dictionary <Sprite, IList <int> >(); for (int i = 0; i < sprites.Count; i++) { sharedSPRs.Add(sprites[i], new List <int>()); } for (int i = 0; i < attrs.Count; i++) { for (int j = i + 1; j < attrs.Count; j++) { if (locs[i].Sector == locs[j].Sector) { sharedSPRs[sprites[i]].Add(j); sharedSPRs[sprites[j]].Add(i); } } } for (int i = 0; i < sprites.Count; i++) { sharedSPRs[sprites[i]].Sort(); sharedSPRs[sprites[i]] = sharedSPRs[sprites[i]].AsReadOnly(); } SharedSPRs = new ReadOnlyDictionary <Sprite, IList <int> >(sharedSPRs); }
private AllSprites( Context context, AllSpriteAttributes attrs, SpriteFileLocations locs, IList<Sprite> otherSprites ) { Count = attrs.Count + otherSprites.Count; sprites = new Sprite[Count]; IList<string> spriteNames = context == Context.US_PSP ? PSPResources.Lists.SpriteFiles : PSXResources.Lists.SpriteFiles; for (int i = 0; i < attrs.Count; i++) { sprites[i] = new CharacterSprite( context, string.Format( "{0:X2} - {1}", i+1, spriteNames[i] ), attrs[i], locs[i] ); } otherSprites.CopyTo( sprites, attrs.Count ); this.attrs = attrs; this.locs = locs; Dictionary<Sprite, IList<int>> sharedSPRs = new Dictionary<Sprite, IList<int>>(); for (int i = 0; i < sprites.Count; i++) { sharedSPRs.Add( sprites[i], new List<int>() ); } for (int i = 0; i < attrs.Count; i++) { for (int j = i + 1; j < attrs.Count; j++) { if (locs[i].Sector == locs[j].Sector) { sharedSPRs[sprites[i]].Add( j ); sharedSPRs[sprites[j]].Add( i ); } } } for (int i = 0; i < sprites.Count; i++) { sharedSPRs[sprites[i]].Sort(); sharedSPRs[sprites[i]] = sharedSPRs[sprites[i]].AsReadOnly(); } SharedSPRs = new ReadOnlyDictionary<Sprite, IList<int>>( sharedSPRs ); }
//public IList<byte> DefaultSpriteFileLocationsBytes { get { return defaultSpriteFileLocationsBytes; } } public static SpriteFileLocations FromPspIso(Stream iso, PspIso.PspIsoInfo info) { //const int numPspSp2 = 0x130 / 8; const int numPspSprites = 170; //0x4d0 / 8 + 0x58 / 8; //const int numPspSp2 = numSprites + 4; //0x130 / 8; const int numPspSp2 = numPspSprites + 4; //0x130 / 8; IList <byte> spriteBytes = new List <byte>(); //spriteBytes.AddRange(PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x32481C, 159 * 8))); //spriteBytes.AddRange(PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324D14, 11 * 8))); spriteBytes.AddRange(PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x32481C, numPspSprites * 8))); spriteBytes = spriteBytes.ToArray(); // Read the sector -> fftpack map IList <byte> fftpackMap = PatcherLib.Iso.PspIso.GetBlock( iso, info, new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x252F34, 0x3E00)); // Convert the fake "Sectors" into FFTPack indices Dictionary <uint, int> sectorToFftPackMap = new Dictionary <uint, int>(); Dictionary <int, uint> fftPackToSectorMap = new Dictionary <int, uint>(); for (int i = 3; i < PatcherLib.Iso.FFTPack.NumFftPackFiles - 1; i++) { UInt32 sector = fftpackMap.Sub((i - 3) * 4, (i - 3) * 4 + 4 - 1).ToUInt32(); sectorToFftPackMap.Add(sector, i); fftPackToSectorMap.Add(i, sector); } byte[] sp2Bytes = PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324D6C, numPspSp2 * 8)).ToArray(); var sp2 = new Dictionary <byte, SpriteLocation>(); for (byte i = 0; i < numPspSp2; i++) { //const byte offset = 0x87; SpriteLocation loc = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324D6C + i * 8, 8), sp2Bytes.Sub(i * 8, (i + 1) * 8 - 1)); if (loc.Sector != 0 && loc.Size != 0) { loc.Sector = (uint)sectorToFftPackMap[loc.Sector]; sp2[(byte)(i)] = loc; } } IList <SpriteLocation> sprites = new SpriteLocation[numPspSprites]; for (byte i = 0; i < numPspSprites; i++) { if (pspSp2toSpriteMapping.ContainsKey(i)) { IList <byte> values = pspSp2toSpriteMapping[i]; List <byte> newValues = new List <byte>(values.Count); foreach (byte value in values) { if (sp2.ContainsKey(value)) { newValues.Add(value); } } values = newValues.AsReadOnly(); SpriteLocation[] sp2s = new SpriteLocation[values.Count]; for (int j = 0; j < values.Count; j++) { sp2s[j] = sp2[values[j]]; } sprites[i] = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, //i <= 0x9A ? (0x32481C + i * 8) : (0x324D14 + (i - 0x9A - 1) * 8), (0x32481C + i * 8), 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1), sp2s); } else { sprites[i] = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, //i <= 0x9A ? (0x32481C + i * 8) : (0x324D14 + (i - 0x9A - 1) * 8), (0x32481C + i * 8), 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1)); } sprites[i].Sector = ((sprites[i].Sector > 0) ? (uint)sectorToFftPackMap[sprites[i].Sector] : 0); } SpriteFileLocations result = new SpriteFileLocations(); result.sprites = sprites; result.sp2 = sp2; return(result); }
public static AllSprites FromPsxIso(Stream iso, bool expand) { if (expand && !DetectExpansionOfPsxIso(iso)) { ExpandPsxIso(iso); } return(new AllSprites(Context.US_PSX, AllSpriteAttributes.FromPsxIso(iso), SpriteFileLocations.FromPsxIso(iso), new Sprite[] { new WepSprite(Context.US_PSX, WepSprite.Wep.WEP1, "WEP1", new PatcherLib.Iso.PsxIso.KnownPosition(PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSX, WepSprite.Wep.WEP2, "WEP2", new PatcherLib.Iso.PsxIso.KnownPosition(PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSX, WepSprite.Wep.EFF1, "EFF1", new PatcherLib.Iso.PsxIso.KnownPosition(PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSX, WepSprite.Wep.EFF2, "EFF2", new PatcherLib.Iso.PsxIso.KnownPosition(PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSX, WepSprite.Wep.EFF1, "TRAP1", new PatcherLib.Iso.PsxIso.KnownPosition(PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, (256 * 256 / 2 + 0x200) * 2, 144 * 256 / 2 + 0x200)), } )); }
public static void ExpandPsxIso(Stream iso) { byte[] expandedBytes = expandedSectorCount.ToBytes(); byte[] reverseBytes = new byte[4] { expandedBytes[3], expandedBytes[2], expandedBytes[1], expandedBytes[0] }; PatcherLib.Iso.PsxIso.PatchPsxIso(iso, PatcherLib.Iso.PsxIso.NumberOfSectorsLittleEndian.GetPatchedByteArray(expandedBytes)); PatcherLib.Iso.PsxIso.PatchPsxIso(iso, PatcherLib.Iso.PsxIso.NumberOfSectorsBigEndian.GetPatchedByteArray(reverseBytes)); //PatcherLib.Iso.PsxIso.PatchPsxIso( iso, // new PatchedByteArray( // (PatcherLib.Iso.PsxIso.Sectors)22, // 0xDC, // new byte[] { 0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00 } ) ); // Build directory entry for /DUMMY //iso.Seek(0x203E6500, SeekOrigin.Begin); //iso.Write(Properties.Resources.PatchedDummyFolder, 0, Properties.Resources.PatchedDummyFolder.Length); // Read old sprites var locs = SpriteFileLocations.FromPsxIso(iso); byte[][] oldSprites = new byte[NumPsxSprites][]; for (int i = 0; i < NumPsxSprites; i++) { var loc = locs[i]; oldSprites[i] = PatcherLib.Iso.PsxIso.ReadFile(iso, (PatcherLib.Iso.PsxIso.Sectors)loc.Sector, 0, (int)loc.Size); } Set <string> allowedEntries = new Set <string>(new string[] { "\0", "\x01", "ARUTE.SEQ;1", "ARUTE.SHP;1", "CYOKO.SEQ;1", "CYOKO.SHP;1", "EFC_FNT.TIM;1", "EFF1.SEQ;1", "EFF1.SHP;1", "EFF2.SEQ;1", "EFF2.SHP;1", "ENTD1.ENT;1", "ENTD2.ENT;1", "ENTD3.ENT;1", "ENTD4.ENT;1", "KANZEN.SEQ;1", "KANZEN.SHP;1", "MON.SEQ;1", "MON.SHP;1", "OTHER.SEQ;1", "OTHER.SHP;1", "OTHER.SPR;1", "RUKA.SEQ;1", "TYPE1.SEQ;1", "TYPE1.SHP;1", "TYPE2.SEQ;1", "TYPE2.SHP;1", "TYPE3.SEQ;1", "TYPE4.SEQ;1", "WEP.SPR;1", "WEP1.SEQ;1", "WEP1.SHP;1", "WEP2.SEQ;1", "WEP2.SHP;1", "ZODIAC.BIN;1" }); List <PatcherLib.Iso.DirectoryEntry> battleDir = new List <PatcherLib.Iso.DirectoryEntry>(PatcherLib.Iso.DirectoryEntry.GetPsxBattleEntries(iso)); byte[] extBytes = battleDir[2].ExtendedBytes; System.Diagnostics.Debug.Assert(battleDir.Sub(2).TrueForAll(ent => PatcherLib.Utilities.Utilities.CompareArrays(extBytes, ent.ExtendedBytes))); byte[] midBytes = battleDir[2].MiddleBytes; System.Diagnostics.Debug.Assert(battleDir.Sub(2).TrueForAll(ent => PatcherLib.Utilities.Utilities.CompareArrays(midBytes, ent.MiddleBytes))); battleDir.RemoveAll(dirent => !allowedEntries.Contains(dirent.Filename)); // Expand length of ISO byte[] anchorBytes = new byte[] { 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00 }; byte[] sectorBytes = new byte[] { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x08, 0x00 }; byte[] endOfFileBytes = new byte[] { 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, 0x89, 0x00 }; //byte[] sectorBytes = new byte[8]; //byte[] endOfFileBytes = new byte[8]; byte[] emptySector = new byte[2328]; Time t = new Time(51, 9, 39); for (long l = 0x2040B100; l < 0x20F18D00; l += 2352) { // write 0x00FFFFFF FFFFFFFF FFFFFF00 MM SS FF 02 // write 0x00000800 00000800 for sector of file // write 0x00008900 00008900 for last sector of file iso.Seek(l, SeekOrigin.Begin); iso.Write(anchorBytes, 0, anchorBytes.Length); iso.Write(t.ToBCD(), 0, 3); t = t.AddFrame(); iso.WriteByte(0x02); if ((l - 0x2040B100 + 2352) % 0x12600 != 0) { iso.Write(sectorBytes, 0, 8); } else { iso.Write(endOfFileBytes, 0, 8); } iso.Write(emptySector, 0, 2328); } // Copy old sprites to new locations List <byte> posBytes = new List <byte>(NumPsxSprites * 8); const long startSector = 0x2040B100 / 2352; for (int i = 0; i < NumPsxSprites; i++) { uint sector = (uint)(startSector + i * 65536 / 2048); byte[] bytes = oldSprites[i]; byte[] realBytes = new byte[65536]; bytes.CopyTo(realBytes, 0); PatcherLib.Iso.PsxIso.PatchPsxIso(iso, new PatchedByteArray((int)sector, 0, realBytes)); posBytes.AddRange(sector.ToBytes()); posBytes.AddRange(((uint)realBytes.Length).ToBytes()); battleDir.Add(new PatcherLib.Iso.DirectoryEntry(sector, 65536, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, string.Format("{0:X2}.SPR;1", i + 1), battleDir[2].ExtendedBytes)); } battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_ARLI2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "8D.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_BIBU2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "96.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_BOM2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "88.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_BEHI2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "93.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_DEMON2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "99.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_DORA22_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "95.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_HYOU2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "89.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_IRON5_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "9A_2.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_IRON4_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "9A_3.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_IRON2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "9A_4.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_IRON3_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "9A_5.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_MINOTA2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "91.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_MOL2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "92.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_TORI2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "8E.SP2;1", battleDir[2].ExtendedBytes)); battleDir.Add(new PatcherLib.Iso.DirectoryEntry( (uint)PatcherLib.Iso.PsxIso.Sectors.BATTLE_URI2_SP2, 32768, DateTime.Now, battleDir[2].GMTOffset, battleDir[2].MiddleBytes, "8F.SP2;1", battleDir[2].ExtendedBytes)); //"ARLI2.SP2;1", // 0x8c //"BIBU2.SP2;1", // 0x95 //"BOM2.SP2;1", // 0x87 //"BEHI2.SP2;1", // 0x92 //"DEMON2.SP2;1", // 0x98 //"DORA22.SP2;1", // 0x94 //"HYOU2.SP2;1", // 0x88 //"IRON5.SP2;1", //"IRON4.SP2;1", //"IRON2.SP2;1", //"IRON3.SP2;1", //"MINOTA2.SP2;1", // 0x90 //"MOL2.SP2;1", // 0x91 //"TORI2.SP2;1", // 0x8d //"UR2.SP2;1", // 0x8e battleDir.Sort((a, b) => a.Filename.CompareTo(b.Filename)); // Patch direntry PatcherLib.Iso.DirectoryEntry.WritePsxDirectoryEntries( iso, PatcherLib.Iso.PsxIso.BattleDirectoryEntrySector, PatcherLib.Iso.PsxIso.BattleDirectoryEntryLength, battleDir); // Erase the dummy directory, just to be sure PatcherLib.Iso.DirectoryEntry.WritePsxDirectoryEntries( iso, PatcherLib.Iso.PsxIso.DummyDirectoryEntrySector, PatcherLib.Iso.PsxIso.DummyDirectoryEntryLength, new PatcherLib.Iso.DirectoryEntry[0]); // Update battle.bin PatcherLib.Iso.PsxIso.PatchPsxIso(iso, SpriteFileLocations.SpriteLocationsPosition.GetPatchedByteArray(posBytes.ToArray())); }
private static void ExpandPspIso(Stream iso) { throw new InvalidOperationException("This method doesn't work."); return; string tempPath = Path.GetTempPath(); string guid = Path.GetRandomFileName(); string tempDirPath = Path.Combine(tempPath, guid); DirectoryInfo temp = Directory.CreateDirectory(tempDirPath); PatcherLib.Iso.PspIso.PspIsoInfo info = PatcherLib.Iso.PspIso.PspIsoInfo.GetPspIsoInfo(iso); long fftpackSector = info[PatcherLib.Iso.PspIso.Sectors.PSP_GAME_USRDIR_fftpack_bin]; iso.Seek(2048 * fftpackSector, SeekOrigin.Begin); // Dump the fftpack PatcherLib.Iso.FFTPack.DumpToDirectory(iso, tempDirPath, info.GetFileSize(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_USRDIR_fftpack_bin), null); // Decrypt the ISO while we have it open... PatcherLib.Iso.PspIso.DecryptISO(iso, info); string battleDirPath = Path.Combine(tempDirPath, "BATTLE"); // Read the sector -> fftpack map IList <byte> fftpackMap = PatcherLib.Iso.PspIso.GetBlock( iso, info, new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x252f34, 0x3e00)); // Convert the fake "Sectors" into FFTPack indices Dictionary <uint, int> sectorToFftPackMap = new Dictionary <uint, int>(); Dictionary <int, uint> fftPackToSectorMap = new Dictionary <int, uint>(); for (int i = 3; i < PatcherLib.Iso.FFTPack.NumFftPackFiles - 1; i++) { UInt32 sector = fftpackMap.Sub((i - 3) * 4, (i - 3) * 4 + 4 - 1).ToUInt32(); sectorToFftPackMap.Add(sector, i); fftPackToSectorMap.Add(i, sector); } const int numPspSp2 = 0x130 / 8; const int numPspSprites = 0x4d0 / 8 + 0x58 / 8; byte[][] oldSpriteBytes = new byte[numPspSprites][]; // Save the old sprites var locs = SpriteFileLocations.FromPspIso(iso, PatcherLib.Iso.PspIso.PspIsoInfo.GetPspIsoInfo(iso)); for (int i = 0; i < numPspSprites; i++) { oldSpriteBytes[i] = new byte[65536]; PatcherLib.Iso.FFTPack.GetFileFromIso(iso, info, (PatcherLib.Iso.FFTPack.Files)sectorToFftPackMap[locs[i].Sector]).CopyTo(oldSpriteBytes[i], 0); } byte[] emptyByteArray = new byte[0]; // Replace old sprites //for (int i = 78; i <= 213; i++) //{ // string currentFile = Path.Combine(tempDirPath, PatcherLib.Iso.FFTPack.FFTPackFiles[i]); // File.Delete(currentFile); // File.WriteAllBytes(currentFile, emptyByteArray); //} for (int i = 0; i < numPspSprites; i++) { File.Delete(Path.Combine(tempDirPath, string.Format("unknown/fftpack.{0}.dummy", i + 1340))); File.WriteAllBytes(Path.Combine(tempDirPath, string.Format("unknown/fftpack.{0}", i + 1340)), oldSpriteBytes[i]); locs[i].Sector = fftPackToSectorMap[i + 1340]; locs[i].Size = 65536; } List <byte> newSpriteLocations = new List <byte>(); for (int i = 0; i < 154; i++) { newSpriteLocations.AddRange(locs[i].Sector.ToBytes()); newSpriteLocations.AddRange(locs[i].Size.ToBytes()); } newSpriteLocations.AddRange(new byte[32]); for (int i = 154; i < numPspSprites; i++) { newSpriteLocations.AddRange(locs[i].Sector.ToBytes()); newSpriteLocations.AddRange(locs[i].Size.ToBytes()); } byte[] newSpriteLocationsArray = newSpriteLocations.ToArray(); string outputPath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); PatcherLib.Iso.FFTPack.MergeDumpedFiles(tempDirPath, outputPath, null); long oldFftPackSize = info.GetFileSize(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_USRDIR_fftpack_bin); byte[] oldFftPackSizeBytes = oldFftPackSize.ToBytes(); oldFftPackSizeBytes = new byte[8] { oldFftPackSizeBytes[0], oldFftPackSizeBytes[1], oldFftPackSizeBytes[2], oldFftPackSizeBytes[3], oldFftPackSizeBytes[3], oldFftPackSizeBytes[2], oldFftPackSizeBytes[1], oldFftPackSizeBytes[0] }; using (Stream newFftPack = File.OpenRead(outputPath)) { long newFftPackSize = newFftPack.Length; byte[] newFftPackSizeBytes = newFftPackSize.ToBytes(); newFftPackSizeBytes = new byte[8] { newFftPackSizeBytes[0], newFftPackSizeBytes[1], newFftPackSizeBytes[2], newFftPackSizeBytes[3], newFftPackSizeBytes[3], newFftPackSizeBytes[2], newFftPackSizeBytes[1], newFftPackSizeBytes[0] }; ReplaceBytesInStream(iso, oldFftPackSizeBytes, newFftPackSizeBytes); CopyStream(newFftPack, 0, iso, info[PatcherLib.Iso.PspIso.Sectors.PSP_GAME_USRDIR_fftpack_bin] * 2048, newFftPack.Length); long oldLength = info.GetFileSize(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_USRDIR_fftpack_bin); if (newFftPack.Length < oldLength) { iso.Write(new byte[oldLength - newFftPack.Length], 0, (int)(oldLength - newFftPack.Length)); } } Directory.Delete(tempDirPath, true); File.Delete(outputPath); PatcherLib.Iso.PspIso.PatchISO(iso, new PatchedByteArray[] { new PatchedByteArray(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324824, newSpriteLocationsArray), new PatchedByteArray(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_SYSDIR_EBOOT_BIN, 0x324824, newSpriteLocationsArray) }); }
public static AllSprites FromPspIso(Stream iso, bool expand) { PatcherLib.Iso.PspIso.PspIsoInfo info = PatcherLib.Iso.PspIso.PspIsoInfo.GetPspIsoInfo(iso); return(new AllSprites(Context.US_PSP, AllSpriteAttributes.FromPspIso(iso, info), SpriteFileLocations.FromPspIso(iso, info), new Sprite[] { new WepSprite(Context.US_PSP, WepSprite.Wep.WEP1, "WEP1", new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.FFTPack.Files.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSP, WepSprite.Wep.WEP2, "WEP2", new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.FFTPack.Files.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSP, WepSprite.Wep.EFF1, "EFF1", new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.FFTPack.Files.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSP, WepSprite.Wep.EFF2, "EFF2", new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.FFTPack.Files.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)), new WepSprite(Context.US_PSP, WepSprite.Wep.EFF2, "TRAP1", new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.FFTPack.Files.BATTLE_WEP_SPR, (256 * 256 / 2 + 0x200) * 2, 144 * 256 / 2 + 0x200)), } )); }
public static SpriteFileLocations FromPsxIso(Stream iso) { SpriteFileLocations result = new SpriteFileLocations(); byte[] spriteBytes = PatcherLib.Iso.PsxIso.ReadFile(iso, spriteLocationsPosition); byte[] sp2Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, sp2LocationsPosition); var sp2 = new Dictionary<byte, SpriteLocation>(); for (byte i = 0; i < numSp2; i++) { const byte offset = 0x87; sp2[(byte)(i + offset)] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(sp2LocationsPosition.Sector, sp2LocationsPosition.StartLocation + i * 8, 8), sp2Bytes.Sub(i * 8, (i + 1) * 8 - 1)); } IList<SpriteLocation> sprites = new SpriteLocation[numSprites + numWep]; for (byte i = 0; i < numSprites; i++) { if (psxSp2toSpriteMapping.ContainsKey(i)) { IList<byte> values = psxSp2toSpriteMapping[i]; SpriteLocation[] sp2s = new SpriteLocation[values.Count]; for (int j = 0; j < values.Count; j++) { sp2s[j] = sp2[values[j]]; } sprites[i] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(spriteLocationsPosition.Sector, spriteLocationsPosition.StartLocation + i * 8, 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1), sp2s); } else { sprites[i] = SpriteLocation.BuildPsx( new PsxIso.KnownPosition(spriteLocationsPosition.Sector, spriteLocationsPosition.StartLocation + i * 8, 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1)); } } //byte[] wep1Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 0, 256 * 256 / 2 + 0x200)); //byte[] wep2Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, 256 * 256 / 2 + 0x200, 256 * 256 / 2 + 0x200)); //byte[] wep3Bytes = PatcherLib.Iso.PsxIso.ReadFile(iso, new PatcherLib.Iso.PsxIso.KnownPosition( // PatcherLib.Iso.PsxIso.Sectors.BATTLE_WEP_SPR, (256 * 256 / 2 + 0x200) * 2, 256 * 144 / 2 + 0x200)); result.sprites = sprites; result.sp2 = sp2; return result; }
public static SpriteFileLocations FromPspIso(Stream iso, PspIso.PspIsoInfo info) { const int numPspSp2 = 0x130 / 8; const int numPspSprites = 0x4d0 / 8 + 0x58 / 8; IList<byte> spriteBytes = new List<byte>(); spriteBytes.AddRange(PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324824, 0x4d0))); spriteBytes.AddRange(PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x324D14, 0x58))); spriteBytes = spriteBytes.ToArray(); // Read the sector -> fftpack map IList<byte> fftpackMap = PatcherLib.Iso.PspIso.GetBlock( iso, info, new PatcherLib.Iso.PspIso.KnownPosition(PatcherLib.Iso.PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x252f34, 0x3e00)); // Convert the fake "Sectors" into FFTPack indices Dictionary<uint, int> sectorToFftPackMap = new Dictionary<uint, int>(); Dictionary<int, uint> fftPackToSectorMap = new Dictionary<int, uint>(); for (int i = 3; i < PatcherLib.Iso.FFTPack.NumFftPackFiles - 1; i++) { UInt32 sector = fftpackMap.Sub((i - 3) * 4, (i - 3) * 4 + 4 - 1).ToUInt32(); sectorToFftPackMap.Add(sector, i); fftPackToSectorMap.Add(i, sector); } byte[] sp2Bytes = PspIso.GetBlock(iso, info, new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x3251ac, 0x130)).ToArray(); var sp2 = new Dictionary<byte, SpriteLocation>(); for (byte i = 0; i < numPspSp2; i++) { const byte offset = 0x87; SpriteLocation loc = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, 0x3251ac + i * 8, 8), sp2Bytes.Sub(i * 8, (i + 1) * 8 - 1)); if (loc.Sector != 0 && loc.Size != 0) { loc.Sector = (uint)sectorToFftPackMap[loc.Sector]; sp2[(byte)(i + offset)] = loc; } else { } } IList<SpriteLocation> sprites = new SpriteLocation[numPspSprites]; for (byte i = 0; i < numPspSprites; i++) { if (pspSp2toSpriteMapping.ContainsKey(i)) { IList<byte> values = pspSp2toSpriteMapping[i]; SpriteLocation[] sp2s = new SpriteLocation[values.Count]; for (int j = 0; j < values.Count; j++) { sp2s[j] = sp2[values[j]]; } sprites[i] = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, i <= 0x99 ? (0x324824 + i * 8) : (0x324d14 + (i - 0x99 - 1) * 8), 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1), sp2s); } else { sprites[i] = SpriteLocation.BuildPsp( new PspIso.KnownPosition(PspIso.Sectors.PSP_GAME_SYSDIR_BOOT_BIN, i <= 0x99 ? (0x324824 + i * 8) : (0x324d14 + (i - 0x99 - 1) * 8), 8), spriteBytes.Sub(i * 8, (i + 1) * 8 - 1)); } sprites[i].Sector = (uint)sectorToFftPackMap[sprites[i].Sector]; } SpriteFileLocations result = new SpriteFileLocations(); result.sprites = sprites; result.sp2 = sp2; return result; }