//アニメーション2の割り当て
        public static uint PreciseMapTileAnimation2Area(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.ANIMATION2);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise ANIMATION2 Area", mapid.ToString("X"));

            //PALデータ 4つ
            byte[] data = new byte[2 * 4];
            U.write_u16(data, 0, 0x16);
            U.write_u16(data, 2, 0x9D);
            U.write_u16(data, 4, 0x17F);
            U.write_u16(data, 6, 0xA1F);

            uint palette_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (palette_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            //パレット領域を新規に割り当てる.
            data = new byte[8 * 2];
            U.write_p32(data, 0, palette_addr);
            U.write_u8(data, 4, 0x13); //アニメ感覚
            U.write_u8(data, 5, 0x4);  //個数
            U.write_u8(data, 6, 0x3C); //書き換え開始パレット

            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.ANIMATION2, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
Beispiel #2
0
        //アニメーションの割り当て
        public static uint PreciseMapTileAnimation1Area(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.ANIMATION);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise ANIMATION1 Area", mapid.ToString("X"));

            //無圧縮bit mapdata
            byte[] data        = new byte[0x1000];
            uint   bitmap_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (bitmap_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            //アニメーション領域を新規に割り当てる.
            data = new byte[8 * 2];
            U.write_u16(data, 0, 0x1C);
            U.write_u16(data, 2, 0x1000);
            U.write_p32(data, 4, bitmap_addr);

            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.ANIMATION, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
        uint NewAlloc()
        {
            byte[] alloc = new byte[U.Padding4(2 * (DATAMAX + 1))];

            uint default_text = DefaultText();

            for (uint i = 1; i < DATAMAX; i++)
            {
                U.write_u16(alloc, i * 2, default_text);
            }

            Undo.UndoData undodata = Program.Undo.NewUndoData("NewAlloc");
            uint          addr     = InputFormRef.AppendBinaryData(alloc, undodata);

            if (addr == U.NOT_FOUND)
            {//割り当て失敗
                return(U.NOT_FOUND);
            }

            //新規に追加した分のデータを書き込み.
            Program.Undo.Push(undodata);

            InputFormRef.WriteButtonToYellow(this.WriteButton, false);
            InputFormRef.ShowWriteNotifyAnimation(this, 0);
            return(addr);
        }
Beispiel #4
0
        bool PaletteImportOne(Bitmap bitmap, uint palette_plist, bool isFog)
        {
            Undo.UndoData undodata = Program.Undo.NewUndoData(this);

            //パレット情報の書き込み.
            uint palette_address = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist);

            if (palette_address == 0)
            {//未割り当てならば新規確保しようか
                palette_address = InputFormRef.AppendBinaryData(PaletteFormRef.NewNullPalette(MAX_MAP_PALETTE_COUNT), undodata);
            }

            if (isFog)
            {
                PFR.MakePaletteBitmapToROM(bitmap, palette_address + (0x20 * PARTS_MAP_PALETTE_COUNT), PARTS_MAP_PALETTE_COUNT, undodata);
            }
            else
            {
                PFR.MakePaletteBitmapToROM(bitmap, palette_address, PARTS_MAP_PALETTE_COUNT, undodata);
            }


            //拡張領域に書き込んでいる可能性もあるので plstを更新する.
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist, palette_address, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(false);
            }

            Program.Undo.Push(undodata);
            return(true);
        }
        private void WriteButton_Click(object sender, EventArgs e)
        {
            if (this.SelectFontBitmapByte == null || this.SelectFontBitmapByte.Length != 40)
            {
                return;
            }

            string undo_name = "FONT " + this.SearchChar.Text;

            PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode();
            uint search_char = U.ConvertMojiCharToUnitFast(this.SearchChar.Text, priorityCode);

            uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0);

            uint width      = (uint)this.FontWidth.Value;
            bool isItemFont = this.FontType.SelectedIndex == 0;

            if (isItemFont)
            {//なぜか中国語フォントでは、アイテムフォントは幅+1しないといけない
                width = width - 1;
            }

            uint prevaddr;
            uint fontaddr = FindFontDataZH(fontlist_pointer, search_char, out prevaddr);

            if (fontaddr == U.NOT_FOUND)
            {     //末尾に追加.
                if (prevaddr == U.NOT_FOUND)
                { //このフォントはルールにより登録できない..
                    return;
                }

                byte[] newFontData = MakeNewFontDataZH(search_char
                                                       , width
                                                       , this.SelectFontBitmapByte
                                                       );

                Undo.UndoData undodata = Program.Undo.NewUndoData(undo_name);

                uint newaddr = InputFormRef.AppendBinaryData(newFontData, undodata);
                if (newaddr == U.NOT_FOUND)
                {//エラー
                    return;
                }

                //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる.
                Program.ROM.write_u32(prevaddr, U.toPointer(newaddr), undodata);
                fontaddr = newaddr;
            }
            else
            {//更新
                Program.Undo.Push(undo_name, fontaddr, 4 + 40);
                Program.ROM.write_u8(fontaddr + 1, width);
                Program.ROM.write_range(fontaddr + 8, this.SelectFontBitmapByte); //40バイト書き込み
            }
            this.Address.Value = U.toPointer(fontaddr);
            InputFormRef.ShowWriteNotifyAnimation(this, fontaddr);
        }
        //マップ変化のベース領域の強制割り当て
        public static uint PreciseChangeListForce(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.CHANGE);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise MapChange", mapid.ToString("X"));

            byte[] data = new byte[12];
            data[0] = 0xFF; //終端.
            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.CHANGE, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            r = MapSettingForm.WriteMapChangePlist(mapid, plist, undodata);
            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
        private void WriteButton_Click(object sender, EventArgs e)
        {
            if (this.SelectFontBitmapByte == null || this.SelectFontBitmapByte.Length != 64)
            {
                return;
            }


            string undo_name = "FONT " + this.SearchChar.Text;

            PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode();
            string target = this.SearchChar.Text;

            target = TextForm.ConvertFEditorToEscape(target);
            uint search_char = U.ConvertMojiCharToUnitFast(target, priorityCode);

            uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0);

            uint prevaddr;
            uint fontaddr = FindFontData(fontlist_pointer, search_char, out prevaddr, priorityCode);

            if (fontaddr == U.NOT_FOUND)
            {     //末尾に追加.
                if (prevaddr == U.NOT_FOUND)
                { //このフォントはルールにより登録できない.日本語フォントで 0x100以下とか.
                    return;
                }
                byte[] newFontData = MakeNewFontData(search_char
                                                     , (uint)this.FontWidth.Value
                                                     , this.SelectFontBitmapByte
                                                     , Program.ROM
                                                     , priorityCode
                                                     );

                Undo.UndoData undodata = Program.Undo.NewUndoData(undo_name);

                uint newaddr = InputFormRef.AppendBinaryData(newFontData, undodata);
                if (newaddr == U.NOT_FOUND)
                {//エラー
                    return;
                }

                //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる.
                Program.ROM.write_u32(prevaddr + 0, U.toPointer(newaddr), undodata);
                fontaddr = newaddr;
            }
            else
            {//更新
                Program.Undo.Push(undo_name, fontaddr, 8 + 64);
                Program.ROM.write_u8(fontaddr + 5, (uint)this.FontWidth.Value);
                Program.ROM.write_range(fontaddr + 8, this.SelectFontBitmapByte); //64バイト書き込み
            }
            this.Address.Value = U.toPointer(fontaddr);
            InputFormRef.ShowWriteNotifyAnimation(this, fontaddr);
        }
