Merge pull request #1040 from pokecal/pokecal-patch-2

Poketch DotArtEdit
This commit is contained in:
Kurt
2017-04-09 14:08:08 -07:00
committed by GitHub
3 changed files with 227 additions and 10 deletions

View File

@@ -33,6 +33,7 @@ private void InitializeComponent()
this.B_Save = new System.Windows.Forms.Button();
this.TC_Misc = new System.Windows.Forms.TabControl();
this.TAB_Poketch = new System.Windows.Forms.TabPage();
this.PB_DotArtist = new System.Windows.Forms.PictureBox();
this.B_GiveAll = new System.Windows.Forms.Button();
this.CHK_App25 = new System.Windows.Forms.CheckBox();
this.CHK_App24 = new System.Windows.Forms.CheckBox();
@@ -61,6 +62,7 @@ private void InitializeComponent()
this.CHK_App01 = new System.Windows.Forms.CheckBox();
this.TC_Misc.SuspendLayout();
this.TAB_Poketch.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.PB_DotArtist)).BeginInit();
this.SuspendLayout();
//
// B_Cancel
@@ -96,6 +98,8 @@ private void InitializeComponent()
//
// TAB_Poketch
//
this.TAB_Poketch.AllowDrop = true;
this.TAB_Poketch.Controls.Add(this.PB_DotArtist);
this.TAB_Poketch.Controls.Add(this.B_GiveAll);
this.TAB_Poketch.Controls.Add(this.CHK_App25);
this.TAB_Poketch.Controls.Add(this.CHK_App24);
@@ -129,6 +133,18 @@ private void InitializeComponent()
this.TAB_Poketch.TabIndex = 0;
this.TAB_Poketch.Text = "Poketch";
this.TAB_Poketch.UseVisualStyleBackColor = true;
this.TAB_Poketch.DragDrop += new System.Windows.Forms.DragEventHandler(this.TAB_Poketch_DragDrop);
this.TAB_Poketch.DragEnter += new System.Windows.Forms.DragEventHandler(this.TAB_Poketch_DragEnter);
//
// PB_DotArtist
//
this.PB_DotArtist.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.PB_DotArtist.Location = new System.Drawing.Point(277, 145);
this.PB_DotArtist.Name = "PB_DotArtist";
this.PB_DotArtist.Size = new System.Drawing.Size(96, 80);
this.PB_DotArtist.TabIndex = 26;
this.PB_DotArtist.TabStop = false;
this.PB_DotArtist.MouseClick += new System.Windows.Forms.MouseEventHandler(this.PB_DotArtist_MouseClick);
//
// B_GiveAll
//
@@ -215,9 +231,9 @@ private void InitializeComponent()
this.CHK_App18.AutoSize = true;
this.CHK_App18.Location = new System.Drawing.Point(151, 160);
this.CHK_App18.Name = "CHK_App18";
this.CHK_App18.Size = new System.Drawing.Size(91, 16);
this.CHK_App18.Size = new System.Drawing.Size(117, 16);
this.CHK_App18.TabIndex = 17;
this.CHK_App18.Text = "18 Dot Artist";
this.CHK_App18.Text = "18 Dot Artist -->";
this.CHK_App18.UseVisualStyleBackColor = true;
//
// CHK_App17
@@ -401,10 +417,11 @@ private void InitializeComponent()
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "SAV_Misc4";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "SAV_Misc4";
this.Text = "Misc Editor";
this.TC_Misc.ResumeLayout(false);
this.TAB_Poketch.ResumeLayout(false);
this.TAB_Poketch.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.PB_DotArtist)).EndInit();
this.ResumeLayout(false);
}
@@ -441,5 +458,6 @@ private void InitializeComponent()
private System.Windows.Forms.CheckBox CHK_App07;
private System.Windows.Forms.CheckBox CHK_App06;
private System.Windows.Forms.Button B_GiveAll;
private System.Windows.Forms.PictureBox PB_DotArtist;
}
}
}

View File

