public static Bitmap DrawWorldMapFE6(uint image256Z, uint paletteZ) { byte[] image256UZ = LZ77.decompress(Program.ROM.Data, image256Z); byte[] paletteUZ = LZ77.decompress(Program.ROM.Data, paletteZ); if (image256UZ.Length <= 0 || paletteUZ.Length <= 0) { return(ImageUtil.BlankDummy()); } return(ImageUtil.ByteToImage256Liner(240, 160, image256UZ, 0, paletteUZ, 0)); }
private void X_N_JumpEditor_Click(object sender, EventArgs e) { if (InputFormRef.IsPleaseWaitDialog(this)) {//2重割り込み禁止 return; } uint battleanime_baseaddress = InputFormRef.SelectToAddr(N_AddressList); if (battleanime_baseaddress == U.NOT_FOUND) { return; } uint sectionData = (uint)N_P12.Value; uint frameData = (uint)N_P16.Value; uint rightToLeftOAM = (uint)N_P20.Value; uint leftToRightOAM = (uint)N_P24.Value; uint palettes = (uint)N_P28.Value; uint ID = (uint)N_AddressList.SelectedIndex + 1; string filehint = GetBattleAnimeHint(ID); if (filehint == "") {//不明な場合、 FE7にある個別バトルにも問い合わせる filehint = UnitCustomBattleAnimeForm.GetBattleAnimeHint((uint)N_AddressList.SelectedIndex + 1); } filehint = N_AddressList.Text + " " + filehint; int palette_count = ImageUtilOAM.CalcMaxPaletteCount(sectionData, frameData, rightToLeftOAM, palettes); //少し時間がかかるので、しばらくお待ちください表示. using (InputFormRef.AutoPleaseWait pleaseWait = new InputFormRef.AutoPleaseWait(this)) //テンポラリディレクトリを利用する using (U.MakeTempDirectory tempdir = new U.MakeTempDirectory()) { string filename = Path.Combine(tempdir.Dir, "anime.txt"); ImageUtilOAM.ExportBattleAnime("", false, filename , sectionData, frameData, rightToLeftOAM, palettes, palette_count); if (!File.Exists(filename)) { R.ShowStopError("アニメーションエディタを表示するために、アニメーションをエクスポートしようとしましたが、アニメをファイルにエクスポートできませんでした。\r\n\r\nファイル:{0}", filename); return; } byte[] paletteBIN = LZ77.decompress(Program.ROM.Data, U.toOffset(palettes)); ToolAnimationCreatorForm f = (ToolAnimationCreatorForm)InputFormRef.JumpFormLow <ToolAnimationCreatorForm>(); f.Init(ToolAnimationCreatorUserControl.AnimationTypeEnum.BattleAnime , ID, filehint, filename, paletteBIN); f.Show(); f.Focus(); } }
public static Bitmap GetPathImage() { uint palette = Program.ROM.p32(Program.ROM.RomInfo.worldmap_icon_palette_pointer()); uint image = Program.ROM.p32(Program.ROM.RomInfo.worldmap_road_tile_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); int width = 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); Bitmap bitmap = ImageUtil.ByteToImage16Tile(width, height, imageUZ, 0, Program.ROM.Data, (int)palette, 1); return(bitmap); }
static uint All_ToolAutoGenLeftToRightAllAnimation(InputFormRef.AutoPleaseWait pleaseWait, Undo.UndoData undodata) { uint totalSize = 0; //テーブル拡張などで同じOAMが複数個所にある場合の対処 Dictionary <uint, uint> convertHistory = new Dictionary <uint, uint>(); InputFormRef N_InputFormRef = N_Init(null); uint addr = N_InputFormRef.BaseAddress; for (uint i = 0; i < N_InputFormRef.DataCount; i++, addr += N_InputFormRef.BlockSize) { uint rightToLeftOAMAddress = Program.ROM.p32(addr + 20); uint leftToRightOAMAddress = Program.ROM.p32(addr + 24); if (rightToLeftOAMAddress == leftToRightOAMAddress) {//処理済み continue; } //実はさっき処理していますか? //D拡張などで同じデータが複数個ある場合への配慮. uint convertAddress; if (convertHistory.TryGetValue(leftToRightOAMAddress, out convertAddress)) { Program.ROM.write_p32(addr + 24, convertAddress, undodata); continue; } byte[] rightToLeftOAMBin = LZ77.decompress(Program.ROM.Data, rightToLeftOAMAddress); byte[] leftToRightOAMBin = LZ77.decompress(Program.ROM.Data, leftToRightOAMAddress); List <byte> rightToLeftOAMArray = new List <byte>(rightToLeftOAMBin); List <byte> leftToRightOAMArray = new List <byte>(leftToRightOAMBin); if (!ImageUtilOAM.IsMatchOAM(rightToLeftOAMArray, leftToRightOAMArray)) {//鏡写しではないので、自動生成できません。 continue; } pleaseWait.DoEvents(R._("{0} 削減サイズ:{1}", U.To0xHexString(i), totalSize)); //データを自動生成できるので、ポインタを共有します Program.ROM.write_p32(addr + 24, rightToLeftOAMAddress, undodata); //不要なデータを消去します uint leftToRightOAMSize = LZ77.getCompressedSize(Program.ROM.Data, leftToRightOAMAddress); Program.ROM.write_fill(leftToRightOAMAddress, leftToRightOAMSize, 0, undodata); convertHistory[leftToRightOAMAddress] = rightToLeftOAMAddress; totalSize += leftToRightOAMSize; } return(totalSize); }
//音楽系の下絵 public static Bitmap BaseMusicImage() { if (SystemMusicCache != null) { return(SystemMusicCache); } uint palette = Program.ROM.p32(Program.ROM.RomInfo.system_music_icon_palette_pointer()); uint image = Program.ROM.p32(Program.ROM.RomInfo.system_music_icon_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); SystemMusicCache = ImageUtil.ByteToImage16Tile(32 * 8, 4 * 8, imageUZ, 0, Program.ROM.Data, (int)palette); return(SystemMusicCache); }
public static Bitmap LoadMoveUnitIcon(uint pic_address, int palette_type) { uint palette; if (palette_type == 1) {//友軍 palette = Program.ROM.RomInfo.unit_icon_npc_palette_address(); } else if (palette_type == 2) {//敵軍 palette = Program.ROM.RomInfo.unit_icon_enemey_palette_address(); } else if (palette_type == 3) {//グレー palette = Program.ROM.RomInfo.unit_icon_gray_palette_address(); } else if (palette_type == 4) {//4軍 palette = Program.ROM.RomInfo.unit_icon_four_palette_address(); } else {//自軍 palette = Program.ROM.RomInfo.unit_icon_palette_address(); } uint pic_address_offset = U.toOffset(pic_address); if (!U.isSafetyOffset(palette)) { return(ImageUtil.Blank(4 * 8, 4 * 8)); } if (!U.isSafetyOffset(pic_address_offset)) { return(ImageUtil.Blank(4 * 8, 4 * 8)); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, pic_address_offset); if (imageUZ.Length <= 0) { return(ImageUtil.Blank(4 * 8, 4 * 8)); } int width = 4 * 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); return(ImageUtil.ByteToImage16Tile(width, height , imageUZ, 0 , Program.ROM.Data, (int)palette , 0 )); }
public static Bitmap DrawFont(uint image) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy(32)); } uint palette = Program.ROM.p32(Program.ROM.RomInfo.op_class_font_palette_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); return(ImageUtil.ByteToImage16Tile(4 * 8, 4 * 8 , imageUZ, 0 , Program.ROM.Data, (int)U.toOffset(palette) )); }
int GetThisImageHeight() { uint tsa = (uint)P8.Value; if (!U.isPointer(tsa)) { return(20 * 8); } byte[] tsaUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(tsa)); int height = ImageUtil.CalcHeightbyTSA(32 * 8, tsaUZ.Length); Debug.Assert(height >= 20 * 8); return(height); }
Bitmap DrawBorderBitmap(uint img) { byte[] bin = LZ77.decompress(Program.ROM.Data, U.toOffset(img)); uint pal = Program.ROM.p32(Program.ROM.RomInfo.worldmap_county_border_palette_pointer()); int height = ImageUtil.CalcHeight(32 * 8, bin.Length); if (height <= 0) { return(ImageUtil.Blank(32 * 8, 4 * 8)); } return(ImageUtil.ByteToImage16Tile(32 * 8, height , bin, 0 , Program.ROM.Data, (int)pal)); }
//下絵の取得 public static Bitmap BaseImage() { if (SystemIconCache != null) { return(SystemIconCache); } uint palette = Program.ROM.p32(Program.ROM.RomInfo.system_icon_palette_pointer()); uint image = Program.ROM.p32(Program.ROM.RomInfo.system_icon_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); Size system_icon_size = GetSystemIconImageSize(); SystemIconCache = ImageUtil.ByteToImage16Tile(system_icon_size.Width, system_icon_size.Height, imageUZ, 0, Program.ROM.Data, (int)palette); return(SystemIconCache); }
static Bitmap DrawTSAAnime2Header(uint image, uint palette) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(palette)) { return(ImageUtil.BlankDummy()); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); int height = (int)ImageUtil.CalcHeight(30 * 8, imageUZ.Length); return(ImageUtil.ByteToImage16Tile(30 * 8, height, imageUZ, 0, Program.ROM.Data, (int)U.toOffset(palette))); }
//マップの配置データの読込 public static byte[] UnLZ77MapData(uint mappointer_plist) { uint mappointer_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.MAP, mappointer_plist); if (!U.isSafetyOffset(mappointer_offset)) { return(null); } byte[] mappointerUZ = LZ77.decompress(Program.ROM.Data, mappointer_offset); //tsa if (mappointerUZ.Length <= 0) { return(null); } return(mappointerUZ); }
//チップセットの読込(マップチップの画像をどう解釈するか定義するデータ) public static byte[] UnLZ77ChipsetData(uint config_plist) { uint config_offset = MapPointerForm.PlistToOffsetAddr(MapPointerForm.PLIST_TYPE.CONFIG, config_plist); if (!U.isSafetyOffset(config_offset)) { return(null); } byte[] configUZ = LZ77.decompress(Program.ROM.Data, config_offset); if (configUZ.Length <= 0)//TSA { return(null); } return(configUZ); }
public static Bitmap DrawPic(uint addr, int width) { byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(addr)); if (imageUZ.Length <= 0) {//ない return(ImageUtil.Blank(width, 8)); } int height = ImageUtil.CalcHeight(width, imageUZ.Length); uint palette = Program.ROM.RomInfo.image_chapter_title_palette(); return(ImageUtil.ByteToImage16Tile(width, height , imageUZ, 0 , Program.ROM.Data, (int)U.toOffset(palette) , 0 )); }
public static Bitmap DrawImage(uint image, uint tsa) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(tsa)) { return(ImageUtil.BlankDummy()); } uint palette = Program.ROM.p32(Program.ROM.RomInfo.op_prologue_palette_color_pointer); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); byte[] tsaUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(tsa)); return(ImageUtil.ByteToImage16TileHeaderTSA(32 * 8, 20 * 8, imageUZ, 0, Program.ROM.Data, (int)U.toOffset(palette), tsaUZ, 0)); }
public static void CheckLZ77ImageErrors(uint lz77addr, List <ErrorSt> errors, Type cond, uint addr, int width, int min_height, uint tag = U.NOT_FOUND) { CheckAlien4(lz77addr, errors, cond, addr, tag); byte[] data = LZ77.decompress(Program.ROM.Data, lz77addr); if (data.Length <= 0) { errors.Add(new FELint.ErrorSt(cond, U.toOffset(addr) , R._("このアドレス({0})はlz77で圧縮されていません。\r\nデータが壊れています。", U.To0xHexString(lz77addr)), tag)); } int height = ImageUtil.CalcHeight(width, data.Length); if (height < min_height) { errors.Add(new FELint.ErrorSt(cond, U.toOffset(addr) , R._("このアドレス({0})にある画像は、高さが最低値{1}より小さい値({2})です。\r\nデータが壊れています。", U.To0xHexString(lz77addr), min_height, height), tag)); } }
static Bitmap DrawOneImage(uint image, uint tsa, uint palette) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(palette)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(tsa)) { return(ImageUtil.BlankDummy()); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); return(ImageUtil.ByteToImage16TileHeaderTSA(32 * 8, 20 * 8, imageUZ, 0, Program.ROM.Data, (int)U.toOffset(palette), Program.ROM.Data, (int)U.toOffset(tsa))); }
static Bitmap DrawTSAAnime2(uint image, uint palette, uint tsa) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(palette)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(tsa)) { return(ImageUtil.BlankDummy()); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); int height = (int)ImageUtil.CalcByteLengthForHeaderTSAData(Program.ROM.Data, (int)U.toOffset(tsa)); return(ImageUtil.ByteToImage16TileHeaderTSA(32 * 8, height, imageUZ, 0, Program.ROM.Data, (int)U.toOffset(palette), Program.ROM.Data, (int)U.toOffset(tsa))); }
uint RecompressOne(InputFormRef.AutoPleaseWait wait, Address a, Undo.UndoData undodata) { if (!Address.IsLZ77(a.DataType)) {//念のためlz77圧縮の確認 return(0); } if (!U.isPadding4(a.Addr)) {//4バイトパディングされていないデータはありえない return(0); } byte[] unzipData = LZ77.decompress(Program.ROM.Data, a.Addr); if (unzipData.Length <= 0) { return(0); } uint uncompressSize = LZ77.getUncompressSize(Program.ROM.Data, a.Addr); if (unzipData.Length != uncompressSize) { return(0); } byte[] lz77Data = LZ77.compress(unzipData); if (lz77Data.Length >= a.Length) {//無意味なのでやらない return(0); } uint diff = (uint)(a.Length - lz77Data.Length); if (diff <= 3) {//無意味なのでやらない return(0); } //書き込み Program.ROM.write_fill(a.Addr, a.Length, 0, undodata); Program.ROM.write_range(a.Addr, lz77Data, undodata); wait.DoEvents(R._("recompress lz77 {0}", U.To0xHexString(a.Addr))); return(diff); }
//武器の下絵 public static Bitmap BaseWeaponImage() { if (SystemWeaponCache != null) { return(SystemWeaponCache); } uint palette = Program.ROM.p32(Program.ROM.RomInfo.system_weapon_icon_palette_pointer()); uint image = Program.ROM.p32(Program.ROM.RomInfo.system_weapon_icon_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); if (Program.ROM.RomInfo.version() == 6) { SystemWeaponCache = ImageUtil.ByteToImage16Tile(32 * 8, 3 * 8, imageUZ, 0, Program.ROM.Data, (int)palette); } else { SystemWeaponCache = ImageUtil.ByteToImage16Tile(32 * 8, 2 * 8, imageUZ, 0, Program.ROM.Data, (int)palette); } return(SystemWeaponCache); }
Bitmap DrawImageLow(uint tsa, uint image, uint palette) { byte[] tsaByte = LZ77.decompress(Program.ROM.Data, tsa); byte[] imageByte = LZ77.decompress(Program.ROM.Data, image); if (tsaByte.Length <= 0 || imageByte.Length <= 0) { return(null); } int imageHeight = ImageUtil.CalcHeightbyTSA(this.ImageWidth * 8, tsaByte.Length); if (imageHeight > 8 * 16) { imageHeight = 8 * 16; } Bitmap bitmap = ImageUtil.ByteToImage16Tile(this.ImageWidth * 8, imageHeight, imageByte, 0, Program.ROM.Data, (int)palette, tsaByte, 0, 0); return(bitmap); }
Bitmap GetChipImage() { int pal = this.PaletteIndexComboBox.SelectedIndex; if (pal < 0) { pal = 0; } uint palette; if (this.PalettePointer == U.NOT_FOUND) { palette = U.toOffset(this.PaletteAddress); } else { palette = Program.ROM.p32(this.PalettePointer); } palette = palette + (uint)(pal * 0x20); int total_height = 0; uint image = Program.ROM.p32(this.ZImgPointer); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); int width = 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); Bitmap src = ImageUtil.ByteToImage16Tile(width, height, imageUZ, 0, Program.ROM.Data, (int)palette); Bitmap bitmap = ImageUtil.Blank(8, height, Program.ROM.Data, (int)palette); ImageUtil.BitBlt(bitmap, 0, total_height, 8, height, src, 0, 0); total_height += height; src.Dispose(); return(bitmap); }
static Bitmap DrawFrameImage(uint frame, out string log) { if (!U.isSafetyOffset(frame)) { log = ""; return(ImageUtil.BlankDummy()); } //struct Frames{ // byte wait; // byte 00; // ushort sound; // void* img; // void* pal; //}//sizeof()==12 uint objOffset = Program.ROM.p32(frame + 4); uint palOffset = Program.ROM.p32(frame + 8); if (!U.isSafetyOffset(objOffset)) { log = R._("BAD OBJ_OFFSET {0}", U.To0xHexString(objOffset)); return(ImageUtil.BlankDummy()); } if (!U.isSafetyOffset(palOffset)) { log = R._("BAD PAL_OFFSET {0}", U.To0xHexString(palOffset)); return(ImageUtil.BlankDummy()); } log = R._("IMG {0}, PAL {1}", U.To0xHexString(objOffset), U.To0xHexString(palOffset)); //objは圧縮されている. //palは、0x20(16色1パレット)固定. byte[] obj = LZ77.decompress(Program.ROM.Data, objOffset); Bitmap retImage = ImageUtil.ByteToImage16Tile(SCREEN_WIDTH, SCREEN_HEIGHT, obj, 0, Program.ROM.Data, (int)palOffset); return(retImage); }
//GetChipImageの逆をする void RevChipImage(byte[] bigbitmap, Undo.UndoData undodata) { uint[] image_pos = new uint[] { Program.ROM.RomInfo.battle_screen_image1_pointer() , Program.ROM.RomInfo.battle_screen_image2_pointer() , Program.ROM.RomInfo.battle_screen_image3_pointer() , Program.ROM.RomInfo.battle_screen_image4_pointer() , Program.ROM.RomInfo.battle_screen_image5_pointer() }; uint readPos = 0; for (int i = 0; i < image_pos.Length; i++) { if (readPos >= bigbitmap.Length) { Program.Undo.Rollback(undodata); throw new Exception(R.Error("途中で書き込むデータが終了してしまいました。i: {0} readPos:{1} bigbitmap:{2}", i, readPos, bigbitmap.Length)); } //数を知りたいので一度すべて解凍します. uint image = Program.ROM.p32(image_pos[i]); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); int width = 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); uint nextPos = (uint)(readPos + ((height / 8) * 32)); byte[] writeData = U.subrange(bigbitmap, readPos, nextPos); uint newAddr = ImageFormRef.WriteImageData(this, image, image_pos[i], writeData, true, undodata); if (newAddr == U.NOT_FOUND) { Program.Undo.Rollback(undodata); throw new Exception(R.Error("書き込みに失敗しました。i: {0} readPos:{1} bigbitmap:{2}", i, readPos, bigbitmap.Length)); } readPos = nextPos; } }
public static Bitmap DrawTSAAnime(uint image, uint palette, uint tsa) { if (!U.isPointer(image)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(palette)) { return(ImageUtil.BlankDummy()); } if (!U.isPointer(tsa)) { return(ImageUtil.BlankDummy()); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(image)); byte[] tsaUZ = LZ77.decompress(Program.ROM.Data, U.toOffset(tsa)); int height = ImageUtil.CalcHeightbyTSA(32 * 8, tsaUZ.Length); Debug.Assert(height >= 20 * 8); return(ImageUtil.ByteToImage16TileHeaderTSA(32 * 8, height, imageUZ, 0, Program.ROM.Data, (int)U.toOffset(palette), tsaUZ, 0)); }
public static Bitmap DrawImage(uint table, uint tsa, uint palette) { if (!ROM.isPointer(table)) { return(ImageUtil.Blank(8, 8)); } if (!ROM.isPointer(tsa)) { return(ImageUtil.Blank(8, 8)); } if (!ROM.isPointer(palette)) { return(ImageUtil.Blank(8, 8)); } table = ROM.toOffset(table); List <byte> imageUZList = new List <byte>(); for (int i = 0; i < 10; i++) { uint image = Program.ROM.u32((uint)(table + (i * 4))); if (!ROM.isPointer(image)) { return(ImageUtil.Blank(8, 8)); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, ROM.toOffset(image)); imageUZList.AddRange(imageUZ); } return(ImageUtil.ByteToImage16TileHeaderTSA(32 * 8, 20 * 8 , imageUZList.ToArray(), 0 , Program.ROM.Data, (int)ROM.toOffset(palette) , Program.ROM.Data, (int)ROM.toOffset(tsa) , 0x8000 //TSAに謎の係数を足しながら、最下層のラインから格納するらしい , -0x80 //パレット番号が0x80シフトされるらしい )); }
private void P8_ValueChanged(object sender, EventArgs e) { uint addr = U.toOffset((uint)P8.Value); if (!U.isSafetyOffset(addr)) { X_NAME_IMG.Image = null; return; } byte[] img = LZ77.decompress(Program.ROM.Data, addr); if (img.Length <= 0) { X_NAME_IMG.Image = null; return; } uint paletteAddr = Program.ROM.p32(JP_FONT_PALETTE_POINTER); if (!U.isSafetyOffset(paletteAddr)) { X_NAME_IMG.Image = null; return; } X_NAME_IMG.Image = ImageUtil.ByteToImage16Tile(32 * 8, 4 * 8, img, 0, Program.ROM.Data, (int)paletteAddr); }
static Bitmap DrawFrameImage(uint frame, uint graphiclist, uint tsalist, uint palettelist) { if (!U.isSafetyOffset(frame)) { return(ImageUtil.BlankDummy()); } //struct Frames{ // ushort id; // ushort wait; //} uint id = Program.ROM.u16(frame + 0); //画像リストなどから、指定ID数、読み飛ばす. uint objPointer = graphiclist + (id * 4); uint tsaPointer = tsalist + (id * 4); uint palPointer = palettelist + (id * 4); if (!U.isSafetyOffset(objPointer + 4)) { return(ImageUtil.BlankDummy()); } if (!U.isSafetyOffset(tsaPointer + 4)) { return(ImageUtil.BlankDummy()); } if (!U.isSafetyOffset(palPointer + 4)) { return(ImageUtil.BlankDummy()); } uint objOffset = Program.ROM.p32(objPointer); uint tsaOffset = Program.ROM.p32(tsaPointer); uint palOffset = Program.ROM.p32(palPointer); if (!U.isSafetyOffset(objOffset)) { return(ImageUtil.BlankDummy()); } if (!U.isSafetyOffset(tsaOffset)) { return(ImageUtil.BlankDummy()); } if (!U.isSafetyOffset(palOffset + 0x20)) { return(ImageUtil.BlankDummy()); } //objとtsaは圧縮されている. //palは、0x20(16色1パレット)固定. byte[] obj = LZ77.decompress(Program.ROM.Data, objOffset); byte[] tsa = LZ77.decompress(Program.ROM.Data, tsaOffset); int width = SCREEN_WIDTH; int height = ImageUtil.CalcHeightbyTSA(width, tsa.Length); if (height < 160) { height = 160; } Bitmap retImage = ImageUtil.ByteToImage16Tile(width, height, obj, 0, Program.ROM.Data, (int)palOffset, tsa, 0); return(retImage); }
static string ExportBGFrameImage( uint frame , byte[] frameData , string basedir , string basename , List <uint> animeHash ) { basename = basename + "b_"; //0 frame16 byte1 x86 //4 objImagePointer //8 OAMAbsoStart //12 OAMBGAbsoStart //16 bgImagePointer //20 objPalettePointer //24 bgPalettePointer //CSA_Creater 28 TSA uint bgPointer = U.u32(frameData, frame + 16); uint bgPalettePointer = U.u32(frameData, frame + 24); uint bgTSAPointer = U.u32(frameData, frame + 28); uint imageHash = (bgPointer + bgTSAPointer); string framefilename = ""; int seatnumber = animeHash.IndexOf(imageHash); if (seatnumber >= 0) {//すでに出力しているのでカットする. framefilename = basename + seatnumber.ToString("000") + ".png"; return(framefilename); } byte[] bgPalette = Program.ROM.getBinaryData(U.toOffset(bgPalettePointer), 0x20); byte[] bg_UZ = LZ77.decompress(Program.ROM.Data, U.toOffset(bgPointer)); byte[] bgTSA_UZ = LZ77.decompress(Program.ROM.Data, U.toOffset(bgTSAPointer)); if (bg_UZ.Length <= 0 || bgTSA_UZ.Length <= 0) { Log.Error("bg_UZ", U.ToHexString(bgPointer), "or bgTSA_UZ", U.ToHexString(bgTSAPointer), "is null. broken frame."); return(""); } //まだ出力していない画像なので作成します. seatnumber = animeHash.Count; animeHash.Add(imageHash); //int width = 264; //FEditorAdv //int height = 64; int width = 256 - 8 - 8; int height = ImageUtil.CalcHeightbyTSA(width, bgTSA_UZ.Length); if (height >= 160) { height = 160; } else { height = 64; } Bitmap retImage = ImageUtil.Blank(width, height, bgPalette, 0); Bitmap bg = ImageUtil.ByteToImage16Tile(width, height, bg_UZ, 0, bgPalette, 0, bgTSA_UZ, 0, 0); ImageUtil.BitBlt(retImage, 0, 0, bg.Width, bg.Height, bg, 0, 0); ////パレットマークを右上に描画 CSA_Creator では不要らしい. ////ImageUtil.AppendPaletteMark(retImage); //利用していないパレットを消す. ImageUtil.BlackOutUnnecessaryColors(retImage, 1); framefilename = basename + seatnumber.ToString("000") + ".png"; if (!U.BitmapSave(retImage, Path.Combine(basedir, framefilename))) { return(""); } retImage.Dispose(); return(framefilename); }
static Bitmap DrawFrameImage(uint frame , byte[] frameData , uint objRightToLeftOAM , uint objBGRightToLeftOAM , bool bgExpands) { //0 frame16 byte1 x86 //4 objImagePointer //8 OAMAbsoStart //12 OAMBGAbsoStart //16 bgImagePointer //20 objPalettePointer //24 bgPalettePointer //CSA_Creater 28 TSA uint objPalettePointer = U.u32(frameData, frame + 20); if (!U.isSafetyPointer(objPalettePointer)) { return(ImageUtil.BlankDummy()); } byte[] objPalette = Program.ROM.getBinaryData(U.toOffset(objPalettePointer), 0x20); uint bgPalettePointer = U.u32(frameData, frame + 24); if (!U.isSafetyPointer(bgPalettePointer)) { return(ImageUtil.BlankDummy()); } byte[] bgPalette = Program.ROM.getBinaryData(U.toOffset(bgPalettePointer), 0x20); Bitmap retImage = ImageUtil.Blank((ImageUtilOAM.SEAT_TILE_WIDTH - 2) * 8, ImageUtilOAM.SEAT_TILE_HEIGHT * 8 * 2, objPalette, 0); uint bgPointer = U.u32(frameData, frame + 16); if (!U.isSafetyPointer(bgPointer)) { return(ImageUtil.BlankDummy()); } byte[] bg_UZ = LZ77.decompress(Program.ROM.Data, U.toOffset(bgPointer)); uint bgTSAPointer = U.u32(frameData, frame + 28); if (!U.isSafetyPointer(bgTSAPointer)) { return(ImageUtil.BlankDummy()); } byte[] bgTSA_UZ = LZ77.decompress(Program.ROM.Data, U.toOffset(bgTSAPointer)); int width = 256 - 8 - 8; int height = ImageUtil.CalcHeightbyTSA(width, bgTSA_UZ.Length); if (height < 160) { height = 160; } Bitmap bg = ImageUtil.ByteToImage16Tile(width, height, bg_UZ, 0, bgPalette, 0, bgTSA_UZ, 0); ImageUtil.AppendPalette(retImage, bg, 1); if (bgExpands) { Bitmap tempbg = ImageUtil.Blank(width, height, bg); ImageUtil.Scale(tempbg, 0, 0, width, 160 - 32, bg, 0, 0, width, 64); bg = tempbg; } ImageUtil.BitBlt(retImage, 0, 0, bg.Width, bg.Height, bg, 0, 0, 1); uint objImagePointer = U.u32(frameData, frame + 4); if (!U.isSafetyPointer(objImagePointer)) { return(ImageUtil.BlankDummy()); } byte[] obj_UZ = LZ77.decompress(Program.ROM.Data, U.toOffset(objImagePointer)); if (obj_UZ.Length > 0) { width = 256; height = ImageUtil.CalcHeight(width, obj_UZ.Length); if (height < 64) { height = 64; } Bitmap obj = ImageUtil.ByteToImage16Tile(width, height, obj_UZ, 0, objPalette, 0); { //利用するOAMデータの開始位置 //OAMは 12byte で 最初の1バイト目が 1になるまで続きます. uint OAMBGAbsoStart = U.u32(frameData, frame + 12); ImageUtilOAM.DrawOAM oam = new ImageUtilOAM.DrawOAM(); oam.SetIsMagicOAM(true); oam.Parse(Program.ROM.Data, objBGRightToLeftOAM + OAMBGAbsoStart); Bitmap tempCanvas = ImageUtil.Blank((ImageUtilOAM.SEAT_TILE_WIDTH - 2) * 8, ImageUtilOAM.SEAT_TILE_HEIGHT * 8 * 2, objPalette, 0); tempCanvas = oam.Draw(tempCanvas, obj); ImageUtil.BitBlt(retImage, 0, 0, tempCanvas.Width, tempCanvas.Height, tempCanvas, 0, 0, 0, 0); tempCanvas.Dispose(); } { //利用するOAMデータの開始位置 //OAMは 12byte で 最初の1バイト目が 1になるまで続きます. uint OAMAbsoStart = U.u32(frameData, frame + 8); ImageUtilOAM.DrawOAM oam = new ImageUtilOAM.DrawOAM(); oam.SetIsMagicOAM(true); oam.Parse(Program.ROM.Data, objRightToLeftOAM + OAMAbsoStart); Bitmap tempCanvas = ImageUtil.Blank((ImageUtilOAM.SEAT_TILE_WIDTH - 2) * 8, ImageUtilOAM.SEAT_TILE_HEIGHT * 8 * 2, objPalette, 0); tempCanvas = oam.Draw(tempCanvas, obj); ImageUtil.BitBlt(retImage, 0, 0, tempCanvas.Width, tempCanvas.Height, tempCanvas, 0, 0, 0, 0); tempCanvas.Dispose(); } } return(retImage); }