Beispiel #8
0
        //マップ領域のベース領域の強制割り当て
        public static uint PreciseMapDataArea(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.MAP);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise MapDataArea", mapid.ToString("X"));


            //マップ領域を新規に割り当てる
            byte[] data = new byte[2 + (15 * 10)];
            data[0] = 15;
            data[1] = 10;

            data = LZ77.compress(data);

            MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereMapID(mapid);
            uint map_addr = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.MAP, plists.mappointer_plist);

            if (U.isSafetyOffset(map_addr))
            {//既存マップがあればコピーする.
                uint length = LZ77.getCompressedSize(Program.ROM.Data, map_addr);
                data = Program.ROM.getBinaryData(map_addr, length);
            }

            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.MAP, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
Beispiel #9
0
        //OBJECTの割り当て
        public static uint PreciseObjectArea(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.OBJECT);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise ObjectArea", mapid.ToString("X"));

            //OBJECT領域を新規に割り当てる.
            MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereMapID(mapid);
            Bitmap bmp;

            if (plists.obj_plist >= 0x100)
            {//2つのplistが必要だからコピーできない
                bmp = ImageUtil.Blank(32 * 8, 32 * 8);
            }
            else
            {
                bmp = DrawMapChipOnly(plists.obj_plist, plists.palette_plist, null);
            }

            byte[] data = ImageUtil.ImageToByte16Tile(bmp, bmp.Width, bmp.Height);
            data = LZ77.compress(data);

            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.OBJECT, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
Beispiel #10
0
        //パレットの割り当て
        public static uint PrecisePaletteArea(uint mapid)
        {
            MapPointerNewPLISTPopupForm f = (MapPointerNewPLISTPopupForm)InputFormRef.JumpFormLow <MapPointerNewPLISTPopupForm>();

            f.Init(MapPointerForm.PLIST_TYPE.PALETTE);
            DialogResult dr = f.ShowDialog();

            if (dr != System.Windows.Forms.DialogResult.OK)
            {
                return(0);
            }

            uint plist = f.GetSelectPLIST();

            Undo.UndoData undodata = Program.Undo.NewUndoData("Precise PaletteArea", mapid.ToString("X"));


            //パレット領域を新規に割り当てる.
            byte[] data = new byte[5 * 2 * 16];

            MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereMapID(mapid);
            uint palette_addr            = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, plists.palette_plist);

            if (U.isSafetyOffset(palette_addr))
            {//既存パレットがあればコピーする.
                data = Program.ROM.getBinaryData(palette_addr, data.Length);
            }

            uint write_addr = InputFormRef.AppendBinaryData(data, undodata);

            if (write_addr == U.NOT_FOUND)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.PALETTE, plist, write_addr, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return(0);
            }

            Program.Undo.Push(undodata);

            return(plist);
        }
Beispiel #11
0
        public uint Write(byte[] write_data, Undo.UndoData undodata)
        {
            for (int i = 0; i < this.Recycle.Count; i++)
            {
                Address p = this.Recycle[i];
                if (p.Length >= write_data.Length)
                {
                    uint use_addr = p.Addr;

                    //ちょうど良い領域があったので利用しよう
                    Program.ROM.write_range(use_addr, write_data, undodata);
                    uint addr   = U.Padding4(p.Addr + (uint)write_data.Length);
                    uint length = U.Sub(p.Length, (addr - use_addr));

                    p.ResizeAddress(addr, length);
                    if (p.Length < 4)
                    {//もう空きがない.
                        this.Recycle.RemoveAt(i);
                    }

                    return(use_addr);
                }
            }

            if (this.Recycle.Count <= 0)
            {
                //空き領域から利用.
                return(InputFormRef.AppendBinaryData(write_data, undodata));
            }
            else
            {
                Address lastP = this.Recycle[this.Recycle.Count - 1];
                if (lastP.Addr + lastP.Length >= Program.ROM.Data.Length)
                {//自分が最後のデータだった場合
                    //ROMサイズを増設.
                    Program.ROM.write_resize_data(U.Padding4(lastP.Addr + (uint)write_data.Length));

                    Program.ROM.write_range(lastP.Addr, write_data, undodata);
                    return(lastP.Addr);
                }

                //空き領域から利用.
                return(InputFormRef.AppendBinaryData(write_data, undodata));
            }
        }
        uint NewAlloc()
        {
            byte[] alloc = new byte[4 * 0xE];

            Undo.UndoData undodata = Program.Undo.NewUndoData("NewAlloc");
            uint          addr     = InputFormRef.AppendBinaryData(alloc, undodata);

            if (addr == U.NOT_FOUND)
            {//割り当て失敗
                return(U.NOT_FOUND);
            }

            //新規に追加した分のデータを書き込み.
            Program.Undo.Push(undodata);

            InputFormRef.WriteButtonToYellow(this.WriteButton, false);
            InputFormRef.ShowWriteNotifyAnimation(this, 0);
            return(addr);
        }
