//マップのタイルの種類だけの配列を作る 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 static Bitmap DrawBorderImages(Bitmap parts, uint ap_addr, int x, int y) { ap_addr = U.toOffset(ap_addr); ImageUtilAP ap = new ImageUtilAP(); bool r = ap.Parse(ap_addr); if (!r) { return(null); } Bitmap borderimg = ImageUtil.Blank(256, 160, parts); ap.DrawFrame(borderimg, 0, x, y, parts); ap.DrawFrame(borderimg, 1, x, y, parts); Bitmap worldmap = ImageUtilMap.DrawWorldMapEvent(); Bitmap retScreen = new Bitmap(256, 160); using (Graphics g = Graphics.FromImage(retScreen)) { g.DrawImage(worldmap, 0, 0); U.MakeTransparent(borderimg); g.DrawImage(borderimg, 0, 0); borderimg.Dispose(); } return(retScreen); }
private void ANIME2numericUpDown_ValueChanged(object sender, EventArgs e) { uint plist = (uint)ANIME2numericUpDown.Value; LINK_PLIST_ANIME2.Text = PlistToName(plist, MapPointerForm.PLIST_TYPE.ANIMATION2); MapPictureBox.LoadMap(ImageUtilMap.DrawMap(GetOBJPLIST(), GetPALPLIST(), GetCONFIGPLIST(), this.MapPointerPListReadOnly)); }
//街マップの下絵 static Bitmap BaseVillageMapCache() { if (MapVillageCache != null) { return(MapVillageCache); } uint obj_plist; uint palette_plist; uint config_plist; //フィールドの画像を取得 if (Program.ROM.RomInfo.version() == 8) {//FE8 obj_plist = 0x0E; palette_plist = 0x0F; config_plist = 0x10; } else if (Program.ROM.RomInfo.version() == 7) {//FE7 obj_plist = 0x10; palette_plist = 0x11; config_plist = 0x12; } else {//FE6 obj_plist = 0x12; palette_plist = 0x13; config_plist = 0x14; } MapVillageCache = ImageUtilMap.DrawMapStyle(obj_plist, palette_plist, config_plist); return(MapVillageCache); }
//フィールドマップの下絵 static Bitmap BaseFieldsMapCache() { if (MapFieldsCache != null) { return(MapFieldsCache); } uint obj_plist; uint palette_plist; uint config_plist; //フィールドの画像を取得 if (Program.ROM.RomInfo.version() == 8) {//FE8 obj_plist = 0x01; palette_plist = 0x02; config_plist = 0x03; } else if (Program.ROM.RomInfo.version() == 7) {//FE7 obj_plist = 0x1d1c; palette_plist = 0x1e; config_plist = 0x1f; } else {//FE6 obj_plist = 0x0201; palette_plist = 0x03; config_plist = 0x04; } MapFieldsCache = ImageUtilMap.DrawMapStyle(obj_plist, palette_plist, config_plist); return(MapFieldsCache); }
void ReloadMap_Obj_Config_Palette(uint obj_plist, uint palette_plist, uint config_plist) { //マップチップの読込 this.MapObjImage = ImageUtilMap.DrawMapChipOnly(obj_plist, palette_plist); if (this.MapObjImage == null) { this.MapObjImage = ImageUtil.BlankDummy(); } //チップセットの読込(マップチップの画像をどう解釈するか定義するデータ) this.ConfigUZ = ImageUtilMap.UnLZ77ChipsetData(config_plist); if (this.ConfigUZ == null) { this.ConfigUZ = new byte[0]; } //Plistアドレスの更新 Display_Plist(obj_plist, palette_plist, config_plist); //チップセットの描画 Chipset_Update(); //マップサンプルを出します. Bitmap newbitmap = ImageUtil.SwapPalette(this.MapObjImage, (int)0); this.MAP.LoadMap(newbitmap); }
public static Bitmap DrawWorldMap() { //FE7U のワールドマップは12分割されている 1024x688 //PAL:574990 16色*4種類 //IMAGE HEADERTSA SIZE //[0x0E7848] [0xB5BEC] //DATA -------------------- //574A10-5CAA10 256x256 //57CA10-5CB214 256x256 //584A10-5CBA18 256x256 //58CA10-5CC21C 256x256 //594A10-5CCA20 256x256 //59CA10-5CD224 256x256 //5A4A10-5CDA28 256x256 //5ACA10-5CE22C 256x256 //5B4A10-5CEA30 256x176 //5BA210-5CF234 256x176 //5BFA10-5CFA38 256x176 //5C5210-5D023C 256x176 // //情報元: //see https://serenesforest.net/forums/index.php?/topic/34362-fe7-world-map-tsa-tips/ uint imagemap = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_image_pointer()); uint palette = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palette_pointer()); uint tsamap = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palettemap_pointer()); return(ImageUtilMap.DrawWorldMapFE7(imagemap, palette, tsamap)); }
public static Bitmap DrawDarkWorldMap() { uint image = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_image_pointer()); uint palette = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_dpalette_pointer()); uint palettemap = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palettemap_pointer()); return(ImageUtilMap.DrawWorldMap(image, palette, palettemap)); }
private void AddressList_SelectedIndexChanged(object sender, EventArgs e) { uint obj_plist = (uint)W4.Value; uint palette_plist = (uint)B6.Value; uint config_plist = (uint)B7.Value; uint mappointer_plist = (uint)B8.Value; MapPictureBox.LoadMap(ImageUtilMap.DrawMap(obj_plist, palette_plist, config_plist, mappointer_plist)); }
public static Bitmap DrawWorldMap() { //FE6のワールドマップは 256色 tileではなく、通常の画像のようなlinerである. // //情報元: uint image256Z = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_image_pointer()); uint paletteZ = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palette_pointer()); return(ImageUtilMap.DrawWorldMapFE6(image256Z, paletteZ)); }
public static Bitmap DrawMap(uint id, uint obj_plist, uint palette_plist, uint config_plist, MapAnimations anime = null) { InputFormRef InputFormRef = Init(null); uint addr = InputFormRef.IDToAddr(id); if (!U.isSafetyOffset(addr)) { return(ImageUtil.BlankDummy(16)); } uint mappointer_plist = (uint)Program.ROM.u8(addr + 8); return(ImageUtilMap.DrawMap(obj_plist, palette_plist, config_plist, mappointer_plist, anime)); }
public void Init(uint objPList, uint palPList, uint configPList , uint mapPointerPListReadOnly , uint anime1PList, uint anime2PList) { InitUI(); MapPointerPListReadOnly = mapPointerPListReadOnly; U.SelectedIndexSafety(OBJ1numericUpDown, objPList & 0xff); U.SelectedIndexSafety(OBJ2numericUpDown, (objPList >> 8) & 0xff); U.SelectedIndexSafety(PALnumericUpDown, palPList); U.SelectedIndexSafety(CONFIGnumericUpDown, configPList); U.SelectedIndexSafety(ANIME1numericUpDown, anime1PList); U.SelectedIndexSafety(ANIME2numericUpDown, anime2PList); MapPictureBox.LoadMap(ImageUtilMap.DrawMap(objPList, palPList, configPList, mapPointerPListReadOnly)); }
void ToConfigData(int chipset_id) { //このチップセットの名前を問い合わせる. uint terrain_data = ImageUtilMap.GetChipsetID(chipset_id, this.ConfigUZ); if (terrain_data == U.NOT_FOUND) { return; } if (terrain_data >= this.ConfigTerrain.Items.Count) { return; } IsInit = true; this.ConfigNo.Text = "0x" + U.ToHexString(chipset_id); U.SelectedIndexSafety(this.ConfigTerrain, terrain_data); int tile_tsa_index = chipset_id << 1; if (tile_tsa_index + 7 >= ConfigUZ.Length) {//不正なTSA SetBadTSA(); IsInit = false; return; } uint mapwidth8 = (uint)(this.MAP.GetMapBitmapWidth() / 8); if (mapwidth8 <= 1) {//元となる画像が正しくないのでTSAを描画できません. SetBadTSA(); IsInit = false; return; } Config_W0.Value = (UInt16)U.u16(ConfigUZ, (uint)tile_tsa_index + 0); Config_W2.Value = (UInt16)U.u16(ConfigUZ, (uint)tile_tsa_index + 2); Config_W4.Value = (UInt16)U.u16(ConfigUZ, (uint)tile_tsa_index + 4); Config_W6.Value = (UInt16)U.u16(ConfigUZ, (uint)tile_tsa_index + 6); IsInit = false; InputFormRef.WriteButtonToYellow(this.Config_WriteButton, false); InputFormRef.WriteButtonToYellow(this.PaletteWriteButton, false); Config_L_0_TSA_PALETTE_SelectedIndexChanged(Config_L_0_TSA_PALETTE, null); DrawConfigPictureBox(chipset_id); }
void Chipset_Update() { Bitmap mapObjCels = ImageUtil.Blank(16 * 32, ImageUtilMap.CHIPSET_SEP_BYTE / 16, this.MapObjImage); int chip = 0; int y = 0; while (chip < ImageUtilMap.CHIPSET_SEP_BYTE / 8) { for (int x = 0; x < 32; x++) { ImageUtil.BitBlt(mapObjCels, x * 16, y * 16, 16, 16, ImageUtilMap.DrawOneChipset(chip << 2, this.ConfigUZ, this.MapObjImage), 0, 0); chip++; } y++; } MAPCHIPLIST.Image = mapObjCels; }
public static Bitmap DrawWorldMap() { if (Program.ROM.RomInfo.version() == 7) { return(WorldMapImageFE7Form.DrawWorldMap()); } else if (Program.ROM.RomInfo.version() == 6) { return(WorldMapImageFE6Form.DrawWorldMap()); } uint image = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_image_pointer()); uint palette = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palette_pointer()); uint palettemap = Program.ROM.p32(Program.ROM.RomInfo.worldmap_big_palettemap_pointer()); return(ImageUtilMap.DrawWorldMap(image, palette, palettemap)); }
public static Bitmap DrawMapChange(uint id, int width, int height, uint change_address, MapAnimations anime = null) { InputFormRef InputFormRef = Init(null); uint addr = InputFormRef.IDToAddr(id); if (!U.isSafetyOffset(addr)) { return(ImageUtil.BlankDummy()); } if (width <= 0 || height <= 0) { return(ImageUtil.BlankDummy()); } uint obj_plist = (uint)Program.ROM.u16(addr + 4); uint palette_plist = (uint)Program.ROM.u8(addr + 6); uint config_plist = (uint)Program.ROM.u8(addr + 7); return(ImageUtilMap.DrawChangeMap(obj_plist, palette_plist, config_plist, width, height, change_address, anime)); }
private void PaletteImportButton_Click(object sender, EventArgs e) { if (this.MapStyle.SelectedIndex < 0) { return; } uint palette_plist = this.MapEditConf[this.MapStyle.SelectedIndex].palette_plist; uint obj_plist = this.MapEditConf[this.MapStyle.SelectedIndex].obj_plist; Bitmap bitmap = ImageFormRef.ImportFilenameDialog(this); if (bitmap == null) { return; } bool r = MapPaletteImport(bitmap, palette_plist); if (!r) { return; } //パレットの交換 this.MapObjImage = ImageUtilMap.DrawMapChipOnly(obj_plist, palette_plist); if (this.MapObjImage == null) { this.MapObjImage = ImageUtil.BlankDummy(); } U.ForceUpdate(this.PaletteCombo, 0); //チップセットの更新. Chipset_Update(); SelectedChipset_Update(); MapStyle_SelectedIndexChanged(sender, e); InputFormRef.WriteButtonToYellow(this.PaletteWriteButton, false); //マップエディタが開いていれば更新する MapEditorForm.UpdateMapStyleIfOpen(); }
public static UInt16[] UnLZ77MapDataUShort(uint mappointer_plist, out int out_width, out int out_height) { //マップ配置データの読込 byte[] mappointerUZ = ImageUtilMap.UnLZ77MapData(mappointer_plist); if (mappointerUZ == null) { out_width = 0; out_height = 0; return(null); } int mapWidth = mappointerUZ[0]; int mapHeight = mappointerUZ[1]; if (mapWidth <= 0 || mapHeight <= 0) { out_width = 0; out_height = 0; return(null); } UInt16[] mar = new UInt16[(mapWidth) * (mapHeight)]; int n = 0; int length = mappointerUZ.Length; for (int i = 2; i + 1 < length; i += 2, n++) { if (n >= mar.Length) { break; } //マップデータを読む int m = (mappointerUZ[i] + ((UInt16)mappointerUZ[i + 1] << 8)); mar[n] = (UInt16)m; } out_width = mapWidth; out_height = mapHeight; return(mar); }
private void ChangeButton_Click(object sender, EventArgs e) { int w = (int)(this.ChangeData.width + L.Value + R.Value); int h = (int)(this.ChangeData.height + T.Value + B.Value); if (this.ChangeData.no == U.NOT_FOUND) {//メインマップ if (w < 15 || h < 10) { FEBuilderGBA.R.ShowStopError(FEBuilderGBA.R._("メインマップは 15x10 以下のサイズにできません。")); return; } uint limitWidth = ImageUtilMap.GetLimitMapWidth(h); if (limitWidth == 0) { FEBuilderGBA.R.ShowStopError(FEBuilderGBA.R._("マップが広すぎます。\r\n現在のサイズ({0},{1})", w, h)); return; } if (w > limitWidth) { FEBuilderGBA.R.ShowStopError(FEBuilderGBA.R._("マップが広すぎます。\r\n現在のサイズ({0},{1})\r\nこの幅だと、利用可能な高さは、幅は{2}までです。", w, h, limitWidth)); return; } } else {//変更 if (w < 1 || h < 1) { FEBuilderGBA.R.ShowStopError("サイズを1x1以下にはできません"); return; } } this.DialogResult = System.Windows.Forms.DialogResult.OK; this.Close(); }
public static Bitmap DrawMapStyle( uint obj_plist //image , uint palette_plist //palette , uint config_plist //tsa ) { //マップチップの読込 Bitmap MapObjImage = ImageUtilMap.DrawMapChipOnly(obj_plist, palette_plist); if (MapObjImage == null) { MapObjImage = ImageUtil.BlankDummy(); } //チップセットの読込(マップチップの画像をどう解釈するか定義するデータ) byte[] configUZ = ImageUtilMap.UnLZ77ChipsetData(config_plist); if (configUZ == null) { configUZ = new byte[0]; } Bitmap mapObjCels = ImageUtil.Blank(16 * 32, ImageUtilMap.CHIPSET_SEP_BYTE / 16, MapObjImage); int chip = 0; int y = 0; while (chip < ImageUtilMap.CHIPSET_SEP_BYTE / 8) { for (int x = 0; x < 32; x++) { ImageUtil.BitBlt(mapObjCels, x * 16, y * 16, 16, 16, ImageUtilMap.DrawOneChipset(chip << 2, configUZ, MapObjImage), 0, 0); chip++; } y++; } return(mapObjCels); }
void DrawConfigPictureBox(int chipset_id) { ConfigPictureBox.Image = ImageUtilMap.DrawOneChipset(chipset_id, this.ConfigUZ, this.MapObjImage); }
void DrawMapChipInfo(int chipset_id, int x, int y, PaintEventArgs e) { PointF pt = new PointF(); pt.X = x; pt.Y = y; //このチップセットの名前を問い合わせる. uint terrain_data = ImageUtilMap.GetChipsetID(chipset_id, this.configUZ); if (terrain_data == U.NOT_FOUND) { return; } const uint test_class = 1; //主人公クラス string terrain_name = MapTerrainNameForm.GetName(terrain_data); string terrain_kaihi = R._("地形回避") + ":" + MoveCostForm.GetMoveCost(test_class, terrain_data, 3).ToString(); //地形回避 string terrain_kaifuku = R._("地形回復") + ":" + MoveCostForm.GetMoveCost(test_class, terrain_data, 6).ToString(); //地形回復 string terrain_tuukou = R._("地形コスト") + ":"; uint cost = MoveCostForm.GetMoveCost(test_class, terrain_data, 0); terrain_tuukou += cost.ToString(); if (cost >= 255) { cost = MoveCostForm.GetMoveCost(ClassForm.GetFlyClass(), terrain_data, 0); if (cost < 255) { terrain_tuukou += R._("(飛行のみ)"); } else { terrain_tuukou += R._("(全員不可)"); } } Rectangle windowrc = new Rectangle(); windowrc.X = (int)pt.X + 48 + 1; windowrc.Y = (int)pt.Y; windowrc.Width = (int)0; windowrc.Height = (int)this.Font.Height * 4; //枠を描画する幅を特定します. SizeF textSize = e.Graphics.MeasureString(terrain_name, this.Font, 1000); if (windowrc.Width < textSize.Width) { windowrc.Width = (int)textSize.Width; } textSize = e.Graphics.MeasureString(terrain_kaihi, this.Font, 1000); if (windowrc.Width < textSize.Width) { windowrc.Width = (int)textSize.Width; } textSize = e.Graphics.MeasureString(terrain_kaifuku, this.Font, 1000); if (windowrc.Width < textSize.Width) { windowrc.Width = (int)textSize.Width; } textSize = e.Graphics.MeasureString(terrain_tuukou, this.Font, 1000); if (windowrc.Width < textSize.Width) { windowrc.Width = (int)textSize.Width; } if (windowrc.X + windowrc.Width > e.ClipRectangle.Right) {//画面右端の場合、左側に押し出す. windowrc.X = windowrc.X - windowrc.Width - 32; windowrc.Y = windowrc.Y + 16 + 32; } if (windowrc.Y + windowrc.Height > e.ClipRectangle.Bottom) {//画面下端の場合、上側に押し出す. windowrc.X = windowrc.X - 16 - 32; windowrc.Y = windowrc.Y - windowrc.Height - 32; } if (windowrc.X < 0) { windowrc.X = 0; while (true) { if (pt.X < windowrc.Width && pt.Y >= windowrc.Y && pt.Y <= windowrc.Y + windowrc.Height) { windowrc.Y += 16; continue; } break; } } pt.X = windowrc.X; pt.Y = windowrc.Y; e.Graphics.FillRectangle(this.BackBrush, windowrc); e.Graphics.DrawString(terrain_name, this.Font, this.ForeBrush, pt); pt.Y = pt.Y + this.Font.Height; e.Graphics.DrawString(terrain_kaihi, this.Font, this.ForeBrush, pt); pt.Y = pt.Y + this.Font.Height; e.Graphics.DrawString(terrain_kaifuku, this.Font, this.ForeBrush, pt); pt.Y = pt.Y + this.Font.Height; e.Graphics.DrawString(terrain_tuukou, this.Font, this.ForeBrush, pt); }
void ImportObjOnePicture(Bitmap loadbitmap) { const int palette_count = MAX_MAP_PALETTE_COUNT; int bitmap_palette_count = ImageUtil.GetPalette16Count(loadbitmap); if (bitmap_palette_count > palette_count) { R.ShowStopError("パレット数が正しくありません。\r\n{1}種類以下(16色*{1}種類) でなければなりません。\r\n\r\n選択された画像のパレット種類:{0}種類", bitmap_palette_count, palette_count); return; } if (loadbitmap.Width > 512 || loadbitmap.Height > 512 || loadbitmap.Width % 8 != 0) { R.ShowStopError("画像サイズが正しくありません。\r\nWidth:{2}以下 Height:{3}以下、でなければなりません。\r\nまた、幅は8で割り切れる必要があります。\r\n\r\n選択された画像のサイズ Width:{0} Height:{1}", loadbitmap.Width, loadbitmap.Height, 512, 512); return; } //マップチップ用に512x512のキャンバスに再描画 Bitmap bitmap = ImageUtil.Blank(512, 512, loadbitmap); ImageUtil.BitBlt(bitmap, 0, 0, loadbitmap.Width, loadbitmap.Height, loadbitmap, 0, 0); byte[] image; byte[] tsa; string error = ImageUtil.ImageToBytePackedTSA(bitmap, 512, 512, 0, out image, out tsa); if (error != "") { R.ShowStopError(error); return; } if (image.Length > 0x8000) { R.ShowStopError("マップが広すぎて、0x8000バイトに収まりませんでした。\r\n入力されたサイズ: {0}\r\n\r\nもっと小さいマップにするか、圧縮率を上げるために共通のパーツを増やしてください。", U.To0xHexString(image.Length)); return; } //写像した画像を再描画 byte[] palette_bin = ImageUtil.ImageToPalette(bitmap, 16); bitmap = ImageUtil.ByteToImage16Tile(256, 256, image, 0, palette_bin, 0); byte[] map_config = ImageUtilMap.ConvertTSAToMapConfig(tsa); //画像等データの書き込み Undo.UndoData undodata = Program.Undo.NewUndoData(this); bool r = WriteMapChipImage(image, undodata); if (!r) { return; } r = WriteMapChipPalette(bitmap, true, palette_count, undodata); if (!r) { return; } r = OverraideMapConfig(map_config, undodata); if (!r) { return; } Program.Undo.Push(undodata); MapStyle_SelectedIndexChanged(null, null); return; }
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 void MakeCheckErrors(uint mapid, List <FELint.ErrorSt> errors) { uint mapaddr = GetMapAddr(mapid); if (mapaddr == U.NOT_FOUND) { return; } PLists plists = GetMapPListsWhereAddr(mapaddr); { uint obj2_plist = (plists.obj_plist >> 8) & 0xFF; //FE8にはないが FE7は、 plistを2つ設定できることがある. uint obj2_offset = 0; uint obj_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.OBJECT, plists.obj_plist & 0xFF); if (!U.isSafetyOffset(obj_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_OBJECT, mapaddr , R._("PLIST({0})が無効です", plists.obj_plist))); } else { FELint.CheckLZ77ImageErrors(obj_offset, errors, FELint.Type.MAPSETTING_PLIST_OBJECT, mapaddr, 256, 120); } if (obj2_plist > 0) {//plist2があれば obj2_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.OBJECT, obj2_plist); if (!U.isSafetyOffset(obj2_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_OBJECT, mapaddr , R._("PLIST({0})が無効です", obj2_plist))); } else { FELint.CheckLZ77ImageErrors(obj2_offset, errors, FELint.Type.MAPSETTING_PLIST_OBJECT, mapaddr, 256, 120); } } } { uint config_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CONFIG, plists.config_plist); if (!U.isSafetyOffset(config_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_CONFIG, mapaddr , R._("PLIST({0})が無効です", plists.config_plist))); } else { FELint.CheckLZ77(config_offset, errors, FELint.Type.MAPSETTING_PLIST_CONFIG, mapaddr); } } { uint map_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.MAP, plists.mappointer_plist); if (!U.isSafetyOffset(map_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAP, mapaddr , R._("PLIST({0})が無効です", plists.mappointer_plist))); } else { Size mapsize = ImageUtilMap.GetMapSize(plists.obj_plist, plists.palette_plist, plists.config_plist, plists.mappointer_plist); if (mapsize.Width <= 0 || mapsize.Height <= 0) { //LZ77に失敗してそうだからチェックする FELint.CheckLZ77(map_offset, errors, FELint.Type.MAPSETTING_PLIST_MAP, mapaddr); errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAP, mapaddr , R._("マップが破損しています。") , mapid)); } uint limitWidth = ImageUtilMap.GetLimitMapWidth(mapsize.Height); if (mapsize.Width < ImageUtilMap.MAP_MIN_WIDTH || mapsize.Height < ImageUtilMap.MAP_MIN_HEIGHT) { if (IsFreliaCasle(mapid)) { //nop //フレリア城 } else { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAP, mapaddr , R._("マップが狭すぎます。現在のサイズ:({0},{1}) 利用できる最少サイズ:({2},{3})" , mapsize.Width, mapsize.Height, ImageUtilMap.MAP_MIN_WIDTH, ImageUtilMap.MAP_MIN_HEIGHT) , mapid)); } } else if (limitWidth == 0) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAP, mapaddr , R._("マップが広すぎます。\r\n現在のサイズ({0},{1})", mapsize.Width, mapsize.Height, limitWidth) )); } else if (mapsize.Width > limitWidth) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAP, mapaddr , R._("マップが広すぎます。\r\n現在のサイズ({0},{1})\r\nこの幅だと、利用可能な高さは、幅は{2}までです。", mapsize.Width, mapsize.Height, limitWidth) )); } } } { uint pal_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.PALETTE, plists.palette_plist); if (!U.isSafetyOffset(pal_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_PALETTE, mapaddr , R._("PLIST({0})が無効です", plists.palette_plist))); } } if (plists.mapchange_plist != 0) { uint mapchange_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CHANGE, plists.mapchange_plist); if (!U.isSafetyOffset(mapchange_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_MAPCHANGE, mapaddr , R._("PLIST({0})が無効です", plists.mapchange_plist))); } } if (plists.anime1_plist != 0) { uint anime1_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.ANIMATION, plists.anime1_plist); if (!U.isSafetyOffset(anime1_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_ANIMETION1, mapaddr , R._("PLIST({0})が無効です", plists.anime1_plist))); } } if (plists.anime2_plist != 0) { uint anime2_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.ANIMATION2, plists.anime2_plist); if (!U.isSafetyOffset(anime2_offset)) { errors.Add(new FELint.ErrorSt(FELint.Type.MAPSETTING_PLIST_ANIMETION2, mapaddr , R._("PLIST({0})が無効です", plists.anime2_plist))); } } }