FrameArr ParseFrame(uint addr) { FrameArr arr = new FrameArr(); arr.Frames = new List <Frame>(); uint count = Program.ROM.u16(addr); addr += 2; uint rotateCount = 0; if ((count & 0x8000) == 0x8000) {//回転などのデータがある場合 rotateCount = count & 0x7FFF; if (rotateCount > 0x100) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。OAM回転データの個数がありえない数です({1})。", U.To0xHexString(this.BaseAddr), rotateCount); return(null); } count = rotateCount; arr.UseRorate = true; arr.CountRorate = rotateCount; } if (count > 0x100) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。データの個数がありえない数です({1})。", U.To0xHexString(this.BaseAddr), count); return(null); } for (int i = 0; i < count; addr += 6, i++) { if (!U.isSafetyOffset(addr + 6 - 1)) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。APをスキャン中に、ROM終端を超えました。({1} @ {2})", U.To0xHexString(this.BaseAddr), U.To0xHexString(addr), i); return(null); } Frame f = new Frame(); f.OAM0 = Program.ROM.u16(addr + 0); f.OAM1 = Program.ROM.u16(addr + 2); f.OAM2 = Program.ROM.u16(addr + 4); arr.Frames.Add(f); } UpdateLength(addr); return(arr); }
public Bitmap DrawFrame(Bitmap ret, int index, int originX, int originY, Bitmap parts) { if (index >= FrameArray.Count) { return(ret); } int graphicsWidth = parts.Width / 8; FrameArr fa = FrameArray[index]; for (int i = 0; i < fa.Frames.Count; i++) { Frame f = fa.Frames[i]; OAMParse t = FrameToDump(f); int src = (int)(t.tile); int src_x = (src % graphicsWidth) * 8; int src_y = (src / graphicsWidth) * 8; ImageUtil.BitBlt(ret , originX + t.image_x, originY + t.image_y , t.width * 8 , t.height * 8 , parts , src_x, src_y , t.paletteShift , 0 , t.v_flipped , t.h_flipped ); // Log.Debug("_" + index + "_" + i + " " + t.image_x + "," + t.image_y + "@" + t.width * 8 + "," + t.height * 8); // ret.Save("_" + index + "_" + i + ".png"); } return(ret); }
public bool Parse(uint addr) { this.BaseAddr = addr; if (!U.isSafetyOffset(addr + 4 - 1)) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。ヘッダがROM終端を超えています", U.To0xHexString(this.BaseAddr)); return(false); } uint frameDataOffset = Program.ROM.u16(addr); uint animeTableOffset = Program.ROM.u16(addr + 2); UpdateLength(addr + 4); //終端マークが存在しないので、読込むときには工夫が必要. uint minData = 0xFFFF; //フレームはアニメ開始地点まで uint end = this.BaseAddr + animeTableOffset; if (!U.isSafetyOffset(end - 1)) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。フレーム終端がROM終端を超えました。({1})", U.To0xHexString(this.BaseAddr), U.To0xHexString(addr)); return(false); } for (addr = this.BaseAddr + frameDataOffset; addr < end; addr += 2) { uint f = Program.ROM.u16(addr); if (minData > f) { minData = f; } FrameArr farr = ParseFrame(this.BaseAddr + frameDataOffset + f); if (farr == null) { return(false); } FrameArray.Add(farr); } if (minData >= 0x100) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。Animeデータの個数がありえない数です({1})。", U.To0xHexString(this.BaseAddr), minData); return(false); } //アニメの終了地点は最初のフレームの開始位置まで end = this.BaseAddr + frameDataOffset + minData; if (!U.isSafetyOffset(end - 1)) {//おかしなデータ this.ErrorMessage = R.Error("APのデータ({0})が壊れています。Anime終端がROM終端を超えました。({1})", U.To0xHexString(this.BaseAddr), U.To0xHexString(addr)); return(false); } for (addr = this.BaseAddr + animeTableOffset; addr < end; addr += 2) { uint a = Program.ROM.u16(addr); AnimeArr aarr = ParseAnime(this.BaseAddr + animeTableOffset + a); if (aarr == null) { return(false); } AnimeArray.Add(aarr); } UpdateLength(addr); return(true); }