Beispiel #13
0
        private void NewListAlloc_Click(object sender, EventArgs e)
        {
            uint exit_point_addrp = InputFormRef.SelectToAddr(this.AddressList);

            if (!U.isSafetyOffset(exit_point_addrp))
            {
                return;
            }

            byte[] data = new byte[8];
            data[4] = 0xFF;

            Undo.UndoData undodata = Program.Undo.NewUndoData(this, "MapExit NewAlloc");
            uint          newaddr  = InputFormRef.AppendBinaryData(data, undodata);

            Program.ROM.write_p32(exit_point_addrp, newaddr, undodata);

            Program.Undo.Push(undodata);

            U.ReSelectList(AddressList);
        }
Beispiel #14
0
        //共有しているデータの分割
        public static uint WriteIndependence(uint readAddr, uint blockSize, uint writeSettingAddr, string warnningName, Undo.UndoData undodata)
        {
            DialogResult dr = R.ShowYesNo("{0}のデータを、分離独立させますか?", warnningName);

            if (dr != DialogResult.Yes)
            {
                return(U.NOT_FOUND);
            }

            byte[] d    = Program.ROM.getBinaryData(readAddr, blockSize);
            uint   addr = InputFormRef.AppendBinaryData(d, undodata);

            if (addr == U.NOT_FOUND)
            {
                return(U.NOT_FOUND);
            }

            Program.ROM.write_p32(writeSettingAddr, addr, undodata);

            return(addr);
        }
        bool WriteMapChipPalette(Bitmap bitmap, bool importObjWithPalette, Undo.UndoData undodata)
        {
            const int palette_count = MAX_MAP_PALETTE_COUNT;

            if (importObjWithPalette)
            {//パレットもインポートする場合
                //パレットの交換
                this.MapObjImage = bitmap;
                U.ForceUpdate(this.PaletteTypeCombo, 0);
                U.ForceUpdate(this.PaletteCombo, 0);

                //パレット情報の書き込み.
                uint palette_plist   = this.MapEditConf[this.MapStyle.SelectedIndex].palette_plist;
                uint palette_address = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist);
                if (palette_address == 0)
                {//未割り当てならば新規確保しようか
                    palette_address = InputFormRef.AppendBinaryData(PaletteFormRef.NewNullPalette(palette_count), undodata);
                }
                PFR.MakePaletteBitmapToROM(bitmap, palette_address, palette_count, undodata);

                //拡張領域に書き込んでいる可能性もあるので plstを更新する.
                bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist, palette_address, undodata);
                if (!r)
                {
                    Program.Undo.Rollback(undodata);
                    return(false);
                }

                PaletteAddress.Value = palette_address;
            }
            else
            {//パレットはインポートしない場合
                //パレット情報の継承.
                bitmap.Palette = this.MapObjImage.Palette;
                //obj Bitmap交換
                this.MapObjImage = bitmap;
            }

            return(true);
        }
Beispiel #16
0
        uint NewAlloc()
        {
            byte[] alloc = new byte[4];

            Undo.UndoData undodata = Program.Undo.NewUndoData("NewAlloc AIRange");
            uint          addr     = InputFormRef.AppendBinaryData(alloc, undodata);

            if (addr == U.NOT_FOUND)
            {//割り当て失敗
                return(U.NOT_FOUND);
            }

            Program.ROM.write_u8(addr + 0, 0, undodata); //
            Program.ROM.write_u8(addr + 1, 0, undodata); //
            Program.ROM.write_u8(addr + 2, 0, undodata); //
            Program.ROM.write_u8(addr + 3, 0, undodata); //

            //新規に追加した分のデータを書き込み.
            Program.Undo.Push(undodata);

            InputFormRef.WriteButtonToYellow(this.AllWriteButton, false);
            InputFormRef.ShowWriteNotifyAnimation(this, 0);
            return(addr);
        }
Beispiel #17
0
        private void PaletteWriteButton_Click(object sender, EventArgs e)
        {
            if (this.MapStyle.SelectedIndex < 0)
            {
                return;
            }
            uint palette_plist = this.MapEditConf[this.MapStyle.SelectedIndex].palette_plist;
            int  palette_count = MAX_MAP_PALETTE_COUNT;

            Undo.UndoData undodata = Program.Undo.NewUndoData(this);

            //パレット情報の書き込み.
            uint palette_address = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist);

            if (palette_address == 0)
            {//未割り当てならば新規確保しようか
                palette_address = InputFormRef.AppendBinaryData(PaletteFormRef.NewNullPalette(palette_count), undodata);
            }

            PFR.MakePaletteColorPaletteToROM(this.MapObjImage.Palette, palette_address, palette_count, undodata);
            InputFormRef.WriteButtonToYellow(this.PaletteWriteButton, false);

            //拡張領域に書き込んでいる可能性もあるので plstを更新する.
            bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist, palette_address, undodata);

            if (!r)
            {
                Program.Undo.Rollback(undodata);
                return;
            }

            Program.Undo.Push(undodata);

            //マップエディタが開いていれば更新する
            MapEditorForm.UpdateMapStyleIfOpen();
        }
