//マップのタイルの種類だけの配列を作る public static byte[] LoadMapTileIDs(uint mapid, out int outMapWidth, out int outMapHeight) { MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereMapID(mapid); ushort[] mar = ImageUtilMap.UnLZ77MapDataUShort(plists.mappointer_plist, out outMapWidth, out outMapHeight); if (mar == null) { return(null); } byte[] configUZ = ImageUtilMap.UnLZ77ChipsetData(plists.config_plist); if (configUZ == null) { return(null); } int size = outMapWidth * outMapHeight; byte[] tiles = new byte[size]; for (int i = 0; i < size; i++) { uint terrain_data = ImageUtilMap.GetChipsetID(mar[i], configUZ); if (terrain_data == U.NOT_FOUND) { continue; } tiles[i] = (byte)terrain_data; } return(tiles); }
public void JumpToMAPID(uint mapid) { MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(mapid); for (int i = 0; i < this.MapEditConf.Count; i++) { if (plist.anime1_plist == this.MapEditConf[i].anime1_plist && plist.anime2_plist == this.MapEditConf[i].anime2_plist && plist.config_plist == this.MapEditConf[i].config_plist && plist.obj_plist == this.MapEditConf[i].obj_plist && plist.palette_plist == this.MapEditConf[i].palette_plist ) { JumpTo(i); return; } } for (int i = 0; i < this.MapEditConf.Count; i++) { if (plist.config_plist == this.MapEditConf[i].config_plist && plist.obj_plist == this.MapEditConf[i].obj_plist && plist.palette_plist == this.MapEditConf[i].palette_plist ) { JumpTo(i); return; } } }
static List <U.AddrResult> MakeTileAnimation2() { Dictionary <uint, bool> alreadFound = new Dictionary <uint, bool>(); List <U.AddrResult> ret_list = new List <U.AddrResult>(); uint mapmax = MapSettingForm.GetDataCount(); for (uint i = 0; i < mapmax; i++) { MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(i); if (plist.anime2_plist == 0) { continue; } if (alreadFound.ContainsKey(plist.anime2_plist)) { continue; } uint addr = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.ANIMATION2, plist.anime2_plist); string name = R._("タイルアニメーション2 パレットアニメ:{0}", U.ToHexString(plist.anime2_plist)); if (addr == U.NOT_FOUND) { name += R._("(破損)"); } U.AddrResult ar = new U.AddrResult(addr, name, plist.anime2_plist); ret_list.Add(ar); alreadFound[plist.anime2_plist] = true; } return(ret_list); }
private void FilterComboBox_SelectedIndexChanged(object sender, EventArgs e) { if (this.InputFormRef == null) { return; } U.AddrResult ar = InputFormRef.SelectToAddrResult(FilterComboBox, FilterComboBox.SelectedIndex); if (ar.isNULL()) { return; } //サンプルのマップを表示します. uint mapmax = MapSettingForm.GetDataCount(); for (uint i = 0; i < mapmax; i++) { MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(i); if (plist.anime2_plist == ar.tag) { this.MapPictureBox.LoadMap(i); break; } } this.InputFormRef.ReInit(ar.addr); }
private void ExportGif(string filename) { uint mapid = this.MapPictureBox.GetMapID(); if (mapid == U.NOT_FOUND) { return; } MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(mapid); if (plist.palette_plist == 0) { return; } uint palette = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, plist.palette_plist); if (palette == U.NOT_FOUND) { return; } int palette_index = SamplePaletteComboBox.SelectedIndex; if (palette_index < 0) { palette_index = 0; } uint addr = InputFormRef.BaseAddress; if (!U.isSafetyOffset(addr)) { return; } //同じアニメを何度も出力しないように記録する. List <ImageUtilAnimeGif.Frame> bitmaps = new List <ImageUtilAnimeGif.Frame>(); for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { uint wait = Program.ROM.u16(addr + 0); uint length = Program.ROM.u16(addr + 2); uint p4 = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(p4)) { continue; } MapSettingForm.MapAnimations anime = new MapSettingForm.MapAnimations(); anime.change_bitmap_bytes = GetTileAnime1(p4, length); Bitmap mapBitmap = MapSettingForm.DrawMap(mapid, anime); bitmaps.Add(new ImageUtilAnimeGif.Frame(mapBitmap, wait)); } //アニメgif生成 ImageUtilAnimeGif.SaveAnimatedGif(filename, bitmaps); U.SelectFileByExplorer(filename); }
//マップ領域のベース領域の強制割り当て 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); }
//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); }
void SelectMapID(uint mapid) { MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID((uint)mapid); uint change_plist_addr = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CHANGE, plist.mapchange_plist); uint selected = InputFormRef.AddrToSelect(this.AddressList, change_plist_addr); if (selected == U.NOT_FOUND) { return; } U.SelectedIndexSafety(this.AddressList, selected); }
static void ExportAll(string filename, InputFormRef ifr, uint mapid, int palette_index) { uint addr = ifr.BaseAddress; if (!U.isSafetyOffset(addr)) { return; } string dir = Path.GetDirectoryName(filename); string file = Path.GetFileNameWithoutExtension(filename); MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(mapid); if (plist.palette_plist == 0) { return; } uint palette = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, plist.palette_plist); if (palette == U.NOT_FOUND) { return; } List <string> lines = new List <string>(); { string line = "//wait\tfilename"; lines.Add(line); } for (int i = 0; i < ifr.DataCount; i++, addr += ifr.BlockSize) { uint w0 = Program.ROM.u16(addr + 0); uint length = Program.ROM.u16(addr + 2); uint p4 = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(p4)) { continue; } Bitmap bitmap = GetTileAnime1(p4, length, palette, palette_index); string imgfilename = file + "_" + i.ToString("000") + ".png"; bitmap.Save(Path.Combine(dir, imgfilename)); string line = w0 + "\t" + imgfilename + "\t" + length; lines.Add(line); } File.WriteAllLines(filename, lines); }
//パレットの割り当て 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); }
static InputFormRef Init(Form self) { return(new InputFormRef(self , "" , Program.ROM.RomInfo.map_setting_pointer() , Program.ROM.RomInfo.map_setting_datasize() , (int i, uint addr) => { //0 がポインタであればデータがあると考える. return U.isPointer(Program.ROM.u32(addr + 0)); } , (int i, uint addr) => { MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID((uint)i); uint change_plist_addr = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CHANGE, plist.mapchange_plist); string name = MapSettingForm.GetMapName((uint)i); return new U.AddrResult(change_plist_addr, name, (uint)i); } )); }
private void AddressList_SelectedIndexChanged(object sender, EventArgs e) { uint mapid = this.MapPictureBox.GetMapID(); if (mapid == U.NOT_FOUND) { return; } MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(mapid); if (plist.palette_plist == 0) { return; } uint palette = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, plist.palette_plist); if (palette == U.NOT_FOUND) { return; } int palette_index = SamplePaletteComboBox.SelectedIndex; if (palette_index < 0) { palette_index = 0; } this.ChangePaletteBitmap = GetTileAnime1((uint)P4.Value, (uint)W2.Value, palette, palette_index); this.X_SAMPLE_BIG_PIC.Image = this.ChangePaletteBitmap; MapSettingForm.MapAnimations anime = new MapSettingForm.MapAnimations(); anime.change_bitmap_bytes = GetTileAnime1((uint)P4.Value, (uint)W2.Value); //マップの再描画 this.MapPictureBox.UpdateAnime(anime); }
public static void MakeCheckError(uint mapid, List <FELint.ErrorSt> errors) { InputFormRef N_InputFormRef = N_Init(null); MapSettingForm.PLists plists = MapSettingForm.GetMapPListsWhereMapID(mapid); if (plists.mapchange_plist == 0) {//マップ変化がない return; } uint change_addr = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CHANGE, plists.mapchange_plist); if (!U.isSafetyOffset(change_addr)) {//マップ設定の方でトラップするので不要. return; } byte[] configUZ = ImageUtilMap.UnLZ77ChipsetData(plists.config_plist); if (configUZ == null) {//マップ設定の方でトラップするので不要. return; } //マップサイズ int mapwidth; int mapheight; ImageUtilMap.UnLZ77MapDataUShort(plists.mappointer_plist, out mapwidth, out mapheight); bool isFE6 = Program.ROM.RomInfo.version() == 6; N_InputFormRef.ReInit(change_addr); List <uint> useNumber = new List <uint>(); uint addr = N_InputFormRef.BaseAddress; for (int i = 0; i < N_InputFormRef.DataCount; i++, addr += N_InputFormRef.BlockSize) { uint number = Program.ROM.u8(0 + addr); if (useNumber.IndexOf(number) >= 0) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr , R._("マップ変化({0})のIDが重複しています", U.To0xHexString(number)))); continue; } if (number > 0x7f) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr , R._("マップ変化({0})のIDが、0x7Fを超えています。\r\nマップ変化IDは、0x7F以下でなければなりません。", U.To0xHexString(number)))); continue; } uint x = Program.ROM.u8(1 + addr); uint y = Program.ROM.u8(2 + addr); uint width = Program.ROM.u8(3 + addr); uint height = Program.ROM.u8(4 + addr); uint pointer = Program.ROM.u32(8 + addr); //マップ変化を使いまわしているところが軒並みエラーになるのでやめておこう... // if (x + width > mapwidth) // { // errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr // , R._("マップ変化({0})の幅(X:{1} Width:{2})は、マップの幅({3})より大きいです", number, x , width, mapwidth))); // } // if (y + height > mapheight) // { // if (isFE6 && mapid == 0x28 && addr == 0x687A94) // { // //FE6にはマップ変化リストを間違えて指定している場所があるので無視する. // continue; // } // errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr // , R._("マップ変化({0})の高さ(Y:{1} Height:{2})は、マップの高さ({3})より大きいです", U.To0xHexString(number), y, height, mapheight))); // } if (pointer == 0) {//マップ変化ポインタ 0 を容認する. continue; } if (!U.isSafetyPointer(pointer)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr , R._("マップ変化({0})のポインタ({1})が危険です。", U.To0xHexString(number), U.To0xHexString(pointer)))); continue; } //ポインタ先の検証. uint mapAddr = U.toOffset(pointer); uint limitAddr = mapAddr + (2 * width * height); if (!U.isSafetyOffset(limitAddr - 1)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr , R._("マップ変化({0})のポインタ({1})か、マップ変化のサイズの指定が正しくありません。", U.To0xHexString(number), U.To0xHexString(pointer)))); continue; } for (; mapAddr < limitAddr; mapAddr += 2) { int mapData = (int)Program.ROM.u16(mapAddr); if (!ImageUtilMap.IsCorrectMapChip(mapData, configUZ, isFE6)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPCHANGE, addr , R._("マップ変化({0})のポインタ({1})先のデータで、不正なタイルデータ({2})。", U.To0xHexString(number), U.To0xHexString(pointer), U.To0xHexString(mapData)))); break; } } } }
//プログラムからのデータ拡張 public static bool ResizeChangeList(uint mapid, uint newcount) { List <ChangeSt> changeList = new List <ChangeSt>(); uint change_addr = MapSettingForm.GetMapChangeAddrWhereMapID(mapid); if (change_addr == U.NOT_FOUND) { return(false); } InputFormRef N_InputFormRef = N_Init(null); N_InputFormRef.ReInit(change_addr); uint olddatasize = N_InputFormRef.DataCount * N_InputFormRef.BlockSize; uint newdatasize = (newcount + 1) * N_InputFormRef.BlockSize; if (newdatasize < olddatasize) {//新しく確保するテーブル数が小さい場合 //特に何もしない. return(true); } //既存データの取得 byte[] oldDataByte = Program.ROM.getBinaryData(change_addr, olddatasize); //新規 byte[] newDataByte = new byte[newdatasize]; Array.Copy(oldDataByte, newDataByte, olddatasize); //新規に確保した領域にindex番号等を振る. int i = (int)N_InputFormRef.DataCount; for (; i < newcount; i++) { uint offset = (uint)(i * N_InputFormRef.BlockSize); U.write_u8(newDataByte, (uint)offset + 0, (uint)i); U.write_u8(newDataByte, (uint)offset + 3, 1); //サイズw U.write_u8(newDataByte, (uint)offset + 4, 1); //サイズh } //終端データ(newdata+1で確保しているため安全) U.write_u8(newDataByte, (uint)(i * N_InputFormRef.BlockSize), (uint)0xff); Undo.UndoData undodata = Program.Undo.NewUndoData("Resize MapChange", mapid.ToString("X"), newcount.ToString("X")); //新規領域の確保 uint newaddr = InputFormRef.AppendBinaryData(newDataByte, undodata); if (newaddr == U.NOT_FOUND) { Program.Undo.Rollback(undodata); return(false); } //PLISTのポインタを書き換える. MapSettingForm.PLists plist = MapSettingForm.GetMapPListsWhereMapID(mapid); bool r = MapPointerForm.Write_Plsit(MapPointerForm.PLIST_TYPE.CHANGE, plist.mapchange_plist, newaddr, undodata); if (!r) { Program.Undo.Rollback(undodata); return(false); } Program.Undo.Push(undodata); return(true); }