diff --git a/Be.Windows.Forms.HexBox/ByteCharConverters.cs b/Be.Windows.Forms.HexBox/ByteCharConverters.cs
index 6c488a9..1210802 100644
--- a/Be.Windows.Forms.HexBox/ByteCharConverters.cs
+++ b/Be.Windows.Forms.HexBox/ByteCharConverters.cs
@@ -21,7 +21,9 @@ namespace Be.Windows.Forms
///
///
///
- byte ToByte(char c);
+ byte[] ToByte(char c);
+
+ Encoding ToEncoding();
}
///
@@ -44,9 +46,11 @@ namespace Be.Windows.Forms
///
///
///
- public virtual byte ToByte(char c)
+ public virtual byte[] ToByte(char c)
{
- return (byte)c;
+ byte[] bytes = new byte[1];
+ bytes[0] = (byte)c;
+ return bytes;
}
///
@@ -57,6 +61,11 @@ namespace Be.Windows.Forms
{
return "ANSI (Default)";
}
+
+ public Encoding ToEncoding()
+ {
+ return Encoding.Default;
+ }
}
///
@@ -86,10 +95,10 @@ namespace Be.Windows.Forms
///
///
///
- public virtual byte ToByte(char c)
+ public virtual byte[] ToByte(char c)
{
byte[] decoded = _ebcdicEncoding.GetBytes(new char[] { c });
- return decoded.Length > 0 ? decoded[0] : (byte)0;
+ return decoded.Length > 0 ? decoded : (new byte[1] { 0 });
}
///
@@ -100,5 +109,10 @@ namespace Be.Windows.Forms
{
return "EBCDIC (Code Page 500)";
}
+
+ public Encoding ToEncoding()
+ {
+ return this._ebcdicEncoding;
+ }
}
}
diff --git a/Be.Windows.Forms.HexBox/HexBox.cs b/Be.Windows.Forms.HexBox/HexBox.cs
index 7b6480c..56d0eb6 100644
--- a/Be.Windows.Forms.HexBox/HexBox.cs
+++ b/Be.Windows.Forms.HexBox/HexBox.cs
@@ -1066,11 +1066,13 @@ namespace Be.Windows.Forms
_hexBox.ReleaseSelection();
- byte b = _hexBox.ByteCharConverter.ToByte(c);
+ byte[] b = _hexBox.ByteCharConverter.ToByte(c);
if(isInsertMode)
- _hexBox._byteProvider.InsertBytes(pos, new byte[]{b});
- else
- _hexBox._byteProvider.WriteByte(pos, b);
+ _hexBox._byteProvider.InsertBytes(pos, b);
+ else {
+ foreach (byte bs in b)
+ _hexBox._byteProvider.WriteByte(pos, bs);
+ }
PerformPosMoveRightByte();
_hexBox.Invalidate();
@@ -1168,15 +1170,15 @@ namespace Be.Windows.Forms
///
int _lastThumbtrack;
///
- /// Contains the border´s left shift
+ /// Contains the border left shift
///
int _recBorderLeft = SystemInformation.Border3DSize.Width;
///
- /// Contains the border´s right shift
+ /// Contains the border right shift
///
int _recBorderRight = SystemInformation.Border3DSize.Width;
///
- /// Contains the border´s top shift
+ /// Contains the border top shift
///
int _recBorderTop = SystemInformation.Border3DSize.Height;
///
@@ -1807,7 +1809,7 @@ namespace Be.Windows.Forms
System.Diagnostics.Debug.WriteLine("UpdateCaret()", "HexBox");
- long byteIndex =_bytePos - _startByte;
+ long byteIndex = _bytePos - _startByte;
PointF p = _keyInterpreter.GetCaretPointF(byteIndex);
p.X += _byteCharacterPos*_charSize.Width;
NativeMethods.SetCaretPos((int)p.X, (int)p.Y);
@@ -2149,7 +2151,8 @@ namespace Be.Windows.Forms
DataObject da = new DataObject();
// set string buffer clipbard data
- string sBuffer = System.Text.Encoding.ASCII.GetString(buffer, 0, buffer.Length);
+ Encoding encoding = ByteCharConverter.ToEncoding();
+ string sBuffer = encoding.GetString(buffer, 0, buffer.Length);
da.SetData(typeof(string), sBuffer);
//set memorystream (BinaryData) clipboard data
@@ -2229,7 +2232,8 @@ namespace Be.Windows.Forms
else if(da.GetDataPresent(typeof(string)))
{
string sBuffer = (string)da.GetData(typeof(string));
- buffer = System.Text.Encoding.ASCII.GetBytes(sBuffer);
+ Encoding encoding = ByteCharConverter.ToEncoding();
+ buffer = encoding.GetBytes(sBuffer);
}
else
{
@@ -2581,9 +2585,37 @@ namespace Be.Windows.Forms
g.DrawString(sB.Substring(1,1), Font, brush, bytePointF, _stringFormat);
}
- void PaintHexAndStringView(Graphics g, long startByte, long endByte)
+ static bool IsCjkCharacter(char ch)
+ {
+ int codePoint = ch;
+
+ // CJK Unified Ideographs
+ if (codePoint >= 0x4E00 && codePoint <= 0x9FFF)
+ return true;
+
+ // CJK Unified Ideographs Extension A
+ if (codePoint >= 0x3400 && codePoint <= 0x4DBF)
+ return true;
+
+ // CJK Compatibility Ideographs
+ if (codePoint >= 0xF900 && codePoint <= 0xFAFF)
+ return true;
+
+ // Additional ranges for CJK (surrogate pairs)
+ // Note: Surrogate pairs are required for characters beyond U+FFFF
+ if (char.IsHighSurrogate(ch) || char.IsLowSurrogate(ch))
+ {
+ // Handle surrogate pairs
+ return false;
+ }
+
+ return false;
+ }
+
+ void PaintHexAndStringView(Graphics g, long startByte, long endByte)
{
- Brush brush = new SolidBrush(GetDefaultForeColor());
+ System.Diagnostics.Debug.WriteLine(ByteCharConverter.ToString(), "PaintHexAndStringView()", "HexBox");
+ Brush brush = new SolidBrush(GetDefaultForeColor());
Brush selBrush = new SolidBrush(_selectionForeColor);
Brush selBrushBack = new SolidBrush(_selectionBackColor);
@@ -2612,18 +2644,23 @@ namespace Be.Windows.Forms
}
string s = new String(ByteCharConverter.ToChar(b), 1);
+ float cjk_ofs = 0;
+ if (IsCjkCharacter(s.ToCharArray()[0]))
+ cjk_ofs = _charSize.Width / 2;
- if(isSelectedByte && isStringKeyInterpreterActive)
+ if (isSelectedByte && isStringKeyInterpreterActive)
{
- g.FillRectangle(selBrushBack, byteStringPointF.X, byteStringPointF.Y, _charSize.Width, _charSize.Height);
- g.DrawString(s, Font, selBrush, byteStringPointF, _stringFormat);
+ g.FillRectangle(selBrushBack, byteStringPointF.X, byteStringPointF.Y, _charSize.Width, _charSize.Height);
+ byteStringPointF.X -= cjk_ofs;
+ g.DrawString(s, Font, selBrush, byteStringPointF, _stringFormat);
}
else
{
- g.DrawString(s, Font, brush, byteStringPointF, _stringFormat);
+ byteStringPointF.X -= cjk_ofs;
+ g.DrawString(s, Font, brush, byteStringPointF, _stringFormat);
}
}
- }
+ }
void PaintCurrentBytesSign(Graphics g)
{
@@ -2818,7 +2855,7 @@ namespace Be.Windows.Forms
return;
_startByte = (_scrollVpos+1) * _iHexMaxHBytes - _iHexMaxHBytes;
- _endByte = (long)Math.Min(_byteProvider.Length - 1, _startByte + _iHexMaxBytes);
+ _endByte = (long)Math.Min(_byteProvider.Length - 1, _startByte + _iHexMaxBytes);
}
#endregion
@@ -3318,9 +3355,9 @@ namespace Be.Windows.Forms
} long _lineInfoOffset = 0;
///
- /// Gets or sets the hex box´s border style.
+ /// Gets or sets the hex box border style.
///
- [DefaultValue(typeof(BorderStyle), "Fixed3D"), Category("Hex"), Description("Gets or sets the hex box´s border style.")]
+ [DefaultValue(typeof(BorderStyle), "Fixed3D"), Category("Hex"), Description("Gets or sets the hex box border style.")]
public BorderStyle BorderStyle
{
get { return _borderStyle;}
diff --git a/Tinke/VisorHex.Designer.cs b/Tinke/VisorHex.Designer.cs
index 3e67531..ef9ea60 100644
--- a/Tinke/VisorHex.Designer.cs
+++ b/Tinke/VisorHex.Designer.cs
@@ -93,7 +93,7 @@ namespace Tinke
this.hexBox1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
- this.hexBox1.Font = new System.Drawing.Font("Courier New", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.hexBox1.Font = new System.Drawing.Font("Arial", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.hexBox1.InfoForeColor = System.Drawing.Color.Empty;
this.hexBox1.LineInfoVisible = true;
this.hexBox1.Location = new System.Drawing.Point(0, 24);
@@ -301,10 +301,13 @@ namespace Tinke
this.encodingCombo.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.encodingCombo.Items.AddRange(new object[] {
"S0D",
+ "EBCDIC(CP500)",
"Shift_JIS",
- "UTF-7",
+ "UTF-16LE",
+ "UTF-16BE",
"UTF-8",
- "ASCII"});
+ "ASCII",
+ "GBK"});
this.encodingCombo.Name = "encodingCombo";
this.encodingCombo.Size = new System.Drawing.Size(120, 25);
this.encodingCombo.DropDownClosed += new System.EventHandler(this.encodingCombo_DropDownClosed);
diff --git a/Tinke/VisorHex.cs b/Tinke/VisorHex.cs
index aeed5c9..cb79a84 100644
--- a/Tinke/VisorHex.cs
+++ b/Tinke/VisorHex.cs
@@ -145,17 +145,18 @@ namespace Tinke
{
hexBox1.Height = this.Height - 83;
- tableGrid.Width = this.Width - 652;
+ tableGrid.Width = this.Width - 750;
if (tableGrid.Visible) hexBox1.Width = this.Width - (tableGrid.Width + 15);
else hexBox1.Width = this.Width - 16;
-
}
private void comboBoxEncoding_SelectedIndexChanged(object sender, EventArgs e)
{
if (encodingCombo.SelectedIndex == 0)
bcc = new DefaultByteCharConverter();
+ else if (encodingCombo.SelectedIndex == 1)
+ bcc = new EbcdicByteCharProvider();
else
bcc = new ByteCharConveter(encodingCombo.Text);
@@ -290,11 +291,12 @@ namespace Tinke
{
hexBox1.Width = this.Width - (tableGrid.Width + 15);
tableGrid.Show();
+ VisorHex_Resize(null, null);
}
private void tableGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
- List codes = new List();
+ List codes = new List();
List charas = new List();
for (int i = 0; i < tableGrid.RowCount; i++)
@@ -303,7 +305,7 @@ namespace Tinke
!(tableGrid.Rows[i].Cells[1].Value is object))
continue;
- codes.Add(Convert.ToUInt64((string)tableGrid.Rows[i].Cells[0].Value, 16));
+ codes.Add(Convert.ToByte((string)tableGrid.Rows[i].Cells[0].Value, 16));
charas.Add(Convert.ToChar(tableGrid.Rows[i].Cells[1].Value));
}
hexBox1.ByteCharConverter = new ByteCharTable(codes.ToArray(), charas.ToArray());
@@ -353,13 +355,10 @@ namespace Tinke
for (int i = 0; i < lines.Length; i++)
{
int sign_pos = lines[i].IndexOf('=');
- ushort code = Convert.ToUInt16(lines[i].Substring(0, sign_pos), 16);
+ byte code = Convert.ToByte(lines[i].Substring(0, sign_pos), 16);
char chara = lines[i].Substring(sign_pos + 1)[0];
- if (code <= 0x7E)
- tableGrid.Rows.Add(code.ToString("x").ToUpper(), chara);
- else
- tableGrid.Rows.Add(code.ToString("x").ToUpper().PadLeft(4, '0'), chara);
+ tableGrid.Rows.Add(code.ToString(), chara);
}
tableGrid_CellEndEdit(null, null);
@@ -465,29 +464,29 @@ namespace Tinke
public class ByteCharTable : IByteCharConverter
{
- Dictionary tableChar;
- Dictionary tableByte;
+ Dictionary tableChar;
+ Dictionary tableByte;
public ByteCharTable(string tablePath)
{
- tableChar = new Dictionary();
- tableByte = new Dictionary();
+ tableChar = new Dictionary();
+ tableByte = new Dictionary();
String[] lines = File.ReadAllLines(tablePath);
for (int i = 0; i < lines.Length; i++)
{
int sign_pos = lines[i].IndexOf('=');
- ulong code = Convert.ToUInt64(lines[i].Substring(0, sign_pos), 16);
+ byte code = Convert.ToByte(lines[i].Substring(0, sign_pos), 16);
char chara = lines[i].Substring(sign_pos + 1)[0];
tableChar.Add(code, chara);
tableByte.Add(chara, code);
}
}
- public ByteCharTable(ulong[] codes, char[] charas)
+ public ByteCharTable(byte[] codes, char[] charas)
{
- tableByte = new Dictionary();
- tableChar = new Dictionary();
+ tableByte = new Dictionary();
+ tableChar = new Dictionary();
for (int i = 0; i < codes.Length; i++)
{
@@ -505,58 +504,136 @@ namespace Tinke
else
return '.';
}
- public byte ToByte(char c)
+ public byte[] ToByte(char c)
{
+ byte[] bytes = new byte[1];
if (tableByte.ContainsKey(c))
- return (byte)tableByte[c];
+ {
+ bytes[0] = tableByte[c];
+ return bytes;
+ }
else
- return 0;
+ return (new byte[1] { 0 });
+ }
+ public Encoding ToEncoding()
+ {
+ return Encoding.Default;
}
}
public class ByteCharConveter : IByteCharConverter
{
Encoding encoding;
- List requeridedChar;
- List requeridedByte;
+ List requiredChar;
+ List requiredByte;
public ByteCharConveter(string encoding)
{
this.encoding = Encoding.GetEncoding(encoding);
- requeridedChar = new List();
- requeridedByte = new List();
+ requiredChar = new List();
+ requiredByte = new List();
}
- public byte ToByte(char c)
+ public byte[] ToByte(char c)
{
- if (encoding.WebName == "shift_jis")
- return ToByteShiftJis(c);
-
- return (byte)c;
+ byte[] decoded = encoding.GetBytes(new char[] { c });
+ return decoded.Length > 0 ? decoded : (new byte[1] { 0 });
}
public char ToChar(byte b)
{
- if (encoding.WebName == "shift_jis")
- return ToCharShiftJis(b);
+ if (encoding.WebName == "shift_jis" || encoding.WebName == "gb2312")
+ return ToCharShiftJisOrGBK(b);
+ if (encoding.WebName == "utf-8")
+ return ToCharUtf8(b);
+ if (encoding.WebName == "utf-16")
+ return ToCharUtf16Le(b);
+ if (encoding.WebName == "utf-16BE")
+ return ToCharUtf16Be(b);
return encoding.GetChars(new byte[] { b })[0];
}
- public byte ToByteShiftJis(char c)
+ public char ToCharShiftJisOrGBK(byte b)
{
- return (byte)c;
- }
- public char ToCharShiftJis(byte b)
- {
- if (requeridedChar.Count == 0 && b > 0x7F)
+ if (requiredChar.Count == 0 && b > 0x7F)
{
- requeridedChar.Add(b);
+ requiredChar.Add(b);
return '\x20';
}
- requeridedChar.Add(b);
- string c = new String(encoding.GetChars(requeridedChar.ToArray()));
- requeridedChar.Clear();
+ requiredChar.Add(b);
+ string c = new String(encoding.GetChars(requiredChar.ToArray()));
+ requiredChar.Clear();
return (c[0] > '\x1F' ? c[0] : '.');
}
+
+ public char ToCharUtf16Le(byte b)
+ {
+ requiredChar.Add(b);
+
+ if (requiredChar.Count == 2)
+ {
+ char c = BitConverter.ToChar(requiredChar.ToArray(), 0);
+ requiredChar.Clear();
+ return (c > '\x1F' ? c : '.');
+ }
+
+ return '\x20';
+ }
+
+ public char ToCharUtf16Be(byte b)
+ {
+ requiredChar.Add(b);
+
+ if (requiredChar.Count == 2)
+ {
+ byte[] bytes = requiredChar.ToArray();
+ Array.Reverse(bytes);
+ char c = BitConverter.ToChar(bytes, 0);
+ requiredChar.Clear();
+ return (c > '\x1F' ? c : '.');
+ }
+
+ return '\x20';
+ }
+
+ public char ToCharUtf8(byte b)
+ {
+ if (requiredChar.Count == 0 && !((b & 0x80) == 0))
+ {
+ requiredChar.Add(b);
+ return '\x20';
+ }
+ else if (requiredChar.Count == 1 && !((requiredChar[0] & 0xE0) == 0xC0))
+ {
+ requiredChar.Add(b);
+ return '\x20';
+ }
+ else if (requiredChar.Count == 2 && !((requiredChar[0] & 0xF0) == 0xE0))
+ {
+ requiredChar.Add(b);
+ return '\x20';
+ }
+
+ requiredChar.Add(b);
+ string c = new String(encoding.GetChars(requiredChar.ToArray()));
+ requiredChar.Clear();
+ return (c[0] > '\x1F' ? c[0] : '.');
+ }
+
+ public override string ToString()
+ {
+ if (encoding.WebName == "utf-16" || encoding.WebName == "utf-16BE")
+ {
+ requiredChar.Clear();
+ return "Unicode";
+ }
+ return encoding.WebName;
+ }
+
+ public Encoding ToEncoding()
+ {
+ return this.encoding;
+ }
}
-}
\ No newline at end of file
+
+}
diff --git a/changelog.txt b/changelog.txt
index ae720ff..1894e9c 100644
--- a/changelog.txt
+++ b/changelog.txt
@@ -5,7 +5,7 @@ TinkeDSi 0.9.5 (Made by R-YaTian)
* Set Topmost for waiting window, add "Please wait..." message
* Special fix for Sonic Classic Collection
* Allow drop files to open
-* WIP: Improve Hex Editor
+* Improve Hex Editor
* NFTR plugins: Disable zoom when more than 7489 chars, will fix scrolling issue
* Add toolkit: get header crc32 for r4cce/TTdT
* Allow copy info to Clipboard by mouse double click on RomInfo window
@@ -19,6 +19,10 @@ TinkeDSi 0.9.5 (Made by R-YaTian)
* 3DModels: Update to OpenTK 3.3.3, fix bug on fullscreen btn
* Improved SF Feather Plugin (By @mn1712trungson)
* Core: Improve Nitrocode check when saving rom
+* Saveoptions: Add an option to "Recompress ARM9 binary"
+* Saveoptions: Add an option to parse the header of flashcart firmware
+* Implement command line support
+* Update Be.Windows.Forms.HexBox to 1.6.0
TODO: full i18n support (include plugins)
TinkeDSi 0.9.4