Beispiel #18
0
        uint PListSplitsExpandsOne(MapPointerForm.PLIST_TYPE type, Undo.UndoData undodata)
        {
            Debug.Assert(type != PLIST_TYPE.ANIMATION2); //Animation1と一緒に処理しないといけない
            Debug.Assert(type != PLIST_TYPE.PALETTE);    //OBJECTと一緒に処理しないといけない

            InputFormRef InputFormRef = Init(null, false);

            InputFormRef.ReInitPointer(GetBasePointer(type));

            byte[] newArray = new byte[4 * (256)];
            List <U.AddrResult> mapSetting = MapSettingForm.MakeMapIDList();
            int mapmax = mapSetting.Count;

            for (int mapid = 0; mapid < mapmax; mapid++)
            {
                if (type == PLIST_TYPE.WORLDMAP_FE6ONLY)
                {
                    Debug.Assert(Program.ROM.RomInfo.version == 6);
                    uint wmapevent_plist = MapSettingForm.GetWorldMapEventIDWhereAddr(mapSetting[mapid].addr);

                    PListSplitExpandsOneConvertPointer(wmapevent_plist, InputFormRef, newArray);
                    continue;
                }

                MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereAddr(mapSetting[mapid].addr);
                if (type == PLIST_TYPE.CHANGE)
                {
                    PListSplitExpandsOneConvertPointer(plists.mapchange_plist, InputFormRef, newArray);
                }
                else if (type == PLIST_TYPE.EVENT)
                {
                    PListSplitExpandsOneConvertPointer(plists.event_plist, InputFormRef, newArray);
                }
                else if (type == PLIST_TYPE.MAP)
                {
                    PListSplitExpandsOneConvertPointer(plists.mappointer_plist, InputFormRef, newArray);
                }
                else if (type == PLIST_TYPE.CONFIG)
                {
                    PListSplitExpandsOneConvertPointer(plists.config_plist, InputFormRef, newArray);
                }
                else if (type == PLIST_TYPE.ANIMATION)
                {
                    PListSplitExpandsOneConvertPointer(plists.anime1_plist, InputFormRef, newArray);
                    PListSplitExpandsOneConvertPointer(plists.anime2_plist, InputFormRef, newArray);
                }
                else
                {
                    uint obj1_plist = (plists.obj_plist & 0xFF);
                    uint obj2_plist = (plists.obj_plist >> 8) & 0xFF; //FE8にはないが FE7は、 plistを2つ設定できることがある.

                    PListSplitExpandsOneConvertPointer(obj1_plist, InputFormRef, newArray);
                    PListSplitExpandsOneConvertPointer(obj2_plist, InputFormRef, newArray);

                    PListSplitExpandsOneConvertPointer(plists.palette_plist, InputFormRef, newArray);
                }
            }
            //終端の0xFFFFFFFFを念のため入れておきます.
//            U.write_u32(newArray, 256 * 4, U.NOT_FOUND);

            uint newpos = InputFormRef.AppendBinaryData(newArray, undodata);

            if (newpos == U.NOT_FOUND)
            {
                throw new PLISTExpandsException(R._("PLIST拡張に失敗しました。\r\ntype={0}\r\nnewaddr=NOT_FOUND", type.ToString()));
            }

            if (type == PLIST_TYPE.CONFIG)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_config_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.ANIMATION)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_tileanime1_pointer, newpos, undodata);
                Program.ROM.write_p32(Program.ROM.RomInfo.map_tileanime2_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.OBJECT)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_obj_pointer, newpos, undodata);
                Program.ROM.write_p32(Program.ROM.RomInfo.map_pal_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.MAP)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_map_pointer_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.CHANGE)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_mapchange_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.EVENT)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_event_pointer, newpos, undodata);
            }
            else if (type == PLIST_TYPE.WORLDMAP_FE6ONLY)
            {
                Program.ROM.write_p32(Program.ROM.RomInfo.map_worldmapevent_pointer, newpos, undodata);
            }
            else
            {
                Debug.Assert(false);
            }
            return(newpos);
        }
        private void ObjImportButton_Click(object sender, EventArgs e)
        {
            if (this.MapStyle.SelectedIndex < 0)
            {
                return;
            }
            uint obj_plist  = this.MapEditConf[this.MapStyle.SelectedIndex].obj_plist;
            uint obj2_plist = (obj_plist >> 8) & 0xFF; //FE8にはないが FE7は、 plistを2つ設定できることがある.

            Bitmap bitmap = ImageFormRef.ImportFilenameDialog(this);

            if (bitmap == null)
            {
                return;
            }
            int width         = 32 * 8;
            int height        = 32 * 8;
            int palette_count = MAX_MAP_PALETTE_COUNT;

            if (bitmap.Width != width || bitmap.Height < 128)
            {
                R.ShowStopError("画像サイズが正しくありません。\r\nWidth:{2} Height:{3} でなければなりません。\r\n\r\n選択された画像のサイズ Width:{0} Height:{1}", bitmap.Width, bitmap.Height, width, height);
                return;
            }
            height = ImageUtil.CalcHeight(width, width * bitmap.Height / 2);

            if (ObjImportOption.SelectedIndex == 1)
            {//パレットもインポートする場合 パレット数のチェック.
                int bitmap_palette_count = ImageUtil.GetPalette16Count(bitmap);
                if (bitmap_palette_count > palette_count)
                {
                    R.ShowStopError("パレット数が正しくありません。\r\n{1}種類以下(16色*{1}種類) でなければなりません。\r\n\r\n選択された画像のパレット種類:{0}種類", bitmap_palette_count, palette_count);
                    return;
                }
                bitmap = PaletteSwapper(bitmap);
            }

            //画像
            byte[] image = ImageUtil.ImageToByte16Tile(bitmap, width, height);

            //画像等データの書き込み
            Undo.UndoData undodata = Program.Undo.NewUndoData(this);
            if (obj2_plist > 0)
            {//FE7とかあるフィールド画像分割
                byte[] image1  = U.subrange(image, 0, (uint)(image.Length / 2));
                byte[] image2  = U.subrange(image, (uint)(image.Length / 2), (uint)image.Length);
                byte[] image1Z = LZ77.compress(image1);
                byte[] image2Z = LZ77.compress(image2);
                uint   newaddr = InputFormRef.WriteBinaryData(this, (uint)ObjAddress.Value, image1Z, InputFormRef.get_data_pos_callback_lz77, undodata);
                if (newaddr == U.NOT_FOUND)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }

                ObjAddress.Value = newaddr;
                //拡張領域に書き込んでいる可能性もあるので plstを更新する.
                MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.OBJECT, obj_plist, newaddr, undodata);

                //分割されたデータを書き込み
                newaddr = InputFormRef.WriteBinaryData(this, (uint)ObjAddress2.Value, image2Z, InputFormRef.get_data_pos_callback_lz77, undodata);
                if (newaddr == U.NOT_FOUND)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }
                ObjAddress2.Value = newaddr;

                //拡張領域に書き込んでいる可能性もあるので plstを更新する.
                bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.OBJECT, obj2_plist, newaddr, undodata);
                if (!r)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }

                //書き込んだ通知.
                InputFormRef.ShowWriteNotifyAnimation(this, newaddr);
            }
            else
            {
                byte[] imageZ  = LZ77.compress(image);
                uint   newaddr = InputFormRef.WriteBinaryData(this, (uint)ObjAddress.Value, imageZ, InputFormRef.get_data_pos_callback_lz77, undodata);
                if (newaddr == U.NOT_FOUND)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }
                ObjAddress.Value = newaddr;

                //拡張領域に書き込んでいる可能性もあるので plstを更新する.
                bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.OBJECT, obj_plist, newaddr, undodata);
                if (!r)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }
                //書き込んだ通知.
                InputFormRef.ShowWriteNotifyAnimation(this, newaddr);
            }


            if (ObjImportOption.SelectedIndex == 1)
            {//パレットもインポートする場合
                //パレットの交換
                MapObjImage = bitmap;
                U.ForceUpdate(this.PaletteTypeCombo, 0);
                U.ForceUpdate(this.PaletteCombo, 0);

                //パレット情報の書き込み.
                uint palette_plist   = this.MapEditConf[this.MapStyle.SelectedIndex].palette_plist;
                uint palette_address = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist);
                if (palette_address == 0)
                {//未割り当てならば新規確保しようか
                    palette_address = InputFormRef.AppendBinaryData(PaletteFormRef.NewNullPalette(palette_count), undodata);
                }
                PaletteFormRef.MakePaletteBitmapToROM(this, bitmap, palette_address, palette_count, undodata);

                //拡張領域に書き込んでいる可能性もあるので plstを更新する.
                bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.PALETTE, palette_plist, palette_address, undodata);
                if (!r)
                {
                    Program.Undo.Rollback(undodata);
                    return;
                }

                PaletteAddress.Value = palette_address;
            }
            else
            {//パレットはインポートしない場合
                //パレット情報の継承.
                bitmap.Palette = this.MapObjImage.Palette;
                //obj Bitmap交換
                this.MapObjImage = bitmap;
            }

            Program.Undo.Push(undodata);

            //チップセットの更新.
            Chipset_Update();
            SelectedChipset_Update();
            MapStyle_SelectedIndexChanged(sender, e);
            InputFormRef.WriteButtonToYellow(this.PaletteWriteButton, false);

            //マップエディタが開いていれば更新する
            MapEditorForm.UpdateMapStyleIfOpen();
        }
