Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
        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);
        }
Exemplo n.º 3
0
        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);
        }