@@ -1,4 +1,8 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using PKHeX.Core;
@@ -20,22 +24,165 @@ public SAV_Misc4()
};
int ret = SAV.PoketchApps;
for(int i = 0; i < Apps.Length; i++)
{
for (int i = 0; i < Apps.Length; i++)
Apps[i].Checked = (ret & 1 << i) != 0;
}
DotArtistByte = SAV.PoketchDotArtist;
ColorTable = new byte[4] { 248, 168, 88, 8 };
setPictureBoxFromFlags(DotArtistByte);
string tip = "Guide about D&D ImageFile Format";
tip += Environment.NewLine + " width = 24px";
tip += Environment.NewLine + " height = 20px";
tip += Environment.NewLine + " used color count <= 4";
tip += Environment.NewLine + " file size < 2058byte";
tip1.SetToolTip(PB_DotArtist, tip);
}
private readonly CheckBox[] Apps;
private byte[] DotArtistByte;
private readonly byte[] ColorTable;
private readonly ToolTip tip1 = new ToolTip();
private void setPictureBoxFromFlags(byte[] inp)
{
if (inp.Length != 120) return;
byte[] dupbyte = new byte[23040];
byte ict;
for (int iy = 0, iz, ib; iy < 20; iy++)
for (int ix = 0; ix < 24; ix++)
{
ib = ix + 24 * iy;
ict = ColorTable[inp[ib >> 2] >> (ib % 4 << 1) & 3];
iz = 12 * ix + 1152 * iy;
for (int izy = 0; izy < 4; izy++)
for (int izx = 0; izx < 4; izx++)
for (int ic = 0; ic < 3; ic++)
dupbyte[ic + 3 * izx + 288 * izy + iz] = ict;
}
Bitmap dabmp = new Bitmap(96, 80);
BitmapData dabdata = dabmp.LockBits(new Rectangle(0, 0, dabmp.Width, dabmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);
System.Runtime.InteropServices.Marshal.Copy(dupbyte, 0, dabdata.Scan0, dupbyte.Length);
dabmp.UnlockBits(dabdata);
PB_DotArtist.Image = dabmp;
}
private void setFlagsFromFileName(string inpFileName)
{
if (new FileInfo(inpFileName).Length > 2058) return; // 24*20*4(ARGB)=1920
Bitmap bmp;
FileStream fs = new FileStream(inpFileName, FileMode.Open, FileAccess.Read);
try
{
bmp = (Bitmap)Image.FromStream(fs);
}
catch
{
bmp = null;
}
fs.Close();
if (bmp == null || bmp.Width != 24 || bmp.Height != 20) return;
byte[] BrightMap = new byte[480];
byte[] BrightCount = new byte[0x100];
byte[] iBrightCount = new byte[0x100];
byte ig;
for (int iy = 0; iy < 20; iy++)
for (int ix = 0; ix < 24; ix++)
{
ig = (byte)(0xFF * bmp.GetPixel(ix, iy).GetBrightness());
BrightMap[ix + 24 * iy] = ig;
BrightCount[ig]++;
}
int ColorCount = BrightCount.Count(v => v > 0);
if (ColorCount > 4 || ColorCount == 0) return;
int errtot, errmin = int.MaxValue;
byte[] LCT = new byte[4];
byte[] mLCT = new byte[4];
for (int i = 0; i < 4; i++)
LCT[i] = (byte)(ColorCount < i + 1 ? 4 : ColorCount - i - 1);
int ee = 0;
while (++ee < 1000)
{
BrightCount.CopyTo(iBrightCount, 0);
for (int i = 0, j = 0; i < 0x100; i++)
if (iBrightCount[i] > 0)
iBrightCount[i] = LCT[j++];
errtot = 0;
for (int i = 0; i < 480; i++)
errtot += Math.Abs(BrightMap[i] - ColorTable[iBrightCount[BrightMap[i]]]);
if (errmin > errtot)
{
errmin = errtot;
LCT.CopyTo(mLCT, 0);
}
LCT = getNextLCT(LCT);
if (LCT[0] >= 4) break;
}
for (int i = 0, j = 0; i < 0x100; i++)
if (BrightCount[i] > 0)
BrightCount[i] = mLCT[j++];
for (int i = 0; i < 480; i++)
BrightMap[i] = BrightCount[BrightMap[i]];
byte[] ndab = new byte[120];
for (int i = 0; i < 480; i++)
ndab[i >> 2] |= (byte)((BrightMap[i] & 3) << (i % 4 << 1));
ndab.CopyTo(DotArtistByte, 0);
}
private byte[] getNextLCT(byte[] inp)
{
while (true)
{
if (++inp[0] >= 4)
{
inp[0] = 0;
if (++inp[1] >= 4)
{
inp[1] = 0;
if (++inp[2] >= 4)
{
inp[2] = 0;
if (++inp[3] >= 4)
{
inp[0] = 4;
return inp;
}
}
}
}
if (inp[1] < 4 && inp[1] >= inp[0]) continue;
if (inp[2] < 4 && inp[2] >= inp[1]) continue;
if (inp[3] < 4 && inp[3] >= inp[2]) continue;
}
return inp;
}
private void setFlagsFromClickPoint(int inpX, int inpY)
{
if (inpX < 0) inpX = 0;
else if (inpX > 95) inpX = 95;
if (inpY < 0) inpY = 0;
else if (inpY > 79) inpY = 79;
int i = (inpX >> 2) + 24 * (inpY >> 2);
byte[] ndab = new byte[120];
DotArtistByte.CopyTo(ndab, 0);
byte c = (byte)(ndab[i >> 2] >> (i % 4 << 1) & 3);
if (++c >= 4) c = 0;
ndab[i >> 2] &= (byte)~(3 << (i % 4 << 1));
ndab[i >> 2] |= (byte)((c & 3) << (i % 4 << 1));
ndab.CopyTo(DotArtistByte, 0);
}
private void saveMisc()
{
int ret = 0;
for(int i = 0; i < Apps.Length; i++)
for (int i = 0; i < Apps.Length; i++)
{
if (Apps[i].Checked) ret |= 1 << i;
}
SAV.PoketchApps = ret;
SAV.PoketchDotArtist = DotArtistByte;
}
private void B_Save_Click(object sender, EventArgs e)
@@ -55,5 +202,27 @@ private void B_GiveAll_Click(object sender, EventArgs e)
{
foreach (CheckBox c in Apps) c.Checked = true;
}
private void TAB_Poketch_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
e.Effect = DragDropEffects.Copy;
else
e.Effect = DragDropEffects.None;
}
private void TAB_Poketch_DragDrop(object sender, DragEventArgs e)
{
string[] t = (string[])e.Data.GetData(DataFormats.FileDrop, false);
if (t.Length != 1) return;
setFlagsFromFileName(t[0]);
setPictureBoxFromFlags(DotArtistByte);
}
private void PB_DotArtist_MouseClick(object sender, MouseEventArgs e)
{
setFlagsFromClickPoint(e.X, e.Y);
setPictureBoxFromFlags(DotArtistByte);
}
}
}

View File

@@ -1137,7 +1137,37 @@ public int PoketchApps
Data[ofs - 1] = 0; // current used, force set for first App.
}
}
public byte[] PoketchDotArtist
{
get
{
byte[] ret = new byte[120]; // 2bit*24px*20px
int ofs = 0;
switch (Version)
{
case GameVersion.DP: ofs = 0x1176; break;
default: return ret;
}
ofs += GBO;
for (int i = 0; i < 120; i++)
ret[i] = Data[ofs + i];
return ret;
}
set
{
int ofs = 0;
switch (Version)
{
case GameVersion.DP: ofs = 0x1176; break;
default: return;
}
ofs += GBO;
for(int i = 0; i < 120; i++)
Data[ofs + i] = value[i];
Data[ofs - 0x2A] |= 0x04; // 0x114C "Touch!"
}
}
public override string getString(int Offset, int Count) => PKX.getString4(Data, Offset, Count);
public override byte[] setString(string value, int maxLength, int PadToSize = 0, ushort PadWith = 0)
{
@@ -1145,5 +1175,5 @@ public override byte[] setString(string value, int maxLength, int PadToSize = 0,
PadToSize = maxLength + 1;
return PKX.setString4(value, maxLength, PadToSize, PadWith);
}
}
}
}