Beispiel #20
0
        void FontImporterOne(string one, bool isItemFont)
        {
            uint moji = U.ConvertMojiCharToUnit(one, this.MyselfPriorityCode);

            if (moji < 0x20 || moji == 0x80)
            {//制御文字なので無視
                return;
            }

            uint topaddress_my;
            uint fontaddress_my;
            uint prevaddress_my;

            topaddress_my  = FontForm.GetFontPointer(isItemFont);
            fontaddress_my = FontForm.FindFontData(topaddress_my
                                                   , moji
                                                   , out prevaddress_my
                                                   , this.MyselfPriorityCode);
            if (fontaddress_my != U.NOT_FOUND)
            {//既存ROMに存在している
                return;
            }
            if (prevaddress_my == U.NOT_FOUND)
            {//このフォントはルールにより登録できない.日本語フォントで 0x100以下とか.
                return;
            }

            //既存ROMにはないフォント
            byte[] newFontData = null;
            if (this.YourROM != null)
            {//相手のROMにあるかどうか.
                uint your_moji = U.ConvertMojiCharToUnit(one, this.YourPriorityCode);
                if (your_moji < 0x20)
                {//制御文字なので無視
                    return;
                }

                //相手のROMにはあるかな?
                uint topaddress_your;
                uint fontaddress_your;
                uint prevaddress_your;

                topaddress_your  = FontForm.GetFontPointer(isItemFont, this.YourROM);
                fontaddress_your = FontForm.FindFontData(topaddress_your
                                                         , moji
                                                         , out prevaddress_your
                                                         , this.YourROM
                                                         , this.YourPriorityCode);
                if (fontaddress_your == U.NOT_FOUND)
                {//相手のROMにもない
                    newFontData = null;
                }
                else
                {
                    Log.Notify("Font Porting", one);

                    //fontデータの取得
                    newFontData = this.YourROM.getBinaryData(fontaddress_your, 8 * 64);

                    FontForm.TransportFontStruct(newFontData, moji, this.MyselfPriorityCode, this.YourPriorityCode);
                }
            }

            if (newFontData == null && //存在しないフォントで
                this.UseAutoGenFont != null    //自動生成する場合
                )
            {
                Log.Notify("Font Auto gen", one);

                //自動生成.
                int    font_width;
                Bitmap autogen = ImageUtil.AutoGenerateFont(one
                                                            , this.UseAutoGenFont
                                                            , isItemFont
                                                            , out font_width);
                if (autogen == null)
                {//ない
                    return;
                }
                byte[] fontimage = ImageUtil.Image4ToByte(autogen);

                newFontData = FontForm.MakeNewFontData(moji
                                                       , (uint)font_width
                                                       , fontimage
                                                       , Program.ROM
                                                       , this.MyselfPriorityCode);
            }

            if (newFontData == null)
            {//存在しない
                return;
            }

            U.write_u32(newFontData, 0, 0);   //NULL リストの末尾に追加するので.

            uint newaddr = InputFormRef.AppendBinaryData(newFontData, this.UndoData);

            if (newaddr == U.NOT_FOUND)
            {//エラー
                return;
            }

            //ひとつ前のフォントリストのポインタを、現在追加した最後尾にすげかえる.
            Program.ROM.write_u32(prevaddress_my + 0, U.toPointer(newaddr), this.UndoData);
        }
