Refactoring

move logic back to cgearbackground, initialize the bg regardless of
psk/cgb input format
cache background data to return psk (potentially unintended side effects
if importing bw psk to b2w2, will have to fix cgb->psk first then undo
this tempfix)
#1699
This commit is contained in:
Kurt 2018-01-09 23:30:44 -08:00
parent f332e41869
commit 4f489a720f
3 changed files with 45 additions and 36 deletions

View file

@ -3,9 +3,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
namespace PKHeX.WinForms
{
@ -46,6 +44,12 @@ namespace PKHeX.WinForms
if (data.Length != SIZE_CGB)
return;
// decode for easy handling
if (!IsCGB(data))
_psk = data = PSKtoCGB(data);
else
_cgb = data;
byte[] Region1 = data.Take(0x1FE0).ToArray();
byte[] ColorData = data.Skip(0x1FE0).Take(0x20).ToArray();
byte[] Region2 = data.Skip(0x2000).Take(0x600).ToArray();
@ -67,6 +71,12 @@ namespace PKHeX.WinForms
Map = new TileMap(Region2);
}
private byte[] _cgb;
private byte[] _psk;
public byte[] GetCGB() => _cgb ?? Write();
public byte[] GetPSK(bool B2W2) => _psk ?? CGBtoPSK(Write(), B2W2);
public byte[] Write()
{
byte[] data = new byte[SIZE_CGB];
@ -100,11 +110,12 @@ namespace PKHeX.WinForms
{
int index = BitConverter.ToUInt16(cgb, i);
int val = IndexToVal(index, shiftVal);
BitConverter.GetBytes((ushort)val).CopyTo(psk, i);
psk[i] = (byte)val;
psk[i + 1] = (byte)(val >> 8);
}
return psk;
}
public static byte[] PSKtoCGB(byte[] psk, bool B2W2)
public static byte[] PSKtoCGB(byte[] psk)
{
byte[] cgb = (byte[])psk.Clone();
for (int i = 0x2000; i < 0x2600; i += 2)
@ -144,11 +155,7 @@ namespace PKHeX.WinForms
throw new ArgumentException($"Invalid image height. Expected {Height} pixels high.");
// get raw bytes of image
BitmapData bData = img.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] data = new byte[bData.Stride * bData.Height];
Marshal.Copy(bData.Scan0, data, 0, data.Length);
img.UnlockBits(bData);
byte[] data = ImageUtil.GetPixelData(img);
const int bpp = 4;
Debug.Assert(data.Length == Width * Height * bpp);
@ -207,6 +214,8 @@ namespace PKHeX.WinForms
Map = tm;
ColorPalette = Palette;
Tiles = tilelist.ToArray();
_psk = null;
_cgb = null;
}
private sealed class Tile : IDisposable
@ -310,16 +319,13 @@ namespace PKHeX.WinForms
}
internal byte[] Write()
{
using (MemoryStream ms = new MemoryStream())
using (BinaryWriter bw = new BinaryWriter(ms))
byte[] data = new byte[TileChoices.Length * 2];
for (int i = 0; i < data.Length; i += 2)
{
for (int i = 0; i < TileChoices.Length; i++)
{
bw.Write((byte)TileChoices[i]);
bw.Write((byte)Rotations[i]);
}
return ms.ToArray();
data[i] = (byte)TileChoices[i/2];
data[i+1] = (byte)Rotations[i/2];
}
return data;
}
}

View file

@ -17,16 +17,10 @@ namespace PKHeX.WinForms
SAV = (SAV5)(Origin = sav).Clone();
InitializeComponent();
SAV = (Origin = sav).Clone() as SAV5;
bool cgearPresent = SAV.Data[SAV.CGearInfoOffset + 0x26] == 1;
byte[] data = new byte[CGearBackground.SIZE_CGB];
if (cgearPresent)
{
Array.Copy(SAV.Data, SAV.CGearDataOffset, data, 0, CGearBackground.SIZE_CGB);
if (!CGearBackground.IsCGB(data))
data = CGearBackground.PSKtoCGB(data, SAV.B2W2);
}
bg = new CGearBackground(data);
PB_Background.Image = bg.GetImage();
@ -82,23 +76,24 @@ namespace PKHeX.WinForms
if (ofd.ShowDialog() != DialogResult.OK)
return;
var len = new FileInfo(ofd.FileName).Length;
var path = ofd.FileName;
var len = new FileInfo(path).Length;
if (len != CGearBackground.SIZE_CGB)
{
WinFormsUtil.Error($"Incorrect size, got {len} bytes, expected {CGearBackground.SIZE_CGB} bytes.");
return;
}
byte[] data = File.ReadAllBytes(ofd.FileName);
if (!CGearBackground.IsCGB(data))
{
bool B2W2 = data[0x2000] != 0x00;
data = CGearBackground.PSKtoCGB(data, B2W2);
}
byte[] data = File.ReadAllBytes(path);
LoadBackground(data);
}
private void LoadBackground(byte[] data)
{
bg = new CGearBackground(data);
PB_Background.Image = bg.GetImage();
}
private void B_ExportCGB_Click(object sender, EventArgs e)
{
SaveFileDialog sfd = new SaveFileDialog
@ -109,19 +104,15 @@ namespace PKHeX.WinForms
if (sfd.ShowDialog() != DialogResult.OK)
return;
byte[] data = bg.Write();
byte[] data = bg.GetCGB();
File.WriteAllBytes(sfd.FileName, data);
}
private void B_Save_Click(object sender, EventArgs e)
{
byte[] bgdata = bg.Write();
byte[] bgdata = bg.GetPSK(SAV.B2W2);
if (bgdata.SequenceEqual(new byte[CGearBackground.SIZE_CGB]))
return;
// Data present
bgdata = CGearBackground.CGBtoPSK(bgdata, SAV.B2W2);
byte[] dlcfooter = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x14, 0x27, 0x00, 0x00, 0x27, 0x35, 0x05, 0x31, 0x00, 0x00 };
bgdata.CopyTo(SAV.Data, SAV.CGearDataOffset);

View file

@ -78,6 +78,18 @@ namespace PKHeX.WinForms
ptr = bmpData.Scan0;
data = new byte[bmp.Width * bmp.Height * 4];
}
public static Bitmap GetBitmap(byte[] data, int width, int height, int stride = 4, PixelFormat format = PixelFormat.Format32bppArgb)
{
return new Bitmap(width, height, stride, format, Marshal.UnsafeAddrOfPinnedArrayElement(data, 0));
}
public static byte[] GetPixelData(Bitmap bitmap)
{
var argbData = new byte[bitmap.Width * bitmap.Height * 4];
var bd = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
Marshal.Copy(bd.Scan0, argbData, 0, bitmap.Width * bitmap.Height * 4);
bitmap.UnlockBits(bd);
return argbData;
}
private static void SetAllTransparencyTo(byte[] data, double trans)
{
for (int i = 0; i < data.Length; i += 4)