Bitmap DrawItemIcons() { Bitmap bitmap = null; for (int i = 0; i < ICON_COUNT; i++) { Bitmap a = ImageItemIconForm.DrawIconWhereID((uint)(i + 1) * 10); if (bitmap == null) { bitmap = ImageUtil.Blank(16 * ICON_COUNT, 16, a); } if (ImageUtil.IsBlankBitmap(a)) { a = ImageItemIconForm.DrawIconWhereID((uint)(i + 1) * 10 + 1); } ImageUtil.BitBlt(bitmap, i * 16, 0, 16, 16, a, 0, 0); } return(bitmap); }
public static Bitmap DrawFontString(string str, bool IsItemFont) { //フォントで描画した場合の幅と高さを求める. Size size = MeasureTextMultiLine(str, IsItemFont); if (size.Width <= 0 || size.Height <= 0) { return(ImageUtil.BlankDummy()); } uint fontlist_pointer = GetFontPointer(IsItemFont); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); Bitmap bitmap = ImageUtil.Blank(size.Width, size.Height); string[] lines = str.Split(new string[] { "\r\n" }, StringSplitOptions.None); for (int n = 0; n < lines.Length; n++) { string line = lines[n]; int totalwidth = 0; for (int i = 0; i < line.Length; i++) { string one = str[i].ToString(); uint search_char = U.ConvertMojiCharToUnitFast(one, priorityCode); int width; Bitmap oneBitmap = DrawFont(search_char, IsItemFont, out width, priorityCode); if (oneBitmap == null) { continue; } if (n == 0) {//最初ならパレット設定. bitmap.Palette = oneBitmap.Palette; } ImageUtil.BitBlt(bitmap, totalwidth, n * 16, width, 16, oneBitmap, 0, 0, 0, 0); totalwidth += width; } } return(bitmap); }
void MakePATHCHIPLIST() { Bitmap pathChipList = ImageUtil.Blank(PathCacheImage.Width * 5, PathCacheImage.Height, PathCacheImage); ImageUtil.BitBlt(pathChipList, 0, 0, PathCacheImage.Width, PathCacheImage.Height, PathCacheImage, 0, 0); for (int y = 0; y < PathCacheImage.Height; y++) { Bitmap flip = ImageUtil.Copy(PathCacheImage, 0, y * 8, 8, 8, true); ImageUtil.BitBlt(pathChipList, 8 * 1, y * 8, 8, 8, flip, 0, 0); flip = ImageUtil.Copy(PathCacheImage, 0, y * 8, 8, 8, false, true); ImageUtil.BitBlt(pathChipList, 8 * 2, y * 8, 8, 8, flip, 0, 0); flip = ImageUtil.Copy(PathCacheImage, 0, y * 8, 8, 8, true, true); ImageUtil.BitBlt(pathChipList, 8 * 3, y * 8, 8, 8, flip, 0, 0); } PATHCHIPLIST.Image = pathChipList; }
Bitmap DrawUnits(int palette_type) { Bitmap bitmap = null; for (int i = 0; i < ICON_COUNT; i++) { Bitmap a = ImageUnitWaitIconFrom.DrawWaitUnitIconBitmap((uint)(i + 1), palette_type, true); if (bitmap == null) { bitmap = ImageUtil.Blank(16 * ICON_COUNT, 16, a); } if (ImageUtil.IsBlankBitmap(a)) { a = ImageUnitWaitIconFrom.DrawWaitUnitIconBitmap((uint)(i + 1) * 2, palette_type, true); } ImageUtil.BitBlt(bitmap, i * 16, 0, 16, 16, a, 0, 0); } return(bitmap); }
void MakeCHIPLIST() { Bitmap pathChiplist = ImageUtil.Blank(this.ChipCache.Width * 4 * 2, this.ChipCache.Height, this.ChipCache); for (int y = 0; y < this.ChipCache.Height; y++) { Bitmap flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, false, false); ImageUtil.BitBlt(pathChiplist, 0, y * 8, 8, 8, flip, 0, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true, false); ImageUtil.BitBlt(pathChiplist, 8 * 1, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, false, true); ImageUtil.BitBlt(pathChiplist, 8 * 2, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true, true); ImageUtil.BitBlt(pathChiplist, 8 * 3, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, false, false); ImageUtil.BitBlt(pathChiplist, 8 * 4, y * 8, 8, 8, flip, 0, 0, 1); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true, false); ImageUtil.BitBlt(pathChiplist, 8 * 5, y * 8, 8, 8, flip, 0, 0, 1); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, false, true); ImageUtil.BitBlt(pathChiplist, 8 * 6, y * 8, 8, 8, flip, 0, 0, 1); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true, true); ImageUtil.BitBlt(pathChiplist, 8 * 7, y * 8, 8, 8, flip, 0, 0, 1); flip.Dispose(); } CHIPLIST.Image = pathChiplist; }
public static Bitmap DrawMoveUnitIconBitmap(uint icon_id, int palette_type, int step) { if (icon_id == 0) { return ImageUtil.BlankDummy(); } else { icon_id = icon_id - 1; } InputFormRef InputFormRef = Init(null); uint addr = InputFormRef.IDToAddr(icon_id); if (!U.isSafetyOffset(addr)) { return ImageUtil.Blank(2 * 8, 2 * 8); } uint pic_address = (uint)Program.ROM.u32(addr + 0); return DrawMoveUnitIcon(pic_address, palette_type,step); }
Bitmap DrawUnits2(int palette_type, uint icon_id) { Bitmap first = ImageUnitWaitIconFrom.DrawWaitUnitIconBitmap((uint)(icon_id), palette_type, true); Bitmap bitmap = ImageUtil.Blank(16 * ICON_COUNT, 16, first); ImageUtil.BitBlt(bitmap, 0, 0, 16, 16, first, 0, 0); for (int i = 1; i < ICON_COUNT; i++) { Bitmap a = ImageUnitWaitIconFrom.DrawWaitUnitIconBitmap((uint)(i), palette_type, true); if (bitmap == null) { bitmap = ImageUtil.Blank(16 * ICON_COUNT, 16, a); } if (ImageUtil.IsBlankBitmap(a)) { a = ImageUnitWaitIconFrom.DrawWaitUnitIconBitmap((uint)(i) * 2, palette_type, true); } ImageUtil.BitBlt(bitmap, i * 16, 0, 16, 16, a, 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); }
//FE7のワールドマップを描画する //詳細は、呼び出し元のメソッドを見てね. public static Bitmap DrawWorldMapFE7(uint imagemap, uint palette, uint tsamap) { Bitmap map = ImageUtil.Blank(1024, 688); map.Palette = ImageUtil.ByteToPalette(map.Palette, Program.ROM.Data, (int)palette); for (int y = 0; y < 2; y++) { for (int x = 0; x < 4; x++) { uint image = Program.ROM.p32(imagemap); uint tsa = Program.ROM.p32(tsamap); Bitmap piece = ImageUtil.ByteToImage16TileHeaderTSA(256, 256, Program.ROM.Data, (int)image, Program.ROM.Data, (int)palette, Program.ROM.Data, (int)tsa); ImageUtil.BitBlt(map, x * 256, y * 256, 256, 256, piece, 0, 0); imagemap += 4; tsamap += 4; } } //最後のラインだけheightが違う. { int y = 2; for (int x = 0; x < 4; x++) { uint image = Program.ROM.p32(imagemap); uint tsa = Program.ROM.p32(tsamap); Bitmap piece = ImageUtil.ByteToImage16TileHeaderTSA(256, 256, Program.ROM.Data, (int)image, Program.ROM.Data, (int)palette, Program.ROM.Data, (int)tsa); ImageUtil.BitBlt(map, x * 256, y * 256, 256, 176, piece, 0, 0); imagemap += 4; tsamap += 4; } } return(map); }
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シフトされるらしい )); }
void MakeCHIPLIST() { this.ChipDisplayCache = ImageUtil.Blank(this.ChipCache.Width * 4, this.ChipCache.Height, this.ChipCache); for (int y = 0; y < this.ChipCache.Height; y++) { Bitmap flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8); ImageUtil.BitBlt(this.ChipDisplayCache, 0, y * 8, 8, 8, flip, 0, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true); ImageUtil.BitBlt(this.ChipDisplayCache, 8 * 1, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, false, true); ImageUtil.BitBlt(this.ChipDisplayCache, 8 * 2, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); flip = ImageUtil.Copy(this.ChipCache, 0, y * 8, 8, 8, true, true); ImageUtil.BitBlt(this.ChipDisplayCache, 8 * 3, y * 8, 8, 8, flip, 0, 0); flip.Dispose(); } CHIPLIST.Image = this.ChipDisplayCache; }
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); }
//顔画像シートを作成する. public static Bitmap DrawPortraitSeetFE6(uint id) { InputFormRef InputFormRef = Init(null); //現在のIDに対応するデータ uint addr = InputFormRef.IDToAddr(id); if (!U.isSafetyOffset(addr)) { return(ImageUtil.BlankDummy()); } uint unit_face = Program.ROM.u32(addr); uint map_face = Program.ROM.u32(addr + 4); uint palette = Program.ROM.u32(addr + 8); if (unit_face == 0) { return(ImagePortraitForm.DrawPortraitClass(unit_face, palette)); } unit_face = U.toOffset(unit_face); palette = U.toOffset(palette); if (unit_face == 0 || !U.isSafetyOffset(unit_face) || !U.isSafetyOffset(palette) ) { //ない. return(ImageUtil.Blank(seet_width, seet_height)); } //FE6の顔画像は圧縮されている. byte[] imageUZ = LZ77.decompress(Program.ROM.Data, unit_face); if (imageUZ.Length <= 0) {//ない return(ImageUtil.Blank(seet_width, seet_height)); } Bitmap allface = ImageUtil.ByteToImage16Tile(32 * 8, 5 * 8 , imageUZ, (int)0 , Program.ROM.Data, (int)palette ); //シートを作る Bitmap seet = ImageUtil.Blank(seet_width, seet_height, allface); //メインの顔を転写 ImageUtil.BitBlt(seet, parts_width / 2, 0 , parts_width * 2, parts_height * 2 , allface, 0, 0);//顔上 ImageUtil.BitBlt(seet, parts_width / 2, parts_height * 2 , parts_width * 2, parts_height * 2 , allface, parts_width * 2, 0);//顔下 ImageUtil.BitBlt(seet, parts_width / 2, parts_height * 4 , parts_width, parts_height , allface, parts_width * 4, 0);//右肩 ImageUtil.BitBlt(seet, 0, parts_height * 3 , parts_width / 2, parts_height * 2 , allface, parts_width * 5, 0);//右端 ImageUtil.BitBlt(seet, parts_width + parts_width / 2, parts_height * 4 , parts_width, parts_height , allface, parts_width * 4, parts_height);//左肩 ImageUtil.BitBlt(seet, parts_width * 2 + parts_width / 2, parts_height * 3 , parts_width / 2, parts_height * 2 , allface, parts_width * 5 + parts_width / 2, 0);//左端 //マップ顔を描画 map_face = U.toOffset(map_face); Bitmap mapface_bitmap = ImageUtil.ByteToImage16Tile(mapface_width, mapface_height , Program.ROM.Data, (int)map_face , Program.ROM.Data, (int)palette , 0 ); //シートにマップ顔を転写 ImageUtil.BitBlt(seet, face_width, parts_height, mapface_width, mapface_height, mapface_bitmap, 0, 0); //口 いい具合に2*2と固まっているのでまとめてもっていく ImageUtil.BitBlt(seet, parts_width * 0, face_height, parts_width * 2, parts_height * 2, allface, (32 * 8) - (parts_width * 2), parts_height * 0); //右端の口 ImageUtil.BitBlt(seet, parts_width * 3, face_height, parts_width, parts_height / 2, allface, 0, 4 * 8); //余白 ImageUtil.BitBlt(seet, parts_width * 3, face_height + (parts_height / 2), parts_width, parts_height / 2, allface, 4 * 8, 4 * 8); return(seet); }
void ConvertBitmaps(string saveFilename) { Bitmap src = ImageUtil.OpenLowBitmap(OrignalFilename.Text); if (src == null) { return; } if (!U.CanWriteFileRetry(saveFilename)) { return; } List <string> liner = new List <string>(); string dir = Path.GetDirectoryName(saveFilename); int partsW = (int)this.PartsX.Value; int partsH = (int)this.PartsY.Value; int frameWait = (int)this.FrameWait.Value; int selected = ConvertType.SelectedIndex; int fileCount = 0; string dummyObjectFilename = "animeobj.png"; //ヘッダ int sound = (int)this.SoundFire.Value; if (IsSkillAnime(selected)) { if (selected == 1) { liner.Add("D"); } string line = "S" + U.ToHexString(sound); liner.Add(line); } else if (IsMagicAnimeByFEidtor(selected)) { liner.Add("C00"); liner.Add("C00"); liner.Add("C00"); liner.Add("C00"); liner.Add("C40 //Scrolls the screen"); liner.Add("S" + U.ToHexString(sound)); Bitmap obj = ImageUtil.Blank(264, 64); obj.Save(Path.Combine(dir, dummyObjectFilename)); } else if (IsMagicAnimeByCSACreator(selected)) { liner.Add("C000000"); liner.Add("C40 //Scrolls the screen"); liner.Add("S" + U.ToHexString(sound)); Bitmap obj = ImageUtil.Blank(480, 160); obj.Save(Path.Combine(dir, dummyObjectFilename)); } for (int srcy = 0; srcy + partsH < src.Height; srcy += partsH) { for (int srcx = 0; srcx + partsW < src.Width; srcx += partsW) { Bitmap bitmap = ConvertBitmap(src, srcx, srcy); string imgFilename; imgFilename = "anime" + fileCount.ToString("000") + ".png"; bitmap.Save(Path.Combine(dir, imgFilename)); fileCount++; if (IsSkillAnime(selected)) { string line = frameWait + " " + imgFilename; liner.Add(line); } else if (IsMagicAnimeByFEidtor(selected)) { string line; line = "O" + " p- " + dummyObjectFilename; liner.Add(line); line = "B" + " p- " + imgFilename; liner.Add(line); line = frameWait.ToString(); liner.Add(line); } else if (IsMagicAnimeByCSACreator(selected)) { string line; line = "O" + " " + dummyObjectFilename; liner.Add(line); line = "B" + " " + imgFilename; liner.Add(line); line = frameWait.ToString(); liner.Add(line); } } } if (IsMagicAnimeByFEidtor(selected) || IsMagicAnimeByCSACreator(selected)) { liner.Add("C1A"); liner.Add("C1F"); liner.Add("~ // miss terminator"); liner.Add("S0133 // Hit sfx"); liner.Add("~"); } File.WriteAllLines(saveFilename, liner.ToArray()); }
void DrawSample(uint battleAnimeID //戦闘アニメID , uint paletteno //利用するユニットパレット (カスタムカラー) , int paletteIndex //敵味方色 ) { Bitmap[] animeframe = new Bitmap[12]; uint showsecstion = 0; uint showframe = 0; for (int index = 0; index < animeframe.Length; index++, showframe += 2) { animeframe[index] = ImageBattleAnimeForm.DrawBattleAnime(battleAnimeID , ImageBattleAnimeForm.ScaleTrim.SCALE_90 , paletteno, showsecstion, showframe, paletteIndex); if (!ImageUtil.IsBlankBitmap(animeframe[index], 10)) { continue; } //何も描画されなければフレームをもうちょっと進めてみる. showframe += 2; animeframe[index] = ImageBattleAnimeForm.DrawBattleAnime(battleAnimeID , ImageBattleAnimeForm.ScaleTrim.SCALE_90 , paletteno, showsecstion, showframe, paletteIndex); if (!ImageUtil.IsBlankBitmap(animeframe[index], 10)) { continue; } //それでもだめならセクションを切り替える. showsecstion += 1; showframe = 0; animeframe[index] = ImageBattleAnimeForm.DrawBattleAnime(battleAnimeID , ImageBattleAnimeForm.ScaleTrim.SCALE_90 , paletteno, showsecstion, showframe, paletteIndex); if (!ImageUtil.IsBlankBitmap(animeframe[index], 10)) { continue; } //さらにダメならもう一つセクションを進める. それでもだめならあきらめる. showsecstion += 1; showframe = 0; animeframe[index] = ImageBattleAnimeForm.DrawBattleAnime(battleAnimeID , ImageBattleAnimeForm.ScaleTrim.SCALE_90 , paletteno, showsecstion, showframe, paletteIndex); } this.DrawBitmap = ImageUtil.Blank(360, 290, animeframe[0]); int x = 0; int y = 0; for (int index = 0; index < animeframe.Length; index++) { ImageUtil.BitBlt(this.DrawBitmap, x, y, animeframe[index].Width, animeframe[index].Height, animeframe[index], 0, 0); x += animeframe[index].Width; if (x >= this.DrawBitmap.Width) { x = 0; y += animeframe[index].Height; } } ReDrawBitmap(); }
public static Bitmap DrawWorldMapIcon(uint icon) { uint palette = Program.ROM.p32(Program.ROM.RomInfo.worldmap_icon_palette_pointer()); if (icon == 7 || icon == 8 || icon == 0xC) { uint image = Program.ROM.p32(Program.ROM.RomInfo.worldmap_icon2_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); int width = 8 * 12; int height = ImageUtil.CalcHeight(width, imageUZ.Length); Bitmap bitmap = ImageUtil.ByteToImage16Tile(width, height, imageUZ, 0, Program.ROM.Data, (int)palette); if (icon == 7) { return(ImageUtil.Copy(bitmap, 0, 0, 32, 32)); } if (icon == 8) { return(ImageUtil.Copy(bitmap, 32, 0, 32, 32)); } //0xC return(ImageUtil.Copy(bitmap, 64, 0, 32, 32)); } else if (icon <= 0x10) { uint image = Program.ROM.p32(Program.ROM.RomInfo.worldmap_icon1_pointer()); byte[] imageUZ = LZ77.decompress(Program.ROM.Data, image); int width = 8 * 32; int height = ImageUtil.CalcHeight(width, imageUZ.Length); Bitmap bitmap = ImageUtil.ByteToImage16Tile(width, height, imageUZ, 0, Program.ROM.Data, (int)palette); if (icon == 0) { return(ImageUtil.Copy(bitmap, 0, 0, 32, 32)); } if (icon == 1) { return(ImageUtil.Copy(bitmap, 32, 0, 32, 32)); } if (icon == 2 || icon == 3 || icon == 4) { return(ImageUtil.Copy(bitmap, 64, 0, 32, 32)); } if (icon == 5) { return(ImageUtil.Copy(bitmap, 144, 0, 16, 16)); } if (icon == 6) { return(ImageUtil.Copy(bitmap, 208, 0, 32, 32)); } if (icon == 9) { return(ImageUtil.Copy(bitmap, 192, 0, 16, 16)); } if (icon == 0xA) { return(ImageUtil.Copy(bitmap, 144, 16, 16, 16)); } if (icon == 0xB) { return(ImageUtil.Copy(bitmap, 160, 0, 16, 16)); } if (icon == 0xD) { return(ImageUtil.Copy(bitmap, 128, 0, 16, 32)); } if (icon == 0xE) { return(ImageUtil.Copy(bitmap, 96, 0, 32, 32)); } if (icon == 0xF) { return(ImageUtil.Copy(bitmap, 160, 16, 8, 8)); } if (icon == 0x10) { return(ImageUtil.Copy(bitmap, 144, 0, 16, 16)); } } return(ImageUtil.Blank(1, 1)); }
void GenPreviewMainChar() { Bitmap face = ImageUtil.Blank(96, 80, this.PreviewBitmap16); int eyex = (int)this.EyeBlockX.Value * 8; int eyey = (int)this.EyeBlockY.Value * 8; int mouthx = (int)this.MouthBlockX.Value * 8; int mouthy = (int)this.MouthBlockY.Value * 8; ImageUtil.BitBlt(face, 0, 0, 96, 80, this.PreviewBitmap16, 0, 0); int f = (int)X_Frame.Value; if (f == 10) { ImageUtil.BitBlt(face, eyex, eyey, 32, 16, this.PreviewBitmap16, 96, 48, 0, 0); ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 0, 80, 0, 0); X_STATUS.Text = R._("位置確認用"); } else if (f == 1) {//半目 ImageUtil.BitBlt(face, eyex, eyey, 32, 16, this.PreviewBitmap16, 96, 48, 0, 0); X_STATUS.Text = R._("半目"); } else if (f == 2) {//閉じ目 ImageUtil.BitBlt(face, eyex, eyey, 32, 16, this.PreviewBitmap16, 96, 48 + 16, 0, 0); X_STATUS.Text = R._("とじ目"); } else if (f == 3) {//口1 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 0, 80, 0, 0); X_STATUS.Text = R._("口1"); } else if (f == 4) {//口2 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 32, 80, 0, 0); X_STATUS.Text = R._("口2"); } else if (f == 5) {//口3 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 32 + 32, 80, 0, 0); X_STATUS.Text = R._("口3"); } else if (f == 6) {//口4 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 32 + 32 + 32, 80, 0, 0); X_STATUS.Text = R._("ステータス画面 口4"); } else if (f == 7) {//口5 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 0, 80 + 16, 0, 0); X_STATUS.Text = R._("口5"); } else if (f == 8) {//口6 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 32, 80 + 16, 0, 0); X_STATUS.Text = R._("口6"); } else if (f == 9) {//口7 ImageUtil.BitBlt(face, mouthx, mouthy, 32, 16, this.PreviewBitmap16, 32 + 32, 80 + 16, 0, 0); X_STATUS.Text = R._("口7"); } else { X_STATUS.Text = R._("通常時"); } this.X_PreviewMainChar.Image = face; }
public static Bitmap DrawBattleAnime(uint id, ScaleTrim trim = ScaleTrim.SCALE_90, uint custompalette = 0, uint showSectionData = 0, uint showFrameData = 0, int showPaletteIndex = 0) { if (id <= 0) { return(ImageUtil.BlankDummy()); } id = id - 1; //anime IDは 1 からスタート. InputFormRef InputFormRef = N_Init(null); uint addr = InputFormRef.IDToAddr(id); if (!U.isSafetyOffset(addr)) { return(ImageUtil.BlankDummy()); } uint sectionData = Program.ROM.u32(addr + 12); uint frameData = Program.ROM.u32(addr + 16); uint rightToLeftOAM = Program.ROM.u32(addr + 20); uint palettes = Program.ROM.u32(addr + 28); if (custompalette > 0) { uint p = ImageUnitPaletteForm.GetPaletteAddr(custompalette); if (U.isSafetyOffset(addr)) { palettes = p; } } Bitmap bitmap = ImageUtilOAM.DrawBattleAnime(showSectionData, showFrameData , sectionData, frameData, rightToLeftOAM, palettes); if (showPaletteIndex > 0) { bitmap = ImageUtil.SwapPalette(bitmap, showPaletteIndex); } if (trim == ScaleTrim.SCALE_48) { Bitmap trimBitmap = ImageUtil.Blank(48, 48, bitmap); ImageUtil.BitBlt(trimBitmap, 0, 0, trimBitmap.Width, trimBitmap.Height, bitmap , 125, 58); bitmap.Dispose(); return(trimBitmap); } else if (trim == ScaleTrim.SCALE_90) { Bitmap trimBitmap = ImageUtil.Blank(90, 90, bitmap); ImageUtil.BitBlt(trimBitmap, 0, 0, trimBitmap.Width, trimBitmap.Height, bitmap , 100, 30); bitmap.Dispose(); return(trimBitmap); } else if (trim == ScaleTrim.NO_BUT_FLIP) { Bitmap flipBitmap = ImageUtil.Copy(bitmap, 0, 0, bitmap.Width - 8, bitmap.Height, true); bitmap.Dispose(); return(flipBitmap); } else { return(bitmap); } }
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 Bitmap LoadWaitUnitIcon(uint pic_address, int palette_type, byte b2) { 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 == 4) {//4軍 palette = Program.ROM.RomInfo.unit_icon_four_palette_address(); } else if (palette_type == 3) {//グレー palette = Program.ROM.RomInfo.unit_icon_gray_palette_address(); } else if (palette_type == 5) {//光の結界 palette = Program.ROM.RomInfo.unit_icon_lightrune_palette_address(); } else if (palette_type == 6) {//セピア palette = Program.ROM.RomInfo.unit_icon_sepia_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(2 * 8, 2 * 8)); } if (!U.isSafetyOffset(pic_address_offset)) { return(ImageUtil.Blank(2 * 8, 2 * 8)); } byte[] imageUZ = LZ77.decompress(Program.ROM.Data, pic_address_offset); if (imageUZ.Length <= 0) { return(ImageUtil.Blank(2 * 8, 2 * 8)); } if (b2 == 2) {//32xN int width = 2 * 2 * 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); return(ImageUtil.ByteToImage16Tile(width, height , imageUZ, 0 , Program.ROM.Data, (int)palette , 0 )); } else {//16xN int width = 2 * 8; int height = ImageUtil.CalcHeight(width, imageUZ.Length); return(ImageUtil.ByteToImage16Tile(width, height , imageUZ, 0 , Program.ROM.Data, (int)palette , 0 )); } }
public Bitmap Convert(Bitmap src, int maxPalette, int yohaku, bool isReserve1StPalette, bool ignoreTSA) { if (maxPalette == 1 || ignoreTSA) {//1パレット16色 または、 TSA無効の場合 return(ConvertIgnoreTSA(src, maxPalette * 16, yohaku, isReserve1StPalette, maxPalette < 16)); } int width = src.Width; int height = src.Height; width = U.Padding8(width); height = U.Padding8(height); Bitmap DestBitmap = ImageUtil.Blank(width + yohaku, height); List <ColorRanking> totalRank = new List <ColorRanking>(); List <TileMapping> tileMapping = new List <TileMapping>(); for (int y = 0; y < height; y += 8) { if (y + 8 > height) { continue; } for (int x = 0; x < width; x += 8) { if (x + 8 > width) { continue; } TileMapping tm = new TileMapping(); tm.Rank = new List <ColorRanking>(); tm.Palette = -1; tm.X = x; tm.Y = y; for (int yy = 0; yy < 8; yy++) { for (int xx = 0; xx < 8; xx++) { try { Color c = src.GetPixel(x + xx, y + yy); if (c.A == 0) { continue; } VoteColor(tm.Rank, c); } catch (System.AccessViolationException) {//なんで例外が飛んでくるんだ? break; } } } SortColor(tm.Rank); tileMapping.Add(tm); //複数パレットの場合、そのタイルの中で最も人気の色 if (tm.Rank.Count > 0) { VoteColor(totalRank, tm.Rank[0]); } } } SortColor(totalRank); //上位の色たちをパレットに割り当てていきます. List <List <ColorRanking> > countList = new List <List <ColorRanking> >(); for (int i = 0; i < maxPalette; i++) { List <ColorRanking> pal = AssingPalette(i, totalRank, tileMapping); countList.Add(pal); } //まだ割り当てていないタイルがあれば、一番近い色セットを持つどれかのパレットに割り当てます. AssingaPaletteByUnassignedTile(countList, tileMapping, totalRank); //パレットの色数を16色にします. List <ColorRanking[]> paletteList = new List <ColorRanking[]>(); for (int i = 0; i < maxPalette; i++) { paletteList.Add(Convert16Color(countList[i], isReserve1StPalette)); } //パレットの適応 ColorPalette cp = DestBitmap.Palette; for (int i = 0; i < maxPalette; i++) { for (int n = 0; n < 16; n++) { cp.Entries[i * 16 + n] = Color.FromArgb(paletteList[i][n].R , paletteList[i][n].G , paletteList[i][n].B ); } } //利用しないところはゼロクリア for (int i = maxPalette; i < 16; i++) { for (int n = 0; n < 16; n++) { cp.Entries[i * 16 + n] = Color.FromArgb(0, 0, 0); } } DestBitmap.Palette = cp; //ピクセルの変換 Rectangle destrect = new Rectangle(new Point(), DestBitmap.Size); BitmapData destbmpData = DestBitmap.LockBits(destrect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); IntPtr dest = destbmpData.Scan0; for (int i = 0; i < tileMapping.Count; i++) { int paletteno = tileMapping[i].Palette; if (paletteno < 0) { Debug.Assert(false); continue; } int x = tileMapping[i].X; int y = tileMapping[i].Y; for (int yy = 0; yy < 8; yy++) { for (int xx = 0; xx < 8; xx++) { int index; try { Color c = src.GetPixel(x + xx, y + yy); if (c.A == 0) { index = 0; } else { index = getPaletteIndex(c, countList[paletteno]); } } catch (System.AccessViolationException) {//なんで例外が飛んでくるんだ? break; } int pos = (x + xx) + ((y + yy) * destrect.Width); byte cc = (byte)(paletteno * 16 + index); Marshal.WriteByte(dest, pos, cc); } } } DestBitmap.UnlockBits(destbmpData); return(DestBitmap); }
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); }
//FE6用 public static Bitmap DrawPortraitUnitFE6( uint unit_face , uint palette , uint mouth_x , uint mouth_y , int showFrame ) { int width = 12 * 8; int height = 10 * 8; unit_face = U.toOffset(unit_face); palette = U.toOffset(palette); if (unit_face == 0 || !U.isSafetyOffset(unit_face) || !U.isSafetyOffset(palette) ) { //ない. return(ImageUtil.Blank(width, height)); } //FE6の顔画像は圧縮されている. byte[] imageUZ = LZ77.decompress(Program.ROM.Data, unit_face); if (imageUZ.Length <= 0) {//ない return(ImageUtil.Blank(width, height)); } Bitmap allface = ImageUtil.ByteToImage16Tile(32 * 8, 5 * 8 , imageUZ, (int)0 , Program.ROM.Data, (int)palette ); //シートを作る Bitmap face = ImageUtil.Blank(face_width, face_height, allface); //メインの顔を転写 ImageUtil.BitBlt(face, parts_width / 2, 0 , parts_width * 2, parts_height * 2 , allface, 0, 0);//顔上 ImageUtil.BitBlt(face, parts_width / 2, parts_height * 2 , parts_width * 2, parts_height * 2 , allface, parts_width * 2, 0);//顔下 ImageUtil.BitBlt(face, parts_width / 2, parts_height * 4 , parts_width, parts_height , allface, parts_width * 4, 0);//右肩 ImageUtil.BitBlt(face, 0, parts_height * 3 , parts_width / 2, parts_height * 2 , allface, parts_width * 5, 0);//右端 ImageUtil.BitBlt(face, parts_width + parts_width / 2, parts_height * 4 , parts_width, parts_height , allface, parts_width * 4, parts_height);//左肩 ImageUtil.BitBlt(face, parts_width * 2 + parts_width / 2, parts_height * 3 , parts_width / 2, parts_height * 2 , allface, parts_width * 5 + parts_width / 2, 0);//左端 //表示フレーム指定 switch (showFrame) { case 1: //口ぱく1 ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8, parts_width, parts_height , allface, 192, 0, 0, 0); break; case 2: //口ぱく2 ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8, parts_width, parts_height , allface, 224, 0, 0, 0); break; case 3: //口ぱく3 ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8, parts_width, parts_height , allface, 192, 16, 0, 0); break; case 4: //口ぱく4 ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8, parts_width, parts_height , allface, 224, 16, 0, 0); break; case 5: //口ぱく5 ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8, parts_width, parts_height / 2 , allface, 0, 32, 0, 0); ImageUtil.BitBlt(face, (int)mouth_x * 8, (int)mouth_y * 8 + (parts_height / 2), parts_width, parts_height / 2 , allface, 32, 32, 0, 0); break; default: break; } allface.Dispose(); return(face); }
//マップを描画する. public static Bitmap DrawMap( uint obj_plist //image , uint palette_plist //palette , uint config_plist //tsa , uint mappointer_plist //mar , MapSettingForm.MapAnimations anime = null ) { //マップチップの読込 Bitmap obj_image = DrawMapChipOnly(obj_plist, palette_plist, anime); if (obj_image == null) { return(ImageUtil.BlankDummy()); } //チップセットの読込(マップチップの画像をどう解釈するか定義するデータ) byte[] configUZ = UnLZ77ChipsetData(config_plist); if (configUZ == null) { return(ImageUtil.BlankDummy()); } //マップ配置データの読込 byte[] mappointerUZ = UnLZ77MapData(mappointer_plist); if (mappointerUZ == null) { return(ImageUtil.BlankDummy()); } if (mappointerUZ.Length < 2) { Debug.Assert(false); return(ImageUtil.BlankDummy()); } //マップデータの先頭2バイトにマップの幅高さが入っている. //チップの数なので、 16*width=ピクセル 16*height=ピクセル である. int width = mappointerUZ[0]; int height = mappointerUZ[1]; if (width <= 0 || height <= 0) {//サイズが不正 return(ImageUtil.BlankDummy()); } UInt16[] tsa = new UInt16[(width * 2) * (height * 2)]; int x = 0; int y = 0; for (int i = 2; i + 1 < mappointerUZ.Length; i += 2) { //マップデータを読む int m = (mappointerUZ[i] + ((UInt16)mappointerUZ[i + 1] << 8)); int tile_tsa_index = m << 1; if (tile_tsa_index + 7 >= configUZ.Length) {//不正なTSA return(ImageUtil.BlankDummy()); } //チップセットのTSAデータを読み込む. UInt16 lefttop = (UInt16)(configUZ[tile_tsa_index] + ((UInt16)configUZ[tile_tsa_index + 1] << 8)); UInt16 righttop = (UInt16)(configUZ[tile_tsa_index + 2] + ((UInt16)configUZ[tile_tsa_index + 3] << 8)); UInt16 leftbottom = (UInt16)(configUZ[tile_tsa_index + 4] + ((UInt16)configUZ[tile_tsa_index + 5] << 8)); UInt16 rightbottom = (UInt16)(configUZ[tile_tsa_index + 6] + ((UInt16)configUZ[tile_tsa_index + 7] << 8)); int tsaIndex; tsaIndex = (x) + ((y) * (width * 2)); if (tsaIndex < tsa.Length) { tsa[tsaIndex] = lefttop; } tsaIndex = (x + 1) + ((y) * (width * 2)); if (tsaIndex < tsa.Length) { tsa[tsaIndex] = righttop; } tsaIndex = (x) + ((y + 1) * (width * 2)); if (tsaIndex < tsa.Length) { tsa[tsaIndex] = leftbottom; } tsaIndex = (x + 1) + ((y + 1) * (width * 2)); if (tsaIndex < tsa.Length) { tsa[tsaIndex] = rightbottom; } x += 2; if (x >= width * 2) { x = 0; y += 2; if (y >= height * 2) { break; } } } Bitmap mapcanvas = ImageUtil.Blank(width * 16, height * 16, obj_image); ImageUtil.BitBltTSA(mapcanvas, obj_image, tsa, 0); return(mapcanvas); }
//マップの部分変更 public static Bitmap DrawChangeMap( uint obj_plist , uint palette_plist , uint config_plist , int width , int height , uint change_address , MapSettingForm.MapAnimations anime = null ) { change_address = U.toOffset(change_address); if (!U.isSafetyOffset(change_address)) { return(ImageUtil.BlankDummy()); } //マップチップの読込 Bitmap obj_image = DrawMapChipOnly(obj_plist, palette_plist, anime); if (obj_image == null) { return(ImageUtil.BlankDummy()); } //チップセットの読込(マップチップの画像をどう解釈するか定義するデータ) byte[] configUZ = UnLZ77ChipsetData(config_plist); if (configUZ == null) { return(ImageUtil.BlankDummy()); } //マップ変更の場合、幅高さはユーザが指定する. UInt16[] tsa = new UInt16[(width * 2) * (height * 2)]; int x = 0; int y = 0; int length = width * height * 2; if (!U.isSafetyOffset(change_address + (uint)length - 1)) {//サイズ超過. R.Error("map size over {0}-{1}", U.ToHexString(change_address), U.ToHexString(length)); return(ImageUtil.BlankDummy()); } for (int i = 0; i + 1 < length; i += 2) { //マップデータを読む int m = (int)Program.ROM.u16((uint)(change_address + i)); int tile_tsa_index = m << 1; if (tile_tsa_index + 7 >= configUZ.Length) {//不正なTSA return(ImageUtil.BlankDummy(16)); } //チップセットのTSAデータを読み込む. UInt16 lefttop = (UInt16)(configUZ[tile_tsa_index] + ((UInt16)configUZ[tile_tsa_index + 1] << 8)); UInt16 righttop = (UInt16)(configUZ[tile_tsa_index + 2] + ((UInt16)configUZ[tile_tsa_index + 3] << 8)); UInt16 leftbottom = (UInt16)(configUZ[tile_tsa_index + 4] + ((UInt16)configUZ[tile_tsa_index + 5] << 8)); UInt16 rightbottom = (UInt16)(configUZ[tile_tsa_index + 6] + ((UInt16)configUZ[tile_tsa_index + 7] << 8)); tsa[(x) + ((y) * (width * 2))] = lefttop; tsa[(x + 1) + ((y) * (width * 2))] = righttop; tsa[(x) + ((y + 1) * (width * 2))] = leftbottom; tsa[(x + 1) + ((y + 1) * (width * 2))] = rightbottom; x += 2; if (x >= width * 2) { x = 0; y += 2; if (y >= height * 2) { break; } } } Bitmap mapcanvas = ImageUtil.Blank(width * 16, height * 16, obj_image); ImageUtil.BitBltTSA(mapcanvas, obj_image, tsa, 0); return(mapcanvas); }
void ExportGif(string filename) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); List <ImageUtilAnimeGif.Frame> bitmaps = new List <ImageUtilAnimeGif.Frame>(); if (!U.isSafetyOffset(this.FramePointer)) { for (int i = 0; i < this.FramePointer; i++) { Bitmap bitmap; bitmap = DrawDirectLow(i); if (bitmap == null) {//デコードできなかった. bitmap = ImageUtil.Blank(30 * 8, 16 * 8); } //利用していないパレットを消す. ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); bitmaps.Add(new ImageUtilAnimeGif.Frame(bitmap, 1)); } } else { //同じアニメを何度も出力しないように記録する. Dictionary <uint, Bitmap> animeHash = new Dictionary <uint, Bitmap>(); uint addr = Program.ROM.p32(FramePointer); //圧縮されていないデータなので、事故防止のため リミッターをかける. uint limitter = addr + 1024 * 1024; //1MBサーチしたらもうあきらめる. limitter = (uint)Math.Min(limitter, Program.ROM.Data.Length); uint id = 0; uint wait = 0; uint i; for (i = 0; addr < limitter; i++, addr += 4) { id = Program.ROM.u16(addr); wait = Program.ROM.u16(addr + 2); if (id == 0xFFFF) { break; } Bitmap bitmap; string imagefilename = basename.Replace(" ", "_") + "g" + id.ToString("000") + ".png"; if (animeHash.ContainsKey(id)) { bitmap = animeHash[id]; } else { bitmap = DrawDirectLow((int)id); if (bitmap == null) {//デコードできなかった. bitmap = ImageUtil.Blank(30 * 8, 16 * 8); } //利用していないパレットを消す. ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); animeHash[id] = bitmap; } bitmaps.Add(new ImageUtilAnimeGif.Frame(bitmap, wait)); } } //アニメgif生成 ImageUtilAnimeGif.SaveAnimatedGif(filename, bitmaps); }
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); }
void Export(string filename) { string basename = Path.GetFileNameWithoutExtension(filename) + "_"; string basedir = Path.GetDirectoryName(filename); List <string> lines = new List <string>(); if (this.TSAList.Count >= 2 && this.PaletteList.Count == 1) { lines.Add("//" + R._("共通パレットを利用する必要があります。最初の画像のパレットのみが利用され、以後は共通パレットが利用されているものとして処理されます。")); } if (!U.isSafetyOffset(this.FramePointer)) { if (this.TSAList.Count == 1 && this.PaletteList.Count >= 2) { lines.Add("//" + R._("パレットアニメーションである必要があります。最初の画像のみ利用され、以後の画像はパレットだけ利用されます。")); } lines.Add("//" + R._("このアニメーションは、フレーム数が固定されています。最大フレーム数が、{0}({1})である必要があります", U.To0xHexString(this.FramePointer), this.FramePointer)); for (int i = 0; i < this.FramePointer; i++) { Bitmap bitmap; string imagefilename = basename.Replace(" ", "_") + "g" + i.ToString("000") + ".png"; bitmap = DrawDirectLow(i); if (bitmap == null) {//デコードできなかった. bitmap = ImageUtil.Blank(30 * 8, 16 * 8); } //利用していないパレットを消す. ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); U.BitmapSave(bitmap, Path.Combine(basedir, imagefilename)); string line = "1" + " " + imagefilename; lines.Add(line); } } else { //同じアニメを何度も出力しないように記録する. Dictionary <uint, Bitmap> animeHash = new Dictionary <uint, Bitmap>(); uint addr = Program.ROM.p32(FramePointer); //圧縮されていないデータなので、事故防止のため リミッターをかける. uint limitter = addr + 1024 * 1024; //1MBサーチしたらもうあきらめる. limitter = (uint)Math.Min(limitter, Program.ROM.Data.Length); uint id = 0; uint wait = 0; uint i; for (i = 0; addr < limitter; i++, addr += 4) { id = Program.ROM.u16(addr); wait = Program.ROM.u16(addr + 2); if (id == 0xFFFF) { break; } Bitmap bitmap; string imagefilename = basename.Replace(" ", "_") + "g" + id.ToString("000") + ".png"; if (animeHash.ContainsKey(id)) { bitmap = animeHash[id]; } else { bitmap = DrawDirectLow((int)id); if (bitmap == null) {//デコードできなかった. bitmap = ImageUtil.Blank(30 * 8, 16 * 8); } //利用していないパレットを消す. ImageUtil.BlackOutUnnecessaryColors(bitmap, 1); U.BitmapSave(bitmap, Path.Combine(basedir, imagefilename)); animeHash[id] = bitmap; } string line = wait.ToString() + " " + imagefilename; lines.Add(line); } } U.WriteAllLinesInError(filename, lines); }
//フォントの描画 void DrawFonts() { if (SearchChar.Text.Length <= 0) { return; } string target = this.SearchChar.Text; target = TextForm.ConvertFEditorToEscape(target); Bitmap fontSampleBitmap; uint fontlist_pointer = GetFontPointer(this.FontType.SelectedIndex == 0); Color bgcolor = GetFontColor(this.FontType.SelectedIndex == 0); fontSampleBitmap = ImageUtil.Blank(FontPictureBox.Width, FontPictureBox.Height); PatchUtil.PRIORITY_CODE priorityCode = PatchUtil.SearchPriorityCode(); int drawwidth = 0; for (int i = 0; i < this.FontSample.Text.Length; i++) { uint search_char; if (this.FontSample.Text[i] == '@') { search_char = U.ConvertMojiCharToUnitFast(target, priorityCode); } else { search_char = U.ConvertMojiCharToUnitFast(this.FontSample.Text.Substring(i, 1), priorityCode); } uint fontaddr = FindFontData(fontlist_pointer, search_char, priorityCode); if (fontaddr == U.NOT_FOUND) { continue; } int width; byte[] fontbyte; if (this.FontSample.Text[i] == '@') { width = (int)this.FontWidth.Value; fontbyte = this.SelectFontBitmapByte; } else { fontbyte = ReadFontData(fontaddr, out width); } if (width <= 0 || fontbyte == null) { continue; } Bitmap bitmap = ImageUtil.ByteToImage4(16, 16, fontbyte, 0, bgcolor); fontSampleBitmap.Palette = bitmap.Palette; ImageUtil.BitBlt(fontSampleBitmap, drawwidth, 0, width, 16, bitmap, 0, 0); drawwidth += width; } FontPictureBox.Image = U.Zoom(fontSampleBitmap, ZoomComboBox.SelectedIndex); }
Bitmap ConvertIgnoreTSA(Bitmap src, int maxColor, int yohaku, bool isReserve1StPalette, bool isUseTransparent) { int width = src.Width; int height = src.Height; width = U.Padding8(width); height = U.Padding8(height); Bitmap DestBitmap = ImageUtil.Blank(width + yohaku, height); List <ColorRanking> totalRank = new List <ColorRanking>(); List <TileMapping> tileMapping = new List <TileMapping>(); for (int y = 0; y < height; y += 8) { if (y + 8 > height) { continue; } for (int x = 0; x < width; x += 8) { if (x + 8 > width) { continue; } TileMapping tm = new TileMapping(); tm.Rank = new List <ColorRanking>(); tm.Palette = -1; tm.X = x; tm.Y = y; for (int yy = 0; yy < 8; yy++) { for (int xx = 0; xx < 8; xx++) { try { Color c = src.GetPixel(x + xx, y + yy); if (c.A == 0 && isUseTransparent) { continue; } VoteColor(tm.Rank, c); } catch (System.AccessViolationException) {//なんで例外が飛んでくるんだ? break; } } } SortColor(tm.Rank); tileMapping.Add(tm); for (int i = 0; i < tm.Rank.Count; i++) { VoteColor(totalRank, tm.Rank[i]); } } } SortColor(totalRank); //パレットの色数を16色 or 256色にします. List <ColorRanking> paletteList = new List <ColorRanking>(); paletteList.AddRange(Convert16Color(totalRank, isReserve1StPalette, maxColor)); //パレットの適応 ColorPalette cp = DestBitmap.Palette; for (int i = 0; i < maxColor; i++) { cp.Entries[i] = Color.FromArgb( paletteList[i].R , paletteList[i].G , paletteList[i].B ); } //利用しないところはゼロクリア for (int i = maxColor; i < 16 * 16; i++) { cp.Entries[i] = Color.FromArgb(0, 0, 0); } DestBitmap.Palette = cp; int startColor = 0; if (isReserve1StPalette && isUseTransparent == false) {//最初の色が背景なのに、背景色を使わないということは、color index==0は予約されている startColor = 1; } //ピクセルの変換 Rectangle destrect = new Rectangle(new Point(), DestBitmap.Size); BitmapData destbmpData = DestBitmap.LockBits(destrect, ImageLockMode.ReadWrite, PixelFormat.Format8bppIndexed); IntPtr dest = destbmpData.Scan0; for (int i = 0; i < tileMapping.Count; i++) { int x = tileMapping[i].X; int y = tileMapping[i].Y; for (int yy = 0; yy < 8; yy++) { for (int xx = 0; xx < 8; xx++) { int index; try { Color c = src.GetPixel(x + xx, y + yy); if (c.A == 0 && isUseTransparent) { index = 0; } else { index = getPaletteIndex(c, paletteList, startColor); } } catch (System.AccessViolationException) {//なんで例外が飛んでくるんだ? break; } int pos = (x + xx) + ((y + yy) * destrect.Width); byte cc = (byte)(index); Marshal.WriteByte(dest, pos, cc); } } } DestBitmap.UnlockBits(destbmpData); return(DestBitmap); }