Beispiel #21
0
        //switch文の拡張
        public static uint Switch2Expands(uint array_pointer
                                          , uint array_switch2_address
                                          , uint newCount
                                          , uint defaultJumpAddr
                                          , Undo.UndoData undodata)
        {
            uint pointeraddr = Program.ROM.p32(array_pointer);

            uint extraByte = 0;

            if (Program.ROM.u16(array_switch2_address + 2) == 0x9A00)
            {//古いコンパイラは、 9A00   ldr r2,[sp, #0x0] を挟むときがあるらしい.
                //sub r0, #0x19
                //ldr r2,[sp, #0x0]
                //cmp r0, #0x37
                extraByte = 2;
            }

            //384b      sub	r0, #4b //ライブ 利用した時の効果
            //2876      cmp	r0, #76
            uint start = Program.ROM.u8(array_switch2_address + 0);
            uint count = Program.ROM.u8(array_switch2_address + 2 + extraByte) + 1;

            if (newCount <= start + count)
            {
                R.ShowStopError("既に十分な数を確保しています。\r\nあなたの要求:{0} 既存サイズ:{1}+{2}={3}"
                                , U.To0xHexString(newCount), U.To0xHexString(start), U.To0xHexString(count), U.To0xHexString(start + count));
                return(U.NOT_FOUND);
            }

            //オペコードの確認
            uint op = Program.ROM.u8(array_switch2_address + 1);

            if (op < 0x38 || op > 0x3D)
            {
                R.ShowStopError("別のパッチでオペコードを書き換えられているので、拡張できません\r\nアドレス:{0} オペコード:{1}"
                                , U.To0xHexString(array_switch2_address + 1), U.To0xHexString(op));
                return(U.NOT_FOUND);
            }
            op = Program.ROM.u8(array_switch2_address + 3 + extraByte);
            if (op < 0x28 || op > 0x2d)
            {
                R.ShowStopError("別のパッチでオペコードを書き換えられているので、拡張できません\r\nアドレス:{0} オペコード:{1}"
                                , U.To0xHexString(array_switch2_address + 3), U.To0xHexString(op));
                return(U.NOT_FOUND);
            }
            //ユーザに確認を求める.
            DialogResult dr = R.ShowYesNo("配列を {0}まで拡張してもよろしいですか?"
                                          , U.To0xHexString(newCount));

            if (dr != DialogResult.Yes)
            {
                return(U.NOT_FOUND);
            }

            byte[] dd = Program.ROM.getBinaryData(pointeraddr, count * 4);
            byte[] d  = new byte[(newCount + 1) * 4];
            for (uint i = 0; i < start; i++)
            {
                U.write_p32(d, i * 4, defaultJumpAddr);
            }
            Array.Copy(dd, 0, d, start * 4, count * 4);
            for (uint i = start + count; i < newCount; i++)
            {
                U.write_p32(d, i * 4, defaultJumpAddr);
            }

            uint newaddr = InputFormRef.AppendBinaryData(d, undodata);

            if (newaddr == U.NOT_FOUND)
            {
                return(U.NOT_FOUND);
            }

            Program.ROM.write_p32(array_pointer, newaddr, undodata);
            Program.ROM.write_u8(array_switch2_address + 0, 0, undodata);
            Program.ROM.write_u8(array_switch2_address + 2 + extraByte, newCount - 1, undodata);

            return(newaddr);
        }
        uint NewAlloc()
        {
            byte[] alloc = new byte[36 + (36 * 9) + 4];

            Undo.UndoData undodata = Program.Undo.NewUndoData("NewAlloc");
            uint          addr     = InputFormRef.AppendBinaryData(alloc, undodata);

            if (addr == U.NOT_FOUND)
            {//割り当て失敗
                return(U.NOT_FOUND);
            }
            uint prEventMenuCommandEffect = FindEventMenuCommandEffect();

            if (prEventMenuCommandEffect == U.NOT_FOUND)
            {//パッチがインストールされていない.
                return(U.NOT_FOUND);
            }

            uint prEventMenuDisplayCommand = FindEventMenuDisplayCommand();
            uint prEventMenuDrawFunction   = FindEventMenuDrawCommand();

            Program.ROM.write_u8(addr + 0, 6, undodata);          //x
            Program.ROM.write_u8(addr + 1, 8, undodata);          //y
            Program.ROM.write_u8(addr + 2, 18, undodata);         //width
            Program.ROM.write_u8(addr + 3, 0, undodata);          //height
            Program.ROM.write_u32(addr + 4, 1, undodata);         //style
            Program.ROM.write_p32(addr + 8, addr + 36, undodata); //Command Definitions


            uint[] texts;
            if (Program.ROM.RomInfo.is_multibyte)
            {
                texts = new uint[] { 0xBD5, 0xBD6, 0, 0, 0, 0, 0, 0 };
            }
            else
            {
                texts = new uint[] { 0xC15, 0xC16, 0, 0, 0, 0, 0, 0 };
            }

            uint a = addr + 36;

            for (uint i = 0; i < 9; i++, a += 36)
            {
                Program.ROM.write_u16(a + 4, texts[i], undodata); //text
                if (texts[i] == 0)
                {
                    break;
                }
                if (Program.ROM.RomInfo.is_multibyte)
                {
                    Program.ROM.write_p32(a + 0, 0x1f5310, undodata); //null文字列
                }

                Program.ROM.write_u8(a + 9, i, undodata);                           //MenuID
                Program.ROM.write_p32(a + 12, prEventMenuDisplayCommand, undodata); //表示時
                Program.ROM.write_p32(a + 16, prEventMenuDrawFunction, undodata);   //描画時
                Program.ROM.write_p32(a + 20, prEventMenuCommandEffect, undodata);  //選択時
            }

            {//nullが大量にできるので、終端マークを入れます.
                a = addr + 36 + (36 * 9);
                Program.ROM.write_u32(a, 0xffffffff, undodata);
            }

            //新規に追加した分のデータを書き込み.
            Program.Undo.Push(undodata);

            InputFormRef.WriteButtonToYellow(this.AllWriteButton, false);
            InputFormRef.ShowWriteNotifyAnimation(this, 0);
            return(addr);
        }
Beispiel #23
0
        public uint Write(byte[] write_data, Undo.UndoData undodata)
        {
            for (int i = 0; i < this.Recycle.Count; i++)
            {
                Address p = this.Recycle[i];
                if (p.Length >= write_data.Length)
                {
                    uint use_addr  = p.Addr;
                    uint left_size = p.Length;
                    if (!U.isPadding4(use_addr))
                    {     //padding4ではないと端数が出てしまうので補正する
                        if (left_size < 4)
                        { //空きがなさすぎるため利用しない
                            Log.Notify("アドレスが端数値なので補正しようとしましたが、サイズが4未満なので利用しません", U.To0xHexString(p.Addr));
                            continue;
                        }
                        uint diff = 4 - (use_addr % 4);
                        use_addr  += diff;
                        left_size -= diff;
                        Debug.Assert(U.isPadding4(use_addr));
                        if (left_size < write_data.Length)
                        {//align 4補正したらサイズが足りん!
                            Log.Notify("アドレスが端数値なので補正しようとしたらサイズ不足になりました", U.To0xHexString(p.Addr));
                            continue;
                        }
                        Log.Notify("アドレスが端数値なので補正します。", U.To0xHexString(p.Addr));
                    }

                    //ちょうど良い領域があったので利用しよう
                    Program.ROM.write_range(use_addr, write_data, undodata);
                    uint next_addr = U.Padding4(use_addr + (uint)write_data.Length);
                    left_size = U.Sub(left_size, (next_addr - use_addr));

                    p.ResizeAddress(next_addr, left_size);
                    if (p.Length < 4)
                    {//もう空きがない.
                        this.Recycle.RemoveAt(i);
                    }

                    return(use_addr);
                }
            }

            if (this.Recycle.Count <= 0)
            {
                //空き領域から利用.
                return(InputFormRef.AppendBinaryData(write_data, undodata));
            }
            else
            {
                int     lasiI = this.Recycle.Count - 1;
                Address lastP = this.Recycle[lasiI];
                if (lastP.Addr + lastP.Length >= Program.ROM.Data.Length)
                {//自分が最後のデータだった場合
                    //ROMサイズを増設.
                    Program.ROM.write_resize_data(U.Padding4(lastP.Addr + (uint)write_data.Length));
                    Program.ROM.write_range(lastP.Addr, write_data, undodata);

                    this.Recycle.RemoveAt(lasiI);
                    return(lastP.Addr);
                }

                //空き領域から利用.
                return(InputFormRef.AppendBinaryData(write_data, undodata));
            }
        }
Beispiel #24
0
        //switch文の拡張
        public static uint Switch1Expands(uint array_pointer
                                          , uint array_switch1_address
                                          , uint newCount
                                          , uint defaultJumpAddr
                                          , Undo.UndoData undodata)
        {
            uint pointeraddr = Program.ROM.p32(array_pointer);
            //0802fbc4 2876         cmp	r0, #76
            uint start = 0;
            uint count = Program.ROM.u8(array_switch1_address + 0);

            if (newCount <= count)
            {
                R.ShowStopError("既に十分な数を確保しています。\r\nあなたの要求:{0} 既存サイズ:{1}+{2}={3}"
                                , U.To0xHexString(newCount), U.To0xHexString(start), U.To0xHexString(count), U.To0xHexString(start + count));
                return(U.NOT_FOUND);
            }

            //オペコードの確認
            uint op = Program.ROM.u8(array_switch1_address + 1);

            if (op < 0x28 || op > 0x2d)
            {
                R.ShowStopError("別のパッチでオペコードを書き換えられているので、拡張できません\r\nアドレス:{0} オペコード:{1}"
                                , U.To0xHexString(array_switch1_address + 1), U.To0xHexString(op));
                return(U.NOT_FOUND);
            }
            //ユーザに確認を求める.
            DialogResult dr = R.ShowYesNo("配列を {0}まで拡張してもよろしいですか?"
                                          , U.To0xHexString(newCount));

            if (dr != DialogResult.Yes)
            {
                return(U.NOT_FOUND);
            }

            byte[] dd = Program.ROM.getBinaryData(pointeraddr, count * 4);
            byte[] d  = new byte[(newCount + 1) * 4];
            for (uint i = 0; i < start; i++)
            {
                U.write_p32(d, i * 4, defaultJumpAddr);
            }
            Array.Copy(dd, 0, d, start * 4, count * 4);
            for (uint i = start + count; i < newCount; i++)
            {
                U.write_p32(d, i * 4, defaultJumpAddr);
            }

            uint newaddr = InputFormRef.AppendBinaryData(d, undodata);

            if (newaddr == U.NOT_FOUND)
            {
                return(U.NOT_FOUND);
            }

            undodata.list.Add(new Undo.UndoPostion(array_pointer, 4));
            undodata.list.Add(new Undo.UndoPostion(array_switch1_address + 0, 1));
            undodata.list.Add(new Undo.UndoPostion(array_switch1_address + 2, 1));

            Program.ROM.write_p32(array_pointer, newaddr);
            Program.ROM.write_u8(array_switch1_address + 0, newCount - 1);

            return(newaddr);
        }
        public static uint ImportAllLow(string filename, Undo.UndoData undodata)
        {
            string dir = Path.GetDirectoryName(filename);

            //まずはデータ数を知らないといけない.
            List <byte>            bin  = new List <byte>();
            List <DataWriteHelper> data = new List <DataWriteHelper>();

            string[] lines = File.ReadAllLines(filename);
            for (int i = 0; i < lines.Length; i++)
            {
                string line = lines[i];
                if (U.IsComment(line) || U.OtherLangLine(line))
                {
                    continue;
                }
                line = U.ClipComment(line);
                if (line == "")
                {
                    continue;
                }
                InputFormRef.DoEvents(null, filename + ":" + i);

                string[] sp = line.Split(new char[] { '\t' }, StringSplitOptions.RemoveEmptyEntries);
                if (sp.Length < 4 + 2)
                {
                    R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 6);
                    return(U.NOT_FOUND);
                }
                uint type = U.atoh(sp[0]);
                U.append_u8(bin, type);
                U.append_u8(bin, U.atoh(sp[1]));
                U.append_u8(bin, U.atoh(sp[2]));
                U.append_u8(bin, U.atoh(sp[3]));

                if (type == 0x00 ||
                    type == 0x08 ||
                    type == 0x10 ||
                    type == 0x18
                    )
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                        return(U.NOT_FOUND);
                    }
                    byte[] wav   = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, wav, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(wav, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x03 ||
                         type == 0x0B
                         )
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                        return(U.NOT_FOUND);
                    }
                    byte[] wav   = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, wav, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(wav, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x80)
                {
                    if (sp.Length < 4 + 1 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 9);
                        return(U.NOT_FOUND);
                    }

                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        if (file.IndexOf("@SELF+") >= 0)
                        {
                            uint relativeAddress = U.atoh(file.Substring(6));
                            data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                            U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                        }
                        else if (file.IndexOf("@BROKENDATA") >= 0)
                        {//ドラム内でドラムがあるような変なデータ
                            uint relativeAddress = 0;
                            data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                            U.append_u32(bin, 0); //とりあえず @SELF+0として扱う.
                        }
                        else
                        {
                            R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                    }
                    else
                    {
                        uint wav = ImportAllLow(file, undodata);
                        if (wav == U.NOT_FOUND)
                        {
                            R.ShowStopError("ネストする楽器データ({1})を登録できません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        U.append_u32(bin, U.toPointer(wav));
                    }
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                }
                else if (type == 0x40)
                {
                    string file = Path.Combine(dir, sp[4]);
                    if (!File.Exists(file))
                    {
                        if (file.IndexOf("@SELF+") < 0)
                        {
                            R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        uint relativeAddress = U.atoh(file.Substring(6));
                        data.Add(new DataWriteHelper(relativeAddress, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {
                        uint wav = ImportAllLow(file, undodata);
                        if (wav == U.NOT_FOUND)
                        {
                            R.ShowStopError("ネストする楽器データ({1})を登録できません。\r\n{0}行目", i + 1, file);
                            return(U.NOT_FOUND);
                        }
                        U.append_u32(bin, U.toPointer(wav));
                    }

                    file = Path.Combine(dir, sp[5]);
                    if (!File.Exists(file))
                    {
                        R.ShowStopError("楽器データ({1})がありません。\r\n{0}行目", i + 1, file);
                    }

                    //データは後で入れましょう.
                    byte[] multi = File.ReadAllBytes(file);
                    uint   found = U.Grep(Program.ROM.Data, multi, 0x100, 0, 4);
                    if (found == U.NOT_FOUND)
                    {                         //既存のROMにないので追加
                        data.Add(new DataWriteHelper(multi, bin.Count));
                        U.append_u32(bin, 0); //後でこの位置にアドレスを書く.
                    }
                    else
                    {//既にあるので使いまわす.
                        U.append_u32(bin, U.toPointer(found));
                    }
                }
                else
                {
                    if (sp.Length < 4 + 4 + 4)
                    {
                        R.ShowStopError("データの形式が正しくありません。\r\n少なくとも{1}個のデータが必要です。\r\n{0}行目", i + 1, 12);
                        return(U.NOT_FOUND);
                    }
                    U.append_u8(bin, U.atoh(sp[4]));
                    U.append_u8(bin, U.atoh(sp[5]));
                    U.append_u8(bin, U.atoh(sp[6]));
                    U.append_u8(bin, U.atoh(sp[7]));
                    U.append_u8(bin, U.atoh(sp[8]));
                    U.append_u8(bin, U.atoh(sp[9]));
                    U.append_u8(bin, U.atoh(sp[10]));
                    U.append_u8(bin, U.atoh(sp[11]));
                }
            }
            //終端データ.
            U.append_u32(bin, 0);
            U.append_u32(bin, 0);
            U.append_u32(bin, 0);

            uint startaddr = InputFormRef.AppendBinaryData(bin.ToArray(), undodata);

            if (startaddr == U.NOT_FOUND)
            {
                return(U.NOT_FOUND);
            }
            for (int i = 0; i < data.Count; i++)
            {
                if (data[i].Data == null)
                {
                    uint writeAddress = startaddr + data[i].WriteOffset;
                    Program.ROM.write_p32(writeAddress, data[i].RelativeAddress + startaddr);
                }
                else
                {
                    uint dataAddress = InputFormRef.AppendBinaryData(data[i].Data, undodata);
                    if (dataAddress == U.NOT_FOUND)
                    {
                        return(U.NOT_FOUND);
                    }

                    uint writeAddress = startaddr + data[i].WriteOffset;
                    Program.ROM.write_p32(writeAddress, dataAddress);
                }
            }

            return(startaddr);
        }